Skip to content

Commit

Permalink
Fix namespace handling (#42)
Browse files Browse the repository at this point in the history
  • Loading branch information
asamuzaK authored Feb 4, 2024
1 parent 9b9b824 commit 1e6fbab
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 45 deletions.
17 changes: 10 additions & 7 deletions src/js/dom-util.js
Original file line number Diff line number Diff line change
Expand Up @@ -307,14 +307,17 @@ export const getNamespaceURI = (ns, node) => {
export const isNamespaceDeclared = (ns = '', node = {}) => {
let res;
if (ns && typeof ns === 'string' && node.nodeType === ELEMENT_NODE) {
const root = node.ownerDocument.documentElement;
let parent = node;
while (parent) {
res = getNamespaceURI(ns, parent);
if (res || parent === root) {
break;
res = node.lookupNamespaceURI(ns);
if (!res) {
const root = node.ownerDocument.documentElement;
let parent = node;
while (parent) {
res = getNamespaceURI(ns, parent);
if (res || parent === root) {
break;
}
parent = parent.parentNode;
}
parent = parent.parentNode;
}
}
return !!res;
Expand Down
19 changes: 10 additions & 9 deletions src/js/matcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ export const _matchTypeSelector = (ast, node, opt = {}) => {
let res;
switch (astPrefix) {
case '': {
if (nodePrefix === '' && namespaceURI === null &&
if (!nodePrefix && !namespaceURI &&
(astLocalName === '*' || astLocalName === nodeLocalName)) {
res = node;
}
Expand All @@ -268,15 +268,16 @@ export const _matchTypeSelector = (ast, node, opt = {}) => {
break;
}
default: {
const namespaceDeclared = isNamespaceDeclared(astPrefix, node);
if (namespaceDeclared) {
if (astPrefix === nodePrefix &&
(astLocalName === '*' || astLocalName === nodeLocalName)) {
res = node;
if (astPrefix === nodePrefix) {
const namespaceDeclared = isNamespaceDeclared(astPrefix, node);
if (namespaceDeclared) {
if (astLocalName === '*' || astLocalName === nodeLocalName) {
res = node;
}
} else if (!forgive) {
const msg = `Undeclared namespace ${astPrefix}`;
throw new DOMException(msg, SYNTAX_ERR);
}
} else if (!forgive) {
const msg = `Undeclared namespace ${astPrefix}`;
throw new DOMException(msg, SYNTAX_ERR);
}
}
}
Expand Down
25 changes: 1 addition & 24 deletions test/dom-util.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -900,8 +900,7 @@ describe('DOM utility functions', () => {
});

it('should get result', () => {
const node =
document.createElementNS('https://example.com/foo', 'foo:div');
const node = document.createElement('foo:div');
const parent = document.getElementById('div0');
parent.appendChild(node);
const res = func('foo', node);
Expand All @@ -911,18 +910,6 @@ describe('DOM utility functions', () => {
it('should get result', () => {
const node =
document.createElementNS('https://example.com/foo', 'foo:div');
node.setAttribute('xmlns:foo', 'https://example.com/foo');
const parent = document.getElementById('div0');
parent.appendChild(node);
const res = func('foo', node);
assert.isTrue(res, 'result');
});

it('should get result', () => {
const node =
document.createElementNS('https://example.com/foo', 'foo:div');
node.setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:foo',
'https://example.com/foo');
const parent = document.getElementById('div0');
parent.appendChild(node);
const res = func('foo', node);
Expand All @@ -935,16 +922,6 @@ describe('DOM utility functions', () => {
document.createElementNS('https://example.com/foo', 'foo:div');
frag.appendChild(node);
const res = func('foo', node);
assert.isFalse(res, 'result');
});

it('should get result', () => {
const frag = document.createDocumentFragment();
const node =
document.createElementNS('https://example.com/foo', 'foo:div');
node.setAttribute('xmlns:foo', 'https://example.com/foo');
frag.appendChild(node);
const res = func('foo', node);
assert.isTrue(res, 'result');
});

Expand Down
36 changes: 31 additions & 5 deletions test/matcher.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -1695,17 +1695,17 @@ describe('matcher', () => {
assert.deepEqual(res, node, 'result');
});

it('should throw', () => {
it('should get matched node', () => {
const leaf = {
name: 'foo|*',
type: SELECTOR_TYPE
};
const node =
document.createElementNS('https://example.com/foo', 'foo:bar');
document.createElementNS('https://example.com/foo', 'foo:bar');
const parent = document.getElementById('div0');
parent.appendChild(node);
assert.throws(() => func(leaf, node),
DOMException, 'Undeclared namespace foo');
const res = func(leaf, node);
assert.deepEqual(res, node, 'result');
});

it('should not match', () => {
Expand Down Expand Up @@ -1759,13 +1759,39 @@ describe('matcher', () => {
type: SELECTOR_TYPE
};
const node =
document.createElementNS('https://example.com/baz', 'baz:qux');
document.createElementNS('https://example.com/baz', 'baz:qux');
const parent = document.getElementById('div0');
parent.appendChild(node);
const res = func(leaf, node);
assert.isNull(res, 'result');
});

it('should throw', () => {
const leaf = {
name: 'foo|bar',
type: SELECTOR_TYPE
};
const node = document.createElement('foo:qux');
const parent = document.getElementById('div0');
parent.appendChild(node);
assert.throws(() => func(leaf, node), DOMException,
'Undeclared namespace foo');
});

it('should not match', () => {
const leaf = {
name: 'foo|bar',
type: SELECTOR_TYPE
};
const node = document.createElement('foo:qux');
const parent = document.getElementById('div0');
parent.appendChild(node);
const res = func(leaf, node, {
forgive: true
});
assert.isNull(res, 'result');
});

it('should get matched node', () => {
const leaf = {
name: '|div',
Expand Down

0 comments on commit 1e6fbab

Please sign in to comment.