@gem-sdk/hash-class-names 1.11.0 → 1.11.1-experimental-f662f2d9

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.
@@ -2,7 +2,7 @@
2
2
 
3
3
  // https://drafts.csswg.org/cssom/#serialize-an-identifier
4
4
  // repo: https://github.com/mathiasbynens/CSS.escape
5
- const cssEscape = function(value) {
5
+ const cssEscape = function (value) {
6
6
  if (arguments.length == 0) {
7
7
  throw new TypeError('`CSS.escape` requires an argument.');
8
8
  }
@@ -12,12 +12,14 @@ const cssEscape = function(value) {
12
12
  let codeUnit;
13
13
  let result = '';
14
14
  const firstCodeUnit = string.charCodeAt(0);
15
- if (// If the character is the first character and is a `-` (U+002D), and
15
+ if (
16
+ // If the character is the first character and is a `-` (U+002D), and
16
17
  // there is no second character, […]
17
- length == 1 && firstCodeUnit == 0x002d) {
18
+ length == 1 &&
19
+ firstCodeUnit == 0x002d) {
18
20
  return '\\' + string;
19
21
  }
20
- while(++index < length){
22
+ while (++index < length) {
21
23
  codeUnit = string.charCodeAt(index);
22
24
  // Note: there’s no need to special-case astral symbols, surrogate
23
25
  // pairs, or lone surrogates.
@@ -27,13 +29,17 @@ const cssEscape = function(value) {
27
29
  result += '\uFFFD';
28
30
  continue;
29
31
  }
30
- if (// If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
32
+ if (
33
+ // If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
31
34
  // U+007F, […]
32
- codeUnit >= 0x0001 && codeUnit <= 0x001f || codeUnit == 0x007f || // If the character is the first character and is in the range [0-9]
33
- // (U+0030 to U+0039), […]
34
- index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039 || // If the character is the second character and is in the range [0-9]
35
- // (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
36
- index == 1 && codeUnit >= 0x0030 && codeUnit <= 0x0039 && firstCodeUnit == 0x002d) {
35
+ (codeUnit >= 0x0001 && codeUnit <= 0x001f) ||
36
+ codeUnit == 0x007f ||
37
+ // If the character is the first character and is in the range [0-9]
38
+ // (U+0030 to U+0039), […]
39
+ (index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) ||
40
+ // If the character is the second character and is in the range [0-9]
41
+ // (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
42
+ (index == 1 && codeUnit >= 0x0030 && codeUnit <= 0x0039 && firstCodeUnit == 0x002d)) {
37
43
  // https://drafts.csswg.org/cssom/#escape-a-character-as-code-point
38
44
  result += '\\' + codeUnit.toString(16) + ' ';
39
45
  continue;
@@ -42,7 +48,12 @@ const cssEscape = function(value) {
42
48
  // greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or
43
49
  // is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to
44
50
  // U+005A), or [a-z] (U+0061 to U+007A), […]
45
- if (codeUnit >= 0x0080 || codeUnit == 0x002d || codeUnit == 0x005f || codeUnit >= 0x0030 && codeUnit <= 0x0039 || codeUnit >= 0x0041 && codeUnit <= 0x005a || codeUnit >= 0x0061 && codeUnit <= 0x007a) {
51
+ if (codeUnit >= 0x0080 ||
52
+ codeUnit == 0x002d ||
53
+ codeUnit == 0x005f ||
54
+ (codeUnit >= 0x0030 && codeUnit <= 0x0039) ||
55
+ (codeUnit >= 0x0041 && codeUnit <= 0x005a) ||
56
+ (codeUnit >= 0x0061 && codeUnit <= 0x007a)) {
46
57
  // the character itself
47
58
  result += string.charAt(index);
48
59
  continue;
@@ -1,16 +1,16 @@
1
1
  'use strict';
2
2
 
3
- const cssToJson = (str)=>{
3
+ const cssToJson = (str) => {
4
4
  let style = str;
5
5
  const jsonCSS = {
6
6
  children: {},
7
- attributes: ''
7
+ attributes: '',
8
8
  };
9
9
  const mediaQuery = {};
10
10
  // eslint-disable-next-line regexp/prefer-d, no-useless-escape, regexp/no-dupe-characters-character-class, regexp/no-useless-escape, regexp/strict, regexp/no-obscure-range, regexp/no-useless-flag, regexp/no-super-linear-backtracking
11
11
  const regex = /(@media[^{]+\)).*?{([\s\S]+?})\s*}/g;
12
12
  let m;
13
- while((m = regex.exec(str)) !== null){
13
+ while ((m = regex.exec(str)) !== null) {
14
14
  // This is necessary to avoid infinite loops with zero-width matches
15
15
  if (m.index === regex.lastIndex) {
16
16
  regex.lastIndex++;
@@ -18,9 +18,9 @@ const cssToJson = (str)=>{
18
18
  // The result can be accessed through the `m`-variable.
19
19
  const css = {
20
20
  media: '',
21
- style: ''
21
+ style: '',
22
22
  };
23
- m.forEach((match, groupIndex)=>{
23
+ m.forEach((match, groupIndex) => {
24
24
  if (groupIndex == 0) {
25
25
  style = style.replaceAll(match, '');
26
26
  }
@@ -36,31 +36,31 @@ const cssToJson = (str)=>{
36
36
  }
37
37
  // Parse css root
38
38
  const cssRoot = parseCSS(style);
39
- for(const key in cssRoot){
39
+ for (const key in cssRoot) {
40
40
  if (Object.prototype.hasOwnProperty.call(cssRoot, key)) {
41
41
  const value = cssRoot[key];
42
42
  jsonCSS.children[key] = {
43
43
  children: {},
44
- attributes: value
44
+ attributes: value,
45
45
  };
46
46
  }
47
47
  }
48
48
  // Append css media
49
- for(const media in mediaQuery){
49
+ for (const media in mediaQuery) {
50
50
  if (Object.prototype.hasOwnProperty.call(mediaQuery, media)) {
51
51
  const css = mediaQuery[media];
52
52
  if (css?.length) {
53
53
  const jsonQueryCss = {
54
54
  children: {},
55
- attributes: ''
55
+ attributes: '',
56
56
  };
57
57
  const cssQuery = parseCSS(css?.join(''));
58
- for(const key in cssQuery){
58
+ for (const key in cssQuery) {
59
59
  if (Object.prototype.hasOwnProperty.call(cssQuery, key)) {
60
60
  const value = cssQuery[key];
61
61
  jsonQueryCss.children[key] = {
62
62
  children: {},
63
- attributes: value
63
+ attributes: value,
64
64
  };
65
65
  }
66
66
  }
@@ -70,10 +70,10 @@ const cssToJson = (str)=>{
70
70
  }
71
71
  return jsonCSS;
72
72
  };
73
- const jsonToCss = (jsonCSS, selector)=>{
73
+ const jsonToCss = (jsonCSS, selector) => {
74
74
  // Replace selector
75
75
  let value = '';
76
- for(const selector in jsonCSS.children){
76
+ for (const selector in jsonCSS.children) {
77
77
  if (Object.prototype.hasOwnProperty.call(jsonCSS.children, selector)) {
78
78
  const style = jsonCSS.children[selector];
79
79
  if (style) {
@@ -86,16 +86,17 @@ const jsonToCss = (jsonCSS, selector)=>{
86
86
  }
87
87
  if (selector) {
88
88
  return `${selector}{${value}}`;
89
- } else {
89
+ }
90
+ else {
90
91
  return value;
91
92
  }
92
93
  };
93
- const parseCSS = (css)=>{
94
+ const parseCSS = (css) => {
94
95
  const cssJSON = {};
95
96
  // eslint-disable-next-line regexp/prefer-d, no-useless-escape, regexp/no-dupe-characters-character-class, regexp/no-useless-escape, regexp/strict, regexp/no-obscure-range, regexp/no-useless-flag, regexp/no-super-linear-backtracking, regexp/prefer-character-class, regexp/no-dupe-disjunctions
96
97
  const cssRegex = /((.|\n|\r|\t)*?){((.|\n|\r|\t)*?)}/gm;
97
98
  let mCSS;
98
- while((mCSS = cssRegex.exec(css)) !== null){
99
+ while ((mCSS = cssRegex.exec(css)) !== null) {
99
100
  // This is necessary to avoid infinite loops with zero-width matches
100
101
  if (mCSS.index === cssRegex.lastIndex) {
101
102
  cssRegex.lastIndex++;
@@ -103,9 +104,9 @@ const parseCSS = (css)=>{
103
104
  // The result can be accessed through the `m`-variable.
104
105
  const selector = {
105
106
  key: '',
106
- value: ''
107
+ value: '',
107
108
  };
108
- mCSS.forEach((match, groupIndex)=>{
109
+ mCSS.forEach((match, groupIndex) => {
109
110
  if (groupIndex == 1) {
110
111
  selector.key = match.trim();
111
112
  }
package/dist/cjs/index.js CHANGED
@@ -4,20 +4,20 @@ var parse5 = require('parse5');
4
4
  var cssEscape = require('./css-escape.js');
5
5
  var cssParser = require('./css-parser.js');
6
6
 
7
- const hashClassNames = (html, css, options)=>{
8
- const { html: htmlWithoutLiquid , arrayMatch } = replaceLiquidToBKPlaceholder(html);
7
+ const hashClassNames = (html, css, options) => {
8
+ const { html: htmlWithoutLiquid, arrayMatch } = replaceLiquidToBKPlaceholder(html);
9
9
  const documentFragment = parse5.parseFragment(htmlWithoutLiquid);
10
10
  const jsonHTML = documentFragment.childNodes;
11
11
  if (jsonHTML?.length) {
12
12
  const classes = {};
13
13
  const hashClasses = {};
14
14
  // Find & Obfuscate class in html
15
- const loopNode = (childNodes, callback)=>{
15
+ const loopNode = (childNodes, callback) => {
16
16
  if (childNodes?.length) {
17
- for(let i = 0; i < childNodes.length; i++){
17
+ for (let i = 0; i < childNodes.length; i++) {
18
18
  const childNode = childNodes[i];
19
19
  if (childNode) {
20
- const keepClass = childNode.attrs?.find((item)=>item.name == 'data-keep-class')?.value;
20
+ const keepClass = childNode.attrs?.find((item) => item.name == 'data-keep-class')?.value;
21
21
  if (!keepClass) {
22
22
  callback(childNode);
23
23
  if (childNode.childNodes?.length) {
@@ -28,13 +28,13 @@ const hashClassNames = (html, css, options)=>{
28
28
  }
29
29
  }
30
30
  };
31
- loopNode(jsonHTML, (node)=>{
31
+ loopNode(jsonHTML, (node) => {
32
32
  if (node?.attrs?.length) {
33
- const attrClass = node.attrs.find((item)=>item.name == 'class');
33
+ const attrClass = node.attrs.find((item) => item.name == 'class');
34
34
  if (attrClass?.value) {
35
35
  const nodeClasses = attrClass.value.split(' ');
36
36
  if (nodeClasses?.length) {
37
- for(let i = 0; i < nodeClasses.length; i++){
37
+ for (let i = 0; i < nodeClasses.length; i++) {
38
38
  let nodeClass = nodeClasses[i]?.trim() || '';
39
39
  nodeClass = nodeClass.replace(/bk-liquid.*?bk-liquid/g, '');
40
40
  if (options?.ignoreClasses?.includes(nodeClass)) {
@@ -44,20 +44,21 @@ const hashClassNames = (html, css, options)=>{
44
44
  const data = classes[nodeClass];
45
45
  if (!data) {
46
46
  // eslint-disable-next-line no-constant-condition
47
- while(true){
47
+ while (true) {
48
48
  const newClass = `a${ID()}`;
49
49
  if (!hashClasses[newClass]) {
50
50
  hashClasses[newClass] = true; // flag
51
51
  // Cache
52
52
  classes[nodeClass] = {
53
- hash: newClass
53
+ hash: newClass,
54
54
  };
55
55
  // replace
56
56
  replaceClass(node, nodeClass, newClass);
57
57
  break;
58
58
  }
59
59
  }
60
- } else {
60
+ }
61
+ else {
61
62
  replaceClass(node, nodeClass, data.hash);
62
63
  }
63
64
  }
@@ -67,7 +68,7 @@ const hashClassNames = (html, css, options)=>{
67
68
  }
68
69
  });
69
70
  let newHTML = '';
70
- for(let i = 0; i < jsonHTML.length; i++){
71
+ for (let i = 0; i < jsonHTML.length; i++) {
71
72
  const node = jsonHTML[i];
72
73
  if (node) {
73
74
  newHTML += parse5.serializeOuter(node);
@@ -75,18 +76,18 @@ const hashClassNames = (html, css, options)=>{
75
76
  }
76
77
  // Replace class in css
77
78
  const orderClasses = [];
78
- for(const oldClass in classes){
79
+ for (const oldClass in classes) {
79
80
  if (Object.prototype.hasOwnProperty.call(classes, oldClass)) {
80
81
  const data = classes[oldClass];
81
82
  if (data?.hash) {
82
83
  orderClasses.push({
83
84
  oldClass: oldClass,
84
- newClass: data.hash
85
+ newClass: data.hash,
85
86
  });
86
87
  }
87
88
  }
88
89
  }
89
- orderClasses.sort((a, b)=>{
90
+ orderClasses.sort((a, b) => {
90
91
  if (a.oldClass.includes(b.oldClass)) {
91
92
  return -1;
92
93
  }
@@ -95,32 +96,34 @@ const hashClassNames = (html, css, options)=>{
95
96
  let newCSS = css;
96
97
  if (newCSS) {
97
98
  const jsonCSS = cssParser.cssToJson(newCSS);
98
- const loopCSSSelector = (style)=>{
99
+ const loopCSSSelector = (style) => {
99
100
  // Replace selector
100
- for(const selector in style.children){
101
+ for (const selector in style.children) {
101
102
  if (Object.prototype.hasOwnProperty.call(style.children, selector)) {
102
103
  let newSelector = selector;
103
104
  // Replace selector new selector
104
105
  const styleSelector = style.children[selector];
105
106
  const selectors = newSelector.split(',');
106
- for(let index = 0; index < selectors.length; index++){
107
+ for (let index = 0; index < selectors.length; index++) {
107
108
  const itemSelector = selectors[index];
108
109
  if (itemSelector) {
109
110
  const selectorClasses = itemSelector.split('.');
110
- for(let i = 0; i < selectorClasses.length; i++){
111
+ for (let i = 0; i < selectorClasses.length; i++) {
111
112
  let selectorClass = selectorClasses[i];
112
113
  selectorClass = selectorClass?.trim();
113
114
  // eslint-disable-next-line prefer-regex-literals, no-useless-escape, regexp/no-useless-flag
114
115
  selectorClass = selectorClass?.replace(new RegExp(`\[.*?\]`, 'gm'), ''); // Replace [data]
115
- selectorClass = selectorClass?.replace(/:(a(ctive|ny(-link)*)|checked|d(efault|i(r\(\)|sabled))|e(mpty|nabled)|f(irst(-(child|of-type))*|ullscreen|ocus)|hover|in(determinate|valid|-range)|la(ng\(\)|(st-(child|of-type)))|l(eft|ink)|n(ot\(\)|th-((last-)*(child|of-type)\(\)))|o(nly-(child|of-type)|ptional|ut-of-range)|r(e(ad-(only|write)|quired)|ight|oot)|scope|target|v(alid|isited))/g, '');
116
+ selectorClass = selectorClass?.replace(/:(a(ctive|ny(-link)*)|checked|d(efault|i(r\(\)|sabled))|e(mpty|nabled)|f(irst(-(child|of-type))*|ullscreen|ocus)|hover|in(determinate|valid|-range)|la(ng\(\)|(st-(child|of-type)))|l(eft|ink)|n(ot\(\)|th-((last-)*(child|of-type)\(\)))|o(nly-(child|of-type)|ptional|ut-of-range)|r(e(ad-(only|write)|quired)|ight|oot)|scope|target|v(alid|isited))/g, // remove pseudo-classes url: https://www.regextester.com/99719
117
+ '');
116
118
  if (selectorClass) {
117
- for(let index = 0; index < orderClasses.length; index++){
119
+ for (let index = 0; index < orderClasses.length; index++) {
118
120
  const orderClass = orderClasses[index];
119
121
  if (orderClass) {
120
122
  let flag = false;
121
123
  if (orderClass.oldClass == selectorClass) {
122
124
  flag = true;
123
- } else if (cssEscape.cssEscape(orderClass.oldClass) == selectorClass) {
125
+ }
126
+ else if (cssEscape.cssEscape(orderClass.oldClass) == selectorClass) {
124
127
  flag = true;
125
128
  }
126
129
  if (flag) {
@@ -144,7 +147,7 @@ const hashClassNames = (html, css, options)=>{
144
147
  }
145
148
  // Loop
146
149
  if (style.children) {
147
- for(const selectorChild in style.children){
150
+ for (const selectorChild in style.children) {
148
151
  if (Object.prototype.hasOwnProperty.call(style.children, selectorChild)) {
149
152
  const styleChild = style.children[selectorChild];
150
153
  if (styleChild) {
@@ -160,27 +163,27 @@ const hashClassNames = (html, css, options)=>{
160
163
  newHTML = replaceBKPlaceholderToLiquid(newHTML, arrayMatch);
161
164
  return {
162
165
  html: newHTML,
163
- css: newCSS
166
+ css: newCSS,
164
167
  };
165
168
  }
166
169
  // Return default
167
170
  return {
168
171
  html,
169
- css
172
+ css,
170
173
  };
171
174
  };
172
- const ID = function() {
175
+ const ID = function () {
173
176
  // Math.random should be unique because of its seeding algorithm.
174
177
  // Convert it to base 36 (numbers + letters), and grab the first 9 characters
175
178
  // after the decimal.
176
179
  return Math.random().toString(36).substr(2, 5);
177
180
  };
178
- const replaceClass = (node, oldClass, newClass)=>{
181
+ const replaceClass = (node, oldClass, newClass) => {
179
182
  if (node.attrs?.length) {
180
- const attrClass = node.attrs.find((item)=>item.name == 'class');
183
+ const attrClass = node.attrs.find((item) => item.name == 'class');
181
184
  if (attrClass?.value) {
182
185
  const values = attrClass.value.split(' ');
183
- for(let i = 0; i < values.length; i++){
186
+ for (let i = 0; i < values.length; i++) {
184
187
  const value = values[i];
185
188
  if (value) {
186
189
  const valueWithoutLiquid = value?.replace(/bk-liquid.*?bk-liquid/g, '');
@@ -194,18 +197,18 @@ const replaceClass = (node, oldClass, newClass)=>{
194
197
  }
195
198
  }
196
199
  };
197
- const replaceSelector = (selector, oldClass, newClass)=>{
200
+ const replaceSelector = (selector, oldClass, newClass) => {
198
201
  let newSelector = selector;
199
202
  newSelector = newSelector.replaceAll(oldClass, newClass);
200
203
  newSelector = newSelector.replaceAll(cssEscape.cssEscape(oldClass), cssEscape.cssEscape(newClass));
201
204
  return newSelector;
202
205
  };
203
- const replaceLiquidToBKPlaceholder = (html)=>{
206
+ const replaceLiquidToBKPlaceholder = (html) => {
204
207
  // eslint-disable-next-line regexp/no-dupe-disjunctions
205
208
  const regex = /\{%(.|[\n\r\t])*?%\}|\{\{(.|[\n\r\t])*?\}\}/g;
206
209
  const arrayMatch = html.match(regex);
207
210
  if (arrayMatch?.length) {
208
- for(let i = 0; i < arrayMatch.length; i++){
211
+ for (let i = 0; i < arrayMatch.length; i++) {
209
212
  const match = arrayMatch[i];
210
213
  if (match) {
211
214
  html = html.replace(match, 'bk-liquid' + i + 'bk-liquid');
@@ -214,12 +217,12 @@ const replaceLiquidToBKPlaceholder = (html)=>{
214
217
  }
215
218
  return {
216
219
  html,
217
- arrayMatch
220
+ arrayMatch,
218
221
  };
219
222
  };
220
- const replaceBKPlaceholderToLiquid = (html, arrayMatch)=>{
223
+ const replaceBKPlaceholderToLiquid = (html, arrayMatch) => {
221
224
  if (arrayMatch?.length) {
222
- for(let i = 0; i < arrayMatch.length; i++){
225
+ for (let i = 0; i < arrayMatch.length; i++) {
223
226
  const match = arrayMatch[i];
224
227
  if (match) {
225
228
  html = html.replace('bk-liquid' + i + 'bk-liquid=""', match); // html data auto fix
@@ -1,6 +1,6 @@
1
1
  // https://drafts.csswg.org/cssom/#serialize-an-identifier
2
2
  // repo: https://github.com/mathiasbynens/CSS.escape
3
- const cssEscape = function(value) {
3
+ const cssEscape = function (value) {
4
4
  if (arguments.length == 0) {
5
5
  throw new TypeError('`CSS.escape` requires an argument.');
6
6
  }
@@ -10,12 +10,14 @@ const cssEscape = function(value) {
10
10
  let codeUnit;
11
11
  let result = '';
12
12
  const firstCodeUnit = string.charCodeAt(0);
13
- if (// If the character is the first character and is a `-` (U+002D), and
13
+ if (
14
+ // If the character is the first character and is a `-` (U+002D), and
14
15
  // there is no second character, […]
15
- length == 1 && firstCodeUnit == 0x002d) {
16
+ length == 1 &&
17
+ firstCodeUnit == 0x002d) {
16
18
  return '\\' + string;
17
19
  }
18
- while(++index < length){
20
+ while (++index < length) {
19
21
  codeUnit = string.charCodeAt(index);
20
22
  // Note: there’s no need to special-case astral symbols, surrogate
21
23
  // pairs, or lone surrogates.
@@ -25,13 +27,17 @@ const cssEscape = function(value) {
25
27
  result += '\uFFFD';
26
28
  continue;
27
29
  }
28
- if (// If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
30
+ if (
31
+ // If the character is in the range [\1-\1F] (U+0001 to U+001F) or is
29
32
  // U+007F, […]
30
- codeUnit >= 0x0001 && codeUnit <= 0x001f || codeUnit == 0x007f || // If the character is the first character and is in the range [0-9]
31
- // (U+0030 to U+0039), […]
32
- index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039 || // If the character is the second character and is in the range [0-9]
33
- // (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
34
- index == 1 && codeUnit >= 0x0030 && codeUnit <= 0x0039 && firstCodeUnit == 0x002d) {
33
+ (codeUnit >= 0x0001 && codeUnit <= 0x001f) ||
34
+ codeUnit == 0x007f ||
35
+ // If the character is the first character and is in the range [0-9]
36
+ // (U+0030 to U+0039), […]
37
+ (index == 0 && codeUnit >= 0x0030 && codeUnit <= 0x0039) ||
38
+ // If the character is the second character and is in the range [0-9]
39
+ // (U+0030 to U+0039) and the first character is a `-` (U+002D), […]
40
+ (index == 1 && codeUnit >= 0x0030 && codeUnit <= 0x0039 && firstCodeUnit == 0x002d)) {
35
41
  // https://drafts.csswg.org/cssom/#escape-a-character-as-code-point
36
42
  result += '\\' + codeUnit.toString(16) + ' ';
37
43
  continue;
@@ -40,7 +46,12 @@ const cssEscape = function(value) {
40
46
  // greater than or equal to U+0080, is `-` (U+002D) or `_` (U+005F), or
41
47
  // is in one of the ranges [0-9] (U+0030 to U+0039), [A-Z] (U+0041 to
42
48
  // U+005A), or [a-z] (U+0061 to U+007A), […]
43
- if (codeUnit >= 0x0080 || codeUnit == 0x002d || codeUnit == 0x005f || codeUnit >= 0x0030 && codeUnit <= 0x0039 || codeUnit >= 0x0041 && codeUnit <= 0x005a || codeUnit >= 0x0061 && codeUnit <= 0x007a) {
49
+ if (codeUnit >= 0x0080 ||
50
+ codeUnit == 0x002d ||
51
+ codeUnit == 0x005f ||
52
+ (codeUnit >= 0x0030 && codeUnit <= 0x0039) ||
53
+ (codeUnit >= 0x0041 && codeUnit <= 0x005a) ||
54
+ (codeUnit >= 0x0061 && codeUnit <= 0x007a)) {
44
55
  // the character itself
45
56
  result += string.charAt(index);
46
57
  continue;
@@ -1,14 +1,14 @@
1
- const cssToJson = (str)=>{
1
+ const cssToJson = (str) => {
2
2
  let style = str;
3
3
  const jsonCSS = {
4
4
  children: {},
5
- attributes: ''
5
+ attributes: '',
6
6
  };
7
7
  const mediaQuery = {};
8
8
  // eslint-disable-next-line regexp/prefer-d, no-useless-escape, regexp/no-dupe-characters-character-class, regexp/no-useless-escape, regexp/strict, regexp/no-obscure-range, regexp/no-useless-flag, regexp/no-super-linear-backtracking
9
9
  const regex = /(@media[^{]+\)).*?{([\s\S]+?})\s*}/g;
10
10
  let m;
11
- while((m = regex.exec(str)) !== null){
11
+ while ((m = regex.exec(str)) !== null) {
12
12
  // This is necessary to avoid infinite loops with zero-width matches
13
13
  if (m.index === regex.lastIndex) {
14
14
  regex.lastIndex++;
@@ -16,9 +16,9 @@ const cssToJson = (str)=>{
16
16
  // The result can be accessed through the `m`-variable.
17
17
  const css = {
18
18
  media: '',
19
- style: ''
19
+ style: '',
20
20
  };
21
- m.forEach((match, groupIndex)=>{
21
+ m.forEach((match, groupIndex) => {
22
22
  if (groupIndex == 0) {
23
23
  style = style.replaceAll(match, '');
24
24
  }
@@ -34,31 +34,31 @@ const cssToJson = (str)=>{
34
34
  }
35
35
  // Parse css root
36
36
  const cssRoot = parseCSS(style);
37
- for(const key in cssRoot){
37
+ for (const key in cssRoot) {
38
38
  if (Object.prototype.hasOwnProperty.call(cssRoot, key)) {
39
39
  const value = cssRoot[key];
40
40
  jsonCSS.children[key] = {
41
41
  children: {},
42
- attributes: value
42
+ attributes: value,
43
43
  };
44
44
  }
45
45
  }
46
46
  // Append css media
47
- for(const media in mediaQuery){
47
+ for (const media in mediaQuery) {
48
48
  if (Object.prototype.hasOwnProperty.call(mediaQuery, media)) {
49
49
  const css = mediaQuery[media];
50
50
  if (css?.length) {
51
51
  const jsonQueryCss = {
52
52
  children: {},
53
- attributes: ''
53
+ attributes: '',
54
54
  };
55
55
  const cssQuery = parseCSS(css?.join(''));
56
- for(const key in cssQuery){
56
+ for (const key in cssQuery) {
57
57
  if (Object.prototype.hasOwnProperty.call(cssQuery, key)) {
58
58
  const value = cssQuery[key];
59
59
  jsonQueryCss.children[key] = {
60
60
  children: {},
61
- attributes: value
61
+ attributes: value,
62
62
  };
63
63
  }
64
64
  }
@@ -68,10 +68,10 @@ const cssToJson = (str)=>{
68
68
  }
69
69
  return jsonCSS;
70
70
  };
71
- const jsonToCss = (jsonCSS, selector)=>{
71
+ const jsonToCss = (jsonCSS, selector) => {
72
72
  // Replace selector
73
73
  let value = '';
74
- for(const selector in jsonCSS.children){
74
+ for (const selector in jsonCSS.children) {
75
75
  if (Object.prototype.hasOwnProperty.call(jsonCSS.children, selector)) {
76
76
  const style = jsonCSS.children[selector];
77
77
  if (style) {
@@ -84,16 +84,17 @@ const jsonToCss = (jsonCSS, selector)=>{
84
84
  }
85
85
  if (selector) {
86
86
  return `${selector}{${value}}`;
87
- } else {
87
+ }
88
+ else {
88
89
  return value;
89
90
  }
90
91
  };
91
- const parseCSS = (css)=>{
92
+ const parseCSS = (css) => {
92
93
  const cssJSON = {};
93
94
  // eslint-disable-next-line regexp/prefer-d, no-useless-escape, regexp/no-dupe-characters-character-class, regexp/no-useless-escape, regexp/strict, regexp/no-obscure-range, regexp/no-useless-flag, regexp/no-super-linear-backtracking, regexp/prefer-character-class, regexp/no-dupe-disjunctions
94
95
  const cssRegex = /((.|\n|\r|\t)*?){((.|\n|\r|\t)*?)}/gm;
95
96
  let mCSS;
96
- while((mCSS = cssRegex.exec(css)) !== null){
97
+ while ((mCSS = cssRegex.exec(css)) !== null) {
97
98
  // This is necessary to avoid infinite loops with zero-width matches
98
99
  if (mCSS.index === cssRegex.lastIndex) {
99
100
  cssRegex.lastIndex++;
@@ -101,9 +102,9 @@ const parseCSS = (css)=>{
101
102
  // The result can be accessed through the `m`-variable.
102
103
  const selector = {
103
104
  key: '',
104
- value: ''
105
+ value: '',
105
106
  };
106
- mCSS.forEach((match, groupIndex)=>{
107
+ mCSS.forEach((match, groupIndex) => {
107
108
  if (groupIndex == 1) {
108
109
  selector.key = match.trim();
109
110
  }
package/dist/esm/index.js CHANGED
@@ -2,20 +2,20 @@ import { parseFragment, serializeOuter } from 'parse5';
2
2
  import { cssEscape } from './css-escape.js';
3
3
  import { cssToJson, jsonToCss } from './css-parser.js';
4
4
 
5
- const hashClassNames = (html, css, options)=>{
6
- const { html: htmlWithoutLiquid , arrayMatch } = replaceLiquidToBKPlaceholder(html);
5
+ const hashClassNames = (html, css, options) => {
6
+ const { html: htmlWithoutLiquid, arrayMatch } = replaceLiquidToBKPlaceholder(html);
7
7
  const documentFragment = parseFragment(htmlWithoutLiquid);
8
8
  const jsonHTML = documentFragment.childNodes;
9
9
  if (jsonHTML?.length) {
10
10
  const classes = {};
11
11
  const hashClasses = {};
12
12
  // Find & Obfuscate class in html
13
- const loopNode = (childNodes, callback)=>{
13
+ const loopNode = (childNodes, callback) => {
14
14
  if (childNodes?.length) {
15
- for(let i = 0; i < childNodes.length; i++){
15
+ for (let i = 0; i < childNodes.length; i++) {
16
16
  const childNode = childNodes[i];
17
17
  if (childNode) {
18
- const keepClass = childNode.attrs?.find((item)=>item.name == 'data-keep-class')?.value;
18
+ const keepClass = childNode.attrs?.find((item) => item.name == 'data-keep-class')?.value;
19
19
  if (!keepClass) {
20
20
  callback(childNode);
21
21
  if (childNode.childNodes?.length) {
@@ -26,13 +26,13 @@ const hashClassNames = (html, css, options)=>{
26
26
  }
27
27
  }
28
28
  };
29
- loopNode(jsonHTML, (node)=>{
29
+ loopNode(jsonHTML, (node) => {
30
30
  if (node?.attrs?.length) {
31
- const attrClass = node.attrs.find((item)=>item.name == 'class');
31
+ const attrClass = node.attrs.find((item) => item.name == 'class');
32
32
  if (attrClass?.value) {
33
33
  const nodeClasses = attrClass.value.split(' ');
34
34
  if (nodeClasses?.length) {
35
- for(let i = 0; i < nodeClasses.length; i++){
35
+ for (let i = 0; i < nodeClasses.length; i++) {
36
36
  let nodeClass = nodeClasses[i]?.trim() || '';
37
37
  nodeClass = nodeClass.replace(/bk-liquid.*?bk-liquid/g, '');
38
38
  if (options?.ignoreClasses?.includes(nodeClass)) {
@@ -42,20 +42,21 @@ const hashClassNames = (html, css, options)=>{
42
42
  const data = classes[nodeClass];
43
43
  if (!data) {
44
44
  // eslint-disable-next-line no-constant-condition
45
- while(true){
45
+ while (true) {
46
46
  const newClass = `a${ID()}`;
47
47
  if (!hashClasses[newClass]) {
48
48
  hashClasses[newClass] = true; // flag
49
49
  // Cache
50
50
  classes[nodeClass] = {
51
- hash: newClass
51
+ hash: newClass,
52
52
  };
53
53
  // replace
54
54
  replaceClass(node, nodeClass, newClass);
55
55
  break;
56
56
  }
57
57
  }
58
- } else {
58
+ }
59
+ else {
59
60
  replaceClass(node, nodeClass, data.hash);
60
61
  }
61
62
  }
@@ -65,7 +66,7 @@ const hashClassNames = (html, css, options)=>{
65
66
  }
66
67
  });
67
68
  let newHTML = '';
68
- for(let i = 0; i < jsonHTML.length; i++){
69
+ for (let i = 0; i < jsonHTML.length; i++) {
69
70
  const node = jsonHTML[i];
70
71
  if (node) {
71
72
  newHTML += serializeOuter(node);
@@ -73,18 +74,18 @@ const hashClassNames = (html, css, options)=>{
73
74
  }
74
75
  // Replace class in css
75
76
  const orderClasses = [];
76
- for(const oldClass in classes){
77
+ for (const oldClass in classes) {
77
78
  if (Object.prototype.hasOwnProperty.call(classes, oldClass)) {
78
79
  const data = classes[oldClass];
79
80
  if (data?.hash) {
80
81
  orderClasses.push({
81
82
  oldClass: oldClass,
82
- newClass: data.hash
83
+ newClass: data.hash,
83
84
  });
84
85
  }
85
86
  }
86
87
  }
87
- orderClasses.sort((a, b)=>{
88
+ orderClasses.sort((a, b) => {
88
89
  if (a.oldClass.includes(b.oldClass)) {
89
90
  return -1;
90
91
  }
@@ -93,32 +94,34 @@ const hashClassNames = (html, css, options)=>{
93
94
  let newCSS = css;
94
95
  if (newCSS) {
95
96
  const jsonCSS = cssToJson(newCSS);
96
- const loopCSSSelector = (style)=>{
97
+ const loopCSSSelector = (style) => {
97
98
  // Replace selector
98
- for(const selector in style.children){
99
+ for (const selector in style.children) {
99
100
  if (Object.prototype.hasOwnProperty.call(style.children, selector)) {
100
101
  let newSelector = selector;
101
102
  // Replace selector new selector
102
103
  const styleSelector = style.children[selector];
103
104
  const selectors = newSelector.split(',');
104
- for(let index = 0; index < selectors.length; index++){
105
+ for (let index = 0; index < selectors.length; index++) {
105
106
  const itemSelector = selectors[index];
106
107
  if (itemSelector) {
107
108
  const selectorClasses = itemSelector.split('.');
108
- for(let i = 0; i < selectorClasses.length; i++){
109
+ for (let i = 0; i < selectorClasses.length; i++) {
109
110
  let selectorClass = selectorClasses[i];
110
111
  selectorClass = selectorClass?.trim();
111
112
  // eslint-disable-next-line prefer-regex-literals, no-useless-escape, regexp/no-useless-flag
112
113
  selectorClass = selectorClass?.replace(new RegExp(`\[.*?\]`, 'gm'), ''); // Replace [data]
113
- selectorClass = selectorClass?.replace(/:(a(ctive|ny(-link)*)|checked|d(efault|i(r\(\)|sabled))|e(mpty|nabled)|f(irst(-(child|of-type))*|ullscreen|ocus)|hover|in(determinate|valid|-range)|la(ng\(\)|(st-(child|of-type)))|l(eft|ink)|n(ot\(\)|th-((last-)*(child|of-type)\(\)))|o(nly-(child|of-type)|ptional|ut-of-range)|r(e(ad-(only|write)|quired)|ight|oot)|scope|target|v(alid|isited))/g, '');
114
+ selectorClass = selectorClass?.replace(/:(a(ctive|ny(-link)*)|checked|d(efault|i(r\(\)|sabled))|e(mpty|nabled)|f(irst(-(child|of-type))*|ullscreen|ocus)|hover|in(determinate|valid|-range)|la(ng\(\)|(st-(child|of-type)))|l(eft|ink)|n(ot\(\)|th-((last-)*(child|of-type)\(\)))|o(nly-(child|of-type)|ptional|ut-of-range)|r(e(ad-(only|write)|quired)|ight|oot)|scope|target|v(alid|isited))/g, // remove pseudo-classes url: https://www.regextester.com/99719
115
+ '');
114
116
  if (selectorClass) {
115
- for(let index = 0; index < orderClasses.length; index++){
117
+ for (let index = 0; index < orderClasses.length; index++) {
116
118
  const orderClass = orderClasses[index];
117
119
  if (orderClass) {
118
120
  let flag = false;
119
121
  if (orderClass.oldClass == selectorClass) {
120
122
  flag = true;
121
- } else if (cssEscape(orderClass.oldClass) == selectorClass) {
123
+ }
124
+ else if (cssEscape(orderClass.oldClass) == selectorClass) {
122
125
  flag = true;
123
126
  }
124
127
  if (flag) {
@@ -142,7 +145,7 @@ const hashClassNames = (html, css, options)=>{
142
145
  }
143
146
  // Loop
144
147
  if (style.children) {
145
- for(const selectorChild in style.children){
148
+ for (const selectorChild in style.children) {
146
149
  if (Object.prototype.hasOwnProperty.call(style.children, selectorChild)) {
147
150
  const styleChild = style.children[selectorChild];
148
151
  if (styleChild) {
@@ -158,27 +161,27 @@ const hashClassNames = (html, css, options)=>{
158
161
  newHTML = replaceBKPlaceholderToLiquid(newHTML, arrayMatch);
159
162
  return {
160
163
  html: newHTML,
161
- css: newCSS
164
+ css: newCSS,
162
165
  };
163
166
  }
164
167
  // Return default
165
168
  return {
166
169
  html,
167
- css
170
+ css,
168
171
  };
169
172
  };
170
- const ID = function() {
173
+ const ID = function () {
171
174
  // Math.random should be unique because of its seeding algorithm.
172
175
  // Convert it to base 36 (numbers + letters), and grab the first 9 characters
173
176
  // after the decimal.
174
177
  return Math.random().toString(36).substr(2, 5);
175
178
  };
176
- const replaceClass = (node, oldClass, newClass)=>{
179
+ const replaceClass = (node, oldClass, newClass) => {
177
180
  if (node.attrs?.length) {
178
- const attrClass = node.attrs.find((item)=>item.name == 'class');
181
+ const attrClass = node.attrs.find((item) => item.name == 'class');
179
182
  if (attrClass?.value) {
180
183
  const values = attrClass.value.split(' ');
181
- for(let i = 0; i < values.length; i++){
184
+ for (let i = 0; i < values.length; i++) {
182
185
  const value = values[i];
183
186
  if (value) {
184
187
  const valueWithoutLiquid = value?.replace(/bk-liquid.*?bk-liquid/g, '');
@@ -192,18 +195,18 @@ const replaceClass = (node, oldClass, newClass)=>{
192
195
  }
193
196
  }
194
197
  };
195
- const replaceSelector = (selector, oldClass, newClass)=>{
198
+ const replaceSelector = (selector, oldClass, newClass) => {
196
199
  let newSelector = selector;
197
200
  newSelector = newSelector.replaceAll(oldClass, newClass);
198
201
  newSelector = newSelector.replaceAll(cssEscape(oldClass), cssEscape(newClass));
199
202
  return newSelector;
200
203
  };
201
- const replaceLiquidToBKPlaceholder = (html)=>{
204
+ const replaceLiquidToBKPlaceholder = (html) => {
202
205
  // eslint-disable-next-line regexp/no-dupe-disjunctions
203
206
  const regex = /\{%(.|[\n\r\t])*?%\}|\{\{(.|[\n\r\t])*?\}\}/g;
204
207
  const arrayMatch = html.match(regex);
205
208
  if (arrayMatch?.length) {
206
- for(let i = 0; i < arrayMatch.length; i++){
209
+ for (let i = 0; i < arrayMatch.length; i++) {
207
210
  const match = arrayMatch[i];
208
211
  if (match) {
209
212
  html = html.replace(match, 'bk-liquid' + i + 'bk-liquid');
@@ -212,12 +215,12 @@ const replaceLiquidToBKPlaceholder = (html)=>{
212
215
  }
213
216
  return {
214
217
  html,
215
- arrayMatch
218
+ arrayMatch,
216
219
  };
217
220
  };
218
- const replaceBKPlaceholderToLiquid = (html, arrayMatch)=>{
221
+ const replaceBKPlaceholderToLiquid = (html, arrayMatch) => {
219
222
  if (arrayMatch?.length) {
220
- for(let i = 0; i < arrayMatch.length; i++){
223
+ for (let i = 0; i < arrayMatch.length; i++) {
221
224
  const match = arrayMatch[i];
222
225
  if (match) {
223
226
  html = html.replace('bk-liquid' + i + 'bk-liquid=""', match); // html data auto fix
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gem-sdk/hash-class-names",
3
- "version": "1.11.0",
3
+ "version": "1.11.1-experimental-f662f2d9",
4
4
  "license": "MIT",
5
5
  "main": "dist/cjs/index.js",
6
6
  "scripts": {