Skip to content

Commit

Permalink
Add non-standard workaround for w3c/DOM-Parsing#29.
Browse files Browse the repository at this point in the history
  • Loading branch information
bwrrp committed Aug 16, 2017
1 parent 1e330ec commit 13c495e
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 25 deletions.
51 changes: 30 additions & 21 deletions src/dom-parsing/serializationAlgorithms.ts
Original file line number Diff line number Diff line change
Expand Up @@ -515,7 +515,7 @@ function serializeAttributes(
requireWellFormed: boolean
): string[] {
// 1. Let result be the empty string.
const result = [];
const result: string[] = [];

// 2. Let localname set be a new empty namespace localname set. This localname set will contain tuples of unique
// attribute namespaceURI and localName pairs, and is populated as each attr is processed. This set is used to
Expand Down Expand Up @@ -545,7 +545,7 @@ function serializeAttributes(
const attributeNamespace = attr.namespaceURI;

// 3.4. Let candidate prefix be null.
let candidatePrefix = null;
let candidatePrefix: string | null = null;

// 3.5. If attribute namespace is not null, then run these sub-steps:
if (attributeNamespace !== null) {
Expand Down Expand Up @@ -617,25 +617,34 @@ function serializeAttributes(
}
} else {
// 3.5.3. Otherwise, the attribute namespace in not the XMLNS namespace. Run these steps:
// 3.5.3.1. Let candidate prefix be the result of generating a prefix providing map, attribute
// namespace, and prefix index as input.
candidatePrefix = generatePrefix(map, attributeNamespace, prefixIndex);

// 3.5.3.2. Append the following to result, in the order listed:
// 3.5.3.2.1. " " (U+0020 SPACE);
// 3.5.3.2.2. The string "xmlns:";
// 3.5.3.2.3. The value of candidate prefix;
// 3.5.3.2.4. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK);
// 3.5.3.2.5. The result of serializing an attribute value given attribute namespace and the require
// well-formed flag as input;
// 3.5.3.2.7. """ (U+0022 QUOTATION MARK).
result.push(
' xmlns:',
candidatePrefix,
'="',
serializeAttributeValue(attributeNamespace, requireWellFormed),
'"'
);

// Note: we deviate from the spec here, as implementing as specified would generate prefixes for all
// namespaced attributes.
if (candidatePrefix === null) {
if (attr.prefix === null || attr.prefix in localPrefixesMap) {
// 3.5.3.1. Let candidate prefix be the result of generating a prefix providing map, attribute
// namespace, and prefix index as input.
candidatePrefix = generatePrefix(map, attributeNamespace, prefixIndex);
} else {
candidatePrefix = attr.prefix;
}

// 3.5.3.2. Append the following to result, in the order listed:
// 3.5.3.2.1. " " (U+0020 SPACE);
// 3.5.3.2.2. The string "xmlns:";
// 3.5.3.2.3. The value of candidate prefix;
// 3.5.3.2.4. "="" (U+003D EQUALS SIGN, U+0022 QUOTATION MARK);
// 3.5.3.2.5. The result of serializing an attribute value given attribute namespace and the require
// well-formed flag as input;
// 3.5.3.2.7. """ (U+0022 QUOTATION MARK).
result.push(
' xmlns:',
candidatePrefix,
'="',
serializeAttributeValue(attributeNamespace, requireWellFormed),
'"'
);
}
}
}
// 3.6. Append a " " (U+0020 SPACE) to result.
Expand Down
13 changes: 9 additions & 4 deletions test/dom-parsing/XMLSerializer.tests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,17 +157,22 @@ describe('XMLSerializer', () => {
chai.assert.equal(serializer.serializeToString(el), '<xml:test/>');
});

it('always generates a new prefix for namespaced attributes', () => {
// TODO: this sounds like it is not intended behavior, but does follow the algorithm
// (see XML serialization of the attributes or an Element, 3.5.3.1.)
it("doesn't generate a new prefix for namespaced attributes", () => {
// TODO: this depends on a deviation from the spec (see https://github.com/w3c/DOM-Parsing/issues/29)
const el = document.createElement('test');
el.setAttributeNS('http://www.example.com/ns', 'prf:test', 'value');
chai.assert.equal(
serializer.serializeToString(el),
'<test xmlns:ns1="http://www.example.com/ns" ns1:test="value"/>'
'<test xmlns:prf="http://www.example.com/ns" prf:test="value"/>'
);
});

it('always uses prefix xml for the xml namespace, for attributes', () => {
const el = document.createElementNS(XML_NAMESPACE, 'test');
el.setAttributeNS(XML_NAMESPACE, 'prf:id', 'value');
chai.assert.equal(serializer.serializeToString(el), '<xml:test xml:id="value"/>');
});

it('always uses prefix xml for the xml namespace, even if declared as default', () => {
const el = document.createElementNS('http://www.example.com/ns', 'prf:test');
el.setAttributeNS(XMLNS_NAMESPACE, 'xmlns', XML_NAMESPACE);
Expand Down

0 comments on commit 13c495e

Please sign in to comment.