Skip to content

Commit

Permalink
use element properties to simplify loops
Browse files Browse the repository at this point in the history
  • Loading branch information
chemerisuk committed Sep 22, 2017
1 parent 203fe78 commit 536d268
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 41 deletions.
41 changes: 21 additions & 20 deletions src/document/create.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { DOCUMENT, ELEMENT_NODE } from "../const";
import { DOCUMENT } from "../const";
import { MethodError } from "../errors";
import { $Document } from "../document/index";
import { $Element } from "../element/index";

Expand All @@ -9,37 +10,37 @@ function makeMethod(all) {
return function(value) {
const node = this["<%= prop() %>"];

if (!node) return all ? [] : new $Element();
if (!node || typeof value !== "string") {
throw new MethodError("create" + all, arguments);
}

var result = all ? [] : null;

const quickMatch = !all && reQuick.exec(value);
const quickMatch = !result && reQuick.exec(value);
if (quickMatch) {
return new $Element(node.createElement(quickMatch[1]));
}

sandbox.innerHTML = value.trim(); // parse HTML string

var result = all ? [] : null;

for (var el; el = sandbox.firstChild; ) {
sandbox.removeChild(el); // detach element from the sandbox
for (var it; it = sandbox.firstElementChild; ) {
sandbox.removeChild(it); // detach element from the sandbox

if (el.nodeType === ELEMENT_NODE) {
if (node !== DOCUMENT) {
// adopt node for external documents
el = node.adoptNode(el);
}
if (node !== DOCUMENT) {
// adopt node for external documents
it = node.adoptNode(it);
}

if (all) {
result.push(new $Element(el));
} else {
result = el;
// stop early, because need only the first element
break;
}
if (result) {
result.push(new $Element(it));
} else {
result = new $Element(it);
// need only the first element
break;
}
}

return all ? result : $Element(result);
return result || new $Element();
};
}

Expand Down
46 changes: 25 additions & 21 deletions src/element/traversing.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,38 @@
import { $Element } from "../element/index";
import { map } from "../util/index";
import { MethodError } from "../errors";
import SelectorMatcher from "../util/selectormatcher";

function makeMethod(methodName, propertyName) {
function makeMethod(methodName, propertyName, all) {
return function(selector) {
if (selector && typeof selector !== "string") {
throw new MethodError(methodName, arguments);
}

var all = methodName.slice(-3) === "All",
matcher = SelectorMatcher(selector),
nodes = all ? [] : null,
it = this["<%= prop() %>"];
var node = this["<%= prop() %>"];
var result = all ? [] : null;

// method closest starts traversing from the element itself
// except no selector was specified where it returns parent
if (it && (!matcher || methodName !== "closest")) {
it = it[propertyName];
}

for (; it; it = it[propertyName]) {
if (it.nodeType === 1 && (!matcher || matcher(it))) {
if (!all) break;
if (node) {
const matcher = SelectorMatcher(selector);
// method closest starts traversing from the element itself
// except no selector was specified where it returns parent
if (node && (!matcher || methodName !== "closest")) {
node = node[propertyName];
}

nodes.push(it);
for (var it = node; it; it = it[propertyName]) {
if (!matcher || matcher(it)) {
if (result) {
result.push($Element(it));
} else {
result = $Element(it);
// need only the first element
break;
}
}
}
}

return all ? map.call(nodes, $Element) : $Element(it);
return result || new $Element();
};
}

Expand All @@ -45,7 +49,7 @@ function makeMethod(methodName, propertyName) {
* link.next(); // <b>
* link.next("i"); // <i>
*/
$Element.prototype.next = makeMethod("next", "nextSibling");
$Element.prototype.next = makeMethod("next", "nextElementSibling");

/**
* Find previous sibling element filtered by optional selector
Expand All @@ -60,7 +64,7 @@ $Element.prototype.next = makeMethod("next", "nextSibling");
* link.prev(); // <i>
* link.prev("b"); // <b>
*/
$Element.prototype.prev = makeMethod("prev", "previousSibling");
$Element.prototype.prev = makeMethod("prev", "previousElementSibling");

/**
* Find all next sibling elements filtered by optional selector
Expand All @@ -75,7 +79,7 @@ $Element.prototype.prev = makeMethod("prev", "previousSibling");
* link.nextAll(); // [<i>, <b>, <i>]
* link.nextAll("i"); // [<i>, <i>]
*/
$Element.prototype.nextAll = makeMethod("nextAll", "nextSibling");
$Element.prototype.nextAll = makeMethod("nextAll", "nextElementSibling", true);

/**
* Find all previous sibling elements filtered by optional selector
Expand All @@ -90,7 +94,7 @@ $Element.prototype.nextAll = makeMethod("nextAll", "nextSibling");
* link.prevAll(); // [<i>, <b>, <i>]
* link.prevAll("b"); // [<b>]
*/
$Element.prototype.prevAll = makeMethod("prevAll", "previousSibling");
$Element.prototype.prevAll = makeMethod("prevAll", "previousElementSibling", true);

/**
* Find the closest ancestor of the current element (or the current element itself) which matches selector
Expand Down

0 comments on commit 536d268

Please sign in to comment.