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.
*