Bug 224389 - Add support for a `media` attribute on `<meta name="theme-color" content="...">`
Summary: Add support for a `media` attribute on `<meta name="theme-color" content="...">`
Status: RESOLVED FIXED
Alias: None
Product: WebKit
Classification: Unclassified
Component: New Bugs (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Devin Rousso
URL:
Keywords: InRadar
Depends on: 220944
Blocks:
  Show dependency treegraph
 
Reported: 2021-04-09 13:54 PDT by Devin Rousso
Modified: 2021-05-10 10:20 PDT (History)
17 users (show)

See Also:


Attachments
Patch (28.17 KB, patch)
2021-04-12 10:03 PDT, Devin Rousso
no flags Details | Formatted Diff | Diff
Patch (27.90 KB, patch)
2021-04-13 14:29 PDT, Devin Rousso
no flags Details | Formatted Diff | Diff
Patch (16.79 KB, patch)
2021-04-22 16:07 PDT, Devin Rousso
no flags Details | Formatted Diff | Diff
Patch (27.77 KB, patch)
2021-04-22 16:09 PDT, Devin Rousso
no flags Details | Formatted Diff | Diff
Patch (25.83 KB, patch)
2021-04-28 19:06 PDT, Devin Rousso
no flags Details | Formatted Diff | Diff
Patch (26.12 KB, patch)
2021-05-07 15:34 PDT, Devin Rousso
no flags Details | Formatted Diff | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Devin Rousso 2021-04-09 13:54:00 PDT
see <https://github.com/whatwg/html/pull/6569>
Comment 1 Devin Rousso 2021-04-09 13:54:46 PDT
<rdar://problem/74991621>
Comment 2 Devin Rousso 2021-04-12 10:03:12 PDT
Created attachment 425761 [details]
Patch
Comment 3 Sam Weinig 2021-04-12 10:50:07 PDT
Comment on attachment 425761 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=425761&action=review

It would be good to have a test for 'currentcolor', since the spec has special rules for that https://html.spec.whatwg.org/#parsed-as-a-css-color-value.

> Source/WebCore/html/HTMLMetaElement.cpp:110
> +            if (equalLettersIgnoringASCIICase(this->name(), "theme-color") && mediaAttributeMatches() && !contentColor().isValid() && CSSParser::parseColor(oldValue).isValid())

It seems unfortunate to reparse the old value. Anyway to avoid that?
Comment 4 Devin Rousso 2021-04-12 10:57:38 PDT
Comment on attachment 425761 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=425761&action=review

(In reply to Sam Weinig from comment #3)
> It would be good to have a test for 'currentcolor', since the spec has special rules for that https://html.spec.whatwg.org/#parsed-as-a-css-color-value.
We currently don't support `currentcolor` for this (see <rdar://74814749>), but I can work on adding it.

>> Source/WebCore/html/HTMLMetaElement.cpp:110
>> +            if (equalLettersIgnoringASCIICase(this->name(), "theme-color") && mediaAttributeMatches() && !contentColor().isValid() && CSSParser::parseColor(oldValue).isValid())
> 
> It seems unfortunate to reparse the old value. Anyway to avoid that?

Yeah I can try restructuring this function a bit so that we check it before `HTMLElement::attributeChanged` (which calls `HTMLMetaElement::parseAttribute`, which clears `m_contentColor`).
Comment 5 Theresa O'Connor 2021-04-12 11:15:24 PDT
(In reply to Sam Weinig from comment #3)

> It would be good to have a test for 'currentcolor', since the spec has
> special rules for that
> https://html.spec.whatwg.org/#parsed-as-a-css-color-value.

The spec PR for this doesn't depend on that algorithm: https://github.com/whatwg/html/pull/6569/files
Comment 6 Theresa O'Connor 2021-04-12 11:16:32 PDT
(In reply to Theresa O'Connor from comment #5)
> (In reply to Sam Weinig from comment #3)
> 
> > It would be good to have a test for 'currentcolor', since the spec has
> > special rules for that
> > https://html.spec.whatwg.org/#parsed-as-a-css-color-value.
> 
> The spec PR for this doesn't depend on that algorithm:
> https://github.com/whatwg/html/pull/6569/files

Whoops, sorry, the existing spec text *does* depend on that. The PR doesn't change that.
Comment 7 Sam Weinig 2021-04-12 12:19:10 PDT
(In reply to Devin Rousso from comment #4)
> Comment on attachment 425761 [details]
> Patch
> 
> View in context:
> https://bugs.webkit.org/attachment.cgi?id=425761&action=review
> 
> (In reply to Sam Weinig from comment #3)
> > It would be good to have a test for 'currentcolor', since the spec has special rules for that https://html.spec.whatwg.org/#parsed-as-a-css-color-value.
> We currently don't support `currentcolor` for this (see <rdar://74814749>),
> but I can work on adding it.

Please don't link just to radar links in bugzilla, many of our contributors cannot see them. If there is work that is only in radar, it is probably worth making a bugzilla bug for it.
Comment 8 Sam Weinig 2021-04-12 12:19:59 PDT
(In reply to Theresa O'Connor from comment #6)
> (In reply to Theresa O'Connor from comment #5)
> > (In reply to Sam Weinig from comment #3)
> > 
> > > It would be good to have a test for 'currentcolor', since the spec has
> > > special rules for that
> > > https://html.spec.whatwg.org/#parsed-as-a-css-color-value.
> > 
> > The spec PR for this doesn't depend on that algorithm:
> > https://github.com/whatwg/html/pull/6569/files
> 
> Whoops, sorry, the existing spec text *does* depend on that. The PR doesn't
> change that.

The tests don't have to pass, I just think there should be tests.
Comment 9 Devin Rousso 2021-04-13 14:29:16 PDT
Created attachment 425913 [details]
Patch

(In reply to Sam Weinig from comment #8)
> (In reply to Theresa O'Connor from comment #6)
> > (In reply to Theresa O'Connor from comment #5)
> > > (In reply to Sam Weinig from comment #3)
> > > 
> > > > It would be good to have a test for 'currentcolor', since the spec has special rules for that https://html.spec.whatwg.org/#parsed-as-a-css-color-value.
> > > 
> > > The spec PR for this doesn't depend on that algorithm: https://github.com/whatwg/html/pull/6569/files
> > 
> > Whoops, sorry, the existing spec text *does* depend on that. The PR doesn't change that.
> 
> The tests don't have to pass, I just think there should be tests.

Personally I'd rather add the test when adding the feature.  I've created a followup <https://webkit.org/b/224509>.
Comment 10 Devin Rousso 2021-04-22 16:07:33 PDT
Created attachment 426860 [details]
Patch

rebase with some minor adjustments
Comment 11 Devin Rousso 2021-04-22 16:09:52 PDT
Created attachment 426861 [details]
Patch

oops forgot tests
Comment 12 Darin Adler 2021-04-25 14:02:39 PDT
Comment on attachment 426861 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=426861&action=review

> Source/WebCore/dom/Document.h:746
> +    enum class RecalculateThemeColor : uint8_t { No, IfNeeded, Yes };
> +    const Color& themeColor(RecalculateThemeColor = RecalculateThemeColor::IfNeeded);

These are three separate functions. They should *not* be a single function with an enum argument.

Compute the theme color (should be private), return the theme color (computed and cached as needed, should be public), or return the old stored version (should be private, and maybe need not be a function at all, just access to a data member).
Comment 13 Darin Adler 2021-04-25 14:09:23 PDT
Comment on attachment 426861 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=426861&action=review

> Source/WebCore/html/HTMLMetaElement.cpp:127
> +    bool wasValidMedia = m_media && mediaAttributeMatches();
> +    bool wasValidColor = m_contentColor && contentColor().isValid();
> +
>      HTMLElement::attributeChanged(name, oldValue, newValue, reason);
>  
> -    if (name == nameAttr && equalLettersIgnoringASCIICase(oldValue, "theme-color") && !equalLettersIgnoringASCIICase(newValue, "theme-color"))
> -        document().processMetaElementThemeColor(emptyString());
> +    // Changing a meta tag while it's not in the tree shouldn't have any effect on the document.
> +    if (!isConnected())
> +        return;
> +
> +    // An attribute being added (i.e. if the `media` attribute didn't exist) is handled by `process()`.
> +    if (!wasValidMedia || !wasValidColor)
> +        return;
> +
> +    if (name == nameAttr) {
> +        if (equalLettersIgnoringASCIICase(oldValue, "theme-color") && !equalLettersIgnoringASCIICase(newValue, "theme-color"))
> +            document().metaElementThemeColorChanged();
> +        return;
> +    }
> +
> +    if (name == contentAttr) {
> +        if (equalLettersIgnoringASCIICase(this->name(), "theme-color") && !contentColor().isValid())
> +            document().metaElementThemeColorChanged();
> +        return;
> +    }
> +
> +    if (name == mediaAttr) {
> +        if (equalLettersIgnoringASCIICase(this->name(), "theme-color") && !mediaAttributeMatches())
> +            document().metaElementThemeColorChanged();
> +        return;
> +    }

Not really great that this code is finely tuned based on the algorithm for what affects the color. Probably better to instead call metaElementThemeColorChanged and have it notice nothing changed. Too much logic here that replicates rules about the color that are also elsewhere. The important optimization is not telling the client outside WebKit that the color changed when it didn’t. Within WebKIt it’s better not to have logic spread across in multiple places. Just a list of which attributes might affect it should be enough, not the value.

I think the best design might be just to call:

    document().metaElementAttributeChanged();

And call it unconditionally. Leave out all the rest of the logic here. Or maybe put all the notification inside things called by process().
Comment 14 Devin Rousso 2021-04-28 16:17:35 PDT
Comment on attachment 426861 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=426861&action=review

>> Source/WebCore/dom/Document.h:746
>> +    const Color& themeColor(RecalculateThemeColor = RecalculateThemeColor::IfNeeded);
> 
> These are three separate functions. They should *not* be a single function with an enum argument.
> 
> Compute the theme color (should be private), return the theme color (computed and cached as needed, should be public), or return the old stored version (should be private, and maybe need not be a function at all, just access to a data member).

Yeah, I'm not really sure what I was thinking when I did this 😅

>> Source/WebCore/html/HTMLMetaElement.cpp:127
>> +    }
> 
> Not really great that this code is finely tuned based on the algorithm for what affects the color. Probably better to instead call metaElementThemeColorChanged and have it notice nothing changed. Too much logic here that replicates rules about the color that are also elsewhere. The important optimization is not telling the client outside WebKit that the color changed when it didn’t. Within WebKIt it’s better not to have logic spread across in multiple places. Just a list of which attributes might affect it should be enough, not the value.
> 
> I think the best design might be just to call:
> 
>     document().metaElementAttributeChanged();
> 
> And call it unconditionally. Leave out all the rest of the logic here. Or maybe put all the notification inside things called by process().

Is there also a performance concern of crawling the entire DOM to find all `HTMLMetaElement`?  That's mainly what I'm trying to avoid here by not notifying the `Document` if the change wouldn't affect `m_metaThemeColorElements` held by the `Document` (e.g. if the color was invalid previously and still is invalid).

Perhaps this is a premature "optimization" though and we could just do as you suggest and always notify the `Document` whenever `content`/`media` changes for any `<meta name="theme-color">` and have `Document` deal with filtering out cases that don't need to notify the UIProcess.  I'll give it a shot.
Comment 15 Devin Rousso 2021-04-28 19:06:46 PDT
Created attachment 427323 [details]
Patch
Comment 16 Ryosuke Niwa 2021-05-07 14:24:37 PDT
Comment on attachment 427323 [details]
Patch

View in context: https://bugs.webkit.org/attachment.cgi?id=427323&action=review

> Source/WebCore/html/HTMLMetaElement.cpp:93
> +    // Changing a meta tag while it's not in the tree shouldn't have any effect on the document.

This comment is unnecessary. It's pretty obvious from the code that's what's happening.
Comment 17 Devin Rousso 2021-05-07 15:34:06 PDT
Created attachment 428044 [details]
Patch
Comment 18 EWS 2021-05-10 10:20:19 PDT
Committed r277270 (237537@main): <https://commits.webkit.org/237537@main>

All reviewed patches have been landed. Closing bug and clearing flags on attachment 428044 [details].