summaryrefslogtreecommitdiff
path: root/bin/wiki/ImportarDesdeURL/node_modules/parse5/lib/parser/formatting_element_list.js
diff options
context:
space:
mode:
Diffstat (limited to 'bin/wiki/ImportarDesdeURL/node_modules/parse5/lib/parser/formatting_element_list.js')
-rw-r--r--bin/wiki/ImportarDesdeURL/node_modules/parse5/lib/parser/formatting_element_list.js167
1 files changed, 167 insertions, 0 deletions
diff --git a/bin/wiki/ImportarDesdeURL/node_modules/parse5/lib/parser/formatting_element_list.js b/bin/wiki/ImportarDesdeURL/node_modules/parse5/lib/parser/formatting_element_list.js
new file mode 100644
index 00000000..72a2c1b8
--- /dev/null
+++ b/bin/wiki/ImportarDesdeURL/node_modules/parse5/lib/parser/formatting_element_list.js
@@ -0,0 +1,167 @@
+'use strict';
+
+//Const
+var NOAH_ARK_CAPACITY = 3;
+
+//List of formatting elements
+var FormattingElementList = module.exports = function (treeAdapter) {
+ this.length = 0;
+ this.entries = [];
+ this.treeAdapter = treeAdapter;
+ this.bookmark = null;
+};
+
+//Entry types
+FormattingElementList.MARKER_ENTRY = 'MARKER_ENTRY';
+FormattingElementList.ELEMENT_ENTRY = 'ELEMENT_ENTRY';
+
+//Noah Ark's condition
+//OPTIMIZATION: at first we try to find possible candidates for exclusion using
+//lightweight heuristics without thorough attributes check.
+FormattingElementList.prototype._getNoahArkConditionCandidates = function (newElement) {
+ var candidates = [];
+
+ if (this.length >= NOAH_ARK_CAPACITY) {
+ var neAttrsLength = this.treeAdapter.getAttrList(newElement).length,
+ neTagName = this.treeAdapter.getTagName(newElement),
+ neNamespaceURI = this.treeAdapter.getNamespaceURI(newElement);
+
+ for (var i = this.length - 1; i >= 0; i--) {
+ var entry = this.entries[i];
+
+ if (entry.type === FormattingElementList.MARKER_ENTRY)
+ break;
+
+ var element = entry.element,
+ elementAttrs = this.treeAdapter.getAttrList(element),
+ isCandidate = this.treeAdapter.getTagName(element) === neTagName &&
+ this.treeAdapter.getNamespaceURI(element) === neNamespaceURI &&
+ elementAttrs.length === neAttrsLength;
+
+ if (isCandidate)
+ candidates.push({idx: i, attrs: elementAttrs});
+ }
+ }
+
+ return candidates.length < NOAH_ARK_CAPACITY ? [] : candidates;
+};
+
+FormattingElementList.prototype._ensureNoahArkCondition = function (newElement) {
+ var candidates = this._getNoahArkConditionCandidates(newElement),
+ cLength = candidates.length;
+
+ if (cLength) {
+ var neAttrs = this.treeAdapter.getAttrList(newElement),
+ neAttrsLength = neAttrs.length,
+ neAttrsMap = Object.create(null);
+
+ //NOTE: build attrs map for the new element so we can perform fast lookups
+ for (var i = 0; i < neAttrsLength; i++) {
+ var neAttr = neAttrs[i];
+
+ neAttrsMap[neAttr.name] = neAttr.value;
+ }
+
+ for (i = 0; i < neAttrsLength; i++) {
+ for (var j = 0; j < cLength; j++) {
+ var cAttr = candidates[j].attrs[i];
+
+ if (neAttrsMap[cAttr.name] !== cAttr.value) {
+ candidates.splice(j, 1);
+ cLength--;
+ }
+
+ if (candidates.length < NOAH_ARK_CAPACITY)
+ return;
+ }
+ }
+
+ //NOTE: remove bottommost candidates until Noah's Ark condition will not be met
+ for (i = cLength - 1; i >= NOAH_ARK_CAPACITY - 1; i--) {
+ this.entries.splice(candidates[i].idx, 1);
+ this.length--;
+ }
+ }
+};
+
+//Mutations
+FormattingElementList.prototype.insertMarker = function () {
+ this.entries.push({type: FormattingElementList.MARKER_ENTRY});
+ this.length++;
+};
+
+FormattingElementList.prototype.pushElement = function (element, token) {
+ this._ensureNoahArkCondition(element);
+
+ this.entries.push({
+ type: FormattingElementList.ELEMENT_ENTRY,
+ element: element,
+ token: token
+ });
+
+ this.length++;
+};
+
+FormattingElementList.prototype.insertElementAfterBookmark = function (element, token) {
+ var bookmarkIdx = this.length - 1;
+
+ for (; bookmarkIdx >= 0; bookmarkIdx--) {
+ if (this.entries[bookmarkIdx] === this.bookmark)
+ break;
+ }
+
+ this.entries.splice(bookmarkIdx + 1, 0, {
+ type: FormattingElementList.ELEMENT_ENTRY,
+ element: element,
+ token: token
+ });
+
+ this.length++;
+};
+
+FormattingElementList.prototype.removeEntry = function (entry) {
+ for (var i = this.length - 1; i >= 0; i--) {
+ if (this.entries[i] === entry) {
+ this.entries.splice(i, 1);
+ this.length--;
+ break;
+ }
+ }
+};
+
+FormattingElementList.prototype.clearToLastMarker = function () {
+ while (this.length) {
+ var entry = this.entries.pop();
+
+ this.length--;
+
+ if (entry.type === FormattingElementList.MARKER_ENTRY)
+ break;
+ }
+};
+
+//Search
+FormattingElementList.prototype.getElementEntryInScopeWithTagName = function (tagName) {
+ for (var i = this.length - 1; i >= 0; i--) {
+ var entry = this.entries[i];
+
+ if (entry.type === FormattingElementList.MARKER_ENTRY)
+ return null;
+
+ if (this.treeAdapter.getTagName(entry.element) === tagName)
+ return entry;
+ }
+
+ return null;
+};
+
+FormattingElementList.prototype.getElementEntry = function (element) {
+ for (var i = this.length - 1; i >= 0; i--) {
+ var entry = this.entries[i];
+
+ if (entry.type === FormattingElementList.ELEMENT_ENTRY && entry.element === element)
+ return entry;
+ }
+
+ return null;
+};