<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>253814</bug_id>
          
          <creation_ts>2023-03-13 02:00:59 -0700</creation_ts>
          <short_desc>Concat with a CSSStyleSheet and shadowRoot.adoptedStyleSheets returns array in array</short_desc>
          <delta_ts>2023-03-13 17:30:07 -0700</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>CSS</component>
          <version>Safari 16</version>
          <rep_platform>All</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords>InRadar</keywords>
          <priority>P2</priority>
          <bug_severity>Major</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Bram Kragten">mail</reporter>
          <assigned_to name="Yusuke Suzuki">ysuzuki</assigned_to>
          <cc>cdumez</cc>
    
    <cc>ggaren</cc>
    
    <cc>mark.lam</cc>
    
    <cc>webkit-bug-importer</cc>
    
    <cc>ysuzuki</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>1940814</commentid>
    <comment_count>0</comment_count>
    <who name="Bram Kragten">mail</who>
    <bug_when>2023-03-13 02:00:59 -0700</bug_when>
    <thetext>In Safari 16.4, when concatting a CSSStyleSheet with the shadowRoot.adoptedStyleSheets, it returns a nested array instead of a flat one:

Correct:
&gt; [new CSSStyleSheet].concat([])
&lt; [CSSStyleSheet] (1)
&gt; [new CSSStyleSheet].concat([new CSSStyleSheet])
&lt; [CSSStyleSheet, CSSStyleSheet] (2)

Not correct:
&gt; $0.shadowRoot.adoptedStyleSheets
&lt; [CSSStyleSheet] (1)
&gt; [new CSSStyleSheet].concat($0.shadowRoot.adoptedStyleSheets)
&lt; [CSSStyleSheet, Array] (2)
Expected:
&lt; [CSSStyleSheet, CSSStyleSheet] (2)

