| Index: node_modules/vulcanize/node_modules/whacko/lib/api/manipulation.js
|
| diff --git a/node_modules/vulcanize/node_modules/whacko/lib/api/manipulation.js b/node_modules/vulcanize/node_modules/whacko/lib/api/manipulation.js
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..c086baa1c02174240c03c96a47840bb5eee7ba92
|
| --- /dev/null
|
| +++ b/node_modules/vulcanize/node_modules/whacko/lib/api/manipulation.js
|
| @@ -0,0 +1,303 @@
|
| +var _ = require('lodash'),
|
| + parse = require('../parse'),
|
| + $ = require('../static'),
|
| + updateDOM = parse.update,
|
| + evaluate = parse.evaluate,
|
| + utils = require('../utils'),
|
| + domEach = utils.domEach,
|
| + slice = Array.prototype.slice;
|
| +
|
| +// Create an array of nodes, recursing into arrays and parsing strings if
|
| +// necessary
|
| +exports._makeDomArray = function makeDomArray(elem) {
|
| + if (elem == null) {
|
| + return [];
|
| + } else if (elem.cheerio) {
|
| + return elem.get();
|
| + } else if (Array.isArray(elem)) {
|
| + return _.flatten(elem.map(makeDomArray, this));
|
| + } else if (typeof elem === 'string') {
|
| + return evaluate(elem, this.options);
|
| + } else {
|
| + return [elem];
|
| + }
|
| +};
|
| +
|
| +var _insert = function(concatenator) {
|
| + return function() {
|
| + var self = this,
|
| + elems = slice.call(arguments),
|
| + dom = this._makeDomArray(elems);
|
| +
|
| + if (typeof elems[0] === 'function') {
|
| + return domEach(this, function(i, el) {
|
| + dom = self._makeDomArray(elems[0].call(el, i, $.html(el.children)));
|
| + concatenator(dom, el.children, el);
|
| + });
|
| + } else {
|
| + return domEach(this, function(i, el) {
|
| + 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.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.after = function() {
|
| + var elems = slice.call(arguments),
|
| + dom = this._makeDomArray(elems),
|
| + self = this;
|
| +
|
| + domEach(this, function(i, el) {
|
| + var parent = el.parent || el.root;
|
| + if (!parent) {
|
| + return;
|
| + }
|
| +
|
| + var siblings = parent.children,
|
| + index = siblings.indexOf(el);
|
| +
|
| + // If not found, move on
|
| + if (!~index) return;
|
| +
|
| + if (typeof elems[0] === 'function') {
|
| + dom = self._makeDomArray(elems[0].call(el, i));
|
| + }
|
| +
|
| + // Add element after `this` element
|
| + uniqueSplice(siblings, ++index, 0, dom, parent);
|
| + });
|
| +
|
| + return this;
|
| +};
|
| +
|
| +exports.before = function() {
|
| + var elems = slice.call(arguments),
|
| + dom = this._makeDomArray(elems),
|
| + self = this;
|
| +
|
| + domEach(this, function(i, el) {
|
| + var parent = el.parent || el.root;
|
| + if (!parent) {
|
| + return;
|
| + }
|
| +
|
| + var siblings = parent.children,
|
| + index = siblings.indexOf(el);
|
| +
|
| + // If not found, move on
|
| + if (!~index) return;
|
| +
|
| + if (typeof elems[0] === 'function') {
|
| + dom = self._makeDomArray(elems[0].call(el, i));
|
| + }
|
| +
|
| + // Add element before `el` element
|
| + uniqueSplice(siblings, index, 0, dom, parent);
|
| + });
|
| +
|
| + return this;
|
| +};
|
| +
|
| +/*
|
| + 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) 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) {
|
| + _.each(el.children, function(el) {
|
| + el.next = el.prev = el.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) {
|
| + _.each(el.children, function(el) {
|
| + el.next = el.prev = el.parent = null;
|
| + });
|
| +
|
| + var content = str.cheerio ? str.clone().get() : evaluate(str, opts);
|
| +
|
| + updateDOM(content, el);
|
| + });
|
| +
|
| + return this;
|
| +};
|
| +
|
| +exports.toString = function() {
|
| + return $.html(this);
|
| +};
|
| +
|
| +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) {
|
| + _.each(el.children, function(el) {
|
| + el.next = el.prev = el.parent = null;
|
| + });
|
| +
|
| + var elem = {
|
| + data: str,
|
| + type: 'text',
|
| + parent: el,
|
| + prev: null,
|
| + next: null,
|
| + children: []
|
| + };
|
| +
|
| + updateDOM(elem, el);
|
| + });
|
| +
|
| + return this;
|
| +};
|
| +
|
| +exports.clone = function() {
|
| + // Turn it into HTML, then recreate it,
|
| + // Seems to be the easiest way to reconnect everything correctly
|
| + return this._make($.html(this, this.options));
|
| +};
|
|
|