Skip to content

[cssom-1] Replace steps of set a CSS declaration with some constraints #2924

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 17, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 91 additions & 16 deletions cssom-1/Overview.bs
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,8 @@ spec:html; type:dfn; text:ascii case-insensitive
spec:html; type:dfn; text:case-sensitive
spec:infra; type:dfn; text:list
spec:css-logical; type:property; text:inline-size
spec:css-logical; type:dfn; text:logical property group
spec:css-logical; type:dfn; text:logical kind
spec:css-variables-1; type:dfn; text:custom property
spec:selectors-3; type:selector; text:::before
spec:selectors-3; type:selector; text:::after
Expand Down Expand Up @@ -2190,28 +2192,101 @@ The <dfn method for=CSSStyleDeclaration>setProperty(<var>property</var>, <var>va
Note: <var>value</var> can not include "<code>!important</code>".

<li>If <var>component value list</var> is null, then return.
<li>Let <var>updated</var> be false.
<li>If <var>property</var> is a shorthand property, then for each longhand property <var>longhand</var> that <var>property</var> maps to, in canonical
order, <a lt="set a CSS declaration">set the CSS declaration</a> <var>longhand</var> with the appropriate value(s) from <var>component value
list</var>, with the <i>important</i> flag set if <var>priority</var> is not the empty string, and unset otherwise, and with the list of declarations being the
<a for="CSSStyleDeclaration">declarations</a>.
<li>Otherwise, <a lt="set a CSS declaration">set the CSS declaration</a> <var>property</var> with value <var>component value list</var>, with
the <i>important</i> flag set if <var>priority</var> is not the empty string, and unset otherwise, and with the list of declarations being the
order, follow these substeps:
<ol>
<li>Let <var>longhand result</var> be the result of <a lt="set a CSS declaration">set the CSS declaration</a>
<var>longhand</var> with the appropriate value(s) from <var>component value list</var>, with the <i>important</i>
flag set if <var>priority</var> is not the empty string, and unset otherwise, and with the list of declarations
being the <a for="CSSStyleDeclaration">declarations</a>.
<li>If <var>longhand result</var> is true, let <var>updated</var> be true.
</ol>
<li>Otherwise, let <var>updated</var> be the result of <a lt="set a CSS declaration">set the CSS declaration</a>
<var>property</var> with value <var>component value list</var>, with the <i>important</i> flag set if
<var>priority</var> is not the empty string, and unset otherwise, and with the list of declarations being the
<a for="CSSStyleDeclaration">declarations</a>.
<li><a>Update style attribute for</a> the <a>CSS declaration block</a>.
<li>If <var>updated</var> is true, <a>update style attribute for</a> the <a>CSS declaration block</a>.
</ol>

To <dfn export>set a CSS declaration</dfn> <var>property</var> with a value <var>component value list</var> and optionally with an <i>important</i> flag set, in
a list of declarations <var>declarations</var>, follow these steps:
a list of declarations <var>declarations</var>, the user agent must ensure the following constraints hold after its steps:

<ol>
<li>If <var>property</var> is a <a>case-sensitive</a> match for a <a for="CSS declaration">property
name</a> of a <a>CSS declaration</a> in <var>declarations</var>, remove that <a>CSS declaration</a>.
<li>Append a new <a>CSS declaration</a> with the <a for="CSS declaration">property name</a> <var>property</var>
to <var>declarations</var> and let <var>declaration</var> be that <a>CSS declaration</a>.
<li>Set <var>declaration</var>'s <a for="CSS declaration">value</a> to <var>component value list</var>.
<li>If the <i>important</i> flag is set, set <var>declaration</var>'s <a for="CSS declaration">important flag</a>.
Otherwise, unset <var>declaration</var>'s <a for="CSS declaration">important flag</a>.
</ol>
<ul>
<li>
Exactly one <a>CSS declaration</a> whose <a for="CSS declaration">property name</a> is a
<a>case-sensitive</a> match of <var>property</var> must exist in <var>declarations</var>.
Such declaration is referenced as the <var>target declaration</var> below.

<li>
The <var>target declaration</var> must have value being <var>component value list</var>,
and <var>target declaration</var>'s <a for="CSS declaration">important flag</a> must be
<a>set</a> if <i>important</i> flag is set, and <a>unset</a> otherwise.

<li>
Any <a>CSS declaration</a> which is not the <var>target declaration</var> must not be changed, inserted,
or removed from <var>declarations</var>.

<li>
If there are <a>CSS declarations</a> in <var>declarations</var> whose
<a for="CSS declaration">property name</a> is in the same <a>logical property group</a> as
<var>property</var>, but has a different <a>logical kind</a>, <var>target declaration</var> must be
at an index after all of those <a>CSS declarations</a>.

<li>
The steps must return true if the serialization of <var>declarations</var> was changed as result
of the steps. It may return false otherwise.
</ul>

Issue: Should we add something like "Any observable side effect must not be made outside
<var>declarations</var>"? The current constraints sound like a hole for undefined behavior.

Note: The steps of <a>set a CSS declaration</a> are not defined in this level of CSSOM. The user agent may
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: plural: user agents may use different algorithms as long as the contraints above hold

use different algorithm as far as the constraints above hold.

<div class="example">
The simplest way to conform with the constraints would be to always remove any existing declaration
matching <var>property</var>, and append the new declaration to the end. But based on implementation
feedback, this approach would likely regress performance.

Another possible algorithm is:
<ol>
<li>If <var>property</var> is a <a>case-sensitive</a> match for a <a for="CSS declaration">property name</a>
of a <a>CSS declaration</a> in <var>declarations</var>, follow these substeps:
<ol>
<li>Let <var>target declaration</var> be such <a>CSS declaration</a>.
<li>Let <var>needs append</var> be false.
<li><a for="list">For each</a> <var>declaration</var> in <var>declarations</var> after
<var>target declaration</var>:
<ol>
<li>If <var>declaration</var>'s <a for="CSS declaration">property name</a> is not in the same
<a>logical property group</a> as <var>property</var>, then <a>continue</a>.
<li>If <var>declaration</var>' <a for="CSS declaration">property name</a> has the same
<a>logical kind</a> as <var>property</var>, then <a>continue</a>.
<li>Let <var>needs append</var> be true.
<li><a>Break</a>.
</ol>
<li>If <var>needs append</var> is false, then:
<ol>
<li>Let <var>needs update</var> be false.
<li>If <var>target declaration</var>'s <a for="CSS declaration">value</a> is not equal to <var>component
value list</var>, then let <var>needs update</var> be true.
<li>If <var>target declaration</var>'s <a for="CSS declaration">important flag</a> is not equal to
whether <i>important</i> flag is set, then let <var>needs update</var> be true.
<li>If <var>needs update</var> is false, then return false.
<li>Set <var>target declaration</var>'s <a for="CSS declaration">value</a> to <var>component value list</var>.
<li>If <i>important</i> flag is set, then set <var>target declaration</var>'s
<a for="CSS declaration">important flag</a>, otherwise unset it.
<li>Return true.
</ol>
<li>Otherwise, remove <var>target declaration</var> from <var>declarations</var>.
</ol>
<li>Append a new <a>CSS declaration</a> with <a for="CSS declaration">property name</a> <var>property</var>,
<a for="CSS declaration">value</a> <var>component value list</var>, and <a for="CSS declaration">important flag</a>
set if <i>important</i> flag is set to <var>declarations</var>.
<li>Return true.
</ol>
</div>

The <dfn method for=CSSStyleDeclaration>removeProperty(<var>property</var>)</dfn> method must run these steps:
<ol>
Expand Down