mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Update web-platform-tests to revision 8dea22c604b5c77f4b244e54373749ac50846947
This commit is contained in:
parent
c7f4eba3db
commit
edbe492dc8
53 changed files with 2798 additions and 111 deletions
|
@ -46,8 +46,7 @@ function initializeTest(aInnerHTML) {
|
|||
gEditor.addEventListener("input", onInput);
|
||||
}
|
||||
|
||||
gEditor.innerHTML = aInnerHTML;
|
||||
gEditor.focus();
|
||||
setupEditor(aInnerHTML);
|
||||
gBeforeinput = [];
|
||||
gInput = [];
|
||||
}
|
||||
|
@ -251,3 +250,267 @@ function checkEditorContentResultAsSubTest(
|
|||
}
|
||||
}, `${description} - comparing innerHTML`);
|
||||
}
|
||||
|
||||
// Similar to `setupDiv` in editing/include/tests.js, this method sets
|
||||
// innerHTML value of gEditor, and sets multiple selection ranges specified
|
||||
// with the markers.
|
||||
// - `[` specifies start boundary in a text node
|
||||
// - `{` specifies start boundary before a node
|
||||
// - `]` specifies end boundary in a text node
|
||||
// - `}` specifies end boundary after a node
|
||||
function setupEditor(innerHTMLWithRangeMarkers) {
|
||||
const startBoundaries = innerHTMLWithRangeMarkers.match(/\{|\[/g) || [];
|
||||
const endBoundaries = innerHTMLWithRangeMarkers.match(/\}|\]/g) || [];
|
||||
if (startBoundaries.length !== endBoundaries.length) {
|
||||
throw "Should match number of open/close markers";
|
||||
}
|
||||
|
||||
gEditor.innerHTML = innerHTMLWithRangeMarkers;
|
||||
gEditor.focus();
|
||||
|
||||
if (startBoundaries.length === 0) {
|
||||
// Don't remove the range for now since some tests may assume that
|
||||
// setting innerHTML does not remove all selection ranges.
|
||||
return;
|
||||
}
|
||||
|
||||
function getNextRangeAndDeleteMarker(startNode) {
|
||||
function getNextLeafNode(node) {
|
||||
function inclusiveDeepestFirstChildNode(container) {
|
||||
while (container.firstChild) {
|
||||
container = container.firstChild;
|
||||
}
|
||||
return container;
|
||||
}
|
||||
if (node.hasChildNodes()) {
|
||||
return inclusiveDeepestFirstChildNode(node);
|
||||
}
|
||||
if (node.nextSibling) {
|
||||
return inclusiveDeepestFirstChildNode(node.nextSibling);
|
||||
}
|
||||
let nextSibling = (function nextSiblingOfAncestorElement(child) {
|
||||
for (
|
||||
let parent = child.parentElement;
|
||||
parent && parent != gEditor;
|
||||
parent = parent.parentElement
|
||||
) {
|
||||
if (parent.nextSibling) {
|
||||
return parent.nextSibling;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
})(node);
|
||||
if (!nextSibling) {
|
||||
return null;
|
||||
}
|
||||
return inclusiveDeepestFirstChildNode(nextSibling);
|
||||
}
|
||||
function scanMarkerInTextNode(textNode, offset) {
|
||||
return /[\{\[\]\}]/.exec(textNode.data.substr(offset));
|
||||
}
|
||||
let startMarker = (function scanNextStartMaker(
|
||||
startContainer,
|
||||
startOffset
|
||||
) {
|
||||
function scanStartMakerInTextNode(textNode, offset) {
|
||||
let scanResult = scanMarkerInTextNode(textNode, offset);
|
||||
if (scanResult === null) {
|
||||
return null;
|
||||
}
|
||||
if (scanResult[0] === "}" || scanResult[0] === "]") {
|
||||
throw "An end marker is found before a start marker";
|
||||
}
|
||||
return {
|
||||
marker: scanResult[0],
|
||||
container: textNode,
|
||||
offset: scanResult.index + offset,
|
||||
};
|
||||
}
|
||||
if (startContainer.nodeType === Node.TEXT_NODE) {
|
||||
let scanResult = scanStartMakerInTextNode(startContainer, startOffset);
|
||||
if (scanResult !== null) {
|
||||
return scanResult;
|
||||
}
|
||||
}
|
||||
let nextNode = startContainer;
|
||||
while ((nextNode = getNextLeafNode(nextNode))) {
|
||||
if (nextNode.nodeType === Node.TEXT_NODE) {
|
||||
let scanResult = scanStartMakerInTextNode(nextNode, 0);
|
||||
if (scanResult !== null) {
|
||||
return scanResult;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
})(startNode, 0);
|
||||
if (startMarker === null) {
|
||||
return null;
|
||||
}
|
||||
let endMarker = (function scanNextEndMarker(startContainer, startOffset) {
|
||||
function scanEndMarkerInTextNode(textNode, offset) {
|
||||
let scanResult = scanMarkerInTextNode(textNode, offset);
|
||||
if (scanResult === null) {
|
||||
return null;
|
||||
}
|
||||
if (scanResult[0] === "{" || scanResult[0] === "[") {
|
||||
throw "A start marker is found before an end marker";
|
||||
}
|
||||
return {
|
||||
marker: scanResult[0],
|
||||
container: textNode,
|
||||
offset: scanResult.index + offset,
|
||||
};
|
||||
}
|
||||
if (startContainer.nodeType === Node.TEXT_NODE) {
|
||||
let scanResult = scanEndMarkerInTextNode(startContainer, startOffset);
|
||||
if (scanResult !== null) {
|
||||
return scanResult;
|
||||
}
|
||||
}
|
||||
let nextNode = startContainer;
|
||||
while ((nextNode = getNextLeafNode(nextNode))) {
|
||||
if (nextNode.nodeType === Node.TEXT_NODE) {
|
||||
let scanResult = scanEndMarkerInTextNode(nextNode, 0);
|
||||
if (scanResult !== null) {
|
||||
return scanResult;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
})(startMarker.container, startMarker.offset + 1);
|
||||
if (endMarker === null) {
|
||||
throw "Found an open marker, but not found corresponding close marker";
|
||||
}
|
||||
function indexOfContainer(container, child) {
|
||||
let offset = 0;
|
||||
for (let node = container.firstChild; node; node = node.nextSibling) {
|
||||
if (node == child) {
|
||||
return offset;
|
||||
}
|
||||
offset++;
|
||||
}
|
||||
throw "child must be a child node of container";
|
||||
}
|
||||
(function deleteFoundMarkers() {
|
||||
function removeNode(node) {
|
||||
let container = node.parentElement;
|
||||
let offset = indexOfContainer(container, node);
|
||||
node.remove();
|
||||
return { container, offset };
|
||||
}
|
||||
if (startMarker.container == endMarker.container) {
|
||||
// If the text node becomes empty, remove it and set collapsed range
|
||||
// to the position where there is the text node.
|
||||
if (startMarker.container.length === 2) {
|
||||
if (!/[\[\{][\]\}]/.test(startMarker.container.data)) {
|
||||
throw `Unexpected text node (data: "${startMarker.container.data}")`;
|
||||
}
|
||||
let { container, offset } = removeNode(startMarker.container);
|
||||
startMarker.container = endMarker.container = container;
|
||||
startMarker.offset = endMarker.offset = offset;
|
||||
startMarker.marker = endMarker.marker = "";
|
||||
return;
|
||||
}
|
||||
startMarker.container.data = `${startMarker.container.data.substring(
|
||||
0,
|
||||
startMarker.offset
|
||||
)}${startMarker.container.data.substring(
|
||||
startMarker.offset + 1,
|
||||
endMarker.offset
|
||||
)}${startMarker.container.data.substring(endMarker.offset + 1)}`;
|
||||
if (startMarker.offset >= startMarker.container.length) {
|
||||
startMarker.offset = endMarker.offset = startMarker.container.length;
|
||||
return;
|
||||
}
|
||||
endMarker.offset--; // remove the start marker's length
|
||||
if (endMarker.offset > endMarker.container.length) {
|
||||
endMarker.offset = endMarker.container.length;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (startMarker.container.length === 1) {
|
||||
let { container, offset } = removeNode(startMarker.container);
|
||||
startMarker.container = container;
|
||||
startMarker.offset = offset;
|
||||
startMarker.marker = "";
|
||||
} else {
|
||||
startMarker.container.data = `${startMarker.container.data.substring(
|
||||
0,
|
||||
startMarker.offset
|
||||
)}${startMarker.container.data.substring(startMarker.offset + 1)}`;
|
||||
}
|
||||
if (endMarker.container.length === 1) {
|
||||
let { container, offset } = removeNode(endMarker.container);
|
||||
endMarker.container = container;
|
||||
endMarker.offset = offset;
|
||||
endMarker.marker = "";
|
||||
} else {
|
||||
endMarker.container.data = `${endMarker.container.data.substring(
|
||||
0,
|
||||
endMarker.offset
|
||||
)}${endMarker.container.data.substring(endMarker.offset + 1)}`;
|
||||
}
|
||||
})();
|
||||
(function handleNodeSelectMarker() {
|
||||
if (startMarker.marker === "{") {
|
||||
if (startMarker.offset === 0) {
|
||||
// The range start with the text node.
|
||||
let container = startMarker.container.parentElement;
|
||||
startMarker.offset = indexOfContainer(
|
||||
container,
|
||||
startMarker.container
|
||||
);
|
||||
startMarker.container = container;
|
||||
} else if (startMarker.offset === startMarker.container.data.length) {
|
||||
// The range start after the text node.
|
||||
let container = startMarker.container.parentElement;
|
||||
startMarker.offset =
|
||||
indexOfContainer(container, startMarker.container) + 1;
|
||||
startMarker.container = container;
|
||||
} else {
|
||||
throw 'Start marker "{" is allowed start or end of a text node';
|
||||
}
|
||||
}
|
||||
if (endMarker.marker === "}") {
|
||||
if (endMarker.offset === 0) {
|
||||
// The range ends before the text node.
|
||||
let container = endMarker.container.parentElement;
|
||||
endMarker.offset = indexOfContainer(container, endMarker.container);
|
||||
endMarker.container = container;
|
||||
} else if (endMarker.offset === endMarker.container.data.length) {
|
||||
// The range ends with the text node.
|
||||
let container = endMarker.container.parentElement;
|
||||
endMarker.offset =
|
||||
indexOfContainer(container, endMarker.container) + 1;
|
||||
endMarker.container = container;
|
||||
} else {
|
||||
throw 'End marker "}" is allowed start or end of a text node';
|
||||
}
|
||||
}
|
||||
})();
|
||||
let range = document.createRange();
|
||||
range.setStart(startMarker.container, startMarker.offset);
|
||||
range.setEnd(endMarker.container, endMarker.offset);
|
||||
return range;
|
||||
}
|
||||
|
||||
let ranges = [];
|
||||
for (
|
||||
let range = getNextRangeAndDeleteMarker(gEditor.firstChild);
|
||||
range;
|
||||
range = getNextRangeAndDeleteMarker(range.endContainer)
|
||||
) {
|
||||
ranges.push(range);
|
||||
}
|
||||
|
||||
gSelection.removeAllRanges();
|
||||
for (let range of ranges) {
|
||||
gSelection.addRange(range);
|
||||
}
|
||||
|
||||
if (gSelection.rangeCount != ranges.length) {
|
||||
throw `Failed to set selection to the given ranges whose length is ${ranges.length}, but only ${gSelection.rangeCount} ranges are added`;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue