summaryrefslogtreecommitdiffstats
path: root/dom/base/nsStyledElement.cpp
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /dom/base/nsStyledElement.cpp
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'dom/base/nsStyledElement.cpp')
-rw-r--r--dom/base/nsStyledElement.cpp197
1 files changed, 197 insertions, 0 deletions
diff --git a/dom/base/nsStyledElement.cpp b/dom/base/nsStyledElement.cpp
new file mode 100644
index 000000000..03d1187ab
--- /dev/null
+++ b/dom/base/nsStyledElement.cpp
@@ -0,0 +1,197 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#include "nsStyledElement.h"
+#include "nsGkAtoms.h"
+#include "nsAttrValue.h"
+#include "nsAttrValueInlines.h"
+#include "mozilla/dom/ElementInlines.h"
+#include "mozilla/InternalMutationEvent.h"
+#include "nsDOMCSSDeclaration.h"
+#include "nsDOMCSSAttrDeclaration.h"
+#include "nsServiceManagerUtils.h"
+#include "nsIDocument.h"
+#include "mozilla/DeclarationBlockInlines.h"
+#include "nsCSSParser.h"
+#include "mozilla/css/Loader.h"
+#include "nsIDOMMutationEvent.h"
+#include "nsXULElement.h"
+#include "nsContentUtils.h"
+#include "nsStyleUtil.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+NS_IMPL_QUERY_INTERFACE_INHERITED(nsStyledElement,
+ nsStyledElementBase,
+ nsStyledElement)
+
+//----------------------------------------------------------------------
+// nsIContent methods
+
+bool
+nsStyledElement::ParseAttribute(int32_t aNamespaceID,
+ nsIAtom* aAttribute,
+ const nsAString& aValue,
+ nsAttrValue& aResult)
+{
+ if (aAttribute == nsGkAtoms::style && aNamespaceID == kNameSpaceID_None) {
+ SetMayHaveStyle();
+ ParseStyleAttribute(aValue, aResult, false);
+ return true;
+ }
+
+ return nsStyledElementBase::ParseAttribute(aNamespaceID, aAttribute, aValue,
+ aResult);
+}
+
+nsresult
+nsStyledElement::SetInlineStyleDeclaration(DeclarationBlock* aDeclaration,
+ const nsAString* aSerialized,
+ bool aNotify)
+{
+ SetMayHaveStyle();
+ bool modification = false;
+ nsAttrValue oldValue;
+
+ bool hasListeners = aNotify &&
+ nsContentUtils::HasMutationListeners(this,
+ NS_EVENT_BITS_MUTATION_ATTRMODIFIED,
+ this);
+
+ // There's no point in comparing the stylerule pointers since we're always
+ // getting a new stylerule here. And we can't compare the stringvalues of
+ // the old and the new rules since both will point to the same declaration
+ // and thus will be the same.
+ if (hasListeners) {
+ // save the old attribute so we can set up the mutation event properly
+ // XXXbz if the old rule points to the same declaration as the new one,
+ // this is getting the new attr value, not the old one....
+ nsAutoString oldValueStr;
+ modification = GetAttr(kNameSpaceID_None, nsGkAtoms::style,
+ oldValueStr);
+ if (modification) {
+ oldValue.SetTo(oldValueStr);
+ }
+ }
+ else if (aNotify && IsInUncomposedDoc()) {
+ modification = !!mAttrsAndChildren.GetAttr(nsGkAtoms::style);
+ }
+
+ nsAttrValue attrValue(do_AddRef(aDeclaration), aSerialized);
+
+ // XXXbz do we ever end up with ADDITION here? I doubt it.
+ uint8_t modType = modification ?
+ static_cast<uint8_t>(nsIDOMMutationEvent::MODIFICATION) :
+ static_cast<uint8_t>(nsIDOMMutationEvent::ADDITION);
+
+ return SetAttrAndNotify(kNameSpaceID_None, nsGkAtoms::style, nullptr,
+ oldValue, attrValue, modType, hasListeners,
+ aNotify, kDontCallAfterSetAttr);
+}
+
+DeclarationBlock*
+nsStyledElement::GetInlineStyleDeclaration()
+{
+ if (!MayHaveStyle()) {
+ return nullptr;
+ }
+ const nsAttrValue* attrVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style);
+
+ if (attrVal && attrVal->Type() == nsAttrValue::eCSSDeclaration) {
+ return attrVal->GetCSSDeclarationValue();
+ }
+
+ return nullptr;
+}
+
+// ---------------------------------------------------------------
+// Others and helpers
+
+nsICSSDeclaration*
+nsStyledElement::Style()
+{
+ Element::nsDOMSlots *slots = DOMSlots();
+
+ if (!slots->mStyle) {
+ // Just in case...
+ ReparseStyleAttribute(true);
+
+ slots->mStyle = new nsDOMCSSAttributeDeclaration(this, false);
+ SetMayHaveStyle();
+ }
+
+ return slots->mStyle;
+}
+
+nsresult
+nsStyledElement::ReparseStyleAttribute(bool aForceInDataDoc)
+{
+ if (!MayHaveStyle()) {
+ return NS_OK;
+ }
+ const nsAttrValue* oldVal = mAttrsAndChildren.GetAttr(nsGkAtoms::style);
+ if (oldVal && oldVal->Type() != nsAttrValue::eCSSDeclaration) {
+ nsAttrValue attrValue;
+ nsAutoString stringValue;
+ oldVal->ToString(stringValue);
+ ParseStyleAttribute(stringValue, attrValue, aForceInDataDoc);
+ // Don't bother going through SetInlineStyleDeclaration; we don't
+ // want to fire off mutation events or document notifications anyway
+ nsresult rv = mAttrsAndChildren.SetAndSwapAttr(nsGkAtoms::style, attrValue);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+}
+
+nsICSSDeclaration*
+nsStyledElement::GetExistingStyle()
+{
+ Element::nsDOMSlots* slots = GetExistingDOMSlots();
+ if (!slots) {
+ return nullptr;
+ }
+
+ return slots->mStyle;
+}
+
+void
+nsStyledElement::ParseStyleAttribute(const nsAString& aValue,
+ nsAttrValue& aResult,
+ bool aForceInDataDoc)
+{
+ nsIDocument* doc = OwnerDoc();
+ bool isNativeAnon = IsInNativeAnonymousSubtree();
+
+ if (!isNativeAnon &&
+ !nsStyleUtil::CSPAllowsInlineStyle(nullptr, NodePrincipal(),
+ doc->GetDocumentURI(), 0, aValue,
+ nullptr))
+ return;
+
+ if (aForceInDataDoc ||
+ !doc->IsLoadedAsData() ||
+ GetExistingStyle() ||
+ doc->IsStaticDocument()) {
+ bool isCSS = true; // assume CSS until proven otherwise
+
+ if (!isNativeAnon) { // native anonymous content always assumes CSS
+ nsAutoString styleType;
+ doc->GetHeaderData(nsGkAtoms::headerContentStyleType, styleType);
+ if (!styleType.IsEmpty()) {
+ static const char textCssStr[] = "text/css";
+ isCSS = (styleType.EqualsIgnoreCase(textCssStr, sizeof(textCssStr) - 1));
+ }
+ }
+
+ if (isCSS && aResult.ParseStyleAttribute(aValue, this)) {
+ return;
+ }
+ }
+
+ aResult.SetTo(aValue);
+}