This commit is contained in:
Mario Pietsch 2024-05-04 14:15:55 +00:00 committed by GitHub
commit b1639a531a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 35 additions and 43 deletions

View File

@ -48,10 +48,7 @@ function FramedEngine(options) {
this.iframeDoc.body.style.padding = "0";
this.widget.domNodes.push(this.iframeNode);
// Construct the textarea or input node
var tag = this.widget.editTag;
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
tag = "input";
}
var tag = $tw.utils.makeTagNameSafe(this.widget.editTag,"input");
this.domNode = this.iframeDoc.createElement(tag);
// Set the text
if(this.widget.editTag === "textarea") {
@ -200,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;
}

View File

@ -22,10 +22,7 @@ function SimpleEngine(options) {
this.parentNode = options.parentNode;
this.nextSibling = options.nextSibling;
// Construct the textarea or input node
var tag = this.widget.editTag;
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
tag = "input";
}
var tag = $tw.utils.makeTagNameSafe(this.widget.editTag,"input");
this.domNode = this.widget.document.createElement(tag);
// Set the text
if(this.widget.editTag === "textarea") {

View File

@ -289,7 +289,7 @@ exports.copyToClipboard = function(text,options) {
var succeeded = false;
try {
succeeded = document.execCommand("copy");
} catch (err) {
} catch(err) {
}
if(!options.doNotNotify) {
$tw.notifier.display(succeeded ? "$:/language/Notifications/CopiedToClipboard/Succeeded" : "$:/language/Notifications/CopiedToClipboard/Failed");
@ -306,8 +306,8 @@ 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();
@ -324,7 +324,7 @@ exports.collectDOMVariables = function(selectedNode,domNode,event) {
variables["tv-popup-coords"] = Popup.buildCoordinates(Popup.coordinatePrefix.csOffsetParent,nodeRect);
var absRect = $tw.utils.extend({}, nodeRect);
for (var currentNode = selectedNode.offsetParent; currentNode; currentNode = currentNode.offsetParent) {
for(var currentNode = selectedNode.offsetParent; currentNode; currentNode = currentNode.offsetParent) {
absRect.left += currentNode.offsetLeft;
absRect.top += currentNode.offsetTop;
}
@ -366,7 +366,7 @@ exports.collectDOMVariables = function(selectedNode,domNode,event) {
};
/*
Make sure the CSS selector is not invalid
Make sure the CSS selector is valid
*/
exports.querySelectorSafe = function(selector,baseElement) {
baseElement = baseElement || document;
@ -386,4 +386,19 @@ exports.querySelectorAllSafe = function(selector,baseElement) {
}
};
/*
Make sure HTML tag names are valid
*/
exports.makeTagNameSafe = function(tag,defaultTag) {
defaultTag = defaultTag || "SPAN";
// This implements a check for standard DOM elements: https://html.spec.whatwg.org/#syntax-tag-name
// It does _not_ deal with Custom Elements: https://html.spec.whatwg.org/#valid-custom-element-name
var regexp = /[a-zA-Z0-9]/g;
if(tag && tag.match(regexp) && $tw.config.htmlUnsafeElements.indexOf(tag) === -1) {
return tag;
}
return defaultTag;
};
})();

View File

@ -38,9 +38,7 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
this.computeAttributes();
this.execute();
// Create element
if(this.buttonTag && $tw.config.htmlUnsafeElements.indexOf(this.buttonTag) === -1) {
tag = this.buttonTag;
}
tag = $tw.utils.makeTagNameSafe(this.buttonTag,tag)
domNode = this.document.createElement(tag);
this.domNode = domNode;
// Assign classes
@ -74,7 +72,7 @@ ButtonWidget.prototype.render = function(parent,nextSibling) {
if(this["aria-label"]) {
domNode.setAttribute("aria-label",this["aria-label"]);
}
if (this.role) {
if(this.role) {
domNode.setAttribute("role", this.role);
}
if(this.popup || this.popupTitle) {

View File

@ -38,10 +38,7 @@ DraggableWidget.prototype.render = function(parent,nextSibling) {
// Execute our logic
this.execute();
// Sanitise the specified tag
tag = this.draggableTag;
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
tag = "div";
}
tag = $tw.utils.makeTagNameSafe(this.draggableTag,"div");
// Create our element
domNode = this.document.createElement(tag);
// Assign classes

View File

@ -35,9 +35,7 @@ DroppableWidget.prototype.render = function(parent,nextSibling) {
// Compute attributes and execute state
this.computeAttributes();
this.execute();
if(this.droppableTag && $tw.config.htmlUnsafeElements.indexOf(this.droppableTag) === -1) {
tag = this.droppableTag;
}
tag = $tw.utils.makeTagNameSafe(this.droppableTag,tag);
// Create element and assign classes
domNode = this.document.createElement(tag);
this.domNode = domNode;

View File

@ -31,9 +31,7 @@ ElementWidget.prototype.render = function(parent,nextSibling) {
this.computeAttributes();
// Neuter blacklisted elements
this.tag = this.parseTreeNode.tag;
if($tw.config.htmlUnsafeElements.indexOf(this.tag) !== -1) {
this.tag = "safe-" + this.tag;
}
this.tag = $tw.utils.makeTagNameSafe(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

View File

@ -35,9 +35,7 @@ EventWidget.prototype.render = function(parent,nextSibling) {
this.execute();
// Create element
var tag = this.parseTreeNode.isBlock ? "div" : "span";
if(this.elementTag && $tw.config.htmlUnsafeElements.indexOf(this.elementTag) === -1) {
tag = this.elementTag;
}
tag = $tw.utils.makeTagNameSafe(this.elementTag,tag)
var domNode = this.document.createElement(tag);
this.domNode = domNode;
// Assign classes

View File

@ -34,9 +34,7 @@ KeyboardWidget.prototype.render = function(parent,nextSibling) {
this.computeAttributes();
this.execute();
var tag = this.parseTreeNode.isBlock ? "div" : "span";
if(this.tag && $tw.config.htmlUnsafeElements.indexOf(this.tag) === -1) {
tag = this.tag;
}
tag = $tw.utils.makeTagNameSafe(this.tag,tag);
// Create element
var domNode = this.document.createElement(tag);
// Assign classes
@ -53,7 +51,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;
}

View File

@ -61,9 +61,7 @@ LinkWidget.prototype.renderLink = function(parent,nextSibling) {
var self = this;
// Sanitise the specified tag
var tag = this.linkTag;
if($tw.config.htmlUnsafeElements.indexOf(tag) !== -1) {
tag = "a";
}
tag = $tw.utils.makeTagNameSafe(tag,"a");
// Create our element
var namespace = this.getVariable("namespace",{defaultValue: "http://www.w3.org/1999/xhtml"}),
domNode = this.document.createElementNS(namespace,tag);

View File

@ -33,9 +33,7 @@ RevealWidget.prototype.render = function(parent,nextSibling) {
this.computeAttributes();
this.execute();
var tag = this.parseTreeNode.isBlock ? "div" : "span";
if(this.revealTag && $tw.config.htmlUnsafeElements.indexOf(this.revealTag) === -1) {
tag = this.revealTag;
}
tag = $tw.utils.makeTagNameSafe(this.revealTag,tag);
var domNode = this.document.createElement(tag);
this.domNode = domNode;
this.assignDomNodeClasses();
@ -96,9 +94,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;
}