2
0
Fork 0

MOBILE-2430 rte: Enable RTE for iOS

main
Pau Ferrer Ocaña 2018-06-18 16:24:27 +02:00
parent 6fa19efcd5
commit 757882428f
21 changed files with 169 additions and 255 deletions

View File

@ -53,22 +53,7 @@ export class AddonModAssignFeedbackCommentsComponent extends AddonModAssignFeedb
* Component being initialized.
*/
ngOnInit(): void {
let promise,
rteEnabled;
// Check if rich text editor is enabled.
if (this.edit) {
promise = this.domUtils.isRichTextEditorEnabled();
} else {
// We aren't editing, so no rich text editor.
promise = Promise.resolve(false);
}
promise.then((enabled) => {
rteEnabled = enabled;
return this.getText(rteEnabled);
}).then((text) => {
this.getText().then((text) => {
this.text = text;
@ -113,10 +98,9 @@ export class AddonModAssignFeedbackCommentsComponent extends AddonModAssignFeedb
/**
* Get the text for the plugin.
*
* @param {boolean} rteEnabled Whether Rich Text Editor is enabled.
* @return {Promise<string>} Promise resolved with the text.
*/
protected getText(rteEnabled: boolean): Promise<string> {
protected getText(): Promise<string> {
// Check if the user already modified the comment.
return this.feedbackDelegate.getPluginDraftData(this.assign.id, this.userId, this.plugin).then((draft) => {
if (draft) {
@ -140,7 +124,7 @@ export class AddonModAssignFeedbackCommentsComponent extends AddonModAssignFeedb
// No offline data found, return online text.
this.isSent = true;
return this.assignProvider.getSubmissionPluginText(this.plugin, this.edit && !rteEnabled);
return this.assignProvider.getSubmissionPluginText(this.plugin);
});
}
});

View File

@ -15,7 +15,6 @@
import { Injectable, Injector } from '@angular/core';
import { CoreSitesProvider } from '@providers/sites';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { AddonModAssignProvider } from '../../../providers/assign';
import { AddonModAssignOfflineProvider } from '../../../providers/assign-offline';
@ -32,9 +31,8 @@ export class AddonModAssignFeedbackCommentsHandler implements AddonModAssignFeed
protected drafts = {}; // Store the data in this service so it isn't lost if the user performs a PTR in the page.
constructor(private sitesProvider: CoreSitesProvider, private domUtils: CoreDomUtilsProvider,
private textUtils: CoreTextUtilsProvider, private assignProvider: AddonModAssignProvider,
private assignOfflineProvider: AddonModAssignOfflineProvider) { }
constructor(private sitesProvider: CoreSitesProvider, private textUtils: CoreTextUtilsProvider,
private assignProvider: AddonModAssignProvider, private assignOfflineProvider: AddonModAssignOfflineProvider) { }
/**
* Discard the draft data of the feedback plugin.
@ -133,9 +131,7 @@ export class AddonModAssignFeedbackCommentsHandler implements AddonModAssignFeed
}
// No offline data found, get text from plugin.
return this.domUtils.isRichTextEditorEnabled().then((enabled) => {
return this.assignProvider.getSubmissionPluginText(plugin, !enabled);
});
return this.assignProvider.getSubmissionPluginText(plugin);
}).then((initialText) => {
const newText = AddonModAssignFeedbackCommentsHandler.getTextFromInputData(this.textUtils, plugin, inputData);
@ -185,14 +181,10 @@ export class AddonModAssignFeedbackCommentsHandler implements AddonModAssignFeed
const draft = this.getDraft(assignId, userId, siteId);
if (draft) {
return this.domUtils.isRichTextEditorEnabled().then((enabled) => {
if (!enabled) {
// Rich text editor not enabled, add some HTML to the text if needed.
draft.text = this.textUtils.formatHtmlLines(draft.text);
}
// Add some HTML to the text if needed.
draft.text = this.textUtils.formatHtmlLines(draft.text);
pluginData.assignfeedbackcomments_editor = draft;
});
pluginData.assignfeedbackcomments_editor = draft;
}
}

View File

@ -50,31 +50,16 @@ export class AddonModAssignSubmissionOnlineTextComponent extends AddonModAssignS
* Component being initialized.
*/
ngOnInit(): void {
let promise,
rteEnabled;
// Get the text. Check if we have anything offline.
this.assignOfflineProvider.getSubmission(this.assign.id).catch(() => {
// No offline data found.
}).then((offlineData) => {
if (offlineData && offlineData.plugindata && offlineData.plugindata.onlinetext_editor) {
return offlineData.plugindata.onlinetext_editor.text;
}
// Check if rich text editor is enabled.
if (this.edit) {
promise = this.domUtils.isRichTextEditorEnabled();
} else {
// We aren't editing, so no rich text editor.
promise = Promise.resolve(false);
}
promise.then((enabled) => {
rteEnabled = enabled;
// Get the text. Check if we have anything offline.
return this.assignOfflineProvider.getSubmission(this.assign.id).catch(() => {
// No offline data found.
}).then((offlineData) => {
if (offlineData && offlineData.plugindata && offlineData.plugindata.onlinetext_editor) {
return offlineData.plugindata.onlinetext_editor.text;
}
// No offline data found, return online text.
return this.assignProvider.getSubmissionPluginText(this.plugin, this.edit && !rteEnabled);
});
// No offline data found, return online text.
return this.assignProvider.getSubmissionPluginText(this.plugin);
}).then((text) => {
// We receive them as strings, convert to int.
this.configs.wordlimit = parseInt(this.configs.wordlimit, 10);

View File

@ -16,7 +16,6 @@
import { Injectable, Injector } from '@angular/core';
import { CoreSitesProvider } from '@providers/sites';
import { CoreWSProvider } from '@providers/ws';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { AddonModAssignProvider } from '../../../providers/assign';
import { AddonModAssignOfflineProvider } from '../../../providers/assign-offline';
@ -33,9 +32,8 @@ export class AddonModAssignSubmissionOnlineTextHandler implements AddonModAssign
type = 'onlinetext';
constructor(private sitesProvider: CoreSitesProvider, private wsProvider: CoreWSProvider,
private domUtils: CoreDomUtilsProvider, private textUtils: CoreTextUtilsProvider,
private assignProvider: AddonModAssignProvider, private assignOfflineProvider: AddonModAssignOfflineProvider,
private assignHelper: AddonModAssignHelperProvider) { }
private textUtils: CoreTextUtilsProvider, private assignProvider: AddonModAssignProvider,
private assignOfflineProvider: AddonModAssignOfflineProvider, private assignHelper: AddonModAssignHelperProvider) { }
/**
* Whether the plugin can be edited in offline for existing submissions. In general, this should return false if the
@ -238,19 +236,16 @@ export class AddonModAssignSubmissionOnlineTextHandler implements AddonModAssign
prepareSubmissionData(assign: any, submission: any, plugin: any, inputData: any, pluginData: any, offline?: boolean,
userId?: number, siteId?: string): void | Promise<any> {
return this.domUtils.isRichTextEditorEnabled().then((enabled) => {
let text = this.getTextToSubmit(plugin, inputData);
if (!enabled) {
// Rich text editor not enabled, add some HTML to the text if needed.
text = this.textUtils.formatHtmlLines(text);
}
let text = this.getTextToSubmit(plugin, inputData);
pluginData.onlinetext_editor = {
text: text,
format: 1,
itemid: 0 // Can't add new files yet, so we use a fake itemid.
};
});
// Add some HTML to the text if needed.
text = this.textUtils.formatHtmlLines(text);
pluginData.onlinetext_editor = {
text: text,
format: 1,
itemid: 0 // Can't add new files yet, so we use a fake itemid.
};
}
/**

View File

@ -15,7 +15,6 @@ import { Injector, Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
import { AddonModDataFieldTextHandler } from '../../text/providers/handler';
import { AddonModDataFieldTextareaComponent } from '../component/textarea';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreTextUtilsProvider } from '@providers/utils/text';
/**
@ -26,8 +25,7 @@ export class AddonModDataFieldTextareaHandler extends AddonModDataFieldTextHandl
name = 'AddonModDataFieldTextareaHandler';
type = 'textarea';
constructor(protected translate: TranslateService, private textUtils: CoreTextUtilsProvider,
private domUtils: CoreDomUtilsProvider) {
constructor(protected translate: TranslateService, private textUtils: CoreTextUtilsProvider) {
super(translate);
}
@ -54,31 +52,27 @@ export class AddonModDataFieldTextareaHandler extends AddonModDataFieldTextHandl
const fieldName = 'f_' + field.id;
if (inputData[fieldName]) {
return this.domUtils.isRichTextEditorEnabled().then((enabled) => {
const files = this.getFieldEditFiles(field, inputData, originalFieldData);
let text = this.textUtils.restorePluginfileUrls(inputData[fieldName], files);
const files = this.getFieldEditFiles(field, inputData, originalFieldData);
let text = this.textUtils.restorePluginfileUrls(inputData[fieldName], files);
if (!enabled) {
// Rich text editor not enabled, add some HTML to the text if needed.
text = this.textUtils.formatHtmlLines(text);
// Add some HTML to the text if needed.
text = this.textUtils.formatHtmlLines(text);
return [{
fieldid: field.id,
value: text
},
{
fieldid: field.id,
subfield: 'content1',
value: 1
},
{
fieldid: field.id,
subfield: 'itemid',
files: files
}
return [{
fieldid: field.id,
value: text
},
{
fieldid: field.id,
subfield: 'content1',
value: 1
},
{
fieldid: field.id,
subfield: 'itemid',
files: files
}
];
});
];
}
return false;

View File

@ -182,29 +182,29 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy {
const files = this.replyData.files || [];
const options: any = {};
const modal = this.domUtils.showModalLoading('core.sending', true);
let promise;
// Check if rich text editor is enabled or not.
this.domUtils.isRichTextEditorEnabled().then((enabled) => {
if (!enabled) {
// Rich text editor not enabled, add some HTML to the message if needed.
message = this.textUtils.formatHtmlLines(message);
}
// Add some HTML to the message if needed.
message = this.textUtils.formatHtmlLines(message);
// Upload attachments first if any.
if (files.length) {
return this.forumHelper.uploadOrStoreReplyFiles(this.forum.id, replyingTo, files, false).catch((error) => {
// Cannot upload them in online, save them in offline.
if (!this.forum.id) {
// Cannot store them in offline without the forum ID. Reject.
return Promise.reject(error);
}
// Upload attachments first if any.
if (files.length) {
promise = this.forumHelper.uploadOrStoreReplyFiles(this.forum.id, replyingTo, files, false).catch((error) => {
// Cannot upload them in online, save them in offline.
if (!this.forum.id) {
// Cannot store them in offline without the forum ID. Reject.
return Promise.reject(error);
}
saveOffline = true;
saveOffline = true;
return this.forumHelper.uploadOrStoreReplyFiles(this.forum.id, replyingTo, files, true);
});
}
}).then((attach) => {
return this.forumHelper.uploadOrStoreReplyFiles(this.forum.id, replyingTo, files, true);
});
} else {
promise = Promise.resolve();
}
promise.then((attach) => {
if (attach) {
options.attachmentsid = attach;
}

View File

@ -423,25 +423,25 @@ export class AddonModForumNewDiscussionPage implements OnDestroy {
}
const modal = this.domUtils.showModalLoading('core.sending', true);
let promise;
// Check if rich text editor is enabled or not.
this.domUtils.isRichTextEditorEnabled().then((enabled) => {
if (!enabled) {
// Rich text editor not enabled, add some HTML to the message if needed.
message = this.textUtils.formatHtmlLines(message);
}
// Add some HTML to the message if needed.
message = this.textUtils.formatHtmlLines(message);
// Upload attachments first if any.
if (attachments.length) {
return this.forumHelper.uploadOrStoreNewDiscussionFiles(this.forumId, discTimecreated, attachments, false)
.catch(() => {
// Cannot upload them in online, save them in offline.
saveOffline = true;
// Upload attachments first if any.
if (attachments.length) {
promise = this.forumHelper.uploadOrStoreNewDiscussionFiles(this.forumId, discTimecreated, attachments, false)
.catch(() => {
// Cannot upload them in online, save them in offline.
saveOffline = true;
return this.forumHelper.uploadOrStoreNewDiscussionFiles(this.forumId, discTimecreated, attachments, true);
});
}
}).then((attach) => {
return this.forumHelper.uploadOrStoreNewDiscussionFiles(this.forumId, discTimecreated, attachments, true);
});
} else {
promise = Promise.resolve();
}
promise.then((attach) => {
if (attach) {
options.attachmentsid = attach;
}

View File

@ -159,9 +159,10 @@ export class AddonModGlossaryEditPage implements OnInit {
* Save the entry.
*/
save(): void {
let definition = this.entry.definition;
let definition = this.entry.definition,
saveOffline = false,
promise;
const timecreated = this.entry.timecreated || Date.now();
let saveOffline = false;
if (!this.entry.concept || !definition) {
this.domUtils.showErrorModal('addon.mod_glossary.fillfields', true);
@ -171,25 +172,24 @@ export class AddonModGlossaryEditPage implements OnInit {
const modal = this.domUtils.showModalLoading('core.sending', true);
// Check if rich text editor is enabled or not.
this.domUtils.isRichTextEditorEnabled().then((enabled) => {
if (!enabled) {
// Rich text editor not enabled, add some HTML to the definition if needed.
definition = this.textUtils.formatHtmlLines(definition);
}
// Add some HTML to the definition if needed.
definition = this.textUtils.formatHtmlLines(definition);
// Upload attachments first if any.
if (this.attachments.length > 0) {
return this.glossaryHelper.uploadOrStoreFiles(this.glossary.id, this.entry.concept, timecreated, this.attachments,
false).catch(() => {
// Cannot upload them in online, save them in offline.
saveOffline = true;
// Upload attachments first if any.
if (this.attachments.length > 0) {
promise = this.glossaryHelper.uploadOrStoreFiles(this.glossary.id, this.entry.concept, timecreated, this.attachments,
false).catch(() => {
// Cannot upload them in online, save them in offline.
saveOffline = true;
return this.glossaryHelper.uploadOrStoreFiles(this.glossary.id, this.entry.concept, timecreated,
this.attachments, true);
});
}
}).then((attach) => {
return this.glossaryHelper.uploadOrStoreFiles(this.glossary.id, this.entry.concept, timecreated,
this.attachments, true);
});
} else {
promise = Promise.resolve();
}
promise.then((attach) => {
const options: any = {
aliases: this.options.aliases,
categories: this.options.categories.join(',')

View File

@ -611,9 +611,9 @@ export class AddonModLessonPlayerPage implements OnInit, OnDestroy {
this.loaded = false;
// Use getRawValue to include disabled values.
this.lessonHelper.prepareQuestionData(this.question, this.questionForm.getRawValue()).then((data) => {
return this.processPage(data);
}).finally(() => {
const data = this.lessonHelper.prepareQuestionData(this.question, this.questionForm.getRawValue());
this.processPage(data).finally(() => {
this.loaded = true;
});
}

View File

@ -452,19 +452,12 @@ export class AddonModLessonHelperProvider {
*
* @param {any} question Question to prepare.
* @param {any} data Data to prepare.
* @return {Promise<any>} Promise resolved with the data to send when done.
* @return {any} Data to send.
*/
prepareQuestionData(question: any, data: any): Promise<any> {
prepareQuestionData(question: any, data: any): any {
if (question.template == 'essay' && question.textarea) {
// The answer might need formatting. Check if rich text editor is enabled or not.
return this.domUtils.isRichTextEditorEnabled().then((enabled) => {
if (!enabled) {
// Rich text editor not enabled, add some HTML to the answer if needed.
data[question.textarea.property] = this.textUtils.formatHtmlLines(data[question.textarea.property]);
}
return data;
});
// Add some HTML to the answer if needed.
data[question.textarea.property] = this.textUtils.formatHtmlLines(data[question.textarea.property]);
} else if (question.template == 'multichoice' && question.multi) {
// Only send the options with value set to true.
for (const name in data) {
@ -474,7 +467,7 @@ export class AddonModLessonHelperProvider {
}
}
return Promise.resolve(data);
return data;
}
/**

View File

@ -58,7 +58,6 @@ export class AddonModWikiEditPage implements OnInit, OnDestroy {
protected blockId: string; // ID to block the subwiki.
protected editing: boolean; // Whether the user is editing a page (true) or creating a new one (false).
protected editOffline: boolean; // Whether the user is editing an offline page.
protected rteEnabled: boolean; // Whether rich text editor is enabled.
protected subwikiFiles: any[]; // List of files of the subwiki.
protected originalContent: string; // The original page content.
protected version: number; // Page version.
@ -151,15 +150,8 @@ export class AddonModWikiEditPage implements OnInit, OnDestroy {
// Wait for sync to be over (if any).
return this.wikiSync.waitForSync(this.blockId);
}).then(() => {
// Check if rich text editor is enabled.
return this.domUtils.isRichTextEditorEnabled();
}).then((enabled) => {
this.rteEnabled = enabled;
if (enabled) {
// Get subwiki files, needed to replace URLs for rich text editor.
return this.wikiProvider.getSubwikiFiles(this.wikiId, this.groupId, this.userId);
}
// Get subwiki files, needed to replace URLs for rich text editor.
return this.wikiProvider.getSubwikiFiles(this.wikiId, this.groupId, this.userId);
}).then((files) => {
this.subwikiFiles = files;
@ -167,8 +159,7 @@ export class AddonModWikiEditPage implements OnInit, OnDestroy {
return this.wikiProvider.getPageForEditing(this.pageId, this.section);
}).then((editContents) => {
// Get the original page contents, treating file URLs if needed.
const content = this.rteEnabled ? this.textUtils.replacePluginfileUrls(editContents.content, this.subwikiFiles) :
editContents.content;
const content = this.textUtils.replacePluginfileUrls(editContents.content, this.subwikiFiles);
this.contentControl.setValue(content);
this.originalContent = content;
@ -411,11 +402,8 @@ export class AddonModWikiEditPage implements OnInit, OnDestroy {
let promise,
text = values.text;
if (this.rteEnabled) {
text = this.textUtils.restorePluginfileUrls(text, this.subwikiFiles);
} else {
text = this.textUtils.formatHtmlLines(text);
}
text = this.textUtils.restorePluginfileUrls(text, this.subwikiFiles);
text = this.textUtils.formatHtmlLines(text);
if (this.editing) {
// Edit existing page.

View File

@ -64,7 +64,6 @@ export class AddonModWorkshopAssessmentStrategyComponent implements OnInit {
weights: any[];
weight: number;
protected rteEnabled: boolean;
protected obsInvalidated: any;
protected hasOffline: boolean;
protected originalData = {
@ -117,24 +116,13 @@ export class AddonModWorkshopAssessmentStrategyComponent implements OnInit {
}
}
let promise;
// Check if rich text editor is enabled.
if (this.edit) {
// Block the workshop.
this.syncProvider.blockOperation(AddonModWorkshopProvider.COMPONENT, this.workshop.id);
promise = this.domUtils.isRichTextEditorEnabled();
} else {
// We aren't editing, so no rich text editor.
promise = Promise.resolve(false);
}
promise.then((enabled) => {
this.rteEnabled = enabled;
return this.load();
}).then(() => {
this.load().then(() => {
this.obsInvalidated = this.eventsProvider.on(AddonModWorkshopProvider.ASSESSMENT_INVALIDATED,
this.load.bind(this), this.sitesProvider.getCurrentSiteId());
}).finally(() => {

View File

@ -331,21 +331,16 @@ export class AddonModWorkshopAssessmentPage implements OnInit, OnDestroy {
* @return {Promise<any>} Resolved when done.
*/
protected sendEvaluation(): Promise<any> {
const modal = this.domUtils.showModalLoading('core.sending', true);
const modal = this.domUtils.showModalLoading('core.sending', true),
inputData = this.evaluateForm.value;
// Check if rich text editor is enabled or not.
return this.domUtils.isRichTextEditorEnabled().then((rteEnabled) => {
const inputData = this.evaluateForm.value;
inputData.grade = inputData.grade >= 0 ? inputData.grade : '';
if (!rteEnabled) {
// Rich text editor not enabled, add some HTML to the message if needed.
inputData.text = this.textUtils.formatHtmlLines(inputData.text);
}
inputData.grade = inputData.grade >= 0 ? inputData.grade : '';
// Add some HTML to the message if needed.
inputData.text = this.textUtils.formatHtmlLines(inputData.text);
// Try to send it to server.
return this.workshopProvider.evaluateAssessment(this.workshopId, this.assessmentId, this.courseId, inputData.text,
inputData.weight, inputData.grade);
}).then(() => {
// Try to send it to server.
return this.workshopProvider.evaluateAssessment(this.workshopId, this.assessmentId, this.courseId, inputData.text,
inputData.weight, inputData.grade).then(() => {
const data = {
workshopId: this.workshopId,
assessmentId: this.assessmentId,

View File

@ -312,25 +312,20 @@ export class AddonModWorkshopEditSubmissionPage implements OnInit, OnDestroy {
const modal = this.domUtils.showModalLoading('core.sending', true),
submissionId = this.submission.id;
// Check if rich text editor is enabled or not.
return this.domUtils.isRichTextEditorEnabled().then((rteEnabled) => {
if (!rteEnabled) {
// Rich text editor not enabled, add some HTML to the message if needed.
inputData.content = this.textUtils.formatHtmlLines(inputData.content);
}
// Add some HTML to the message if needed.
inputData.content = this.textUtils.formatHtmlLines(inputData.content);
// Upload attachments first if any.
allowOffline = !inputData.attachmentfiles.length;
// Upload attachments first if any.
allowOffline = !inputData.attachmentfiles.length;
return this.workshopHelper.uploadOrStoreSubmissionFiles(this.workshopId, this.submission.id, inputData.attachmentfiles,
this.editing, saveOffline).catch(() => {
// Cannot upload them in online, save them in offline.
saveOffline = true;
allowOffline = true;
return this.workshopHelper.uploadOrStoreSubmissionFiles(this.workshopId, this.submission.id, inputData.attachmentfiles,
this.editing, saveOffline).catch(() => {
// Cannot upload them in online, save them in offline.
saveOffline = true;
allowOffline = true;
return this.workshopHelper.uploadOrStoreSubmissionFiles(this.workshopId, this.submission.id,
inputData.attachmentfiles, this.editing, saveOffline);
});
return this.workshopHelper.uploadOrStoreSubmissionFiles(this.workshopId, this.submission.id,
inputData.attachmentfiles, this.editing, saveOffline);
}).then((attachmentsId) => {
if (this.editing) {
if (saveOffline) {

View File

@ -430,20 +430,15 @@ export class AddonModWorkshopSubmissionPage implements OnInit, OnDestroy {
protected sendEvaluation(): Promise<any> {
const modal = this.domUtils.showModalLoading('core.sending', true);
// Check if rich text editor is enabled or not.
return this.domUtils.isRichTextEditorEnabled().then((rteEnabled) => {
const inputData = this.feedbackForm.value;
const inputData = this.feedbackForm.value;
inputData.grade = inputData.grade >= 0 ? inputData.grade : '';
if (!rteEnabled) {
// Rich text editor not enabled, add some HTML to the message if needed.
inputData.text = this.textUtils.formatHtmlLines(inputData.text);
}
inputData.grade = inputData.grade >= 0 ? inputData.grade : '';
// Add some HTML to the message if needed.
inputData.text = this.textUtils.formatHtmlLines(inputData.text);
// Try to send it to server.
return this.workshopProvider.evaluateSubmission(this.workshopId, this.submissionId, this.courseId, inputData.text,
inputData.published, inputData.grade);
}).then(() => {
// Try to send it to server.
return this.workshopProvider.evaluateSubmission(this.workshopId, this.submissionId, this.courseId, inputData.text,
inputData.published, inputData.grade).then(() => {
const data = {
workshopId: this.workshopId,
cmId: this.module.cmid,

View File

@ -14,7 +14,6 @@
// limitations under the License.
import { Injectable, Injector } from '@angular/core';
import { CoreDomUtilsProvider } from '@providers/utils/dom';
import { CoreTextUtilsProvider } from '@providers/utils/text';
import { CoreUtilsProvider } from '@providers/utils/utils';
import { CoreQuestionHandler } from '@core/question/providers/delegate';
@ -32,7 +31,7 @@ export class AddonQtypeEssayHandler implements CoreQuestionHandler {
protected div = document.createElement('div'); // A div element to search in HTML code.
constructor(private utils: CoreUtilsProvider, private questionHelper: CoreQuestionHelperProvider,
private domUtils: CoreDomUtilsProvider, private textUtils: CoreTextUtilsProvider) { }
private textUtils: CoreTextUtilsProvider) { }
/**
* Return the name of the behaviour to use for the question.
@ -148,12 +147,8 @@ export class AddonQtypeEssayHandler implements CoreQuestionHandler {
const textarea = <HTMLTextAreaElement> this.div.querySelector('textarea[name*=_answer]');
if (textarea && typeof answers[textarea.name] != 'undefined') {
return this.domUtils.isRichTextEditorEnabled().then((enabled) => {
if (!enabled) {
// Rich text editor not enabled, add some HTML to the text if needed.
answers[textarea.name] = this.textUtils.formatHtmlLines(answers[textarea.name]);
}
});
// Add some HTML to the text if needed.
answers[textarea.name] = this.textUtils.formatHtmlLines(answers[textarea.name]);
}
}
}

View File

@ -23,7 +23,7 @@
<div [hidden]="rteEnabled">
<ion-textarea #textarea class="core-textarea" [placeholder]="placeholder" [attr.name]="name" ngControl="control" (ionChange)="onChange($event)"></ion-textarea>
<div class="core-rte-toolbar">
<div class="core-rte-toolbar" [hidden]="!editorSupported">
<div #decorate class="core-rte-buttons">
<button tappable (click)="toggleEditor($event)"><core-icon name="fa-pencil-square-o"></core-icon> {{ 'core.vieweditor' | translate }}</button>
</div>

View File

@ -103,6 +103,7 @@ core-rich-text-editor {
border-right: 1px solid $gray-dark;
border-bottom: 1px solid $gray-dark;
flex-grow: 1;
margin: 0;
}
}
}

View File

@ -63,6 +63,7 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
protected valueChangeSubscription: Subscription;
rteEnabled = false;
editorSupported = true;
constructor(private domUtils: CoreDomUtilsProvider, private keyboard: Keyboard, private urlUtils: CoreUrlUtilsProvider,
private sitesProvider: CoreSitesProvider, private filepoolProvider: CoreFilepoolProvider,
@ -79,6 +80,8 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
this.rteEnabled = !!enabled;
});
this.editorSupported = this.domUtils.isRichTextEditorSupported();
// Setup the editor.
this.editorElement = this.editor.nativeElement as HTMLDivElement;
this.editorElement.innerHTML = this.control.value;
@ -169,11 +172,12 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
while (element.parentNode && element.parentNode.tagName != 'ION-CONTENT') {
const parent = element.parentNode;
if (element.tagName && element.tagName != 'CORE-LOADING') {
parent.childNodes.forEach((child) => {
for (let x = 0; x < parent.childNodes.length; x++) {
const child = parent.childNodes[x];
if (child.tagName && child != element) {
height += this.domUtils.getElementHeight(child, false, true, true);
}
});
}
}
element = parent;
}
@ -368,8 +372,8 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
}
setTimeout(() => {
this.keyboard.show();
}, 1);
}, 1);
});
});
}
/**
@ -445,6 +449,17 @@ export class CoreRichTextEditorComponent implements AfterContentInit, OnDestroy
$event.preventDefault();
$event.stopPropagation();
document.execCommand(command, false, parameters);
setTimeout(() => {
if (this.rteEnabled) {
this.editorElement.focus();
} else {
this.textarea.setFocus();
}
setTimeout(() => {
this.keyboard.show();
});
});
}
/**

View File

@ -19,7 +19,7 @@
"displayformat": "Display format",
"enabledownloadsection": "Enable download sections",
"enablerichtexteditor": "Enable text editor",
"enablerichtexteditordescription": "If enabled, a text editor will be available when entering content.",
"enablerichtexteditordescription": "If enabled, a rich text editor will be shown when entering content. If disabled, plain text editor will be shown. You can toggle between both while editing.",
"enablesyncwifi": "Allow sync only when on Wi-Fi",
"errordeletesitefiles": "Error deleting site files.",
"errorsyncsite": "Error synchronising site data. Please check your Internet connection and try again.",

View File

@ -546,8 +546,7 @@ export class CoreDomUtilsProvider {
* @return {boolean} Whether it's supported.
*/
isRichTextEditorSupported(): boolean {
// Disabled just for iOS.
return !this.platform.is('ios');
return true;
}
/**