Merge autoland to mozilla-central. a=merge

This commit is contained in:
Coroiu Cristina 2018-02-12 19:56:50 +02:00
commit e6c323f55d
24 changed files with 323 additions and 183 deletions

View File

@ -7994,8 +7994,10 @@ var gIdentityHandler = {
for (let state of SitePermissions.getAvailableStates(aPermission.id)) {
let menuitem = document.createElement("menuitem");
// We need to correctly display the default/unknown state, which has its
// own integer value (0) but represents one of the other states.
if (state == SitePermissions.getDefault(aPermission.id)) {
menuitem.setAttribute("value", 0);
menuitem.setAttribute("value", "0");
} else {
menuitem.setAttribute("value", state);
}
@ -8004,7 +8006,12 @@ var gIdentityHandler = {
}
menulist.appendChild(menupopup);
menulist.setAttribute("value", aPermission.state);
if (aPermission.state == SitePermissions.getDefault(aPermission.id)) {
menulist.value = "0";
} else {
menulist.value = aPermission.state;
}
// Avoiding listening to the "select" event on purpose. See Bug 1404262.
menulist.addEventListener("command", () => {

View File

@ -165,3 +165,30 @@ add_task(async function check_permission_state_change() {
gBrowser.removeTab(tab);
});
// Explicitly set the permission to the otherwise default state and check that
// the label still displays correctly.
add_task(async function check_explicit_default_permission() {
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, URL);
// DENY only works if triggered through Services.perms (it's very edge-casey),
// since SitePermissions.jsm considers setting default permissions to be removal.
Services.perms.add(URI, "popup", Ci.nsIPermissionManager.DENY_ACTION);
await openIdentityPopup();
let menulist = document.getElementById("identity-popup-popup-menulist");
Assert.equal(menulist.value, "0");
Assert.equal(menulist.label, "Block");
await closeIdentityPopup();
SitePermissions.set(URI, "popup", SitePermissions.ALLOW);
await openIdentityPopup();
menulist = document.getElementById("identity-popup-popup-menulist");
Assert.equal(menulist.value, "1");
Assert.equal(menulist.label, "Allow");
await closeIdentityPopup();
SitePermissions.remove(URI, "popup");
gBrowser.removeTab(tab);
});

View File

@ -902,7 +902,6 @@ if (Services.prefs.getBoolPref("privacy.panicButton.enabled")) {
let doc = aEvent.target.ownerDocument;
let group = doc.getElementById("PanelUI-panic-timeSpan");
BrowserUITelemetry.countPanicEvent(group.selectedItem.id);
group.selectedItem = doc.getElementById("PanelUI-panic-5min");
let itemsToClear = [
"cookies", "history", "openWindows", "formdata", "sessions", "cache", "downloads"
];
@ -934,6 +933,9 @@ if (Services.prefs.getBoolPref("privacy.panicButton.enabled")) {
},
onViewShowing(aEvent) {
let forgetButton = aEvent.target.querySelector("#PanelUI-panic-view-button");
let doc = aEvent.target.ownerDocument;
let group = doc.getElementById("PanelUI-panic-timeSpan");
group.selectedItem = doc.getElementById("PanelUI-panic-5min");
forgetButton.addEventListener("command", this);
},
onViewHiding(aEvent) {

View File

@ -10,6 +10,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "nsIDocument.h"
#include "MediaManager.h"
namespace mozilla {
namespace dom {
@ -27,6 +28,16 @@ AutoplayPolicy::IsMediaElementAllowedToPlay(NotNull<HTMLMediaElement*> aElement)
return true;
}
// Pages which have been granted permission to capture WebRTC camera or
// microphone are assumed to be trusted, and are allowed to autoplay.
MediaManager* manager = MediaManager::GetIfExists();
if (manager) {
nsCOMPtr<nsPIDOMWindowInner> window = aElement->OwnerDoc()->GetInnerWindow();
if (window && manager->IsActivelyCapturingOrHasAPermission(window->WindowID())) {
return true;
}
}
// TODO : this old way would be removed when user-gestures-needed becomes
// as a default option to block autoplay.
if (!Preferences::GetBool("media.autoplay.enabled.user-gestures-needed", false)) {

View File

@ -735,14 +735,11 @@ nsPresContext::AppUnitsPerDevPixelChanged()
mDeviceContext->FlushFontCache();
}
if (HasCachedStyleData()) {
// All cached style data must be recomputed.
MediaFeatureValuesChanged({
eRestyle_ForceDescendants,
NS_STYLE_HINT_REFLOW,
MediaFeatureChangeReason::ResolutionChange
});
}
MediaFeatureValuesChanged({
eRestyle_ForceDescendants,
NS_STYLE_HINT_REFLOW,
MediaFeatureChangeReason::ResolutionChange
});
mCurAppUnitsPerDevPixel = AppUnitsPerDevPixel();
}
@ -1406,18 +1403,13 @@ nsPresContext::UpdateEffectiveTextZoom()
mEffectiveTextZoom = newZoom;
// In case of servo, stylist.device might have already generated the default
// computed values with the previous effective text zoom value even if the
// pres shell has not initialized yet.
if (mDocument->IsStyledByServo() || HasCachedStyleData()) {
// Media queries could have changed, since we changed the meaning
// of 'em' units in them.
MediaFeatureValuesChanged({
eRestyle_ForceDescendants,
NS_STYLE_HINT_REFLOW,
MediaFeatureChangeReason::ZoomChange
});
}
// Media queries could have changed, since we changed the meaning
// of 'em' units in them.
MediaFeatureValuesChanged({
eRestyle_ForceDescendants,
NS_STYLE_HINT_REFLOW,
MediaFeatureChangeReason::ZoomChange
});
}
float
@ -1460,13 +1452,12 @@ nsPresContext::SetOverrideDPPX(float aDPPX)
// SetOverrideDPPX is called during navigations, including history
// traversals. In that case, it's typically called with our current value,
// and we don't need to actually do anything.
if (aDPPX != mOverrideDPPX) {
mOverrideDPPX = aDPPX;
if (HasCachedStyleData()) {
MediaFeatureValuesChanged({ MediaFeatureChangeReason::ResolutionChange });
}
if (aDPPX == mOverrideDPPX) {
return;
}
mOverrideDPPX = aDPPX;
MediaFeatureValuesChanged({ MediaFeatureChangeReason::ResolutionChange });
}
gfxSize
@ -2210,10 +2201,6 @@ NotifyTabSizeModeChanged(TabParent* aTab, void* aArg)
void
nsPresContext::SizeModeChanged(nsSizeMode aSizeMode)
{
if (!HasCachedStyleData()) {
return;
}
nsContentUtils::CallOnAllRemoteChildren(mDocument->GetWindow(),
NotifyTabSizeModeChanged,
&aSizeMode);
@ -2786,27 +2773,6 @@ nsPresContext::NotifyDidPaintForSubtree(uint64_t aTransactionId,
mDocument->EnumerateSubDocuments(nsPresContext::NotifyDidPaintSubdocumentCallback, &closure);
}
bool
nsPresContext::HasCachedStyleData()
{
if (!mShell) {
return false;
}
if (mShell->StyleSet()->IsGecko()) {
#ifdef MOZ_OLD_STYLE
return mShell->StyleSet()->AsGecko()->HasCachedStyleData();
#else
MOZ_CRASH("old style system disabled");
#endif
}
// XXXheycam ServoStyleSets do not use the rule tree, so just assume for now
// that we need to restyle when e.g. dppx changes assuming we're sufficiently
// bootstrapped.
return mShell->DidInitialize();
}
already_AddRefed<nsITimer>
nsPresContext::CreateTimer(nsTimerCallbackFunc aCallback,
const char* aName,

View File

@ -472,7 +472,7 @@ public:
if (!r.IsEqualEdges(mVisibleArea)) {
mVisibleArea = r;
// Visible area does not affect media queries when paginated.
if (!IsPaginated() && HasCachedStyleData()) {
if (!IsPaginated()) {
MediaFeatureValuesChanged({
mozilla::MediaFeatureChangeReason::ViewportChange
});
@ -619,19 +619,19 @@ public:
* independent of the language-specific global preference.
*/
void SetBaseMinFontSize(int32_t aMinFontSize) {
if (aMinFontSize == mBaseMinFontSize)
if (aMinFontSize == mBaseMinFontSize) {
return;
}
mBaseMinFontSize = aMinFontSize;
if (HasCachedStyleData()) {
// Media queries could have changed, since we changed the meaning
// of 'em' units in them.
MediaFeatureValuesChanged({
eRestyle_ForceDescendants,
NS_STYLE_HINT_REFLOW,
mozilla::MediaFeatureChangeReason::MinFontSizeChange
});
}
// Media queries could have changed, since we changed the meaning
// of 'em' units in them.
MediaFeatureValuesChanged({
eRestyle_ForceDescendants,
NS_STYLE_HINT_REFLOW,
mozilla::MediaFeatureChangeReason::MinFontSizeChange
});
}
float GetFullZoom() { return mFullZoom; }
@ -1282,9 +1282,6 @@ protected:
bool HavePendingInputEvent();
// Can't be inline because we can't include nsStyleSet.h.
bool HasCachedStyleData();
// Creates a one-shot timer with the given aCallback & aDelay.
// Returns a refcounted pointer to the timer (or nullptr on failure).
already_AddRefed<nsITimer> CreateTimer(nsTimerCallbackFunc aCallback,

View File

@ -1,4 +1,4 @@
== usercss.html usercss-ref.html
random-if(!browserIsRemote&&(stylo||styloVsGecko)) == usercss-uppercase.html usercss-ref.html
== usercss-uppercase.html usercss-ref.html
== usercss-xbl.html usercss-ref.html
== usercss-moz-document.html usercss-moz-document-ref.html

View File

@ -1314,6 +1314,7 @@ void
ServoStyleSet::CompatibilityModeChanged()
{
Servo_StyleSet_CompatModeChanged(mRawSet.get());
SetStylistStyleSheetsDirty();
}
already_AddRefed<ServoStyleContext>

View File

@ -475,16 +475,6 @@ class nsStyleSet final
--mRootStyleContextCount;
}
// Return whether the rule tree has cached data such that we need to
// do dynamic change handling for changes that change the results of
// media queries or require rebuilding all style data.
// We don't care whether we have cached rule processors or whether
// they have cached rule cascades; getting the rule cascades again in
// order to do rule matching will get the correct rule cascade.
bool HasCachedStyleData() const {
return (mRuleTree && mRuleTree->TreeHasCachedData()) || mRootStyleContextCount > 0;
}
// Notify the style set that a rulenode is no longer in use, or was
// just created and is not in use yet.
static const uint32_t kGCInterval = 300;

View File

@ -31,7 +31,7 @@ use std::fmt;
use std::fmt::Debug;
use std::hash::Hash;
use std::ops::Deref;
use stylist::{CascadeData, Stylist};
use stylist::CascadeData;
use traversal_flags::TraversalFlags;
/// An opaque handle to a node, which, unlike UnsafeNode, cannot be transformed
@ -751,10 +751,10 @@ pub trait TElement
/// Implements Gecko's `nsBindingManager::WalkRules`.
///
/// Returns whether to cut off the inheritance.
fn each_xbl_stylist<'a, F>(&self, _: F) -> bool
fn each_xbl_cascade_data<'a, F>(&self, _: F) -> bool
where
Self: 'a,
F: FnMut(AtomicRef<'a, Stylist>),
F: FnMut(AtomicRef<'a, CascadeData>, QuirksMode),
{
false
}
@ -768,24 +768,11 @@ pub trait TElement
Self: 'a,
F: FnMut(AtomicRef<'a, CascadeData>, QuirksMode),
{
let cut_off_inheritance = self.each_xbl_stylist(|stylist| {
let quirks_mode = stylist.quirks_mode();
f(
AtomicRef::map(stylist, |stylist| stylist.author_cascade_data()),
quirks_mode,
)
});
let cut_off_inheritance = self.each_xbl_cascade_data(&mut f);
let mut current = self.assigned_slot();
while let Some(slot) = current {
slot.each_xbl_stylist(|stylist| {
let quirks_mode = stylist.quirks_mode();
f(
AtomicRef::map(stylist, |stylist| stylist.author_cascade_data()),
quirks_mode,
)
});
slot.each_xbl_cascade_data(&mut f);
current = slot.assigned_slot();
}
@ -794,8 +781,9 @@ pub trait TElement
/// Gets the current existing CSS transitions, by |property, end value| pairs in a FnvHashMap.
#[cfg(feature = "gecko")]
fn get_css_transitions_info(&self)
-> FnvHashMap<LonghandId, Arc<AnimationValue>>;
fn get_css_transitions_info(
&self,
) -> FnvHashMap<LonghandId, Arc<AnimationValue>>;
/// Does a rough (and cheap) check for whether or not transitions might need to be updated that
/// will quickly return false for the common case of no transitions specified or running. If

View File

@ -86,7 +86,7 @@ use std::mem;
use std::ops::DerefMut;
use std::ptr;
use string_cache::{Atom, Namespace, WeakAtom, WeakNamespace};
use stylist::Stylist;
use stylist::CascadeData;
/// A simple wrapper over `nsIDocument`.
#[derive(Clone, Copy)]
@ -429,12 +429,12 @@ impl<'lb> GeckoXBLBinding<'lb> {
}
}
fn each_xbl_stylist<F>(&self, f: &mut F)
fn each_xbl_cascade_data<F>(&self, f: &mut F)
where
F: FnMut(AtomicRef<'lb, Stylist>),
F: FnMut(AtomicRef<'lb, CascadeData>, QuirksMode),
{
if let Some(base) = self.base_binding() {
base.each_xbl_stylist(f);
base.each_xbl_cascade_data(f);
}
let raw_data = unsafe {
@ -443,7 +443,8 @@ impl<'lb> GeckoXBLBinding<'lb> {
if let Some(raw_data) = raw_data {
let data = PerDocumentStyleData::from_ffi(&*raw_data).borrow();
f(AtomicRef::map(data, |d| &d.stylist));
let quirks_mode = data.stylist.quirks_mode();
f(AtomicRef::map(data, |d| d.stylist.author_cascade_data()), quirks_mode);
}
}
}
@ -1374,10 +1375,10 @@ impl<'le> TElement for GeckoElement<'le> {
self.may_have_animations() && unsafe { Gecko_ElementHasCSSTransitions(self.0) }
}
fn each_xbl_stylist<'a, F>(&self, mut f: F) -> bool
fn each_xbl_cascade_data<'a, F>(&self, mut f: F) -> bool
where
'le: 'a,
F: FnMut(AtomicRef<'a, Stylist>),
F: FnMut(AtomicRef<'a, CascadeData>, QuirksMode),
{
// Walk the binding scope chain, starting with the binding attached to
// our content, up till we run out of scopes or we get cut off.
@ -1388,7 +1389,7 @@ impl<'le> TElement for GeckoElement<'le> {
while let Some(element) = current {
if let Some(binding) = element.get_xbl_binding() {
binding.each_xbl_stylist(&mut f);
binding.each_xbl_cascade_data(&mut f);
// If we're not looking at our original element, allow the
// binding to cut off style inheritance.
@ -1416,8 +1417,7 @@ impl<'le> TElement for GeckoElement<'le> {
fn xbl_binding_anonymous_content(&self) -> Option<GeckoNode<'le>> {
self.get_xbl_binding_with_content()
.map(|b| unsafe { b.anon_content().as_ref() }.unwrap())
.map(GeckoNode::from_content)
.map(|b| unsafe { GeckoNode::from_content(&*b.anon_content()) })
}
fn get_css_transitions_info(

View File

@ -24,11 +24,11 @@ use properties::longhands::visibility::computed_value::T as Visibility;
#[cfg(feature = "gecko")]
use properties::PropertyId;
use properties::{LonghandId, ShorthandId};
use selectors::parser::SelectorParseErrorKind;
use servo_arc::Arc;
use smallvec::SmallVec;
use std::{cmp, mem, ptr};
use std::{cmp, ptr};
use std::fmt::{self, Write};
use std::mem::{self, ManuallyDrop};
#[cfg(feature = "gecko")] use hash::FnvHashMap;
use style_traits::{CssWriter, ParseError, ToCss};
use super::ComputedValues;
@ -141,21 +141,42 @@ impl TransitionProperty {
/// Parse a transition-property value.
pub fn parse<'i, 't>(input: &mut Parser<'i, 't>) -> Result<Self, ParseError<'i>> {
// FIXME(https://github.com/rust-lang/rust/issues/33156): remove this
// enum and use PropertyId when stable Rust allows destructors in
// statics.
//
// FIXME: This should handle aliases too.
pub enum StaticId {
All,
Longhand(LonghandId),
Shorthand(ShorthandId),
}
ascii_case_insensitive_phf_map! {
static_id -> StaticId = {
"all" => StaticId::All,
% for prop in data.shorthands_except_all():
"${prop.name}" => StaticId::Shorthand(ShorthandId::${prop.camel_case}),
% endfor
% for prop in data.longhands:
"${prop.name}" => StaticId::Longhand(LonghandId::${prop.camel_case}),
% endfor
}
}
let location = input.current_source_location();
let ident = input.expect_ident()?;
match_ignore_ascii_case! { &ident,
"all" => Ok(TransitionProperty::All),
% for prop in data.shorthands_except_all():
"${prop.name}" => Ok(TransitionProperty::Shorthand(ShorthandId::${prop.camel_case})),
% endfor
% for prop in data.longhands:
"${prop.name}" => Ok(TransitionProperty::Longhand(LonghandId::${prop.camel_case})),
% endfor
"none" => Err(location.new_custom_error(SelectorParseErrorKind::UnexpectedIdent(ident.clone()))),
_ => CustomIdent::from_ident(location, ident, &[]).map(TransitionProperty::Unsupported),
}
}
Ok(match static_id(&ident) {
Some(&StaticId::All) => TransitionProperty::All,
Some(&StaticId::Longhand(id)) => TransitionProperty::Longhand(id),
Some(&StaticId::Shorthand(id)) => TransitionProperty::Shorthand(id),
None => {
TransitionProperty::Unsupported(
CustomIdent::from_ident(location, ident, &["none"])?,
)
},
})
}
/// Convert TransitionProperty to nsCSSPropertyID.
#[cfg(feature = "gecko")]
@ -345,8 +366,8 @@ unsafe impl HasSimpleFFI for AnimationValueMap {}
///
/// FIXME: We need to add a path for custom properties, but that's trivial after
/// this (is a similar path to that of PropertyDeclaration).
#[derive(Clone, Debug, PartialEq)]
#[cfg_attr(feature = "servo", derive(MallocSizeOf))]
#[derive(Debug)]
#[repr(u16)]
pub enum AnimationValue {
% for prop in data.longhands:
@ -370,6 +391,95 @@ pub enum AnimationValue {
unanimated.append(prop)
%>
#[repr(C)]
struct AnimationValueVariantRepr<T> {
tag: u16,
value: T
}
impl Clone for AnimationValue {
#[inline]
fn clone(&self) -> Self {
use self::AnimationValue::*;
<%
[copy, others] = [list(g) for _, g in groupby(animated, key=lambda x: not x.specified_is_copy())]
%>
let self_tag = unsafe { *(self as *const _ as *const u16) };
if self_tag <= LonghandId::${copy[-1].camel_case} as u16 {
#[derive(Clone, Copy)]
#[repr(u16)]
enum CopyVariants {
% for prop in copy:
_${prop.camel_case}(${prop.animated_type()}),
% endfor
}
unsafe {
let mut out = mem::uninitialized();
ptr::write(
&mut out as *mut _ as *mut CopyVariants,
*(self as *const _ as *const CopyVariants),
);
return out;
}
}
match *self {
% for ty, props in groupby(others, key=lambda x: x.animated_type()):
<% props = list(props) %>
${" |\n".join("{}(ref value)".format(prop.camel_case) for prop in props)} => {
% if len(props) == 1:
${props[0].camel_case}(value.clone())
% else:
unsafe {
let mut out = ManuallyDrop::new(mem::uninitialized());
ptr::write(
&mut out as *mut _ as *mut AnimationValueVariantRepr<${ty}>,
AnimationValueVariantRepr {
tag: *(self as *const _ as *const u16),
value: value.clone(),
},
);
ManuallyDrop::into_inner(out)
}
% endif
}
% endfor
_ => unsafe { debug_unreachable!() }
}
}
}
impl PartialEq for AnimationValue {
#[inline]
fn eq(&self, other: &Self) -> bool {
use self::AnimationValue::*;
unsafe {
let this_tag = *(self as *const _ as *const u16);
let other_tag = *(other as *const _ as *const u16);
if this_tag != other_tag {
return false;
}
match *self {
% for ty, props in groupby(animated, key=lambda x: x.animated_type()):
${" |\n".join("{}(ref this)".format(prop.camel_case) for prop in props)} => {
let other_repr =
&*(other as *const _ as *const AnimationValueVariantRepr<${ty}>);
*this == other_repr.value
}
% endfor
${" |\n".join("{}(void)".format(prop.camel_case) for prop in unanimated)} => {
void::unreachable(void)
}
}
}
}
}
impl AnimationValue {
/// Returns the longhand id this animated value corresponds to.
#[inline]
@ -564,12 +674,6 @@ fn animate_discrete<T: Clone>(this: &T, other: &T, procedure: Procedure) -> Resu
}
}
#[repr(C)]
struct AnimationValueVariantRepr<T> {
tag: u16,
value: T
}
impl Animate for AnimationValue {
fn animate(&self, other: &Self, procedure: Procedure) -> Result<Self, ()> {
Ok(unsafe {

View File

@ -133,7 +133,6 @@ ${helpers.predefined_type("marker-end", "UrlOrNone", "Either::Second(None_)",
${helpers.predefined_type("paint-order", "SVGPaintOrder", "computed::SVGPaintOrder::normal()",
products="gecko",
animation_value_type="discrete",
gecko_pref="svg.paint-order.enabled",
spec="https://www.w3.org/TR/SVG2/painting.html#PaintOrder")}
${helpers.predefined_type("-moz-context-properties",

View File

@ -77,6 +77,9 @@ impl UserAgentCascadeDataCache {
}
}
// FIXME(emilio): This may need to be keyed on quirks-mode too, though there
// aren't class / id selectors on those sheets, usually, so it's probably
// ok...
fn lookup<'a, I, S>(
&'a mut self,
sheets: I,
@ -1146,13 +1149,11 @@ impl Stylist {
/// Sets the quirks mode of the document.
pub fn set_quirks_mode(&mut self, quirks_mode: QuirksMode) {
// FIXME(emilio): We don't seem to change the quirks mode dynamically
// during multiple layout passes, but this is totally bogus, in the
// sense that it's updated asynchronously.
//
// This should probably be an argument to `update`, and use the quirks
// mode info in the `SharedLayoutContext`.
if self.quirks_mode == quirks_mode {
return;
}
self.quirks_mode = quirks_mode;
self.force_stylesheet_origins_dirty(OriginSet::all());
}
/// Returns the applicable CSS declarations for the given element.
@ -1267,8 +1268,8 @@ impl Stylist {
}
for slot in slots.iter().rev() {
slot.each_xbl_stylist(|stylist| {
if let Some(map) = stylist.cascade_data.author.slotted_rules(pseudo_element) {
slot.each_xbl_cascade_data(|cascade_data, _quirks_mode| {
if let Some(map) = cascade_data.slotted_rules(pseudo_element) {
map.get_all_matching_rules(
element,
rule_hash_target,
@ -1286,8 +1287,8 @@ impl Stylist {
// even for getDefaultComputedStyle!
//
// Also, this doesn't account for the author_styles_enabled stuff.
let cut_off_inheritance = element.each_xbl_stylist(|stylist| {
if let Some(map) = stylist.cascade_data.author.normal_rules(pseudo_element) {
let cut_off_inheritance = element.each_xbl_cascade_data(|cascade_data, quirks_mode| {
if let Some(map) = cascade_data.normal_rules(pseudo_element) {
// NOTE(emilio): This is needed because the XBL stylist may
// think it has a different quirks mode than the document.
//
@ -1298,7 +1299,7 @@ impl Stylist {
context.matching_mode(),
context.bloom_filter,
context.nth_index_cache.as_mut().map(|s| &mut **s),
stylist.quirks_mode,
quirks_mode,
);
matching_context.pseudo_element_matching_fn = context.pseudo_element_matching_fn;

View File

@ -88,7 +88,7 @@ impl ToAnimatedZero for BorderCornerRadius {
/// The computed value of the `border-image-repeat` property:
///
/// https://drafts.csswg.org/css-backgrounds/#the-border-image-repeat
#[derive(Clone, Debug, MallocSizeOf, PartialEq)]
#[derive(Clone, Copy, Debug, MallocSizeOf, PartialEq)]
pub struct BorderImageRepeat(pub BorderImageRepeatKeyword, pub BorderImageRepeatKeyword);
impl BorderImageRepeat {

View File

@ -146,28 +146,6 @@ impl Parse for Content {
}
}
impl ToCss for Content {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where W: Write,
{
match *self {
Content::Normal => dest.write_str("normal"),
Content::None => dest.write_str("none"),
#[cfg(feature = "gecko")]
Content::MozAltContent => dest.write_str("-moz-alt-content"),
Content::Items(ref content) => {
let mut iter = content.iter();
iter.next().unwrap().to_css(dest)?;
for c in iter {
dest.write_str(" ")?;
c.to_css(dest)?;
}
Ok(())
}
}
}
}
impl ToCss for ContentItem {
fn to_css<W>(&self, dest: &mut CssWriter<W>) -> fmt::Result
where W: Write,

View File

@ -82,7 +82,7 @@ type CounterStyleType = CounterStyleOrNone;
/// The specified value for the `content` property.
///
/// https://drafts.csswg.org/css-content/#propdef-content
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue)]
#[derive(Clone, Debug, Eq, MallocSizeOf, PartialEq, ToComputedValue, ToCss)]
pub enum Content {
/// `normal` reserved keyword.
Normal,
@ -92,6 +92,7 @@ pub enum Content {
#[cfg(feature = "gecko")]
MozAltContent,
/// Content items.
#[css(iterable)]
Items(Box<[ContentItem]>),
}

View File

@ -2450,19 +2450,12 @@ pub extern "C" fn Servo_StyleSet_Drop(data: RawServoStyleSetOwned) {
let _ = data.into_box::<PerDocumentStyleData>();
}
/// Updating the stylesheets and redoing selector matching is always happens
/// before the document element is inserted. Therefore we don't need to call
/// `force_dirty` here.
#[no_mangle]
pub extern "C" fn Servo_StyleSet_CompatModeChanged(raw_data: RawServoStyleSetBorrowed) {
pub unsafe extern "C" fn Servo_StyleSet_CompatModeChanged(raw_data: RawServoStyleSetBorrowed) {
let mut data = PerDocumentStyleData::from_ffi(raw_data).borrow_mut();
let quirks_mode = unsafe {
(*data.stylist.device().pres_context().mDocument.raw::<nsIDocument>())
.mCompatMode
};
data.stylist.set_quirks_mode(quirks_mode.into());
let doc =
&*data.stylist.device().pres_context().mDocument.raw::<nsIDocument>();
data.stylist.set_quirks_mode(QuirksMode::from(doc.mCompatMode));
}
fn parse_property_into<R>(

View File

@ -15,6 +15,9 @@ LOCAL_CACHE_DIR=
S3_CACHE_HITS=0
S3_CACHE_MISSES=0
# Don't cache files smaller than this, as it's slower with S3
# Bug 1437473
CACHE_THRESHOLD=500000
getsha512(){
openssl sha512 "${1}" | awk '{print $2}'
@ -35,6 +38,10 @@ print_usage(){
}
upload_patch(){
if [ "$(stat -f "%z" "$2")" -lt ${CACHE_THRESHOLD} ]
then
return 0
fi
sha_from=$(getsha512 "$1")
sha_to=$(getsha512 "$2")
patch_path="$3"
@ -63,6 +70,10 @@ upload_patch(){
get_patch(){
# $1 and $2 are the /path/to/filename
if [ "$(stat -f "%z" "$2")" -lt ${CACHE_THRESHOLD} ]
then
return 1
fi
sha_from=$(getsha512 "$1")
sha_to=$(getsha512 "$2")
destination_file="$3"

View File

@ -160077,6 +160077,18 @@
{}
]
],
"css/mediaqueries/viewport-script-dynamic.html": [
[
"/css/mediaqueries/viewport-script-dynamic.html",
[
[
"/css/mediaqueries/viewport-script-dynamic-ref.html",
"=="
]
],
{}
]
],
"css/motion/offset-anchor-transform-box-fill-box.html": [
[
"/css/motion/offset-anchor-transform-box-fill-box.html",
@ -260035,6 +260047,11 @@
{}
]
],
"css/mediaqueries/viewport-script-dynamic-ref.html": [
[
{}
]
],
"css/motion/animation/resources/interpolation-testcommon.js": [
[
{}
@ -526220,6 +526237,14 @@
"234627714b5f304ad7efbeaf2dea3455125f8cc4",
"testharness"
],
"css/mediaqueries/viewport-script-dynamic-ref.html": [
"7d55c513e2de39c9b362fc864233a3008ca6ced2",
"support"
],
"css/mediaqueries/viewport-script-dynamic.html": [
"1c2ba1a9116942599804ed29553e85628afadb04",
"reftest"
],
"css/motion/animation/offset-anchor-interpolation.html": [
"30eb3ea68aa502d93125d4e54ff15c0a96458cfa",
"testharness"
@ -592249,19 +592274,19 @@
"wdspec"
],
"webdriver/tests/actions/modifier_click.py": [
"56df38086ef05cd8bff1437038efb598ab63f1e3",
"88a384182fdd9df1515b9d8cfda8f56aed138ec7",
"wdspec"
],
"webdriver/tests/actions/mouse.py": [
"2fb4c47335f144a2dd6f16db4c20239116f20fed",
"edad7693fcd01b418821942edb870191db64ea41",
"wdspec"
],
"webdriver/tests/actions/mouse_dblclick.py": [
"932b053eef5e052d53ab2007540428d68b758ad4",
"f6afcb8c0fa017d58a9fcdd3cc474e0c8fd52db5",
"wdspec"
],
"webdriver/tests/actions/pointer_origin.py": [
"da2a9f21018582c8cd52d206d172841f71fd19f3",
"a9a99d58daec7719ee53ed758f566ccceb582f65",
"wdspec"
],
"webdriver/tests/actions/sequence.py": [
@ -592281,7 +592306,7 @@
"support"
],
"webdriver/tests/actions/support/mouse.py": [
"208a1c4fbc0d5c542d17de7f6474d477ce1feb45",
"bc7da107e5b897105dfa7405aa57cba7355854dc",
"support"
],
"webdriver/tests/actions/support/refine.py": [
@ -592289,7 +592314,7 @@
"support"
],
"webdriver/tests/actions/support/test_actions_wdspec.html": [
"34f99c46ac9c52e5902477c26a3d16a89a29235a",
"95203777fcc012ab64465287737a89a4ba2c31dc",
"support"
],
"webdriver/tests/conftest.py": [

View File

@ -0,0 +1,2 @@
[viewport-script-dynamic.html]
prefs: [dom.meta-viewport.enabled:true]

View File

@ -13,14 +13,22 @@
#test1 {
font-feature-settings: 'vert' 1;
}
#test2 {
font-feature-settings: "vert" off;
}
</style>
<div id="test"></div>
<div id="test1"></div>
<div id="test2"></div>
<script>
const div = document.querySelector("#test");
const div1 = document.querySelector("#test1");
const div2 = document.querySelector("#test2");
test(function() {
assert_equals(getComputedStyle(div).fontFeatureSettings, '"vert"');
assert_equals(getComputedStyle(div1).fontFeatureSettings, '"vert"');
}, "font-feature-settings should be serialized with double quotes, and the default value of 1 should be omitted");
test(function() {
assert_equals(getComputedStyle(div2).fontFeatureSettings, '"vert" 0');
}, "font-feature-settings should serialize 0 instead of off, given it's shorter");
</script>

View File

@ -0,0 +1,9 @@
<!doctype html>
<meta charset="utf-8">
<title>CSS Test Reference</title>
<link rel="author" href="mailto:emilio@crisal.io">
<meta name="viewport" content="width=300">
<style>
p { color: green; }
</style>
<p>Should be green</p>

View File

@ -0,0 +1,20 @@
<!doctype html>
<meta charset="utf-8">
<title>CSS Test: Meta viewport after a script and stylesheets</title>
<link rel="author" href="mailto:emilio@crisal.io">
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1424878">
<link rel="help" href="https://drafts.csswg.org/mediaqueries/#mf-dimensions">
<link rel="match" href="viewport-script-dynamic-ref.html">
<style>
p { color: green; }
/* Ensure that we initially match it, and stop matching it afterwards */
@media (min-width: 310px) {
p {
color: red;
}
}
</style>
<!-- The broken script below is the point of the test, see the bugzilla bug. -->
<script src="intentionally-broken-url.js"></script>
<meta name="viewport" content="width=300">
<p>Should be green</p>