Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(204)

Unified Diff: node_modules/vulcanize/node_modules/whacko/lib/api/traversing.js

Issue 800513006: Added vulcanize under third_party/npm_modules (Closed) Base URL: https://chromium.googlesource.com/infra/third_party/npm_modules.git@master
Patch Set: Created 6 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: node_modules/vulcanize/node_modules/whacko/lib/api/traversing.js
diff --git a/node_modules/vulcanize/node_modules/whacko/lib/api/traversing.js b/node_modules/vulcanize/node_modules/whacko/lib/api/traversing.js
new file mode 100644
index 0000000000000000000000000000000000000000..c7209fe727f16a0e0544feff574cd0adbdf3a63d
--- /dev/null
+++ b/node_modules/vulcanize/node_modules/whacko/lib/api/traversing.js
@@ -0,0 +1,416 @@
+var _ = require('lodash'),
+ select = require('CSSselect'),
+ utils = require('../utils'),
+ domEach = utils.domEach,
+ uniqueSort = require('domutils').uniqueSort,
+ isTag = utils.isTag;
+
+exports.find = function(selectorOrHaystack) {
+ var elems = _.reduce(this, function(memo, elem) {
+ return memo.concat(_.filter(elem.children, isTag));
+ }, []);
+ var contains = this.constructor.contains;
+ var haystack;
+
+ if (selectorOrHaystack && typeof selectorOrHaystack !== 'string') {
+ if (selectorOrHaystack.cheerio) {
+ haystack = selectorOrHaystack.get();
+ } else {
+ haystack = [selectorOrHaystack];
+ }
+
+ return this._make(haystack.filter(function(elem) {
+ var idx, len;
+ for (idx = 0, len = this.length; idx < len; ++idx) {
+ if (contains(this[idx], elem)) {
+ return true;
+ }
+ }
+ }, this));
+ }
+
+ return this._make(select(selectorOrHaystack, elems, this.options));
+};
+
+// Get the parent of each element in the current set of matched elements,
+// optionally filtered by a selector.
+exports.parent = function(selector) {
+ var set = [];
+
+ domEach(this, function(idx, elem) {
+ var parentElem = elem.parent;
+ if (parentElem && set.indexOf(parentElem) < 0) {
+ set.push(parentElem);
+ }
+ });
+
+ if (arguments.length) {
+ set = exports.filter.call(set, selector, this);
+ }
+
+ return this._make(set);
+};
+
+exports.parents = function(selector) {
+ var parentNodes = [];
+
+ // When multiple DOM elements are in the original set, the resulting set will
+ // be in *reverse* order of the original elements as well, with duplicates
+ // removed.
+ this.get().reverse().forEach(function(elem) {
+ traverseParents(this, elem.parent, selector, Infinity)
+ .forEach(function(node) {
+ if (parentNodes.indexOf(node) === -1) {
+ parentNodes.push(node);
+ }
+ }
+ );
+ }, this);
+
+ return this._make(parentNodes);
+};
+
+exports.parentsUntil = function(selector, filter) {
+ var parentNodes = [], untilNode, untilNodes;
+
+ if (typeof selector === 'string') {
+ untilNode = select(selector, this.parents().toArray(), this.options)[0];
+ } else if (selector && selector.cheerio) {
+ untilNodes = selector.toArray();
+ } else if (selector) {
+ untilNode = selector;
+ }
+
+ // When multiple DOM elements are in the original set, the resulting set will
+ // be in *reverse* order of the original elements as well, with duplicates
+ // removed.
+
+ this.toArray().reverse().forEach(function(elem) {
+ while ((elem = elem.parent)) {
+ if ((untilNode && elem !== untilNode) ||
+ (untilNodes && untilNodes.indexOf(elem) === -1) ||
+ (!untilNode && !untilNodes)) {
+ if (isTag(elem) && parentNodes.indexOf(elem) === -1) { parentNodes.push(elem); }
+ } else {
+ break;
+ }
+ }
+ }, this);
+
+ return this._make(filter ? select(filter, parentNodes, this.options) : parentNodes);
+};
+
+// For each element in the set, get the first element that matches the selector
+// by testing the element itself and traversing up through its ancestors in the
+// DOM tree.
+exports.closest = function(selector) {
+ var set = [];
+
+ if (!selector) {
+ return this._make(set);
+ }
+
+ domEach(this, function(idx, elem) {
+ var closestElem = traverseParents(this, elem, selector, 1)[0];
+
+ // Do not add duplicate elements to the set
+ if (closestElem && set.indexOf(closestElem) < 0) {
+ set.push(closestElem);
+ }
+ }.bind(this));
+
+ return this._make(set);
+};
+
+exports.next = function(selector) {
+ if (!this[0]) { return this; }
+ var elems = [];
+
+ _.forEach(this, function(elem) {
+ while ((elem = elem.next)) {
+ if (isTag(elem)) {
+ elems.push(elem);
+ return;
+ }
+ }
+ });
+
+ return selector ?
+ exports.filter.call(elems, selector, this) :
+ this._make(elems);
+};
+
+exports.nextAll = function(selector) {
+ if (!this[0]) { return this; }
+ var elems = [];
+
+ _.forEach(this, function(elem) {
+ while ((elem = elem.next)) {
+ if (isTag(elem) && elems.indexOf(elem) === -1) {
+ elems.push(elem);
+ }
+ }
+ });
+
+ return selector ?
+ exports.filter.call(elems, selector, this) :
+ this._make(elems);
+};
+
+exports.nextUntil = function(selector, filterSelector) {
+ if (!this[0]) { return this; }
+ var elems = [], untilNode, untilNodes;
+
+ if (typeof selector === 'string') {
+ untilNode = select(selector, this.nextAll().get(), this.options)[0];
+ } else if (selector && selector.cheerio) {
+ untilNodes = selector.get();
+ } else if (selector) {
+ untilNode = selector;
+ }
+
+ _.forEach(this, function(elem) {
+ while ((elem = elem.next)) {
+ if ((untilNode && elem !== untilNode) ||
+ (untilNodes && untilNodes.indexOf(elem) === -1) ||
+ (!untilNode && !untilNodes)) {
+ if (isTag(elem) && elems.indexOf(elem) === -1) {
+ elems.push(elem);
+ }
+ } else {
+ break;
+ }
+ }
+ });
+
+ return filterSelector ?
+ exports.filter.call(elems, filterSelector, this) :
+ this._make(elems);
+};
+
+exports.prev = function(selector) {
+ if (!this[0]) { return this; }
+ var elems = [];
+
+ _.forEach(this, function(elem) {
+ while ((elem = elem.prev)) {
+ if (isTag(elem)) {
+ elems.push(elem);
+ return;
+ }
+ }
+ });
+
+ return selector ?
+ exports.filter.call(elems, selector, this) :
+ this._make(elems);
+};
+
+exports.prevAll = function(selector) {
+ if (!this[0]) { return this; }
+ var elems = [];
+
+ _.forEach(this, function(elem) {
+ while ((elem = elem.prev)) {
+ if (isTag(elem) && elems.indexOf(elem) === -1) {
+ elems.push(elem);
+ }
+ }
+ });
+
+ return selector ?
+ exports.filter.call(elems, selector, this) :
+ this._make(elems);
+};
+
+exports.prevUntil = function(selector, filterSelector) {
+ if (!this[0]) { return this; }
+ var elems = [], untilNode, untilNodes;
+
+ if (typeof selector === 'string') {
+ untilNode = select(selector, this.prevAll().get(), this.options)[0];
+ } else if (selector && selector.cheerio) {
+ untilNodes = selector.get();
+ } else if (selector) {
+ untilNode = selector;
+ }
+
+ _.forEach(this, function(elem) {
+ while ((elem = elem.prev)) {
+ if ((untilNode && elem !== untilNode) ||
+ (untilNodes && untilNodes.indexOf(elem) === -1) ||
+ (!untilNode && !untilNodes)) {
+ if (isTag(elem) && elems.indexOf(elem) === -1) {
+ elems.push(elem);
+ }
+ } else {
+ break;
+ }
+ }
+ });
+
+ return filterSelector ?
+ exports.filter.call(elems, filterSelector, this) :
+ this._make(elems);
+};
+
+exports.siblings = function(selector) {
+ var parent = this.parent();
+
+ var elems = _.filter(
+ parent ? parent.children() : this.siblingsAndMe(),
+ function(elem) { return isTag(elem) && !this.is(elem); },
+ this
+ );
+
+ if (selector !== undefined) {
+ return exports.filter.call(elems, selector, this);
+ } else {
+ return this._make(elems);
+ }
+};
+
+exports.children = function(selector) {
+
+ var elems = _.reduce(this, function(memo, elem) {
+ return memo.concat(_.filter(elem.children, isTag));
+ }, []);
+
+ if (selector === undefined) return this._make(elems);
+ else if (typeof selector === 'number') return this._make(elems[selector]);
+
+ return exports.filter.call(elems, selector, this);
+};
+
+exports.contents = function() {
+ return this._make(_.reduce(this, function(all, elem) {
+ all.push.apply(all, elem.children);
+ return all;
+ }, []));
+};
+
+exports.each = function(fn) {
+ var i = 0, len = this.length;
+ while (i < len && fn.call(this[i], i, this[i]) !== false) ++i;
+ return this;
+};
+
+exports.map = function(fn) {
+ return this._make(_.reduce(this, function(memo, el, i) {
+ var val = fn.call(el, i, el);
+ return val == null ? memo : memo.concat(val);
+ }, []));
+};
+
+var makeFilterMethod = function(filterFn) {
+ return function(match, container) {
+ var testFn;
+ container = container || this;
+
+ if (typeof match === 'string') {
+ testFn = select.compile(match, container.options);
+ } else if (typeof match === 'function') {
+ testFn = function(el, i) {
+ return match.call(el, i, el);
+ };
+ } else if (match.cheerio) {
+ testFn = match.is.bind(match);
+ } else {
+ testFn = function(el) {
+ return match === el;
+ };
+ }
+
+ return container._make(filterFn(this, testFn));
+ };
+};
+
+exports.filter = makeFilterMethod(_.filter);
+exports.not = makeFilterMethod(_.reject);
+
+exports.first = function() {
+ return this.length > 1 ? this._make(this[0]) : this;
+};
+
+exports.last = function() {
+ return this.length > 1 ? this._make(this[this.length - 1]) : this;
+};
+
+// Reduce the set of matched elements to the one at the specified index.
+exports.eq = function(i) {
+ i = +i;
+
+ // Use the first identity optimization if possible
+ if (i === 0 && this.length <= 1) return this;
+
+ if (i < 0) i = this.length + i;
+ return this[i] ? this._make(this[i]) : this._make([]);
+};
+
+// Retrieve the DOM elements matched by the jQuery object.
+exports.get = function(i) {
+ if (i == null) {
+ return Array.prototype.slice.call(this);
+ } else {
+ return this[i < 0 ? (this.length + i) : i];
+ }
+};
+
+// Search for a given element from among the matched elements.
+exports.index = function(selectorOrNeedle) {
+ var $haystack, needle;
+
+ if (arguments.length === 0) {
+ $haystack = this.parent().children();
+ needle = this[0];
+ } else if (typeof selectorOrNeedle === 'string') {
+ $haystack = this._make(selectorOrNeedle);
+ needle = this[0];
+ } else {
+ $haystack = this;
+ needle = selectorOrNeedle.cheerio ? selectorOrNeedle[0] : selectorOrNeedle;
+ }
+
+ return $haystack.get().indexOf(needle);
+};
+
+exports.slice = function() {
+ return this._make([].slice.apply(this, arguments));
+};
+
+function traverseParents(self, elem, selector, limit) {
+ var elems = [];
+ while (elem && elems.length < limit) {
+ if (!selector || exports.filter.call([elem], selector, self).length) {
+ elems.push(elem);
+ }
+ elem = elem.parent;
+ }
+ return elems;
+}
+
+// End the most recent filtering operation in the current chain and return the
+// set of matched elements to its previous state.
+exports.end = function() {
+ return this.prevObject || this._make([]);
+};
+
+exports.add = function(other, context) {
+ var selection = this._make(other, context);
+ var contents = uniqueSort(selection.get().concat(this.get()));
+
+ for (var i = 0; i < contents.length; ++i) {
+ selection[i] = contents[i];
+ }
+ selection.length = contents.length;
+
+ return selection;
+};
+
+// Add the previous set of elements on the stack to the current set, optionally
+// filtered by a selector.
+exports.addBack = function(selector) {
+ return this.add(
+ arguments.length ? this.prevObject.filter(selector) : this.prevObject
+ );
+};

Powered by Google App Engine
This is Rietveld 408576698