diff --git a/packages/stylify/src/Compiler/Compiler.ts b/packages/stylify/src/Compiler/Compiler.ts index 7e50a14a..4250ce9a 100755 --- a/packages/stylify/src/Compiler/Compiler.ts +++ b/packages/stylify/src/Compiler/Compiler.ts @@ -452,14 +452,9 @@ export class Compiler { contentToProcess = contentToProcess.replace( /\[([^{}\s]+)\]{([^{}]+)}/g, (fullMatch: string, cssSelectors: string, stylifySelectors: string) => { - const customSelector = MacroMatch.replaceCharactersAliases(cssSelectors); - const customSelectorSelector = this.mangleSelectors - ? minifiedSelectorGenerator.getMangledSelector(fullMatch, null) - : fullMatch; - this.addCustomSelector( - customSelectorSelector, - `${customSelector}{${stylifySelectors.replace(/;/g, ' ')}}`, + this.generateMangledSelector(fullMatch, null), + `${MacroMatch.replaceCharactersAliases(cssSelectors)}{${stylifySelectors.replace(/;/g, ' ')}}`, false, 'customMatchedInClass' ); @@ -471,12 +466,8 @@ export class Compiler { contentToProcess = contentToProcess.replace( /(\S+):{([^{}]+)}/g, (fullMatch: string, screenAndPseudoClasses: string, stylifySelectors: string) => { - const customSelectorSelector = this.mangleSelectors - ? minifiedSelectorGenerator.getMangledSelector(fullMatch, null) - : fullMatch; - this.addCustomSelector( - customSelectorSelector, + this.generateMangledSelector(fullMatch, null), stylifySelectors.split(';') .map((stylifySelector) => `${screenAndPseudoClasses}:${stylifySelector}`) .join(' '), @@ -537,6 +528,14 @@ export class Compiler { return contentOptions as Data; } + private generateMangledSelector(selector: string, prefix: string|null = '.'): string { + if (!this.mangleSelectors) { + return selector; + } + + return minifiedSelectorGenerator.generateMangledSelector(selector, prefix); + } + private configureCompilationResult(compilationResult: CompilationResult): CompilationResult { const newLine = this.dev ? '\n' : ''; @@ -634,7 +633,7 @@ export class Compiler { const isUtilitiesGroup = config.type === 'utilitiesGroup'; const isCustomSelectorMatchedInClass = config.type === 'customMatchedInClass'; const isClassSelector = isComponent || isUtilitiesGroup || isCustomSelectorMatchedInClass; - const preparedEscapedSelector = config.type === 'custom' + const preparedEscapedSelector = this.mangleSelectors || config.type === 'custom' ? selector : escapeCssSelector(selector, isComponent || isUtilitiesGroup || isCustomSelectorMatchedInClass); @@ -670,7 +669,7 @@ export class Compiler { return fullMatch.substring(1).replace( prepareStringForReplace(clearedComponentName), - `.${minifiedSelectorGenerator.getMangledSelector(clearedComponentName)}` + `.${this.generateMangledSelector(clearedComponentName)}` ); }); } @@ -715,8 +714,7 @@ export class Compiler { }) : selectorsOrGenerator; - minifiedSelectorGenerator.getMangledSelector(componentSelector); - + this.generateMangledSelector(componentSelector); this.addCustomSelector(componentSelector, componentSelectors, false, 'component'); } } diff --git a/packages/stylify/src/Compiler/CssRecord.ts b/packages/stylify/src/Compiler/CssRecord.ts index 1ff00153..dd7febf3 100755 --- a/packages/stylify/src/Compiler/CssRecord.ts +++ b/packages/stylify/src/Compiler/CssRecord.ts @@ -57,7 +57,7 @@ export class CssRecord { } this.mangledSelector = config.selector - ? minifiedSelectorGenerator.getMangledSelector(config.selector) + ? minifiedSelectorGenerator.generateMangledSelector(config.selector) : this.mangledSelector; this.screenId = config.screenId ?? this.screenId; this.selector = config.selector?.replace(/([^-_a-zA-Z\d])/g, '\\$1') ?? this.selector; diff --git a/packages/stylify/src/Compiler/MinifiedSelectorGenerator.ts b/packages/stylify/src/Compiler/MinifiedSelectorGenerator.ts index 545a12f1..b9d8b390 100644 --- a/packages/stylify/src/Compiler/MinifiedSelectorGenerator.ts +++ b/packages/stylify/src/Compiler/MinifiedSelectorGenerator.ts @@ -21,7 +21,7 @@ export class MinifiedSelectorGenerator { return addPrefix ? `${this.processedSelectors[selector].prefix ?? ''}${selector}`: selector; } - public getMangledSelector(selector: string, prefix: string|null = '.') { + public generateMangledSelector(selector: string, prefix: string|null = '.') { if (!(selector in this.processedSelectors)) { this.processedSelectors[selector] = { mangledSelector: this.divideLengthAndGetLetter( @@ -34,6 +34,10 @@ export class MinifiedSelectorGenerator { return this.processedSelectors[selector].mangledSelector; } + public getMangledSelector(selector: string) { + return this.processedSelectors[selector]?.mangledSelector ?? null; + } + private divideLengthAndGetLetter(length: number): string { let shortSelector = ''; diff --git a/packages/stylify/src/Compiler/defaultPreset.ts b/packages/stylify/src/Compiler/defaultPreset.ts index f69499c5..6ab5dede 100644 --- a/packages/stylify/src/Compiler/defaultPreset.ts +++ b/packages/stylify/src/Compiler/defaultPreset.ts @@ -113,7 +113,12 @@ export const defaultPreset = { '(?:^|\\s+)\\[(?:ngClass|className)\\]=\'([^\']+)', // Nette '(?:^|\\s+)n:class="([^"]+)"', - '(?:^|\\s+)n:class=\'([^\']+)\'' + '(?:^|\\s+)n:class=\'([^\']+)\'', + // Twig form widgets + '\'class\':\\s*\'([^\']+)\'', + '\'class\':\\s*"([^"]+)"', + '"class":\\s*"([^"]+)"', + '"class":\\s*\'([^\']+)\'' ], screens: { tosm: maxWidthScreen('639px'), diff --git a/packages/stylify/tests/jest/components/expected/mangle-dynamic-components.css b/packages/stylify/tests/jest/components/expected/mangle-dynamic-components.css index 7e34cb1a..a8c4c13e 100644 --- a/packages/stylify/tests/jest/components/expected/mangle-dynamic-components.css +++ b/packages/stylify/tests/jest/components/expected/mangle-dynamic-components.css @@ -2,12 +2,12 @@ --red: darkred; } .a, -.c{ +.b{ font-size: 24px } .a{ color: #000 } -.c{ +.b{ color: darkred } diff --git a/packages/stylify/tests/jest/custom-macros.test.ts b/packages/stylify/tests/jest/custom-macros.test.ts deleted file mode 100644 index 28b5fb0d..00000000 --- a/packages/stylify/tests/jest/custom-macros.test.ts +++ /dev/null @@ -1,24 +0,0 @@ -import TestUtils from '../../../../tests/TestUtils'; -import { Compiler } from '../../src'; - -const testName = 'custom-macros'; -const testUtils = new TestUtils('stylify', testName); -const inputIndex = testUtils.getHtmlInputFile(); - -const compiler = new Compiler({ - dev: true, - macros: { - 'zi:(\\S+?)': ({macroMatch, selectorProperties}) => { - selectorProperties.addMultiple({ - 'position': 'relative', - 'z-index': Number(macroMatch.getCapture(0)) - }); - } - } -}); - -let compilationResult = compiler.compile(inputIndex); - -test('Single letter macros', (): void => { - testUtils.testCssFileToBe(compilationResult.generateCss()); -}); diff --git a/packages/stylify/tests/jest/macros.test.ts b/packages/stylify/tests/jest/macros.test.ts new file mode 100644 index 00000000..c970f73b --- /dev/null +++ b/packages/stylify/tests/jest/macros.test.ts @@ -0,0 +1,55 @@ +import TestUtils from '../../../../tests/TestUtils'; +import { Compiler, minifiedSelectorGenerator } from '../../src'; + +const testName = 'macros'; +const testUtils = new TestUtils('stylify', testName); + +beforeEach(() => minifiedSelectorGenerator.processedSelectors = {}); + +test('Single letter macros', (): void => { + const inputIndex = testUtils.getHtmlInputFile('single-letter-macros'); + + const compiler = new Compiler({ + dev: true, + macros: { + 'm:(\\S+?)': ({macroMatch, selectorProperties}) => { + selectorProperties.add('margin', macroMatch.getCapture(0)); + } + } + }); + + let compilationResult = compiler.compile(inputIndex); + + testUtils.testCssFileToBe(compilationResult.generateCss(), 'single-letter-macros'); +}); + +test('Custom macros', (): void => { + const inputIndex = testUtils.getHtmlInputFile('custom-macros'); + + const compiler = new Compiler({ + dev: true, + macros: { + 'zi:(\\S+?)': ({macroMatch, selectorProperties}) => { + selectorProperties.addMultiple({ + 'position': 'relative', + 'z-index': Number(macroMatch.getCapture(0)) + }); + } + } + }); + + let compilationResult = compiler.compile(inputIndex); + + testUtils.testCssFileToBe(compilationResult.generateCss(), 'custom-macros'); +}); + +test('Selectors areas', (): void => { + const inputIndex = testUtils.getHtmlInputFile('selectors-areas'); + + const compiler = new Compiler({ dev: true }); + + console.log(inputIndex); + let compilationResult = compiler.compile(inputIndex); + console.log(compilationResult); + testUtils.testCssFileToBe(compilationResult.generateCss(), 'selectors-areas'); +}); diff --git a/packages/stylify/tests/jest/custom-macros/expected/index.css b/packages/stylify/tests/jest/macros/expected/custom-macros.css similarity index 100% rename from packages/stylify/tests/jest/custom-macros/expected/index.css rename to packages/stylify/tests/jest/macros/expected/custom-macros.css diff --git a/packages/stylify/tests/jest/macros/expected/selectors-areas.css b/packages/stylify/tests/jest/macros/expected/selectors-areas.css new file mode 100644 index 00000000..2c1b61ad --- /dev/null +++ b/packages/stylify/tests/jest/macros/expected/selectors-areas.css @@ -0,0 +1,12 @@ +.color\:blue{ + color: blue +} +.font-size\:1px{ + font-size: 1px +} +.color\:red{ + color: red +} +.font-size\:2px{ + font-size: 2px +} diff --git a/packages/stylify/tests/jest/single-letter-macros/expected/index.css b/packages/stylify/tests/jest/macros/expected/single-letter-macros.css similarity index 100% rename from packages/stylify/tests/jest/single-letter-macros/expected/index.css rename to packages/stylify/tests/jest/macros/expected/single-letter-macros.css diff --git a/packages/stylify/tests/jest/custom-macros/input/index.html b/packages/stylify/tests/jest/macros/input/custom-macros.html similarity index 100% rename from packages/stylify/tests/jest/custom-macros/input/index.html rename to packages/stylify/tests/jest/macros/input/custom-macros.html diff --git a/packages/stylify/tests/jest/macros/input/selectors-areas.html b/packages/stylify/tests/jest/macros/input/selectors-areas.html new file mode 100644 index 00000000..1f7b6b44 --- /dev/null +++ b/packages/stylify/tests/jest/macros/input/selectors-areas.html @@ -0,0 +1,2 @@ +{{ form_widget(form, { 'attr': {'class': 'color:blue font-size:1px'} }) }} +{{ form_widget(form, { 'attr': {"class": 'color:red font-size:2px'} }) }} diff --git a/packages/stylify/tests/jest/single-letter-macros/input/index.html b/packages/stylify/tests/jest/macros/input/single-letter-macros.html similarity index 100% rename from packages/stylify/tests/jest/single-letter-macros/input/index.html rename to packages/stylify/tests/jest/macros/input/single-letter-macros.html diff --git a/packages/stylify/tests/jest/screens.test.ts b/packages/stylify/tests/jest/screens.test.ts index 1a5de68b..230026ae 100644 --- a/packages/stylify/tests/jest/screens.test.ts +++ b/packages/stylify/tests/jest/screens.test.ts @@ -8,14 +8,14 @@ beforeEach(() => { minifiedSelectorGenerator.processedSelectors = {}; }); -/* test('Dynamic screens', (): void => { +test('Dynamic screens', (): void => { const inputIndex = testUtils.getHtmlInputFile(); const compiler = new Compiler({ dev: true }); let compilationResult = compiler.compile(inputIndex); testUtils.testCssFileToBe(compilationResult.generateCss()); -}); */ +}); test('Similar screens', (): void => { const compiler = new Compiler({ diff --git a/packages/stylify/tests/jest/selectors-mangling.test.ts b/packages/stylify/tests/jest/selectors-mangling.test.ts index eb5fb880..cac884b9 100644 --- a/packages/stylify/tests/jest/selectors-mangling.test.ts +++ b/packages/stylify/tests/jest/selectors-mangling.test.ts @@ -12,7 +12,6 @@ beforeEach(() => { * This test is here, because dollars were removed when content was mangled. It is becuase $$ is replaced by $ * and it broke some of the functionality in some codes when mangled. */ - test('Mangle with special characters - dollars should stay as they are and non should removed.', (): void => { const fileName = 'mangle-with-special-characters'; const inputContent = testUtils.getHtmlInputFile(fileName); @@ -79,3 +78,15 @@ test('Component selector similar to custom selector', (): void => { testUtils.testCssFileToBe(compilationResult.generateCss(), fileName); testUtils.testHtmlFileToBe(compiler.rewriteSelectors(inputContent), fileName); }); + + +test('Chained classes from custom selector', (): void => { + const fileName = 'chained-classes-from-custom-selector'; + const inputContent = testUtils.getHtmlInputFile(fileName); + + const compiler = new Compiler({ dev: true, mangleSelectors: true }); + let compilationResult = compiler.compile(inputContent); + + testUtils.testCssFileToBe(compilationResult.generateCss(), fileName); + testUtils.testHtmlFileToBe(compiler.rewriteSelectors(inputContent), fileName); +}); diff --git a/packages/stylify/tests/jest/selectors-mangling/expected/chained-classes-from-custom-selector.css b/packages/stylify/tests/jest/selectors-mangling/expected/chained-classes-from-custom-selector.css new file mode 100644 index 00000000..422074d6 --- /dev/null +++ b/packages/stylify/tests/jest/selectors-mangling/expected/chained-classes-from-custom-selector.css @@ -0,0 +1,6 @@ +.a{ + width: 1px +} +.b{ + width: 2px +} diff --git a/packages/stylify/tests/jest/selectors-mangling/expected/chained-classes-from-custom-selector.html b/packages/stylify/tests/jest/selectors-mangling/expected/chained-classes-from-custom-selector.html new file mode 100644 index 00000000..44945a10 --- /dev/null +++ b/packages/stylify/tests/jest/selectors-mangling/expected/chained-classes-from-custom-selector.html @@ -0,0 +1,9 @@ + +
diff --git a/packages/stylify/tests/jest/selectors-mangling/input/chained-classes-from-custom-selector.html b/packages/stylify/tests/jest/selectors-mangling/input/chained-classes-from-custom-selector.html new file mode 100644 index 00000000..ebad6e58 --- /dev/null +++ b/packages/stylify/tests/jest/selectors-mangling/input/chained-classes-from-custom-selector.html @@ -0,0 +1,9 @@ + + diff --git a/packages/stylify/tests/jest/single-letter-macros.test.ts b/packages/stylify/tests/jest/single-letter-macros.test.ts deleted file mode 100644 index d0da10a5..00000000 --- a/packages/stylify/tests/jest/single-letter-macros.test.ts +++ /dev/null @@ -1,21 +0,0 @@ -import TestUtils from '../../../../tests/TestUtils'; -import { Compiler } from '../../src'; - -const testName = 'single-letter-macros'; -const testUtils = new TestUtils('stylify', testName); -const inputIndex = testUtils.getHtmlInputFile(); - -const compiler = new Compiler({ - dev: true, - macros: { - 'm:(\\S+?)': ({macroMatch, selectorProperties}) => { - selectorProperties.add('margin', macroMatch.getCapture(0)); - } - } -}); - -let compilationResult = compiler.compile(inputIndex); - -test('Single letter macros', (): void => { - testUtils.testCssFileToBe(compilationResult.generateCss()); -});