Skip to content

Commit

Permalink
feat(compiler): support directive selectors with attributes containin…
Browse files Browse the repository at this point in the history
…g `$`

This commit adds support for `$` in when selecting attributes.

Resolves angular#41244.

test(language-service): Add test to expose bug caused by source file change (angular#41500)

This commit adds a test to expose the bug caused by source file change in
between typecheck programs.

PR Close angular#41500
  • Loading branch information
iRealNirmal committed Apr 28, 2021
1 parent 3b7d4eb commit 3e4d7d5
Show file tree
Hide file tree
Showing 2 changed files with 90 additions and 5 deletions.
10 changes: 5 additions & 5 deletions packages/compiler/src/selector.ts
Expand Up @@ -13,11 +13,11 @@ const _SELECTOR_REGEXP = new RegExp(
'(([\\.\\#]?)[-\\w]+)|' + // 2: "tag"; 3: "."/"#";
// "-" should appear first in the regexp below as FF31 parses "[.-\w]" as a range
// 4: attribute; 5: attribute_string; 6: attribute_value
'(?:\\[([-.\\w*]+)(?:=([\"\']?)([^\\]\"\']*)\\5)?\\])|' + // "[name]", "[name=value]",
// "[name="value"]",
// "[name='value']"
'(\\))|' + // 7: ")"
'(\\s*,\\s*)', // 8: ","
'(?:\\[([-.\\w$*]+)(?:=([\"\']?)([^\\]\"\']*)\\5)?\\])|' + // "[name]", "[name=value]",
// "[name="value"]",
// "[name='value']"
'(\\))|' + // 7: ")"
'(\\s*,\\s*)', // 8: ","
'g');

/**
Expand Down
85 changes: 85 additions & 0 deletions packages/compiler/test/selector/selector_spec.ts
Expand Up @@ -126,6 +126,91 @@ import {el} from '@angular/platform-browser/testing/src/browser_util';
expect(matched).toEqual([s1[0], 1]);
});

it('should support "$" in attribute names', () => {
matcher.addSelectables(s1 = CssSelector.parse('[someAttr$]'), 1);

      expect(
matcher.match(getSelectorFor({attrs[['someAttr', '']]}), selectableCollector))
.toEqual(false);
expect(matched).toEqual([]);

expect(matcher.match(getSelectorFor({attrs[['someAttr$', '']]}), selectableCollector))
.toEqual(true);
expect(matched).toEqual([s1[0], 1]);
      reset();

matcher.addSelectables(s1 = CssSelector.parse('[some$attr]'), 1);

      expect(
matcher.match(getSelectorFor({attrs[['someattr', '']]}), selectableCollector))
.toEqual(false);
expect(matched).toEqual([]);

expect(matcher.match(getSelectorFor({attrs[['some$attr', '']]}), selectableCollector))
.toEqual(true);
expect(matched).toEqual([s1[0], 1]);
      reset();

matcher.addSelectables(s1 = CssSelector.parse('[$someAttr]'), 1);

      expect(
matcher.match(getSelectorFor({attrs[['someAttr', '']]}), selectableCollector))
.toEqual(false);
expect(matched).toEqual([]);

expect(matcher.match(getSelectorFor({attrs[['$someAttr', '']]}), selectableCollector))
.toEqual(true);
expect(matched).toEqual([s1[0], 1]);
reset();

matcher.addSelectables(s1 = CssSelector.parse('[some-$Attr]'), 1);
matcher.addSelectables(s2 = CssSelector.parse('[some-$Attr][some-$-attr]'), 2);

expect(matcher.match(getSelectorFor({attrs[['some$Attr', '']]}), selectableCollector))
.toEqual(false);
expect(matched).toEqual([]);

expect(matcher.match(
getSelectorFor({attrs: [['some-$-attr', 'someValue'], ['some-$Attr', '']]}),
selectableCollector))
.toEqual(true);
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
reset();

matcher.addSelectables(s1 = CssSelector.parse('[some-attr-$]'), 1);
matcher.addSelectables(s2 = CssSelector.parse('[some-attr-$][$-some-attr]'), 2);

expect(matcher.match(getSelectorFor({attrs[['someattr$', '']]}), selectableCollector))
.toEqual(false);
expect(matched).toEqual([]);

expect(matcher.match(
getSelectorFor(
{attrs: [['$-some-attr', 'someOtherValue'], ['some-attr-$', 'someValue']]}),
selectableCollector))
.toEqual(true);
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
reset();


matcher.addSelectables(s1 = CssSelector.parse('[someSimpleAttr]'), 1);
matcher.addSelectables(s2 = CssSelector.parse('[someSimpleAttr][$-some-attr]'), 2);

expect(matcher.match(
getSelectorFor({attrs[['some-simple-attr', '']]}), selectableCollector))
.toEqual(false);
expect(matched).toEqual([]);

expect(
matcher.match(
getSelectorFor(
{attrs: [['$-some-attr', 'someValue'], ['someSimpleAttr', 'someSimpleValue']]}),
selectableCollector))
.toEqual(true);
expect(matched).toEqual([s1[0], 1, s2[0], 2]);
reset();
});

it('should select by attr name only once if the value is from the DOM', () => {
matcher.addSelectables(s1 = CssSelector.parse('[some-decor]'), 1);

Expand Down

0 comments on commit 3e4d7d5

Please sign in to comment.