aboutsummaryrefslogtreecommitdiffstats
path: root/components/script/layout_wrapper.rs
diff options
context:
space:
mode:
authorbors-servo <lbergstrom+bors@mozilla.com>2017-06-07 19:00:54 -0700
committerGitHub <noreply@github.com>2017-06-07 19:00:54 -0700
commitad47d33511c318fe208158bb16deb5086979e0c7 (patch)
treed2057957e2bb00cbfc236b0a4fa5dbbfe664f230 /components/script/layout_wrapper.rs
parent1ea4a44fad4dfd6d7ca1152e06cf07b7e927951b (diff)
parent18d847227c82ca552099e53606aa846cc873df5d (diff)
downloadservo-ad47d33511c318fe208158bb16deb5086979e0c7.tar.gz
servo-ad47d33511c318fe208158bb16deb5086979e0c7.zip
Auto merge of #17206 - heycam:lang-snapshots, r=emilio
match :lang() against snapshots correctly Reviewed in https://bugzilla.mozilla.org/show_bug.cgi?id=1365162. <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/17206) <!-- Reviewable:end -->
Diffstat (limited to 'components/script/layout_wrapper.rs')
-rw-r--r--components/script/layout_wrapper.rs41
1 files changed, 36 insertions, 5 deletions
diff --git a/components/script/layout_wrapper.rs b/components/script/layout_wrapper.rs
index e915a2d07b1..f7f5396dc8d 100644
--- a/components/script/layout_wrapper.rs
+++ b/components/script/layout_wrapper.rs
@@ -34,7 +34,6 @@ use atomic_refcell::{AtomicRef, AtomicRefCell};
use dom::bindings::inheritance::{CharacterDataTypeId, ElementTypeId};
use dom::bindings::inheritance::{HTMLElementTypeId, NodeTypeId};
use dom::bindings::js::LayoutJS;
-use dom::bindings::str::extended_filtering;
use dom::characterdata::LayoutCharacterDataHelpers;
use dom::document::{Document, LayoutDocumentHelpers, PendingRestyle};
use dom::element::{Element, LayoutElementHelpers, RawLayoutElementHelpers};
@@ -70,7 +69,8 @@ use style::dom::{PresentationalHintsSynthesizer, TElement, TNode, UnsafeNode};
use style::element_state::*;
use style::font_metrics::ServoMetricsProvider;
use style::properties::{ComputedValues, PropertyDeclarationBlock};
-use style::selector_parser::{NonTSPseudoClass, PseudoElement, SelectorImpl};
+use style::selector_parser::{AttrValue as SelectorAttrValue, NonTSPseudoClass, PseudoClassStringArg};
+use style::selector_parser::{PseudoElement, SelectorImpl, extended_filtering};
use style::shared_lock::{SharedRwLock as StyleSharedRwLock, Locked as StyleLocked};
use style::sink::Push;
use style::str::is_whitespace;
@@ -499,6 +499,39 @@ impl<'le> TElement for ServoLayoutElement<'le> {
fn has_css_transitions(&self) -> bool {
unreachable!("this should be only called on gecko");
}
+
+ #[inline]
+ fn lang_attr(&self) -> Option<SelectorAttrValue> {
+ self.get_attr(&ns!(xml), &local_name!("lang"))
+ .or_else(|| self.get_attr(&ns!(), &local_name!("lang")))
+ .map(|v| String::from(v as &str))
+ }
+
+ fn match_element_lang(&self,
+ override_lang: Option<Option<SelectorAttrValue>>,
+ value: &PseudoClassStringArg)
+ -> bool
+ {
+ // Servo supports :lang() from CSS Selectors 4, which can take a comma-
+ // separated list of language tags in the pseudo-class, and which
+ // performs RFC 4647 extended filtering matching on them.
+ //
+ // FIXME(heycam): This is wrong, since extended_filtering accepts
+ // a string containing commas (separating each language tag in
+ // a list) but the pseudo-class instead should be parsing and
+ // storing separate <ident> or <string>s for each language tag.
+ //
+ // FIXME(heycam): Look at `element`'s document's Content-Language
+ // HTTP header for language tags to match `value` against. To
+ // do this, we should make `get_lang_for_layout` return an Option,
+ // so we can decide when to fall back to the Content-Language check.
+ let element_lang = match override_lang {
+ Some(Some(lang)) => lang,
+ Some(None) => String::new(),
+ None => self.element.get_lang_for_layout(),
+ };
+ extended_filtering(&element_lang, &*value)
+ }
}
impl<'le> PartialEq for ServoLayoutElement<'le> {
@@ -691,9 +724,7 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
NonTSPseudoClass::AnyLink => self.is_link(),
NonTSPseudoClass::Visited => false,
- // 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) => extended_filtering(&*self.element.get_lang_for_layout(), &*lang),
+ NonTSPseudoClass::Lang(ref lang) => self.match_element_lang(None, &*lang),
NonTSPseudoClass::ServoNonZeroBorder => unsafe {
match (*self.element.unsafe_get()).get_attr_for_layout(&ns!(), &local_name!("border")) {