diff --git a/src/plugin.js b/src/plugin.js index eb88416..307c680 100644 --- a/src/plugin.js +++ b/src/plugin.js @@ -47,6 +47,14 @@ const plugin = { description: "Orders XML attributes by key alphabetically while prioritizing xmlns attributes." }, + xmlSortAttributesFirst: { + type: "string", + category: "XML", + array: true, + default: [{ value: [] }], + description: + "When 'xmlSortAttributesByKey' is enabled, make sure that the given keys are always sorted first. Ignores namespace sorting." + }, xmlQuoteAttributes: { type: "choice", category: "XML", diff --git a/src/printer.js b/src/printer.js index aca9ef4..f96c851 100644 --- a/src/printer.js +++ b/src/printer.js @@ -412,6 +412,20 @@ function printElement(path, opts, print) { if (leftAttr.includes(":")) return -1; if (rightAttr.includes(":")) return 1; + // Check if the attributes need to be sorted first + if ( + Array.isArray(opts.xmlSortAttributesFirst) && + opts.xmlSortAttributesFirst.length > 0 + ) { + const leftFirstIndex = opts.xmlSortAttributesFirst.indexOf(leftAttr); + const rightFirstIndex = + opts.xmlSortAttributesFirst.indexOf(rightAttr); + if (leftFirstIndex !== -1 && rightFirstIndex !== -1) + return leftFirstIndex - rightFirstIndex; + else if (leftFirstIndex !== -1) return -1; + else if (rightFirstIndex !== -1) return 1; + } + return leftAttr.localeCompare(rightAttr); }); } diff --git a/test/__snapshots__/format.test.js.snap b/test/__snapshots__/format.test.js.snap index 130388b..336d5c5 100644 --- a/test/__snapshots__/format.test.js.snap +++ b/test/__snapshots__/format.test.js.snap @@ -1197,6 +1197,260 @@ use { " `; +exports[`xmlSortAttributesFirst => [width] 1`] = ` +" + + + + + Style inheritance and the use element + + &anp; 〹 + + bar + + + + + + + + + +- 1 + - 2 +- 3 + + + + + + + + + + + + < ignored /> + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed at est eget enim consectetur accumsan. Aliquam pretium sodales ipsum quis dignissim. Sed id sem vel diam luctus fringilla. Aliquam quis egestas magna. Curabitur molestie lorem et odio porta, et molestie libero laoreet. Morbi rhoncus sagittis cursus. Nullam vehicula pretium consequat. Praesent porta ante at posuere sollicitudin. Nullam commodo tempor arcu, at condimentum neque elementum ut. + + + content + + + text with space + + + even more + + + + + + + + + + + + + + + + + + + + + + + + He said, "Don't quote me." + + + + + + slide + + +" +`; + +exports[`xmlSortAttributesFirst => [viewBox, width] 1`] = ` +" + + + + + Style inheritance and the use element + + &anp; 〹 + + bar + + + + + + + + + +- 1 + - 2 +- 3 + + + + + + + + + + + + < ignored /> + + + + Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed at est eget enim consectetur accumsan. Aliquam pretium sodales ipsum quis dignissim. Sed id sem vel diam luctus fringilla. Aliquam quis egestas magna. Curabitur molestie lorem et odio porta, et molestie libero laoreet. Morbi rhoncus sagittis cursus. Nullam vehicula pretium consequat. Praesent porta ante at posuere sollicitudin. Nullam commodo tempor arcu, at condimentum neque elementum ut. + + + content + + + text with space + + + even more + + + + + + + + + + + + + + + + + + + + + + + + He said, "Don't quote me." + + + + + + slide + + +" +`; + exports[`xmlWhitespaceSensitivity => ignore 1`] = ` " true", async () => { expect(formatted).toMatchSnapshot(); }); +test("xmlSortAttributesFirst => [width]", async () => { + const formatted = await format(fixture, { + xmlSortAttributesByKey: true, + xmlSortAttributesFirst: ["width"] + }); + + expect(formatted).toMatchSnapshot(); +}); + +test("xmlSortAttributesFirst => [viewBox, width]", async () => { + const formatted = await format(fixture, { + xmlSortAttributesByKey: true, + xmlSortAttributesFirst: ["viewBox", "width"] + }); + + expect(formatted).toMatchSnapshot(); +}); + test("xmlQuoteAttributes => preserve", async () => { const formatted = await format(fixture, { xmlQuoteAttributes: "preserve"
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed at est eget enim consectetur accumsan. Aliquam pretium sodales ipsum quis dignissim. Sed id sem vel diam luctus fringilla. Aliquam quis egestas magna. Curabitur molestie lorem et odio porta, et molestie libero laoreet. Morbi rhoncus sagittis cursus. Nullam vehicula pretium consequat. Praesent porta ante at posuere sollicitudin. Nullam commodo tempor arcu, at condimentum neque elementum ut. +