Skip to content

fix(icon): handle references for pages with base tag - #12428

Merged
vivian-hu-zz merged 1 commit into
angular:masterfrom
crisbeto:9276/svg-references-prepend
Oct 5, 2018
Merged

fix(icon): handle references for pages with base tag#12428
vivian-hu-zz merged 1 commit into
angular:masterfrom
crisbeto:9276/svg-references-prepend

Conversation

@crisbeto

Copy link
Copy Markdown
Member

Prepends the current path to any SVG elements with attributes pointing to something by id. If the reference isn't prefixed, it won't work on Safari if the page has a base tag (which is used by most Angular apps that are using the router).

Fixes#9276.

@crisbetocrisbeto added the target: patch This PR is targeted for the next patch release label Jul 29, 2018
@crisbeto
crisbeto requested a review from jelbourn as a code ownerJuly 29, 2018 14:29
@googlebotgooglebot added the cla: yes PR author has agreed to Google's Contributor License Agreement label Jul 29, 2018

@jelbournjelbourn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a breaking change is someone was already depending on the component not changing the uris?

@crisbeto

Copy link
Copy Markdown
MemberAuthor

I can only see it being a breaking change if somebody was unit testing it and checking explicitly that it doesn't have a prefix, otherwise it should work exactly the same.

Comment threadsrc/lib/icon/icon.ts
const funcIriAttributeSelector = funcIriAttributes.map(attr => `[${attr}]`).join(', ');

/** Regex that can be used to extract the id out of a FuncIRI. */
const funcIriPattern = /^url\(['"]?#(.*?)['"]?\)$/;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a link we could put here for some spec for this format? Should the # be optional?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could link to the SVG spec or MDN, but the link is longer than the description of the format: https://developer.mozilla.org/en-US/docs/Web/SVG/Content_type#FuncIRI. As for the #, it shouldn't be optional, because we only want to target references by ID.

Comment threadsrc/lib/icon/icon.ts
*/
private _prependCurrentPathToReferences(element: SVGElement) {
// @breaking-change 8.0.0 Remove this null check once `_location` parameter is required.
if (!this._location) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last thing: should we just restrict this to webkit, then? I suspect it's not hugely costly, but if we can easily/reliably cut out the extra work, we might as well.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with doing it on all browsers since it shouldn't be too costly (unless an individual icon has hundreds of elements that all have one of the attributes) and to avoid having too many of these forks in the logic where we sniff out the browser and do special things just for one vendor.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking a little closer- could we do this prepending at the icon-registry level so that it only has to happen once per svg? I didn't realize earlier it was happening for every directive instance.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left a comment for it a bit further down. Having it in the registry would be ideal, but we want the path at the time the icon was created, rather than when it was fetched. If we did it in the registry, it would be cached with the initial path.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the path in <base> normally change?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't the icon registry not request an SVG until it's used anyway?

I'm just hesitant to go forward with adding the extra work for pages that might have multiple icons in something like a large data table or option list.

@crisbetocrisbetoAug 1, 2018

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does, but it also caches it afterwards. If performance is a concern, an alternative can be to have some kind of inexpensive check against the string representation of the icon before we do the querySelector and we walk through all the attributes. E.g. adding a MatIconRegistry.hasFuncIRI(iconName) method which just does a regex match or an indexOf.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not the check so much as actually updating each uri that I'm worried about.

@crisbetocrisbetoAug 1, 2018

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure whether it would be that expensive, compared to what we're doing for each icon already (cloning the cached SVG node).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fair.

@jelbournjelbourn left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@jelbournjelbourn added pr: lgtm action: merge The PR is ready for merge by the caretaker labels Aug 1, 2018
@ngbot

ngbotBot commented Aug 31, 2018

Copy link
Copy Markdown

Hi @crisbeto! This PR has merge conflicts due to recent upstream merges.
Please help to unblock it by resolving these conflicts. Thanks!

@crisbeto
crisbetoforce-pushed the 9276/svg-references-prepend branch from 4911d4b to 301fd78CompareSeptember 1, 2018 07:51
Prepends the current path to any SVG elements with attributes pointing to something by id. If the reference isn't prefixed, it won't work on Safari if the page has a `base` tag (which is used by most Angular apps that are using the router).
Fixesangular#9276.
@crisbeto
crisbetoforce-pushed the 9276/svg-references-prepend branch from 301fd78 to 6b8868dCompareOctober 5, 2018 06:02
@vivian-hu-zz
vivian-hu-zz merged commit 9e5fd91 into angular:masterOct 5, 2018
roboshoes pushed a commit to roboshoes/material2 that referenced this pull request Oct 23, 2018
Prepends the current path to any SVG elements with attributes pointing to something by id. If the reference isn't prefixed, it won't work on Safari if the page has a `base` tag (which is used by most Angular apps that are using the router).
Fixesangular#9276.
@angular-automatic-lock-bot

Copy link
Copy Markdown

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

This action has been performed automatically by a bot.

@angular-automatic-lock-botangular-automatic-lock-botBot locked and limited conversation to collaborators Sep 9, 2019
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

action: mergeThe PR is ready for merge by the caretakercla: yesPR author has agreed to Google's Contributor License Agreementtarget: patchThis PR is targeted for the next patch release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Enhancement: mat-icon set current page absolute path on filter urls for compatibility with safari

4 participants

@crisbeto@jelbourn@googlebot@vivian-hu-zz