ember-scoped-css 2.2.2 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -1
- package/dist/cjs/all-BI7LOSuT.cjs +1519 -0
- package/dist/cjs/all.cjs +1 -1
- package/dist/cjs/babel.cjs +1 -1
- package/dist/cjs/rollup.cjs +1 -1
- package/dist/cjs/vite.cjs +1 -1
- package/dist/runtime/test-support.js +11 -1
- package/dist/runtime/test-support.js.map +1 -1
- package/package.json +7 -2
- package/src/build/template-plugin.js +14 -1
- package/src/lib/css/rewrite.attributes.test.ts +119 -0
- package/src/lib/css/rewrite.js +57 -5
- package/src/lib/css/utils.js +98 -6
- package/src/lib/renameClass.js +12 -4
- package/src/lib/rewriteHbs.attributes.test.ts +118 -0
- package/src/lib/rewriteHbs.js +65 -15
- package/types.d.ts +30 -0
- package/dist/cjs/all-DYmccIER.cjs +0 -1416
package/dist/cjs/all.cjs
CHANGED
package/dist/cjs/babel.cjs
CHANGED
package/dist/cjs/rollup.cjs
CHANGED
package/dist/cjs/vite.cjs
CHANGED
|
@@ -373,6 +373,16 @@ if (import.meta.vitest) {
|
|
|
373
373
|
//#endregion
|
|
374
374
|
//#region src/lib/renameClass.js
|
|
375
375
|
/**
|
|
376
|
+
* Splits a space-separated class list (the value of a `class` attribute or of
|
|
377
|
+
* a `[class="..."]` selector) into its individual class names.
|
|
378
|
+
*
|
|
379
|
+
* @param {string} classList
|
|
380
|
+
* @returns {string[]}
|
|
381
|
+
*/
|
|
382
|
+
function splitClassList(classList) {
|
|
383
|
+
return classList.split(/\s+/).filter(Boolean);
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
376
386
|
*
|
|
377
387
|
* @param {string} className
|
|
378
388
|
* @param {string} postfix
|
|
@@ -380,7 +390,7 @@ if (import.meta.vitest) {
|
|
|
380
390
|
* @returns
|
|
381
391
|
*/
|
|
382
392
|
function renameClass(className, postfix, classesInCss) {
|
|
383
|
-
const renamedClasses = className
|
|
393
|
+
const renamedClasses = splitClassList(className).map((c) => {
|
|
384
394
|
if (!classesInCss || classesInCss.has(c)) {
|
|
385
395
|
if (c.endsWith(postfix)) return c;
|
|
386
396
|
return c + "_" + postfix;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"test-support.js","names":["hash"],"sources":["../../src/lib/path/md5.js","../../src/lib/path/hash-from-module-path.js","../../src/lib/renameClass.js","../../src/runtime/test-support.ts"],"sourcesContent":["/*\n * JavaScript MD5\n * https://github.com/blueimp/JavaScript-MD5\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Based on\n * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message\n * Digest Algorithm, as defined in RFC 1321.\n * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009\n * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet\n * Distributed under the BSD License\n * See http://pajhome.org.uk/crypt/md5 for more info.\n *\n * Modifications:\n * - removed IIFE, exported md5 (this file is now ESM)\n */\n\n/**\n * Add integers, wrapping at 2^32.\n * This uses 16-bit operations internally to work around bugs in interpreters.\n *\n * @param {number} x First integer\n * @param {number} y Second integer\n * @returns {number} Sum\n */\nfunction safeAdd(x, y) {\n var lsw = (x & 0xffff) + (y & 0xffff);\n var msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n\n return (msw << 16) | (lsw & 0xffff);\n}\n\n/**\n * Bitwise rotate a 32-bit number to the left.\n *\n * @param {number} num 32-bit number\n * @param {number} cnt Rotation count\n * @returns {number} Rotated number\n */\nfunction bitRotateLeft(num, cnt) {\n return (num << cnt) | (num >>> (32 - cnt));\n}\n\n/**\n * Basic operation the algorithm uses.\n *\n * @param {number} q q\n * @param {number} a a\n * @param {number} b b\n * @param {number} x x\n * @param {number} s s\n * @param {number} t t\n * @returns {number} Result\n */\nfunction md5cmn(q, a, b, x, s, t) {\n return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);\n}\n\n/**\n * Basic operation the algorithm uses.\n *\n * @param {number} a a\n * @param {number} b b\n * @param {number} c c\n * @param {number} d d\n * @param {number} x x\n * @param {number} s s\n * @param {number} t t\n * @returns {number} Result\n */\nfunction md5ff(a, b, c, d, x, s, t) {\n return md5cmn((b & c) | (~b & d), a, b, x, s, t);\n}\n\n/**\n * Basic operation the algorithm uses.\n *\n * @param {number} a a\n * @param {number} b b\n * @param {number} c c\n * @param {number} d d\n * @param {number} x x\n * @param {number} s s\n * @param {number} t t\n * @returns {number} Result\n */\nfunction md5gg(a, b, c, d, x, s, t) {\n return md5cmn((b & d) | (c & ~d), a, b, x, s, t);\n}\n\n/**\n * Basic operation the algorithm uses.\n *\n * @param {number} a a\n * @param {number} b b\n * @param {number} c c\n * @param {number} d d\n * @param {number} x x\n * @param {number} s s\n * @param {number} t t\n * @returns {number} Result\n */\nfunction md5hh(a, b, c, d, x, s, t) {\n return md5cmn(b ^ c ^ d, a, b, x, s, t);\n}\n\n/**\n * Basic operation the algorithm uses.\n *\n * @param {number} a a\n * @param {number} b b\n * @param {number} c c\n * @param {number} d d\n * @param {number} x x\n * @param {number} s s\n * @param {number} t t\n * @returns {number} Result\n */\nfunction md5ii(a, b, c, d, x, s, t) {\n return md5cmn(c ^ (b | ~d), a, b, x, s, t);\n}\n\n/**\n * Calculate the MD5 of an array of little-endian words, and a bit length.\n *\n * @param {Array} x Array of little-endian words\n * @param {number} len Bit length\n * @returns {Array<number>} MD5 Array\n */\nfunction binlMD5(x, len) {\n /* append padding */\n x[len >> 5] |= 0x80 << len % 32;\n x[(((len + 64) >>> 9) << 4) + 14] = len;\n\n var i;\n var olda;\n var oldb;\n var oldc;\n var oldd;\n var a = 1732584193;\n var b = -271733879;\n var c = -1732584194;\n var d = 271733878;\n\n for (i = 0; i < x.length; i += 16) {\n olda = a;\n oldb = b;\n oldc = c;\n oldd = d;\n\n a = md5ff(a, b, c, d, x[i], 7, -680876936);\n d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);\n c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);\n b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);\n a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);\n d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);\n c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);\n b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);\n a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);\n d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);\n c = md5ff(c, d, a, b, x[i + 10], 17, -42063);\n b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);\n a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);\n d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);\n c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);\n b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);\n\n a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);\n d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);\n c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);\n b = md5gg(b, c, d, a, x[i], 20, -373897302);\n a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);\n d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);\n c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);\n b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);\n a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);\n d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);\n c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);\n b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);\n a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);\n d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);\n c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);\n b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);\n\n a = md5hh(a, b, c, d, x[i + 5], 4, -378558);\n d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);\n c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);\n b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);\n a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);\n d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);\n c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);\n b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);\n a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);\n d = md5hh(d, a, b, c, x[i], 11, -358537222);\n c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);\n b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);\n a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);\n d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);\n c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);\n b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);\n\n a = md5ii(a, b, c, d, x[i], 6, -198630844);\n d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);\n c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);\n b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);\n a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);\n d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);\n c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);\n b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);\n a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);\n d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);\n c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);\n b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);\n a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);\n d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);\n c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);\n b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);\n\n a = safeAdd(a, olda);\n b = safeAdd(b, oldb);\n c = safeAdd(c, oldc);\n d = safeAdd(d, oldd);\n }\n\n return [a, b, c, d];\n}\n\n/**\n * Convert an array of little-endian words to a string\n *\n * @param {Array<number>} input MD5 Array\n * @returns {string} MD5 string\n */\nfunction binl2rstr(input) {\n var i;\n var output = '';\n var length32 = input.length * 32;\n\n for (i = 0; i < length32; i += 8) {\n output += String.fromCharCode((input[i >> 5] >>> i % 32) & 0xff);\n }\n\n return output;\n}\n\n/**\n * Convert a raw string to an array of little-endian words\n * Characters >255 have their high-byte silently ignored.\n *\n * @param {string} input Raw input string\n * @returns {Array<number>} Array of little-endian words\n */\nfunction rstr2binl(input) {\n var i;\n var output = [];\n output[(input.length >> 2) - 1] = undefined;\n\n for (i = 0; i < output.length; i += 1) {\n output[i] = 0;\n }\n\n var length8 = input.length * 8;\n\n for (i = 0; i < length8; i += 8) {\n output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << i % 32;\n }\n\n return output;\n}\n\n/**\n * Calculate the MD5 of a raw string\n *\n * @param {string} s Input string\n * @returns {string} Raw MD5 string\n */\nfunction rstrMD5(s) {\n return binl2rstr(binlMD5(rstr2binl(s), s.length * 8));\n}\n\n/**\n * Calculates the HMAC-MD5 of a key and some data (raw strings)\n *\n * @param {string} key HMAC key\n * @param {string} data Raw input string\n * @returns {string} Raw MD5 string\n */\nfunction rstrHMACMD5(key, data) {\n var i;\n var bkey = rstr2binl(key);\n var ipad = [];\n var opad = [];\n var hash;\n ipad[15] = opad[15] = undefined;\n\n if (bkey.length > 16) {\n bkey = binlMD5(bkey, key.length * 8);\n }\n\n for (i = 0; i < 16; i += 1) {\n ipad[i] = bkey[i] ^ 0x36363636;\n opad[i] = bkey[i] ^ 0x5c5c5c5c;\n }\n\n hash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);\n\n return binl2rstr(binlMD5(opad.concat(hash), 512 + 128));\n}\n\n/**\n * Convert a raw string to a hex string\n *\n * @param {string} input Raw input string\n * @returns {string} Hex encoded string\n */\nfunction rstr2hex(input) {\n var hexTab = '0123456789abcdef';\n var output = '';\n var x;\n var i;\n\n for (i = 0; i < input.length; i += 1) {\n x = input.charCodeAt(i);\n output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f);\n }\n\n return output;\n}\n\n/**\n * Encode a string as UTF-8\n *\n * @param {string} input Input string\n * @returns {string} UTF8 string\n */\nfunction str2rstrUTF8(input) {\n return unescape(encodeURIComponent(input));\n}\n\n/**\n * Encodes input string as raw MD5 string\n *\n * @param {string} s Input string\n * @returns {string} Raw MD5 string\n */\nfunction rawMD5(s) {\n return rstrMD5(str2rstrUTF8(s));\n}\n\n/**\n * Encodes input string as Hex encoded string\n *\n * @param {string} s Input string\n * @returns {string} Hex encoded string\n */\nfunction hexMD5(s) {\n return rstr2hex(rawMD5(s));\n}\n\n/**\n * Calculates the raw HMAC-MD5 for the given key and data\n *\n * @param {string} k HMAC key\n * @param {string} d Input string\n * @returns {string} Raw MD5 string\n */\nfunction rawHMACMD5(k, d) {\n return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d));\n}\n\n/**\n * Calculates the Hex encoded HMAC-MD5 for the given key and data\n *\n * @param {string} k HMAC key\n * @param {string} d Input string\n * @returns {string} Raw MD5 string\n */\nfunction hexHMACMD5(k, d) {\n return rstr2hex(rawHMACMD5(k, d));\n}\n\n/**\n * Calculates MD5 value for a given string.\n * If a key is provided, calculates the HMAC-MD5 value.\n * Returns a Hex encoded string unless the raw argument is given.\n *\n * @param {string} string Input string\n * @param {string} [key] HMAC key\n * @param {boolean} [raw] Raw output switch\n * @returns {string} MD5 output\n */\nexport function md5(string, key, raw) {\n if (!key) {\n if (!raw) {\n return hexMD5(string);\n }\n\n return rawMD5(string);\n }\n\n if (!raw) {\n return hexHMACMD5(key, string);\n }\n\n return rawHMACMD5(key, string);\n}\n","import { md5 } from './md5.js';\n\n/**\n * The intent of this function is to generate the suffix/postfix for the\n * css classes, based on the module-scoped path name.\n *\n * for example,\n * hash('my-app/components/foo')\n * instead of\n * hash('app/components/foo')\n *\n * (unless your app name is 'app')\n *\n * @param {string} modulePath\n * @returns {string}\n */\nexport function hash(modulePath) {\n return 'e' + md5(modulePath).substring(0, 8);\n}\n\nif (import.meta.vitest) {\n const { it, expect } = import.meta.vitest;\n\n it('should return a string', function () {\n const postfix = hash('foo.css');\n\n expect(postfix).to.be.a('string');\n });\n\n it('should return a string starting with \"e\"', function () {\n const postfix = hash('foo.css');\n\n expect(postfix).to.match(/^e/);\n });\n\n it('should return a string of length 9', function () {\n const postfix = hash('foo.css');\n\n expect(postfix).to.have.lengthOf(9);\n });\n}\n\nexport const hashFromModulePath = hash;\n","/**\n *\n * @param {string} className\n * @param {string} postfix\n * @param {Set<string>} [classesInCss]\n * @returns\n */\nexport function renameClass(className, postfix, classesInCss) {\n const classes = className.split(/\\s+/);\n const renamedClasses = classes\n .filter((c) => c)\n .map((c) => c.trim())\n .map((c) => {\n if (!classesInCss || classesInCss.has(c)) {\n if (c.endsWith(postfix)) return c;\n\n return c + '_' + postfix;\n }\n\n return c;\n })\n .join(' ');\n\n const renamedWithPreservedSpaces = className.replace(\n className.trimStart().trimEnd(),\n renamedClasses,\n );\n\n return renamedWithPreservedSpaces;\n}\n","import { hash } from '../lib/path/hash-from-module-path.js';\nimport { renameClass } from '../lib/renameClass.js';\n\n/**\n * On element selectors where there are no classes,\n * you may pass only the modulePath and get the hash for the element.\n *\n * For example, in app code,\n * with template code `<h3>x</h3>`\n * and css `h3 { }`\n * a class will be added during the build, result in:\n * the template: `<h3 class=\"some-hash\">x</h3>`\n * and css `h3.some-hash { }`\n *\n * @example\n * If a file is located at `app/components/foo/bar.hbs`\n * The associated css should be at `app/components/foo/bar.css`\n * and the path passed to `scopedClass` should be `<modulePrefix>/components/foo/bar`\n *\n * @example\n * If a file is located at `app/templates/bar.hbs`\n * The associated css should be at `app/templates/bar.css`\n * and the path passed to `scopedClass` should be `<modulePrefix>/templates/bar`\n *\n * @example\n * If a file is located at `<podModulePrefix>/bar/template.hbs`\n * The associated css should be at `app/<podModulePrefix sub path>/bar/styles.css`\n * and the path passed to `scopedClass` should be `<podModulePrefix>/bar`\n *\n */\nexport function scopedClass(modulePath: string): string;\n\n/**\n * Retrieve the built hash for a class.\n *\n * For example, in app code,\n * with template code `<h3 class=\"foo\">x</h3>`\n * and css `.foo { }`\n * a hash will be added during the build, resulting in:\n * the template: `<h3 class=\"foo_some-hash\">x</h3>`\n * and css `.foo_some-hash { }`\n *\n * @example\n * If a file is located at `app/components/foo/bar.hbs`\n * The associated css should be at `app/components/foo/bar.css`\n * and the path passed to `scopedClass` should be `<modulePrefix>/components/foo/bar`\n *\n * @example\n * If a file is located at `app/templates/bar.hbs`\n * The associated css should be at `app/templates/bar.css`\n * and the path passed to `scopedClass` should be `<modulePrefix>/templates/bar`\n *\n * @example\n * If a file is located at `<podModulePrefix>/bar/template.hbs`\n * The associated css should be at `app/<podModulePrefix sub path>/bar/styles.css`\n * and the path passed to `scopedClass` should be `<podModulePrefix>/bar`\n *\n */\nexport function scopedClass(className: string, modulePath: string): string;\n\nexport function scopedClass(\n ...args: [modulepath: string] | [className: string, modulePath: string]\n) {\n if (args.length === 1) {\n return hash(args[0]);\n }\n\n let [className, modulePath] = args;\n\n const postfix = hash(modulePath);\n\n return renameClass(className, postfix);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"test-support.js","names":["hash"],"sources":["../../src/lib/path/md5.js","../../src/lib/path/hash-from-module-path.js","../../src/lib/renameClass.js","../../src/runtime/test-support.ts"],"sourcesContent":["/*\n * JavaScript MD5\n * https://github.com/blueimp/JavaScript-MD5\n *\n * Copyright 2011, Sebastian Tschan\n * https://blueimp.net\n *\n * Licensed under the MIT license:\n * https://opensource.org/licenses/MIT\n *\n * Based on\n * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message\n * Digest Algorithm, as defined in RFC 1321.\n * Version 2.2 Copyright (C) Paul Johnston 1999 - 2009\n * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet\n * Distributed under the BSD License\n * See http://pajhome.org.uk/crypt/md5 for more info.\n *\n * Modifications:\n * - removed IIFE, exported md5 (this file is now ESM)\n */\n\n/**\n * Add integers, wrapping at 2^32.\n * This uses 16-bit operations internally to work around bugs in interpreters.\n *\n * @param {number} x First integer\n * @param {number} y Second integer\n * @returns {number} Sum\n */\nfunction safeAdd(x, y) {\n var lsw = (x & 0xffff) + (y & 0xffff);\n var msw = (x >> 16) + (y >> 16) + (lsw >> 16);\n\n return (msw << 16) | (lsw & 0xffff);\n}\n\n/**\n * Bitwise rotate a 32-bit number to the left.\n *\n * @param {number} num 32-bit number\n * @param {number} cnt Rotation count\n * @returns {number} Rotated number\n */\nfunction bitRotateLeft(num, cnt) {\n return (num << cnt) | (num >>> (32 - cnt));\n}\n\n/**\n * Basic operation the algorithm uses.\n *\n * @param {number} q q\n * @param {number} a a\n * @param {number} b b\n * @param {number} x x\n * @param {number} s s\n * @param {number} t t\n * @returns {number} Result\n */\nfunction md5cmn(q, a, b, x, s, t) {\n return safeAdd(bitRotateLeft(safeAdd(safeAdd(a, q), safeAdd(x, t)), s), b);\n}\n\n/**\n * Basic operation the algorithm uses.\n *\n * @param {number} a a\n * @param {number} b b\n * @param {number} c c\n * @param {number} d d\n * @param {number} x x\n * @param {number} s s\n * @param {number} t t\n * @returns {number} Result\n */\nfunction md5ff(a, b, c, d, x, s, t) {\n return md5cmn((b & c) | (~b & d), a, b, x, s, t);\n}\n\n/**\n * Basic operation the algorithm uses.\n *\n * @param {number} a a\n * @param {number} b b\n * @param {number} c c\n * @param {number} d d\n * @param {number} x x\n * @param {number} s s\n * @param {number} t t\n * @returns {number} Result\n */\nfunction md5gg(a, b, c, d, x, s, t) {\n return md5cmn((b & d) | (c & ~d), a, b, x, s, t);\n}\n\n/**\n * Basic operation the algorithm uses.\n *\n * @param {number} a a\n * @param {number} b b\n * @param {number} c c\n * @param {number} d d\n * @param {number} x x\n * @param {number} s s\n * @param {number} t t\n * @returns {number} Result\n */\nfunction md5hh(a, b, c, d, x, s, t) {\n return md5cmn(b ^ c ^ d, a, b, x, s, t);\n}\n\n/**\n * Basic operation the algorithm uses.\n *\n * @param {number} a a\n * @param {number} b b\n * @param {number} c c\n * @param {number} d d\n * @param {number} x x\n * @param {number} s s\n * @param {number} t t\n * @returns {number} Result\n */\nfunction md5ii(a, b, c, d, x, s, t) {\n return md5cmn(c ^ (b | ~d), a, b, x, s, t);\n}\n\n/**\n * Calculate the MD5 of an array of little-endian words, and a bit length.\n *\n * @param {Array} x Array of little-endian words\n * @param {number} len Bit length\n * @returns {Array<number>} MD5 Array\n */\nfunction binlMD5(x, len) {\n /* append padding */\n x[len >> 5] |= 0x80 << len % 32;\n x[(((len + 64) >>> 9) << 4) + 14] = len;\n\n var i;\n var olda;\n var oldb;\n var oldc;\n var oldd;\n var a = 1732584193;\n var b = -271733879;\n var c = -1732584194;\n var d = 271733878;\n\n for (i = 0; i < x.length; i += 16) {\n olda = a;\n oldb = b;\n oldc = c;\n oldd = d;\n\n a = md5ff(a, b, c, d, x[i], 7, -680876936);\n d = md5ff(d, a, b, c, x[i + 1], 12, -389564586);\n c = md5ff(c, d, a, b, x[i + 2], 17, 606105819);\n b = md5ff(b, c, d, a, x[i + 3], 22, -1044525330);\n a = md5ff(a, b, c, d, x[i + 4], 7, -176418897);\n d = md5ff(d, a, b, c, x[i + 5], 12, 1200080426);\n c = md5ff(c, d, a, b, x[i + 6], 17, -1473231341);\n b = md5ff(b, c, d, a, x[i + 7], 22, -45705983);\n a = md5ff(a, b, c, d, x[i + 8], 7, 1770035416);\n d = md5ff(d, a, b, c, x[i + 9], 12, -1958414417);\n c = md5ff(c, d, a, b, x[i + 10], 17, -42063);\n b = md5ff(b, c, d, a, x[i + 11], 22, -1990404162);\n a = md5ff(a, b, c, d, x[i + 12], 7, 1804603682);\n d = md5ff(d, a, b, c, x[i + 13], 12, -40341101);\n c = md5ff(c, d, a, b, x[i + 14], 17, -1502002290);\n b = md5ff(b, c, d, a, x[i + 15], 22, 1236535329);\n\n a = md5gg(a, b, c, d, x[i + 1], 5, -165796510);\n d = md5gg(d, a, b, c, x[i + 6], 9, -1069501632);\n c = md5gg(c, d, a, b, x[i + 11], 14, 643717713);\n b = md5gg(b, c, d, a, x[i], 20, -373897302);\n a = md5gg(a, b, c, d, x[i + 5], 5, -701558691);\n d = md5gg(d, a, b, c, x[i + 10], 9, 38016083);\n c = md5gg(c, d, a, b, x[i + 15], 14, -660478335);\n b = md5gg(b, c, d, a, x[i + 4], 20, -405537848);\n a = md5gg(a, b, c, d, x[i + 9], 5, 568446438);\n d = md5gg(d, a, b, c, x[i + 14], 9, -1019803690);\n c = md5gg(c, d, a, b, x[i + 3], 14, -187363961);\n b = md5gg(b, c, d, a, x[i + 8], 20, 1163531501);\n a = md5gg(a, b, c, d, x[i + 13], 5, -1444681467);\n d = md5gg(d, a, b, c, x[i + 2], 9, -51403784);\n c = md5gg(c, d, a, b, x[i + 7], 14, 1735328473);\n b = md5gg(b, c, d, a, x[i + 12], 20, -1926607734);\n\n a = md5hh(a, b, c, d, x[i + 5], 4, -378558);\n d = md5hh(d, a, b, c, x[i + 8], 11, -2022574463);\n c = md5hh(c, d, a, b, x[i + 11], 16, 1839030562);\n b = md5hh(b, c, d, a, x[i + 14], 23, -35309556);\n a = md5hh(a, b, c, d, x[i + 1], 4, -1530992060);\n d = md5hh(d, a, b, c, x[i + 4], 11, 1272893353);\n c = md5hh(c, d, a, b, x[i + 7], 16, -155497632);\n b = md5hh(b, c, d, a, x[i + 10], 23, -1094730640);\n a = md5hh(a, b, c, d, x[i + 13], 4, 681279174);\n d = md5hh(d, a, b, c, x[i], 11, -358537222);\n c = md5hh(c, d, a, b, x[i + 3], 16, -722521979);\n b = md5hh(b, c, d, a, x[i + 6], 23, 76029189);\n a = md5hh(a, b, c, d, x[i + 9], 4, -640364487);\n d = md5hh(d, a, b, c, x[i + 12], 11, -421815835);\n c = md5hh(c, d, a, b, x[i + 15], 16, 530742520);\n b = md5hh(b, c, d, a, x[i + 2], 23, -995338651);\n\n a = md5ii(a, b, c, d, x[i], 6, -198630844);\n d = md5ii(d, a, b, c, x[i + 7], 10, 1126891415);\n c = md5ii(c, d, a, b, x[i + 14], 15, -1416354905);\n b = md5ii(b, c, d, a, x[i + 5], 21, -57434055);\n a = md5ii(a, b, c, d, x[i + 12], 6, 1700485571);\n d = md5ii(d, a, b, c, x[i + 3], 10, -1894986606);\n c = md5ii(c, d, a, b, x[i + 10], 15, -1051523);\n b = md5ii(b, c, d, a, x[i + 1], 21, -2054922799);\n a = md5ii(a, b, c, d, x[i + 8], 6, 1873313359);\n d = md5ii(d, a, b, c, x[i + 15], 10, -30611744);\n c = md5ii(c, d, a, b, x[i + 6], 15, -1560198380);\n b = md5ii(b, c, d, a, x[i + 13], 21, 1309151649);\n a = md5ii(a, b, c, d, x[i + 4], 6, -145523070);\n d = md5ii(d, a, b, c, x[i + 11], 10, -1120210379);\n c = md5ii(c, d, a, b, x[i + 2], 15, 718787259);\n b = md5ii(b, c, d, a, x[i + 9], 21, -343485551);\n\n a = safeAdd(a, olda);\n b = safeAdd(b, oldb);\n c = safeAdd(c, oldc);\n d = safeAdd(d, oldd);\n }\n\n return [a, b, c, d];\n}\n\n/**\n * Convert an array of little-endian words to a string\n *\n * @param {Array<number>} input MD5 Array\n * @returns {string} MD5 string\n */\nfunction binl2rstr(input) {\n var i;\n var output = '';\n var length32 = input.length * 32;\n\n for (i = 0; i < length32; i += 8) {\n output += String.fromCharCode((input[i >> 5] >>> i % 32) & 0xff);\n }\n\n return output;\n}\n\n/**\n * Convert a raw string to an array of little-endian words\n * Characters >255 have their high-byte silently ignored.\n *\n * @param {string} input Raw input string\n * @returns {Array<number>} Array of little-endian words\n */\nfunction rstr2binl(input) {\n var i;\n var output = [];\n output[(input.length >> 2) - 1] = undefined;\n\n for (i = 0; i < output.length; i += 1) {\n output[i] = 0;\n }\n\n var length8 = input.length * 8;\n\n for (i = 0; i < length8; i += 8) {\n output[i >> 5] |= (input.charCodeAt(i / 8) & 0xff) << i % 32;\n }\n\n return output;\n}\n\n/**\n * Calculate the MD5 of a raw string\n *\n * @param {string} s Input string\n * @returns {string} Raw MD5 string\n */\nfunction rstrMD5(s) {\n return binl2rstr(binlMD5(rstr2binl(s), s.length * 8));\n}\n\n/**\n * Calculates the HMAC-MD5 of a key and some data (raw strings)\n *\n * @param {string} key HMAC key\n * @param {string} data Raw input string\n * @returns {string} Raw MD5 string\n */\nfunction rstrHMACMD5(key, data) {\n var i;\n var bkey = rstr2binl(key);\n var ipad = [];\n var opad = [];\n var hash;\n ipad[15] = opad[15] = undefined;\n\n if (bkey.length > 16) {\n bkey = binlMD5(bkey, key.length * 8);\n }\n\n for (i = 0; i < 16; i += 1) {\n ipad[i] = bkey[i] ^ 0x36363636;\n opad[i] = bkey[i] ^ 0x5c5c5c5c;\n }\n\n hash = binlMD5(ipad.concat(rstr2binl(data)), 512 + data.length * 8);\n\n return binl2rstr(binlMD5(opad.concat(hash), 512 + 128));\n}\n\n/**\n * Convert a raw string to a hex string\n *\n * @param {string} input Raw input string\n * @returns {string} Hex encoded string\n */\nfunction rstr2hex(input) {\n var hexTab = '0123456789abcdef';\n var output = '';\n var x;\n var i;\n\n for (i = 0; i < input.length; i += 1) {\n x = input.charCodeAt(i);\n output += hexTab.charAt((x >>> 4) & 0x0f) + hexTab.charAt(x & 0x0f);\n }\n\n return output;\n}\n\n/**\n * Encode a string as UTF-8\n *\n * @param {string} input Input string\n * @returns {string} UTF8 string\n */\nfunction str2rstrUTF8(input) {\n return unescape(encodeURIComponent(input));\n}\n\n/**\n * Encodes input string as raw MD5 string\n *\n * @param {string} s Input string\n * @returns {string} Raw MD5 string\n */\nfunction rawMD5(s) {\n return rstrMD5(str2rstrUTF8(s));\n}\n\n/**\n * Encodes input string as Hex encoded string\n *\n * @param {string} s Input string\n * @returns {string} Hex encoded string\n */\nfunction hexMD5(s) {\n return rstr2hex(rawMD5(s));\n}\n\n/**\n * Calculates the raw HMAC-MD5 for the given key and data\n *\n * @param {string} k HMAC key\n * @param {string} d Input string\n * @returns {string} Raw MD5 string\n */\nfunction rawHMACMD5(k, d) {\n return rstrHMACMD5(str2rstrUTF8(k), str2rstrUTF8(d));\n}\n\n/**\n * Calculates the Hex encoded HMAC-MD5 for the given key and data\n *\n * @param {string} k HMAC key\n * @param {string} d Input string\n * @returns {string} Raw MD5 string\n */\nfunction hexHMACMD5(k, d) {\n return rstr2hex(rawHMACMD5(k, d));\n}\n\n/**\n * Calculates MD5 value for a given string.\n * If a key is provided, calculates the HMAC-MD5 value.\n * Returns a Hex encoded string unless the raw argument is given.\n *\n * @param {string} string Input string\n * @param {string} [key] HMAC key\n * @param {boolean} [raw] Raw output switch\n * @returns {string} MD5 output\n */\nexport function md5(string, key, raw) {\n if (!key) {\n if (!raw) {\n return hexMD5(string);\n }\n\n return rawMD5(string);\n }\n\n if (!raw) {\n return hexHMACMD5(key, string);\n }\n\n return rawHMACMD5(key, string);\n}\n","import { md5 } from './md5.js';\n\n/**\n * The intent of this function is to generate the suffix/postfix for the\n * css classes, based on the module-scoped path name.\n *\n * for example,\n * hash('my-app/components/foo')\n * instead of\n * hash('app/components/foo')\n *\n * (unless your app name is 'app')\n *\n * @param {string} modulePath\n * @returns {string}\n */\nexport function hash(modulePath) {\n return 'e' + md5(modulePath).substring(0, 8);\n}\n\nif (import.meta.vitest) {\n const { it, expect } = import.meta.vitest;\n\n it('should return a string', function () {\n const postfix = hash('foo.css');\n\n expect(postfix).to.be.a('string');\n });\n\n it('should return a string starting with \"e\"', function () {\n const postfix = hash('foo.css');\n\n expect(postfix).to.match(/^e/);\n });\n\n it('should return a string of length 9', function () {\n const postfix = hash('foo.css');\n\n expect(postfix).to.have.lengthOf(9);\n });\n}\n\nexport const hashFromModulePath = hash;\n","/**\n * Splits a space-separated class list (the value of a `class` attribute or of\n * a `[class=\"...\"]` selector) into its individual class names.\n *\n * @param {string} classList\n * @returns {string[]}\n */\nexport function splitClassList(classList) {\n return classList.split(/\\s+/).filter(Boolean);\n}\n\n/**\n *\n * @param {string} className\n * @param {string} postfix\n * @param {Set<string>} [classesInCss]\n * @returns\n */\nexport function renameClass(className, postfix, classesInCss) {\n const renamedClasses = splitClassList(className)\n .map((c) => {\n if (!classesInCss || classesInCss.has(c)) {\n if (c.endsWith(postfix)) return c;\n\n return c + '_' + postfix;\n }\n\n return c;\n })\n .join(' ');\n\n const renamedWithPreservedSpaces = className.replace(\n className.trimStart().trimEnd(),\n renamedClasses,\n );\n\n return renamedWithPreservedSpaces;\n}\n","import { hash } from '../lib/path/hash-from-module-path.js';\nimport { renameClass } from '../lib/renameClass.js';\n\n/**\n * On element selectors where there are no classes,\n * you may pass only the modulePath and get the hash for the element.\n *\n * For example, in app code,\n * with template code `<h3>x</h3>`\n * and css `h3 { }`\n * a class will be added during the build, result in:\n * the template: `<h3 class=\"some-hash\">x</h3>`\n * and css `h3.some-hash { }`\n *\n * @example\n * If a file is located at `app/components/foo/bar.hbs`\n * The associated css should be at `app/components/foo/bar.css`\n * and the path passed to `scopedClass` should be `<modulePrefix>/components/foo/bar`\n *\n * @example\n * If a file is located at `app/templates/bar.hbs`\n * The associated css should be at `app/templates/bar.css`\n * and the path passed to `scopedClass` should be `<modulePrefix>/templates/bar`\n *\n * @example\n * If a file is located at `<podModulePrefix>/bar/template.hbs`\n * The associated css should be at `app/<podModulePrefix sub path>/bar/styles.css`\n * and the path passed to `scopedClass` should be `<podModulePrefix>/bar`\n *\n */\nexport function scopedClass(modulePath: string): string;\n\n/**\n * Retrieve the built hash for a class.\n *\n * For example, in app code,\n * with template code `<h3 class=\"foo\">x</h3>`\n * and css `.foo { }`\n * a hash will be added during the build, resulting in:\n * the template: `<h3 class=\"foo_some-hash\">x</h3>`\n * and css `.foo_some-hash { }`\n *\n * @example\n * If a file is located at `app/components/foo/bar.hbs`\n * The associated css should be at `app/components/foo/bar.css`\n * and the path passed to `scopedClass` should be `<modulePrefix>/components/foo/bar`\n *\n * @example\n * If a file is located at `app/templates/bar.hbs`\n * The associated css should be at `app/templates/bar.css`\n * and the path passed to `scopedClass` should be `<modulePrefix>/templates/bar`\n *\n * @example\n * If a file is located at `<podModulePrefix>/bar/template.hbs`\n * The associated css should be at `app/<podModulePrefix sub path>/bar/styles.css`\n * and the path passed to `scopedClass` should be `<podModulePrefix>/bar`\n *\n */\nexport function scopedClass(className: string, modulePath: string): string;\n\nexport function scopedClass(\n ...args: [modulepath: string] | [className: string, modulePath: string]\n) {\n if (args.length === 1) {\n return hash(args[0]);\n }\n\n let [className, modulePath] = args;\n\n const postfix = hash(modulePath);\n\n return renameClass(className, postfix);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ember-scoped-css",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ember-addon"
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
"dist",
|
|
20
20
|
"declarations",
|
|
21
21
|
"addon-main.cjs",
|
|
22
|
-
"template-registry.d.ts"
|
|
22
|
+
"template-registry.d.ts",
|
|
23
|
+
"types.d.ts"
|
|
23
24
|
],
|
|
24
25
|
"exports": {
|
|
25
26
|
".": {
|
|
@@ -42,6 +43,10 @@
|
|
|
42
43
|
"types": "./template-registry.d.ts",
|
|
43
44
|
"default": "./src/noop.js"
|
|
44
45
|
},
|
|
46
|
+
"./types": {
|
|
47
|
+
"types": "./types.d.ts",
|
|
48
|
+
"default": "./src/noop.js"
|
|
49
|
+
},
|
|
45
50
|
"./test-support": {
|
|
46
51
|
"types": "./declarations/runtime/test-support.d.ts",
|
|
47
52
|
"default": "./dist/runtime/test-support.js"
|
|
@@ -64,7 +64,15 @@ export function createPlugin(config) {
|
|
|
64
64
|
let scopedClasses = new Set();
|
|
65
65
|
|
|
66
66
|
/**
|
|
67
|
-
*
|
|
67
|
+
* The attribute names found in attribute selectors in the CSS, used to
|
|
68
|
+
* mark matching elements with the scope class.
|
|
69
|
+
*
|
|
70
|
+
* @type {Set<string>}
|
|
71
|
+
*/
|
|
72
|
+
let scopedAttributes = new Set();
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* @param {{ tags: Set<string>; classes: Set<string>; attributes: Set<string> }} info
|
|
68
76
|
*/
|
|
69
77
|
function addInfo(info) {
|
|
70
78
|
for (let item of info.tags) {
|
|
@@ -74,6 +82,10 @@ export function createPlugin(config) {
|
|
|
74
82
|
for (let item of info.classes) {
|
|
75
83
|
scopedClasses.add(item);
|
|
76
84
|
}
|
|
85
|
+
|
|
86
|
+
for (let item of info.attributes) {
|
|
87
|
+
scopedAttributes.add(item);
|
|
88
|
+
}
|
|
77
89
|
}
|
|
78
90
|
|
|
79
91
|
let cssPath = cssPathFor(absolutePath);
|
|
@@ -98,6 +110,7 @@ export function createPlugin(config) {
|
|
|
98
110
|
let visitors = templatePlugin({
|
|
99
111
|
classes: scopedClasses,
|
|
100
112
|
tags: scopedTags,
|
|
113
|
+
attributes: scopedAttributes,
|
|
101
114
|
postfix,
|
|
102
115
|
});
|
|
103
116
|
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import postcss from 'postcss';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
|
|
4
|
+
import { rewriteCss } from './rewrite.js';
|
|
5
|
+
|
|
6
|
+
/** Rewrite a single rule and return just the scoped selector. */
|
|
7
|
+
function scopeSelector(css) {
|
|
8
|
+
const rewritten = rewriteCss(css, 'postfix', 'foo.css');
|
|
9
|
+
|
|
10
|
+
let selector = '';
|
|
11
|
+
|
|
12
|
+
postcss.parse(rewritten).walkRules((rule) => {
|
|
13
|
+
selector ||= rule.selector;
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
return selector;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
describe('attribute selectors', () => {
|
|
20
|
+
it('scopes a bare attribute selector with the postfix class', () => {
|
|
21
|
+
expect(scopeSelector('[disabled] { color: red; }')).to.equal(
|
|
22
|
+
'[disabled].postfix',
|
|
23
|
+
);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
it('scopes an attribute selector with a value', () => {
|
|
27
|
+
expect(scopeSelector('[type="text"] { color: red; }')).to.equal(
|
|
28
|
+
'[type="text"].postfix',
|
|
29
|
+
);
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
it('preserves the case-insensitive flag', () => {
|
|
33
|
+
expect(scopeSelector('[href^="http" i] { color: red; }')).to.equal(
|
|
34
|
+
'[href^="http" i].postfix',
|
|
35
|
+
);
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
it('adds the postfix class once for a tag + attribute compound', () => {
|
|
39
|
+
expect(scopeSelector('input[type="text"] { color: red; }')).to.equal(
|
|
40
|
+
'input.postfix[type="text"]',
|
|
41
|
+
);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
it('adds the postfix class once for multiple attributes in a compound', () => {
|
|
45
|
+
expect(
|
|
46
|
+
scopeSelector('[data-state="open"][role="dialog"] { color: red; }'),
|
|
47
|
+
).to.equal('[data-state="open"].postfix[role="dialog"]');
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
it('scopes each compound of a descendant selector', () => {
|
|
51
|
+
expect(scopeSelector('[data-x] [data-y] { color: red; }')).to.equal(
|
|
52
|
+
'[data-x].postfix [data-y].postfix',
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('does not scope attribute selectors inside :global', () => {
|
|
57
|
+
expect(scopeSelector(':global([data-x]) { color: red; }')).to.equal(
|
|
58
|
+
'[data-x]',
|
|
59
|
+
);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
describe('class-targeting operators', () => {
|
|
63
|
+
it('rewrites the value for ~= (renamed value, no postfix class)', () => {
|
|
64
|
+
expect(scopeSelector('[class~="foo"] { color: red; }')).to.equal(
|
|
65
|
+
'[class~="foo_postfix"]',
|
|
66
|
+
);
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it('rewrites every token for = (renamed value, no postfix class)', () => {
|
|
70
|
+
expect(scopeSelector('[class="foo bar"] { color: red; }')).to.equal(
|
|
71
|
+
'[class="foo_postfix bar_postfix"]',
|
|
72
|
+
);
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
it('keeps the value and adds the postfix class for ^=', () => {
|
|
76
|
+
expect(scopeSelector('[class^="foo"] { color: red; }')).to.equal(
|
|
77
|
+
'[class^="foo"].postfix',
|
|
78
|
+
);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
it('keeps the value and adds the postfix class for *=', () => {
|
|
82
|
+
expect(scopeSelector('[class*="foo"] { color: red; }')).to.equal(
|
|
83
|
+
'[class*="foo"].postfix',
|
|
84
|
+
);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
it('keeps the value and adds the postfix class for $=', () => {
|
|
88
|
+
expect(scopeSelector('[class$="foo"] { color: red; }')).to.equal(
|
|
89
|
+
'[class$="foo"].postfix',
|
|
90
|
+
);
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
it('falls back to the postfix class for |= (no runtime warning)', () => {
|
|
94
|
+
expect(scopeSelector('[class|="foo"] { color: red; }')).to.equal(
|
|
95
|
+
'[class|="foo"].postfix',
|
|
96
|
+
);
|
|
97
|
+
});
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
describe('functional pseudo-classes', () => {
|
|
101
|
+
it('scopes via the outer compound for button:not([disabled])', () => {
|
|
102
|
+
expect(scopeSelector('button:not([disabled]) { color: red; }')).to.equal(
|
|
103
|
+
'button.postfix:not([disabled].postfix)',
|
|
104
|
+
);
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
it('rewrites a standalone :not (documented leak — no outer anchor)', () => {
|
|
108
|
+
expect(scopeSelector(':not([disabled]) { color: red; }')).to.equal(
|
|
109
|
+
':not([disabled].postfix)',
|
|
110
|
+
);
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
it('scopes attributes inside :is()', () => {
|
|
114
|
+
expect(scopeSelector(':is([type="text"]) { color: red; }')).to.equal(
|
|
115
|
+
':is([type="text"].postfix)',
|
|
116
|
+
);
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
});
|
package/src/lib/css/rewrite.js
CHANGED
|
@@ -5,7 +5,8 @@
|
|
|
5
5
|
import postcss from 'postcss';
|
|
6
6
|
import parser from 'postcss-selector-parser';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { renameClass } from '../renameClass.js';
|
|
9
|
+
import { isInsideGlobal, isRenamedClassAttribute } from './utils.js';
|
|
9
10
|
|
|
10
11
|
const SEP = '__';
|
|
11
12
|
|
|
@@ -33,8 +34,44 @@ function rewriteReferenceable(node, postfix) {
|
|
|
33
34
|
};
|
|
34
35
|
}
|
|
35
36
|
|
|
37
|
+
/**
|
|
38
|
+
* Walk left and right from `node` within its compound selector (bounded by
|
|
39
|
+
* combinators) to see if the postfix class has already been added. Used to add
|
|
40
|
+
* the postfix class at most once per compound, e.g. `input[type="text"]`
|
|
41
|
+
* becomes `input.postfix[type="text"]`, not `input.postfix[type="text"].postfix`.
|
|
42
|
+
*/
|
|
43
|
+
function compoundHasPostfixClass(node, postfix) {
|
|
44
|
+
const siblings = node.parent.nodes;
|
|
45
|
+
const index = siblings.indexOf(node);
|
|
46
|
+
|
|
47
|
+
for (let i = index; i >= 0; i--) {
|
|
48
|
+
if (siblings[i].type === 'combinator') break;
|
|
49
|
+
if (siblings[i].type === 'class' && siblings[i].value === postfix)
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
for (let i = index + 1; i < siblings.length; i++) {
|
|
54
|
+
if (siblings[i].type === 'combinator') break;
|
|
55
|
+
if (siblings[i].type === 'class' && siblings[i].value === postfix)
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function addPostfixClass(node, postfix) {
|
|
63
|
+
if (compoundHasPostfixClass(node, postfix)) return;
|
|
64
|
+
|
|
65
|
+
node.parent.insertAfter(node, parser.className({ value: postfix }));
|
|
66
|
+
}
|
|
67
|
+
|
|
36
68
|
function rewriteSelector(sel, postfix) {
|
|
37
69
|
const transform = (selectors) => {
|
|
70
|
+
// Nodes that need the postfix class added next to them. We collect them
|
|
71
|
+
// during the walk and insert the classes afterwards so the freshly-inserted
|
|
72
|
+
// classes are never themselves re-visited by the walk.
|
|
73
|
+
const needsPostfixClass = [];
|
|
74
|
+
|
|
38
75
|
selectors.walk((selector) => {
|
|
39
76
|
if (isInsideGlobal(selector)) return;
|
|
40
77
|
|
|
@@ -50,13 +87,28 @@ function rewriteSelector(sel, postfix) {
|
|
|
50
87
|
if (selector.type === 'class') {
|
|
51
88
|
selector.value += '_' + postfix;
|
|
52
89
|
} else if (selector.type === 'tag') {
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
90
|
+
needsPostfixClass.push(selector);
|
|
91
|
+
} else if (selector.type === 'attribute') {
|
|
92
|
+
if (isRenamedClassAttribute(selector)) {
|
|
93
|
+
// The renamed token (e.g. `foo_postfix`) is already unique per
|
|
94
|
+
// file, so no postfix class is needed.
|
|
95
|
+
selector.value = renameClass(selector.value, postfix);
|
|
96
|
+
if (!selector.quoteMark) selector.quoteMark = '"';
|
|
97
|
+
} else {
|
|
98
|
+
// `[class|="foo"]` and `[class$="foo"]` cannot be reliably scoped
|
|
99
|
+
// with the postfix class (the postfix class defeats them). That is
|
|
100
|
+
// surfaced to authors by the
|
|
101
|
+
// `ember-scoped-css/no-unscopable-class-attribute-selectors`
|
|
102
|
+
// stylelint rule rather than a runtime warning.
|
|
103
|
+
needsPostfixClass.push(selector);
|
|
104
|
+
}
|
|
57
105
|
}
|
|
58
106
|
});
|
|
59
107
|
|
|
108
|
+
for (const node of needsPostfixClass) {
|
|
109
|
+
addPostfixClass(node, postfix);
|
|
110
|
+
}
|
|
111
|
+
|
|
60
112
|
// remove :global
|
|
61
113
|
selectors.walk((selector) => {
|
|
62
114
|
if (selector.type === 'pseudo' && selector.value === ':global') {
|
package/src/lib/css/utils.js
CHANGED
|
@@ -4,6 +4,7 @@ import scssSyntax from 'postcss-scss';
|
|
|
4
4
|
import parser from 'postcss-selector-parser';
|
|
5
5
|
|
|
6
6
|
import { md5 } from '../path/md5.js';
|
|
7
|
+
import { splitClassList } from '../renameClass.js';
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* @param {string} css
|
|
@@ -13,6 +14,34 @@ export function hash(css) {
|
|
|
13
14
|
return `css-${md5(css)}`;
|
|
14
15
|
}
|
|
15
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Attribute selectors are scoped with one of two strategies:
|
|
19
|
+
*
|
|
20
|
+
* - **renamed value**: class-targeting selectors whose value names real
|
|
21
|
+
* class(es) (`[class="foo"]`, `[class~="foo"]`) are scoped by renaming the
|
|
22
|
+
* value the same way `.foo` is renamed to `.foo_postfix`. The renamed token
|
|
23
|
+
* is unique per file, so nothing else is needed.
|
|
24
|
+
* - **postfix class**: every other attribute selector keeps its discriminator
|
|
25
|
+
* and is scoped by the generated postfix class — appended to the selector
|
|
26
|
+
* in the CSS and added to matching elements in the template (the same
|
|
27
|
+
* strategy bare tag selectors use: `div` becomes `div.postfix`).
|
|
28
|
+
*
|
|
29
|
+
* This predicate decides between the two. It is shared by the CSS rewrite
|
|
30
|
+
* (which renames the selector value) and by discovery in this file (which
|
|
31
|
+
* registers the value's class names for template renaming) so both sides
|
|
32
|
+
* always classify a selector the same way.
|
|
33
|
+
*
|
|
34
|
+
* @param {import('postcss-selector-parser').Attribute} node
|
|
35
|
+
* @returns {boolean}
|
|
36
|
+
*/
|
|
37
|
+
export function isRenamedClassAttribute(node) {
|
|
38
|
+
return (
|
|
39
|
+
node.attribute === 'class' &&
|
|
40
|
+
(node.operator === '=' || node.operator === '~=') &&
|
|
41
|
+
Boolean(node.value)
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
16
45
|
export function isInsideGlobal(node, func) {
|
|
17
46
|
const parent = node.parent;
|
|
18
47
|
|
|
@@ -41,11 +70,12 @@ export function getCSSInfo(cssPath) {
|
|
|
41
70
|
*
|
|
42
71
|
* @param {string} css the CSS's contents
|
|
43
72
|
* @param {string} [lang] optional language hint (e.g. 'scss', 'sass', 'less')
|
|
44
|
-
* @return {{ classes: Set<string>, tags: Set<string>, css: string, id: string }}
|
|
73
|
+
* @return {{ classes: Set<string>, tags: Set<string>, attributes: Set<string>, css: string, id: string }}
|
|
45
74
|
*/
|
|
46
75
|
export function getCSSContentInfo(css, lang) {
|
|
47
76
|
const classes = new Set();
|
|
48
77
|
const tags = new Set();
|
|
78
|
+
const attributes = new Set();
|
|
49
79
|
|
|
50
80
|
const parseOptions =
|
|
51
81
|
lang === 'scss' || lang === 'sass' ? { syntax: scssSyntax } : {};
|
|
@@ -58,13 +88,13 @@ export function getCSSContentInfo(css, lang) {
|
|
|
58
88
|
if (node.type === 'rule') {
|
|
59
89
|
const selector = isScss ? resolveNestedSassSelector(node) : node.selector;
|
|
60
90
|
|
|
61
|
-
|
|
91
|
+
collectSelectorInfo(selector, classes, tags, attributes);
|
|
62
92
|
}
|
|
63
93
|
});
|
|
64
94
|
|
|
65
95
|
let id = hash(css);
|
|
66
96
|
|
|
67
|
-
return { classes, tags, css, id };
|
|
97
|
+
return { classes, tags, attributes, css, id };
|
|
68
98
|
}
|
|
69
99
|
|
|
70
100
|
/**
|
|
@@ -97,13 +127,38 @@ function resolveNestedSassSelector(node) {
|
|
|
97
127
|
return selector.replace(/&/g, resolvedParent);
|
|
98
128
|
}
|
|
99
129
|
|
|
100
|
-
function
|
|
130
|
+
function collectSelectorInfo(sel, classes, tags, attributes) {
|
|
101
131
|
const transform = (sls) => {
|
|
102
132
|
sls.walk((selector) => {
|
|
103
|
-
if (
|
|
133
|
+
if (isInsideGlobal(selector)) return;
|
|
134
|
+
|
|
135
|
+
if (selector.type === 'class') {
|
|
104
136
|
classes.add(selector.value);
|
|
105
|
-
} else if (selector.type === 'tag'
|
|
137
|
+
} else if (selector.type === 'tag') {
|
|
106
138
|
tags.add(selector.value);
|
|
139
|
+
} else if (selector.type === 'attribute') {
|
|
140
|
+
if (isRenamedClassAttribute(selector)) {
|
|
141
|
+
// Register the value's class names so the template renames them.
|
|
142
|
+
//
|
|
143
|
+
// postcss-selector-parser exposes the attribute value only as an
|
|
144
|
+
// opaque string, so splitting `[class="foo bar"]` into its
|
|
145
|
+
// space-separated class names is on us — `splitClassList` is the
|
|
146
|
+
// same tokenization `renameClass` applies.
|
|
147
|
+
for (let token of splitClassList(selector.value)) {
|
|
148
|
+
classes.add(token);
|
|
149
|
+
}
|
|
150
|
+
} else {
|
|
151
|
+
// Elements carrying this attribute get the postfix class. For
|
|
152
|
+
// class-target operators (^=, *=, $=, |=) and presence, the name
|
|
153
|
+
// is `class`.
|
|
154
|
+
//
|
|
155
|
+
// CSS matches HTML attribute names case-insensitively, so store the
|
|
156
|
+
// name lowercased and compare against lowercased template attribute
|
|
157
|
+
// names. (Coarser than SVG's case-sensitive matching, but the two
|
|
158
|
+
// sides always agree; worst case an element gets the postfix class
|
|
159
|
+
// it didn't strictly need.)
|
|
160
|
+
attributes.add(selector.attribute.toLowerCase());
|
|
161
|
+
}
|
|
107
162
|
}
|
|
108
163
|
});
|
|
109
164
|
};
|
|
@@ -125,6 +180,43 @@ if (import.meta.vitest) {
|
|
|
125
180
|
expect([...tags]).to.have.members(['div']);
|
|
126
181
|
});
|
|
127
182
|
|
|
183
|
+
it('collects attribute names for postfix-class scoping', function () {
|
|
184
|
+
const css = '[disabled] [data-x="y"] { color: red; }';
|
|
185
|
+
const { attributes } = getCSSContentInfo(css);
|
|
186
|
+
|
|
187
|
+
expect(attributes).to.deep.equal(new Set(['disabled', 'data-x']));
|
|
188
|
+
});
|
|
189
|
+
|
|
190
|
+
it('treats =/~= class attribute values as renamed classes', function () {
|
|
191
|
+
const css = '[class="foo bar"] [class~="baz"] { color: red; }';
|
|
192
|
+
const { classes, attributes } = getCSSContentInfo(css);
|
|
193
|
+
|
|
194
|
+
expect(classes).to.deep.equal(new Set(['foo', 'bar', 'baz']));
|
|
195
|
+
expect(attributes).to.deep.equal(new Set());
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it('treats other class attribute operators as postfix-class attributes', function () {
|
|
199
|
+
const css = '[class^="foo"] [class*="bar"] { color: red; }';
|
|
200
|
+
const { classes, attributes } = getCSSContentInfo(css);
|
|
201
|
+
|
|
202
|
+
expect(classes).to.deep.equal(new Set());
|
|
203
|
+
expect(attributes).to.deep.equal(new Set(['class']));
|
|
204
|
+
});
|
|
205
|
+
|
|
206
|
+
it('lowercases attribute names (CSS matches them case-insensitively)', function () {
|
|
207
|
+
const css = '[TYPE="submit"] { color: red; }';
|
|
208
|
+
const { attributes } = getCSSContentInfo(css);
|
|
209
|
+
|
|
210
|
+
expect(attributes).to.deep.equal(new Set(['type']));
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
it('ignores attribute selectors inside :global', function () {
|
|
214
|
+
const css = ':global([data-x]) [data-y] { color: red; }';
|
|
215
|
+
const { attributes } = getCSSContentInfo(css);
|
|
216
|
+
|
|
217
|
+
expect(attributes).to.deep.equal(new Set(['data-y']));
|
|
218
|
+
});
|
|
219
|
+
|
|
128
220
|
it('should parse SCSS nesting syntax without crashing when lang=scss', function () {
|
|
129
221
|
const scss = `
|
|
130
222
|
$base-color: #c6538c;
|
package/src/lib/renameClass.js
CHANGED
|
@@ -1,3 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Splits a space-separated class list (the value of a `class` attribute or of
|
|
3
|
+
* a `[class="..."]` selector) into its individual class names.
|
|
4
|
+
*
|
|
5
|
+
* @param {string} classList
|
|
6
|
+
* @returns {string[]}
|
|
7
|
+
*/
|
|
8
|
+
export function splitClassList(classList) {
|
|
9
|
+
return classList.split(/\s+/).filter(Boolean);
|
|
10
|
+
}
|
|
11
|
+
|
|
1
12
|
/**
|
|
2
13
|
*
|
|
3
14
|
* @param {string} className
|
|
@@ -6,10 +17,7 @@
|
|
|
6
17
|
* @returns
|
|
7
18
|
*/
|
|
8
19
|
export function renameClass(className, postfix, classesInCss) {
|
|
9
|
-
const
|
|
10
|
-
const renamedClasses = classes
|
|
11
|
-
.filter((c) => c)
|
|
12
|
-
.map((c) => c.trim())
|
|
20
|
+
const renamedClasses = splitClassList(className)
|
|
13
21
|
.map((c) => {
|
|
14
22
|
if (!classesInCss || classesInCss.has(c)) {
|
|
15
23
|
if (c.endsWith(postfix)) return c;
|