commit
5f9192f21a
|
@ -147,6 +147,9 @@
|
||||||
<edit-config file="AndroidManifest.xml" mode="merge" target="/manifest/application/activity[@android:name='MainActivity']">
|
<edit-config file="AndroidManifest.xml" mode="merge" target="/manifest/application/activity[@android:name='MainActivity']">
|
||||||
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|screenLayout|smallestScreenSize" android:debuggable="true" />
|
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|screenLayout|smallestScreenSize" android:debuggable="true" />
|
||||||
</edit-config>
|
</edit-config>
|
||||||
|
<edit-config file="AndroidManifest.xml" mode="merge" target="/manifest/application">
|
||||||
|
<application android:usesCleartextTraffic="true" />
|
||||||
|
</edit-config>
|
||||||
<config-file parent="/manifest/application" target="AndroidManifest.xml">
|
<config-file parent="/manifest/application" target="AndroidManifest.xml">
|
||||||
<meta-data android:name="firebase_analytics_collection_deactivated" android:value="true" />
|
<meta-data android:name="firebase_analytics_collection_deactivated" android:value="true" />
|
||||||
</config-file>
|
</config-file>
|
||||||
|
|
|
@ -299,14 +299,14 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
|
||||||
if (!this.isEmpty) {
|
if (!this.isEmpty) {
|
||||||
this.entries = entries.offlineEntries.concat(entries.entries);
|
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.
|
// Get first entry from the whole list.
|
||||||
if (!this.search.searching || !this.firstEntry) {
|
if (!this.search.searching || !this.firstEntry) {
|
||||||
this.firstEntry = this.entries[0].id;
|
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 = {};
|
const entriesById = {};
|
||||||
this.entries.forEach((entry, index) => {
|
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.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;
|
this.entriesRendered = entriesHTML;
|
||||||
|
|
||||||
|
|
|
@ -287,7 +287,7 @@ export class AddonModDataEditPage {
|
||||||
|
|
||||||
let replace,
|
let replace,
|
||||||
render,
|
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.
|
// Replace the fields found on template.
|
||||||
this.fieldsArray.forEach((field) => {
|
this.fieldsArray.forEach((field) => {
|
||||||
|
|
|
@ -163,7 +163,7 @@ export class AddonModDataEntryPage implements OnDestroy {
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
const actions = this.dataHelper.getActions(this.data, this.access, this.entry);
|
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',
|
this.entryHtml = this.dataHelper.displayShowFields(template, this.fieldsArray, this.entry, this.offset, 'show',
|
||||||
actions);
|
actions);
|
||||||
this.showComments = actions.comments;
|
this.showComments = actions.comments;
|
||||||
|
|
|
@ -89,7 +89,7 @@ export class AddonModDataSearchPage {
|
||||||
search: this.search.advanced
|
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, render;
|
||||||
|
|
||||||
// Replace the fields found on template.
|
// Replace the fields found on template.
|
||||||
|
|
|
@ -410,10 +410,14 @@ export class AddonModDataHelperProvider {
|
||||||
* @param {any[]} fields List of database fields.
|
* @param {any[]} fields List of database fields.
|
||||||
* @return {string} Template HTML.
|
* @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 = [];
|
const html = [];
|
||||||
|
|
||||||
if (type == 'list') {
|
if (type == 'listtemplate') {
|
||||||
html.push('##delcheck##<br />');
|
html.push('##delcheck##<br />');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -432,7 +436,7 @@ export class AddonModDataHelperProvider {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (type == 'list') {
|
if (type == 'listtemplate') {
|
||||||
html.push(
|
html.push(
|
||||||
'<tr class="lastrow">',
|
'<tr class="lastrow">',
|
||||||
'<td class="controls template-field cell c0 lastcol" style="" colspan="2">',
|
'<td class="controls template-field cell c0 lastcol" style="" colspan="2">',
|
||||||
|
@ -440,7 +444,7 @@ export class AddonModDataHelperProvider {
|
||||||
'</td>',
|
'</td>',
|
||||||
'</tr>'
|
'</tr>'
|
||||||
);
|
);
|
||||||
} else if (type == 'single') {
|
} else if (type == 'singletemplate') {
|
||||||
html.push(
|
html.push(
|
||||||
'<tr class="lastrow">',
|
'<tr class="lastrow">',
|
||||||
'<td class="controls template-field cell c0 lastcol" style="" colspan="2">',
|
'<td class="controls template-field cell c0 lastcol" style="" colspan="2">',
|
||||||
|
@ -448,7 +452,7 @@ export class AddonModDataHelperProvider {
|
||||||
'</td>',
|
'</td>',
|
||||||
'</tr>'
|
'</tr>'
|
||||||
);
|
);
|
||||||
} else if (type == 'asearch') {
|
} else if (type == 'asearchtemplate') {
|
||||||
html.push(
|
html.push(
|
||||||
'<tr class="searchcontrols">',
|
'<tr class="searchcontrols">',
|
||||||
'<td class="template-field cell c0" style="">Author first name: </td>',
|
'<td class="template-field cell c0" style="">Author first name: </td>',
|
||||||
|
@ -467,7 +471,7 @@ export class AddonModDataHelperProvider {
|
||||||
'</div>'
|
'</div>'
|
||||||
);
|
);
|
||||||
|
|
||||||
if (type == 'list') {
|
if (type == 'listtemplate') {
|
||||||
html.push('<hr />');
|
html.push('<hr />');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -583,6 +587,28 @@ 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);
|
||||||
|
|
||||||
|
// 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(/<a ([^>]*href="[^>]*)>/i, (match, attributes) => {
|
||||||
|
return '<a core-link capture="true" ' + attributes + '>';
|
||||||
|
});
|
||||||
|
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if data has been changed by the user.
|
* Check if data has been changed by the user.
|
||||||
*
|
*
|
||||||
|
|
|
@ -323,6 +323,33 @@ export class CoreDomUtilsProvider {
|
||||||
return urls;
|
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.
|
* Focus an element and open keyboard.
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue