зеркало из https://github.com/mozilla/gecko-dev.git
Merge autoland to mozilla-central. a=merge
This commit is contained in:
Коммит
e6c323f55d
|
@ -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", () => {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1314,6 +1314,7 @@ void
|
|||
ServoStyleSet::CompatibilityModeChanged()
|
||||
{
|
||||
Servo_StyleSet_CompatModeChanged(mRawSet.get());
|
||||
SetStylistStyleSheetsDirty();
|
||||
}
|
||||
|
||||
already_AddRefed<ServoStyleContext>
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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(
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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]>),
|
||||
}
|
||||
|
||||
|
|
|
@ -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>(
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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": [
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
[viewport-script-dynamic.html]
|
||||
prefs: [dom.meta-viewport.enabled:true]
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
Загрузка…
Ссылка в новой задаче