Correct:
&gt; [new CSSStyleSheet, ...$0.shadowRoot.adoptedStyleSheets]
&lt; [CSSStyleSheet, CSSStyleSheet] (2)</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1940869</commentid>
    <comment_count>1</comment_count>
    <who name="Chris Dumez">cdumez</who>
    <bug_when>2023-03-13 07:27:44 -0700</bug_when>
    <thetext>Question for JSC people (added in cc). Do you know what I need to do in order to make concat() behave correctly with this new IDL type?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1940875</commentid>
    <comment_count>2</comment_count>
    <who name="Chris Dumez">cdumez</who>
    <bug_when>2023-03-13 07:33:36 -0700</bug_when>
    <thetext>(In reply to Chris Dumez from comment #1)
&gt; Question for JSC people (added in cc). Do you know what I need to do in
&gt; order to make concat() behave correctly with this new IDL type?

The type of adoptedStyleSheets is a JSC::JSObservableArray, which is a subclass of JSC::JSArray.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1940883</commentid>
    <comment_count>3</comment_count>
    <who name="Chris Dumez">cdumez</who>
    <bug_when>2023-03-13 07:45:36 -0700</bug_when>
    <thetext>(In reply to Chris Dumez from comment #2)
&gt; (In reply to Chris Dumez from comment #1)
&gt; &gt; Question for JSC people (added in cc). Do you know what I need to do in
&gt; &gt; order to make concat() behave correctly with this new IDL type?
&gt; 
&gt; The type of adoptedStyleSheets is a JSC::JSObservableArray, which is a
&gt; subclass of JSC::JSArray.

Looks like concat relies on isJSArray():

inline bool isJSArray(JSCell* cell)
{
    ASSERT((cell-&gt;classInfo() == JSArray::info()) == (cell-&gt;type() == ArrayType));
    return cell-&gt;type() == ArrayType;
}

So `cell-&gt;type() == ArrayType` is likely false for JSC::JSObservableArray.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1940888</commentid>
    <comment_count>4</comment_count>
    <who name="Chris Dumez">cdumez</who>
    <bug_when>2023-03-13 07:50:50 -0700</bug_when>
    <thetext>(In reply to Chris Dumez from comment #3)
&gt; (In reply to Chris Dumez from comment #2)
&gt; &gt; (In reply to Chris Dumez from comment #1)
&gt; &gt; &gt; Question for JSC people (added in cc). Do you know what I need to do in
&gt; &gt; &gt; order to make concat() behave correctly with this new IDL type?
&gt; &gt; 
&gt; &gt; The type of adoptedStyleSheets is a JSC::JSObservableArray, which is a
&gt; &gt; subclass of JSC::JSArray.
&gt; 
&gt; Looks like concat relies on isJSArray():
&gt; 
&gt; inline bool isJSArray(JSCell* cell)
&gt; {
&gt;     ASSERT((cell-&gt;classInfo() == JSArray::info()) == (cell-&gt;type() ==
&gt; ArrayType));
&gt;     return cell-&gt;type() == ArrayType;
&gt; }
&gt; 
&gt; So `cell-&gt;type() == ArrayType` is likely false for JSC::JSObservableArray.

cell-&gt;type() is DerivedArrayType for JSObservableArray, not ArrayType.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1940890</commentid>
    <comment_count>5</comment_count>
    <who name="Chris Dumez">cdumez</who>
    <bug_when>2023-03-13 08:04:12 -0700</bug_when>
    <thetext>Ecmascript for concat [1] says to rely on IsConcatSpreadable() [2]. IsConcatSpreadable() checks the @@isConcatSpreadable symbol and then fallback to calling IsArray() [3].

ObservableArray is defined here [4].

[1] https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.prototype.concat
[2] https://tc39.es/ecma262/multipage/indexed-collections.html#sec-isconcatspreadable
[3] https://tc39.es/ecma262/multipage/abstract-operations.html#sec-isarray
[4] https://webidl.spec.whatwg.org/#es-observable-array</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1940891</commentid>
    <comment_count>6</comment_count>
    <who name="Chris Dumez">cdumez</who>
    <bug_when>2023-03-13 08:06:44 -0700</bug_when>
    <thetext>(In reply to Chris Dumez from comment #5)
&gt; Ecmascript for concat [1] says to rely on IsConcatSpreadable() [2].
&gt; IsConcatSpreadable() checks the @@isConcatSpreadable symbol and then
&gt; fallback to calling IsArray() [3].
&gt; 
&gt; ObservableArray is defined here [4].
&gt; 
&gt; [1]
&gt; https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.
&gt; prototype.concat
&gt; [2]
&gt; https://tc39.es/ecma262/multipage/indexed-collections.html#sec-
&gt; isconcatspreadable
&gt; [3] https://tc39.es/ecma262/multipage/abstract-operations.html#sec-isarray
&gt; [4] https://webidl.spec.whatwg.org/#es-observable-array

From https://webidl.spec.whatwg.org/#observable-array-exotic-object:
```
An observable array exotic object is a specific type of ECMAScript Proxy exotic object which is created using the proxy traps defined in this section. They are defined in this manner because the ECMAScript specification includes special treatment for Proxy exotic objects that have Array instances as their proxy target, and we want to ensure that observable array types are exposed to ECMAScript code with this special treatment intact.
```

So I believe concat should indeed spread the observable array here. However, our implementation currently relies on isJSArray(), not isArray() (which would be what the spec says).</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1940910</commentid>
    <comment_count>7</comment_count>
    <who name="Chris Dumez">cdumez</who>
    <bug_when>2023-03-13 09:11:43 -0700</bug_when>
    <thetext>(In reply to Chris Dumez from comment #6)
&gt; (In reply to Chris Dumez from comment #5)
&gt; &gt; Ecmascript for concat [1] says to rely on IsConcatSpreadable() [2].
&gt; &gt; IsConcatSpreadable() checks the @@isConcatSpreadable symbol and then
&gt; &gt; fallback to calling IsArray() [3].
&gt; &gt; 
&gt; &gt; ObservableArray is defined here [4].
&gt; &gt; 
&gt; &gt; [1]
&gt; &gt; https://tc39.es/ecma262/multipage/indexed-collections.html#sec-array.
&gt; &gt; prototype.concat
&gt; &gt; [2]
&gt; &gt; https://tc39.es/ecma262/multipage/indexed-collections.html#sec-
&gt; &gt; isconcatspreadable
&gt; &gt; [3] https://tc39.es/ecma262/multipage/abstract-operations.html#sec-isarray
&gt; &gt; [4] https://webidl.spec.whatwg.org/#es-observable-array
&gt; 
&gt; From https://webidl.spec.whatwg.org/#observable-array-exotic-object:
&gt; ```
&gt; An observable array exotic object is a specific type of ECMAScript Proxy
&gt; exotic object which is created using the proxy traps defined in this
&gt; section. They are defined in this manner because the ECMAScript
&gt; specification includes special treatment for Proxy exotic objects that have
&gt; Array instances as their proxy target, and we want to ensure that observable
&gt; array types are exposed to ECMAScript code with this special treatment
&gt; intact.
&gt; ```
&gt; 
&gt; So I believe concat should indeed spread the observable array here. However,
&gt; our implementation currently relies on isJSArray(), not isArray() (which
&gt; would be what the spec says).

I have tried several approaches here but I keep hitting assertions. Seems existing code is not happy dealing with a JSObservableArray, even though it is a JSArray subclass.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1940942</commentid>
    <comment_count>8</comment_count>
    <who name="Chris Dumez">cdumez</who>
    <bug_when>2023-03-13 10:42:24 -0700</bug_when>
    <thetext>Pull request: https://github.com/WebKit/WebKit/pull/11449</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1941018</commentid>
    <comment_count>9</comment_count>
    <who name="Radar WebKit Bug Importer">webkit-bug-importer</who>
    <bug_when>2023-03-13 15:24:35 -0700</bug_when>
    <thetext>&lt;rdar://problem/106667776&gt;</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1941022</commentid>
    <comment_count>10</comment_count>
    <who name="Yusuke Suzuki">ysuzuki</who>
    <bug_when>2023-03-13 15:29:52 -0700</bug_when>
    <thetext>Pull request: https://github.com/WebKit/WebKit/pull/11465</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>1941060</commentid>
    <comment_count>11</comment_count>
    <who name="EWS">ews-feeder</who>
    <bug_when>2023-03-13 17:30:02 -0700</bug_when>
    <thetext>Committed 261604@main (9d30cd47aaab): &lt;https://commits.webkit.org/261604@main&gt;

Reviewed commits have been landed. Closing PR #11465 and removing active labels.</thetext>
  </long_desc>
      
      

    </bug>

</bugzilla>