mirror of
https://github.com/servo/servo.git
synced 2025-06-06 16:45:39 +00:00
Implement declarative shadow dom (#34964)
* Implement declarative shadow dom Signed-off-by: batu_hoang <longvatrong111@gmail.com> * Set allowDeclarativeShadowRoots false for innerHTML Signed-off-by: batu_hoang <longvatrong111@gmail.com> * Enable allowDeclarativeShadowRoots for Document Signed-off-by: batu_hoang <longvatrong111@gmail.com> * Expose HTMLTemplateElement to js Signed-off-by: batu_hoang <longvatrong111@gmail.com> * Implemenet setHTMLUnsafe and add more test cases Signed-off-by: batu_hoang <longvatrong111@gmail.com> * Declarative shadow dom: minor updates and expected test result update Signed-off-by: batu_hoang <longvatrong111@gmail.com> * Shadow-dom: add more test cases Signed-off-by: batu_hoang <longvatrong111@gmail.com> * Update comments according to the spec Signed-off-by: batu_hoang <longvatrong111@gmail.com> * Bump html5ever version Signed-off-by: batu_hoang <longvatrong111@gmail.com> --------- Signed-off-by: batu_hoang <longvatrong111@gmail.com>
This commit is contained in:
parent
f483a3d34b
commit
28c8c1df0c
44 changed files with 360 additions and 1965 deletions
|
@ -513,6 +513,8 @@ pub(crate) struct Document {
|
|||
status_code: Option<u16>,
|
||||
/// <https://html.spec.whatwg.org/multipage/#is-initial-about:blank>
|
||||
is_initial_about_blank: Cell<bool>,
|
||||
/// <https://dom.spec.whatwg.org/#document-allow-declarative-shadow-roots>
|
||||
allow_declarative_shadow_roots: Cell<bool>,
|
||||
/// <https://w3c.github.io/webappsec-upgrade-insecure-requests/#insecure-requests-policy>
|
||||
#[no_trace]
|
||||
inherited_insecure_requests_policy: Cell<Option<InsecureRequestsPolicy>>,
|
||||
|
@ -3590,6 +3592,7 @@ impl Document {
|
|||
status_code: Option<u16>,
|
||||
canceller: FetchCanceller,
|
||||
is_initial_about_blank: bool,
|
||||
allow_declarative_shadow_roots: bool,
|
||||
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
|
||||
) -> Document {
|
||||
let url = url.unwrap_or_else(|| ServoUrl::parse("about:blank").unwrap());
|
||||
|
@ -3740,6 +3743,7 @@ impl Document {
|
|||
visibility_state: Cell::new(DocumentVisibilityState::Hidden),
|
||||
status_code,
|
||||
is_initial_about_blank: Cell::new(is_initial_about_blank),
|
||||
allow_declarative_shadow_roots: Cell::new(allow_declarative_shadow_roots),
|
||||
inherited_insecure_requests_policy: Cell::new(inherited_insecure_requests_policy),
|
||||
intersection_observer_task_queued: Cell::new(false),
|
||||
}
|
||||
|
@ -3874,6 +3878,7 @@ impl Document {
|
|||
status_code: Option<u16>,
|
||||
canceller: FetchCanceller,
|
||||
is_initial_about_blank: bool,
|
||||
allow_declarative_shadow_roots: bool,
|
||||
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<Document> {
|
||||
|
@ -3893,6 +3898,7 @@ impl Document {
|
|||
status_code,
|
||||
canceller,
|
||||
is_initial_about_blank,
|
||||
allow_declarative_shadow_roots,
|
||||
inherited_insecure_requests_policy,
|
||||
can_gc,
|
||||
)
|
||||
|
@ -3915,6 +3921,7 @@ impl Document {
|
|||
status_code: Option<u16>,
|
||||
canceller: FetchCanceller,
|
||||
is_initial_about_blank: bool,
|
||||
allow_declarative_shadow_roots: bool,
|
||||
inherited_insecure_requests_policy: Option<InsecureRequestsPolicy>,
|
||||
can_gc: CanGc,
|
||||
) -> DomRoot<Document> {
|
||||
|
@ -3934,6 +3941,7 @@ impl Document {
|
|||
status_code,
|
||||
canceller,
|
||||
is_initial_about_blank,
|
||||
allow_declarative_shadow_roots,
|
||||
inherited_insecure_requests_policy,
|
||||
)),
|
||||
window,
|
||||
|
@ -4066,6 +4074,7 @@ impl Document {
|
|||
None,
|
||||
Default::default(),
|
||||
false,
|
||||
self.allow_declarative_shadow_roots(),
|
||||
Some(self.insecure_requests_policy()),
|
||||
can_gc,
|
||||
);
|
||||
|
@ -4598,6 +4607,15 @@ impl Document {
|
|||
pub(crate) fn is_initial_about_blank(&self) -> bool {
|
||||
self.is_initial_about_blank.get()
|
||||
}
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#document-allow-declarative-shadow-roots>
|
||||
pub fn allow_declarative_shadow_roots(&self) -> bool {
|
||||
self.allow_declarative_shadow_roots.get()
|
||||
}
|
||||
|
||||
pub fn set_allow_declarative_shadow_roots(&self, value: bool) {
|
||||
self.allow_declarative_shadow_roots.set(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl ProfilerMetadataFactory for Document {
|
||||
|
@ -4636,6 +4654,7 @@ impl DocumentMethods<crate::DomTypeHolder> for Document {
|
|||
None,
|
||||
Default::default(),
|
||||
false,
|
||||
doc.allow_declarative_shadow_roots(),
|
||||
Some(doc.insecure_requests_policy()),
|
||||
can_gc,
|
||||
))
|
||||
|
|
|
@ -174,6 +174,7 @@ impl DOMImplementationMethods<crate::DomTypeHolder> for DOMImplementation {
|
|||
None,
|
||||
Default::default(),
|
||||
false,
|
||||
self.document.allow_declarative_shadow_roots(),
|
||||
Some(self.document.insecure_requests_policy()),
|
||||
can_gc,
|
||||
);
|
||||
|
|
|
@ -88,6 +88,7 @@ impl DOMParserMethods<crate::DomTypeHolder> for DOMParser {
|
|||
None,
|
||||
Default::default(),
|
||||
false,
|
||||
false,
|
||||
Some(doc.insecure_requests_policy()),
|
||||
can_gc,
|
||||
);
|
||||
|
@ -111,6 +112,7 @@ impl DOMParserMethods<crate::DomTypeHolder> for DOMParser {
|
|||
None,
|
||||
Default::default(),
|
||||
false,
|
||||
false,
|
||||
Some(doc.insecure_requests_policy()),
|
||||
can_gc,
|
||||
);
|
||||
|
|
|
@ -2076,7 +2076,7 @@ impl Element {
|
|||
) -> Fallible<DomRoot<DocumentFragment>> {
|
||||
// Steps 1-2.
|
||||
// TODO(#11995): XML case.
|
||||
let new_children = ServoParser::parse_html_fragment(self, markup, can_gc);
|
||||
let new_children = ServoParser::parse_html_fragment(self, markup, false, can_gc);
|
||||
// Step 3.
|
||||
// See https://github.com/w3c/DOM-Parsing/issues/61.
|
||||
let context_document = {
|
||||
|
@ -2857,6 +2857,39 @@ impl ElementMethods<crate::DomTypeHolder> for Element {
|
|||
self.client_rect(can_gc).size.height
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-element-sethtmlunsafe>
|
||||
fn SetHTMLUnsafe(&self, html: DOMString, can_gc: CanGc) {
|
||||
// Step 2. Let target be this's template contents if this is a template element; otherwise this.
|
||||
let target = if let Some(template) = self.downcast::<HTMLTemplateElement>() {
|
||||
DomRoot::upcast(template.Content(can_gc))
|
||||
} else {
|
||||
DomRoot::from_ref(self.upcast())
|
||||
};
|
||||
|
||||
// Step 3. Unsafely set HTML given target, this, and compliantHTML.
|
||||
// Let newChildren be the result of the HTML fragment parsing algorithm.
|
||||
let new_children = ServoParser::parse_html_fragment(self, html, true, can_gc);
|
||||
|
||||
let context_document = {
|
||||
if let Some(template) = self.downcast::<HTMLTemplateElement>() {
|
||||
template.Content(can_gc).upcast::<Node>().owner_doc()
|
||||
} else {
|
||||
self.owner_document()
|
||||
}
|
||||
};
|
||||
|
||||
// Let fragment be a new DocumentFragment whose node document is contextElement's node document.
|
||||
let frag = DocumentFragment::new(&context_document, can_gc);
|
||||
|
||||
// For each node in newChildren, append node to fragment.
|
||||
for child in new_children {
|
||||
frag.upcast::<Node>().AppendChild(&child).unwrap();
|
||||
}
|
||||
|
||||
// Replace all with fragment within target.
|
||||
Node::replace_all(Some(frag.upcast()), &target);
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-element-innerhtml>
|
||||
fn GetInnerHTML(&self) -> Fallible<DOMString> {
|
||||
let qname = QualName::new(
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use dom_struct::dom_struct;
|
||||
use html5ever::{LocalName, Prefix};
|
||||
use html5ever::{LocalName, Prefix, namespace_url};
|
||||
use js::rust::HandleObject;
|
||||
|
||||
use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
|
||||
|
@ -11,6 +11,7 @@ use crate::dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTem
|
|||
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::root::{DomRoot, MutNullableDom};
|
||||
use crate::dom::bindings::str::DOMString;
|
||||
use crate::dom::document::Document;
|
||||
use crate::dom::documentfragment::DocumentFragment;
|
||||
use crate::dom::htmlelement::HTMLElement;
|
||||
|
@ -58,9 +59,44 @@ impl HTMLTemplateElement {
|
|||
n.upcast::<Node>().set_weird_parser_insertion_mode();
|
||||
n
|
||||
}
|
||||
|
||||
pub(crate) fn set_contents(&self, document_fragment: Option<&DocumentFragment>) {
|
||||
self.contents.set(document_fragment);
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unused_doc_comments)]
|
||||
impl HTMLTemplateElementMethods<crate::DomTypeHolder> for HTMLTemplateElement {
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-template-shadowrootmode>
|
||||
make_enumerated_getter!(
|
||||
ShadowRootMode,
|
||||
"shadowrootmode",
|
||||
"open" | "closed",
|
||||
missing => "",
|
||||
invalid => ""
|
||||
);
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-template-shadowrootmode>
|
||||
make_atomic_setter!(SetShadowRootMode, "shadowrootmode");
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-template-shadowrootdelegatesfocus>
|
||||
make_bool_getter!(ShadowRootDelegatesFocus, "shadowrootdelegatesfocus");
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-template-shadowrootdelegatesfocus>
|
||||
make_bool_setter!(SetShadowRootDelegatesFocus, "shadowrootdelegatesfocus");
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-template-shadowrootclonable>
|
||||
make_bool_getter!(ShadowRootClonable, "shadowrootclonable");
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-template-shadowrootclonable>
|
||||
make_bool_setter!(SetShadowRootClonable, "shadowrootclonable");
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-template-shadowrootserializable>
|
||||
make_bool_getter!(ShadowRootSerializable, "shadowrootserializable");
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-template-shadowrootserializable>
|
||||
make_bool_setter!(SetShadowRootSerializable, "shadowrootserializable");
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-template-content>
|
||||
fn Content(&self, can_gc: CanGc) -> DomRoot<DocumentFragment> {
|
||||
self.contents.or_init(|| {
|
||||
|
|
|
@ -2637,6 +2637,7 @@ impl Node {
|
|||
document.status_code(),
|
||||
Default::default(),
|
||||
false,
|
||||
document.allow_declarative_shadow_roots(),
|
||||
Some(document.insecure_requests_policy()),
|
||||
can_gc,
|
||||
);
|
||||
|
|
|
@ -44,6 +44,9 @@ use crate::dom::bindings::codegen::Bindings::DocumentBinding::{
|
|||
use crate::dom::bindings::codegen::Bindings::HTMLImageElementBinding::HTMLImageElementMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::HTMLTemplateElementBinding::HTMLTemplateElementMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::ShadowRootBinding::{
|
||||
ShadowRootMode, SlotAssignmentMode,
|
||||
};
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::refcounted::Trusted;
|
||||
use crate::dom::bindings::reflector::{DomGlobal, Reflector, reflect_dom_object};
|
||||
|
@ -53,6 +56,7 @@ use crate::dom::bindings::str::{DOMString, USVString};
|
|||
use crate::dom::characterdata::CharacterData;
|
||||
use crate::dom::comment::Comment;
|
||||
use crate::dom::document::{Document, DocumentSource, HasBrowsingContext, IsHTMLDocument};
|
||||
use crate::dom::documentfragment::DocumentFragment;
|
||||
use crate::dom::documenttype::DocumentType;
|
||||
use crate::dom::element::{CustomElementCreationMode, Element, ElementCreator};
|
||||
use crate::dom::htmlformelement::{FormControlElementHelpers, HTMLFormElement};
|
||||
|
@ -64,6 +68,7 @@ use crate::dom::node::{Node, ShadowIncluding};
|
|||
use crate::dom::performanceentry::PerformanceEntry;
|
||||
use crate::dom::performancenavigationtiming::PerformanceNavigationTiming;
|
||||
use crate::dom::processinginstruction::ProcessingInstruction;
|
||||
use crate::dom::shadowroot::IsUserAgentWidget;
|
||||
use crate::dom::text::Text;
|
||||
use crate::dom::virtualmethods::vtable_for;
|
||||
use crate::network_listener::PreInvoke;
|
||||
|
@ -191,6 +196,7 @@ impl ServoParser {
|
|||
pub(crate) fn parse_html_fragment(
|
||||
context: &Element,
|
||||
input: DOMString,
|
||||
allow_declarative_shadow_roots: bool,
|
||||
can_gc: CanGc,
|
||||
) -> impl Iterator<Item = DomRoot<Node>> + use<'_> {
|
||||
let context_node = context.upcast::<Node>();
|
||||
|
@ -218,6 +224,7 @@ impl ServoParser {
|
|||
None,
|
||||
Default::default(),
|
||||
false,
|
||||
allow_declarative_shadow_roots,
|
||||
Some(context_document.insecure_requests_policy()),
|
||||
can_gc,
|
||||
);
|
||||
|
@ -1184,18 +1191,23 @@ impl TreeSink for Sink {
|
|||
&self,
|
||||
name: QualName,
|
||||
attrs: Vec<Attribute>,
|
||||
_flags: ElementFlags,
|
||||
flags: ElementFlags,
|
||||
) -> Dom<Node> {
|
||||
let attrs = attrs
|
||||
.into_iter()
|
||||
.map(|attr| ElementAttribute::new(attr.name, DOMString::from(String::from(attr.value))))
|
||||
.collect();
|
||||
let parsing_algorithm = if flags.template {
|
||||
ParsingAlgorithm::Fragment
|
||||
} else {
|
||||
self.parsing_algorithm
|
||||
};
|
||||
let element = create_element_for_token(
|
||||
name,
|
||||
attrs,
|
||||
&self.document,
|
||||
ElementCreator::ParserCreated(self.current_line.get()),
|
||||
self.parsing_algorithm,
|
||||
parsing_algorithm,
|
||||
CanGc::note(),
|
||||
);
|
||||
Dom::from_ref(element.upcast())
|
||||
|
@ -1381,6 +1393,91 @@ impl TreeSink for Sink {
|
|||
let node = DomRoot::from_ref(&**node);
|
||||
vtable_for(&node).pop();
|
||||
}
|
||||
|
||||
fn allow_declarative_shadow_roots(&self, intended_parent: &Dom<Node>) -> bool {
|
||||
intended_parent.owner_doc().allow_declarative_shadow_roots()
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#parsing-main-inhead>
|
||||
/// A start tag whose tag name is "template"
|
||||
/// Attach shadow path
|
||||
fn attach_declarative_shadow(
|
||||
&self,
|
||||
host: &Dom<Node>,
|
||||
template: &Dom<Node>,
|
||||
attrs: Vec<Attribute>,
|
||||
) -> Result<(), String> {
|
||||
let host_element = host.downcast::<Element>().unwrap();
|
||||
|
||||
if host_element.shadow_root().is_some() {
|
||||
return Err(String::from("Already in a shadow host"));
|
||||
}
|
||||
|
||||
let template_element = template.downcast::<HTMLTemplateElement>().unwrap();
|
||||
|
||||
// Step 3. Let mode be template start tag's shadowrootmode attribute's value.
|
||||
// Step 4. Let clonable be true if template start tag has a shadowrootclonable attribute; otherwise false.
|
||||
// Step 5. Let delegatesfocus be true if template start tag
|
||||
// has a shadowrootdelegatesfocus attribute; otherwise false.
|
||||
// Step 6. Let serializable be true if template start tag
|
||||
// has a shadowrootserializable attribute; otherwise false.
|
||||
let mut shadow_root_mode = ShadowRootMode::Open;
|
||||
let mut clonable = false;
|
||||
let mut _delegatesfocus = false;
|
||||
let mut _serializable = false;
|
||||
|
||||
let attrs: Vec<ElementAttribute> = attrs
|
||||
.clone()
|
||||
.into_iter()
|
||||
.map(|attr| ElementAttribute::new(attr.name, DOMString::from(String::from(attr.value))))
|
||||
.collect();
|
||||
|
||||
attrs
|
||||
.iter()
|
||||
.for_each(|attr: &ElementAttribute| match attr.name.local {
|
||||
local_name!("shadowrootmode") => {
|
||||
if attr.value.str().eq_ignore_ascii_case("open") {
|
||||
shadow_root_mode = ShadowRootMode::Open;
|
||||
} else if attr.value.str().eq_ignore_ascii_case("closed") {
|
||||
shadow_root_mode = ShadowRootMode::Closed;
|
||||
} else {
|
||||
unreachable!("shadowrootmode value is not open nor closed");
|
||||
}
|
||||
},
|
||||
local_name!("shadowrootclonable") => {
|
||||
clonable = true;
|
||||
},
|
||||
local_name!("shadowrootdelegatesfocus") => {
|
||||
_delegatesfocus = true;
|
||||
},
|
||||
local_name!("shadowrootserializable") => {
|
||||
_serializable = true;
|
||||
},
|
||||
_ => {},
|
||||
});
|
||||
|
||||
// Step 8.1. Attach a shadow root with declarative shadow host element,
|
||||
// mode, clonable, serializable, delegatesFocus, and "named".
|
||||
match host_element.attach_shadow(
|
||||
IsUserAgentWidget::No,
|
||||
shadow_root_mode,
|
||||
clonable,
|
||||
SlotAssignmentMode::Manual,
|
||||
CanGc::note(),
|
||||
) {
|
||||
Ok(shadow_root) => {
|
||||
// Step 8.3. Set shadow's declarative to true.
|
||||
shadow_root.set_declarative(true);
|
||||
|
||||
// Set 8.4. Set template's template contents property to shadow.
|
||||
let shadow = shadow_root.upcast::<DocumentFragment>();
|
||||
template_element.set_contents(Some(shadow));
|
||||
|
||||
Ok(())
|
||||
},
|
||||
Err(_) => Err(String::from("Attaching shadow fails")),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#create-an-element-for-the-token>
|
||||
|
|
|
@ -79,6 +79,9 @@ pub(crate) struct ShadowRoot {
|
|||
slots: DomRefCell<HashMap<DOMString, Vec<Dom<HTMLSlotElement>>>>,
|
||||
|
||||
is_user_agent_widget: bool,
|
||||
|
||||
/// <https://dom.spec.whatwg.org/#shadowroot-declarative>
|
||||
declarative: Cell<bool>,
|
||||
}
|
||||
|
||||
impl ShadowRoot {
|
||||
|
@ -113,6 +116,7 @@ impl ShadowRoot {
|
|||
available_to_element_internals: Cell::new(false),
|
||||
slots: Default::default(),
|
||||
is_user_agent_widget: is_user_agent_widget == IsUserAgentWidget::Yes,
|
||||
declarative: Cell::new(false),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -276,6 +280,10 @@ impl ShadowRoot {
|
|||
pub(crate) fn is_user_agent_widget(&self) -> bool {
|
||||
self.is_user_agent_widget
|
||||
}
|
||||
|
||||
pub(crate) fn set_declarative(&self, declarative: bool) {
|
||||
self.declarative.set(declarative);
|
||||
}
|
||||
}
|
||||
|
||||
impl ShadowRootMethods<crate::DomTypeHolder> for ShadowRoot {
|
||||
|
|
|
@ -60,6 +60,7 @@ impl XMLDocument {
|
|||
None,
|
||||
Default::default(),
|
||||
false,
|
||||
false,
|
||||
inherited_insecure_requests_policy,
|
||||
),
|
||||
}
|
||||
|
|
|
@ -1508,6 +1508,7 @@ impl XMLHttpRequest {
|
|||
None,
|
||||
Default::default(),
|
||||
false,
|
||||
false,
|
||||
Some(doc.insecure_requests_policy()),
|
||||
can_gc,
|
||||
)
|
||||
|
|
|
@ -3193,6 +3193,7 @@ impl ScriptThread {
|
|||
Some(metadata.status.raw_code()),
|
||||
incomplete.canceller,
|
||||
is_initial_about_blank,
|
||||
true,
|
||||
incomplete.load_data.inherited_insecure_requests_policy,
|
||||
can_gc,
|
||||
);
|
||||
|
|
|
@ -186,7 +186,7 @@ DOMInterfaces = {
|
|||
},
|
||||
|
||||
'Element': {
|
||||
'canGc': ['SetInnerHTML', 'SetOuterHTML', 'InsertAdjacentHTML', 'GetClientRects', 'GetBoundingClientRect', 'InsertAdjacentText', 'ToggleAttribute', 'SetAttribute', 'SetAttributeNS', 'SetId','SetClassName','Prepend','Append','ReplaceChildren','Before','After','ReplaceWith', 'SetRole', 'SetAriaAtomic', 'SetAriaAutoComplete', 'SetAriaBrailleLabel', 'SetAriaBrailleRoleDescription', 'SetAriaBusy', 'SetAriaChecked', 'SetAriaColCount', 'SetAriaColIndex', 'SetAriaColIndexText', 'SetAriaColSpan', 'SetAriaCurrent', 'SetAriaDescription', 'SetAriaDisabled', 'SetAriaExpanded', 'SetAriaHasPopup', 'SetAriaHidden', 'SetAriaInvalid', 'SetAriaKeyShortcuts', 'SetAriaLabel', 'SetAriaLevel', 'SetAriaLive', 'SetAriaModal', 'SetAriaMultiLine', 'SetAriaMultiSelectable', 'SetAriaOrientation', 'SetAriaPlaceholder', 'SetAriaPosInSet', 'SetAriaPressed','SetAriaReadOnly', 'SetAriaRelevant', 'SetAriaRequired', 'SetAriaRoleDescription', 'SetAriaRowCount', 'SetAriaRowIndex', 'SetAriaRowIndexText', 'SetAriaRowSpan', 'SetAriaSelected', 'SetAriaSetSize','SetAriaSort', 'SetAriaValueMax', 'SetAriaValueMin', 'SetAriaValueNow', 'SetAriaValueText', 'SetScrollTop', 'SetScrollLeft', 'Scroll', 'Scroll_', 'ScrollBy', 'ScrollBy_', 'ScrollWidth', 'ScrollHeight', 'ScrollTop', 'ScrollLeft', 'ClientTop', 'ClientLeft', 'ClientWidth', 'ClientHeight', 'RequestFullscreen'],
|
||||
'canGc': ['SetHTMLUnsafe', 'SetInnerHTML', 'SetOuterHTML', 'InsertAdjacentHTML', 'GetClientRects', 'GetBoundingClientRect', 'InsertAdjacentText', 'ToggleAttribute', 'SetAttribute', 'SetAttributeNS', 'SetId','SetClassName','Prepend','Append','ReplaceChildren','Before','After','ReplaceWith', 'SetRole', 'SetAriaAtomic', 'SetAriaAutoComplete', 'SetAriaBrailleLabel', 'SetAriaBrailleRoleDescription', 'SetAriaBusy', 'SetAriaChecked', 'SetAriaColCount', 'SetAriaColIndex', 'SetAriaColIndexText', 'SetAriaColSpan', 'SetAriaCurrent', 'SetAriaDescription', 'SetAriaDisabled', 'SetAriaExpanded', 'SetAriaHasPopup', 'SetAriaHidden', 'SetAriaInvalid', 'SetAriaKeyShortcuts', 'SetAriaLabel', 'SetAriaLevel', 'SetAriaLive', 'SetAriaModal', 'SetAriaMultiLine', 'SetAriaMultiSelectable', 'SetAriaOrientation', 'SetAriaPlaceholder', 'SetAriaPosInSet', 'SetAriaPressed','SetAriaReadOnly', 'SetAriaRelevant', 'SetAriaRequired', 'SetAriaRoleDescription', 'SetAriaRowCount', 'SetAriaRowIndex', 'SetAriaRowIndexText', 'SetAriaRowSpan', 'SetAriaSelected', 'SetAriaSetSize','SetAriaSort', 'SetAriaValueMax', 'SetAriaValueMin', 'SetAriaValueNow', 'SetAriaValueText', 'SetScrollTop', 'SetScrollLeft', 'Scroll', 'Scroll_', 'ScrollBy', 'ScrollBy_', 'ScrollWidth', 'ScrollHeight', 'ScrollTop', 'ScrollLeft', 'ClientTop', 'ClientLeft', 'ClientWidth', 'ClientHeight', 'RequestFullscreen'],
|
||||
},
|
||||
|
||||
'ElementInternals': {
|
||||
|
|
|
@ -122,6 +122,8 @@ partial interface Element {
|
|||
|
||||
// https://w3c.github.io/DOM-Parsing/#extensions-to-the-element-interface
|
||||
partial interface Element {
|
||||
[CEReactions] undefined setHTMLUnsafe(DOMString html);
|
||||
|
||||
[CEReactions, Throws] attribute [LegacyNullToEmptyString] DOMString innerHTML;
|
||||
[CEReactions, Throws] attribute [LegacyNullToEmptyString] DOMString outerHTML;
|
||||
};
|
||||
|
|
|
@ -8,4 +8,8 @@ interface HTMLTemplateElement : HTMLElement {
|
|||
[HTMLConstructor] constructor();
|
||||
|
||||
readonly attribute DocumentFragment content;
|
||||
[CEReactions] attribute DOMString shadowRootMode;
|
||||
[CEReactions] attribute boolean shadowRootDelegatesFocus;
|
||||
[CEReactions] attribute boolean shadowRootClonable;
|
||||
[CEReactions] attribute boolean shadowRootSerializable;
|
||||
};
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
[function-shadow-container.html]
|
||||
[Can query named container in shadow]
|
||||
expected: FAIL
|
||||
|
||||
[::part() can not see inner named containers]
|
||||
expected: FAIL
|
||||
|
||||
[::slotted() can see inner named containers]
|
||||
expected: FAIL
|
|
@ -1,33 +0,0 @@
|
|||
[function-shadow.html]
|
||||
[@function works inside shadow]
|
||||
expected: FAIL
|
||||
|
||||
[Looking up document-global function]
|
||||
expected: FAIL
|
||||
|
||||
[@function works inside nested shadow]
|
||||
expected: FAIL
|
||||
|
||||
[@function defined in outer shadow is visible]
|
||||
expected: FAIL
|
||||
|
||||
[Combining functions from various scopes]
|
||||
expected: FAIL
|
||||
|
||||
[::part() can not see inner functions]
|
||||
expected: FAIL
|
||||
|
||||
[::slotted() can see inner functions]
|
||||
expected: FAIL
|
||||
|
||||
[:host can see inner functions]
|
||||
expected: FAIL
|
||||
|
||||
[Outer functions can't see inner functions]
|
||||
expected: FAIL
|
||||
|
||||
[Outer functions can't see inner functions (local vars)]
|
||||
expected: FAIL
|
||||
|
||||
[Function with same name in different scopes]
|
||||
expected: FAIL
|
|
@ -1,2 +1,78 @@
|
|||
[host-has-shadow-tree-element-at-nonsubject-position.html]
|
||||
expected: ERROR
|
||||
[Initial color]
|
||||
expected: FAIL
|
||||
|
||||
[Add .descendant to #shadow_child]
|
||||
expected: FAIL
|
||||
|
||||
[Remove .descendant from #shadow_child]
|
||||
expected: FAIL
|
||||
|
||||
[Add .descendant to #shadow_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[Add .ancestor to #shadow_child:has(.descendant)]
|
||||
expected: FAIL
|
||||
|
||||
[Remove .ancestor from #shadow_child:has(.descendant)]
|
||||
expected: FAIL
|
||||
|
||||
[Add .child to #shadow_child:has(.descendant)]
|
||||
expected: FAIL
|
||||
|
||||
[Remove .child from #shadow_child:has(.descendant)]
|
||||
expected: FAIL
|
||||
|
||||
[Remove .descendant from #shadow_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[Add .child to #shadow_child]
|
||||
expected: FAIL
|
||||
|
||||
[Add .grand_child to #shadow_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[Add .host_context to #host]
|
||||
expected: FAIL
|
||||
|
||||
[Add .descendant to #shadow_descendant.grand_child]
|
||||
expected: FAIL
|
||||
|
||||
[Remove .descendant from #shadow_descendant.grand_child]
|
||||
expected: FAIL
|
||||
|
||||
[Remove .grand_child from #shadow_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[Remove .child from #shadow_child]
|
||||
expected: FAIL
|
||||
|
||||
[Add .child to #shadow_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[Remove .child from #shadow_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[Insert #first_child.descendant to shadow root]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #first_child.descendant from shadow root]
|
||||
expected: FAIL
|
||||
|
||||
[Insert #last_child.descendant to shadow root]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #last_child.descendant from shadow root]
|
||||
expected: FAIL
|
||||
|
||||
[Insert #child_in_middle.descendant before #shadow_child]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #child_in_middle.descendant from shadow root]
|
||||
expected: FAIL
|
||||
|
||||
[Insert #grand_child.descendant before #shadow_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[Remove #grand_child.descendant from shadow tree]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,2 +1,48 @@
|
|||
[host-has-shadow-tree-element-at-subject-position.html]
|
||||
expected: ERROR
|
||||
[Add .descendant to #shadow_child]
|
||||
expected: FAIL
|
||||
|
||||
[Add .descendant to #shadow_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[Add .ancestor to #shadow_child:has(.descendant)]
|
||||
expected: FAIL
|
||||
|
||||
[Remove .ancestor from #shadow_child:has(.descendant)]
|
||||
expected: FAIL
|
||||
|
||||
[Add .child to #shadow_child:has(.descendant)]
|
||||
expected: FAIL
|
||||
|
||||
[Remove .child from #shadow_child:has(.descendant)]
|
||||
expected: FAIL
|
||||
|
||||
[Add .child to #shadow_child]
|
||||
expected: FAIL
|
||||
|
||||
[Add .grand_child to #shadow_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[Add .host_context to #host]
|
||||
expected: FAIL
|
||||
|
||||
[Add .descendant to #shadow_descendant.grand_child]
|
||||
expected: FAIL
|
||||
|
||||
[Remove .descendant from #shadow_descendant.grand_child]
|
||||
expected: FAIL
|
||||
|
||||
[Remove .grand_child from #shadow_descendant]
|
||||
expected: FAIL
|
||||
|
||||
[Insert #first_child.descendant to shadow root]
|
||||
expected: FAIL
|
||||
|
||||
[Insert #last_child.descendant to shadow root]
|
||||
expected: FAIL
|
||||
|
||||
[Insert #child_in_middle.descendant before #shadow_child]
|
||||
expected: FAIL
|
||||
|
||||
[Insert #grand_child.descendant before #shadow_descendant]
|
||||
expected: FAIL
|
||||
|
|
|
@ -4,6 +4,3 @@
|
|||
|
||||
[customElements on a failed custom element created by setting innerHTML should return the associated scoped registry]
|
||||
expected: FAIL
|
||||
|
||||
[customElements on a failed custom element created by parser should return the specified custom regsitry]
|
||||
expected: FAIL
|
||||
|
|
|
@ -4613,12 +4613,6 @@
|
|||
[DOMStringList interface: calling contains(DOMString) on location.ancestorOrigins with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: document.createElement("noscript") must inherit property "setHTMLUnsafe((TrustedHTML or DOMString))" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: calling setHTMLUnsafe((TrustedHTML or DOMString)) on document.createElement("noscript") with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: document.createElement("noscript") must inherit property "getHTML(optional GetHTMLOptions)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -5927,9 +5921,6 @@
|
|||
[ShadowRoot interface: operation getHTML(optional GetHTMLOptions)]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: operation setHTMLUnsafe((TrustedHTML or DOMString))]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: operation getHTML(optional GetHTMLOptions)]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -5975,12 +5966,6 @@
|
|||
[OffscreenCanvasRenderingContext2D interface: attribute lang]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: document.createElement("div") must inherit property "setHTMLUnsafe((TrustedHTML or DOMString))" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: calling setHTMLUnsafe((TrustedHTML or DOMString)) on document.createElement("div") with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[Element interface: document.createElement("div") must inherit property "getHTML(optional GetHTMLOptions)" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
|
@ -7810,30 +7795,6 @@
|
|||
[HTMLScriptElement interface: calling supports(DOMString) on document.createElement("script") with too few arguments must throw TypeError]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLTemplateElement interface: attribute shadowRootMode]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLTemplateElement interface: attribute shadowRootDelegatesFocus]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLTemplateElement interface: attribute shadowRootClonable]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLTemplateElement interface: attribute shadowRootSerializable]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLTemplateElement interface: document.createElement("template") must inherit property "shadowRootMode" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLTemplateElement interface: document.createElement("template") must inherit property "shadowRootDelegatesFocus" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLTemplateElement interface: document.createElement("template") must inherit property "shadowRootClonable" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLTemplateElement interface: document.createElement("template") must inherit property "shadowRootSerializable" with the proper type]
|
||||
expected: FAIL
|
||||
|
||||
[HTMLMarqueeElement interface: existence and properties of interface object]
|
||||
expected: FAIL
|
||||
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
[form-indexed-element-shadow.html]
|
||||
[form.elements: indexed access reflects DOM order, not flat tree]
|
||||
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[template-shadowrootmode-img-src.tentative.html]
|
||||
[Speculative parsing, page load: template-shadowrootmode-img-src]
|
||||
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[template-shadowrootmode-link-stylesheet.tentative.html]
|
||||
[Speculative parsing, page load: template-shadowrootmode-link-stylesheet]
|
||||
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[template-shadowrootmode-script-src.tentative.html]
|
||||
[Speculative parsing, page load: template-shadowrootmode-script-src]
|
||||
expected: FAIL
|
|
@ -1,3 +0,0 @@
|
|||
[Element-setHTMLUnsafe-04.html]
|
||||
[setHTMLUnsafe should leave the removed children alone.]
|
||||
expected: FAIL
|
|
@ -1,6 +1,3 @@
|
|||
[setHTMLUnsafe-CEReactions.html]
|
||||
[Element.setHTMLUnsafe should trigger custom element reactions.]
|
||||
expected: FAIL
|
||||
|
||||
[ShadowRoot.setHTMLUnsafe should trigger custom element reactions.]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
[setHTMLUnsafe-xml.html]
|
||||
[setHTMLUnsafe should still parse HTML even in XML documents.]
|
||||
expected: FAIL
|
||||
|
||||
[setHTMLUnsafe should still parse HTML even in SVG documents.]
|
||||
expected: FAIL
|
|
@ -1,15 +1,6 @@
|
|||
[setHTMLUnsafe.html]
|
||||
[Element: setHTMLUnsafe with no shadowdom.]
|
||||
expected: FAIL
|
||||
|
||||
[Element: setHTMLUnsafe with shadowdom.]
|
||||
expected: FAIL
|
||||
|
||||
[ShadowRoot: setHTMLUnsafe with no shadowdom.]
|
||||
expected: FAIL
|
||||
|
||||
[ShadowRoot: setHTMLUnsafe with shadowdom.]
|
||||
expected: FAIL
|
||||
|
||||
[template.setHTMLUnsafe() should modify template content fragment rather than actual children.]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
[cross-shadow-boundary-6.html]
|
||||
expected: TIMEOUT
|
|
@ -1,6 +1,3 @@
|
|||
[Range-isPointInRange.html]
|
||||
[isPointInRange() test for collapsed selection]
|
||||
expected: FAIL
|
||||
|
||||
[isPointInRange() test for non-collapsed selection]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,2 +1,9 @@
|
|||
[Selection-getComposedRanges-range-update.html]
|
||||
expected: ERROR
|
||||
[modify getRangeAt() range.]
|
||||
expected: FAIL
|
||||
|
||||
[modify createRange() range added to selection after setEnd call.]
|
||||
expected: FAIL
|
||||
|
||||
[modify createRange() range added to selection before setStart/setEnd calls.]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,2 +1,12 @@
|
|||
[Selection-isCollapsed.html]
|
||||
expected: ERROR
|
||||
[Selection in light tree is not collapsed]
|
||||
expected: FAIL
|
||||
|
||||
[Selection in shadow tree is not collapsed]
|
||||
expected: FAIL
|
||||
|
||||
[Selection between light and shadow tree is not valid and is collapsed. Composed range is not collapsed]
|
||||
expected: FAIL
|
||||
|
||||
[Selection between two shadow trees is not valid and is collapsed. Composed range is not collapsed]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
[HighlightRegistry-highlightsFromPoint.html]
|
||||
[CSS.highlights.highlightsFromPoint() should throw when called with nodes that are not ShadowRoot objects in options.]
|
||||
expected: FAIL
|
||||
|
||||
[CSS.highlights.highlightsFromPoint() returns Highlights present at a given point inside a shadow tree in the right order.]
|
||||
expected: FAIL
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,59 +2,8 @@
|
|||
[Declarative Shadow DOM: Basic test]
|
||||
expected: FAIL
|
||||
|
||||
[Declarative Shadow DOM: Feature detection]
|
||||
expected: FAIL
|
||||
|
||||
[Shadowrootmode reflection]
|
||||
expected: FAIL
|
||||
|
||||
[Shadowrootmode reflection, setter]
|
||||
expected: FAIL
|
||||
|
||||
[Shadowrootdelegatesfocus reflection]
|
||||
expected: FAIL
|
||||
|
||||
[Shadowrootdelegatesfocus reflection, setter]
|
||||
expected: FAIL
|
||||
|
||||
[Shadowrootclonable reflection]
|
||||
expected: FAIL
|
||||
|
||||
[Shadowrootclonable reflection, setter]
|
||||
expected: FAIL
|
||||
|
||||
[Declarative Shadow DOM: Fragment parser basic test]
|
||||
expected: FAIL
|
||||
|
||||
[Declarative Shadow DOM: Invalid shadow root attribute]
|
||||
expected: FAIL
|
||||
|
||||
[Declarative Shadow DOM: Closed shadow root attribute]
|
||||
expected: FAIL
|
||||
|
||||
[Declarative Shadow DOM: Missing closing tag]
|
||||
expected: FAIL
|
||||
|
||||
[Declarative Shadow DOM: delegates focus attribute]
|
||||
expected: FAIL
|
||||
|
||||
[Declarative Shadow DOM: clonable attribute]
|
||||
expected: FAIL
|
||||
|
||||
[Declarative Shadow DOM: Multiple roots]
|
||||
expected: FAIL
|
||||
|
||||
[Declarative Shadow DOM: template containing declarative shadow root (with shadowrootclonable)]
|
||||
expected: FAIL
|
||||
|
||||
[Declarative Shadow DOM: template containing (deeply nested) declarative shadow root]
|
||||
expected: FAIL
|
||||
|
||||
[Declarative Shadow DOM: template containing a template containing declarative shadow root]
|
||||
expected: FAIL
|
||||
|
||||
[Declarative Shadow DOM: template containing declarative shadow root and UA shadow root]
|
||||
expected: FAIL
|
||||
|
||||
[Declarative Shadow DOM: explicit test that exceptions are not thrown]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,25 +1,10 @@
|
|||
[declarative-shadow-dom-opt-in.html]
|
||||
expected: TIMEOUT
|
||||
[Non-fragment parsing needs no opt-in]
|
||||
expected: FAIL
|
||||
|
||||
[innerHTML on shadowRoot]
|
||||
expected: PASS
|
||||
|
||||
[document.write allowed from synchronous script loaded from main document]
|
||||
expected: FAIL
|
||||
|
||||
[document.write disallowed on fresh document]
|
||||
expected: FAIL
|
||||
|
||||
[iframe]
|
||||
expected: FAIL
|
||||
|
||||
[iframe, no sandbox]
|
||||
expected: FAIL
|
||||
|
||||
[sandboxed iframe allows declarative Shadow DOM]
|
||||
expected: TIMEOUT
|
||||
|
||||
[iframe with no sandbox allows declarative Shadow DOM]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,3 +0,0 @@
|
|||
[declarative-shadow-dom-repeats-2.html]
|
||||
[Repeated declarative shadow roots keep only the first]
|
||||
expected: FAIL
|
|
@ -1,7 +1,4 @@
|
|||
[declarative-shadow-dom-repeats.html]
|
||||
[Repeated declarative shadow roots keep only the first]
|
||||
expected: FAIL
|
||||
|
||||
[Calling attachShadow() on declarative shadow root must match mode]
|
||||
expected: FAIL
|
||||
|
||||
|
|
3
tests/wpt/meta/shadow-dom/declarative/declarative-with-disabled-shadow.html.ini
vendored
Normal file
3
tests/wpt/meta/shadow-dom/declarative/declarative-with-disabled-shadow.html.ini
vendored
Normal file
|
@ -0,0 +1,3 @@
|
|||
[declarative-with-disabled-shadow.html]
|
||||
[Declarative Shadow DOM: declarative shadow should fail if attachShadow() already called]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[innerhtml-before-closing-tag.html]
|
||||
expected: ERROR
|
|
@ -1,6 +0,0 @@
|
|||
[move-template-before-closing-tag.html]
|
||||
[Moving the template node during parsing should attach to initial parent (content before observer)]
|
||||
expected: FAIL
|
||||
|
||||
[Moving the template node during parsing should attach to initial parent (content after observer)]
|
||||
expected: FAIL
|
|
@ -1,2 +0,0 @@
|
|||
[script-access.html]
|
||||
expected: ERROR
|
|
@ -4,3 +4,6 @@
|
|||
|
||||
[Verifies that HTMLElement.offsetTop accounts for shadow boundaries when nested in multiple shadow roots.]
|
||||
expected: FAIL
|
||||
|
||||
[Verifies that HTMLElement.offsetLeft accounts for shadow boundaries.]
|
||||
expected: FAIL
|
||||
|
|
|
@ -1,9 +0,0 @@
|
|||
[shadow-root-clonable.html]
|
||||
[declarative shadow roots do *not* get clonable: true automatically]
|
||||
expected: FAIL
|
||||
|
||||
[declarative shadow roots can opt in to clonable with shadowrootclonable]
|
||||
expected: FAIL
|
||||
|
||||
[declarative shadow roots inside templates do *not* get cloned automatically]
|
||||
expected: FAIL
|
Loading…
Add table
Add a link
Reference in a new issue