diff options
Diffstat (limited to 'bin/wiki/ImportarDesdeURL/node_modules/cheerio/lib/api/manipulation.js')
-rw-r--r-- | bin/wiki/ImportarDesdeURL/node_modules/cheerio/lib/api/manipulation.js | 442 |
1 files changed, 442 insertions, 0 deletions
diff --git a/bin/wiki/ImportarDesdeURL/node_modules/cheerio/lib/api/manipulation.js b/bin/wiki/ImportarDesdeURL/node_modules/cheerio/lib/api/manipulation.js new file mode 100644 index 00000000..8d09d9a4 --- /dev/null +++ b/bin/wiki/ImportarDesdeURL/node_modules/cheerio/lib/api/manipulation.js @@ -0,0 +1,442 @@ +var parse = require('../parse'), + $ = require('../static'), + updateDOM = parse.update, + evaluate = parse.evaluate, + utils = require('../utils'), + domEach = utils.domEach, + cloneDom = utils.cloneDom, + isHtml = utils.isHtml, + slice = Array.prototype.slice, + _ = { + flatten: require('lodash/flatten'), + bind: require('lodash/bind'), + forEach: require('lodash/forEach') + }; + +// Create an array of nodes, recursing into arrays and parsing strings if +// necessary +exports._makeDomArray = function makeDomArray(elem, clone) { + if (elem == null) { + return []; + } else if (elem.cheerio) { + return clone ? cloneDom(elem.get(), elem.options) : elem.get(); + } else if (Array.isArray(elem)) { + return _.flatten(elem.map(function(el) { + return this._makeDomArray(el, clone); + }, this)); + } else if (typeof elem === 'string') { + return evaluate(elem, this.options, false); + } else { + return clone ? cloneDom([elem]) : [elem]; + } +}; + +var _insert = function(concatenator) { + return function() { + var elems = slice.call(arguments), + lastIdx = this.length - 1; + + return domEach(this, function(i, el) { + var dom, domSrc; + + if (typeof elems[0] === 'function') { + domSrc = elems[0].call(el, i, $.html(el.children)); + } else { + domSrc = elems; + } + + dom = this._makeDomArray(domSrc, i < lastIdx); + concatenator(dom, el.children, el); + }); + }; +}; + +/* + * Modify an array in-place, removing some number of elements and adding new + * elements directly following them. + * + * @param {Array} array Target array to splice. + * @param {Number} spliceIdx Index at which to begin changing the array. + * @param {Number} spliceCount Number of elements to remove from the array. + * @param {Array} newElems Elements to insert into the array. + * + * @api private + */ +var uniqueSplice = function(array, spliceIdx, spliceCount, newElems, parent) { + var spliceArgs = [spliceIdx, spliceCount].concat(newElems), + prev = array[spliceIdx - 1] || null, + next = array[spliceIdx] || null; + var idx, len, prevIdx, node, oldParent; + + // Before splicing in new elements, ensure they do not already appear in the + // current array. + for (idx = 0, len = newElems.length; idx < len; ++idx) { + node = newElems[idx]; + oldParent = node.parent || node.root; + prevIdx = oldParent && oldParent.children.indexOf(newElems[idx]); + + if (oldParent && prevIdx > -1) { + oldParent.children.splice(prevIdx, 1); + if (parent === oldParent && spliceIdx > prevIdx) { + spliceArgs[0]--; + } + } + + node.root = null; + node.parent = parent; + + if (node.prev) { + node.prev.next = node.next || null; + } + + if (node.next) { + node.next.prev = node.prev || null; + } + + node.prev = newElems[idx - 1] || prev; + node.next = newElems[idx + 1] || next; + } + + if (prev) { + prev.next = newElems[0]; + } + if (next) { + next.prev = newElems[newElems.length - 1]; + } + return array.splice.apply(array, spliceArgs); +}; + +exports.appendTo = function(target) { + if (!target.cheerio) { + target = this.constructor.call(this.constructor, target, null, this._originalRoot); + } + + target.append(this); + + return this; +}; + +exports.prependTo = function(target) { + if (!target.cheerio) { + target = this.constructor.call(this.constructor, target, null, this._originalRoot); + } + + target.prepend(this); + + return this; +}; + +exports.append = _insert(function(dom, children, parent) { + uniqueSplice(children, children.length, 0, dom, parent); +}); + +exports.prepend = _insert(function(dom, children, parent) { + uniqueSplice(children, 0, 0, dom, parent); +}); + +exports.wrap = function(wrapper) { + var wrapperFn = typeof wrapper === 'function' && wrapper, + lastIdx = this.length - 1; + + _.forEach(this, _.bind(function(el, i) { + var parent = el.parent || el.root, + siblings = parent.children, + wrapperDom, elInsertLocation, j, index; + + if (!parent) { + return; + } + + if (wrapperFn) { + wrapper = wrapperFn.call(el, i); + } + + if (typeof wrapper === 'string' && !isHtml(wrapper)) { + wrapper = this.parents().last().find(wrapper).clone(); + } + + wrapperDom = this._makeDomArray(wrapper, i < lastIdx).slice(0, 1); + elInsertLocation = wrapperDom[0]; + // Find the deepest child. Only consider the first tag child of each node + // (ignore text); stop if no children are found. + j = 0; + + while (elInsertLocation && elInsertLocation.children) { + if (j >= elInsertLocation.children.length) { + break; + } + + if (elInsertLocation.children[j].type === 'tag') { + elInsertLocation = elInsertLocation.children[j]; + j=0; + } else { + j++; + } + } + index = siblings.indexOf(el); + + updateDOM([el], elInsertLocation); + // The previous operation removed the current element from the `siblings` + // array, so the `dom` array can be inserted without removing any + // additional elements. + uniqueSplice(siblings, index, 0, wrapperDom, parent); + }, this)); + + return this; +}; + +exports.after = function() { + var elems = slice.call(arguments), + lastIdx = this.length - 1; + + domEach(this, function(i, el) { + var parent = el.parent || el.root; + if (!parent) { + return; + } + + var siblings = parent.children, + index = siblings.indexOf(el), + domSrc, dom; + + // If not found, move on + if (index < 0) return; + + if (typeof elems[0] === 'function') { + domSrc = elems[0].call(el, i, $.html(el.children)); + } else { + domSrc = elems; + } + dom = this._makeDomArray(domSrc, i < lastIdx); + + // Add element after `this` element + uniqueSplice(siblings, index + 1, 0, dom, parent); + }); + + return this; +}; + +exports.insertAfter = function(target) { + var clones = [], + self = this; + if (typeof target === 'string') { + target = this.constructor.call(this.constructor, target, null, this._originalRoot); + } + target = this._makeDomArray(target); + self.remove(); + domEach(target, function(i, el) { + var clonedSelf = self._makeDomArray(self.clone()); + var parent = el.parent || el.root; + if (!parent) { + return; + } + + var siblings = parent.children, + index = siblings.indexOf(el); + + // If not found, move on + if (index < 0) return; + + // Add cloned `this` element(s) after target element + uniqueSplice(siblings, index + 1, 0, clonedSelf, parent); + clones.push(clonedSelf); + }); + return this.constructor.call(this.constructor, this._makeDomArray(clones)); +}; + +exports.before = function() { + var elems = slice.call(arguments), + lastIdx = this.length - 1; + + domEach(this, function(i, el) { + var parent = el.parent || el.root; + if (!parent) { + return; + } + + var siblings = parent.children, + index = siblings.indexOf(el), + domSrc, dom; + + // If not found, move on + if (index < 0) return; + + if (typeof elems[0] === 'function') { + domSrc = elems[0].call(el, i, $.html(el.children)); + } else { + domSrc = elems; + } + + dom = this._makeDomArray(domSrc, i < lastIdx); + + // Add element before `el` element + uniqueSplice(siblings, index, 0, dom, parent); + }); + + return this; +}; + +exports.insertBefore = function(target) { + var clones = [], + self = this; + if (typeof target === 'string') { + target = this.constructor.call(this.constructor, target, null, this._originalRoot); + } + target = this._makeDomArray(target); + self.remove(); + domEach(target, function(i, el) { + var clonedSelf = self._makeDomArray(self.clone()); + var parent = el.parent || el.root; + if (!parent) { + return; + } + + var siblings = parent.children, + index = siblings.indexOf(el); + + // If not found, move on + if (index < 0) return; + + // Add cloned `this` element(s) after target element + uniqueSplice(siblings, index, 0, clonedSelf, parent); + clones.push(clonedSelf); + }); + return this.constructor.call(this.constructor, this._makeDomArray(clones)); +}; + +/* + remove([selector]) +*/ +exports.remove = function(selector) { + var elems = this; + + // Filter if we have selector + if (selector) + elems = elems.filter(selector); + + domEach(elems, function(i, el) { + var parent = el.parent || el.root; + if (!parent) { + return; + } + + var siblings = parent.children, + index = siblings.indexOf(el); + + if (index < 0) return; + + siblings.splice(index, 1); + if (el.prev) { + el.prev.next = el.next; + } + if (el.next) { + el.next.prev = el.prev; + } + el.prev = el.next = el.parent = el.root = null; + }); + + return this; +}; + +exports.replaceWith = function(content) { + var self = this; + + domEach(this, function(i, el) { + var parent = el.parent || el.root; + if (!parent) { + return; + } + + var siblings = parent.children, + dom = self._makeDomArray(typeof content === 'function' ? content.call(el, i, el) : content), + index; + + // In the case that `dom` contains nodes that already exist in other + // structures, ensure those nodes are properly removed. + updateDOM(dom, null); + + index = siblings.indexOf(el); + + // Completely remove old element + uniqueSplice(siblings, index, 1, dom, parent); + el.parent = el.prev = el.next = el.root = null; + }); + + return this; +}; + +exports.empty = function() { + domEach(this, function(i, el) { + _.forEach(el.children, function(child) { + child.next = child.prev = child.parent = null; + }); + + el.children.length = 0; + }); + return this; +}; + +/** + * Set/Get the HTML + */ +exports.html = function(str) { + if (str === undefined) { + if (!this[0] || !this[0].children) return null; + return $.html(this[0].children, this.options); + } + + var opts = this.options; + + domEach(this, function(i, el) { + _.forEach(el.children, function(child) { + child.next = child.prev = child.parent = null; + }); + + var content = str.cheerio ? str.clone().get() : evaluate('' + str, opts, false); + + updateDOM(content, el); + }); + + return this; +}; + +exports.toString = function() { + return $.html(this, this.options); +}; + +exports.text = function(str) { + // If `str` is undefined, act as a "getter" + if (str === undefined) { + return $.text(this); + } else if (typeof str === 'function') { + // Function support + return domEach(this, function(i, el) { + var $el = [el]; + return exports.text.call($el, str.call(el, i, $.text($el))); + }); + } + + // Append text node to each selected elements + domEach(this, function(i, el) { + _.forEach(el.children, function(child) { + child.next = child.prev = child.parent = null; + }); + + var elem = { + data: '' + str, + type: 'text', + parent: el, + prev: null, + next: null, + children: [] + }; + + updateDOM(elem, el); + }); + + return this; +}; + +exports.clone = function() { + return this._make(cloneDom(this.get(), this.options)); +}; |