From 45aa7f6bb8b34fd80064ca2bf25c088f6b8dca9f Mon Sep 17 00:00:00 2001 From: Gaurav Bhagchandani Date: Wed, 9 Nov 2022 04:42:09 -0800 Subject: [PATCH 1/6] Fixed the issue for nested specificity in SCSS --- src/services/selectorPrinting.ts | 40 ++++++++++++++++++++++++++++++-- 1 file changed, 38 insertions(+), 2 deletions(-) diff --git a/src/services/selectorPrinting.ts b/src/services/selectorPrinting.ts index edc1654b..001e8051 100644 --- a/src/services/selectorPrinting.ts +++ b/src/services/selectorPrinting.ts @@ -222,6 +222,11 @@ class Specificity { public attr = 0; /** Count of tag names (`div`), and pseudo-elements (`::before`) */ public tag = 0; + public merge(specificity_to_merge: Specificity){ + this.id += specificity_to_merge.id; + this.attr += specificity_to_merge.attr; + this.tag += specificity_to_merge.tag; + } } export function toElement(node: nodes.SimpleSelector, parentElement?: Element | null): Element { @@ -451,9 +456,40 @@ export class SelectorPrinting { return specificity; }; + let total_specificity = new Specificity(); + let initial: boolean = true; + /* + Loop past the first Ruleset. + This is to handle the case where the deepest Selector is comma separated + and the user might hover over just one of them + */ + let pastInitial: boolean = false; + while(node.parent instanceof nodes.Node){ + /* + Only Ruleset nodes are useful to calculate the ancestor selectors + Exception is the deepest selector which is a Node + */ + if(!initial && !(node instanceof nodes.RuleSet)){ + node = node.parent; + continue; + } + if(!pastInitial && node instanceof nodes.RuleSet){ + node = node.parent; + pastInitial = true; + continue; + } + let specificity: Specificity = new Specificity(); + if(initial){ + specificity = calculateScore(node); + initial = false; + } else if(node instanceof nodes.RuleSet){ + specificity = calculateScore(node.getSelectors()) + } + total_specificity.merge(specificity); + node = node.parent; + } - const specificity = calculateScore(node);; - return localize('specificity', "[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): ({0}, {1}, {2})", specificity.id, specificity.attr, specificity.tag); + return localize('specificity', "[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): ({0}, {1}, {2})", total_specificity.id, total_specificity.attr, total_specificity.tag); } } From 6884e1f67d38ed87d5e0e646ff8862ced21c30f6 Mon Sep 17 00:00:00 2001 From: Gaurav Bhagchandani Date: Wed, 9 Nov 2022 04:42:27 -0800 Subject: [PATCH 2/6] Fixed a test that was using the old value of specificity as a check --- src/test/css/hover.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/css/hover.test.ts b/src/test/css/hover.test.ts index ca457081..5fd0d860 100644 --- a/src/test/css/hover.test.ts +++ b/src/test/css/hover.test.ts @@ -78,7 +78,7 @@ suite('SCSS Hover', () => { { contents: [ { language: 'html', value: '
\n …\n
' }, - '[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): (0, 0, 1)' + '[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): (0, 0, 2)' ] }, 'scss' From 618cacc73087c5e3d2fd4ee215b5b6cfd4d3506f Mon Sep 17 00:00:00 2001 From: Martin Aeschlimann Date: Wed, 9 Nov 2022 15:30:10 +0100 Subject: [PATCH 3/6] fix l10n.t, format --- src/services/selectorPrinting.ts | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/services/selectorPrinting.ts b/src/services/selectorPrinting.ts index f5bd896c..368caa8a 100644 --- a/src/services/selectorPrinting.ts +++ b/src/services/selectorPrinting.ts @@ -220,7 +220,7 @@ class Specificity { public attr = 0; /** Count of tag names (`div`), and pseudo-elements (`::before`) */ public tag = 0; - public merge(specificity_to_merge: Specificity){ + public merge(specificity_to_merge: Specificity) { this.id += specificity_to_merge.id; this.attr += specificity_to_merge.attr; this.tag += specificity_to_merge.tag; @@ -458,36 +458,36 @@ export class SelectorPrinting { let initial: boolean = true; /* Loop past the first Ruleset. - This is to handle the case where the deepest Selector is comma separated - and the user might hover over just one of them + This is to handle the case where the deepest Selector is comma separated + and the user might hover over just one of them */ - let pastInitial: boolean = false; - while(node.parent instanceof nodes.Node){ + let pastInitial: boolean = false; + while (node.parent instanceof nodes.Node) { /* Only Ruleset nodes are useful to calculate the ancestor selectors Exception is the deepest selector which is a Node */ - if(!initial && !(node instanceof nodes.RuleSet)){ + if (!initial && !(node instanceof nodes.RuleSet)) { node = node.parent; continue; } - if(!pastInitial && node instanceof nodes.RuleSet){ + if (!pastInitial && node instanceof nodes.RuleSet) { node = node.parent; pastInitial = true; continue; } let specificity: Specificity = new Specificity(); - if(initial){ + if (initial) { specificity = calculateScore(node); initial = false; - } else if(node instanceof nodes.RuleSet){ - specificity = calculateScore(node.getSelectors()) + } else if (node instanceof nodes.RuleSet) { + specificity = calculateScore(node.getSelectors()); } total_specificity.merge(specificity); node = node.parent; } - return l10n.t('specificity', "[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): ({0}, {1}, {2})", total_specificity.id, total_specificity.attr, total_specificity.tag); + return l10n.t("[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): ({0}, {1}, {2})", total_specificity.id, total_specificity.attr, total_specificity.tag); } } From 62d3fd502c7af956d6fbfe90c62ab0ba1267a622 Mon Sep 17 00:00:00 2001 From: Gaurav Bhagchandani Date: Fri, 11 Nov 2022 08:07:02 -0800 Subject: [PATCH 4/6] Logic fix when some ancestors in the nesting are comma separated --- src/services/selectorPrinting.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/services/selectorPrinting.ts b/src/services/selectorPrinting.ts index 368caa8a..cf6d3cfe 100644 --- a/src/services/selectorPrinting.ts +++ b/src/services/selectorPrinting.ts @@ -481,7 +481,7 @@ export class SelectorPrinting { specificity = calculateScore(node); initial = false; } else if (node instanceof nodes.RuleSet) { - specificity = calculateScore(node.getSelectors()); + specificity = calculateScore(node.getSelectors().getChild(0) ?? node.getSelectors()); } total_specificity.merge(specificity); node = node.parent; From 8104066e949663b43ce6b900b1f0cfd615f5c7f0 Mon Sep 17 00:00:00 2001 From: Gaurav Bhagchandani Date: Fri, 11 Nov 2022 08:07:22 -0800 Subject: [PATCH 5/6] Added test cases --- src/test/css/hover.test.ts | 60 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/test/css/hover.test.ts b/src/test/css/hover.test.ts index 5fd0d860..58b1a3cf 100644 --- a/src/test/css/hover.test.ts +++ b/src/test/css/hover.test.ts @@ -83,6 +83,66 @@ suite('SCSS Hover', () => { }, 'scss' ); + assertHover( + '.test-class { p, .test-class { |p {} } }', + { + contents: [ + { language: 'html', value: '\n …\n

\n …\n

' }, + '[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): (0, 1, 2)' + ] + }, + 'scss' + ); + assertHover( + '.test-class { p, .test|-class { |p {} } }', + { + contents: [ + { language: 'html', value: '\n …\n ' }, + '[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): (0, 2, 0)' + ] + }, + 'scss' + ); + assertHover( + 'input { &:hover, &:focus { &::|placeholder {} } }', + { + contents: [ + { language: 'html', value: '' }, + '[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): (0, 1, 2)' + ] + }, + 'scss' + ); + assertHover( + 'input { &:hover, &:fo|cus { &::placeholder {} } }', + { + contents: [ + { language: 'html', value: '' }, + '[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): (0, 1, 1)' + ] + }, + 'scss' + ); + assertHover( + 'input { &:ho|ver, &:focus { &::placeholder {} } }', + { + contents: [ + { language: 'html', value: '' }, + '[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): (0, 1, 1)' + ] + }, + 'scss' + ); + assertHover( + 'in|put { &:hover, &:focus { &::placeholder {} } }', + { + contents: [ + { language: 'html', value: '' }, + '[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): (0, 0, 1)' + ] + }, + 'scss' + ); }); test('@at-root', () => { From 40daf3af563233dbb207b92dc656aad100d4ac26 Mon Sep 17 00:00:00 2001 From: Gaurav Bhagchandani Date: Fri, 11 Nov 2022 08:08:42 -0800 Subject: [PATCH 6/6] Changed the class name in the test case to something more standard --- src/test/css/hover.test.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/css/hover.test.ts b/src/test/css/hover.test.ts index 58b1a3cf..398cef00 100644 --- a/src/test/css/hover.test.ts +++ b/src/test/css/hover.test.ts @@ -84,20 +84,20 @@ suite('SCSS Hover', () => { 'scss' ); assertHover( - '.test-class { p, .test-class { |p {} } }', + '.foo { p, .foo { |p {} } }', { contents: [ - { language: 'html', value: '\n …\n

\n …\n

' }, + { language: 'html', value: '\n …\n

\n …\n

' }, '[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): (0, 1, 2)' ] }, 'scss' ); assertHover( - '.test-class { p, .test|-class { |p {} } }', + '.foo { p, .fo|o { |p {} } }', { contents: [ - { language: 'html', value: '\n …\n ' }, + { language: 'html', value: '\n …\n ' }, '[Selector Specificity](https://developer.mozilla.org/en-US/docs/Web/CSS/Specificity): (0, 2, 0)' ] },