mirror of
https://github.com/Jermolene/TiddlyWiki5.git
synced 2025-12-05 18:20:38 -08:00
Revert "Fix 8166 html tag validation (#8176)"
This reverts commit 9a5f4cc0ef.
This commit is contained in:
parent
9a5f4cc0ef
commit
89233c558c
12 changed files with 47 additions and 67 deletions
|
|
@ -34,15 +34,3 @@ exports.htmlVoidElements = "area,base,br,col,command,embed,hr,img,input,keygen,l
|
|||
exports.htmlBlockElements = "address,article,aside,audio,blockquote,canvas,dd,details,div,dl,dt,fieldset,figcaption,figure,footer,form,h1,h2,h3,h4,h5,h6,header,hgroup,hr,li,nav,ol,p,pre,section,summary,table,tfoot,ul,video".split(",");
|
||||
|
||||
exports.htmlUnsafeElements = "script".split(",");
|
||||
|
||||
// Custom Web Components: https://html.spec.whatwg.org/#valid-custom-element-name
|
||||
exports.htmlForbiddenTags = "annotation-xml,color-profile,font-face,font-face-src,font-face-uri,font-face-format,font-face-name,missing-glyph".split(",");
|
||||
|
||||
// (EBNF notation) - PotentialCustomElementName ::= [a-z] (PCENChar)* '-' (PCENChar)*
|
||||
// Unicode table with ranges see: https://symbl.cc/en/unicode-table
|
||||
exports.htmlCustomPrimitives = {
|
||||
prefix: "[a-z]",
|
||||
validPCENChar: ".|[0-9]|_|[a-z]|\xB7|[\xC0-\xD6]|[\xD8-\xF6]|[\u00F8-\u037D]|[\u037F-\u1FFF]|[\u200C-\u200D]|[\u203F-\u2040]|[\u2070-\u218F]|[\u2C00-\u2FEF]|[\u3001-\uD7FF]|[\uF900-\uFDCF]|[\uFDF0-\uFFFD]",
|
||||
sanitizePCENChar: "[\x00-\x2C]|\x2F|[\x3A-\x40]|[\x5B-\x60]|[\x7B-\xB6]|[\xB8-\xBF]|\xD7|\xF7|\x37E|[\u2000\u200B]|[\u200E-\u203E]|[\u2041-\u206F]|[\u2190-\u2BFF]|[\u2FF0-\u3000]|[\uD800-\uF8FF]|[\uFDD0-\uFDEF]|[\uFFFE-\uFFFF]"
|
||||
};
|
||||
exports.htmlCustomPrimitives.nonValidPCENChar = "[A-Z]|" + exports.htmlCustomPrimitives.sanitizePCENChar;
|
||||
|
|
|
|||
|
|
@ -45,7 +45,10 @@ function FramedEngine(options) {
|
|||
this.iframeDoc.body.style.padding = "0";
|
||||
this.widget.domNodes.push(this.iframeNode);
|
||||
// Construct the textarea or input node
|
||||
var tag = $tw.utils.makeTagNameSafe(this.widget.editTag,"input");
|
||||
var tag = this.widget.editTag;
|
||||
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
|
||||
tag = "input";
|
||||
}
|
||||
this.domNode = this.iframeDoc.createElement(tag);
|
||||
// Set the text
|
||||
if(this.widget.editTag === "textarea") {
|
||||
|
|
@ -194,7 +197,7 @@ FramedEngine.prototype.handleFocusEvent = function(event) {
|
|||
Handle a keydown event
|
||||
*/
|
||||
FramedEngine.prototype.handleKeydownEvent = function(event) {
|
||||
if($tw.keyboardManager.handleKeydownEvent(event, {onlyPriority: true})) {
|
||||
if ($tw.keyboardManager.handleKeydownEvent(event, {onlyPriority: true})) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,10 @@ function SimpleEngine(options) {
|
|||
this.parentNode = options.parentNode;
|
||||
this.nextSibling = options.nextSibling;
|
||||
// Construct the textarea or input node
|
||||
var tag = $tw.utils.makeTagNameSafe(this.widget.editTag,"input");
|
||||
var tag = this.widget.editTag;
|
||||
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
|
||||
tag = "input";
|
||||
}
|
||||
this.domNode = this.widget.document.createElement(tag);
|
||||
// Set the text
|
||||
if(this.widget.editTag === "textarea") {
|
||||
|
|
|
|||
|
|
@ -306,13 +306,13 @@ Collect DOM variables
|
|||
*/
|
||||
exports.collectDOMVariables = function(selectedNode,domNode,event) {
|
||||
var variables = {},
|
||||
selectedNodeRect,
|
||||
domNodeRect;
|
||||
selectedNodeRect,
|
||||
domNodeRect;
|
||||
if(selectedNode) {
|
||||
$tw.utils.each(selectedNode.attributes,function(attribute) {
|
||||
variables["dom-" + attribute.name] = attribute.value.toString();
|
||||
});
|
||||
|
||||
|
||||
if("offsetLeft" in selectedNode) {
|
||||
// Add variables with a (relative and absolute) popup coordinate string for the selected node
|
||||
var nodeRect = {
|
||||
|
|
@ -337,7 +337,7 @@ exports.collectDOMVariables = function(selectedNode,domNode,event) {
|
|||
variables["tv-selectednode-height"] = selectedNode.offsetHeight.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(domNode && ("offsetWidth" in domNode)) {
|
||||
variables["tv-widgetnode-width"] = domNode.offsetWidth.toString();
|
||||
variables["tv-widgetnode-height"] = domNode.offsetHeight.toString();
|
||||
|
|
@ -366,7 +366,7 @@ exports.collectDOMVariables = function(selectedNode,domNode,event) {
|
|||
};
|
||||
|
||||
/*
|
||||
Make sure the CSS selector is valid
|
||||
Make sure the CSS selector is not invalid
|
||||
*/
|
||||
exports.querySelectorSafe = function(selector,baseElement) {
|
||||
baseElement = baseElement || document;
|
||||
|
|
@ -385,37 +385,3 @@ exports.querySelectorAllSafe = function(selector,baseElement) {
|
|||
console.log("Invalid selector: ",selector);
|
||||
}
|
||||
};
|
||||
|
||||
/*
|
||||
Sanitize HTML tag- and custom web component names
|
||||
Check function parameters for invalid character ranges up to \uFFFF. This detects problems in a range JS RegExp can handle
|
||||
We assume that everything out of js RegExp-range is valid, which is OK for \u10000-\uEFFFF according to the spec
|
||||
Unicode overview: https://symbl.cc/en/unicode-table/
|
||||
*/
|
||||
exports.makeTagNameSafe = function(tag,defaultTag) {
|
||||
// Custom web-components need to be "lowercase()" https://html.spec.whatwg.org/#valid-custom-element-name
|
||||
var regxSanitizeChars = new RegExp($tw.config.htmlCustomPrimitives.sanitizePCENChar,"mg");
|
||||
|
||||
// Sanitize inputs to make the logic simpler
|
||||
defaultTag = (defaultTag) ? defaultTag.replace(regxSanitizeChars,"") : "SPAN";
|
||||
tag = (tag) ? tag.replace(regxSanitizeChars,"") : defaultTag;
|
||||
|
||||
// RegExp for valid standard HTML element, extended including hyphen "-" because browsers allow it
|
||||
var regexStandardChars = /(?:[a-z]|[A-Z]|[0-9]|-)+/g,
|
||||
result = "";
|
||||
|
||||
// Check if tag matches standard HTML spec https://html.spec.whatwg.org/#syntax-tag-name
|
||||
if(tag.match(regexStandardChars)[0] === tag) {
|
||||
result = tag;
|
||||
}
|
||||
// Check for unsafe tag and unsafe defaultTag
|
||||
if($tw.config.htmlUnsafeElements.indexOf(result.toLowerCase()) !== -1) {
|
||||
result = ($tw.config.htmlUnsafeElements.indexOf(defaultTag.toLowerCase()) !== -1) ? "safe-" + defaultTag : defaultTag;
|
||||
}
|
||||
// Check for forbidden tag names according to spec and log info to help users. See: $:/core/modules/config.js
|
||||
if($tw.config.htmlForbiddenTags.indexOf(result.toLowerCase()) >= 0) {
|
||||
console.log("Forbidden custom element:\"" + result.toLowerCase() + "\" See: https://html.spec.whatwg.org/#valid-custom-element-name")
|
||||
result = "safe-" + result;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -35,7 +35,9 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
|
|||
this.computeAttributes();
|
||||
this.execute();
|
||||
// Create element
|
||||
tag = $tw.utils.makeTagNameSafe(this.buttonTag,tag)
|
||||
if(this.buttonTag && $tw.config.htmlUnsafeElements.indexOf(this.buttonTag) === -1) {
|
||||
tag = this.buttonTag;
|
||||
}
|
||||
domNode = this.document.createElement(tag);
|
||||
this.domNode = domNode;
|
||||
// Assign classes
|
||||
|
|
|
|||
|
|
@ -35,7 +35,10 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
|
|||
// Execute our logic
|
||||
this.execute();
|
||||
// Sanitise the specified tag
|
||||
tag = $tw.utils.makeTagNameSafe(this.draggableTag,"div");
|
||||
tag = this.draggableTag;
|
||||
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
|
||||
tag = "div";
|
||||
}
|
||||
// Create our element
|
||||
domNode = this.document.createElement(tag);
|
||||
// Assign classes
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@ DroppableWidget.prototype.render = function(parent,nextSibling) {
|
|||
// Compute attributes and execute state
|
||||
this.computeAttributes();
|
||||
this.execute();
|
||||
tag = $tw.utils.makeTagNameSafe(this.droppableTag,tag);
|
||||
if(this.droppableTag && $tw.config.htmlUnsafeElements.indexOf(this.droppableTag) === -1) {
|
||||
tag = this.droppableTag;
|
||||
}
|
||||
// Create element and assign classes
|
||||
domNode = this.document.createElement(tag);
|
||||
this.domNode = domNode;
|
||||
|
|
|
|||
|
|
@ -26,10 +26,15 @@ Render this widget into the DOM
|
|||
ElementWidget.prototype.render = function(parent,nextSibling) {
|
||||
this.parentDomNode = parent;
|
||||
this.computeAttributes();
|
||||
// Eliminate blacklisted elements
|
||||
// Neuter blacklisted elements
|
||||
this.tag = this.parseTreeNode.tag;
|
||||
// Sanitize tag name if needed according to Custom Web-Componenets spec
|
||||
this.tag = $tw.utils.makeTagNameSafe(this.tag, "safe-" + this.tag);
|
||||
if($tw.config.htmlUnsafeElements.indexOf(this.tag) !== -1) {
|
||||
this.tag = "safe-" + this.tag;
|
||||
}
|
||||
// Restrict tag name to digits, letts and dashes
|
||||
this.tag = this.tag.replace(/[^0-9a-zA-Z\-]/mg,"");
|
||||
// Default to a span
|
||||
this.tag = this.tag || "span";
|
||||
// Adjust headings by the current base level
|
||||
var headingLevel = ["h1","h2","h3","h4","h5","h6"].indexOf(this.tag);
|
||||
if(headingLevel !== -1) {
|
||||
|
|
|
|||
|
|
@ -32,7 +32,9 @@ EventWidget.prototype.render = function(parent,nextSibling) {
|
|||
this.execute();
|
||||
// Create element
|
||||
var tag = this.parseTreeNode.isBlock ? "div" : "span";
|
||||
tag = $tw.utils.makeTagNameSafe(this.elementTag,tag)
|
||||
if(this.elementTag && $tw.config.htmlUnsafeElements.indexOf(this.elementTag) === -1) {
|
||||
tag = this.elementTag;
|
||||
}
|
||||
var domNode = this.document.createElement(tag);
|
||||
this.domNode = domNode;
|
||||
// Assign classes
|
||||
|
|
|
|||
|
|
@ -31,7 +31,9 @@ KeyboardWidget.prototype.render = function(parent,nextSibling) {
|
|||
this.computeAttributes();
|
||||
this.execute();
|
||||
var tag = this.parseTreeNode.isBlock ? "div" : "span";
|
||||
tag = $tw.utils.makeTagNameSafe(this.tag,tag);
|
||||
if(this.tag && $tw.config.htmlUnsafeElements.indexOf(this.tag) === -1) {
|
||||
tag = this.tag;
|
||||
}
|
||||
// Create element
|
||||
var domNode = this.document.createElement(tag);
|
||||
// Assign classes
|
||||
|
|
@ -48,7 +50,7 @@ KeyboardWidget.prototype.render = function(parent,nextSibling) {
|
|||
};
|
||||
|
||||
KeyboardWidget.prototype.handleChangeEvent = function(event) {
|
||||
if($tw.keyboardManager.handleKeydownEvent(event, {onlyPriority: true})) {
|
||||
if ($tw.keyboardManager.handleKeydownEvent(event, {onlyPriority: true})) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -62,7 +62,9 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
|
|||
var self = this;
|
||||
// Sanitise the specified tag
|
||||
var tag = this.linkTag;
|
||||
tag = $tw.utils.makeTagNameSafe(tag,"a");
|
||||
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
|
||||
tag = "a";
|
||||
}
|
||||
// Create our element
|
||||
var namespace = this.getVariable("namespace",{defaultValue: "http://www.w3.org/1999/xhtml"}),
|
||||
domNode = this.document.createElementNS(namespace,tag);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,9 @@ RevealWidget.prototype.render = function(parent,nextSibling) {
|
|||
this.computeAttributes();
|
||||
this.execute();
|
||||
var tag = this.parseTreeNode.isBlock ? "div" : "span";
|
||||
tag = $tw.utils.makeTagNameSafe(this.revealTag,tag);
|
||||
if(this.revealTag && $tw.config.htmlUnsafeElements.indexOf(this.revealTag) === -1) {
|
||||
tag = this.revealTag;
|
||||
}
|
||||
var domNode = this.document.createElement(tag);
|
||||
this.domNode = domNode;
|
||||
this.assignDomNodeClasses();
|
||||
|
|
@ -91,9 +93,9 @@ RevealWidget.prototype.positionPopup = function(domNode) {
|
|||
left = Math.max(0,left);
|
||||
top = Math.max(0,top);
|
||||
}
|
||||
if(this.popup.absolute) {
|
||||
if (this.popup.absolute) {
|
||||
// Traverse the offsetParent chain and correct the offset to make it relative to the parent node.
|
||||
for(var offsetParentDomNode = domNode.offsetParent; offsetParentDomNode; offsetParentDomNode = offsetParentDomNode.offsetParent) {
|
||||
for (var offsetParentDomNode = domNode.offsetParent; offsetParentDomNode; offsetParentDomNode = offsetParentDomNode.offsetParent) {
|
||||
left -= offsetParentDomNode.offsetLeft;
|
||||
top -= offsetParentDomNode.offsetTop;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue