mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
212144c57f
- Bug 1153936 - nsIHttpChannelInteral attribute to opt out of alt-svc on per channel basis r=hurley (0e5667321) - Bug 1137287 - Part 2: Send non-200/404 synthesized responses via the parent HTTP implementation for proper processing. r=mayhemer (3c38a1908) - Bug 1137287 - Part 0: Test for synthesized redirects. r=jdm (6f12f95de) - Bug 1137287 - Build fix. rs=KWierso for a CLOSED TREE (85694256a) - Bug 1095098 - move do_QueryObject templates into their own header; r=froydnj (5d349c248) - Bug 1095098 - followup - add back some static analysis attributes lost in a rebase; r=me (917a6b5da) - Bug 1159303 - Reduce noise due to sort operations warnings. r=bent (cac3c3e12) - Bug 1164559 - Part 1: Remove instances of #ifdef PR_LOGGING in storage. r=froydnj (5dd0f92b0) - Bug 1164559 - Part 2: Wrap expensive calls in PR_LOG_TEST. r=froydnj (54e94d1ce) - Bug 1148833 part 1 - Remove nsMathMLContainerFrame::WillReflow, reset the NS_MATHML_ERROR bit at the start of Reflow instead. r=roc (803abb8d9) - Bug 1148833 part 2 - Makes sure gLogModule is initialized by calling GetLogModuleInfo(). r=roc (722e2019d) - Bug 1148833 part 3 - Remove nsIFrame::WillReflow and add a non-virtual MarkInReflow method instead that sets NS_FRAME_IN_REFLOW. Call it at the start of Reflow(). r=roc (9cceb221d) - Bug 1148833 part 4 - Fix indentation of some Reflow params (white-space changes only). (b2ba3e18a) - Bug 1158546 - Remove nsDisplayHeaderFooter::mFrame in favor of nsDisplayItem::mFrame; r=roc (f6a20967f) - Bug 1162673 - Part 1: Remove instances of #ifdef PR_LOGGING in layout. r=froydnj (453a452fc) - Bug 1162673 - Part 2: Wrap expensive calls in PR_LOG_TEST. r=froydnj (d745eab19) - Bug 1144031 - fix use of uninitialized variable, r=mcmanus (327dc1af9) - Bug 1144270 : Update remaining callers of newChannel to newChannel2 in netwerk/ (r=mcmanus) (60c21d7cb) - Bug 1161558 cleanup some nsIObserver shutdown paths r=bagder (eb8441bb9) - Bug 1162336 - Part 1: Remove instances of #ifdef PR_LOGGING in netwerk. r=froydnj (8cadc40a2) - Bug 1162336 - Part 2: Wrap expensive calls in PR_LOG_TEST. r=froydnj (4e26e4886) - Bug 1163194 - Part 1: Remove instances of #ifdef PR_LOGGING in dom/xul. r=froydnj (4f840564b) - Bug 1163194 - Part 2: Wrap expensive calls in PR_LOG_TEST. r=froydnj (653707f34) - Bug 1153737: Avoid unnecessary uses of mozilla::pkix::ScopedPtr, r=keeler (fd9eb9aa2) - Bug 1038072 - signature verification for JAR files unpacked into a directory. r=keeler (32469e1dd) - Bug 1124076 - Properly detect certs when loaded and prompt to import them. r=sworkman/dkeeler (d860e3cac) - Bug 1124076 followup - fix the build when PR_LOGGING is not defined. r=mrbkap (657b18bf2) - Bug 1162691 - Part 1: Remove instances of #ifdef PR_LOGGING in security. r=froydnj (98a916e82) - Bug 1162691 - Part 2: Wrap expensive calls in PR_LOG_TEST. r=froydnj (000c2fe42) - bug 1147085 - remove nsINSSCertCache (replace it with nsIX509CertDB.getCerts()) r=Cykesiopka (88f7eba23) - Bug 1149888 - Make PLDHashTable::mRecursionLevel atomic, r=froydnj. Pushing on CLOSED TREE with a=ryanvm. (25d8e2da1) - Bug 1050035 (part 1, attempt 2) - Lazily allocate PLDHashTable::mEntryStore. r=froydnj. (195615f16) - Bug 1159972 - Remove the fallible version of PL_DHashTableInit(). r=froydnj. (d31806eeb)
456 lines
14 KiB
C++
456 lines
14 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* 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/. */
|
|
|
|
/* base class for DOM objects for element.style and cssStyleRule.style */
|
|
|
|
#include "nsDOMCSSDeclaration.h"
|
|
|
|
#include "nsCSSParser.h"
|
|
#include "mozilla/CSSStyleSheet.h"
|
|
#include "mozilla/css/Rule.h"
|
|
#include "mozilla/css/Declaration.h"
|
|
#include "mozilla/dom/CSS2PropertiesBinding.h"
|
|
#include "nsCSSProps.h"
|
|
#include "nsCOMPtr.h"
|
|
#include "mozAutoDocUpdate.h"
|
|
#include "nsIURI.h"
|
|
#include "mozilla/dom/BindingUtils.h"
|
|
#include "nsContentUtils.h"
|
|
#include "nsQueryObject.h"
|
|
|
|
using namespace mozilla;
|
|
|
|
nsDOMCSSDeclaration::~nsDOMCSSDeclaration()
|
|
{
|
|
}
|
|
|
|
/* virtual */ JSObject*
|
|
nsDOMCSSDeclaration::WrapObject(JSContext* aCx, JS::Handle<JSObject*> aGivenProto)
|
|
{
|
|
return dom::CSS2PropertiesBinding::Wrap(aCx, this, aGivenProto);
|
|
}
|
|
|
|
NS_INTERFACE_TABLE_HEAD(nsDOMCSSDeclaration)
|
|
NS_INTERFACE_TABLE(nsDOMCSSDeclaration,
|
|
nsICSSDeclaration,
|
|
nsIDOMCSSStyleDeclaration)
|
|
NS_INTERFACE_TABLE_TO_MAP_SEGUE
|
|
NS_INTERFACE_MAP_END
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMCSSDeclaration::GetPropertyValue(const nsCSSProperty aPropID,
|
|
nsAString& aValue)
|
|
{
|
|
NS_PRECONDITION(aPropID != eCSSProperty_UNKNOWN,
|
|
"Should never pass eCSSProperty_UNKNOWN around");
|
|
|
|
css::Declaration* decl = GetCSSDeclaration(false);
|
|
|
|
aValue.Truncate();
|
|
if (decl) {
|
|
decl->GetValue(aPropID, aValue);
|
|
}
|
|
return NS_OK;
|
|
}
|
|
|
|
void
|
|
nsDOMCSSDeclaration::GetCustomPropertyValue(const nsAString& aPropertyName,
|
|
nsAString& aValue)
|
|
{
|
|
MOZ_ASSERT(Substring(aPropertyName, 0,
|
|
CSS_CUSTOM_NAME_PREFIX_LENGTH).EqualsLiteral("--"));
|
|
|
|
css::Declaration* decl = GetCSSDeclaration(false);
|
|
if (!decl) {
|
|
aValue.Truncate();
|
|
return;
|
|
}
|
|
|
|
decl->GetVariableDeclaration(Substring(aPropertyName,
|
|
CSS_CUSTOM_NAME_PREFIX_LENGTH),
|
|
aValue);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMCSSDeclaration::SetPropertyValue(const nsCSSProperty aPropID,
|
|
const nsAString& aValue)
|
|
{
|
|
if (aValue.IsEmpty()) {
|
|
// If the new value of the property is an empty string we remove the
|
|
// property.
|
|
return RemoveProperty(aPropID);
|
|
}
|
|
|
|
return ParsePropertyValue(aPropID, aValue, false);
|
|
}
|
|
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMCSSDeclaration::GetCssText(nsAString& aCssText)
|
|
{
|
|
css::Declaration* decl = GetCSSDeclaration(false);
|
|
aCssText.Truncate();
|
|
|
|
if (decl) {
|
|
decl->ToString(aCssText);
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMCSSDeclaration::SetCssText(const nsAString& aCssText)
|
|
{
|
|
// We don't need to *do* anything with the old declaration, but we need
|
|
// to ensure that it exists, or else SetCSSDeclaration may crash.
|
|
css::Declaration* olddecl = GetCSSDeclaration(true);
|
|
if (!olddecl) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
CSSParsingEnvironment env;
|
|
GetCSSParsingEnvironment(env);
|
|
if (!env.mPrincipal) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
// For nsDOMCSSAttributeDeclaration, SetCSSDeclaration will lead to
|
|
// Attribute setting code, which leads in turn to BeginUpdate. We
|
|
// need to start the update now so that the old rule doesn't get used
|
|
// between when we mutate the declaration and when we set the new
|
|
// rule (see stack in bug 209575).
|
|
mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
|
|
|
|
nsAutoPtr<css::Declaration> decl(new css::Declaration());
|
|
decl->InitializeEmpty();
|
|
nsCSSParser cssParser(env.mCSSLoader);
|
|
bool changed;
|
|
nsresult result = cssParser.ParseDeclarations(aCssText, env.mSheetURI,
|
|
env.mBaseURI,
|
|
env.mPrincipal, decl, &changed);
|
|
if (NS_FAILED(result) || !changed) {
|
|
return result;
|
|
}
|
|
|
|
return SetCSSDeclaration(decl.forget());
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMCSSDeclaration::GetLength(uint32_t* aLength)
|
|
{
|
|
css::Declaration* decl = GetCSSDeclaration(false);
|
|
|
|
if (decl) {
|
|
*aLength = decl->Count();
|
|
} else {
|
|
*aLength = 0;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
already_AddRefed<dom::CSSValue>
|
|
nsDOMCSSDeclaration::GetPropertyCSSValue(const nsAString& aPropertyName, ErrorResult& aRv)
|
|
{
|
|
// We don't support CSSValue yet so we'll just return null...
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
void
|
|
nsDOMCSSDeclaration::IndexedGetter(uint32_t aIndex, bool& aFound, nsAString& aPropName)
|
|
{
|
|
css::Declaration* decl = GetCSSDeclaration(false);
|
|
aFound = decl && decl->GetNthProperty(aIndex, aPropName);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMCSSDeclaration::GetPropertyValue(const nsAString& aPropertyName,
|
|
nsAString& aReturn)
|
|
{
|
|
const nsCSSProperty propID =
|
|
nsCSSProps::LookupProperty(aPropertyName,
|
|
nsCSSProps::eEnabledForAllContent);
|
|
if (propID == eCSSProperty_UNKNOWN) {
|
|
aReturn.Truncate();
|
|
return NS_OK;
|
|
}
|
|
|
|
if (propID == eCSSPropertyExtra_variable) {
|
|
GetCustomPropertyValue(aPropertyName, aReturn);
|
|
return NS_OK;
|
|
}
|
|
|
|
return GetPropertyValue(propID, aReturn);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMCSSDeclaration::GetAuthoredPropertyValue(const nsAString& aPropertyName,
|
|
nsAString& aReturn)
|
|
{
|
|
const nsCSSProperty propID =
|
|
nsCSSProps::LookupProperty(aPropertyName,
|
|
nsCSSProps::eEnabledForAllContent);
|
|
if (propID == eCSSProperty_UNKNOWN) {
|
|
aReturn.Truncate();
|
|
return NS_OK;
|
|
}
|
|
|
|
if (propID == eCSSPropertyExtra_variable) {
|
|
GetCustomPropertyValue(aPropertyName, aReturn);
|
|
return NS_OK;
|
|
}
|
|
|
|
css::Declaration* decl = GetCSSDeclaration(false);
|
|
if (!decl) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
decl->GetAuthoredValue(propID, aReturn);
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMCSSDeclaration::GetPropertyPriority(const nsAString& aPropertyName,
|
|
nsAString& aReturn)
|
|
{
|
|
css::Declaration* decl = GetCSSDeclaration(false);
|
|
|
|
aReturn.Truncate();
|
|
if (decl && decl->GetValueIsImportant(aPropertyName)) {
|
|
aReturn.AssignLiteral("important");
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMCSSDeclaration::SetProperty(const nsAString& aPropertyName,
|
|
const nsAString& aValue,
|
|
const nsAString& aPriority)
|
|
{
|
|
// In the common (and fast) cases we can use the property id
|
|
nsCSSProperty propID =
|
|
nsCSSProps::LookupProperty(aPropertyName,
|
|
nsCSSProps::eEnabledForAllContent);
|
|
if (propID == eCSSProperty_UNKNOWN) {
|
|
return NS_OK;
|
|
}
|
|
|
|
if (aValue.IsEmpty()) {
|
|
// If the new value of the property is an empty string we remove the
|
|
// property.
|
|
// XXX this ignores the priority string, should it?
|
|
if (propID == eCSSPropertyExtra_variable) {
|
|
return RemoveCustomProperty(aPropertyName);
|
|
}
|
|
return RemoveProperty(propID);
|
|
}
|
|
|
|
bool important;
|
|
if (aPriority.IsEmpty()) {
|
|
important = false;
|
|
} else if (aPriority.EqualsLiteral("important")) {
|
|
important = true;
|
|
} else {
|
|
// XXX silent failure?
|
|
return NS_OK;
|
|
}
|
|
|
|
if (propID == eCSSPropertyExtra_variable) {
|
|
return ParseCustomPropertyValue(aPropertyName, aValue, important);
|
|
}
|
|
return ParsePropertyValue(propID, aValue, important);
|
|
}
|
|
|
|
NS_IMETHODIMP
|
|
nsDOMCSSDeclaration::RemoveProperty(const nsAString& aPropertyName,
|
|
nsAString& aReturn)
|
|
{
|
|
const nsCSSProperty propID =
|
|
nsCSSProps::LookupProperty(aPropertyName,
|
|
nsCSSProps::eEnabledForAllContent);
|
|
if (propID == eCSSProperty_UNKNOWN) {
|
|
aReturn.Truncate();
|
|
return NS_OK;
|
|
}
|
|
|
|
if (propID == eCSSPropertyExtra_variable) {
|
|
RemoveCustomProperty(aPropertyName);
|
|
return NS_OK;
|
|
}
|
|
|
|
nsresult rv = GetPropertyValue(propID, aReturn);
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
|
|
|
return RemoveProperty(propID);
|
|
}
|
|
|
|
/* static */ void
|
|
nsDOMCSSDeclaration::GetCSSParsingEnvironmentForRule(css::Rule* aRule,
|
|
CSSParsingEnvironment& aCSSParseEnv)
|
|
{
|
|
nsIStyleSheet* sheet = aRule ? aRule->GetStyleSheet() : nullptr;
|
|
nsRefPtr<CSSStyleSheet> cssSheet(do_QueryObject(sheet));
|
|
if (!cssSheet) {
|
|
aCSSParseEnv.mPrincipal = nullptr;
|
|
return;
|
|
}
|
|
|
|
nsIDocument* document = sheet->GetOwningDocument();
|
|
aCSSParseEnv.mSheetURI = sheet->GetSheetURI();
|
|
aCSSParseEnv.mBaseURI = sheet->GetBaseURI();
|
|
aCSSParseEnv.mPrincipal = cssSheet->Principal();
|
|
aCSSParseEnv.mCSSLoader = document ? document->CSSLoader() : nullptr;
|
|
}
|
|
|
|
nsresult
|
|
nsDOMCSSDeclaration::ParsePropertyValue(const nsCSSProperty aPropID,
|
|
const nsAString& aPropValue,
|
|
bool aIsImportant)
|
|
{
|
|
css::Declaration* olddecl = GetCSSDeclaration(true);
|
|
if (!olddecl) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
CSSParsingEnvironment env;
|
|
GetCSSParsingEnvironment(env);
|
|
if (!env.mPrincipal) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
// For nsDOMCSSAttributeDeclaration, SetCSSDeclaration will lead to
|
|
// Attribute setting code, which leads in turn to BeginUpdate. We
|
|
// need to start the update now so that the old rule doesn't get used
|
|
// between when we mutate the declaration and when we set the new
|
|
// rule (see stack in bug 209575).
|
|
mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
|
|
css::Declaration* decl = olddecl->EnsureMutable();
|
|
|
|
nsCSSParser cssParser(env.mCSSLoader);
|
|
bool changed;
|
|
nsresult result = cssParser.ParseProperty(aPropID, aPropValue, env.mSheetURI,
|
|
env.mBaseURI, env.mPrincipal, decl,
|
|
&changed, aIsImportant);
|
|
if (NS_FAILED(result) || !changed) {
|
|
if (decl != olddecl) {
|
|
delete decl;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
return SetCSSDeclaration(decl);
|
|
}
|
|
|
|
nsresult
|
|
nsDOMCSSDeclaration::ParseCustomPropertyValue(const nsAString& aPropertyName,
|
|
const nsAString& aPropValue,
|
|
bool aIsImportant)
|
|
{
|
|
MOZ_ASSERT(nsCSSProps::IsCustomPropertyName(aPropertyName));
|
|
|
|
css::Declaration* olddecl = GetCSSDeclaration(true);
|
|
if (!olddecl) {
|
|
return NS_ERROR_FAILURE;
|
|
}
|
|
|
|
CSSParsingEnvironment env;
|
|
GetCSSParsingEnvironment(env);
|
|
if (!env.mPrincipal) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
// For nsDOMCSSAttributeDeclaration, SetCSSDeclaration will lead to
|
|
// Attribute setting code, which leads in turn to BeginUpdate. We
|
|
// need to start the update now so that the old rule doesn't get used
|
|
// between when we mutate the declaration and when we set the new
|
|
// rule (see stack in bug 209575).
|
|
mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
|
|
css::Declaration* decl = olddecl->EnsureMutable();
|
|
|
|
nsCSSParser cssParser(env.mCSSLoader);
|
|
bool changed;
|
|
nsresult result =
|
|
cssParser.ParseVariable(Substring(aPropertyName,
|
|
CSS_CUSTOM_NAME_PREFIX_LENGTH),
|
|
aPropValue, env.mSheetURI,
|
|
env.mBaseURI, env.mPrincipal, decl,
|
|
&changed, aIsImportant);
|
|
if (NS_FAILED(result) || !changed) {
|
|
if (decl != olddecl) {
|
|
delete decl;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
return SetCSSDeclaration(decl);
|
|
}
|
|
|
|
nsresult
|
|
nsDOMCSSDeclaration::RemoveProperty(const nsCSSProperty aPropID)
|
|
{
|
|
css::Declaration* decl = GetCSSDeclaration(false);
|
|
if (!decl) {
|
|
return NS_OK; // no decl, so nothing to remove
|
|
}
|
|
|
|
// For nsDOMCSSAttributeDeclaration, SetCSSDeclaration will lead to
|
|
// Attribute setting code, which leads in turn to BeginUpdate. We
|
|
// need to start the update now so that the old rule doesn't get used
|
|
// between when we mutate the declaration and when we set the new
|
|
// rule (see stack in bug 209575).
|
|
mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
|
|
|
|
decl = decl->EnsureMutable();
|
|
decl->RemoveProperty(aPropID);
|
|
return SetCSSDeclaration(decl);
|
|
}
|
|
|
|
nsresult
|
|
nsDOMCSSDeclaration::RemoveCustomProperty(const nsAString& aPropertyName)
|
|
{
|
|
MOZ_ASSERT(Substring(aPropertyName, 0,
|
|
CSS_CUSTOM_NAME_PREFIX_LENGTH).EqualsLiteral("--"));
|
|
|
|
css::Declaration* decl = GetCSSDeclaration(false);
|
|
if (!decl) {
|
|
return NS_OK; // no decl, so nothing to remove
|
|
}
|
|
|
|
// For nsDOMCSSAttributeDeclaration, SetCSSDeclaration will lead to
|
|
// Attribute setting code, which leads in turn to BeginUpdate. We
|
|
// need to start the update now so that the old rule doesn't get used
|
|
// between when we mutate the declaration and when we set the new
|
|
// rule (see stack in bug 209575).
|
|
mozAutoDocConditionalContentUpdateBatch autoUpdate(DocToUpdate(), true);
|
|
|
|
decl = decl->EnsureMutable();
|
|
decl->RemoveVariableDeclaration(Substring(aPropertyName,
|
|
CSS_CUSTOM_NAME_PREFIX_LENGTH));
|
|
return SetCSSDeclaration(decl);
|
|
}
|
|
|
|
bool IsCSSPropertyExposedToJS(nsCSSProperty aProperty, JSContext* cx, JSObject* obj)
|
|
{
|
|
nsCSSProps::EnabledState enabledState = nsCSSProps::eEnabledForAllContent;
|
|
|
|
// Optimization: we skip checking properties of the JSContext
|
|
// in the majority case where the property does not have the
|
|
// CSS_PROPERTY_ALWAYS_ENABLED_IN_PRIVILEGED_CONTENT flag.
|
|
bool isEnabledInChromeOrCertifiedApp
|
|
= nsCSSProps::PropHasFlags(aProperty,
|
|
CSS_PROPERTY_ALWAYS_ENABLED_IN_CHROME_OR_CERTIFIED_APP);
|
|
|
|
if (isEnabledInChromeOrCertifiedApp) {
|
|
if (dom::IsInCertifiedApp(cx, obj) ||
|
|
nsContentUtils::ThreadsafeIsCallerChrome())
|
|
{
|
|
enabledState |= nsCSSProps::eEnabledInChromeOrCertifiedApp;
|
|
}
|
|
}
|
|
return nsCSSProps::IsEnabled(aProperty, enabledState);
|
|
}
|