summaryrefslogtreecommitdiffstats
path: root/layout/style
diff options
context:
space:
mode:
authorMoonchild <moonchild@palemoon.org>2020-09-23 23:45:46 +0000
committerMoonchild <moonchild@palemoon.org>2020-09-23 23:45:46 +0000
commit9f5c27ba479c54d4ebb1bd59b61fbf793f6df93f (patch)
tree831e0ae1649d6135429def03688bc93ff7c86b03 /layout/style
parent42f895f27f239e973c9c06241f7a58da7381353c (diff)
parentf624bd1375655dea196cdcb70a9860bc5817df49 (diff)
downloadUXP-f583969f6ffe8f2dbd525dd3dc55d25347d7c492.tar
UXP-f583969f6ffe8f2dbd525dd3dc55d25347d7c492.tar.gz
UXP-f583969f6ffe8f2dbd525dd3dc55d25347d7c492.tar.lz
UXP-f583969f6ffe8f2dbd525dd3dc55d25347d7c492.tar.xz
UXP-f583969f6ffe8f2dbd525dd3dc55d25347d7c492.zip
Merge branch 'redwood' into releaseRELBASE_20200929RC_20200924
Diffstat (limited to 'layout/style')
-rw-r--r--layout/style/Loader.cpp12
-rw-r--r--layout/style/MediaQueryList.cpp215
-rw-r--r--layout/style/MediaQueryList.h48
-rw-r--r--layout/style/contenteditable.css9
-rw-r--r--layout/style/moz.build1
-rw-r--r--layout/style/nsCSSKeywordList.h1
-rw-r--r--layout/style/nsCSSParser.cpp54
-rw-r--r--layout/style/nsCSSPropList.h10
-rw-r--r--layout/style/nsCSSProps.cpp3
-rw-r--r--layout/style/nsCSSProps.h1
-rw-r--r--layout/style/nsRuleNode.cpp2
-rw-r--r--layout/style/nsStyleConsts.h1
-rw-r--r--layout/style/nsStyleStruct.h6
-rw-r--r--layout/style/res/html.css17
-rw-r--r--layout/style/test/property_database.js22
-rw-r--r--layout/style/xbl-marquee/jar.mn8
-rw-r--r--layout/style/xbl-marquee/moz.build7
-rw-r--r--layout/style/xbl-marquee/xbl-marquee.css12
-rw-r--r--layout/style/xbl-marquee/xbl-marquee.xml733
19 files changed, 245 insertions, 917 deletions
diff --git a/layout/style/Loader.cpp b/layout/style/Loader.cpp
index df523174d..a06dd3737 100644
--- a/layout/style/Loader.cpp
+++ b/layout/style/Loader.cpp
@@ -2272,7 +2272,6 @@ Loader::LoadChildSheet(StyleSheet* aParentSheet,
state = eSheetComplete;
} else {
bool isAlternate;
- bool isExplicitlyEnabled;
const nsSubstring& empty = EmptyString();
// For now, use CORS_NONE for child sheets
rv = CreateSheet(aURL, nullptr, principal,
@@ -2282,8 +2281,9 @@ Loader::LoadChildSheet(StyleSheet* aParentSheet,
parentData ? parentData->mSyncLoad : false,
false, empty, state, &isAlternate, &sheet);
NS_ENSURE_SUCCESS(rv, rv);
-
- PrepareSheet(sheet, empty, empty, aMedia, nullptr, isAlternate, isExplicitlyEnabled);
+ // For now, child sheets are not explicitly enabled (seventh argument is
+ // always false here).
+ PrepareSheet(sheet, empty, empty, aMedia, nullptr, isAlternate, false);
}
rv = InsertChildSheet(sheet, aParentSheet, aParentRule);
@@ -2396,7 +2396,6 @@ Loader::InternalLoadNonDocumentSheet(nsIURI* aURL,
StyleSheetState state;
bool isAlternate;
- bool isExplicitlyEnabled;
RefPtr<StyleSheet> sheet;
bool syncLoad = (aObserver == nullptr);
const nsSubstring& empty = EmptyString();
@@ -2406,7 +2405,10 @@ Loader::InternalLoadNonDocumentSheet(nsIURI* aURL,
false, empty, state, &isAlternate, &sheet);
NS_ENSURE_SUCCESS(rv, rv);
- PrepareSheet(sheet, empty, empty, nullptr, nullptr, isAlternate, isExplicitlyEnabled);
+ // Sheets can only be explicitly enabled after creation and preparation, so
+ // we always pass false for the initial value of the explicitly enabled flag
+ // when calling PrepareSheet.
+ PrepareSheet(sheet, empty, empty, nullptr, nullptr, isAlternate, false);
if (state == eSheetComplete) {
LOG((" Sheet already complete"));
diff --git a/layout/style/MediaQueryList.cpp b/layout/style/MediaQueryList.cpp
index db3781b76..5838645be 100644
--- a/layout/style/MediaQueryList.cpp
+++ b/layout/style/MediaQueryList.cpp
@@ -1,5 +1,4 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
-/* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
@@ -7,19 +6,26 @@
/* implements DOM interface for querying and observing media queries */
#include "mozilla/dom/MediaQueryList.h"
+#include "mozilla/dom/MediaQueryListEvent.h"
+#include "mozilla/dom/EventTarget.h"
+#include "mozilla/dom/EventTargetBinding.h"
#include "nsPresContext.h"
#include "nsIMediaList.h"
#include "nsCSSParser.h"
#include "nsIDocument.h"
+// Fixed event target type
+#define ONCHANGE_STRING NS_LITERAL_STRING("change")
+
namespace mozilla {
namespace dom {
MediaQueryList::MediaQueryList(nsIDocument *aDocument,
const nsAString &aMediaQueryList)
- : mDocument(aDocument),
- mMediaList(new nsMediaList),
- mMatchesValid(false)
+ : mDocument(aDocument)
+ , mMediaList(new nsMediaList)
+ , mMatchesValid(false)
+ , mIsKeptAlive(false)
{
PR_INIT_CLIST(this);
@@ -36,30 +42,24 @@ MediaQueryList::~MediaQueryList()
NS_IMPL_CYCLE_COLLECTION_CLASS(MediaQueryList)
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(MediaQueryList)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(MediaQueryList, DOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocument)
- NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mCallbacks)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
-NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(MediaQueryList)
+NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(MediaQueryList, DOMEventTargetHelper)
if (tmp->mDocument) {
PR_REMOVE_LINK(tmp);
NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocument)
}
- tmp->RemoveAllListeners();
+ tmp->Disconnect();
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
-NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(MediaQueryList)
-
-NS_INTERFACE_MAP_BEGIN(MediaQueryList)
- NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
- NS_INTERFACE_MAP_ENTRY(nsISupports)
- NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(MediaQueryList)
-NS_INTERFACE_MAP_END
+NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(MediaQueryList)
+NS_INTERFACE_MAP_END_INHERITING(DOMEventTargetHelper)
-NS_IMPL_CYCLE_COLLECTING_ADDREF(MediaQueryList)
-NS_IMPL_CYCLE_COLLECTING_RELEASE(MediaQueryList)
+NS_IMPL_ADDREF_INHERITED(MediaQueryList, DOMEventTargetHelper)
+NS_IMPL_RELEASE_INHERITED(MediaQueryList, DOMEventTargetHelper)
void
MediaQueryList::GetMedia(nsAString &aMedia)
@@ -80,57 +80,124 @@ MediaQueryList::Matches()
}
void
-MediaQueryList::AddListener(MediaQueryListListener& aListener)
+MediaQueryList::AddListener(EventListener* aListener, ErrorResult& aRv)
{
- if (!HasListeners()) {
- // When we have listeners, the pres context owns a reference to
- // this. This is a cyclic reference that can only be broken by
- // cycle collection.
- NS_ADDREF_THIS();
+ if (!aListener) {
+ return;
}
+ AddEventListenerOptionsOrBoolean options;
+ options.SetAsBoolean() = false;
+
+ AddEventListener(ONCHANGE_STRING, aListener, options, Nullable<bool>(), aRv);
+}
+
+void
+MediaQueryList::AddEventListener(const nsAString& aType,
+ EventListener* aCallback,
+ const AddEventListenerOptionsOrBoolean& aOptions,
+ const dom::Nullable<bool>& aWantsUntrusted,
+ ErrorResult& aRv)
+{
if (!mMatchesValid) {
MOZ_ASSERT(!HasListeners(),
"when listeners present, must keep mMatches current");
RecomputeMatches();
}
- for (uint32_t i = 0; i < mCallbacks.Length(); ++i) {
- if (aListener == *mCallbacks[i]) {
- // Already registered
- return;
- }
+ DOMEventTargetHelper::AddEventListener(aType, aCallback, aOptions,
+ aWantsUntrusted, aRv);
+
+ if (aRv.Failed()) {
+ return;
}
- if (!mCallbacks.AppendElement(&aListener, fallible)) {
- if (!HasListeners()) {
- // Append failed; undo the AddRef above.
- NS_RELEASE_THIS();
- }
+ UpdateMustKeepAlive();
+}
+
+void
+MediaQueryList::RemoveListener(EventListener* aListener, ErrorResult& aRv)
+{
+ if (!aListener) {
+ return;
}
+
+ EventListenerOptionsOrBoolean options;
+ options.SetAsBoolean() = false;
+
+ RemoveEventListener(ONCHANGE_STRING, aListener, options, aRv);
}
void
-MediaQueryList::RemoveListener(MediaQueryListListener& aListener)
-{
- for (uint32_t i = 0; i < mCallbacks.Length(); ++i) {
- if (aListener == *mCallbacks[i]) {
- mCallbacks.RemoveElementAt(i);
- if (!HasListeners()) {
- // See NS_ADDREF_THIS() in AddListener.
- NS_RELEASE_THIS();
- }
- break;
- }
+MediaQueryList::RemoveEventListener(const nsAString& aType,
+ EventListener* aCallback,
+ const EventListenerOptionsOrBoolean& aOptions,
+ ErrorResult& aRv)
+{
+ DOMEventTargetHelper::RemoveEventListener(aType, aCallback, aOptions, aRv);
+
+ if (aRv.Failed()) {
+ return;
+ }
+
+ UpdateMustKeepAlive();
+}
+
+EventHandlerNonNull*
+MediaQueryList::GetOnchange()
+{
+ if (NS_IsMainThread()) {
+ return GetEventHandler(nsGkAtoms::onchange, EmptyString());
+ }
+ return GetEventHandler(nullptr, ONCHANGE_STRING);
+}
+
+void
+MediaQueryList::SetOnchange(EventHandlerNonNull* aCallback)
+{
+ if (NS_IsMainThread()) {
+ SetEventHandler(nsGkAtoms::onchange, EmptyString(), aCallback);
+ } else {
+ SetEventHandler(nullptr, ONCHANGE_STRING, aCallback);
}
+
+ UpdateMustKeepAlive();
}
void
-MediaQueryList::RemoveAllListeners()
+MediaQueryList::UpdateMustKeepAlive()
{
- bool hadListeners = HasListeners();
- mCallbacks.Clear();
- if (hadListeners) {
+ bool toKeepAlive = HasListeners();
+ if (toKeepAlive == mIsKeptAlive) {
+ return;
+ }
+
+ // When we have listeners, the pres context owns a reference to
+ // this. This is a cyclic reference that can only be broken by
+ // cycle collection.
+
+ mIsKeptAlive = toKeepAlive;
+
+ if (toKeepAlive) {
+ NS_ADDREF_THIS();
+ } else {
+ NS_RELEASE_THIS();
+ }
+}
+
+bool
+MediaQueryList::HasListeners()
+{
+ return HasListenersFor(ONCHANGE_STRING);
+}
+
+void
+MediaQueryList::Disconnect()
+{
+ DisconnectFromOwner();
+
+ if (mIsKeptAlive) {
+ mIsKeptAlive = false;
// See NS_ADDREF_THIS() in AddListener.
NS_RELEASE_THIS();
}
@@ -169,27 +236,6 @@ MediaQueryList::RecomputeMatches()
mMatchesValid = true;
}
-void
-MediaQueryList::MediumFeaturesChanged(
- nsTArray<HandleChangeData>& aListenersToNotify)
-{
- mMatchesValid = false;
-
- if (HasListeners()) {
- bool oldMatches = mMatches;
- RecomputeMatches();
- if (mMatches != oldMatches) {
- for (uint32_t i = 0, i_end = mCallbacks.Length(); i != i_end; ++i) {
- HandleChangeData *d = aListenersToNotify.AppendElement(fallible);
- if (d) {
- d->mql = this;
- d->callback = mCallbacks[i];
- }
- }
- }
- }
-}
-
nsISupports*
MediaQueryList::GetParentObject() const
{
@@ -202,5 +248,36 @@ MediaQueryList::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
return MediaQueryListBinding::Wrap(aCx, this, aGivenProto);
}
+void
+MediaQueryList::MaybeNotify()
+{
+ mMatchesValid = false;
+
+ if (!HasListeners()) {
+ return;
+ }
+
+ bool oldMatches = mMatches;
+ RecomputeMatches();
+
+ // No need to notify the change.
+ if (mMatches == oldMatches) {
+ return;
+ }
+
+ MediaQueryListEventInit init;
+ init.mBubbles = false;
+ init.mCancelable = false;
+ init.mMatches = mMatches;
+ mMediaList->GetText(init.mMedia);
+
+ RefPtr<MediaQueryListEvent> event =
+ MediaQueryListEvent::Constructor(this, ONCHANGE_STRING, init);
+ event->SetTrusted(true);
+
+ bool dummy;
+ DispatchEvent(event, &dummy);
+}
+
} // namespace dom
} // namespace mozilla
diff --git a/layout/style/MediaQueryList.h b/layout/style/MediaQueryList.h
index 5ba568528..d2acb34c1 100644
--- a/layout/style/MediaQueryList.h
+++ b/layout/style/MediaQueryList.h
@@ -16,6 +16,7 @@
#include "prclist.h"
#include "mozilla/Attributes.h"
#include "nsWrapperCache.h"
+#include "mozilla/DOMEventTargetHelper.h"
#include "mozilla/dom/MediaQueryListBinding.h"
class nsIDocument;
@@ -24,8 +25,7 @@ class nsMediaList;
namespace mozilla {
namespace dom {
-class MediaQueryList final : public nsISupports,
- public nsWrapperCache,
+class MediaQueryList final : public DOMEventTargetHelper,
public PRCList
{
public:
@@ -37,33 +37,45 @@ private:
~MediaQueryList();
public:
- NS_DECL_CYCLE_COLLECTING_ISUPPORTS
- NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(MediaQueryList)
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(MediaQueryList, DOMEventTargetHelper)
nsISupports* GetParentObject() const;
- struct HandleChangeData {
- RefPtr<MediaQueryList> mql;
- RefPtr<mozilla::dom::MediaQueryListListener> callback;
- };
-
- // Appends listeners that need notification to aListenersToNotify
- void MediumFeaturesChanged(nsTArray<HandleChangeData>& aListenersToNotify);
-
- bool HasListeners() const { return !mCallbacks.IsEmpty(); }
-
- void RemoveAllListeners();
+ void MaybeNotify();
JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
// WebIDL methods
void GetMedia(nsAString& aMedia);
bool Matches();
- void AddListener(mozilla::dom::MediaQueryListListener& aListener);
- void RemoveListener(mozilla::dom::MediaQueryListListener& aListener);
+ void AddListener(EventListener* aListener, ErrorResult& aRv);
+ void RemoveListener(EventListener* aListener, ErrorResult& aRv);
+
+ EventHandlerNonNull* GetOnchange();
+ void SetOnchange(EventHandlerNonNull* aCallback);
+
+ using nsIDOMEventTarget::AddEventListener;
+ using nsIDOMEventTarget::RemoveEventListener;
+
+ virtual void AddEventListener(const nsAString& aType,
+ EventListener* aCallback,
+ const AddEventListenerOptionsOrBoolean& aOptions,
+ const Nullable<bool>& aWantsUntrusted,
+ ErrorResult& aRv) override;
+ virtual void RemoveEventListener(const nsAString& aType,
+ EventListener* aCallback,
+ const EventListenerOptionsOrBoolean& aOptions,
+ ErrorResult& aRv) override;
+
+ bool HasListeners();
+
+ void Disconnect();
private:
void RecomputeMatches();
+
+ void UpdateMustKeepAlive();
// We only need a pointer to the document to support lazy
// reevaluation following dynamic changes. However, this lazy
@@ -84,7 +96,7 @@ private:
RefPtr<nsMediaList> mMediaList;
bool mMatches;
bool mMatchesValid;
- nsTArray<RefPtr<mozilla::dom::MediaQueryListListener>> mCallbacks;
+ bool mIsKeptAlive;
};
} // namespace dom
diff --git a/layout/style/contenteditable.css b/layout/style/contenteditable.css
index c550bc7c9..6d569f75e 100644
--- a/layout/style/contenteditable.css
+++ b/layout/style/contenteditable.css
@@ -80,15 +80,6 @@ input[contenteditable="true"][type="file"] {
-moz-user-focus: none !important;
}
-/* emulation of non-standard HTML <marquee> tag */
-marquee:-moz-read-write {
- -moz-binding: url('chrome://xbl-marquee/content/xbl-marquee.xml#marquee-horizontal-editable');
-}
-
-marquee[direction="up"]:-moz-read-write, marquee[direction="down"]:-moz-read-write {
- -moz-binding: url('chrome://xbl-marquee/content/xbl-marquee.xml#marquee-vertical-editable');
-}
-
*|*:-moz-read-write > input[type="hidden"],
input[contenteditable="true"][type="hidden"] {
border: 1px solid black !important;
diff --git a/layout/style/moz.build b/layout/style/moz.build
index ff06b5101..bdc86ee99 100644
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -19,7 +19,6 @@ with Files('CSSRuleList.*'):
with Files('nsDOM*'):
BUG_COMPONENT = ('Core', 'DOM: CSS Object Model')
-DIRS += ['xbl-marquee']
TEST_DIRS += ['test']
XPIDL_SOURCES += [
diff --git a/layout/style/nsCSSKeywordList.h b/layout/style/nsCSSKeywordList.h
index 34a46ffce..9045da9ff 100644
--- a/layout/style/nsCSSKeywordList.h
+++ b/layout/style/nsCSSKeywordList.h
@@ -285,6 +285,7 @@ CSS_KEY(flex, flex)
CSS_KEY(flex-end, flex_end)
CSS_KEY(flex-start, flex_start)
CSS_KEY(flip, flip)
+CSS_KEY(flow-root, flow_root)
CSS_KEY(forwards, forwards)
CSS_KEY(fraktur, fraktur)
CSS_KEY(from-image, from_image)
diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp
index 556e35406..1525c5f9a 100644
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -1300,7 +1300,7 @@ protected:
}
bool ParseNonNegativeNumber(nsCSSValue& aValue)
{
- return ParseSingleTokenNonNegativeVariant(aValue, VARIANT_NUMBER, nullptr);
+ return ParseSingleTokenNonNegativeVariant(aValue, VARIANT_NUMBER | VARIANT_OPACITY, nullptr);
}
// Helpers for some common ParseSingleTokenOneOrLargerVariant calls.
@@ -1310,7 +1310,7 @@ protected:
}
bool ParseOneOrLargerNumber(nsCSSValue& aValue)
{
- return ParseSingleTokenOneOrLargerVariant(aValue, VARIANT_NUMBER, nullptr);
+ return ParseSingleTokenOneOrLargerVariant(aValue, VARIANT_NUMBER | VARIANT_OPACITY, nullptr);
}
// http://dev.w3.org/csswg/css-values/#custom-idents
@@ -5941,8 +5941,6 @@ CSSParserImpl::ParseAttributeSelector(int32_t& aDataMask,
"language",
"defer",
"type",
- // additional attributes not in HTML4
- "direction", // marquee
nullptr
};
short i = 0;
@@ -7791,6 +7789,7 @@ CSSParserImpl::ParseNonNegativeVariant(nsCSSValue& aValue,
VARIANT_NUMBER |
VARIANT_LENGTH |
VARIANT_PERCENT |
+ VARIANT_OPACITY |
VARIANT_INTEGER)) == 0,
"need to update code below to handle additional variants");
@@ -7831,6 +7830,7 @@ CSSParserImpl::ParseOneOrLargerVariant(nsCSSValue& aValue,
// that we specifically handle.
MOZ_ASSERT((aVariantMask & ~(VARIANT_ALL_NONNUMERIC |
VARIANT_NUMBER |
+ VARIANT_OPACITY |
VARIANT_INTEGER)) == 0,
"need to update code below to handle additional variants");
@@ -7959,9 +7959,9 @@ CSSParserImpl::ParseVariant(nsCSSValue& aValue,
}
}
}
- // Check VARIANT_NUMBER and VARIANT_INTEGER before VARIANT_LENGTH or
- // VARIANT_ZERO_ANGLE.
- if (((aVariantMask & VARIANT_NUMBER) != 0) &&
+ // Check VARIANT_NUMBER, number tokens for VARIANT_OPACITY, and
+ // VARIANT_INTEGER before VARIANT_LENGTH or VARIANT_ZERO_ANGLE.
+ if (((aVariantMask & (VARIANT_NUMBER | VARIANT_OPACITY)) != 0) &&
(eCSSToken_Number == tk->mType)) {
aValue.SetFloatValue(tk->mNumber, eCSSUnit_Number);
return CSSParseResult::Ok;
@@ -7971,6 +7971,7 @@ CSSParserImpl::ParseVariant(nsCSSValue& aValue,
aValue.SetIntValue(tk->mInteger, eCSSUnit_Integer);
return CSSParseResult::Ok;
}
+
if (((aVariantMask & (VARIANT_LENGTH | VARIANT_ANGLE |
VARIANT_FREQUENCY | VARIANT_TIME)) != 0 &&
eCSSToken_Dimension == tk->mType) ||
@@ -7996,6 +7997,15 @@ CSSParserImpl::ParseVariant(nsCSSValue& aValue,
aValue.SetPercentValue(tk->mNumber);
return CSSParseResult::Ok;
}
+ // We need to store eCSSToken_Percentage in eCSSUnit_Number in order to
+ // serialize opacity according to spec. All percentage tokens are stored
+ // as floats, so no type conversion is needed to make this possible.
+ // Percentage tokens have to be evaluated later than number tokens.
+ if (((aVariantMask & VARIANT_OPACITY) != 0) &&
+ (eCSSToken_Percentage == tk->mType)) {
+ aValue.SetFloatValue(tk->mNumber, eCSSUnit_Number);
+ return CSSParseResult::Ok;
+ }
if (mUnitlessLengthQuirk) { // NONSTANDARD: Nav interprets unitless numbers as px
if (((aVariantMask & VARIANT_LENGTH) != 0) &&
(eCSSToken_Number == tk->mType)) {
@@ -8474,7 +8484,7 @@ CSSParserImpl::ParseImageRect(nsCSSValue& aImage)
break;
}
- static const int32_t VARIANT_SIDE = VARIANT_NUMBER | VARIANT_PERCENT;
+ static const int32_t VARIANT_SIDE = VARIANT_NUMBER | VARIANT_PERCENT | VARIANT_OPACITY;
if (!ParseSingleTokenNonNegativeVariant(top, VARIANT_SIDE, nullptr) ||
!ExpectSymbol(',', true) ||
!ParseSingleTokenNonNegativeVariant(right, VARIANT_SIDE, nullptr) ||
@@ -10883,7 +10893,7 @@ CSSParserImpl::ParseWebkitGradientColorStop(nsCSSValueGradient* aGradient)
if (mToken.mIdent.LowerCaseEqualsLiteral("color-stop")) {
// Parse stop location, followed by comma.
if (!ParseSingleTokenVariant(stop->mLocation,
- VARIANT_NUMBER | VARIANT_PERCENT,
+ VARIANT_NUMBER | VARIANT_PERCENT | VARIANT_OPACITY,
nullptr) ||
!ExpectSymbol(',', true)) {
SkipUntil(')'); // Skip to end of color-stop(...) expression.
@@ -15318,17 +15328,17 @@ CSSParserImpl::ParseFontFeatureSettings(nsCSSValue& aValue)
return true;
}
-bool
-CSSParserImpl::ParseFontVariationSettings(nsCSSValue& aValue)
-{
- // TODO: Actually implement this.
-
- // This stub is here because websites insist on considering this
- // very hardware-dependent and O.S.-variable low-level font-control
- // as a "critical feature" which it isn't as there is 0 guarantee
- // that font variation settings are supported or honored by any
- // operating system used by the client.
- return true;
+bool
+CSSParserImpl::ParseFontVariationSettings(nsCSSValue& aValue)
+{
+ // TODO: Actually implement this.
+
+ // This stub is here because websites insist on considering this
+ // very hardware-dependent and O.S.-variable low-level font-control
+ // as a "critical feature" which it isn't as there is 0 guarantee
+ // that font variation settings are supported or honored by any
+ // operating system used by the client.
+ return true;
}
bool
@@ -16046,7 +16056,7 @@ static bool GetFunctionParseInformation(nsCSSKeyword aToken,
{VARIANT_LBCALC, VARIANT_LBCALC, VARIANT_LBCALC},
{VARIANT_ANGLE_OR_ZERO},
{VARIANT_ANGLE_OR_ZERO, VARIANT_ANGLE_OR_ZERO},
- {VARIANT_NUMBER},
+ {VARIANT_NUMBER|VARIANT_OPACITY},
{VARIANT_LENGTH|VARIANT_NONNEGATIVE_DIMENSION},
{VARIANT_LB|VARIANT_NONNEGATIVE_DIMENSION},
{VARIANT_NUMBER, VARIANT_NUMBER},
@@ -17628,7 +17638,7 @@ CSSParserImpl::ParseScrollSnapPoints(nsCSSValue& aValue, nsCSSPropertyID aPropID
nsCSSKeywords::LookupKeyword(mToken.mIdent) == eCSSKeyword_repeat) {
nsCSSValue lengthValue;
if (ParseNonNegativeVariant(lengthValue,
- VARIANT_LENGTH | VARIANT_PERCENT | VARIANT_CALC,
+ VARIANT_LENGTH | VARIANT_PERCENT | VARIANT_OPACITY | VARIANT_CALC,
nullptr) != CSSParseResult::Ok) {
REPORT_UNEXPECTED(PEExpectedNonnegativeNP);
SkipUntil(')');
diff --git a/layout/style/nsCSSPropList.h b/layout/style/nsCSSPropList.h
index f62aa3827..890019245 100644
--- a/layout/style/nsCSSPropList.h
+++ b/layout/style/nsCSSPropList.h
@@ -1703,7 +1703,7 @@ CSS_PROP_SVG(
FillOpacity,
CSS_PROPERTY_PARSE_VALUE,
"",
- VARIANT_HN | VARIANT_OPENTYPE_SVG_KEYWORD,
+ VARIANT_INHERIT | VARIANT_OPACITY | VARIANT_OPENTYPE_SVG_KEYWORD,
kContextOpacityKTable,
offsetof(nsStyleSVG, mFillOpacity),
eStyleAnimType_float)
@@ -1841,7 +1841,7 @@ CSS_PROP_SVGRESET(
FloodOpacity,
CSS_PROPERTY_PARSE_VALUE,
"",
- VARIANT_HN,
+ VARIANT_INHERIT | VARIANT_OPACITY,
nullptr,
offsetof(nsStyleSVGReset, mFloodOpacity),
eStyleAnimType_float)
@@ -3070,7 +3070,7 @@ CSS_PROP_EFFECTS(
CSS_PROPERTY_CAN_ANIMATE_ON_COMPOSITOR |
CSS_PROPERTY_CREATES_STACKING_CONTEXT,
"",
- VARIANT_HN,
+ VARIANT_INHERIT | VARIANT_OPACITY,
nullptr,
offsetof(nsStyleEffects, mOpacity),
eStyleAnimType_float)
@@ -3761,7 +3761,7 @@ CSS_PROP_SVGRESET(
StopOpacity,
CSS_PROPERTY_PARSE_VALUE,
"",
- VARIANT_HN,
+ VARIANT_INHERIT | VARIANT_OPACITY,
nullptr,
offsetof(nsStyleSVGReset, mStopOpacity),
eStyleAnimType_float)
@@ -3836,7 +3836,7 @@ CSS_PROP_SVG(
StrokeOpacity,
CSS_PROPERTY_PARSE_VALUE,
"",
- VARIANT_HN | VARIANT_OPENTYPE_SVG_KEYWORD,
+ VARIANT_INHERIT | VARIANT_OPACITY | VARIANT_OPENTYPE_SVG_KEYWORD,
kContextOpacityKTable,
offsetof(nsStyleSVG, mStrokeOpacity),
eStyleAnimType_float)
diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp
index ac2978c27..24c97cf33 100644
--- a/layout/style/nsCSSProps.cpp
+++ b/layout/style/nsCSSProps.cpp
@@ -1345,6 +1345,9 @@ KTableEntry nsCSSProps::kDisplayKTable[] = {
// The next entry is controlled by the layout.css.display-contents.enabled
// pref.
{ eCSSKeyword_contents, StyleDisplay::Contents },
+ // The next entry is controlled by the layout.css.display-flow-root.enabled
+ // pref.
+ { eCSSKeyword_flow_root, StyleDisplay::FlowRoot },
{ eCSSKeyword_UNKNOWN, -1 }
};
diff --git a/layout/style/nsCSSProps.h b/layout/style/nsCSSProps.h
index aabbac07a..34d457c08 100644
--- a/layout/style/nsCSSProps.h
+++ b/layout/style/nsCSSProps.h
@@ -43,6 +43,7 @@
#define VARIANT_IDENTIFIER 0x002000 // D
#define VARIANT_IDENTIFIER_NO_INHERIT 0x004000 // like above, but excluding
// 'inherit' and 'initial'
+#define VARIANT_OPACITY 0x008000 // Take floats and percents as input, output float.
#define VARIANT_AUTO 0x010000 // A
#define VARIANT_INHERIT 0x020000 // H eCSSUnit_Initial, eCSSUnit_Inherit, eCSSUnit_Unset
#define VARIANT_NONE 0x040000 // O
diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp
index 1a451a2ef..036d97f86 100644
--- a/layout/style/nsRuleNode.cpp
+++ b/layout/style/nsRuleNode.cpp
@@ -250,6 +250,7 @@ nsRuleNode::EnsureBlockDisplay(StyleDisplay& display,
case StyleDisplay::Flex:
case StyleDisplay::WebkitBox:
case StyleDisplay::Grid:
+ case StyleDisplay::FlowRoot:
// do not muck with these at all - already blocks
// This is equivalent to nsStyleDisplay::IsBlockOutside. (XXX Maybe we
// should just call that?)
@@ -293,6 +294,7 @@ nsRuleNode::EnsureInlineDisplay(StyleDisplay& display)
// see if the display value is already inline
switch (display) {
case StyleDisplay::Block:
+ case StyleDisplay::FlowRoot:
display = StyleDisplay::InlineBlock;
break;
case StyleDisplay::Table:
diff --git a/layout/style/nsStyleConsts.h b/layout/style/nsStyleConsts.h
index 6d207aec9..f54387aa8 100644
--- a/layout/style/nsStyleConsts.h
+++ b/layout/style/nsStyleConsts.h
@@ -524,6 +524,7 @@ enum class FillMode : uint32_t;
enum class StyleDisplay : uint8_t {
None = 0,
Block,
+ FlowRoot,
Inline,
InlineBlock,
ListItem,
diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h
index 4bda817dd..f49cdc43e 100644
--- a/layout/style/nsStyleStruct.h
+++ b/layout/style/nsStyleStruct.h
@@ -2890,7 +2890,8 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay
return mozilla::StyleDisplay::Block == mDisplay ||
mozilla::StyleDisplay::ListItem == mDisplay ||
mozilla::StyleDisplay::InlineBlock == mDisplay ||
- mozilla::StyleDisplay::TableCaption == mDisplay;
+ mozilla::StyleDisplay::TableCaption == mDisplay ||
+ mozilla::StyleDisplay::FlowRoot == mDisplay;
// Should TABLE_CELL be included here? They have
// block frames nested inside of them.
// (But please audit all callers before changing.)
@@ -2902,7 +2903,8 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay
mozilla::StyleDisplay::WebkitBox == mDisplay ||
mozilla::StyleDisplay::Grid == mDisplay ||
mozilla::StyleDisplay::ListItem == mDisplay ||
- mozilla::StyleDisplay::Table == mDisplay;
+ mozilla::StyleDisplay::Table == mDisplay ||
+ mozilla::StyleDisplay::FlowRoot == mDisplay;
}
static bool IsDisplayTypeInlineOutside(mozilla::StyleDisplay aDisplay) {
diff --git a/layout/style/res/html.css b/layout/style/res/html.css
index 44e41c8d0..b975bf0c9 100644
--- a/layout/style/res/html.css
+++ b/layout/style/res/html.css
@@ -64,7 +64,6 @@ legend,
li,
listing,
main,
-marquee,
menu,
nav,
noframes,
@@ -819,25 +818,9 @@ dialog:not([open]) {
display: none;
}
-/* emulation of non-standard HTML <marquee> tag */
-marquee {
- inline-size: -moz-available;
- display: inline-block;
- vertical-align: text-bottom;
- text-align: start;
- -moz-binding: url('chrome://xbl-marquee/content/xbl-marquee.xml#marquee-horizontal');
-}
-
-marquee[direction="up"], marquee[direction="down"] {
- -moz-binding: url('chrome://xbl-marquee/content/xbl-marquee.xml#marquee-vertical');
- block-size: 200px;
-}
-
/* PRINT ONLY rules follow */
@media print {
- marquee { -moz-binding: none; }
-
}
/* Ruby */
diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js
index c75f7b498..bc4383630 100644
--- a/layout/style/test/property_database.js
+++ b/layout/style/test/property_database.js
@@ -3540,7 +3540,7 @@ var gCSSProperties = {
inherited: false,
type: CSS_TYPE_LONGHAND,
initial_values: [ "1", "17", "397.376", "3e1", "3e+1", "3e0", "3e+0", "3e-0" ],
- other_values: [ "0", "0.4", "0.0000", "-3", "3e-1" ],
+ other_values: [ "0", "0.4", "0.0000", "-3", "3e-1" "-100%", "50%" ],
invalid_values: [ "0px", "1px" ]
},
"-moz-orient": {
@@ -4272,8 +4272,8 @@ var gCSSProperties = {
domProp: "fillOpacity",
inherited: true,
type: CSS_TYPE_LONGHAND,
- initial_values: [ "1", "2.8", "1.000", "context-fill-opacity", "context-stroke-opacity" ],
- other_values: [ "0", "0.3", "-7.3" ],
+ initial_values: [ "1", "2.8", "1.000", "300%", "context-fill-opacity", "context-stroke-opacity" ],
+ other_values: [ "0", "0.3", "-7.3", "-100%", "50%" ],
invalid_values: []
},
"fill-rule": {
@@ -4305,8 +4305,8 @@ var gCSSProperties = {
domProp: "floodOpacity",
inherited: false,
type: CSS_TYPE_LONGHAND,
- initial_values: [ "1", "2.8", "1.000" ],
- other_values: [ "0", "0.3", "-7.3" ],
+ initial_values: [ "1", "2.8", "1.000", "300%" ],
+ other_values: [ "0", "0.3", "-7.3", "-100%", "50%" ],
invalid_values: []
},
"image-rendering": {
@@ -4380,8 +4380,8 @@ var gCSSProperties = {
domProp: "stopOpacity",
inherited: false,
type: CSS_TYPE_LONGHAND,
- initial_values: [ "1", "2.8", "1.000" ],
- other_values: [ "0", "0.3", "-7.3" ],
+ initial_values: [ "1", "2.8", "1.000", "300%" ],
+ other_values: [ "0", "0.3", "-7.3", "-100%", "50%" ],
invalid_values: []
},
"stroke": {
@@ -4436,8 +4436,8 @@ var gCSSProperties = {
domProp: "strokeOpacity",
inherited: true,
type: CSS_TYPE_LONGHAND,
- initial_values: [ "1", "2.8", "1.000", "context-fill-opacity", "context-stroke-opacity" ],
- other_values: [ "0", "0.3", "-7.3" ],
+ initial_values: [ "1", "2.8", "1.000", "300%", "context-fill-opacity", "context-stroke-opacity" ],
+ other_values: [ "0", "0.3", "-7.3", "-100%", "50% ],
invalid_values: []
},
"stroke-width": {
@@ -7892,6 +7892,10 @@ if (IsCSSPropertyPrefEnabled("layout.css.background-clip-text.enabled")) {
);
}
+if (IsCSSPropertyPrefEnabled("layout.css.display-flow-root.enabled")) {
+ gCSSProperties["display"].other_values.push("flow-root");
+}
+
// Copy aliased properties' fields from their alias targets.
for (var prop in gCSSProperties) {
var entry = gCSSProperties[prop];
diff --git a/layout/style/xbl-marquee/jar.mn b/layout/style/xbl-marquee/jar.mn
deleted file mode 100644
index 9247cb4a1..000000000
--- a/layout/style/xbl-marquee/jar.mn
+++ /dev/null
@@ -1,8 +0,0 @@
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-toolkit.jar:
-% content xbl-marquee %content/xbl-marquee/ contentaccessible=yes
- content/xbl-marquee/xbl-marquee.xml
- content/xbl-marquee/xbl-marquee.css
diff --git a/layout/style/xbl-marquee/moz.build b/layout/style/xbl-marquee/moz.build
deleted file mode 100644
index eb4454d28..000000000
--- a/layout/style/xbl-marquee/moz.build
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-
-JAR_MANIFESTS += ['jar.mn'] \ No newline at end of file
diff --git a/layout/style/xbl-marquee/xbl-marquee.css b/layout/style/xbl-marquee/xbl-marquee.css
deleted file mode 100644
index e6d3ee94b..000000000
--- a/layout/style/xbl-marquee/xbl-marquee.css
+++ /dev/null
@@ -1,12 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* PRINT ONLY rules */
-@media print {
-
- marquee > * > * {
- margin: 0 !important;
- padding: 0 !important;
- } /* This hack is needed until bug 119078 gets fixed */
-}
diff --git a/layout/style/xbl-marquee/xbl-marquee.xml b/layout/style/xbl-marquee/xbl-marquee.xml
deleted file mode 100644
index bb837624d..000000000
--- a/layout/style/xbl-marquee/xbl-marquee.xml
+++ /dev/null
@@ -1,733 +0,0 @@
-<?xml version="1.0"?>
-<!-- This Source Code Form is subject to the terms of the Mozilla Public
- - License, v. 2.0. If a copy of the MPL was not distributed with this
- - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
-
-<bindings id="marqueeBindings"
- xmlns="http://www.mozilla.org/xbl"
- xmlns:html="http://www.w3.org/1999/xhtml"
- xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- xmlns:xbl="http://www.mozilla.org/xbl">
-
-
- <binding id="marquee" bindToUntrustedContent="true">
-
- <resources>
- <stylesheet src="chrome://xbl-marquee/content/xbl-marquee.css"/>
- </resources>
- <implementation>
-
- <property name="scrollAmount" exposeToUntrustedContent="true">
- <getter>
- <![CDATA[
- this._mutationActor(this._mutationObserver.takeRecords());
- return this._scrollAmount;
- ]]>
- </getter>
- <setter>
- <![CDATA[
- var val = parseInt(val);
- if (val < 0) {
- return;
- }
- if (isNaN(val)) {
- val = 0;
- }
- this.setAttribute("scrollamount", val);
- ]]>
- </setter>
- </property>
-
- <property name="scrollDelay" exposeToUntrustedContent="true">
- <getter>
- <![CDATA[
- this._mutationActor(this._mutationObserver.takeRecords());
- var val = parseInt(this.getAttribute("scrolldelay"));
-
- if (val <= 0 || isNaN(val)) {
- return this._scrollDelay;
- }
-
- return val;
- ]]>
- </getter>
- <setter>
- var val = parseInt(val);
- if (val > 0 ) {
- this.setAttribute("scrolldelay", val);
- }
- </setter>
- </property>
-
- <property name="trueSpeed" exposeToUntrustedContent="true">
- <getter>
- <![CDATA[
- if (!this.hasAttribute("truespeed")) {
- return false;
- }
-
- return true;
- ]]>
- </getter>
- <setter>
- <![CDATA[
- if (val) {
- this.setAttribute("truespeed", "");
- } else {
- this.removeAttribute('truespeed');
- }
- ]]>
- </setter>
- </property>
-
- <property name="direction" exposeToUntrustedContent="true">
- <getter>
- this._mutationActor(this._mutationObserver.takeRecords());
- return this._direction;
- </getter>
- <setter>
- <![CDATA[
- if (typeof val == 'string') {
- val = val.toLowerCase();
- } else {
- return;
- }
- if (val != 'left' && val != 'right' && val != 'up' && val != 'down') {
- val = 'left';
- }
-
- this.setAttribute("direction", val);
- ]]>
- </setter>
- </property>
-
- <property name="behavior" exposeToUntrustedContent="true">
- <getter>
- this._mutationActor(this._mutationObserver.takeRecords());
- return this._behavior;
- </getter>
- <setter>
- if (typeof val == 'string') {
- val = val.toLowerCase();
- }
- if (val == "alternate" || val == "slide" || val == 'scroll') {
- this.setAttribute("behavior", val);
- }
- </setter>
- </property>
-
-
- <property name="loop" exposeToUntrustedContent="true">
- <getter>
- <![CDATA[
- this._mutationActor(this._mutationObserver.takeRecords());
- return this._loop;
- ]]>
- </getter>
- <setter>
- <![CDATA[
- var val = parseInt(val);
- if (val == -1 || val > 0) {
- this.setAttribute("loop", val);
- }
- ]]>
- </setter>
- </property>
-
-
- <property name="onstart" exposeToUntrustedContent="true">
- <getter>
- return this.getAttribute("onstart");
- </getter>
- <setter>
- this._setEventListener("start", val, true);
- this.setAttribute("onstart", val);
- </setter>
- </property>
-
- <property name="onfinish" exposeToUntrustedContent="true">
- <getter>
- return this.getAttribute("onfinish");
- </getter>
- <setter>
- this._setEventListener("finish", val, true);
- this.setAttribute("onfinish", val);
- </setter>
- </property>
-
- <property name="onbounce" exposeToUntrustedContent="true">
- <getter>
- return this.getAttribute("onbounce");
- </getter>
- <setter>
- this._setEventListener("bounce", val, true);
- this.setAttribute("onbounce", val);
- </setter>
- </property>
-
- <property name="outerDiv"
- onget="return document.getAnonymousNodes(this)[0]"
- />
-
- <property name="innerDiv"
- onget="return document.getAnonymousElementByAttribute(this, 'class', 'innerDiv');"
- />
-
- <property name="height" exposeToUntrustedContent="true"
- onget="return this.getAttribute('height');"
- onset="this.setAttribute('height', val);"
- />
-
- <property name="width" exposeToUntrustedContent="true"
- onget="return this.getAttribute('width');"
- onset="this.setAttribute('width', val);"
- />
-
- <method name="_set_scrollDelay">
- <parameter name="aValue"/>
- <body>
- <![CDATA[
- aValue = parseInt(aValue);
- if (aValue <= 0) {
- return;
- } else if (isNaN(aValue)) {
- this._scrollDelay = 85;
- } else if (aValue < 60) {
- if (this.trueSpeed == true) {
- this._scrollDelay = aValue;
- } else {
- this._scrollDelay = 60;
- }
- } else {
- this._scrollDelay = aValue;
- }
- ]]>
- </body>
- </method>
-
- <method name="_set_scrollAmount">
- <parameter name="aValue"/>
- <body>
- <![CDATA[
- aValue = parseInt(aValue);
- if (isNaN(aValue)) {
- this._scrollAmount = 6;
- } else if (aValue < 0) {
- return;
- } else {
- this._scrollAmount = aValue;
- }
- ]]>
- </body>
- </method>
-
- <method name="_set_behavior">
- <parameter name="aValue"/>
- <body>
- <![CDATA[
- if (typeof aValue == 'string') {
- aValue = aValue.toLowerCase();
- }
- if (aValue != 'alternate' && aValue != 'slide' && aValue != 'scroll') {
- this._behavior = 'scroll';
- } else {
- this._behavior = aValue;
- }
- ]]>
- </body>
- </method>
-
- <method name="_set_direction">
- <parameter name="aValue"/>
- <body>
- <![CDATA[
- if (typeof aValue == 'string') {
- aValue = aValue.toLowerCase();
- }
- if (aValue != 'left' && aValue != 'right' && aValue != 'up' && aValue != 'down') {
- aValue = 'left';
- }
-
- if (aValue != this._direction) {
- this.startNewDirection = true;
- }
- this._direction = aValue;
- ]]>
- </body>
- </method>
-
- <method name="_set_loop">
- <parameter name="aValue"/>
- <body>
- <![CDATA[
- var aValue = parseInt(aValue);
- if (aValue == 0) {
- return;
- }
- if (isNaN(aValue) || aValue <= -1) {
- aValue = -1;
- }
- this._loop = aValue;
- ]]>
- </body>
- </method>
-
- <method name="_setEventListener">
- <parameter name="aName"/>
- <parameter name="aValue"/>
- <parameter name="aIgnoreNextCall"/>
- <body>
- <![CDATA[
- // _setEventListener is only used for setting the attribute event
- // handlers, which we want to ignore if our document is sandboxed
- // without the allow-scripts keyword.
- if (document.hasScriptsBlockedBySandbox) {
- return true;
- }
-
- // attribute event handlers should only be added if the
- // document's CSP allows it.
- if (!document.inlineScriptAllowedByCSP) {
- return true;
- }
-
- if (this._ignoreNextCall) {
- return this._ignoreNextCall = false;
- }
-
- if (aIgnoreNextCall) {
- this._ignoreNextCall = true;
- }
-
- if (typeof this["_on" + aName] == 'function') {
- this.removeEventListener(aName, this["_on" + aName], false);
- }
-
- switch (typeof aValue)
- {
- case "function":
- this["_on" + aName] = aValue;
- this.addEventListener(aName, this["_on" + aName], false);
- break;
-
- case "string":
- if (!aIgnoreNextCall) {
- try {
- // Function Xrays make this simple and safe. \o/
- this["_on" + aName] = new window.Function("event", aValue);
- }
- catch(e) {
- return false;
- }
- this.addEventListener(aName, this["_on" + aName], false);
- }
- else {
- this["_on" + aName] = aValue;
- }
- break;
-
- case "object":
- this["_on" + aName] = aValue;
- break;
-
- default:
- this._ignoreNextCall = false;
- throw new Error("Invalid argument for Marquee::on" + aName);
- }
- return true;
- ]]>
- </body>
- </method>
-
- <method name="_fireEvent">
- <parameter name="aName"/>
- <parameter name="aBubbles"/>
- <parameter name="aCancelable"/>
- <body>
- <![CDATA[
- var e = document.createEvent("Events");
- e.initEvent(aName, aBubbles, aCancelable);
- this.dispatchEvent(e);
- ]]>
- </body>
- </method>
-
- <method name="start" exposeToUntrustedContent="true">
- <body>
- <![CDATA[
- if (this.runId == 0) {
- var myThis = this;
- var lambda = function myTimeOutFunction(){myThis._doMove(false);}
- this.runId = window.setTimeout(lambda, this._scrollDelay - this._deltaStartStop);
- this._deltaStartStop = 0;
- }
- ]]>
- </body>
- </method>
-
- <method name="stop" exposeToUntrustedContent="true">
- <body>
- <![CDATA[
- if (this.runId != 0) {
- this._deltaStartStop = Date.now()- this._lastMoveDate;
- clearTimeout(this.runId);
- }
-
- this.runId = 0;
- ]]>
- </body>
- </method>
-
- <method name="_doMove">
- <parameter name="aResetPosition"/>
- <body>
- <![CDATA[
- this._lastMoveDate = Date.now();
-
- //startNewDirection is true at first load and whenever the direction is changed
- if (this.startNewDirection) {
- this.startNewDirection = false; //we only want this to run once every scroll direction change
-
- var corrvalue = 0;
-
- switch (this._direction)
- {
- case "up":
- var height = document.defaultView.getComputedStyle(this, "").height;
- this.outerDiv.style.height = height;
- if (this.originalHeight > this.outerDiv.offsetHeight) {
- corrvalue = this.originalHeight - this.outerDiv.offsetHeight;
- }
- this.innerDiv.style.padding = height + " 0";
- this.dirsign = 1;
- this.startAt = (this._behavior == 'alternate') ? (this.originalHeight - corrvalue) : 0;
- this.stopAt = (this._behavior == 'alternate' || this._behavior == 'slide') ?
- (parseInt(height) + corrvalue) : (this.originalHeight + parseInt(height));
- break;
-
- case "down":
- var height = document.defaultView.getComputedStyle(this, "").height;
- this.outerDiv.style.height = height;
- if (this.originalHeight > this.outerDiv.offsetHeight) {
- corrvalue = this.originalHeight - this.outerDiv.offsetHeight;
- }
- this.innerDiv.style.padding = height + " 0";
- this.dirsign = -1;
- this.startAt = (this._behavior == 'alternate') ?
- (parseInt(height) + corrvalue) : (this.originalHeight + parseInt(height));
- this.stopAt = (this._behavior == 'alternate' || this._behavior == 'slide') ?
- (this.originalHeight - corrvalue) : 0;
- break;
-
- case "right":
- if (this.innerDiv.offsetWidth > this.outerDiv.offsetWidth) {
- corrvalue = this.innerDiv.offsetWidth - this.outerDiv.offsetWidth;
- }
- this.dirsign = -1;
- this.stopAt = (this._behavior == 'alternate' || this._behavior == 'slide') ?
- (this.innerDiv.offsetWidth - corrvalue) : 0;
- this.startAt = this.outerDiv.offsetWidth + ((this._behavior == 'alternate') ?
- corrvalue : (this.innerDiv.offsetWidth + this.stopAt));
- break;
-
- case "left":
- default:
- if (this.innerDiv.offsetWidth > this.outerDiv.offsetWidth) {
- corrvalue = this.innerDiv.offsetWidth - this.outerDiv.offsetWidth;
- }
- this.dirsign = 1;
- this.startAt = (this._behavior == 'alternate') ? (this.innerDiv.offsetWidth - corrvalue) : 0;
- this.stopAt = this.outerDiv.offsetWidth +
- ((this._behavior == 'alternate' || this._behavior == 'slide') ?
- corrvalue : (this.innerDiv.offsetWidth + this.startAt));
- }
-
- if (aResetPosition) {
- this.newPosition = this.startAt;
- this._fireEvent("start", false, false);
- }
- } //end if
-
- this.newPosition = this.newPosition + (this.dirsign * this._scrollAmount);
-
- if ((this.dirsign == 1 && this.newPosition > this.stopAt) ||
- (this.dirsign == -1 && this.newPosition < this.stopAt))
- {
- switch (this._behavior)
- {
- case 'alternate':
- // lets start afresh
- this.startNewDirection = true;
-
- // swap direction
- const swap = {left: "right", down: "up", up: "down", right: "left"};
- this._direction = swap[this._direction];
- this.newPosition = this.stopAt;
-
- if ((this._direction == "up") || (this._direction == "down")) {
- this.outerDiv.scrollTop = this.newPosition;
- } else {
- this.outerDiv.scrollLeft = this.newPosition;
- }
-
- if (this._loop != 1) {
- this._fireEvent("bounce", false, true);
- }
- break;
-
- case 'slide':
- if (this._loop > 1) {
- this.newPosition = this.startAt;
- }
- break;
-
- default:
- this.newPosition = this.startAt;
-
- if ((this._direction == "up") || (this._direction == "down")) {
- this.outerDiv.scrollTop = this.newPosition;
- } else {
- this.outerDiv.scrollLeft = this.newPosition;
- }
-
- //dispatch start event, even when this._loop == 1, comp. with IE6
- this._fireEvent("start", false, false);
- }
-
- if (this._loop > 1) {
- this._loop--;
- } else if (this._loop == 1) {
- if ((this._direction == "up") || (this._direction == "down")) {
- this.outerDiv.scrollTop = this.stopAt;
- } else {
- this.outerDiv.scrollLeft = this.stopAt;
- }
- this.stop();
- this._fireEvent("finish", false, true);
- return;
- }
- }
- else {
- if ((this._direction == "up") || (this._direction == "down")) {
- this.outerDiv.scrollTop = this.newPosition;
- } else {
- this.outerDiv.scrollLeft = this.newPosition;
- }
- }
-
- var myThis = this;
- var lambda = function myTimeOutFunction(){myThis._doMove(false);}
- this.runId = window.setTimeout(lambda, this._scrollDelay);
- ]]>
- </body>
- </method>
-
- <method name="init">
- <body>
- <![CDATA[
- this.stop();
-
- if ((this._direction != "up") && (this._direction != "down")) {
- var width = window.getComputedStyle(this, "").width;
- this.innerDiv.parentNode.style.margin = '0 ' + width;
-
- //XXX Adding the margin sometimes causes the marquee to widen,
- // see testcase from bug bug 364434:
- // https://bugzilla.mozilla.org/attachment.cgi?id=249233
- // Just add a fixed width with current marquee's width for now
- if (width != window.getComputedStyle(this, "").width) {
- var width = window.getComputedStyle(this, "").width;
- this.outerDiv.style.width = width;
- this.innerDiv.parentNode.style.margin = '0 ' + width;
- }
- }
- else {
- // store the original height before we add padding
- this.innerDiv.style.padding = 0;
- this.originalHeight = this.innerDiv.offsetHeight;
- }
-
- this._doMove(true);
- ]]>
- </body>
- </method>
-
- <method name="_mutationActor">
- <parameter name="aMutations"/>
- <body>
- <![CDATA[
- while (aMutations.length > 0) {
- var mutation = aMutations.shift();
- var attrName = mutation.attributeName.toLowerCase();
- var oldValue = mutation.oldValue;
- var target = mutation.target;
- var newValue = target.getAttribute(attrName);
-
- if (oldValue != newValue) {
- switch (attrName) {
- case "loop":
- target._set_loop(newValue);
- if (target.rundId == 0) {
- target.start();
- }
- break;
- case "scrollamount":
- target._set_scrollAmount(newValue);
- break;
- case "scrolldelay":
- target._set_scrollDelay(newValue);
- target.stop();
- target.start();
- break;
- case "truespeed":
- //needed to update target._scrollDelay
- var myThis = target;
- var lambda = function() {myThis._set_scrollDelay(myThis.getAttribute('scrolldelay'));}
- window.setTimeout(lambda, 0);
- break;
- case "behavior":
- target._set_behavior(newValue);
- target.startNewDirection = true;
- if ((oldValue == "slide" && target.newPosition == target.stopAt) ||
- newValue == "alternate" || newValue == "slide") {
- target.stop();
- target._doMove(true);
- }
- break;
- case "direction":
- if (!newValue) {
- newValue = "left";
- }
- target._set_direction(newValue);
- break;
- case "width":
- case "height":
- target.startNewDirection = true;
- break;
- case "onstart":
- target._setEventListener("start", newValue);
- break;
- case "onfinish":
- target._setEventListener("finish", newValue);
- break;
- case "onbounce":
- target._setEventListener("bounce", newValue);
- break;
- }
- }
- }
- ]]>
- </body>
- </method>
-
- <constructor>
- <![CDATA[
- // Set up state.
- this._scrollAmount = 6;
- this._scrollDelay = 85;
- this._direction = "left";
- this._behavior = "scroll";
- this._loop = -1;
- this.dirsign = 1;
- this.startAt = 0;
- this.stopAt = 0;
- this.newPosition = 0;
- this.runId = 0;
- this.originalHeight = 0;
- this.startNewDirection = true;
-
- // hack needed to fix js error, see bug 386470
- var myThis = this;
- var lambda = function myScopeFunction() { if (myThis.init) myThis.init(); }
-
- this._set_direction(this.getAttribute('direction'));
- this._set_behavior(this.getAttribute('behavior'));
- this._set_scrollDelay(this.getAttribute('scrolldelay'));
- this._set_scrollAmount(this.getAttribute('scrollamount'));
- this._set_loop(this.getAttribute('loop'));
- this._setEventListener("start", this.getAttribute("onstart"));
- this._setEventListener("finish", this.getAttribute("onfinish"));
- this._setEventListener("bounce", this.getAttribute("onbounce"));
- this.startNewDirection = true;
-
- this._mutationObserver = new MutationObserver(this._mutationActor);
- this._mutationObserver.observe(this, { attributes: true,
- attributeOldValue: true,
- attributeFilter: ['loop', 'scrollamount', 'scrolldelay', '', 'truespeed', 'behavior',
- 'direction', 'width', 'height', 'onstart', 'onfinish', 'onbounce'] });
-
- // init needs to be run after the page has loaded in order to calculate
- // the correct height/width
- if (document.readyState == "complete") {
- lambda();
- } else {
- window.addEventListener("load", lambda, false);
- }
- ]]>
- </constructor>
- </implementation>
-
- </binding>
-
- <binding id="marquee-horizontal" bindToUntrustedContent="true"
- extends="chrome://xbl-marquee/content/xbl-marquee.xml#marquee"
- inheritstyle="false">
-
- <!-- White-space isn't allowed because a marquee could be
- inside 'white-space: pre' -->
- <content>
- <html:div style="display: -moz-box; overflow: hidden; width: -moz-available;"
- ><html:div style="display: -moz-box;"
- ><html:div class="innerDiv" style="display: table; border-spacing: 0;"
- ><html:div
- ><children
- /></html:div
- ></html:div
- ></html:div
- ></html:div>
- </content>
-
- </binding>
-
- <binding id="marquee-vertical" bindToUntrustedContent="true"
- extends="chrome://xbl-marquee/content/xbl-marquee.xml#marquee"
- inheritstyle="false">
-
- <!-- White-space isn't allowed because a marquee could be
- inside 'white-space: pre' -->
- <content>
- <html:div style="overflow: hidden; width: -moz-available;"
- ><html:div class="innerDiv"
- ><children
- /></html:div
- ></html:div>
- </content>
-
- </binding>
-
- <binding id="marquee-horizontal-editable" bindToUntrustedContent="true"
- inheritstyle="false">
-
- <!-- White-space isn't allowed because a marquee could be
- inside 'white-space: pre' -->
- <content>
- <html:div style="display: inline-block; overflow: auto; width: -moz-available;"
- ><children
- /></html:div>
- </content>
-
- </binding>
-
- <binding id="marquee-vertical-editable" bindToUntrustedContent="true"
- inheritstyle="false">
-
- <!-- White-space isn't allowed because a marquee could be
- inside 'white-space: pre' -->
- <content>
- <html:div style="overflow: auto; height: inherit; width: -moz-available;"
- ><children/></html:div>
- </content>
-
- </binding>
-
-</bindings>