Browse Source

escape block attributes in patterns utility (#6281)

* extend support for escaping block attributes in patterns utility

* separate real attrs to escape differently
Madhu Dollu 3 years ago
parent
commit
2775cea2b5
1 changed files with 40 additions and 3 deletions
  1. 40 3
      theme-utils.mjs

+ 40 - 3
theme-utils.mjs

@@ -1179,16 +1179,53 @@ async function escapePatterns() {
 				});
 				});
 			}
 			}
 
 
-			if (startTag.tagName === 'p') {
-				console.log({tag: startTag, rawHtml})
-			}
 
 
 			rewriter.emitStartTag(startTag);
 			rewriter.emitStartTag(startTag);
 		});
 		});
 
 
+		rewriter.on('comment', (comment, rawHtml) => {
+			if (comment.text.startsWith('?php')) {
+				rewriter.emitRaw(rawHtml);
+				return;
+			}
+			// escape the strings in block config (blocks that are represented as comments)
+			// ex: <!-- wp:search {label: "Search"} /-->
+			const block = escapeBlockAttrs(comment.text, themeSlug)
+			rewriter.emitComment({...comment, text: block})
+		});
+
 		return rewriter;
 		return rewriter;
 	}
 	}
 
 
+	function escapeBlockAttrs(block, themeSlug) {
+		// Set isAttr to true if it is an attribute in the result HTML
+		// If set to true, it generates esc_attr_, otherwise it generates esc_html_
+		const allowedAttrs=[
+			{ name: 'label' },
+			{ name: 'placeholder', isAttr: true },
+			{ name: 'buttonText' },
+			{ name: 'content' }
+		];
+		const start = block.indexOf('{');
+		const end = block.lastIndexOf('}');
+		
+		const configPrefix = block.slice(0, start);
+		const config = block.slice(start, end+1);
+		const configSuffix = block.slice(end+1);
+
+		try {
+			const configJson = JSON.parse(config);
+			allowedAttrs.forEach((attr) => {
+				if (!configJson[attr.name]) return;
+				configJson[attr.name] = escapeText(configJson[attr.name], themeSlug, attr.isAttr)
+			})
+			return configPrefix + JSON.stringify(configJson) + configSuffix;
+		} catch (error) {
+			// do nothing
+			return block
+		}
+	}
+
 	function escapeText(text, themeSlug, isAttr = false) {
 	function escapeText(text, themeSlug, isAttr = false) {
 		const trimmedText = text && text.trim();
 		const trimmedText = text && text.trim();
 		if (!themeSlug || !trimmedText || trimmedText.startsWith(`<?php`)) return text;
 		if (!themeSlug || !trimmedText || trimmedText.startsWith(`<?php`)) return text;