From d20e2e057ef03286fcbff0e0d04a5d58b4b85643 Mon Sep 17 00:00:00 2001 From: Albert Gasset Date: Mon, 22 Jul 2019 14:07:22 +0200 Subject: [PATCH 1/3] MOBILE-3086 data: Handle links in templates --- src/addon/mod/data/components/index/index.ts | 6 ++-- src/addon/mod/data/pages/edit/edit.ts | 2 +- src/addon/mod/data/pages/entry/entry.ts | 2 +- src/addon/mod/data/pages/search/search.ts | 2 +- src/addon/mod/data/providers/helper.ts | 35 ++++++++++++++++---- 5 files changed, 35 insertions(+), 12 deletions(-) diff --git a/src/addon/mod/data/components/index/index.ts b/src/addon/mod/data/components/index/index.ts index 37a806f43..69d6fdcbf 100644 --- a/src/addon/mod/data/components/index/index.ts +++ b/src/addon/mod/data/components/index/index.ts @@ -299,14 +299,14 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp if (!this.isEmpty) { this.entries = entries.offlineEntries.concat(entries.entries); - let entriesHTML = this.data.listtemplateheader || ''; + let entriesHTML = this.dataHelper.getTemplate(this.data, 'listtemplateheader', this.fieldsArray); // Get first entry from the whole list. if (!this.search.searching || !this.firstEntry) { this.firstEntry = this.entries[0].id; } - const template = this.data.listtemplate || this.dataHelper.getDefaultTemplate('list', this.fieldsArray); + const template = this.dataHelper.getTemplate(this.data, 'listtemplate', this.fieldsArray); const entriesById = {}; this.entries.forEach((entry, index) => { @@ -318,7 +318,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp entriesHTML += this.dataHelper.displayShowFields(template, this.fieldsArray, entry, offset, 'list', actions); }); - entriesHTML += this.data.listtemplatefooter || ''; + entriesHTML += this.dataHelper.getTemplate(this.data, 'listtemplatefooter', this.fieldsArray); this.entriesRendered = entriesHTML; diff --git a/src/addon/mod/data/pages/edit/edit.ts b/src/addon/mod/data/pages/edit/edit.ts index 35e74cd06..52025cfa3 100644 --- a/src/addon/mod/data/pages/edit/edit.ts +++ b/src/addon/mod/data/pages/edit/edit.ts @@ -287,7 +287,7 @@ export class AddonModDataEditPage { let replace, render, - template = this.data.addtemplate || this.dataHelper.getDefaultTemplate('add', this.fieldsArray); + template = this.dataHelper.getTemplate(this.data, 'addtemplate', this.fieldsArray); // Replace the fields found on template. this.fieldsArray.forEach((field) => { diff --git a/src/addon/mod/data/pages/entry/entry.ts b/src/addon/mod/data/pages/entry/entry.ts index 51e95ce9c..b8c7da5dd 100644 --- a/src/addon/mod/data/pages/entry/entry.ts +++ b/src/addon/mod/data/pages/entry/entry.ts @@ -163,7 +163,7 @@ export class AddonModDataEntryPage implements OnDestroy { }).then(() => { const actions = this.dataHelper.getActions(this.data, this.access, this.entry); - const template = this.data.singletemplate || this.dataHelper.getDefaultTemplate('single', this.fieldsArray); + const template = this.dataHelper.getTemplate(this.data, 'singletemplate', this.fieldsArray); this.entryHtml = this.dataHelper.displayShowFields(template, this.fieldsArray, this.entry, this.offset, 'show', actions); this.showComments = actions.comments; diff --git a/src/addon/mod/data/pages/search/search.ts b/src/addon/mod/data/pages/search/search.ts index 4ca20b5d0..036f517b7 100644 --- a/src/addon/mod/data/pages/search/search.ts +++ b/src/addon/mod/data/pages/search/search.ts @@ -89,7 +89,7 @@ export class AddonModDataSearchPage { search: this.search.advanced }; - let template = this.data.asearchtemplate || this.dataHelper.getDefaultTemplate('asearch', this.fieldsArray), + let template = this.dataHelper.getTemplate(this.data, 'asearchtemplate', this.fieldsArray), replace, render; // Replace the fields found on template. diff --git a/src/addon/mod/data/providers/helper.ts b/src/addon/mod/data/providers/helper.ts index b5aaadcec..e68275545 100644 --- a/src/addon/mod/data/providers/helper.ts +++ b/src/addon/mod/data/providers/helper.ts @@ -410,10 +410,14 @@ export class AddonModDataHelperProvider { * @param {any[]} fields List of database fields. * @return {string} Template HTML. */ - getDefaultTemplate( type: 'add' | 'list' | 'single' | 'asearch', fields: any[]): string { + getDefaultTemplate(type: string, fields: any[]): string { + if (type == 'listtemplateheader' || type == 'listtemplatefooter') { + return ''; + } + const html = []; - if (type == 'list') { + if (type == 'listtemplate') { html.push('##delcheck##
'); } @@ -432,7 +436,7 @@ export class AddonModDataHelperProvider { ); }); - if (type == 'list') { + if (type == 'listtemplate') { html.push( '', '', @@ -440,7 +444,7 @@ export class AddonModDataHelperProvider { '', '' ); - } else if (type == 'single') { + } else if (type == 'singletemplate') { html.push( '', '', @@ -448,7 +452,7 @@ export class AddonModDataHelperProvider { '', '' ); - } else if (type == 'asearch') { + } else if (type == 'asearchtemplate') { html.push( '', 'Author first name: ', @@ -467,7 +471,7 @@ export class AddonModDataHelperProvider { '' ); - if (type == 'list') { + if (type == 'listtemplate') { html.push('
'); } @@ -583,6 +587,25 @@ export class AddonModDataHelperProvider { }); } + /** + * Returns the template of a certain type. + * + * @param {any} data Database object. + * @param {string} type Type of template. + * @param {any[]} fields List of database fields. + * @return {string} Template HTML. + */ + getTemplate(data: any, type: string, fields: any[]): string { + let template = data[type] || this.getDefaultTemplate(type, fields); + + // Add core-link directive to links. + template = template.replace(/]*href="[^>]*)>/i, (match, attributes) => { + return ''; + }); + + return template; + } + /** * Check if data has been changed by the user. * From 3788afe8b343c1622b8dfd01f12b666b8d8d6821 Mon Sep 17 00:00:00 2001 From: Albert Gasset Date: Mon, 22 Jul 2019 14:08:33 +0200 Subject: [PATCH 2/3] MOBILE-3086 data: Fix syntax errors in templates --- src/addon/mod/data/providers/helper.ts | 3 +++ src/providers/utils/dom.ts | 27 ++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/addon/mod/data/providers/helper.ts b/src/addon/mod/data/providers/helper.ts index e68275545..a425a5cc6 100644 --- a/src/addon/mod/data/providers/helper.ts +++ b/src/addon/mod/data/providers/helper.ts @@ -598,6 +598,9 @@ export class AddonModDataHelperProvider { getTemplate(data: any, type: string, fields: any[]): string { let template = data[type] || this.getDefaultTemplate(type, fields); + // Try to fix syntax errors so the template can be parsed by Angular. + template = this.domUtils.fixHtml(template); + // Add core-link directive to links. template = template.replace(/]*href="[^>]*)>/i, (match, attributes) => { return ''; diff --git a/src/providers/utils/dom.ts b/src/providers/utils/dom.ts index 24374f3cd..4a9ad7ed6 100644 --- a/src/providers/utils/dom.ts +++ b/src/providers/utils/dom.ts @@ -323,6 +323,33 @@ export class CoreDomUtilsProvider { return urls; } + /** + * Fix syntax errors in HTML. + * + * @param {string} html HTML text. + * @return {string} Fixed HTML text. + */ + fixHtml(html: string): string { + this.template.innerHTML = html; + + const attrNameRegExp = /[^\x00-\x20\x7F-\x9F"'>\/=]+/; + + const fixElement = (element: Element): void => { + // Remove attributes with an invalid name. + Array.from(element.attributes).forEach((attr) => { + if (!attrNameRegExp.test(attr.name)) { + element.removeAttributeNode(attr); + } + }); + + Array.from(element.children).forEach(fixElement); + }; + + Array.from(this.template.content.children).forEach(fixElement); + + return this.template.innerHTML; + } + /** * Focus an element and open keyboard. * From ab3c15d9b7ccdf06a37156a1d50af859d5958f48 Mon Sep 17 00:00:00 2001 From: Albert Gasset Date: Mon, 22 Jul 2019 15:49:11 +0200 Subject: [PATCH 3/3] MOBILE-3089 android: Allow non-secure HTTP --- config.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/config.xml b/config.xml index 211280ed8..744ea653e 100644 --- a/config.xml +++ b/config.xml @@ -147,6 +147,9 @@ + + +