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
Support lang pseudo class #15464
Support lang pseudo class #15464
Changes from all commits
File filter...
Jump to…
| @@ -354,6 +354,7 @@ pub trait LayoutElementHelpers { | ||
| fn style_attribute(&self) -> *const Option<Arc<RwLock<PropertyDeclarationBlock>>>; | ||
| fn local_name(&self) -> &LocalName; | ||
| fn namespace(&self) -> &Namespace; | ||
| fn get_lang_for_layout(&self) -> String; | ||
| fn get_checked_state_for_layout(&self) -> bool; | ||
| fn get_indeterminate_state_for_layout(&self) -> bool; | ||
| fn get_state_for_layout(&self) -> ElementState; | ||
| @@ -693,6 +694,30 @@ impl LayoutElementHelpers for LayoutJS<Element> { | ||
| } | ||
| } | ||
|
|
||
| #[allow(unsafe_code)] | ||
| fn get_lang_for_layout(&self) -> String { | ||
| unsafe { | ||
| let mut current_node = Some(self.upcast::<Node>()); | ||
KiChjang
Author
Member
|
||
| while let Some(node) = current_node { | ||
| current_node = node.parent_node_ref(); | ||
| match node.downcast::<Element>().map(|el| el.unsafe_get()) { | ||
| Some(elem) => { | ||
| if let Some(attr) = (*elem).get_attr_val_for_layout(&ns!(xml), &local_name!("lang")) { | ||
| return attr.to_owned(); | ||
| } | ||
| if let Some(attr) = (*elem).get_attr_val_for_layout(&ns!(), &local_name!("lang")) { | ||
| return attr.to_owned(); | ||
| } | ||
| } | ||
| None => continue | ||
| } | ||
| } | ||
| // TODO: Check meta tags for a pragma-set default language | ||
| // TODO: Check HTTP Content-Language header | ||
| String::new() | ||
| } | ||
| } | ||
|
|
||
| #[inline] | ||
| #[allow(unsafe_code)] | ||
| fn get_checked_state_for_layout(&self) -> bool { | ||
| @@ -2372,6 +2397,10 @@ impl<'a> ::selectors::Element for Root<Element> { | ||
| } | ||
| }, | ||
|
|
||
| // FIXME(#15746): This is wrong, we need to instead use extended filtering as per RFC4647 | ||
| // https://tools.ietf.org/html/rfc4647#section-3.3.2 | ||
| NonTSPseudoClass::Lang(ref lang) => lang.eq_ignore_ascii_case(&self.get_lang()), | ||
|
|
||
| NonTSPseudoClass::ReadOnly => | ||
| !Element::state(self).contains(pseudo_class.state_flag()), | ||
|
|
||
| @@ -2576,6 +2605,19 @@ impl Element { | ||
| self.set_click_in_progress(false); | ||
| } | ||
|
|
||
| // https://html.spec.whatwg.org/multipage/#language | ||
| pub fn get_lang(&self) -> String { | ||
| self.upcast::<Node>().inclusive_ancestors().filter_map(|node| { | ||
| node.downcast::<Element>().and_then(|el| { | ||
| el.get_attribute(&ns!(xml), &local_name!("lang")).or_else(|| { | ||
| el.get_attribute(&ns!(), &local_name!("lang")) | ||
| }).map(|attr| String::from(attr.Value())) | ||
| }) | ||
| // TODO: Check meta tags for a pragma-set default language | ||
| // TODO: Check HTTP Content-Language header | ||
| }).next().unwrap_or(String::new()) | ||
| } | ||
|
|
||
| pub fn state(&self) -> ElementState { | ||
| self.state.get() | ||
| } | ||
| @@ -0,0 +1,5 @@ | ||
| [css3-selectors-lang-005.htm] | ||
| type: testharness | ||
| [A :lang value will match a lang attribute value when the latter contains additional subtags.] | ||
| expected: FAIL | ||
|
|
| @@ -0,0 +1,5 @@ | ||
| [css3-selectors-lang-009.htm] | ||
| type: testharness | ||
| [A :lang value with a multiple subtags will match a lang attribute value with multiple subtags as long as the first part is the same.] | ||
emilio
Member
|
||
| expected: FAIL | ||
|
|
||
| @@ -0,0 +1,5 @@ | ||
| [css3-selectors-lang-024.htm] | ||
| type: testharness | ||
| [A lang|= value will match a lang attribute value regardless of case differences.] | ||
| expected: FAIL | ||
|
|
| @@ -0,0 +1,5 @@ | ||
| [css3-selectors-lang-035.htm] | ||
| type: testharness | ||
| [A lang|= value will match a lang attribute value regardless of case differences in the script tag.] | ||
| expected: FAIL | ||
|
|
| @@ -0,0 +1,5 @@ | ||
| [css3-selectors-lang-044.htm] | ||
| type: testharness | ||
| [A lang= value will match a lang attribute value regardless of case differences.] | ||
| expected: FAIL | ||
|
|
| @@ -0,0 +1,5 @@ | ||
| [css3-selectors-lang-055.htm] | ||
| type: testharness | ||
| [A lang= value will match a lang attribute value regardless of case differences in the script tag.] | ||
| expected: FAIL | ||
|
|
| @@ -0,0 +1,3 @@ | ||
| [grid-first-letter-001.htm] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-first-letter-002.htm] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-first-letter-003.htm] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -1,3 +1,3 @@ | ||
| [case-sensitive-004.htm] | ||
| [grid-first-line-001.htm] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -1,3 +1,3 @@ | ||
| [lang-selector-003.htm] | ||
| [grid-first-line-002.htm] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-first-line-003.htm] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-inline-first-letter-001.htm] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-inline-first-letter-002.htm] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-inline-first-letter-003.htm] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-inline-first-line-001.htm] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-inline-first-line-002.htm] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-inline-first-line-003.htm] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,5 @@ | ||
| [css3-selectors-lang-005.xht] | ||
| type: testharness | ||
| [A :lang value will match a lang attribute value when the latter contains additional subtags.] | ||
| expected: FAIL | ||
|
|
| @@ -0,0 +1,5 @@ | ||
| [css3-selectors-lang-009.xht] | ||
| type: testharness | ||
| [A :lang value with a multiple subtags will match a lang attribute value with multiple subtags as long as the first part is the same.] | ||
| expected: FAIL | ||
|
|
| @@ -0,0 +1,3 @@ | ||
| [grid-first-letter-001.xht] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-first-letter-002.xht] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-first-letter-003.xht] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-first-line-001.xht] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-first-line-002.xht] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-first-line-003.xht] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-inline-first-letter-001.xht] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-inline-first-letter-002.xht] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-inline-first-letter-003.xht] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-inline-first-line-001.xht] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-inline-first-line-002.xht] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-inline-first-line-003.xht] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,5 @@ | ||
| [css3-selectors-lang-005.xht] | ||
| type: testharness | ||
| [A :lang value will match a lang attribute value when the latter contains additional subtags.] | ||
| expected: FAIL | ||
|
|
| @@ -0,0 +1,5 @@ | ||
| [css3-selectors-lang-009.xht] | ||
| type: testharness | ||
| [A :lang value with a multiple subtags will match a lang attribute value with multiple subtags as long as the first part is the same.] | ||
| expected: FAIL | ||
|
|
| @@ -0,0 +1,3 @@ | ||
| [grid-first-letter-001.xht] | ||
| type: reftest | ||
| expected: FAIL |
| @@ -0,0 +1,3 @@ | ||
| [grid-first-letter-002.xht] | ||
| type: reftest | ||
| expected: FAIL |
I suggested this should be using
Elementitself, and doesn't seem addressed. If there's any particular reason it can't be done, or you think it's not worth it, please comment about it, otherwise, please do :)