1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/style/nsComputedDOMStyle.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,5656 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* vim:set tw=78 expandtab softtabstop=2 ts=2 sw=2: */ 1.6 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.7 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.8 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.9 + 1.10 +/* DOM object returned from element.getComputedStyle() */ 1.11 + 1.12 +#include "nsComputedDOMStyle.h" 1.13 + 1.14 +#include "mozilla/ArrayUtils.h" 1.15 +#include "mozilla/Preferences.h" 1.16 + 1.17 +#include "nsError.h" 1.18 +#include "nsDOMString.h" 1.19 +#include "nsIDOMCSSPrimitiveValue.h" 1.20 +#include "nsStyleContext.h" 1.21 +#include "nsIScrollableFrame.h" 1.22 +#include "nsContentUtils.h" 1.23 +#include "nsIContent.h" 1.24 + 1.25 +#include "nsDOMCSSRect.h" 1.26 +#include "nsDOMCSSRGBColor.h" 1.27 +#include "nsDOMCSSValueList.h" 1.28 +#include "nsGkAtoms.h" 1.29 +#include "nsHTMLReflowState.h" 1.30 +#include "nsStyleUtil.h" 1.31 +#include "nsStyleStructInlines.h" 1.32 +#include "nsROCSSPrimitiveValue.h" 1.33 + 1.34 +#include "nsPresContext.h" 1.35 +#include "nsIDocument.h" 1.36 + 1.37 +#include "nsCSSPseudoElements.h" 1.38 +#include "nsStyleSet.h" 1.39 +#include "imgIRequest.h" 1.40 +#include "nsLayoutUtils.h" 1.41 +#include "nsCSSKeywords.h" 1.42 +#include "nsStyleCoord.h" 1.43 +#include "nsDisplayList.h" 1.44 +#include "nsDOMCSSDeclaration.h" 1.45 +#include "nsStyleTransformMatrix.h" 1.46 +#include "mozilla/dom/Element.h" 1.47 +#include "prtime.h" 1.48 +#include "nsWrapperCacheInlines.h" 1.49 +#include "mozilla/AppUnits.h" 1.50 +#include <algorithm> 1.51 + 1.52 +using namespace mozilla; 1.53 +using namespace mozilla::dom; 1.54 + 1.55 +#if defined(DEBUG_bzbarsky) || defined(DEBUG_caillon) 1.56 +#define DEBUG_ComputedDOMStyle 1.57 +#endif 1.58 + 1.59 +/* 1.60 + * This is the implementation of the readonly CSSStyleDeclaration that is 1.61 + * returned by the getComputedStyle() function. 1.62 + */ 1.63 + 1.64 +static nsComputedDOMStyle *sCachedComputedDOMStyle; 1.65 + 1.66 +already_AddRefed<nsComputedDOMStyle> 1.67 +NS_NewComputedDOMStyle(dom::Element* aElement, const nsAString& aPseudoElt, 1.68 + nsIPresShell* aPresShell, 1.69 + nsComputedDOMStyle::StyleType aStyleType) 1.70 +{ 1.71 + nsRefPtr<nsComputedDOMStyle> computedStyle; 1.72 + if (sCachedComputedDOMStyle) { 1.73 + // There's an unused nsComputedDOMStyle cached, use it. 1.74 + // But before we use it, re-initialize the object. 1.75 + 1.76 + // Oh yeah baby, placement new! 1.77 + computedStyle = new (sCachedComputedDOMStyle) 1.78 + nsComputedDOMStyle(aElement, aPseudoElt, aPresShell, aStyleType); 1.79 + 1.80 + sCachedComputedDOMStyle = nullptr; 1.81 + } else { 1.82 + // No nsComputedDOMStyle cached, create a new one. 1.83 + 1.84 + computedStyle = new nsComputedDOMStyle(aElement, aPseudoElt, aPresShell, 1.85 + aStyleType); 1.86 + } 1.87 + 1.88 + return computedStyle.forget(); 1.89 +} 1.90 + 1.91 +/** 1.92 + * An object that represents the ordered set of properties that are exposed on 1.93 + * an nsComputedDOMStyle object and how their computed values can be obtained. 1.94 + */ 1.95 +struct nsComputedStyleMap 1.96 +{ 1.97 + friend class nsComputedDOMStyle; 1.98 + 1.99 + struct Entry 1.100 + { 1.101 + // Create a pointer-to-member-function type. 1.102 + typedef mozilla::dom::CSSValue* (nsComputedDOMStyle::*ComputeMethod)(); 1.103 + 1.104 + nsCSSProperty mProperty; 1.105 + ComputeMethod mGetter; 1.106 + 1.107 + bool IsLayoutFlushNeeded() const 1.108 + { 1.109 + return nsCSSProps::PropHasFlags(mProperty, 1.110 + CSS_PROPERTY_GETCS_NEEDS_LAYOUT_FLUSH); 1.111 + } 1.112 + 1.113 + bool IsEnabled() const 1.114 + { 1.115 + return nsCSSProps::IsEnabled(mProperty); 1.116 + } 1.117 + }; 1.118 + 1.119 + // We define this enum just to count the total number of properties that can 1.120 + // be exposed on an nsComputedDOMStyle, including properties that may be 1.121 + // disabled. 1.122 + enum { 1.123 +#define COMPUTED_STYLE_PROP(prop_, method_) \ 1.124 + eComputedStyleProperty_##prop_, 1.125 +#include "nsComputedDOMStylePropertyList.h" 1.126 +#undef COMPUTED_STYLE_PROP 1.127 + eComputedStyleProperty_COUNT 1.128 + }; 1.129 + 1.130 + /** 1.131 + * Returns the number of properties that should be exposed on an 1.132 + * nsComputedDOMStyle, ecxluding any disabled properties. 1.133 + */ 1.134 + uint32_t Length() 1.135 + { 1.136 + Update(); 1.137 + return mExposedPropertyCount; 1.138 + } 1.139 + 1.140 + /** 1.141 + * Returns the property at the given index in the list of properties 1.142 + * that should be exposed on an nsComputedDOMStyle, excluding any 1.143 + * disabled properties. 1.144 + */ 1.145 + nsCSSProperty PropertyAt(uint32_t aIndex) 1.146 + { 1.147 + Update(); 1.148 + return kEntries[EntryIndex(aIndex)].mProperty; 1.149 + } 1.150 + 1.151 + /** 1.152 + * Searches for and returns the computed style map entry for the given 1.153 + * property, or nullptr if the property is not exposed on nsComputedDOMStyle 1.154 + * or is currently disabled. 1.155 + */ 1.156 + const Entry* FindEntryForProperty(nsCSSProperty aPropID) 1.157 + { 1.158 + Update(); 1.159 + for (uint32_t i = 0; i < mExposedPropertyCount; i++) { 1.160 + const Entry* entry = &kEntries[EntryIndex(i)]; 1.161 + if (entry->mProperty == aPropID) { 1.162 + return entry; 1.163 + } 1.164 + } 1.165 + return nullptr; 1.166 + } 1.167 + 1.168 + /** 1.169 + * Records that mIndexMap needs updating, due to prefs changing that could 1.170 + * affect the set of properties exposed on an nsComputedDOMStyle. 1.171 + */ 1.172 + void MarkDirty() { mExposedPropertyCount = 0; } 1.173 + 1.174 + // The member variables are public so that we can use an initializer in 1.175 + // nsComputedDOMStyle::GetComputedStyleMap. Use the member functions 1.176 + // above to get information from this object. 1.177 + 1.178 + /** 1.179 + * An entry for each property that can be exposed on an nsComputedDOMStyle. 1.180 + */ 1.181 + const Entry kEntries[eComputedStyleProperty_COUNT]; 1.182 + 1.183 + /** 1.184 + * The number of properties that should be exposed on an nsComputedDOMStyle. 1.185 + * This will be less than eComputedStyleProperty_COUNT if some property 1.186 + * prefs are disabled. A value of 0 indicates that it and mIndexMap are out 1.187 + * of date. 1.188 + */ 1.189 + uint32_t mExposedPropertyCount; 1.190 + 1.191 + /** 1.192 + * A map of indexes on the nsComputedDOMStyle object to indexes into kEntries. 1.193 + */ 1.194 + uint32_t mIndexMap[eComputedStyleProperty_COUNT]; 1.195 + 1.196 +private: 1.197 + /** 1.198 + * Returns whether mExposedPropertyCount and mIndexMap are out of date. 1.199 + */ 1.200 + bool IsDirty() { return mExposedPropertyCount == 0; } 1.201 + 1.202 + /** 1.203 + * Updates mExposedPropertyCount and mIndexMap to take into account properties 1.204 + * whose prefs are currently disabled. 1.205 + */ 1.206 + void Update(); 1.207 + 1.208 + /** 1.209 + * Maps an nsComputedDOMStyle indexed getter index to an index into kEntries. 1.210 + */ 1.211 + uint32_t EntryIndex(uint32_t aIndex) const 1.212 + { 1.213 + MOZ_ASSERT(aIndex < mExposedPropertyCount); 1.214 + return mIndexMap[aIndex]; 1.215 + } 1.216 +}; 1.217 + 1.218 +void 1.219 +nsComputedStyleMap::Update() 1.220 +{ 1.221 + if (!IsDirty()) { 1.222 + return; 1.223 + } 1.224 + 1.225 + uint32_t index = 0; 1.226 + for (uint32_t i = 0; i < eComputedStyleProperty_COUNT; i++) { 1.227 + if (kEntries[i].IsEnabled()) { 1.228 + mIndexMap[index++] = i; 1.229 + } 1.230 + } 1.231 + mExposedPropertyCount = index; 1.232 +} 1.233 + 1.234 +nsComputedDOMStyle::nsComputedDOMStyle(dom::Element* aElement, 1.235 + const nsAString& aPseudoElt, 1.236 + nsIPresShell* aPresShell, 1.237 + StyleType aStyleType) 1.238 + : mDocumentWeak(nullptr), mOuterFrame(nullptr), 1.239 + mInnerFrame(nullptr), mPresShell(nullptr), 1.240 + mStyleType(aStyleType), 1.241 + mExposeVisitedStyle(false) 1.242 +{ 1.243 + MOZ_ASSERT(aElement && aPresShell); 1.244 + 1.245 + mDocumentWeak = do_GetWeakReference(aPresShell->GetDocument()); 1.246 + 1.247 + mContent = aElement; 1.248 + 1.249 + if (!DOMStringIsNull(aPseudoElt) && !aPseudoElt.IsEmpty() && 1.250 + aPseudoElt.First() == char16_t(':')) { 1.251 + // deal with two-colon forms of aPseudoElt 1.252 + nsAString::const_iterator start, end; 1.253 + aPseudoElt.BeginReading(start); 1.254 + aPseudoElt.EndReading(end); 1.255 + NS_ASSERTION(start != end, "aPseudoElt is not empty!"); 1.256 + ++start; 1.257 + bool haveTwoColons = true; 1.258 + if (start == end || *start != char16_t(':')) { 1.259 + --start; 1.260 + haveTwoColons = false; 1.261 + } 1.262 + mPseudo = do_GetAtom(Substring(start, end)); 1.263 + MOZ_ASSERT(mPseudo); 1.264 + 1.265 + // There aren't any non-CSS2 pseudo-elements with a single ':' 1.266 + if (!haveTwoColons && 1.267 + (!nsCSSPseudoElements::IsPseudoElement(mPseudo) || 1.268 + !nsCSSPseudoElements::IsCSS2PseudoElement(mPseudo))) { 1.269 + // XXXbz I'd really rather we threw an exception or something, but 1.270 + // the DOM spec sucks. 1.271 + mPseudo = nullptr; 1.272 + } 1.273 + } 1.274 + 1.275 + MOZ_ASSERT(aPresShell->GetPresContext()); 1.276 +} 1.277 + 1.278 + 1.279 +nsComputedDOMStyle::~nsComputedDOMStyle() 1.280 +{ 1.281 +} 1.282 + 1.283 +void 1.284 +nsComputedDOMStyle::Shutdown() 1.285 +{ 1.286 + // We want to de-allocate without calling the dtor since we 1.287 + // already did that manually in doDestroyComputedDOMStyle(), 1.288 + // so cast our cached object to something that doesn't know 1.289 + // about our dtor. 1.290 + delete reinterpret_cast<char*>(sCachedComputedDOMStyle); 1.291 + sCachedComputedDOMStyle = nullptr; 1.292 +} 1.293 + 1.294 + 1.295 +NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsComputedDOMStyle, mContent) 1.296 + 1.297 +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsComputedDOMStyle) 1.298 + return tmp->IsBlack(); 1.299 +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END 1.300 + 1.301 +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsComputedDOMStyle) 1.302 + return tmp->IsBlack(); 1.303 +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END 1.304 + 1.305 +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsComputedDOMStyle) 1.306 + return tmp->IsBlack(); 1.307 +NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END 1.308 + 1.309 +// QueryInterface implementation for nsComputedDOMStyle 1.310 +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsComputedDOMStyle) 1.311 + NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY 1.312 +NS_INTERFACE_MAP_END_INHERITING(nsDOMCSSDeclaration) 1.313 + 1.314 + 1.315 +static void doDestroyComputedDOMStyle(nsComputedDOMStyle *aComputedStyle) 1.316 +{ 1.317 + if (!sCachedComputedDOMStyle) { 1.318 + // The cache is empty, store aComputedStyle in the cache. 1.319 + 1.320 + sCachedComputedDOMStyle = aComputedStyle; 1.321 + sCachedComputedDOMStyle->~nsComputedDOMStyle(); 1.322 + } else { 1.323 + // The cache is full, delete aComputedStyle 1.324 + 1.325 + delete aComputedStyle; 1.326 + } 1.327 +} 1.328 + 1.329 +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsComputedDOMStyle) 1.330 +NS_IMPL_CYCLE_COLLECTING_RELEASE_WITH_DESTROY(nsComputedDOMStyle, 1.331 + doDestroyComputedDOMStyle(this)) 1.332 + 1.333 + 1.334 +NS_IMETHODIMP 1.335 +nsComputedDOMStyle::GetPropertyValue(const nsCSSProperty aPropID, 1.336 + nsAString& aValue) 1.337 +{ 1.338 + // This is mostly to avoid code duplication with GetPropertyCSSValue(); if 1.339 + // perf ever becomes an issue here (doubtful), we can look into changing 1.340 + // this. 1.341 + return GetPropertyValue( 1.342 + NS_ConvertASCIItoUTF16(nsCSSProps::GetStringValue(aPropID)), 1.343 + aValue); 1.344 +} 1.345 + 1.346 +NS_IMETHODIMP 1.347 +nsComputedDOMStyle::SetPropertyValue(const nsCSSProperty aPropID, 1.348 + const nsAString& aValue) 1.349 +{ 1.350 + return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; 1.351 +} 1.352 + 1.353 + 1.354 +NS_IMETHODIMP 1.355 +nsComputedDOMStyle::GetCssText(nsAString& aCssText) 1.356 +{ 1.357 + aCssText.Truncate(); 1.358 + 1.359 + return NS_OK; 1.360 +} 1.361 + 1.362 + 1.363 +NS_IMETHODIMP 1.364 +nsComputedDOMStyle::SetCssText(const nsAString& aCssText) 1.365 +{ 1.366 + return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; 1.367 +} 1.368 + 1.369 + 1.370 +NS_IMETHODIMP 1.371 +nsComputedDOMStyle::GetLength(uint32_t* aLength) 1.372 +{ 1.373 + NS_PRECONDITION(aLength, "Null aLength! Prepare to die!"); 1.374 + 1.375 + uint32_t length = GetComputedStyleMap()->Length(); 1.376 + 1.377 + // Make sure we have up to date style so that we can include custom 1.378 + // properties. 1.379 + UpdateCurrentStyleSources(false); 1.380 + if (mStyleContextHolder) { 1.381 + length += StyleVariables()->mVariables.Count(); 1.382 + } 1.383 + 1.384 + *aLength = length; 1.385 + 1.386 + ClearCurrentStyleSources(); 1.387 + 1.388 + return NS_OK; 1.389 +} 1.390 + 1.391 + 1.392 +NS_IMETHODIMP 1.393 +nsComputedDOMStyle::GetParentRule(nsIDOMCSSRule** aParentRule) 1.394 +{ 1.395 + *aParentRule = nullptr; 1.396 + 1.397 + return NS_OK; 1.398 +} 1.399 + 1.400 + 1.401 +NS_IMETHODIMP 1.402 +nsComputedDOMStyle::GetPropertyValue(const nsAString& aPropertyName, 1.403 + nsAString& aReturn) 1.404 +{ 1.405 + aReturn.Truncate(); 1.406 + 1.407 + ErrorResult error; 1.408 + nsRefPtr<CSSValue> val = GetPropertyCSSValue(aPropertyName, error); 1.409 + if (error.Failed()) { 1.410 + return error.ErrorCode(); 1.411 + } 1.412 + 1.413 + if (val) { 1.414 + nsString text; 1.415 + val->GetCssText(text, error); 1.416 + aReturn.Assign(text); 1.417 + return error.ErrorCode(); 1.418 + } 1.419 + 1.420 + return NS_OK; 1.421 +} 1.422 + 1.423 +NS_IMETHODIMP 1.424 +nsComputedDOMStyle::GetAuthoredPropertyValue(const nsAString& aPropertyName, 1.425 + nsAString& aReturn) 1.426 +{ 1.427 + // Authored style doesn't make sense to return from computed DOM style, 1.428 + // so just return whatever GetPropertyValue() returns. 1.429 + return GetPropertyValue(aPropertyName, aReturn); 1.430 +} 1.431 + 1.432 +/* static */ 1.433 +already_AddRefed<nsStyleContext> 1.434 +nsComputedDOMStyle::GetStyleContextForElement(Element* aElement, 1.435 + nsIAtom* aPseudo, 1.436 + nsIPresShell* aPresShell, 1.437 + StyleType aStyleType) 1.438 +{ 1.439 + // If the content has a pres shell, we must use it. Otherwise we'd 1.440 + // potentially mix rule trees by using the wrong pres shell's style 1.441 + // set. Using the pres shell from the content also means that any 1.442 + // content that's actually *in* a document will get the style from the 1.443 + // correct document. 1.444 + nsCOMPtr<nsIPresShell> presShell = GetPresShellForContent(aElement); 1.445 + if (!presShell) { 1.446 + presShell = aPresShell; 1.447 + if (!presShell) 1.448 + return nullptr; 1.449 + } 1.450 + 1.451 + presShell->FlushPendingNotifications(Flush_Style); 1.452 + 1.453 + return GetStyleContextForElementNoFlush(aElement, aPseudo, presShell, 1.454 + aStyleType); 1.455 +} 1.456 + 1.457 +/* static */ 1.458 +already_AddRefed<nsStyleContext> 1.459 +nsComputedDOMStyle::GetStyleContextForElementNoFlush(Element* aElement, 1.460 + nsIAtom* aPseudo, 1.461 + nsIPresShell* aPresShell, 1.462 + StyleType aStyleType) 1.463 +{ 1.464 + NS_ABORT_IF_FALSE(aElement, "NULL element"); 1.465 + // If the content has a pres shell, we must use it. Otherwise we'd 1.466 + // potentially mix rule trees by using the wrong pres shell's style 1.467 + // set. Using the pres shell from the content also means that any 1.468 + // content that's actually *in* a document will get the style from the 1.469 + // correct document. 1.470 + nsIPresShell *presShell = GetPresShellForContent(aElement); 1.471 + if (!presShell) { 1.472 + presShell = aPresShell; 1.473 + if (!presShell) 1.474 + return nullptr; 1.475 + } 1.476 + 1.477 + if (!aPseudo && aStyleType == eAll) { 1.478 + nsIFrame* frame = nsLayoutUtils::GetStyleFrame(aElement); 1.479 + if (frame) { 1.480 + nsStyleContext* result = frame->StyleContext(); 1.481 + // Don't use the style context if it was influenced by 1.482 + // pseudo-elements, since then it's not the primary style 1.483 + // for this element. 1.484 + if (!result->HasPseudoElementData()) { 1.485 + // this function returns an addrefed style context 1.486 + nsRefPtr<nsStyleContext> ret = result; 1.487 + return ret.forget(); 1.488 + } 1.489 + } 1.490 + } 1.491 + 1.492 + // No frame has been created, or we have a pseudo, or we're looking 1.493 + // for the default style, so resolve the style ourselves. 1.494 + nsRefPtr<nsStyleContext> parentContext; 1.495 + nsIContent* parent = aPseudo ? aElement : aElement->GetParent(); 1.496 + // Don't resolve parent context for document fragments. 1.497 + if (parent && parent->IsElement()) 1.498 + parentContext = GetStyleContextForElementNoFlush(parent->AsElement(), 1.499 + nullptr, presShell, 1.500 + aStyleType); 1.501 + 1.502 + nsPresContext *presContext = presShell->GetPresContext(); 1.503 + if (!presContext) 1.504 + return nullptr; 1.505 + 1.506 + nsStyleSet *styleSet = presShell->StyleSet(); 1.507 + 1.508 + nsRefPtr<nsStyleContext> sc; 1.509 + if (aPseudo) { 1.510 + nsCSSPseudoElements::Type type = nsCSSPseudoElements::GetPseudoType(aPseudo); 1.511 + if (type >= nsCSSPseudoElements::ePseudo_PseudoElementCount) { 1.512 + return nullptr; 1.513 + } 1.514 + nsIFrame* frame = nsLayoutUtils::GetStyleFrame(aElement); 1.515 + Element* pseudoElement = frame ? frame->GetPseudoElement(type) : nullptr; 1.516 + sc = styleSet->ResolvePseudoElementStyle(aElement, type, parentContext, 1.517 + pseudoElement); 1.518 + } else { 1.519 + sc = styleSet->ResolveStyleFor(aElement, parentContext); 1.520 + } 1.521 + 1.522 + if (aStyleType == eDefaultOnly) { 1.523 + // We really only want the user and UA rules. Filter out the other ones. 1.524 + nsTArray< nsCOMPtr<nsIStyleRule> > rules; 1.525 + for (nsRuleNode* ruleNode = sc->RuleNode(); 1.526 + !ruleNode->IsRoot(); 1.527 + ruleNode = ruleNode->GetParent()) { 1.528 + if (ruleNode->GetLevel() == nsStyleSet::eAgentSheet || 1.529 + ruleNode->GetLevel() == nsStyleSet::eUserSheet) { 1.530 + rules.AppendElement(ruleNode->GetRule()); 1.531 + } 1.532 + } 1.533 + 1.534 + // We want to build a list of user/ua rules that is in order from least to 1.535 + // most important, so we have to reverse the list. 1.536 + // Integer division to get "stop" is purposeful here: if length is odd, we 1.537 + // don't have to do anything with the middle element of the array. 1.538 + for (uint32_t i = 0, length = rules.Length(), stop = length / 2; 1.539 + i < stop; ++i) { 1.540 + rules[i].swap(rules[length - i - 1]); 1.541 + } 1.542 + 1.543 + sc = styleSet->ResolveStyleForRules(parentContext, rules); 1.544 + } 1.545 + 1.546 + return sc.forget(); 1.547 +} 1.548 + 1.549 +nsMargin 1.550 +nsComputedDOMStyle::GetAdjustedValuesForBoxSizing() 1.551 +{ 1.552 + // We want the width/height of whatever parts 'width' or 'height' controls, 1.553 + // which can be different depending on the value of the 'box-sizing' property. 1.554 + const nsStylePosition* stylePos = StylePosition(); 1.555 + 1.556 + nsMargin adjustment; 1.557 + switch(stylePos->mBoxSizing) { 1.558 + case NS_STYLE_BOX_SIZING_BORDER: 1.559 + adjustment += mInnerFrame->GetUsedBorder(); 1.560 + // fall through 1.561 + 1.562 + case NS_STYLE_BOX_SIZING_PADDING: 1.563 + adjustment += mInnerFrame->GetUsedPadding(); 1.564 + } 1.565 + 1.566 + return adjustment; 1.567 +} 1.568 + 1.569 +/* static */ 1.570 +nsIPresShell* 1.571 +nsComputedDOMStyle::GetPresShellForContent(nsIContent* aContent) 1.572 +{ 1.573 + nsIDocument* currentDoc = aContent->GetCurrentDoc(); 1.574 + if (!currentDoc) 1.575 + return nullptr; 1.576 + 1.577 + return currentDoc->GetShell(); 1.578 +} 1.579 + 1.580 +// nsDOMCSSDeclaration abstract methods which should never be called 1.581 +// on a nsComputedDOMStyle object, but must be defined to avoid 1.582 +// compile errors. 1.583 +css::Declaration* 1.584 +nsComputedDOMStyle::GetCSSDeclaration(bool) 1.585 +{ 1.586 + NS_RUNTIMEABORT("called nsComputedDOMStyle::GetCSSDeclaration"); 1.587 + return nullptr; 1.588 +} 1.589 + 1.590 +nsresult 1.591 +nsComputedDOMStyle::SetCSSDeclaration(css::Declaration*) 1.592 +{ 1.593 + NS_RUNTIMEABORT("called nsComputedDOMStyle::SetCSSDeclaration"); 1.594 + return NS_ERROR_FAILURE; 1.595 +} 1.596 + 1.597 +nsIDocument* 1.598 +nsComputedDOMStyle::DocToUpdate() 1.599 +{ 1.600 + NS_RUNTIMEABORT("called nsComputedDOMStyle::DocToUpdate"); 1.601 + return nullptr; 1.602 +} 1.603 + 1.604 +void 1.605 +nsComputedDOMStyle::GetCSSParsingEnvironment(CSSParsingEnvironment& aCSSParseEnv) 1.606 +{ 1.607 + NS_RUNTIMEABORT("called nsComputedDOMStyle::GetCSSParsingEnvironment"); 1.608 + // Just in case NS_RUNTIMEABORT ever stops killing us for some reason 1.609 + aCSSParseEnv.mPrincipal = nullptr; 1.610 +} 1.611 + 1.612 +void 1.613 +nsComputedDOMStyle::UpdateCurrentStyleSources(bool aNeedsLayoutFlush) 1.614 +{ 1.615 + MOZ_ASSERT(!mStyleContextHolder); 1.616 + 1.617 + nsCOMPtr<nsIDocument> document = do_QueryReferent(mDocumentWeak); 1.618 + if (!document) { 1.619 + return; 1.620 + } 1.621 + 1.622 + document->FlushPendingLinkUpdates(); 1.623 + 1.624 + // Flush _before_ getting the presshell, since that could create a new 1.625 + // presshell. Also note that we want to flush the style on the document 1.626 + // we're computing style in, not on the document mContent is in -- the two 1.627 + // may be different. 1.628 + document->FlushPendingNotifications( 1.629 + aNeedsLayoutFlush ? Flush_Layout : Flush_Style); 1.630 +#ifdef DEBUG 1.631 + mFlushedPendingReflows = aNeedsLayoutFlush; 1.632 +#endif 1.633 + 1.634 + mPresShell = document->GetShell(); 1.635 + if (!mPresShell || !mPresShell->GetPresContext()) { 1.636 + return; 1.637 + } 1.638 + 1.639 + if (!mPseudo && mStyleType == eAll) { 1.640 + mOuterFrame = mContent->GetPrimaryFrame(); 1.641 + mInnerFrame = mOuterFrame; 1.642 + if (mOuterFrame) { 1.643 + nsIAtom* type = mOuterFrame->GetType(); 1.644 + if (type == nsGkAtoms::tableOuterFrame) { 1.645 + // If the frame is an outer table frame then we should get the style 1.646 + // from the inner table frame. 1.647 + mInnerFrame = mOuterFrame->GetFirstPrincipalChild(); 1.648 + NS_ASSERTION(mInnerFrame, "Outer table must have an inner"); 1.649 + NS_ASSERTION(!mInnerFrame->GetNextSibling(), 1.650 + "Outer table frames should have just one child, " 1.651 + "the inner table"); 1.652 + } 1.653 + 1.654 + mStyleContextHolder = mInnerFrame->StyleContext(); 1.655 + NS_ASSERTION(mStyleContextHolder, "Frame without style context?"); 1.656 + } 1.657 + } 1.658 + 1.659 + if (!mStyleContextHolder || mStyleContextHolder->HasPseudoElementData()) { 1.660 +#ifdef DEBUG 1.661 + if (mStyleContextHolder) { 1.662 + // We want to check that going through this path because of 1.663 + // HasPseudoElementData is rare, because it slows us down a good 1.664 + // bit. So check that we're really inside something associated 1.665 + // with a pseudo-element that contains elements. 1.666 + nsStyleContext *topWithPseudoElementData = mStyleContextHolder; 1.667 + while (topWithPseudoElementData->GetParent()->HasPseudoElementData()) { 1.668 + topWithPseudoElementData = topWithPseudoElementData->GetParent(); 1.669 + } 1.670 + nsCSSPseudoElements::Type pseudo = 1.671 + topWithPseudoElementData->GetPseudoType(); 1.672 + nsIAtom* pseudoAtom = nsCSSPseudoElements::GetPseudoAtom(pseudo); 1.673 + nsAutoString assertMsg( 1.674 + NS_LITERAL_STRING("we should be in a pseudo-element that is expected to contain elements (")); 1.675 + assertMsg.Append(nsDependentString(pseudoAtom->GetUTF16String())); 1.676 + assertMsg.Append(NS_LITERAL_STRING(")")); 1.677 + NS_ASSERTION(nsCSSPseudoElements::PseudoElementContainsElements(pseudo), 1.678 + NS_LossyConvertUTF16toASCII(assertMsg).get()); 1.679 + } 1.680 +#endif 1.681 + // Need to resolve a style context 1.682 + mStyleContextHolder = 1.683 + nsComputedDOMStyle::GetStyleContextForElement(mContent->AsElement(), 1.684 + mPseudo, 1.685 + mPresShell, 1.686 + mStyleType); 1.687 + if (!mStyleContextHolder) { 1.688 + return; 1.689 + } 1.690 + 1.691 + NS_ASSERTION(mPseudo || !mStyleContextHolder->HasPseudoElementData(), 1.692 + "should not have pseudo-element data"); 1.693 + } 1.694 + 1.695 + // mExposeVisitedStyle is set to true only by testing APIs that 1.696 + // require chrome privilege. 1.697 + NS_ABORT_IF_FALSE(!mExposeVisitedStyle || 1.698 + nsContentUtils::IsCallerChrome(), 1.699 + "mExposeVisitedStyle set incorrectly"); 1.700 + if (mExposeVisitedStyle && mStyleContextHolder->RelevantLinkVisited()) { 1.701 + nsStyleContext *styleIfVisited = mStyleContextHolder->GetStyleIfVisited(); 1.702 + if (styleIfVisited) { 1.703 + mStyleContextHolder = styleIfVisited; 1.704 + } 1.705 + } 1.706 +} 1.707 + 1.708 +void 1.709 +nsComputedDOMStyle::ClearCurrentStyleSources() 1.710 +{ 1.711 + mOuterFrame = nullptr; 1.712 + mInnerFrame = nullptr; 1.713 + mPresShell = nullptr; 1.714 + 1.715 + // Release the current style context for it should be re-resolved 1.716 + // whenever a frame is not available. 1.717 + mStyleContextHolder = nullptr; 1.718 +} 1.719 + 1.720 +already_AddRefed<CSSValue> 1.721 +nsComputedDOMStyle::GetPropertyCSSValue(const nsAString& aPropertyName, ErrorResult& aRv) 1.722 +{ 1.723 + nsCSSProperty prop = nsCSSProps::LookupProperty(aPropertyName, 1.724 + nsCSSProps::eEnabledForAllContent); 1.725 + 1.726 + bool needsLayoutFlush; 1.727 + nsComputedStyleMap::Entry::ComputeMethod getter; 1.728 + 1.729 + if (prop == eCSSPropertyExtra_variable) { 1.730 + needsLayoutFlush = false; 1.731 + getter = nullptr; 1.732 + } else { 1.733 + // We don't (for now, anyway, though it may make sense to change it 1.734 + // for all aliases, including those in nsCSSPropAliasList) want 1.735 + // aliases to be enumerable (via GetLength and IndexedGetter), so 1.736 + // handle them here rather than adding entries to 1.737 + // GetQueryablePropertyMap. 1.738 + if (prop != eCSSProperty_UNKNOWN && 1.739 + nsCSSProps::PropHasFlags(prop, CSS_PROPERTY_IS_ALIAS)) { 1.740 + const nsCSSProperty* subprops = nsCSSProps::SubpropertyEntryFor(prop); 1.741 + NS_ABORT_IF_FALSE(subprops[1] == eCSSProperty_UNKNOWN, 1.742 + "must have list of length 1"); 1.743 + prop = subprops[0]; 1.744 + } 1.745 + 1.746 + const nsComputedStyleMap::Entry* propEntry = 1.747 + GetComputedStyleMap()->FindEntryForProperty(prop); 1.748 + 1.749 + if (!propEntry) { 1.750 +#ifdef DEBUG_ComputedDOMStyle 1.751 + NS_WARNING(PromiseFlatCString(NS_ConvertUTF16toUTF8(aPropertyName) + 1.752 + NS_LITERAL_CSTRING(" is not queryable!")).get()); 1.753 +#endif 1.754 + 1.755 + // NOTE: For branches, we should flush here for compatibility! 1.756 + return nullptr; 1.757 + } 1.758 + 1.759 + needsLayoutFlush = propEntry->IsLayoutFlushNeeded(); 1.760 + getter = propEntry->mGetter; 1.761 + } 1.762 + 1.763 + UpdateCurrentStyleSources(needsLayoutFlush); 1.764 + if (!mStyleContextHolder) { 1.765 + aRv.Throw(NS_ERROR_NOT_AVAILABLE); 1.766 + return nullptr; 1.767 + } 1.768 + 1.769 + nsRefPtr<CSSValue> val; 1.770 + if (prop == eCSSPropertyExtra_variable) { 1.771 + val = DoGetCustomProperty(aPropertyName); 1.772 + } else { 1.773 + // Call our pointer-to-member-function. 1.774 + val = (this->*getter)(); 1.775 + } 1.776 + 1.777 + ClearCurrentStyleSources(); 1.778 + 1.779 + return val.forget(); 1.780 +} 1.781 + 1.782 + 1.783 +NS_IMETHODIMP 1.784 +nsComputedDOMStyle::RemoveProperty(const nsAString& aPropertyName, 1.785 + nsAString& aReturn) 1.786 +{ 1.787 + return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; 1.788 +} 1.789 + 1.790 + 1.791 +NS_IMETHODIMP 1.792 +nsComputedDOMStyle::GetPropertyPriority(const nsAString& aPropertyName, 1.793 + nsAString& aReturn) 1.794 +{ 1.795 + aReturn.Truncate(); 1.796 + 1.797 + return NS_OK; 1.798 +} 1.799 + 1.800 + 1.801 +NS_IMETHODIMP 1.802 +nsComputedDOMStyle::SetProperty(const nsAString& aPropertyName, 1.803 + const nsAString& aValue, 1.804 + const nsAString& aPriority) 1.805 +{ 1.806 + return NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR; 1.807 +} 1.808 + 1.809 + 1.810 +NS_IMETHODIMP 1.811 +nsComputedDOMStyle::Item(uint32_t aIndex, nsAString& aReturn) 1.812 +{ 1.813 + return nsDOMCSSDeclaration::Item(aIndex, aReturn); 1.814 +} 1.815 + 1.816 +void 1.817 +nsComputedDOMStyle::IndexedGetter(uint32_t aIndex, bool& aFound, 1.818 + nsAString& aPropName) 1.819 +{ 1.820 + nsComputedStyleMap* map = GetComputedStyleMap(); 1.821 + uint32_t length = map->Length(); 1.822 + 1.823 + if (aIndex < length) { 1.824 + aFound = true; 1.825 + CopyASCIItoUTF16(nsCSSProps::GetStringValue(map->PropertyAt(aIndex)), 1.826 + aPropName); 1.827 + return; 1.828 + } 1.829 + 1.830 + // Custom properties are exposed with indexed properties just after all 1.831 + // of the built-in properties. 1.832 + UpdateCurrentStyleSources(false); 1.833 + if (!mStyleContextHolder) { 1.834 + aFound = false; 1.835 + return; 1.836 + } 1.837 + 1.838 + const nsStyleVariables* variables = StyleVariables(); 1.839 + if (aIndex - length < variables->mVariables.Count()) { 1.840 + aFound = true; 1.841 + variables->mVariables.GetVariableAt(aIndex - length, aPropName); 1.842 + } else { 1.843 + aFound = false; 1.844 + } 1.845 + 1.846 + ClearCurrentStyleSources(); 1.847 +} 1.848 + 1.849 +// Property getters... 1.850 + 1.851 +CSSValue* 1.852 +nsComputedDOMStyle::DoGetBinding() 1.853 +{ 1.854 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.855 + 1.856 + const nsStyleDisplay* display = StyleDisplay(); 1.857 + 1.858 + if (display->mBinding) { 1.859 + val->SetURI(display->mBinding->GetURI()); 1.860 + } else { 1.861 + val->SetIdent(eCSSKeyword_none); 1.862 + } 1.863 + 1.864 + return val; 1.865 +} 1.866 + 1.867 +CSSValue* 1.868 +nsComputedDOMStyle::DoGetClear() 1.869 +{ 1.870 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.871 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBreakType, 1.872 + nsCSSProps::kClearKTable)); 1.873 + return val; 1.874 +} 1.875 + 1.876 +CSSValue* 1.877 +nsComputedDOMStyle::DoGetFloat() 1.878 +{ 1.879 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.880 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mFloats, 1.881 + nsCSSProps::kFloatKTable)); 1.882 + return val; 1.883 +} 1.884 + 1.885 +CSSValue* 1.886 +nsComputedDOMStyle::DoGetBottom() 1.887 +{ 1.888 + return GetOffsetWidthFor(NS_SIDE_BOTTOM); 1.889 +} 1.890 + 1.891 +CSSValue* 1.892 +nsComputedDOMStyle::DoGetStackSizing() 1.893 +{ 1.894 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.895 + val->SetIdent(StyleXUL()->mStretchStack ? eCSSKeyword_stretch_to_fit : 1.896 + eCSSKeyword_ignore); 1.897 + return val; 1.898 +} 1.899 + 1.900 +void 1.901 +nsComputedDOMStyle::SetToRGBAColor(nsROCSSPrimitiveValue* aValue, 1.902 + nscolor aColor) 1.903 +{ 1.904 + if (NS_GET_A(aColor) == 0) { 1.905 + aValue->SetIdent(eCSSKeyword_transparent); 1.906 + return; 1.907 + } 1.908 + 1.909 + nsROCSSPrimitiveValue *red = new nsROCSSPrimitiveValue; 1.910 + nsROCSSPrimitiveValue *green = new nsROCSSPrimitiveValue; 1.911 + nsROCSSPrimitiveValue *blue = new nsROCSSPrimitiveValue; 1.912 + nsROCSSPrimitiveValue *alpha = new nsROCSSPrimitiveValue; 1.913 + 1.914 + uint8_t a = NS_GET_A(aColor); 1.915 + nsDOMCSSRGBColor *rgbColor = 1.916 + new nsDOMCSSRGBColor(red, green, blue, alpha, a < 255); 1.917 + 1.918 + red->SetNumber(NS_GET_R(aColor)); 1.919 + green->SetNumber(NS_GET_G(aColor)); 1.920 + blue->SetNumber(NS_GET_B(aColor)); 1.921 + alpha->SetNumber(nsStyleUtil::ColorComponentToFloat(a)); 1.922 + 1.923 + aValue->SetColor(rgbColor); 1.924 +} 1.925 + 1.926 +CSSValue* 1.927 +nsComputedDOMStyle::DoGetColor() 1.928 +{ 1.929 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.930 + SetToRGBAColor(val, StyleColor()->mColor); 1.931 + return val; 1.932 +} 1.933 + 1.934 +CSSValue* 1.935 +nsComputedDOMStyle::DoGetOpacity() 1.936 +{ 1.937 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.938 + val->SetNumber(StyleDisplay()->mOpacity); 1.939 + return val; 1.940 +} 1.941 + 1.942 +CSSValue* 1.943 +nsComputedDOMStyle::DoGetColumnCount() 1.944 +{ 1.945 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.946 + 1.947 + const nsStyleColumn* column = StyleColumn(); 1.948 + 1.949 + if (column->mColumnCount == NS_STYLE_COLUMN_COUNT_AUTO) { 1.950 + val->SetIdent(eCSSKeyword_auto); 1.951 + } else { 1.952 + val->SetNumber(column->mColumnCount); 1.953 + } 1.954 + 1.955 + return val; 1.956 +} 1.957 + 1.958 +CSSValue* 1.959 +nsComputedDOMStyle::DoGetColumnWidth() 1.960 +{ 1.961 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.962 + 1.963 + // XXX fix the auto case. When we actually have a column frame, I think 1.964 + // we should return the computed column width. 1.965 + SetValueToCoord(val, StyleColumn()->mColumnWidth, true); 1.966 + return val; 1.967 +} 1.968 + 1.969 +CSSValue* 1.970 +nsComputedDOMStyle::DoGetColumnGap() 1.971 +{ 1.972 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.973 + 1.974 + const nsStyleColumn* column = StyleColumn(); 1.975 + if (column->mColumnGap.GetUnit() == eStyleUnit_Normal) { 1.976 + val->SetAppUnits(StyleFont()->mFont.size); 1.977 + } else { 1.978 + SetValueToCoord(val, StyleColumn()->mColumnGap, true); 1.979 + } 1.980 + 1.981 + return val; 1.982 +} 1.983 + 1.984 +CSSValue* 1.985 +nsComputedDOMStyle::DoGetColumnFill() 1.986 +{ 1.987 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.988 + val->SetIdent( 1.989 + nsCSSProps::ValueToKeywordEnum(StyleColumn()->mColumnFill, 1.990 + nsCSSProps::kColumnFillKTable)); 1.991 + return val; 1.992 +} 1.993 + 1.994 +CSSValue* 1.995 +nsComputedDOMStyle::DoGetColumnRuleWidth() 1.996 +{ 1.997 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.998 + val->SetAppUnits(StyleColumn()->GetComputedColumnRuleWidth()); 1.999 + return val; 1.1000 +} 1.1001 + 1.1002 +CSSValue* 1.1003 +nsComputedDOMStyle::DoGetColumnRuleStyle() 1.1004 +{ 1.1005 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.1006 + val->SetIdent( 1.1007 + nsCSSProps::ValueToKeywordEnum(StyleColumn()->mColumnRuleStyle, 1.1008 + nsCSSProps::kBorderStyleKTable)); 1.1009 + return val; 1.1010 +} 1.1011 + 1.1012 +CSSValue* 1.1013 +nsComputedDOMStyle::DoGetColumnRuleColor() 1.1014 +{ 1.1015 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.1016 + 1.1017 + const nsStyleColumn* column = StyleColumn(); 1.1018 + nscolor ruleColor; 1.1019 + if (column->mColumnRuleColorIsForeground) { 1.1020 + ruleColor = StyleColor()->mColor; 1.1021 + } else { 1.1022 + ruleColor = column->mColumnRuleColor; 1.1023 + } 1.1024 + 1.1025 + SetToRGBAColor(val, ruleColor); 1.1026 + return val; 1.1027 +} 1.1028 + 1.1029 +CSSValue* 1.1030 +nsComputedDOMStyle::DoGetContent() 1.1031 +{ 1.1032 + const nsStyleContent *content = StyleContent(); 1.1033 + 1.1034 + if (content->ContentCount() == 0) { 1.1035 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.1036 + val->SetIdent(eCSSKeyword_none); 1.1037 + return val; 1.1038 + } 1.1039 + 1.1040 + if (content->ContentCount() == 1 && 1.1041 + content->ContentAt(0).mType == eStyleContentType_AltContent) { 1.1042 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.1043 + val->SetIdent(eCSSKeyword__moz_alt_content); 1.1044 + return val; 1.1045 + } 1.1046 + 1.1047 + nsDOMCSSValueList *valueList = GetROCSSValueList(false); 1.1048 + 1.1049 + for (uint32_t i = 0, i_end = content->ContentCount(); i < i_end; ++i) { 1.1050 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1051 + valueList->AppendCSSValue(val); 1.1052 + 1.1053 + const nsStyleContentData &data = content->ContentAt(i); 1.1054 + switch (data.mType) { 1.1055 + case eStyleContentType_String: 1.1056 + { 1.1057 + nsString str; 1.1058 + nsStyleUtil::AppendEscapedCSSString( 1.1059 + nsDependentString(data.mContent.mString), str); 1.1060 + val->SetString(str); 1.1061 + } 1.1062 + break; 1.1063 + case eStyleContentType_Image: 1.1064 + { 1.1065 + nsCOMPtr<nsIURI> uri; 1.1066 + if (data.mContent.mImage) { 1.1067 + data.mContent.mImage->GetURI(getter_AddRefs(uri)); 1.1068 + } 1.1069 + val->SetURI(uri); 1.1070 + } 1.1071 + break; 1.1072 + case eStyleContentType_Attr: 1.1073 + { 1.1074 + nsAutoString str; 1.1075 + nsStyleUtil::AppendEscapedCSSIdent( 1.1076 + nsDependentString(data.mContent.mString), str); 1.1077 + val->SetString(str, nsIDOMCSSPrimitiveValue::CSS_ATTR); 1.1078 + } 1.1079 + break; 1.1080 + case eStyleContentType_Counter: 1.1081 + case eStyleContentType_Counters: 1.1082 + { 1.1083 + /* FIXME: counters should really use an object */ 1.1084 + nsAutoString str; 1.1085 + if (data.mType == eStyleContentType_Counter) { 1.1086 + str.AppendLiteral("counter("); 1.1087 + } 1.1088 + else { 1.1089 + str.AppendLiteral("counters("); 1.1090 + } 1.1091 + // WRITE ME 1.1092 + nsCSSValue::Array *a = data.mContent.mCounters; 1.1093 + 1.1094 + nsStyleUtil::AppendEscapedCSSIdent( 1.1095 + nsDependentString(a->Item(0).GetStringBufferValue()), str); 1.1096 + int32_t typeItem = 1; 1.1097 + if (data.mType == eStyleContentType_Counters) { 1.1098 + typeItem = 2; 1.1099 + str.AppendLiteral(", "); 1.1100 + nsStyleUtil::AppendEscapedCSSString( 1.1101 + nsDependentString(a->Item(1).GetStringBufferValue()), str); 1.1102 + } 1.1103 + NS_ABORT_IF_FALSE(eCSSUnit_None != a->Item(typeItem).GetUnit(), 1.1104 + "'none' should be handled as enumerated value"); 1.1105 + int32_t type = a->Item(typeItem).GetIntValue(); 1.1106 + if (type != NS_STYLE_LIST_STYLE_DECIMAL) { 1.1107 + str.AppendLiteral(", "); 1.1108 + AppendASCIItoUTF16( 1.1109 + nsCSSProps::ValueToKeyword(type, nsCSSProps::kListStyleKTable), 1.1110 + str); 1.1111 + } 1.1112 + 1.1113 + str.Append(char16_t(')')); 1.1114 + val->SetString(str, nsIDOMCSSPrimitiveValue::CSS_COUNTER); 1.1115 + } 1.1116 + break; 1.1117 + case eStyleContentType_OpenQuote: 1.1118 + val->SetIdent(eCSSKeyword_open_quote); 1.1119 + break; 1.1120 + case eStyleContentType_CloseQuote: 1.1121 + val->SetIdent(eCSSKeyword_close_quote); 1.1122 + break; 1.1123 + case eStyleContentType_NoOpenQuote: 1.1124 + val->SetIdent(eCSSKeyword_no_open_quote); 1.1125 + break; 1.1126 + case eStyleContentType_NoCloseQuote: 1.1127 + val->SetIdent(eCSSKeyword_no_close_quote); 1.1128 + break; 1.1129 + case eStyleContentType_AltContent: 1.1130 + default: 1.1131 + NS_NOTREACHED("unexpected type"); 1.1132 + break; 1.1133 + } 1.1134 + } 1.1135 + 1.1136 + return valueList; 1.1137 +} 1.1138 + 1.1139 +CSSValue* 1.1140 +nsComputedDOMStyle::DoGetCounterIncrement() 1.1141 +{ 1.1142 + const nsStyleContent *content = StyleContent(); 1.1143 + 1.1144 + if (content->CounterIncrementCount() == 0) { 1.1145 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.1146 + val->SetIdent(eCSSKeyword_none); 1.1147 + return val; 1.1148 + } 1.1149 + 1.1150 + nsDOMCSSValueList *valueList = GetROCSSValueList(false); 1.1151 + 1.1152 + for (uint32_t i = 0, i_end = content->CounterIncrementCount(); i < i_end; ++i) { 1.1153 + nsROCSSPrimitiveValue* name = new nsROCSSPrimitiveValue; 1.1154 + valueList->AppendCSSValue(name); 1.1155 + 1.1156 + nsROCSSPrimitiveValue* value = new nsROCSSPrimitiveValue; 1.1157 + valueList->AppendCSSValue(value); 1.1158 + 1.1159 + const nsStyleCounterData *data = content->GetCounterIncrementAt(i); 1.1160 + nsAutoString escaped; 1.1161 + nsStyleUtil::AppendEscapedCSSIdent(data->mCounter, escaped); 1.1162 + name->SetString(escaped); 1.1163 + value->SetNumber(data->mValue); // XXX This should really be integer 1.1164 + } 1.1165 + 1.1166 + return valueList; 1.1167 +} 1.1168 + 1.1169 +/* Convert the stored representation into a list of two values and then hand 1.1170 + * it back. 1.1171 + */ 1.1172 +CSSValue* 1.1173 +nsComputedDOMStyle::DoGetTransformOrigin() 1.1174 +{ 1.1175 + /* We need to build up a list of two values. We'll call them 1.1176 + * width and height. 1.1177 + */ 1.1178 + 1.1179 + /* Store things as a value list */ 1.1180 + nsDOMCSSValueList* valueList = GetROCSSValueList(false); 1.1181 + 1.1182 + /* Now, get the values. */ 1.1183 + const nsStyleDisplay* display = StyleDisplay(); 1.1184 + 1.1185 + nsROCSSPrimitiveValue* width = new nsROCSSPrimitiveValue; 1.1186 + SetValueToCoord(width, display->mTransformOrigin[0], false, 1.1187 + &nsComputedDOMStyle::GetFrameBoundsWidthForTransform); 1.1188 + valueList->AppendCSSValue(width); 1.1189 + 1.1190 + nsROCSSPrimitiveValue* height = new nsROCSSPrimitiveValue; 1.1191 + SetValueToCoord(height, display->mTransformOrigin[1], false, 1.1192 + &nsComputedDOMStyle::GetFrameBoundsHeightForTransform); 1.1193 + valueList->AppendCSSValue(height); 1.1194 + 1.1195 + if (display->mTransformOrigin[2].GetUnit() != eStyleUnit_Coord || 1.1196 + display->mTransformOrigin[2].GetCoordValue() != 0) { 1.1197 + nsROCSSPrimitiveValue* depth = new nsROCSSPrimitiveValue; 1.1198 + SetValueToCoord(depth, display->mTransformOrigin[2], false, 1.1199 + nullptr); 1.1200 + valueList->AppendCSSValue(depth); 1.1201 + } 1.1202 + 1.1203 + return valueList; 1.1204 +} 1.1205 + 1.1206 +/* Convert the stored representation into a list of two values and then hand 1.1207 + * it back. 1.1208 + */ 1.1209 +CSSValue* 1.1210 +nsComputedDOMStyle::DoGetPerspectiveOrigin() 1.1211 +{ 1.1212 + /* We need to build up a list of two values. We'll call them 1.1213 + * width and height. 1.1214 + */ 1.1215 + 1.1216 + /* Store things as a value list */ 1.1217 + nsDOMCSSValueList* valueList = GetROCSSValueList(false); 1.1218 + 1.1219 + /* Now, get the values. */ 1.1220 + const nsStyleDisplay* display = StyleDisplay(); 1.1221 + 1.1222 + nsROCSSPrimitiveValue* width = new nsROCSSPrimitiveValue; 1.1223 + SetValueToCoord(width, display->mPerspectiveOrigin[0], false, 1.1224 + &nsComputedDOMStyle::GetFrameBoundsWidthForTransform); 1.1225 + valueList->AppendCSSValue(width); 1.1226 + 1.1227 + nsROCSSPrimitiveValue* height = new nsROCSSPrimitiveValue; 1.1228 + SetValueToCoord(height, display->mPerspectiveOrigin[1], false, 1.1229 + &nsComputedDOMStyle::GetFrameBoundsHeightForTransform); 1.1230 + valueList->AppendCSSValue(height); 1.1231 + 1.1232 + return valueList; 1.1233 +} 1.1234 + 1.1235 +CSSValue* 1.1236 +nsComputedDOMStyle::DoGetPerspective() 1.1237 +{ 1.1238 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1239 + SetValueToCoord(val, StyleDisplay()->mChildPerspective, false); 1.1240 + return val; 1.1241 +} 1.1242 + 1.1243 +CSSValue* 1.1244 +nsComputedDOMStyle::DoGetBackfaceVisibility() 1.1245 +{ 1.1246 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1247 + val->SetIdent( 1.1248 + nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBackfaceVisibility, 1.1249 + nsCSSProps::kBackfaceVisibilityKTable)); 1.1250 + return val; 1.1251 +} 1.1252 + 1.1253 +CSSValue* 1.1254 +nsComputedDOMStyle::DoGetTransformStyle() 1.1255 +{ 1.1256 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.1257 + val->SetIdent( 1.1258 + nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mTransformStyle, 1.1259 + nsCSSProps::kTransformStyleKTable)); 1.1260 + return val; 1.1261 +} 1.1262 + 1.1263 +/* If the property is "none", hand back "none" wrapped in a value. 1.1264 + * Otherwise, compute the aggregate transform matrix and hands it back in a 1.1265 + * "matrix" wrapper. 1.1266 + */ 1.1267 +CSSValue* 1.1268 +nsComputedDOMStyle::DoGetTransform() 1.1269 +{ 1.1270 + /* First, get the display data. We'll need it. */ 1.1271 + const nsStyleDisplay* display = StyleDisplay(); 1.1272 + 1.1273 + /* If there are no transforms, then we should construct a single-element 1.1274 + * entry and hand it back. 1.1275 + */ 1.1276 + if (!display->mSpecifiedTransform) { 1.1277 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1278 + 1.1279 + /* Set it to "none." */ 1.1280 + val->SetIdent(eCSSKeyword_none); 1.1281 + return val; 1.1282 + } 1.1283 + 1.1284 + /* Otherwise, we need to compute the current value of the transform matrix, 1.1285 + * store it in a string, and hand it back to the caller. 1.1286 + */ 1.1287 + 1.1288 + /* Use the inner frame for width and height. If we fail, assume zero. 1.1289 + * TODO: There is no good way for us to represent the case where there's no 1.1290 + * frame, which is problematic. The reason is that when we have percentage 1.1291 + * transforms, there are a total of four stored matrix entries that influence 1.1292 + * the transform based on the size of the element. However, this poses a 1.1293 + * problem, because only two of these values can be explicitly referenced 1.1294 + * using the named transforms. Until a real solution is found, we'll just 1.1295 + * use this approach. 1.1296 + */ 1.1297 + nsRect bounds = 1.1298 + (mInnerFrame ? nsDisplayTransform::GetFrameBoundsForTransform(mInnerFrame) : 1.1299 + nsRect(0, 0, 0, 0)); 1.1300 + 1.1301 + bool dummy; 1.1302 + gfx3DMatrix matrix = 1.1303 + nsStyleTransformMatrix::ReadTransforms(display->mSpecifiedTransform->mHead, 1.1304 + mStyleContextHolder, 1.1305 + mStyleContextHolder->PresContext(), 1.1306 + dummy, 1.1307 + bounds, 1.1308 + float(mozilla::AppUnitsPerCSSPixel())); 1.1309 + 1.1310 + return MatrixToCSSValue(matrix); 1.1311 +} 1.1312 + 1.1313 +/* static */ nsROCSSPrimitiveValue* 1.1314 +nsComputedDOMStyle::MatrixToCSSValue(gfx3DMatrix& matrix) 1.1315 +{ 1.1316 + bool is3D = !matrix.Is2D(); 1.1317 + 1.1318 + nsAutoString resultString(NS_LITERAL_STRING("matrix")); 1.1319 + if (is3D) { 1.1320 + resultString.Append(NS_LITERAL_STRING("3d")); 1.1321 + } 1.1322 + 1.1323 + resultString.Append(NS_LITERAL_STRING("(")); 1.1324 + resultString.AppendFloat(matrix._11); 1.1325 + resultString.Append(NS_LITERAL_STRING(", ")); 1.1326 + resultString.AppendFloat(matrix._12); 1.1327 + resultString.Append(NS_LITERAL_STRING(", ")); 1.1328 + if (is3D) { 1.1329 + resultString.AppendFloat(matrix._13); 1.1330 + resultString.Append(NS_LITERAL_STRING(", ")); 1.1331 + resultString.AppendFloat(matrix._14); 1.1332 + resultString.Append(NS_LITERAL_STRING(", ")); 1.1333 + } 1.1334 + resultString.AppendFloat(matrix._21); 1.1335 + resultString.Append(NS_LITERAL_STRING(", ")); 1.1336 + resultString.AppendFloat(matrix._22); 1.1337 + resultString.Append(NS_LITERAL_STRING(", ")); 1.1338 + if (is3D) { 1.1339 + resultString.AppendFloat(matrix._23); 1.1340 + resultString.Append(NS_LITERAL_STRING(", ")); 1.1341 + resultString.AppendFloat(matrix._24); 1.1342 + resultString.Append(NS_LITERAL_STRING(", ")); 1.1343 + resultString.AppendFloat(matrix._31); 1.1344 + resultString.Append(NS_LITERAL_STRING(", ")); 1.1345 + resultString.AppendFloat(matrix._32); 1.1346 + resultString.Append(NS_LITERAL_STRING(", ")); 1.1347 + resultString.AppendFloat(matrix._33); 1.1348 + resultString.Append(NS_LITERAL_STRING(", ")); 1.1349 + resultString.AppendFloat(matrix._34); 1.1350 + resultString.Append(NS_LITERAL_STRING(", ")); 1.1351 + } 1.1352 + resultString.AppendFloat(matrix._41); 1.1353 + resultString.Append(NS_LITERAL_STRING(", ")); 1.1354 + resultString.AppendFloat(matrix._42); 1.1355 + if (is3D) { 1.1356 + resultString.Append(NS_LITERAL_STRING(", ")); 1.1357 + resultString.AppendFloat(matrix._43); 1.1358 + resultString.Append(NS_LITERAL_STRING(", ")); 1.1359 + resultString.AppendFloat(matrix._44); 1.1360 + } 1.1361 + resultString.Append(NS_LITERAL_STRING(")")); 1.1362 + 1.1363 + /* Create a value to hold our result. */ 1.1364 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1365 + 1.1366 + val->SetString(resultString); 1.1367 + return val; 1.1368 +} 1.1369 + 1.1370 +CSSValue* 1.1371 +nsComputedDOMStyle::DoGetCounterReset() 1.1372 +{ 1.1373 + const nsStyleContent *content = StyleContent(); 1.1374 + 1.1375 + if (content->CounterResetCount() == 0) { 1.1376 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.1377 + val->SetIdent(eCSSKeyword_none); 1.1378 + return val; 1.1379 + } 1.1380 + 1.1381 + nsDOMCSSValueList *valueList = GetROCSSValueList(false); 1.1382 + 1.1383 + for (uint32_t i = 0, i_end = content->CounterResetCount(); i < i_end; ++i) { 1.1384 + nsROCSSPrimitiveValue* name = new nsROCSSPrimitiveValue; 1.1385 + valueList->AppendCSSValue(name); 1.1386 + 1.1387 + nsROCSSPrimitiveValue* value = new nsROCSSPrimitiveValue; 1.1388 + valueList->AppendCSSValue(value); 1.1389 + 1.1390 + const nsStyleCounterData *data = content->GetCounterResetAt(i); 1.1391 + nsAutoString escaped; 1.1392 + nsStyleUtil::AppendEscapedCSSIdent(data->mCounter, escaped); 1.1393 + name->SetString(escaped); 1.1394 + value->SetNumber(data->mValue); // XXX This should really be integer 1.1395 + } 1.1396 + 1.1397 + return valueList; 1.1398 +} 1.1399 + 1.1400 +CSSValue* 1.1401 +nsComputedDOMStyle::DoGetQuotes() 1.1402 +{ 1.1403 + const nsStyleQuotes *quotes = StyleQuotes(); 1.1404 + 1.1405 + if (quotes->QuotesCount() == 0) { 1.1406 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.1407 + val->SetIdent(eCSSKeyword_none); 1.1408 + return val; 1.1409 + } 1.1410 + 1.1411 + nsDOMCSSValueList *valueList = GetROCSSValueList(false); 1.1412 + 1.1413 + for (uint32_t i = 0, i_end = quotes->QuotesCount(); i < i_end; ++i) { 1.1414 + nsROCSSPrimitiveValue* openVal = new nsROCSSPrimitiveValue; 1.1415 + valueList->AppendCSSValue(openVal); 1.1416 + 1.1417 + nsROCSSPrimitiveValue* closeVal = new nsROCSSPrimitiveValue; 1.1418 + valueList->AppendCSSValue(closeVal); 1.1419 + 1.1420 + nsString s; 1.1421 + nsStyleUtil::AppendEscapedCSSString(*quotes->OpenQuoteAt(i), s); 1.1422 + openVal->SetString(s); 1.1423 + s.Truncate(); 1.1424 + nsStyleUtil::AppendEscapedCSSString(*quotes->CloseQuoteAt(i), s); 1.1425 + closeVal->SetString(s); 1.1426 + } 1.1427 + 1.1428 + return valueList; 1.1429 +} 1.1430 + 1.1431 +CSSValue* 1.1432 +nsComputedDOMStyle::DoGetFontFamily() 1.1433 +{ 1.1434 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1435 + 1.1436 + const nsStyleFont* font = StyleFont(); 1.1437 + 1.1438 + nsCOMPtr<nsIDocument> doc = do_QueryReferent(mDocumentWeak); 1.1439 + NS_ASSERTION(doc, "document is required"); 1.1440 + nsIPresShell* presShell = doc->GetShell(); 1.1441 + NS_ASSERTION(presShell, "pres shell is required"); 1.1442 + nsPresContext *presContext = presShell->GetPresContext(); 1.1443 + NS_ASSERTION(presContext, "pres context is required"); 1.1444 + 1.1445 + const nsString& fontName = font->mFont.name; 1.1446 + if (font->mGenericID == kGenericFont_NONE && !font->mFont.systemFont) { 1.1447 + const nsFont* defaultFont = 1.1448 + presContext->GetDefaultFont(kPresContext_DefaultVariableFont_ID, 1.1449 + font->mLanguage); 1.1450 + 1.1451 + int32_t lendiff = fontName.Length() - defaultFont->name.Length(); 1.1452 + if (lendiff > 0) { 1.1453 + val->SetString(Substring(fontName, 0, lendiff-1)); // -1 removes comma 1.1454 + } else { 1.1455 + val->SetString(fontName); 1.1456 + } 1.1457 + } else { 1.1458 + val->SetString(fontName); 1.1459 + } 1.1460 + 1.1461 + return val; 1.1462 +} 1.1463 + 1.1464 +CSSValue* 1.1465 +nsComputedDOMStyle::DoGetFontSize() 1.1466 +{ 1.1467 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1468 + 1.1469 + // Note: StyleFont()->mSize is the 'computed size'; 1.1470 + // StyleFont()->mFont.size is the 'actual size' 1.1471 + val->SetAppUnits(StyleFont()->mSize); 1.1472 + return val; 1.1473 +} 1.1474 + 1.1475 +CSSValue* 1.1476 +nsComputedDOMStyle::DoGetFontSizeAdjust() 1.1477 +{ 1.1478 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.1479 + 1.1480 + const nsStyleFont *font = StyleFont(); 1.1481 + 1.1482 + if (font->mFont.sizeAdjust) { 1.1483 + val->SetNumber(font->mFont.sizeAdjust); 1.1484 + } else { 1.1485 + val->SetIdent(eCSSKeyword_none); 1.1486 + } 1.1487 + 1.1488 + return val; 1.1489 +} 1.1490 + 1.1491 +CSSValue* 1.1492 +nsComputedDOMStyle::DoGetOSXFontSmoothing() 1.1493 +{ 1.1494 + if (!nsContentUtils::IsCallerChrome()) 1.1495 + return nullptr; 1.1496 + 1.1497 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1498 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.smoothing, 1.1499 + nsCSSProps::kFontSmoothingKTable)); 1.1500 + return val; 1.1501 +} 1.1502 + 1.1503 +CSSValue* 1.1504 +nsComputedDOMStyle::DoGetFontStretch() 1.1505 +{ 1.1506 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1507 + 1.1508 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.stretch, 1.1509 + nsCSSProps::kFontStretchKTable)); 1.1510 + 1.1511 + return val; 1.1512 +} 1.1513 + 1.1514 +CSSValue* 1.1515 +nsComputedDOMStyle::DoGetFontStyle() 1.1516 +{ 1.1517 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1518 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.style, 1.1519 + nsCSSProps::kFontStyleKTable)); 1.1520 + return val; 1.1521 +} 1.1522 + 1.1523 +CSSValue* 1.1524 +nsComputedDOMStyle::DoGetFontWeight() 1.1525 +{ 1.1526 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1527 + 1.1528 + const nsStyleFont* font = StyleFont(); 1.1529 + 1.1530 + uint16_t weight = font->mFont.weight; 1.1531 + NS_ASSERTION(weight % 100 == 0, "unexpected value of font-weight"); 1.1532 + val->SetNumber(weight); 1.1533 + 1.1534 + return val; 1.1535 +} 1.1536 + 1.1537 +CSSValue* 1.1538 +nsComputedDOMStyle::DoGetFontVariant() 1.1539 +{ 1.1540 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1541 + val->SetIdent( 1.1542 + nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.variant, 1.1543 + nsCSSProps::kFontVariantKTable)); 1.1544 + return val; 1.1545 +} 1.1546 + 1.1547 +CSSValue* 1.1548 +nsComputedDOMStyle::DoGetFontFeatureSettings() 1.1549 +{ 1.1550 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1551 + 1.1552 + const nsStyleFont* font = StyleFont(); 1.1553 + if (font->mFont.fontFeatureSettings.IsEmpty()) { 1.1554 + val->SetIdent(eCSSKeyword_normal); 1.1555 + } else { 1.1556 + nsAutoString result; 1.1557 + nsStyleUtil::AppendFontFeatureSettings(font->mFont.fontFeatureSettings, 1.1558 + result); 1.1559 + val->SetString(result); 1.1560 + } 1.1561 + return val; 1.1562 +} 1.1563 + 1.1564 +CSSValue* 1.1565 +nsComputedDOMStyle::DoGetFontKerning() 1.1566 +{ 1.1567 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1568 + val->SetIdent( 1.1569 + nsCSSProps::ValueToKeywordEnum(StyleFont()->mFont.kerning, 1.1570 + nsCSSProps::kFontKerningKTable)); 1.1571 + return val; 1.1572 +} 1.1573 + 1.1574 +CSSValue* 1.1575 +nsComputedDOMStyle::DoGetFontLanguageOverride() 1.1576 +{ 1.1577 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1578 + 1.1579 + const nsStyleFont* font = StyleFont(); 1.1580 + if (font->mFont.languageOverride.IsEmpty()) { 1.1581 + val->SetIdent(eCSSKeyword_normal); 1.1582 + } else { 1.1583 + nsString str; 1.1584 + nsStyleUtil::AppendEscapedCSSString(font->mFont.languageOverride, str); 1.1585 + val->SetString(str); 1.1586 + } 1.1587 + return val; 1.1588 +} 1.1589 + 1.1590 +CSSValue* 1.1591 +nsComputedDOMStyle::DoGetFontSynthesis() 1.1592 +{ 1.1593 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1594 + 1.1595 + int32_t intValue = StyleFont()->mFont.synthesis; 1.1596 + 1.1597 + if (0 == intValue) { 1.1598 + val->SetIdent(eCSSKeyword_none); 1.1599 + } else { 1.1600 + nsAutoString valueStr; 1.1601 + 1.1602 + nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_synthesis, 1.1603 + intValue, NS_FONT_SYNTHESIS_WEIGHT, 1.1604 + NS_FONT_SYNTHESIS_STYLE, valueStr); 1.1605 + val->SetString(valueStr); 1.1606 + } 1.1607 + 1.1608 + return val; 1.1609 +} 1.1610 + 1.1611 +CSSValue* 1.1612 +nsComputedDOMStyle::DoGetFontVariantAlternates() 1.1613 +{ 1.1614 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1615 + 1.1616 + int32_t intValue = StyleFont()->mFont.variantAlternates; 1.1617 + 1.1618 + if (0 == intValue) { 1.1619 + val->SetIdent(eCSSKeyword_normal); 1.1620 + return val; 1.1621 + } 1.1622 + 1.1623 + // first, include enumerated values 1.1624 + nsAutoString valueStr; 1.1625 + 1.1626 + nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_alternates, 1.1627 + intValue & NS_FONT_VARIANT_ALTERNATES_ENUMERATED_MASK, 1.1628 + NS_FONT_VARIANT_ALTERNATES_HISTORICAL, 1.1629 + NS_FONT_VARIANT_ALTERNATES_HISTORICAL, valueStr); 1.1630 + 1.1631 + // next, include functional values if present 1.1632 + if (intValue & NS_FONT_VARIANT_ALTERNATES_FUNCTIONAL_MASK) { 1.1633 + nsStyleUtil::SerializeFunctionalAlternates(StyleFont()->mFont.alternateValues, 1.1634 + valueStr); 1.1635 + } 1.1636 + 1.1637 + val->SetString(valueStr); 1.1638 + return val; 1.1639 +} 1.1640 + 1.1641 + 1.1642 +CSSValue* 1.1643 +nsComputedDOMStyle::DoGetFontVariantCaps() 1.1644 +{ 1.1645 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1646 + 1.1647 + int32_t intValue = StyleFont()->mFont.variantCaps; 1.1648 + 1.1649 + if (0 == intValue) { 1.1650 + val->SetIdent(eCSSKeyword_normal); 1.1651 + } else { 1.1652 + val->SetIdent( 1.1653 + nsCSSProps::ValueToKeywordEnum(intValue, 1.1654 + nsCSSProps::kFontVariantCapsKTable)); 1.1655 + } 1.1656 + 1.1657 + return val; 1.1658 +} 1.1659 + 1.1660 +CSSValue* 1.1661 +nsComputedDOMStyle::DoGetFontVariantEastAsian() 1.1662 +{ 1.1663 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1664 + 1.1665 + int32_t intValue = StyleFont()->mFont.variantEastAsian; 1.1666 + 1.1667 + if (0 == intValue) { 1.1668 + val->SetIdent(eCSSKeyword_normal); 1.1669 + } else { 1.1670 + nsAutoString valueStr; 1.1671 + 1.1672 + nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_east_asian, 1.1673 + intValue, NS_FONT_VARIANT_EAST_ASIAN_JIS78, 1.1674 + NS_FONT_VARIANT_EAST_ASIAN_RUBY, valueStr); 1.1675 + val->SetString(valueStr); 1.1676 + } 1.1677 + 1.1678 + return val; 1.1679 +} 1.1680 + 1.1681 +CSSValue* 1.1682 +nsComputedDOMStyle::DoGetFontVariantLigatures() 1.1683 +{ 1.1684 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1685 + 1.1686 + int32_t intValue = StyleFont()->mFont.variantLigatures; 1.1687 + 1.1688 + if (0 == intValue) { 1.1689 + val->SetIdent(eCSSKeyword_normal); 1.1690 + } else { 1.1691 + nsAutoString valueStr; 1.1692 + 1.1693 + nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_ligatures, 1.1694 + intValue, NS_FONT_VARIANT_LIGATURES_NONE, 1.1695 + NS_FONT_VARIANT_LIGATURES_NO_CONTEXTUAL, valueStr); 1.1696 + val->SetString(valueStr); 1.1697 + } 1.1698 + 1.1699 + return val; 1.1700 +} 1.1701 + 1.1702 +CSSValue* 1.1703 +nsComputedDOMStyle::DoGetFontVariantNumeric() 1.1704 +{ 1.1705 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1706 + 1.1707 + int32_t intValue = StyleFont()->mFont.variantNumeric; 1.1708 + 1.1709 + if (0 == intValue) { 1.1710 + val->SetIdent(eCSSKeyword_normal); 1.1711 + } else { 1.1712 + nsAutoString valueStr; 1.1713 + 1.1714 + nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_font_variant_numeric, 1.1715 + intValue, NS_FONT_VARIANT_NUMERIC_LINING, 1.1716 + NS_FONT_VARIANT_NUMERIC_ORDINAL, valueStr); 1.1717 + val->SetString(valueStr); 1.1718 + } 1.1719 + 1.1720 + return val; 1.1721 +} 1.1722 + 1.1723 +CSSValue* 1.1724 +nsComputedDOMStyle::DoGetFontVariantPosition() 1.1725 +{ 1.1726 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1727 + 1.1728 + int32_t intValue = StyleFont()->mFont.variantPosition; 1.1729 + 1.1730 + if (0 == intValue) { 1.1731 + val->SetIdent(eCSSKeyword_normal); 1.1732 + } else { 1.1733 + val->SetIdent( 1.1734 + nsCSSProps::ValueToKeywordEnum(intValue, 1.1735 + nsCSSProps::kFontVariantPositionKTable)); 1.1736 + } 1.1737 + 1.1738 + return val; 1.1739 +} 1.1740 + 1.1741 +CSSValue* 1.1742 +nsComputedDOMStyle::GetBackgroundList(uint8_t nsStyleBackground::Layer::* aMember, 1.1743 + uint32_t nsStyleBackground::* aCount, 1.1744 + const KTableValue aTable[]) 1.1745 +{ 1.1746 + const nsStyleBackground* bg = StyleBackground(); 1.1747 + 1.1748 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.1749 + 1.1750 + for (uint32_t i = 0, i_end = bg->*aCount; i < i_end; ++i) { 1.1751 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.1752 + valueList->AppendCSSValue(val); 1.1753 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(bg->mLayers[i].*aMember, 1.1754 + aTable)); 1.1755 + } 1.1756 + 1.1757 + return valueList; 1.1758 +} 1.1759 + 1.1760 +CSSValue* 1.1761 +nsComputedDOMStyle::DoGetBackgroundAttachment() 1.1762 +{ 1.1763 + return GetBackgroundList(&nsStyleBackground::Layer::mAttachment, 1.1764 + &nsStyleBackground::mAttachmentCount, 1.1765 + nsCSSProps::kBackgroundAttachmentKTable); 1.1766 +} 1.1767 + 1.1768 +CSSValue* 1.1769 +nsComputedDOMStyle::DoGetBackgroundClip() 1.1770 +{ 1.1771 + return GetBackgroundList(&nsStyleBackground::Layer::mClip, 1.1772 + &nsStyleBackground::mClipCount, 1.1773 + nsCSSProps::kBackgroundOriginKTable); 1.1774 +} 1.1775 + 1.1776 +CSSValue* 1.1777 +nsComputedDOMStyle::DoGetBackgroundColor() 1.1778 +{ 1.1779 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.1780 + SetToRGBAColor(val, StyleBackground()->mBackgroundColor); 1.1781 + return val; 1.1782 +} 1.1783 + 1.1784 + 1.1785 +static void 1.1786 +SetValueToCalc(const nsStyleCoord::Calc *aCalc, nsROCSSPrimitiveValue *aValue) 1.1787 +{ 1.1788 + nsRefPtr<nsROCSSPrimitiveValue> val = new nsROCSSPrimitiveValue; 1.1789 + nsAutoString tmp, result; 1.1790 + 1.1791 + result.AppendLiteral("calc("); 1.1792 + 1.1793 + val->SetAppUnits(aCalc->mLength); 1.1794 + val->GetCssText(tmp); 1.1795 + result.Append(tmp); 1.1796 + 1.1797 + if (aCalc->mHasPercent) { 1.1798 + result.AppendLiteral(" + "); 1.1799 + 1.1800 + val->SetPercent(aCalc->mPercent); 1.1801 + val->GetCssText(tmp); 1.1802 + result.Append(tmp); 1.1803 + } 1.1804 + 1.1805 + result.AppendLiteral(")"); 1.1806 + 1.1807 + aValue->SetString(result); // not really SetString 1.1808 +} 1.1809 + 1.1810 +static void 1.1811 +AppendCSSGradientLength(const nsStyleCoord& aValue, 1.1812 + nsROCSSPrimitiveValue* aPrimitive, 1.1813 + nsAString& aString) 1.1814 +{ 1.1815 + nsAutoString tokenString; 1.1816 + if (aValue.IsCalcUnit()) 1.1817 + SetValueToCalc(aValue.GetCalcValue(), aPrimitive); 1.1818 + else if (aValue.GetUnit() == eStyleUnit_Coord) 1.1819 + aPrimitive->SetAppUnits(aValue.GetCoordValue()); 1.1820 + else 1.1821 + aPrimitive->SetPercent(aValue.GetPercentValue()); 1.1822 + aPrimitive->GetCssText(tokenString); 1.1823 + aString.Append(tokenString); 1.1824 +} 1.1825 + 1.1826 +static void 1.1827 +AppendCSSGradientToBoxPosition(const nsStyleGradient* aGradient, 1.1828 + nsAString& aString, 1.1829 + bool& aNeedSep) 1.1830 +{ 1.1831 + float xValue = aGradient->mBgPosX.GetPercentValue(); 1.1832 + float yValue = aGradient->mBgPosY.GetPercentValue(); 1.1833 + 1.1834 + if (yValue == 1.0f && xValue == 0.5f) { 1.1835 + // omit "to bottom" 1.1836 + return; 1.1837 + } 1.1838 + NS_ASSERTION(yValue != 0.5f || xValue != 0.5f, "invalid box position"); 1.1839 + 1.1840 + aString.AppendLiteral("to"); 1.1841 + 1.1842 + if (yValue == 0.0f) { 1.1843 + aString.AppendLiteral(" top"); 1.1844 + } else if (yValue == 1.0f) { 1.1845 + aString.AppendLiteral(" bottom"); 1.1846 + } else if (yValue != 0.5f) { // do not write "center" keyword 1.1847 + NS_NOTREACHED("invalid box position"); 1.1848 + } 1.1849 + 1.1850 + if (xValue == 0.0f) { 1.1851 + aString.AppendLiteral(" left"); 1.1852 + } else if (xValue == 1.0f) { 1.1853 + aString.AppendLiteral(" right"); 1.1854 + } else if (xValue != 0.5f) { // do not write "center" keyword 1.1855 + NS_NOTREACHED("invalid box position"); 1.1856 + } 1.1857 + 1.1858 + aNeedSep = true; 1.1859 +} 1.1860 + 1.1861 +void 1.1862 +nsComputedDOMStyle::GetCSSGradientString(const nsStyleGradient* aGradient, 1.1863 + nsAString& aString) 1.1864 +{ 1.1865 + if (!aGradient->mLegacySyntax) { 1.1866 + aString.Truncate(); 1.1867 + } else { 1.1868 + aString.AssignLiteral("-moz-"); 1.1869 + } 1.1870 + if (aGradient->mRepeating) { 1.1871 + aString.AppendLiteral("repeating-"); 1.1872 + } 1.1873 + bool isRadial = aGradient->mShape != NS_STYLE_GRADIENT_SHAPE_LINEAR; 1.1874 + if (isRadial) { 1.1875 + aString.AppendLiteral("radial-gradient("); 1.1876 + } else { 1.1877 + aString.AppendLiteral("linear-gradient("); 1.1878 + } 1.1879 + 1.1880 + bool needSep = false; 1.1881 + nsAutoString tokenString; 1.1882 + nsROCSSPrimitiveValue *tmpVal = new nsROCSSPrimitiveValue; 1.1883 + 1.1884 + if (isRadial && !aGradient->mLegacySyntax) { 1.1885 + if (aGradient->mSize != NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE) { 1.1886 + if (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_CIRCULAR) { 1.1887 + aString.AppendLiteral("circle"); 1.1888 + needSep = true; 1.1889 + } 1.1890 + if (aGradient->mSize != NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER) { 1.1891 + if (needSep) { 1.1892 + aString.AppendLiteral(" "); 1.1893 + } 1.1894 + AppendASCIItoUTF16(nsCSSProps:: 1.1895 + ValueToKeyword(aGradient->mSize, 1.1896 + nsCSSProps::kRadialGradientSizeKTable), 1.1897 + aString); 1.1898 + needSep = true; 1.1899 + } 1.1900 + } else { 1.1901 + AppendCSSGradientLength(aGradient->mRadiusX, tmpVal, aString); 1.1902 + if (aGradient->mShape != NS_STYLE_GRADIENT_SHAPE_CIRCULAR) { 1.1903 + aString.AppendLiteral(" "); 1.1904 + AppendCSSGradientLength(aGradient->mRadiusY, tmpVal, aString); 1.1905 + } 1.1906 + needSep = true; 1.1907 + } 1.1908 + } 1.1909 + if (aGradient->mBgPosX.GetUnit() != eStyleUnit_None) { 1.1910 + MOZ_ASSERT(aGradient->mBgPosY.GetUnit() != eStyleUnit_None); 1.1911 + if (!isRadial && !aGradient->mLegacySyntax) { 1.1912 + AppendCSSGradientToBoxPosition(aGradient, aString, needSep); 1.1913 + } else if (aGradient->mBgPosX.GetUnit() != eStyleUnit_Percent || 1.1914 + aGradient->mBgPosX.GetPercentValue() != 0.5f || 1.1915 + aGradient->mBgPosY.GetUnit() != eStyleUnit_Percent || 1.1916 + aGradient->mBgPosY.GetPercentValue() != (isRadial ? 0.5f : 1.0f)) { 1.1917 + if (isRadial && !aGradient->mLegacySyntax) { 1.1918 + if (needSep) { 1.1919 + aString.AppendLiteral(" "); 1.1920 + } 1.1921 + aString.AppendLiteral("at "); 1.1922 + needSep = false; 1.1923 + } 1.1924 + AppendCSSGradientLength(aGradient->mBgPosX, tmpVal, aString); 1.1925 + if (aGradient->mBgPosY.GetUnit() != eStyleUnit_None) { 1.1926 + aString.AppendLiteral(" "); 1.1927 + AppendCSSGradientLength(aGradient->mBgPosY, tmpVal, aString); 1.1928 + } 1.1929 + needSep = true; 1.1930 + } 1.1931 + } 1.1932 + if (aGradient->mAngle.GetUnit() != eStyleUnit_None) { 1.1933 + MOZ_ASSERT(!isRadial || aGradient->mLegacySyntax); 1.1934 + if (needSep) { 1.1935 + aString.AppendLiteral(" "); 1.1936 + } 1.1937 + nsStyleUtil::AppendAngleValue(aGradient->mAngle, aString); 1.1938 + needSep = true; 1.1939 + } 1.1940 + 1.1941 + if (isRadial && aGradient->mLegacySyntax && 1.1942 + (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_CIRCULAR || 1.1943 + aGradient->mSize != NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER)) { 1.1944 + MOZ_ASSERT(aGradient->mSize != NS_STYLE_GRADIENT_SIZE_EXPLICIT_SIZE); 1.1945 + if (needSep) { 1.1946 + aString.AppendLiteral(", "); 1.1947 + needSep = false; 1.1948 + } 1.1949 + if (aGradient->mShape == NS_STYLE_GRADIENT_SHAPE_CIRCULAR) { 1.1950 + aString.AppendLiteral("circle"); 1.1951 + needSep = true; 1.1952 + } 1.1953 + if (aGradient->mSize != NS_STYLE_GRADIENT_SIZE_FARTHEST_CORNER) { 1.1954 + if (needSep) { 1.1955 + aString.AppendLiteral(" "); 1.1956 + } 1.1957 + AppendASCIItoUTF16(nsCSSProps:: 1.1958 + ValueToKeyword(aGradient->mSize, 1.1959 + nsCSSProps::kRadialGradientSizeKTable), 1.1960 + aString); 1.1961 + } 1.1962 + needSep = true; 1.1963 + } 1.1964 + 1.1965 + 1.1966 + // color stops 1.1967 + for (uint32_t i = 0; i < aGradient->mStops.Length(); ++i) { 1.1968 + if (needSep) { 1.1969 + aString.AppendLiteral(", "); 1.1970 + } 1.1971 + SetToRGBAColor(tmpVal, aGradient->mStops[i].mColor); 1.1972 + tmpVal->GetCssText(tokenString); 1.1973 + aString.Append(tokenString); 1.1974 + 1.1975 + if (aGradient->mStops[i].mLocation.GetUnit() != eStyleUnit_None) { 1.1976 + aString.AppendLiteral(" "); 1.1977 + AppendCSSGradientLength(aGradient->mStops[i].mLocation, tmpVal, aString); 1.1978 + } 1.1979 + needSep = true; 1.1980 + } 1.1981 + 1.1982 + delete tmpVal; 1.1983 + aString.AppendLiteral(")"); 1.1984 +} 1.1985 + 1.1986 +// -moz-image-rect(<uri>, <top>, <right>, <bottom>, <left>) 1.1987 +void 1.1988 +nsComputedDOMStyle::GetImageRectString(nsIURI* aURI, 1.1989 + const nsStyleSides& aCropRect, 1.1990 + nsString& aString) 1.1991 +{ 1.1992 + nsDOMCSSValueList* valueList = GetROCSSValueList(true); 1.1993 + 1.1994 + // <uri> 1.1995 + nsROCSSPrimitiveValue *valURI = new nsROCSSPrimitiveValue; 1.1996 + valueList->AppendCSSValue(valURI); 1.1997 + valURI->SetURI(aURI); 1.1998 + 1.1999 + // <top>, <right>, <bottom>, <left> 1.2000 + NS_FOR_CSS_SIDES(side) { 1.2001 + nsROCSSPrimitiveValue *valSide = new nsROCSSPrimitiveValue; 1.2002 + valueList->AppendCSSValue(valSide); 1.2003 + SetValueToCoord(valSide, aCropRect.Get(side), false); 1.2004 + } 1.2005 + 1.2006 + nsAutoString argumentString; 1.2007 + valueList->GetCssText(argumentString); 1.2008 + delete valueList; 1.2009 + 1.2010 + aString = NS_LITERAL_STRING("-moz-image-rect(") + 1.2011 + argumentString + 1.2012 + NS_LITERAL_STRING(")"); 1.2013 +} 1.2014 + 1.2015 +void 1.2016 +nsComputedDOMStyle::SetValueToStyleImage(const nsStyleImage& aStyleImage, 1.2017 + nsROCSSPrimitiveValue* aValue) 1.2018 +{ 1.2019 + switch (aStyleImage.GetType()) { 1.2020 + case eStyleImageType_Image: 1.2021 + { 1.2022 + imgIRequest *req = aStyleImage.GetImageData(); 1.2023 + nsCOMPtr<nsIURI> uri; 1.2024 + req->GetURI(getter_AddRefs(uri)); 1.2025 + 1.2026 + const nsStyleSides* cropRect = aStyleImage.GetCropRect(); 1.2027 + if (cropRect) { 1.2028 + nsAutoString imageRectString; 1.2029 + GetImageRectString(uri, *cropRect, imageRectString); 1.2030 + aValue->SetString(imageRectString); 1.2031 + } else { 1.2032 + aValue->SetURI(uri); 1.2033 + } 1.2034 + break; 1.2035 + } 1.2036 + case eStyleImageType_Gradient: 1.2037 + { 1.2038 + nsAutoString gradientString; 1.2039 + GetCSSGradientString(aStyleImage.GetGradientData(), 1.2040 + gradientString); 1.2041 + aValue->SetString(gradientString); 1.2042 + break; 1.2043 + } 1.2044 + case eStyleImageType_Element: 1.2045 + { 1.2046 + nsAutoString elementId; 1.2047 + nsStyleUtil::AppendEscapedCSSIdent( 1.2048 + nsDependentString(aStyleImage.GetElementId()), elementId); 1.2049 + nsAutoString elementString = NS_LITERAL_STRING("-moz-element(#") + 1.2050 + elementId + 1.2051 + NS_LITERAL_STRING(")"); 1.2052 + aValue->SetString(elementString); 1.2053 + break; 1.2054 + } 1.2055 + case eStyleImageType_Null: 1.2056 + aValue->SetIdent(eCSSKeyword_none); 1.2057 + break; 1.2058 + default: 1.2059 + NS_NOTREACHED("unexpected image type"); 1.2060 + break; 1.2061 + } 1.2062 +} 1.2063 + 1.2064 +CSSValue* 1.2065 +nsComputedDOMStyle::DoGetBackgroundImage() 1.2066 +{ 1.2067 + const nsStyleBackground* bg = StyleBackground(); 1.2068 + 1.2069 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.2070 + 1.2071 + for (uint32_t i = 0, i_end = bg->mImageCount; i < i_end; ++i) { 1.2072 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.2073 + valueList->AppendCSSValue(val); 1.2074 + 1.2075 + const nsStyleImage& image = bg->mLayers[i].mImage; 1.2076 + SetValueToStyleImage(image, val); 1.2077 + } 1.2078 + 1.2079 + return valueList; 1.2080 +} 1.2081 + 1.2082 +CSSValue* 1.2083 +nsComputedDOMStyle::DoGetBackgroundInlinePolicy() 1.2084 +{ 1.2085 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.2086 + val->SetIdent(nsCSSProps::ValueToKeywordEnum( 1.2087 + StyleBackground()->mBackgroundInlinePolicy, 1.2088 + nsCSSProps::kBackgroundInlinePolicyKTable)); 1.2089 + return val; 1.2090 +} 1.2091 + 1.2092 +CSSValue* 1.2093 +nsComputedDOMStyle::DoGetBackgroundBlendMode() 1.2094 +{ 1.2095 + return GetBackgroundList(&nsStyleBackground::Layer::mBlendMode, 1.2096 + &nsStyleBackground::mBlendModeCount, 1.2097 + nsCSSProps::kBlendModeKTable); 1.2098 +} 1.2099 + 1.2100 +CSSValue* 1.2101 +nsComputedDOMStyle::DoGetBackgroundOrigin() 1.2102 +{ 1.2103 + return GetBackgroundList(&nsStyleBackground::Layer::mOrigin, 1.2104 + &nsStyleBackground::mOriginCount, 1.2105 + nsCSSProps::kBackgroundOriginKTable); 1.2106 +} 1.2107 + 1.2108 +CSSValue* 1.2109 +nsComputedDOMStyle::DoGetBackgroundPosition() 1.2110 +{ 1.2111 + const nsStyleBackground* bg = StyleBackground(); 1.2112 + 1.2113 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.2114 + 1.2115 + for (uint32_t i = 0, i_end = bg->mPositionCount; i < i_end; ++i) { 1.2116 + nsDOMCSSValueList *itemList = GetROCSSValueList(false); 1.2117 + valueList->AppendCSSValue(itemList); 1.2118 + 1.2119 + nsROCSSPrimitiveValue *valX = new nsROCSSPrimitiveValue; 1.2120 + itemList->AppendCSSValue(valX); 1.2121 + 1.2122 + nsROCSSPrimitiveValue *valY = new nsROCSSPrimitiveValue; 1.2123 + itemList->AppendCSSValue(valY); 1.2124 + 1.2125 + const nsStyleBackground::Position &pos = bg->mLayers[i].mPosition; 1.2126 + 1.2127 + if (!pos.mXPosition.mHasPercent) { 1.2128 + NS_ABORT_IF_FALSE(pos.mXPosition.mPercent == 0.0f, 1.2129 + "Shouldn't have mPercent!"); 1.2130 + valX->SetAppUnits(pos.mXPosition.mLength); 1.2131 + } else if (pos.mXPosition.mLength == 0) { 1.2132 + valX->SetPercent(pos.mXPosition.mPercent); 1.2133 + } else { 1.2134 + SetValueToCalc(&pos.mXPosition, valX); 1.2135 + } 1.2136 + 1.2137 + if (!pos.mYPosition.mHasPercent) { 1.2138 + NS_ABORT_IF_FALSE(pos.mYPosition.mPercent == 0.0f, 1.2139 + "Shouldn't have mPercent!"); 1.2140 + valY->SetAppUnits(pos.mYPosition.mLength); 1.2141 + } else if (pos.mYPosition.mLength == 0) { 1.2142 + valY->SetPercent(pos.mYPosition.mPercent); 1.2143 + } else { 1.2144 + SetValueToCalc(&pos.mYPosition, valY); 1.2145 + } 1.2146 + } 1.2147 + 1.2148 + return valueList; 1.2149 +} 1.2150 + 1.2151 +CSSValue* 1.2152 +nsComputedDOMStyle::DoGetBackgroundRepeat() 1.2153 +{ 1.2154 + const nsStyleBackground* bg = StyleBackground(); 1.2155 + 1.2156 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.2157 + 1.2158 + for (uint32_t i = 0, i_end = bg->mRepeatCount; i < i_end; ++i) { 1.2159 + nsDOMCSSValueList *itemList = GetROCSSValueList(false); 1.2160 + valueList->AppendCSSValue(itemList); 1.2161 + 1.2162 + nsROCSSPrimitiveValue *valX = new nsROCSSPrimitiveValue; 1.2163 + itemList->AppendCSSValue(valX); 1.2164 + 1.2165 + const uint8_t& xRepeat = bg->mLayers[i].mRepeat.mXRepeat; 1.2166 + const uint8_t& yRepeat = bg->mLayers[i].mRepeat.mYRepeat; 1.2167 + 1.2168 + bool hasContraction = true; 1.2169 + unsigned contraction; 1.2170 + if (xRepeat == yRepeat) { 1.2171 + contraction = xRepeat; 1.2172 + } else if (xRepeat == NS_STYLE_BG_REPEAT_REPEAT && 1.2173 + yRepeat == NS_STYLE_BG_REPEAT_NO_REPEAT) { 1.2174 + contraction = NS_STYLE_BG_REPEAT_REPEAT_X; 1.2175 + } else if (xRepeat == NS_STYLE_BG_REPEAT_NO_REPEAT && 1.2176 + yRepeat == NS_STYLE_BG_REPEAT_REPEAT) { 1.2177 + contraction = NS_STYLE_BG_REPEAT_REPEAT_Y; 1.2178 + } else { 1.2179 + hasContraction = false; 1.2180 + } 1.2181 + 1.2182 + if (hasContraction) { 1.2183 + valX->SetIdent(nsCSSProps::ValueToKeywordEnum(contraction, 1.2184 + nsCSSProps::kBackgroundRepeatKTable)); 1.2185 + } else { 1.2186 + nsROCSSPrimitiveValue *valY = new nsROCSSPrimitiveValue; 1.2187 + itemList->AppendCSSValue(valY); 1.2188 + 1.2189 + valX->SetIdent(nsCSSProps::ValueToKeywordEnum(xRepeat, 1.2190 + nsCSSProps::kBackgroundRepeatKTable)); 1.2191 + valY->SetIdent(nsCSSProps::ValueToKeywordEnum(yRepeat, 1.2192 + nsCSSProps::kBackgroundRepeatKTable)); 1.2193 + } 1.2194 + } 1.2195 + 1.2196 + return valueList; 1.2197 +} 1.2198 + 1.2199 +CSSValue* 1.2200 +nsComputedDOMStyle::DoGetBackgroundSize() 1.2201 +{ 1.2202 + const nsStyleBackground* bg = StyleBackground(); 1.2203 + 1.2204 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.2205 + 1.2206 + for (uint32_t i = 0, i_end = bg->mSizeCount; i < i_end; ++i) { 1.2207 + const nsStyleBackground::Size &size = bg->mLayers[i].mSize; 1.2208 + 1.2209 + switch (size.mWidthType) { 1.2210 + case nsStyleBackground::Size::eContain: 1.2211 + case nsStyleBackground::Size::eCover: { 1.2212 + NS_ABORT_IF_FALSE(size.mWidthType == size.mHeightType, 1.2213 + "unsynced types"); 1.2214 + nsCSSKeyword keyword = size.mWidthType == nsStyleBackground::Size::eContain 1.2215 + ? eCSSKeyword_contain 1.2216 + : eCSSKeyword_cover; 1.2217 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.2218 + valueList->AppendCSSValue(val); 1.2219 + val->SetIdent(keyword); 1.2220 + break; 1.2221 + } 1.2222 + default: { 1.2223 + nsDOMCSSValueList *itemList = GetROCSSValueList(false); 1.2224 + valueList->AppendCSSValue(itemList); 1.2225 + 1.2226 + nsROCSSPrimitiveValue* valX = new nsROCSSPrimitiveValue; 1.2227 + itemList->AppendCSSValue(valX); 1.2228 + nsROCSSPrimitiveValue* valY = new nsROCSSPrimitiveValue; 1.2229 + itemList->AppendCSSValue(valY); 1.2230 + 1.2231 + if (size.mWidthType == nsStyleBackground::Size::eAuto) { 1.2232 + valX->SetIdent(eCSSKeyword_auto); 1.2233 + } else { 1.2234 + NS_ABORT_IF_FALSE(size.mWidthType == 1.2235 + nsStyleBackground::Size::eLengthPercentage, 1.2236 + "bad mWidthType"); 1.2237 + if (!size.mWidth.mHasPercent && 1.2238 + // negative values must have come from calc() 1.2239 + size.mWidth.mLength >= 0) { 1.2240 + NS_ABORT_IF_FALSE(size.mWidth.mPercent == 0.0f, 1.2241 + "Shouldn't have mPercent"); 1.2242 + valX->SetAppUnits(size.mWidth.mLength); 1.2243 + } else if (size.mWidth.mLength == 0 && 1.2244 + // negative values must have come from calc() 1.2245 + size.mWidth.mPercent >= 0.0f) { 1.2246 + valX->SetPercent(size.mWidth.mPercent); 1.2247 + } else { 1.2248 + SetValueToCalc(&size.mWidth, valX); 1.2249 + } 1.2250 + } 1.2251 + 1.2252 + if (size.mHeightType == nsStyleBackground::Size::eAuto) { 1.2253 + valY->SetIdent(eCSSKeyword_auto); 1.2254 + } else { 1.2255 + NS_ABORT_IF_FALSE(size.mHeightType == 1.2256 + nsStyleBackground::Size::eLengthPercentage, 1.2257 + "bad mHeightType"); 1.2258 + if (!size.mHeight.mHasPercent && 1.2259 + // negative values must have come from calc() 1.2260 + size.mHeight.mLength >= 0) { 1.2261 + NS_ABORT_IF_FALSE(size.mHeight.mPercent == 0.0f, 1.2262 + "Shouldn't have mPercent"); 1.2263 + valY->SetAppUnits(size.mHeight.mLength); 1.2264 + } else if (size.mHeight.mLength == 0 && 1.2265 + // negative values must have come from calc() 1.2266 + size.mHeight.mPercent >= 0.0f) { 1.2267 + valY->SetPercent(size.mHeight.mPercent); 1.2268 + } else { 1.2269 + SetValueToCalc(&size.mHeight, valY); 1.2270 + } 1.2271 + } 1.2272 + break; 1.2273 + } 1.2274 + } 1.2275 + } 1.2276 + 1.2277 + return valueList; 1.2278 +} 1.2279 + 1.2280 +CSSValue* 1.2281 +nsComputedDOMStyle::DoGetGridTemplateAreas() 1.2282 +{ 1.2283 + const css::GridTemplateAreasValue* areas = 1.2284 + StylePosition()->mGridTemplateAreas; 1.2285 + if (!areas) { 1.2286 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.2287 + val->SetIdent(eCSSKeyword_none); 1.2288 + return val; 1.2289 + } 1.2290 + 1.2291 + MOZ_ASSERT(!areas->mTemplates.IsEmpty(), 1.2292 + "Unexpected empty array in GridTemplateAreasValue"); 1.2293 + nsDOMCSSValueList *valueList = GetROCSSValueList(false); 1.2294 + for (uint32_t i = 0; i < areas->mTemplates.Length(); i++) { 1.2295 + nsAutoString str; 1.2296 + nsStyleUtil::AppendEscapedCSSString(areas->mTemplates[i], str); 1.2297 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.2298 + val->SetString(str); 1.2299 + valueList->AppendCSSValue(val); 1.2300 + } 1.2301 + return valueList; 1.2302 +} 1.2303 + 1.2304 +// aLineNames must not be empty 1.2305 +CSSValue* 1.2306 +nsComputedDOMStyle::GetGridLineNames(const nsTArray<nsString>& aLineNames) 1.2307 +{ 1.2308 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.2309 + nsAutoString lineNamesString; 1.2310 + uint32_t i_end = aLineNames.Length(); 1.2311 + lineNamesString.AssignLiteral("("); 1.2312 + if (i_end > 0) { 1.2313 + for (uint32_t i = 0;;) { 1.2314 + nsStyleUtil::AppendEscapedCSSIdent(aLineNames[i], lineNamesString); 1.2315 + if (++i == i_end) { 1.2316 + break; 1.2317 + } 1.2318 + lineNamesString.AppendLiteral(" "); 1.2319 + } 1.2320 + } 1.2321 + lineNamesString.AppendLiteral(")"); 1.2322 + val->SetString(lineNamesString); 1.2323 + return val; 1.2324 +} 1.2325 + 1.2326 +CSSValue* 1.2327 +nsComputedDOMStyle::GetGridTrackSize(const nsStyleCoord& aMinValue, 1.2328 + const nsStyleCoord& aMaxValue) 1.2329 +{ 1.2330 + // FIXME bug 978212: for grid-template-columns and grid-template-rows 1.2331 + // (not grid-auto-columns and grid-auto-rows), if we have frame, 1.2332 + // every <track-size> should be resolved into 'px' here, 1.2333 + // based on layout results. 1.2334 + if (aMinValue == aMaxValue) { 1.2335 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.2336 + SetValueToCoord(val, aMinValue, true, 1.2337 + nullptr, nsCSSProps::kGridTrackBreadthKTable); 1.2338 + return val; 1.2339 + } 1.2340 + 1.2341 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.2342 + nsAutoString argumentStr, minmaxStr; 1.2343 + minmaxStr.AppendLiteral("minmax("); 1.2344 + 1.2345 + SetValueToCoord(val, aMinValue, true, 1.2346 + nullptr, nsCSSProps::kGridTrackBreadthKTable); 1.2347 + val->GetCssText(argumentStr); 1.2348 + minmaxStr.Append(argumentStr); 1.2349 + 1.2350 + minmaxStr.AppendLiteral(", "); 1.2351 + 1.2352 + SetValueToCoord(val, aMaxValue, true, 1.2353 + nullptr, nsCSSProps::kGridTrackBreadthKTable); 1.2354 + val->GetCssText(argumentStr); 1.2355 + minmaxStr.Append(argumentStr); 1.2356 + 1.2357 + minmaxStr.Append(char16_t(')')); 1.2358 + val->SetString(minmaxStr); 1.2359 + return val; 1.2360 +} 1.2361 + 1.2362 +CSSValue* 1.2363 +nsComputedDOMStyle::GetGridTemplateColumnsRows(const nsStyleGridTemplate& aTrackList) 1.2364 +{ 1.2365 + if (aTrackList.mIsSubgrid) { 1.2366 + NS_ASSERTION(aTrackList.mMinTrackSizingFunctions.IsEmpty() && 1.2367 + aTrackList.mMaxTrackSizingFunctions.IsEmpty(), 1.2368 + "Unexpected sizing functions with subgrid"); 1.2369 + nsDOMCSSValueList* valueList = GetROCSSValueList(false); 1.2370 + 1.2371 + nsROCSSPrimitiveValue* subgridKeyword = new nsROCSSPrimitiveValue; 1.2372 + subgridKeyword->SetIdent(eCSSKeyword_subgrid); 1.2373 + valueList->AppendCSSValue(subgridKeyword); 1.2374 + 1.2375 + for (uint32_t i = 0; i < aTrackList.mLineNameLists.Length(); i++) { 1.2376 + valueList->AppendCSSValue(GetGridLineNames(aTrackList.mLineNameLists[i])); 1.2377 + } 1.2378 + return valueList; 1.2379 + } 1.2380 + 1.2381 + uint32_t numSizes = aTrackList.mMinTrackSizingFunctions.Length(); 1.2382 + MOZ_ASSERT(aTrackList.mMaxTrackSizingFunctions.Length() == numSizes, 1.2383 + "Different number of min and max track sizing functions"); 1.2384 + // An empty <track-list> is represented as "none" in syntax. 1.2385 + if (numSizes == 0) { 1.2386 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.2387 + val->SetIdent(eCSSKeyword_none); 1.2388 + return val; 1.2389 + } 1.2390 + 1.2391 + nsDOMCSSValueList* valueList = GetROCSSValueList(false); 1.2392 + // Delimiting N tracks requires N+1 lines: 1.2393 + // one before each track, plus one at the very end. 1.2394 + MOZ_ASSERT(aTrackList.mLineNameLists.Length() == numSizes + 1, 1.2395 + "Unexpected number of line name lists"); 1.2396 + for (uint32_t i = 0;; i++) { 1.2397 + const nsTArray<nsString>& lineNames = aTrackList.mLineNameLists[i]; 1.2398 + if (!lineNames.IsEmpty()) { 1.2399 + valueList->AppendCSSValue(GetGridLineNames(lineNames)); 1.2400 + } 1.2401 + if (i == numSizes) { 1.2402 + break; 1.2403 + } 1.2404 + valueList->AppendCSSValue(GetGridTrackSize(aTrackList.mMinTrackSizingFunctions[i], 1.2405 + aTrackList.mMaxTrackSizingFunctions[i])); 1.2406 + } 1.2407 + 1.2408 + return valueList; 1.2409 +} 1.2410 + 1.2411 +CSSValue* 1.2412 +nsComputedDOMStyle::DoGetGridAutoFlow() 1.2413 +{ 1.2414 + nsAutoString str; 1.2415 + nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_grid_auto_flow, 1.2416 + StylePosition()->mGridAutoFlow, 1.2417 + NS_STYLE_GRID_AUTO_FLOW_NONE, 1.2418 + NS_STYLE_GRID_AUTO_FLOW_DENSE, 1.2419 + str); 1.2420 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.2421 + val->SetString(str); 1.2422 + return val; 1.2423 +} 1.2424 + 1.2425 +CSSValue* 1.2426 +nsComputedDOMStyle::DoGetGridAutoColumns() 1.2427 +{ 1.2428 + return GetGridTrackSize(StylePosition()->mGridAutoColumnsMin, 1.2429 + StylePosition()->mGridAutoColumnsMax); 1.2430 +} 1.2431 + 1.2432 +CSSValue* 1.2433 +nsComputedDOMStyle::DoGetGridAutoRows() 1.2434 +{ 1.2435 + return GetGridTrackSize(StylePosition()->mGridAutoRowsMin, 1.2436 + StylePosition()->mGridAutoRowsMax); 1.2437 +} 1.2438 + 1.2439 +CSSValue* 1.2440 +nsComputedDOMStyle::DoGetGridTemplateColumns() 1.2441 +{ 1.2442 + return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateColumns); 1.2443 +} 1.2444 + 1.2445 +CSSValue* 1.2446 +nsComputedDOMStyle::DoGetGridTemplateRows() 1.2447 +{ 1.2448 + return GetGridTemplateColumnsRows(StylePosition()->mGridTemplateRows); 1.2449 +} 1.2450 + 1.2451 +CSSValue* 1.2452 +nsComputedDOMStyle::GetGridLine(const nsStyleGridLine& aGridLine) 1.2453 +{ 1.2454 + if (aGridLine.IsAuto()) { 1.2455 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.2456 + val->SetIdent(eCSSKeyword_auto); 1.2457 + return val; 1.2458 + } 1.2459 + 1.2460 + nsDOMCSSValueList* valueList = GetROCSSValueList(false); 1.2461 + 1.2462 + if (aGridLine.mHasSpan) { 1.2463 + nsROCSSPrimitiveValue* span = new nsROCSSPrimitiveValue; 1.2464 + span->SetIdent(eCSSKeyword_span); 1.2465 + valueList->AppendCSSValue(span); 1.2466 + } 1.2467 + 1.2468 + if (aGridLine.mInteger != 0) { 1.2469 + nsROCSSPrimitiveValue* integer = new nsROCSSPrimitiveValue; 1.2470 + integer->SetNumber(aGridLine.mInteger); 1.2471 + valueList->AppendCSSValue(integer); 1.2472 + } 1.2473 + 1.2474 + if (!aGridLine.mLineName.IsEmpty()) { 1.2475 + nsROCSSPrimitiveValue* lineName = new nsROCSSPrimitiveValue; 1.2476 + nsString escapedLineName; 1.2477 + nsStyleUtil::AppendEscapedCSSIdent(aGridLine.mLineName, escapedLineName); 1.2478 + lineName->SetString(escapedLineName); 1.2479 + valueList->AppendCSSValue(lineName); 1.2480 + } 1.2481 + 1.2482 + NS_ASSERTION(valueList->Length() > 0, 1.2483 + "Should have appended at least one value"); 1.2484 + return valueList; 1.2485 +} 1.2486 + 1.2487 +CSSValue* 1.2488 +nsComputedDOMStyle::DoGetGridAutoPosition() 1.2489 +{ 1.2490 + nsDOMCSSValueList* valueList = GetROCSSValueList(false); 1.2491 + 1.2492 + valueList->AppendCSSValue( 1.2493 + GetGridLine(StylePosition()->mGridAutoPositionColumn)); 1.2494 + 1.2495 + nsROCSSPrimitiveValue* slash = new nsROCSSPrimitiveValue; 1.2496 + slash->SetString(NS_LITERAL_STRING("/")); 1.2497 + valueList->AppendCSSValue(slash); 1.2498 + 1.2499 + valueList->AppendCSSValue( 1.2500 + GetGridLine(StylePosition()->mGridAutoPositionRow)); 1.2501 + 1.2502 + return valueList; 1.2503 +} 1.2504 + 1.2505 +CSSValue* 1.2506 +nsComputedDOMStyle::DoGetGridColumnStart() 1.2507 +{ 1.2508 + return GetGridLine(StylePosition()->mGridColumnStart); 1.2509 +} 1.2510 + 1.2511 +CSSValue* 1.2512 +nsComputedDOMStyle::DoGetGridColumnEnd() 1.2513 +{ 1.2514 + return GetGridLine(StylePosition()->mGridColumnEnd); 1.2515 +} 1.2516 + 1.2517 +CSSValue* 1.2518 +nsComputedDOMStyle::DoGetGridRowStart() 1.2519 +{ 1.2520 + return GetGridLine(StylePosition()->mGridRowStart); 1.2521 +} 1.2522 + 1.2523 +CSSValue* 1.2524 +nsComputedDOMStyle::DoGetGridRowEnd() 1.2525 +{ 1.2526 + return GetGridLine(StylePosition()->mGridRowEnd); 1.2527 +} 1.2528 + 1.2529 +CSSValue* 1.2530 +nsComputedDOMStyle::DoGetPaddingTop() 1.2531 +{ 1.2532 + return GetPaddingWidthFor(NS_SIDE_TOP); 1.2533 +} 1.2534 + 1.2535 +CSSValue* 1.2536 +nsComputedDOMStyle::DoGetPaddingBottom() 1.2537 +{ 1.2538 + return GetPaddingWidthFor(NS_SIDE_BOTTOM); 1.2539 +} 1.2540 + 1.2541 +CSSValue* 1.2542 +nsComputedDOMStyle::DoGetPaddingLeft() 1.2543 +{ 1.2544 + return GetPaddingWidthFor(NS_SIDE_LEFT); 1.2545 +} 1.2546 + 1.2547 +CSSValue* 1.2548 +nsComputedDOMStyle::DoGetPaddingRight() 1.2549 +{ 1.2550 + return GetPaddingWidthFor(NS_SIDE_RIGHT); 1.2551 +} 1.2552 + 1.2553 +CSSValue* 1.2554 +nsComputedDOMStyle::DoGetBorderCollapse() 1.2555 +{ 1.2556 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.2557 + val->SetIdent( 1.2558 + nsCSSProps::ValueToKeywordEnum(StyleTableBorder()->mBorderCollapse, 1.2559 + nsCSSProps::kBorderCollapseKTable)); 1.2560 + return val; 1.2561 +} 1.2562 + 1.2563 +CSSValue* 1.2564 +nsComputedDOMStyle::DoGetBorderSpacing() 1.2565 +{ 1.2566 + nsDOMCSSValueList *valueList = GetROCSSValueList(false); 1.2567 + 1.2568 + nsROCSSPrimitiveValue* xSpacing = new nsROCSSPrimitiveValue; 1.2569 + valueList->AppendCSSValue(xSpacing); 1.2570 + 1.2571 + nsROCSSPrimitiveValue* ySpacing = new nsROCSSPrimitiveValue; 1.2572 + valueList->AppendCSSValue(ySpacing); 1.2573 + 1.2574 + const nsStyleTableBorder *border = StyleTableBorder(); 1.2575 + xSpacing->SetAppUnits(border->mBorderSpacingX); 1.2576 + ySpacing->SetAppUnits(border->mBorderSpacingY); 1.2577 + 1.2578 + return valueList; 1.2579 +} 1.2580 + 1.2581 +CSSValue* 1.2582 +nsComputedDOMStyle::DoGetCaptionSide() 1.2583 +{ 1.2584 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.2585 + val->SetIdent( 1.2586 + nsCSSProps::ValueToKeywordEnum(StyleTableBorder()->mCaptionSide, 1.2587 + nsCSSProps::kCaptionSideKTable)); 1.2588 + return val; 1.2589 +} 1.2590 + 1.2591 +CSSValue* 1.2592 +nsComputedDOMStyle::DoGetEmptyCells() 1.2593 +{ 1.2594 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.2595 + val->SetIdent( 1.2596 + nsCSSProps::ValueToKeywordEnum(StyleTableBorder()->mEmptyCells, 1.2597 + nsCSSProps::kEmptyCellsKTable)); 1.2598 + return val; 1.2599 +} 1.2600 + 1.2601 +CSSValue* 1.2602 +nsComputedDOMStyle::DoGetTableLayout() 1.2603 +{ 1.2604 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.2605 + val->SetIdent( 1.2606 + nsCSSProps::ValueToKeywordEnum(StyleTable()->mLayoutStrategy, 1.2607 + nsCSSProps::kTableLayoutKTable)); 1.2608 + return val; 1.2609 +} 1.2610 + 1.2611 +CSSValue* 1.2612 +nsComputedDOMStyle::DoGetBorderTopStyle() 1.2613 +{ 1.2614 + return GetBorderStyleFor(NS_SIDE_TOP); 1.2615 +} 1.2616 + 1.2617 +CSSValue* 1.2618 +nsComputedDOMStyle::DoGetBorderBottomStyle() 1.2619 +{ 1.2620 + return GetBorderStyleFor(NS_SIDE_BOTTOM); 1.2621 +} 1.2622 + 1.2623 +CSSValue* 1.2624 +nsComputedDOMStyle::DoGetBorderLeftStyle() 1.2625 +{ 1.2626 + return GetBorderStyleFor(NS_SIDE_LEFT); 1.2627 +} 1.2628 + 1.2629 +CSSValue* 1.2630 +nsComputedDOMStyle::DoGetBorderRightStyle() 1.2631 +{ 1.2632 + return GetBorderStyleFor(NS_SIDE_RIGHT); 1.2633 +} 1.2634 + 1.2635 +CSSValue* 1.2636 +nsComputedDOMStyle::DoGetBorderBottomColors() 1.2637 +{ 1.2638 + return GetBorderColorsFor(NS_SIDE_BOTTOM); 1.2639 +} 1.2640 + 1.2641 +CSSValue* 1.2642 +nsComputedDOMStyle::DoGetBorderLeftColors() 1.2643 +{ 1.2644 + return GetBorderColorsFor(NS_SIDE_LEFT); 1.2645 +} 1.2646 + 1.2647 +CSSValue* 1.2648 +nsComputedDOMStyle::DoGetBorderRightColors() 1.2649 +{ 1.2650 + return GetBorderColorsFor(NS_SIDE_RIGHT); 1.2651 +} 1.2652 + 1.2653 + 1.2654 +CSSValue* 1.2655 +nsComputedDOMStyle::DoGetBorderTopColors() 1.2656 +{ 1.2657 + return GetBorderColorsFor(NS_SIDE_TOP); 1.2658 +} 1.2659 + 1.2660 +CSSValue* 1.2661 +nsComputedDOMStyle::DoGetBorderBottomLeftRadius() 1.2662 +{ 1.2663 + return GetEllipseRadii(StyleBorder()->mBorderRadius, 1.2664 + NS_CORNER_BOTTOM_LEFT, true); 1.2665 +} 1.2666 + 1.2667 +CSSValue* 1.2668 +nsComputedDOMStyle::DoGetBorderBottomRightRadius() 1.2669 +{ 1.2670 + return GetEllipseRadii(StyleBorder()->mBorderRadius, 1.2671 + NS_CORNER_BOTTOM_RIGHT, true); 1.2672 +} 1.2673 + 1.2674 +CSSValue* 1.2675 +nsComputedDOMStyle::DoGetBorderTopLeftRadius() 1.2676 +{ 1.2677 + return GetEllipseRadii(StyleBorder()->mBorderRadius, 1.2678 + NS_CORNER_TOP_LEFT, true); 1.2679 +} 1.2680 + 1.2681 +CSSValue* 1.2682 +nsComputedDOMStyle::DoGetBorderTopRightRadius() 1.2683 +{ 1.2684 + return GetEllipseRadii(StyleBorder()->mBorderRadius, 1.2685 + NS_CORNER_TOP_RIGHT, true); 1.2686 +} 1.2687 + 1.2688 +CSSValue* 1.2689 +nsComputedDOMStyle::DoGetBorderTopWidth() 1.2690 +{ 1.2691 + return GetBorderWidthFor(NS_SIDE_TOP); 1.2692 +} 1.2693 + 1.2694 +CSSValue* 1.2695 +nsComputedDOMStyle::DoGetBorderBottomWidth() 1.2696 +{ 1.2697 + return GetBorderWidthFor(NS_SIDE_BOTTOM); 1.2698 +} 1.2699 + 1.2700 +CSSValue* 1.2701 +nsComputedDOMStyle::DoGetBorderLeftWidth() 1.2702 +{ 1.2703 + return GetBorderWidthFor(NS_SIDE_LEFT); 1.2704 +} 1.2705 + 1.2706 +CSSValue* 1.2707 +nsComputedDOMStyle::DoGetBorderRightWidth() 1.2708 +{ 1.2709 + return GetBorderWidthFor(NS_SIDE_RIGHT); 1.2710 +} 1.2711 + 1.2712 +CSSValue* 1.2713 +nsComputedDOMStyle::DoGetBorderTopColor() 1.2714 +{ 1.2715 + return GetBorderColorFor(NS_SIDE_TOP); 1.2716 +} 1.2717 + 1.2718 +CSSValue* 1.2719 +nsComputedDOMStyle::DoGetBorderBottomColor() 1.2720 +{ 1.2721 + return GetBorderColorFor(NS_SIDE_BOTTOM); 1.2722 +} 1.2723 + 1.2724 +CSSValue* 1.2725 +nsComputedDOMStyle::DoGetBorderLeftColor() 1.2726 +{ 1.2727 + return GetBorderColorFor(NS_SIDE_LEFT); 1.2728 +} 1.2729 + 1.2730 +CSSValue* 1.2731 +nsComputedDOMStyle::DoGetBorderRightColor() 1.2732 +{ 1.2733 + return GetBorderColorFor(NS_SIDE_RIGHT); 1.2734 +} 1.2735 + 1.2736 +CSSValue* 1.2737 +nsComputedDOMStyle::DoGetMarginTopWidth() 1.2738 +{ 1.2739 + return GetMarginWidthFor(NS_SIDE_TOP); 1.2740 +} 1.2741 + 1.2742 +CSSValue* 1.2743 +nsComputedDOMStyle::DoGetMarginBottomWidth() 1.2744 +{ 1.2745 + return GetMarginWidthFor(NS_SIDE_BOTTOM); 1.2746 +} 1.2747 + 1.2748 +CSSValue* 1.2749 +nsComputedDOMStyle::DoGetMarginLeftWidth() 1.2750 +{ 1.2751 + return GetMarginWidthFor(NS_SIDE_LEFT); 1.2752 +} 1.2753 + 1.2754 +CSSValue* 1.2755 +nsComputedDOMStyle::DoGetMarginRightWidth() 1.2756 +{ 1.2757 + return GetMarginWidthFor(NS_SIDE_RIGHT); 1.2758 +} 1.2759 + 1.2760 +CSSValue* 1.2761 +nsComputedDOMStyle::DoGetMarkerOffset() 1.2762 +{ 1.2763 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.2764 + SetValueToCoord(val, StyleContent()->mMarkerOffset, false); 1.2765 + return val; 1.2766 +} 1.2767 + 1.2768 +CSSValue* 1.2769 +nsComputedDOMStyle::DoGetOrient() 1.2770 +{ 1.2771 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.2772 + val->SetIdent( 1.2773 + nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOrient, 1.2774 + nsCSSProps::kOrientKTable)); 1.2775 + return val; 1.2776 +} 1.2777 + 1.2778 +CSSValue* 1.2779 +nsComputedDOMStyle::DoGetOutlineWidth() 1.2780 +{ 1.2781 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.2782 + 1.2783 + const nsStyleOutline* outline = StyleOutline(); 1.2784 + 1.2785 + nscoord width; 1.2786 + if (outline->GetOutlineStyle() == NS_STYLE_BORDER_STYLE_NONE) { 1.2787 + NS_ASSERTION(outline->GetOutlineWidth(width) && width == 0, 1.2788 + "unexpected width"); 1.2789 + width = 0; 1.2790 + } else { 1.2791 +#ifdef DEBUG 1.2792 + bool res = 1.2793 +#endif 1.2794 + outline->GetOutlineWidth(width); 1.2795 + NS_ASSERTION(res, "percent outline doesn't exist"); 1.2796 + } 1.2797 + val->SetAppUnits(width); 1.2798 + 1.2799 + return val; 1.2800 +} 1.2801 + 1.2802 +CSSValue* 1.2803 +nsComputedDOMStyle::DoGetOutlineStyle() 1.2804 +{ 1.2805 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.2806 + val->SetIdent( 1.2807 + nsCSSProps::ValueToKeywordEnum(StyleOutline()->GetOutlineStyle(), 1.2808 + nsCSSProps::kOutlineStyleKTable)); 1.2809 + return val; 1.2810 +} 1.2811 + 1.2812 +CSSValue* 1.2813 +nsComputedDOMStyle::DoGetOutlineOffset() 1.2814 +{ 1.2815 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.2816 + val->SetAppUnits(StyleOutline()->mOutlineOffset); 1.2817 + return val; 1.2818 +} 1.2819 + 1.2820 +CSSValue* 1.2821 +nsComputedDOMStyle::DoGetOutlineRadiusBottomLeft() 1.2822 +{ 1.2823 + return GetEllipseRadii(StyleOutline()->mOutlineRadius, 1.2824 + NS_CORNER_BOTTOM_LEFT, false); 1.2825 +} 1.2826 + 1.2827 +CSSValue* 1.2828 +nsComputedDOMStyle::DoGetOutlineRadiusBottomRight() 1.2829 +{ 1.2830 + return GetEllipseRadii(StyleOutline()->mOutlineRadius, 1.2831 + NS_CORNER_BOTTOM_RIGHT, false); 1.2832 +} 1.2833 + 1.2834 +CSSValue* 1.2835 +nsComputedDOMStyle::DoGetOutlineRadiusTopLeft() 1.2836 +{ 1.2837 + return GetEllipseRadii(StyleOutline()->mOutlineRadius, 1.2838 + NS_CORNER_TOP_LEFT, false); 1.2839 +} 1.2840 + 1.2841 +CSSValue* 1.2842 +nsComputedDOMStyle::DoGetOutlineRadiusTopRight() 1.2843 +{ 1.2844 + return GetEllipseRadii(StyleOutline()->mOutlineRadius, 1.2845 + NS_CORNER_TOP_RIGHT, false); 1.2846 +} 1.2847 + 1.2848 +CSSValue* 1.2849 +nsComputedDOMStyle::DoGetOutlineColor() 1.2850 +{ 1.2851 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.2852 + 1.2853 + nscolor color; 1.2854 + if (!StyleOutline()->GetOutlineColor(color)) 1.2855 + color = StyleColor()->mColor; 1.2856 + 1.2857 + SetToRGBAColor(val, color); 1.2858 + return val; 1.2859 +} 1.2860 + 1.2861 +CSSValue* 1.2862 +nsComputedDOMStyle::GetEllipseRadii(const nsStyleCorners& aRadius, 1.2863 + uint8_t aFullCorner, 1.2864 + bool aIsBorder) // else outline 1.2865 +{ 1.2866 + nsStyleCoord radiusX, radiusY; 1.2867 + if (mInnerFrame && aIsBorder) { 1.2868 + nscoord radii[8]; 1.2869 + mInnerFrame->GetBorderRadii(radii); 1.2870 + radiusX.SetCoordValue(radii[NS_FULL_TO_HALF_CORNER(aFullCorner, false)]); 1.2871 + radiusY.SetCoordValue(radii[NS_FULL_TO_HALF_CORNER(aFullCorner, true)]); 1.2872 + } else { 1.2873 + radiusX = aRadius.Get(NS_FULL_TO_HALF_CORNER(aFullCorner, false)); 1.2874 + radiusY = aRadius.Get(NS_FULL_TO_HALF_CORNER(aFullCorner, true)); 1.2875 + 1.2876 + if (mInnerFrame) { 1.2877 + // We need to convert to absolute coordinates before doing the 1.2878 + // equality check below. 1.2879 + nscoord v; 1.2880 + 1.2881 + v = StyleCoordToNSCoord(radiusX, 1.2882 + &nsComputedDOMStyle::GetFrameBorderRectWidth, 1.2883 + 0, true); 1.2884 + radiusX.SetCoordValue(v); 1.2885 + 1.2886 + v = StyleCoordToNSCoord(radiusY, 1.2887 + &nsComputedDOMStyle::GetFrameBorderRectHeight, 1.2888 + 0, true); 1.2889 + radiusY.SetCoordValue(v); 1.2890 + } 1.2891 + } 1.2892 + 1.2893 + // for compatibility, return a single value if X and Y are equal 1.2894 + if (radiusX == radiusY) { 1.2895 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.2896 + 1.2897 + SetValueToCoord(val, radiusX, true); 1.2898 + 1.2899 + return val; 1.2900 + } 1.2901 + 1.2902 + nsDOMCSSValueList *valueList = GetROCSSValueList(false); 1.2903 + 1.2904 + nsROCSSPrimitiveValue *valX = new nsROCSSPrimitiveValue; 1.2905 + valueList->AppendCSSValue(valX); 1.2906 + 1.2907 + nsROCSSPrimitiveValue *valY = new nsROCSSPrimitiveValue; 1.2908 + valueList->AppendCSSValue(valY); 1.2909 + 1.2910 + SetValueToCoord(valX, radiusX, true); 1.2911 + SetValueToCoord(valY, radiusY, true); 1.2912 + 1.2913 + return valueList; 1.2914 +} 1.2915 + 1.2916 +CSSValue* 1.2917 +nsComputedDOMStyle::GetCSSShadowArray(nsCSSShadowArray* aArray, 1.2918 + const nscolor& aDefaultColor, 1.2919 + bool aIsBoxShadow) 1.2920 +{ 1.2921 + if (!aArray) { 1.2922 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.2923 + val->SetIdent(eCSSKeyword_none); 1.2924 + return val; 1.2925 + } 1.2926 + 1.2927 + static nscoord nsCSSShadowItem::* const shadowValuesNoSpread[] = { 1.2928 + &nsCSSShadowItem::mXOffset, 1.2929 + &nsCSSShadowItem::mYOffset, 1.2930 + &nsCSSShadowItem::mRadius 1.2931 + }; 1.2932 + 1.2933 + static nscoord nsCSSShadowItem::* const shadowValuesWithSpread[] = { 1.2934 + &nsCSSShadowItem::mXOffset, 1.2935 + &nsCSSShadowItem::mYOffset, 1.2936 + &nsCSSShadowItem::mRadius, 1.2937 + &nsCSSShadowItem::mSpread 1.2938 + }; 1.2939 + 1.2940 + nscoord nsCSSShadowItem::* const * shadowValues; 1.2941 + uint32_t shadowValuesLength; 1.2942 + if (aIsBoxShadow) { 1.2943 + shadowValues = shadowValuesWithSpread; 1.2944 + shadowValuesLength = ArrayLength(shadowValuesWithSpread); 1.2945 + } else { 1.2946 + shadowValues = shadowValuesNoSpread; 1.2947 + shadowValuesLength = ArrayLength(shadowValuesNoSpread); 1.2948 + } 1.2949 + 1.2950 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.2951 + 1.2952 + for (nsCSSShadowItem *item = aArray->ShadowAt(0), 1.2953 + *item_end = item + aArray->Length(); 1.2954 + item < item_end; ++item) { 1.2955 + nsDOMCSSValueList *itemList = GetROCSSValueList(false); 1.2956 + valueList->AppendCSSValue(itemList); 1.2957 + 1.2958 + // Color is either the specified shadow color or the foreground color 1.2959 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.2960 + itemList->AppendCSSValue(val); 1.2961 + nscolor shadowColor; 1.2962 + if (item->mHasColor) { 1.2963 + shadowColor = item->mColor; 1.2964 + } else { 1.2965 + shadowColor = aDefaultColor; 1.2966 + } 1.2967 + SetToRGBAColor(val, shadowColor); 1.2968 + 1.2969 + // Set the offsets, blur radius, and spread if available 1.2970 + for (uint32_t i = 0; i < shadowValuesLength; ++i) { 1.2971 + val = new nsROCSSPrimitiveValue; 1.2972 + itemList->AppendCSSValue(val); 1.2973 + val->SetAppUnits(item->*(shadowValues[i])); 1.2974 + } 1.2975 + 1.2976 + if (item->mInset && aIsBoxShadow) { 1.2977 + // This is an inset box-shadow 1.2978 + val = new nsROCSSPrimitiveValue; 1.2979 + itemList->AppendCSSValue(val); 1.2980 + val->SetIdent( 1.2981 + nsCSSProps::ValueToKeywordEnum(NS_STYLE_BOX_SHADOW_INSET, 1.2982 + nsCSSProps::kBoxShadowTypeKTable)); 1.2983 + } 1.2984 + } 1.2985 + 1.2986 + return valueList; 1.2987 +} 1.2988 + 1.2989 +CSSValue* 1.2990 +nsComputedDOMStyle::DoGetBoxShadow() 1.2991 +{ 1.2992 + return GetCSSShadowArray(StyleBorder()->mBoxShadow, 1.2993 + StyleColor()->mColor, 1.2994 + true); 1.2995 +} 1.2996 + 1.2997 +CSSValue* 1.2998 +nsComputedDOMStyle::DoGetZIndex() 1.2999 +{ 1.3000 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3001 + SetValueToCoord(val, StylePosition()->mZIndex, false); 1.3002 + return val; 1.3003 +} 1.3004 + 1.3005 +CSSValue* 1.3006 +nsComputedDOMStyle::DoGetListStyleImage() 1.3007 +{ 1.3008 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3009 + 1.3010 + const nsStyleList* list = StyleList(); 1.3011 + 1.3012 + if (!list->GetListStyleImage()) { 1.3013 + val->SetIdent(eCSSKeyword_none); 1.3014 + } else { 1.3015 + nsCOMPtr<nsIURI> uri; 1.3016 + if (list->GetListStyleImage()) { 1.3017 + list->GetListStyleImage()->GetURI(getter_AddRefs(uri)); 1.3018 + } 1.3019 + val->SetURI(uri); 1.3020 + } 1.3021 + 1.3022 + return val; 1.3023 +} 1.3024 + 1.3025 +CSSValue* 1.3026 +nsComputedDOMStyle::DoGetListStylePosition() 1.3027 +{ 1.3028 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3029 + val->SetIdent( 1.3030 + nsCSSProps::ValueToKeywordEnum(StyleList()->mListStylePosition, 1.3031 + nsCSSProps::kListStylePositionKTable)); 1.3032 + return val; 1.3033 +} 1.3034 + 1.3035 +CSSValue* 1.3036 +nsComputedDOMStyle::DoGetListStyleType() 1.3037 +{ 1.3038 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3039 + val->SetIdent( 1.3040 + nsCSSProps::ValueToKeywordEnum(StyleList()->mListStyleType, 1.3041 + nsCSSProps::kListStyleKTable)); 1.3042 + return val; 1.3043 +} 1.3044 + 1.3045 +CSSValue* 1.3046 +nsComputedDOMStyle::DoGetImageRegion() 1.3047 +{ 1.3048 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3049 + 1.3050 + const nsStyleList* list = StyleList(); 1.3051 + 1.3052 + if (list->mImageRegion.width <= 0 || list->mImageRegion.height <= 0) { 1.3053 + val->SetIdent(eCSSKeyword_auto); 1.3054 + } else { 1.3055 + // create the cssvalues for the sides, stick them in the rect object 1.3056 + nsROCSSPrimitiveValue *topVal = new nsROCSSPrimitiveValue; 1.3057 + nsROCSSPrimitiveValue *rightVal = new nsROCSSPrimitiveValue; 1.3058 + nsROCSSPrimitiveValue *bottomVal = new nsROCSSPrimitiveValue; 1.3059 + nsROCSSPrimitiveValue *leftVal = new nsROCSSPrimitiveValue; 1.3060 + nsDOMCSSRect * domRect = new nsDOMCSSRect(topVal, rightVal, 1.3061 + bottomVal, leftVal); 1.3062 + topVal->SetAppUnits(list->mImageRegion.y); 1.3063 + rightVal->SetAppUnits(list->mImageRegion.width + list->mImageRegion.x); 1.3064 + bottomVal->SetAppUnits(list->mImageRegion.height + list->mImageRegion.y); 1.3065 + leftVal->SetAppUnits(list->mImageRegion.x); 1.3066 + val->SetRect(domRect); 1.3067 + } 1.3068 + 1.3069 + return val; 1.3070 +} 1.3071 + 1.3072 +CSSValue* 1.3073 +nsComputedDOMStyle::DoGetLineHeight() 1.3074 +{ 1.3075 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3076 + 1.3077 + nscoord lineHeight; 1.3078 + if (GetLineHeightCoord(lineHeight)) { 1.3079 + val->SetAppUnits(lineHeight); 1.3080 + } else { 1.3081 + SetValueToCoord(val, StyleText()->mLineHeight, true, 1.3082 + nullptr, nsCSSProps::kLineHeightKTable); 1.3083 + } 1.3084 + 1.3085 + return val; 1.3086 +} 1.3087 + 1.3088 +CSSValue* 1.3089 +nsComputedDOMStyle::DoGetVerticalAlign() 1.3090 +{ 1.3091 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3092 + SetValueToCoord(val, StyleTextReset()->mVerticalAlign, false, 1.3093 + &nsComputedDOMStyle::GetLineHeightCoord, 1.3094 + nsCSSProps::kVerticalAlignKTable); 1.3095 + return val; 1.3096 +} 1.3097 + 1.3098 +CSSValue* 1.3099 +nsComputedDOMStyle::CreateTextAlignValue(uint8_t aAlign, bool aAlignTrue, 1.3100 + const KTableValue aTable[]) 1.3101 +{ 1.3102 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3103 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(aAlign, aTable)); 1.3104 + if (!aAlignTrue) { 1.3105 + return val; 1.3106 + } 1.3107 + 1.3108 + nsROCSSPrimitiveValue* first = new nsROCSSPrimitiveValue; 1.3109 + first->SetIdent(eCSSKeyword_true); 1.3110 + 1.3111 + nsDOMCSSValueList* valueList = GetROCSSValueList(false); 1.3112 + valueList->AppendCSSValue(first); 1.3113 + valueList->AppendCSSValue(val); 1.3114 + return valueList; 1.3115 +} 1.3116 + 1.3117 +CSSValue* 1.3118 +nsComputedDOMStyle::DoGetTextAlign() 1.3119 +{ 1.3120 + const nsStyleText* style = StyleText(); 1.3121 + return CreateTextAlignValue(style->mTextAlign, style->mTextAlignTrue, 1.3122 + nsCSSProps::kTextAlignKTable); 1.3123 +} 1.3124 + 1.3125 +CSSValue* 1.3126 +nsComputedDOMStyle::DoGetTextAlignLast() 1.3127 +{ 1.3128 + const nsStyleText* style = StyleText(); 1.3129 + return CreateTextAlignValue(style->mTextAlignLast, style->mTextAlignLastTrue, 1.3130 + nsCSSProps::kTextAlignLastKTable); 1.3131 +} 1.3132 + 1.3133 +CSSValue* 1.3134 +nsComputedDOMStyle::DoGetTextCombineUpright() 1.3135 +{ 1.3136 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3137 + uint8_t tch = StyleText()->mTextCombineUpright; 1.3138 + 1.3139 + if (tch <= NS_STYLE_TEXT_COMBINE_UPRIGHT_ALL) { 1.3140 + val->SetIdent( 1.3141 + nsCSSProps::ValueToKeywordEnum(tch, 1.3142 + nsCSSProps::kTextCombineUprightKTable)); 1.3143 + } else if (tch <= NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_2) { 1.3144 + val->SetString(NS_LITERAL_STRING("digits 2")); 1.3145 + } else if (tch <= NS_STYLE_TEXT_COMBINE_UPRIGHT_DIGITS_3) { 1.3146 + val->SetString(NS_LITERAL_STRING("digits 3")); 1.3147 + } else { 1.3148 + val->SetString(NS_LITERAL_STRING("digits 4")); 1.3149 + } 1.3150 + 1.3151 + return val; 1.3152 +} 1.3153 + 1.3154 +CSSValue* 1.3155 +nsComputedDOMStyle::DoGetTextDecoration() 1.3156 +{ 1.3157 + const nsStyleTextReset* textReset = StyleTextReset(); 1.3158 + 1.3159 + // If decoration style or color wasn't initial value, the author knew the 1.3160 + // text-decoration is a shorthand property in CSS 3. 1.3161 + // Return nullptr in such cases. 1.3162 + if (textReset->GetDecorationStyle() != NS_STYLE_TEXT_DECORATION_STYLE_SOLID) { 1.3163 + return nullptr; 1.3164 + } 1.3165 + 1.3166 + nscolor color; 1.3167 + bool isForegroundColor; 1.3168 + textReset->GetDecorationColor(color, isForegroundColor); 1.3169 + if (!isForegroundColor) { 1.3170 + return nullptr; 1.3171 + } 1.3172 + 1.3173 + // Otherwise, the web pages may have been written for CSS 2.1 or earlier, 1.3174 + // i.e., text-decoration was assumed as a longhand property. In that case, 1.3175 + // we should return computed value same as CSS 2.1 for backward compatibility. 1.3176 + 1.3177 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3178 + uint8_t line = textReset->mTextDecorationLine; 1.3179 + // Clear the -moz-anchor-decoration bit and the OVERRIDE_ALL bits -- we 1.3180 + // don't want these to appear in the computed style. 1.3181 + line &= ~(NS_STYLE_TEXT_DECORATION_LINE_PREF_ANCHORS | 1.3182 + NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL); 1.3183 + 1.3184 + if (line == NS_STYLE_TEXT_DECORATION_LINE_NONE) { 1.3185 + val->SetIdent(eCSSKeyword_none); 1.3186 + } else { 1.3187 + nsAutoString str; 1.3188 + nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_text_decoration_line, 1.3189 + line, NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, 1.3190 + NS_STYLE_TEXT_DECORATION_LINE_BLINK, str); 1.3191 + val->SetString(str); 1.3192 + } 1.3193 + 1.3194 + return val; 1.3195 +} 1.3196 + 1.3197 +CSSValue* 1.3198 +nsComputedDOMStyle::DoGetTextDecorationColor() 1.3199 +{ 1.3200 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3201 + 1.3202 + nscolor color; 1.3203 + bool isForeground; 1.3204 + StyleTextReset()->GetDecorationColor(color, isForeground); 1.3205 + if (isForeground) { 1.3206 + color = StyleColor()->mColor; 1.3207 + } 1.3208 + 1.3209 + SetToRGBAColor(val, color); 1.3210 + 1.3211 + return val; 1.3212 +} 1.3213 + 1.3214 +CSSValue* 1.3215 +nsComputedDOMStyle::DoGetTextDecorationLine() 1.3216 +{ 1.3217 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3218 + 1.3219 + int32_t intValue = StyleTextReset()->mTextDecorationLine; 1.3220 + 1.3221 + if (NS_STYLE_TEXT_DECORATION_LINE_NONE == intValue) { 1.3222 + val->SetIdent(eCSSKeyword_none); 1.3223 + } else { 1.3224 + nsAutoString decorationLineString; 1.3225 + // Clear the -moz-anchor-decoration bit and the OVERRIDE_ALL bits -- we 1.3226 + // don't want these to appear in the computed style. 1.3227 + intValue &= ~(NS_STYLE_TEXT_DECORATION_LINE_PREF_ANCHORS | 1.3228 + NS_STYLE_TEXT_DECORATION_LINE_OVERRIDE_ALL); 1.3229 + nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_text_decoration_line, 1.3230 + intValue, NS_STYLE_TEXT_DECORATION_LINE_UNDERLINE, 1.3231 + NS_STYLE_TEXT_DECORATION_LINE_BLINK, decorationLineString); 1.3232 + val->SetString(decorationLineString); 1.3233 + } 1.3234 + 1.3235 + return val; 1.3236 +} 1.3237 + 1.3238 +CSSValue* 1.3239 +nsComputedDOMStyle::DoGetTextDecorationStyle() 1.3240 +{ 1.3241 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3242 + 1.3243 + val->SetIdent( 1.3244 + nsCSSProps::ValueToKeywordEnum(StyleTextReset()->GetDecorationStyle(), 1.3245 + nsCSSProps::kTextDecorationStyleKTable)); 1.3246 + 1.3247 + return val; 1.3248 +} 1.3249 + 1.3250 +CSSValue* 1.3251 +nsComputedDOMStyle::DoGetTextIndent() 1.3252 +{ 1.3253 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3254 + SetValueToCoord(val, StyleText()->mTextIndent, false, 1.3255 + &nsComputedDOMStyle::GetCBContentWidth); 1.3256 + return val; 1.3257 +} 1.3258 + 1.3259 +CSSValue* 1.3260 +nsComputedDOMStyle::DoGetTextOrientation() 1.3261 +{ 1.3262 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3263 + val->SetIdent( 1.3264 + nsCSSProps::ValueToKeywordEnum(StyleText()->mTextOrientation, 1.3265 + nsCSSProps::kTextOrientationKTable)); 1.3266 + return val; 1.3267 +} 1.3268 + 1.3269 +CSSValue* 1.3270 +nsComputedDOMStyle::DoGetTextOverflow() 1.3271 +{ 1.3272 + const nsStyleTextReset *style = StyleTextReset(); 1.3273 + nsROCSSPrimitiveValue *first = new nsROCSSPrimitiveValue; 1.3274 + const nsStyleTextOverflowSide *side = style->mTextOverflow.GetFirstValue(); 1.3275 + if (side->mType == NS_STYLE_TEXT_OVERFLOW_STRING) { 1.3276 + nsString str; 1.3277 + nsStyleUtil::AppendEscapedCSSString(side->mString, str); 1.3278 + first->SetString(str); 1.3279 + } else { 1.3280 + first->SetIdent( 1.3281 + nsCSSProps::ValueToKeywordEnum(side->mType, 1.3282 + nsCSSProps::kTextOverflowKTable)); 1.3283 + } 1.3284 + side = style->mTextOverflow.GetSecondValue(); 1.3285 + if (!side) { 1.3286 + return first; 1.3287 + } 1.3288 + nsROCSSPrimitiveValue *second = new nsROCSSPrimitiveValue; 1.3289 + if (side->mType == NS_STYLE_TEXT_OVERFLOW_STRING) { 1.3290 + nsString str; 1.3291 + nsStyleUtil::AppendEscapedCSSString(side->mString, str); 1.3292 + second->SetString(str); 1.3293 + } else { 1.3294 + second->SetIdent( 1.3295 + nsCSSProps::ValueToKeywordEnum(side->mType, 1.3296 + nsCSSProps::kTextOverflowKTable)); 1.3297 + } 1.3298 + 1.3299 + nsDOMCSSValueList *valueList = GetROCSSValueList(false); 1.3300 + valueList->AppendCSSValue(first); 1.3301 + valueList->AppendCSSValue(second); 1.3302 + return valueList; 1.3303 +} 1.3304 + 1.3305 +CSSValue* 1.3306 +nsComputedDOMStyle::DoGetTextShadow() 1.3307 +{ 1.3308 + return GetCSSShadowArray(StyleText()->mTextShadow, 1.3309 + StyleColor()->mColor, 1.3310 + false); 1.3311 +} 1.3312 + 1.3313 +CSSValue* 1.3314 +nsComputedDOMStyle::DoGetTextTransform() 1.3315 +{ 1.3316 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3317 + val->SetIdent( 1.3318 + nsCSSProps::ValueToKeywordEnum(StyleText()->mTextTransform, 1.3319 + nsCSSProps::kTextTransformKTable)); 1.3320 + return val; 1.3321 +} 1.3322 + 1.3323 +CSSValue* 1.3324 +nsComputedDOMStyle::DoGetTabSize() 1.3325 +{ 1.3326 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3327 + val->SetNumber(StyleText()->mTabSize); 1.3328 + return val; 1.3329 +} 1.3330 + 1.3331 +CSSValue* 1.3332 +nsComputedDOMStyle::DoGetLetterSpacing() 1.3333 +{ 1.3334 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3335 + SetValueToCoord(val, StyleText()->mLetterSpacing, false); 1.3336 + return val; 1.3337 +} 1.3338 + 1.3339 +CSSValue* 1.3340 +nsComputedDOMStyle::DoGetWordSpacing() 1.3341 +{ 1.3342 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3343 + val->SetAppUnits(StyleText()->mWordSpacing); 1.3344 + return val; 1.3345 +} 1.3346 + 1.3347 +CSSValue* 1.3348 +nsComputedDOMStyle::DoGetWhiteSpace() 1.3349 +{ 1.3350 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3351 + val->SetIdent( 1.3352 + nsCSSProps::ValueToKeywordEnum(StyleText()->mWhiteSpace, 1.3353 + nsCSSProps::kWhitespaceKTable)); 1.3354 + return val; 1.3355 +} 1.3356 + 1.3357 +CSSValue* 1.3358 +nsComputedDOMStyle::DoGetWindowShadow() 1.3359 +{ 1.3360 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3361 + val->SetIdent( 1.3362 + nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mWindowShadow, 1.3363 + nsCSSProps::kWindowShadowKTable)); 1.3364 + return val; 1.3365 +} 1.3366 + 1.3367 +CSSValue* 1.3368 +nsComputedDOMStyle::DoGetWordBreak() 1.3369 +{ 1.3370 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3371 + val->SetIdent( 1.3372 + nsCSSProps::ValueToKeywordEnum(StyleText()->mWordBreak, 1.3373 + nsCSSProps::kWordBreakKTable)); 1.3374 + return val; 1.3375 +} 1.3376 + 1.3377 +CSSValue* 1.3378 +nsComputedDOMStyle::DoGetWordWrap() 1.3379 +{ 1.3380 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3381 + val->SetIdent( 1.3382 + nsCSSProps::ValueToKeywordEnum(StyleText()->mWordWrap, 1.3383 + nsCSSProps::kWordWrapKTable)); 1.3384 + return val; 1.3385 +} 1.3386 + 1.3387 +CSSValue* 1.3388 +nsComputedDOMStyle::DoGetHyphens() 1.3389 +{ 1.3390 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3391 + val->SetIdent( 1.3392 + nsCSSProps::ValueToKeywordEnum(StyleText()->mHyphens, 1.3393 + nsCSSProps::kHyphensKTable)); 1.3394 + return val; 1.3395 +} 1.3396 + 1.3397 +CSSValue* 1.3398 +nsComputedDOMStyle::DoGetTextSizeAdjust() 1.3399 +{ 1.3400 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3401 + switch (StyleText()->mTextSizeAdjust) { 1.3402 + default: 1.3403 + NS_NOTREACHED("unexpected value"); 1.3404 + // fall through 1.3405 + case NS_STYLE_TEXT_SIZE_ADJUST_AUTO: 1.3406 + val->SetIdent(eCSSKeyword_auto); 1.3407 + break; 1.3408 + case NS_STYLE_TEXT_SIZE_ADJUST_NONE: 1.3409 + val->SetIdent(eCSSKeyword_none); 1.3410 + break; 1.3411 + } 1.3412 + return val; 1.3413 +} 1.3414 + 1.3415 +CSSValue* 1.3416 +nsComputedDOMStyle::DoGetPointerEvents() 1.3417 +{ 1.3418 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3419 + val->SetIdent( 1.3420 + nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mPointerEvents, 1.3421 + nsCSSProps::kPointerEventsKTable)); 1.3422 + return val; 1.3423 +} 1.3424 + 1.3425 +CSSValue* 1.3426 +nsComputedDOMStyle::DoGetVisibility() 1.3427 +{ 1.3428 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3429 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mVisible, 1.3430 + nsCSSProps::kVisibilityKTable)); 1.3431 + return val; 1.3432 +} 1.3433 + 1.3434 +CSSValue* 1.3435 +nsComputedDOMStyle::DoGetWritingMode() 1.3436 +{ 1.3437 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3438 + val->SetIdent( 1.3439 + nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mWritingMode, 1.3440 + nsCSSProps::kWritingModeKTable)); 1.3441 + return val; 1.3442 +} 1.3443 + 1.3444 +CSSValue* 1.3445 +nsComputedDOMStyle::DoGetDirection() 1.3446 +{ 1.3447 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3448 + val->SetIdent( 1.3449 + nsCSSProps::ValueToKeywordEnum(StyleVisibility()->mDirection, 1.3450 + nsCSSProps::kDirectionKTable)); 1.3451 + return val; 1.3452 +} 1.3453 + 1.3454 +static_assert(NS_STYLE_UNICODE_BIDI_NORMAL == 0, 1.3455 + "unicode-bidi style constants not as expected"); 1.3456 + 1.3457 +CSSValue* 1.3458 +nsComputedDOMStyle::DoGetUnicodeBidi() 1.3459 +{ 1.3460 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3461 + val->SetIdent( 1.3462 + nsCSSProps::ValueToKeywordEnum(StyleTextReset()->mUnicodeBidi, 1.3463 + nsCSSProps::kUnicodeBidiKTable)); 1.3464 + return val; 1.3465 +} 1.3466 + 1.3467 +CSSValue* 1.3468 +nsComputedDOMStyle::DoGetCursor() 1.3469 +{ 1.3470 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.3471 + 1.3472 + const nsStyleUserInterface *ui = StyleUserInterface(); 1.3473 + 1.3474 + for (nsCursorImage *item = ui->mCursorArray, 1.3475 + *item_end = ui->mCursorArray + ui->mCursorArrayLength; 1.3476 + item < item_end; ++item) { 1.3477 + nsDOMCSSValueList *itemList = GetROCSSValueList(false); 1.3478 + valueList->AppendCSSValue(itemList); 1.3479 + 1.3480 + nsCOMPtr<nsIURI> uri; 1.3481 + item->GetImage()->GetURI(getter_AddRefs(uri)); 1.3482 + 1.3483 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3484 + itemList->AppendCSSValue(val); 1.3485 + val->SetURI(uri); 1.3486 + 1.3487 + if (item->mHaveHotspot) { 1.3488 + nsROCSSPrimitiveValue *valX = new nsROCSSPrimitiveValue; 1.3489 + itemList->AppendCSSValue(valX); 1.3490 + nsROCSSPrimitiveValue *valY = new nsROCSSPrimitiveValue; 1.3491 + itemList->AppendCSSValue(valY); 1.3492 + 1.3493 + valX->SetNumber(item->mHotspotX); 1.3494 + valY->SetNumber(item->mHotspotY); 1.3495 + } 1.3496 + } 1.3497 + 1.3498 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3499 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(ui->mCursor, 1.3500 + nsCSSProps::kCursorKTable)); 1.3501 + valueList->AppendCSSValue(val); 1.3502 + return valueList; 1.3503 +} 1.3504 + 1.3505 +CSSValue* 1.3506 +nsComputedDOMStyle::DoGetAppearance() 1.3507 +{ 1.3508 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3509 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mAppearance, 1.3510 + nsCSSProps::kAppearanceKTable)); 1.3511 + return val; 1.3512 +} 1.3513 + 1.3514 + 1.3515 +CSSValue* 1.3516 +nsComputedDOMStyle::DoGetBoxAlign() 1.3517 +{ 1.3518 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3519 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxAlign, 1.3520 + nsCSSProps::kBoxAlignKTable)); 1.3521 + return val; 1.3522 +} 1.3523 + 1.3524 +CSSValue* 1.3525 +nsComputedDOMStyle::DoGetBoxDirection() 1.3526 +{ 1.3527 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3528 + val->SetIdent( 1.3529 + nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxDirection, 1.3530 + nsCSSProps::kBoxDirectionKTable)); 1.3531 + return val; 1.3532 +} 1.3533 + 1.3534 +CSSValue* 1.3535 +nsComputedDOMStyle::DoGetBoxFlex() 1.3536 +{ 1.3537 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3538 + val->SetNumber(StyleXUL()->mBoxFlex); 1.3539 + return val; 1.3540 +} 1.3541 + 1.3542 +CSSValue* 1.3543 +nsComputedDOMStyle::DoGetBoxOrdinalGroup() 1.3544 +{ 1.3545 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3546 + val->SetNumber(StyleXUL()->mBoxOrdinal); 1.3547 + return val; 1.3548 +} 1.3549 + 1.3550 +CSSValue* 1.3551 +nsComputedDOMStyle::DoGetBoxOrient() 1.3552 +{ 1.3553 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3554 + val->SetIdent( 1.3555 + nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxOrient, 1.3556 + nsCSSProps::kBoxOrientKTable)); 1.3557 + return val; 1.3558 +} 1.3559 + 1.3560 +CSSValue* 1.3561 +nsComputedDOMStyle::DoGetBoxPack() 1.3562 +{ 1.3563 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3564 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleXUL()->mBoxPack, 1.3565 + nsCSSProps::kBoxPackKTable)); 1.3566 + return val; 1.3567 +} 1.3568 + 1.3569 +CSSValue* 1.3570 +nsComputedDOMStyle::DoGetBoxSizing() 1.3571 +{ 1.3572 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3573 + val->SetIdent( 1.3574 + nsCSSProps::ValueToKeywordEnum(StylePosition()->mBoxSizing, 1.3575 + nsCSSProps::kBoxSizingKTable)); 1.3576 + return val; 1.3577 +} 1.3578 + 1.3579 +/* Border image properties */ 1.3580 + 1.3581 +CSSValue* 1.3582 +nsComputedDOMStyle::DoGetBorderImageSource() 1.3583 +{ 1.3584 + const nsStyleBorder* border = StyleBorder(); 1.3585 + 1.3586 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3587 + const nsStyleImage& image = border->mBorderImageSource; 1.3588 + SetValueToStyleImage(image, val); 1.3589 + 1.3590 + return val; 1.3591 +} 1.3592 + 1.3593 +CSSValue* 1.3594 +nsComputedDOMStyle::DoGetBorderImageSlice() 1.3595 +{ 1.3596 + nsDOMCSSValueList* valueList = GetROCSSValueList(false); 1.3597 + 1.3598 + const nsStyleBorder* border = StyleBorder(); 1.3599 + // Four slice numbers. 1.3600 + NS_FOR_CSS_SIDES (side) { 1.3601 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3602 + valueList->AppendCSSValue(val); 1.3603 + SetValueToCoord(val, border->mBorderImageSlice.Get(side), true, nullptr); 1.3604 + } 1.3605 + 1.3606 + // Fill keyword. 1.3607 + if (NS_STYLE_BORDER_IMAGE_SLICE_FILL == border->mBorderImageFill) { 1.3608 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3609 + valueList->AppendCSSValue(val); 1.3610 + val->SetIdent(eCSSKeyword_fill); 1.3611 + } 1.3612 + 1.3613 + return valueList; 1.3614 +} 1.3615 + 1.3616 +CSSValue* 1.3617 +nsComputedDOMStyle::DoGetBorderImageWidth() 1.3618 +{ 1.3619 + const nsStyleBorder* border = StyleBorder(); 1.3620 + nsDOMCSSValueList* valueList = GetROCSSValueList(false); 1.3621 + NS_FOR_CSS_SIDES (side) { 1.3622 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3623 + valueList->AppendCSSValue(val); 1.3624 + SetValueToCoord(val, border->mBorderImageWidth.Get(side), 1.3625 + true, nullptr); 1.3626 + } 1.3627 + 1.3628 + return valueList; 1.3629 +} 1.3630 + 1.3631 +CSSValue* 1.3632 +nsComputedDOMStyle::DoGetBorderImageOutset() 1.3633 +{ 1.3634 + nsDOMCSSValueList *valueList = GetROCSSValueList(false); 1.3635 + 1.3636 + const nsStyleBorder* border = StyleBorder(); 1.3637 + // four slice numbers 1.3638 + NS_FOR_CSS_SIDES (side) { 1.3639 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3640 + valueList->AppendCSSValue(val); 1.3641 + SetValueToCoord(val, border->mBorderImageOutset.Get(side), 1.3642 + true, nullptr); 1.3643 + } 1.3644 + 1.3645 + return valueList; 1.3646 +} 1.3647 + 1.3648 +CSSValue* 1.3649 +nsComputedDOMStyle::DoGetBorderImageRepeat() 1.3650 +{ 1.3651 + nsDOMCSSValueList* valueList = GetROCSSValueList(false); 1.3652 + 1.3653 + const nsStyleBorder* border = StyleBorder(); 1.3654 + 1.3655 + // horizontal repeat 1.3656 + nsROCSSPrimitiveValue* valX = new nsROCSSPrimitiveValue; 1.3657 + valueList->AppendCSSValue(valX); 1.3658 + valX->SetIdent( 1.3659 + nsCSSProps::ValueToKeywordEnum(border->mBorderImageRepeatH, 1.3660 + nsCSSProps::kBorderImageRepeatKTable)); 1.3661 + 1.3662 + // vertical repeat 1.3663 + nsROCSSPrimitiveValue* valY = new nsROCSSPrimitiveValue; 1.3664 + valueList->AppendCSSValue(valY); 1.3665 + valY->SetIdent( 1.3666 + nsCSSProps::ValueToKeywordEnum(border->mBorderImageRepeatV, 1.3667 + nsCSSProps::kBorderImageRepeatKTable)); 1.3668 + return valueList; 1.3669 +} 1.3670 + 1.3671 +CSSValue* 1.3672 +nsComputedDOMStyle::DoGetAlignContent() 1.3673 +{ 1.3674 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3675 + val->SetIdent( 1.3676 + nsCSSProps::ValueToKeywordEnum(StylePosition()->mAlignContent, 1.3677 + nsCSSProps::kAlignContentKTable)); 1.3678 + return val; 1.3679 +} 1.3680 + 1.3681 +CSSValue* 1.3682 +nsComputedDOMStyle::DoGetAlignItems() 1.3683 +{ 1.3684 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3685 + val->SetIdent( 1.3686 + nsCSSProps::ValueToKeywordEnum(StylePosition()->mAlignItems, 1.3687 + nsCSSProps::kAlignItemsKTable)); 1.3688 + return val; 1.3689 +} 1.3690 + 1.3691 +CSSValue* 1.3692 +nsComputedDOMStyle::DoGetAlignSelf() 1.3693 +{ 1.3694 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3695 + uint8_t computedAlignSelf = StylePosition()->mAlignSelf; 1.3696 + 1.3697 + if (computedAlignSelf == NS_STYLE_ALIGN_SELF_AUTO) { 1.3698 + // "align-self: auto" needs to compute to parent's align-items value. 1.3699 + nsStyleContext* parentStyleContext = mStyleContextHolder->GetParent(); 1.3700 + if (parentStyleContext) { 1.3701 + computedAlignSelf = 1.3702 + parentStyleContext->StylePosition()->mAlignItems; 1.3703 + } else { 1.3704 + // No parent --> use default. 1.3705 + computedAlignSelf = NS_STYLE_ALIGN_ITEMS_INITIAL_VALUE; 1.3706 + } 1.3707 + } 1.3708 + 1.3709 + NS_ABORT_IF_FALSE(computedAlignSelf != NS_STYLE_ALIGN_SELF_AUTO, 1.3710 + "Should have swapped out 'auto' for something non-auto"); 1.3711 + val->SetIdent( 1.3712 + nsCSSProps::ValueToKeywordEnum(computedAlignSelf, 1.3713 + nsCSSProps::kAlignSelfKTable)); 1.3714 + return val; 1.3715 +} 1.3716 + 1.3717 +CSSValue* 1.3718 +nsComputedDOMStyle::DoGetFlexBasis() 1.3719 +{ 1.3720 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3721 + 1.3722 + // XXXdholbert We could make this more automagic and resolve percentages 1.3723 + // if we wanted, by passing in a PercentageBaseGetter instead of nullptr 1.3724 + // below. Logic would go like this: 1.3725 + // if (i'm a flex item) { 1.3726 + // if (my flex container is horizontal) { 1.3727 + // percentageBaseGetter = &nsComputedDOMStyle::GetCBContentWidth; 1.3728 + // } else { 1.3729 + // percentageBaseGetter = &nsComputedDOMStyle::GetCBContentHeight; 1.3730 + // } 1.3731 + // } 1.3732 + 1.3733 + SetValueToCoord(val, StylePosition()->mFlexBasis, true, 1.3734 + nullptr, nsCSSProps::kWidthKTable); 1.3735 + return val; 1.3736 +} 1.3737 + 1.3738 +CSSValue* 1.3739 +nsComputedDOMStyle::DoGetFlexDirection() 1.3740 +{ 1.3741 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3742 + val->SetIdent( 1.3743 + nsCSSProps::ValueToKeywordEnum(StylePosition()->mFlexDirection, 1.3744 + nsCSSProps::kFlexDirectionKTable)); 1.3745 + return val; 1.3746 +} 1.3747 + 1.3748 +CSSValue* 1.3749 +nsComputedDOMStyle::DoGetFlexGrow() 1.3750 +{ 1.3751 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3752 + val->SetNumber(StylePosition()->mFlexGrow); 1.3753 + return val; 1.3754 +} 1.3755 + 1.3756 +CSSValue* 1.3757 +nsComputedDOMStyle::DoGetFlexShrink() 1.3758 +{ 1.3759 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3760 + val->SetNumber(StylePosition()->mFlexShrink); 1.3761 + return val; 1.3762 +} 1.3763 + 1.3764 +CSSValue* 1.3765 +nsComputedDOMStyle::DoGetFlexWrap() 1.3766 +{ 1.3767 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3768 + val->SetIdent( 1.3769 + nsCSSProps::ValueToKeywordEnum(StylePosition()->mFlexWrap, 1.3770 + nsCSSProps::kFlexWrapKTable)); 1.3771 + return val; 1.3772 +} 1.3773 + 1.3774 +CSSValue* 1.3775 +nsComputedDOMStyle::DoGetOrder() 1.3776 +{ 1.3777 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3778 + val->SetNumber(StylePosition()->mOrder); 1.3779 + return val; 1.3780 +} 1.3781 + 1.3782 +CSSValue* 1.3783 +nsComputedDOMStyle::DoGetJustifyContent() 1.3784 +{ 1.3785 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3786 + val->SetIdent( 1.3787 + nsCSSProps::ValueToKeywordEnum(StylePosition()->mJustifyContent, 1.3788 + nsCSSProps::kJustifyContentKTable)); 1.3789 + return val; 1.3790 +} 1.3791 + 1.3792 +CSSValue* 1.3793 +nsComputedDOMStyle::DoGetFloatEdge() 1.3794 +{ 1.3795 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3796 + val->SetIdent( 1.3797 + nsCSSProps::ValueToKeywordEnum(StyleBorder()->mFloatEdge, 1.3798 + nsCSSProps::kFloatEdgeKTable)); 1.3799 + return val; 1.3800 +} 1.3801 + 1.3802 +CSSValue* 1.3803 +nsComputedDOMStyle::DoGetForceBrokenImageIcon() 1.3804 +{ 1.3805 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3806 + val->SetNumber(StyleUIReset()->mForceBrokenImageIcon); 1.3807 + return val; 1.3808 +} 1.3809 + 1.3810 +CSSValue* 1.3811 +nsComputedDOMStyle::DoGetImageOrientation() 1.3812 +{ 1.3813 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3814 + nsAutoString string; 1.3815 + nsStyleImageOrientation orientation = StyleVisibility()->mImageOrientation; 1.3816 + 1.3817 + if (orientation.IsFromImage()) { 1.3818 + string.AppendLiteral("from-image"); 1.3819 + } else { 1.3820 + nsStyleUtil::AppendAngleValue(orientation.AngleAsCoord(), string); 1.3821 + 1.3822 + if (orientation.IsFlipped()) { 1.3823 + string.AppendLiteral(" flip"); 1.3824 + } 1.3825 + } 1.3826 + 1.3827 + val->SetString(string); 1.3828 + return val; 1.3829 +} 1.3830 + 1.3831 +CSSValue* 1.3832 +nsComputedDOMStyle::DoGetIMEMode() 1.3833 +{ 1.3834 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3835 + val->SetIdent( 1.3836 + nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mIMEMode, 1.3837 + nsCSSProps::kIMEModeKTable)); 1.3838 + return val; 1.3839 +} 1.3840 + 1.3841 +CSSValue* 1.3842 +nsComputedDOMStyle::DoGetUserFocus() 1.3843 +{ 1.3844 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3845 + val->SetIdent( 1.3846 + nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mUserFocus, 1.3847 + nsCSSProps::kUserFocusKTable)); 1.3848 + return val; 1.3849 +} 1.3850 + 1.3851 +CSSValue* 1.3852 +nsComputedDOMStyle::DoGetUserInput() 1.3853 +{ 1.3854 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3855 + val->SetIdent( 1.3856 + nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mUserInput, 1.3857 + nsCSSProps::kUserInputKTable)); 1.3858 + return val; 1.3859 +} 1.3860 + 1.3861 +CSSValue* 1.3862 +nsComputedDOMStyle::DoGetUserModify() 1.3863 +{ 1.3864 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3865 + val->SetIdent( 1.3866 + nsCSSProps::ValueToKeywordEnum(StyleUserInterface()->mUserModify, 1.3867 + nsCSSProps::kUserModifyKTable)); 1.3868 + return val; 1.3869 +} 1.3870 + 1.3871 +CSSValue* 1.3872 +nsComputedDOMStyle::DoGetUserSelect() 1.3873 +{ 1.3874 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3875 + val->SetIdent( 1.3876 + nsCSSProps::ValueToKeywordEnum(StyleUIReset()->mUserSelect, 1.3877 + nsCSSProps::kUserSelectKTable)); 1.3878 + return val; 1.3879 +} 1.3880 + 1.3881 +CSSValue* 1.3882 +nsComputedDOMStyle::DoGetDisplay() 1.3883 +{ 1.3884 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3885 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mDisplay, 1.3886 + nsCSSProps::kDisplayKTable)); 1.3887 + return val; 1.3888 +} 1.3889 + 1.3890 +CSSValue* 1.3891 +nsComputedDOMStyle::DoGetPosition() 1.3892 +{ 1.3893 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3894 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mPosition, 1.3895 + nsCSSProps::kPositionKTable)); 1.3896 + return val; 1.3897 +} 1.3898 + 1.3899 +CSSValue* 1.3900 +nsComputedDOMStyle::DoGetClip() 1.3901 +{ 1.3902 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3903 + 1.3904 + const nsStyleDisplay* display = StyleDisplay(); 1.3905 + 1.3906 + if (display->mClipFlags == NS_STYLE_CLIP_AUTO) { 1.3907 + val->SetIdent(eCSSKeyword_auto); 1.3908 + } else { 1.3909 + // create the cssvalues for the sides, stick them in the rect object 1.3910 + nsROCSSPrimitiveValue *topVal = new nsROCSSPrimitiveValue; 1.3911 + nsROCSSPrimitiveValue *rightVal = new nsROCSSPrimitiveValue; 1.3912 + nsROCSSPrimitiveValue *bottomVal = new nsROCSSPrimitiveValue; 1.3913 + nsROCSSPrimitiveValue *leftVal = new nsROCSSPrimitiveValue; 1.3914 + nsDOMCSSRect * domRect = new nsDOMCSSRect(topVal, rightVal, 1.3915 + bottomVal, leftVal); 1.3916 + if (display->mClipFlags & NS_STYLE_CLIP_TOP_AUTO) { 1.3917 + topVal->SetIdent(eCSSKeyword_auto); 1.3918 + } else { 1.3919 + topVal->SetAppUnits(display->mClip.y); 1.3920 + } 1.3921 + 1.3922 + if (display->mClipFlags & NS_STYLE_CLIP_RIGHT_AUTO) { 1.3923 + rightVal->SetIdent(eCSSKeyword_auto); 1.3924 + } else { 1.3925 + rightVal->SetAppUnits(display->mClip.width + display->mClip.x); 1.3926 + } 1.3927 + 1.3928 + if (display->mClipFlags & NS_STYLE_CLIP_BOTTOM_AUTO) { 1.3929 + bottomVal->SetIdent(eCSSKeyword_auto); 1.3930 + } else { 1.3931 + bottomVal->SetAppUnits(display->mClip.height + display->mClip.y); 1.3932 + } 1.3933 + 1.3934 + if (display->mClipFlags & NS_STYLE_CLIP_LEFT_AUTO) { 1.3935 + leftVal->SetIdent(eCSSKeyword_auto); 1.3936 + } else { 1.3937 + leftVal->SetAppUnits(display->mClip.x); 1.3938 + } 1.3939 + val->SetRect(domRect); 1.3940 + } 1.3941 + 1.3942 + return val; 1.3943 +} 1.3944 + 1.3945 +CSSValue* 1.3946 +nsComputedDOMStyle::DoGetWillChange() 1.3947 +{ 1.3948 + const nsTArray<nsString>& willChange = StyleDisplay()->mWillChange; 1.3949 + 1.3950 + if (willChange.IsEmpty()) { 1.3951 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.3952 + val->SetIdent(eCSSKeyword_auto); 1.3953 + return val; 1.3954 + } 1.3955 + 1.3956 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.3957 + for (size_t i = 0; i < willChange.Length(); i++) { 1.3958 + const nsString& willChangeIdentifier = willChange[i]; 1.3959 + nsROCSSPrimitiveValue* property = new nsROCSSPrimitiveValue; 1.3960 + valueList->AppendCSSValue(property); 1.3961 + property->SetString(willChangeIdentifier); 1.3962 + } 1.3963 + 1.3964 + return valueList; 1.3965 +} 1.3966 + 1.3967 +CSSValue* 1.3968 +nsComputedDOMStyle::DoGetOverflow() 1.3969 +{ 1.3970 + const nsStyleDisplay* display = StyleDisplay(); 1.3971 + 1.3972 + if (display->mOverflowX != display->mOverflowY) { 1.3973 + // No value to return. We can't express this combination of 1.3974 + // values as a shorthand. 1.3975 + return nullptr; 1.3976 + } 1.3977 + 1.3978 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3979 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(display->mOverflowX, 1.3980 + nsCSSProps::kOverflowKTable)); 1.3981 + return val; 1.3982 +} 1.3983 + 1.3984 +CSSValue* 1.3985 +nsComputedDOMStyle::DoGetOverflowX() 1.3986 +{ 1.3987 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3988 + val->SetIdent( 1.3989 + nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOverflowX, 1.3990 + nsCSSProps::kOverflowSubKTable)); 1.3991 + return val; 1.3992 +} 1.3993 + 1.3994 +CSSValue* 1.3995 +nsComputedDOMStyle::DoGetOverflowY() 1.3996 +{ 1.3997 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.3998 + val->SetIdent( 1.3999 + nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOverflowY, 1.4000 + nsCSSProps::kOverflowSubKTable)); 1.4001 + return val; 1.4002 +} 1.4003 + 1.4004 +CSSValue* 1.4005 +nsComputedDOMStyle::DoGetOverflowClipBox() 1.4006 +{ 1.4007 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.4008 + val->SetIdent( 1.4009 + nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mOverflowClipBox, 1.4010 + nsCSSProps::kOverflowClipBoxKTable)); 1.4011 + return val; 1.4012 +} 1.4013 + 1.4014 +CSSValue* 1.4015 +nsComputedDOMStyle::DoGetResize() 1.4016 +{ 1.4017 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4018 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mResize, 1.4019 + nsCSSProps::kResizeKTable)); 1.4020 + return val; 1.4021 +} 1.4022 + 1.4023 + 1.4024 +CSSValue* 1.4025 +nsComputedDOMStyle::DoGetPageBreakAfter() 1.4026 +{ 1.4027 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4028 + 1.4029 + const nsStyleDisplay *display = StyleDisplay(); 1.4030 + 1.4031 + if (display->mBreakAfter) { 1.4032 + val->SetIdent(eCSSKeyword_always); 1.4033 + } else { 1.4034 + val->SetIdent(eCSSKeyword_auto); 1.4035 + } 1.4036 + 1.4037 + return val; 1.4038 +} 1.4039 + 1.4040 +CSSValue* 1.4041 +nsComputedDOMStyle::DoGetPageBreakBefore() 1.4042 +{ 1.4043 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4044 + 1.4045 + const nsStyleDisplay *display = StyleDisplay(); 1.4046 + 1.4047 + if (display->mBreakBefore) { 1.4048 + val->SetIdent(eCSSKeyword_always); 1.4049 + } else { 1.4050 + val->SetIdent(eCSSKeyword_auto); 1.4051 + } 1.4052 + 1.4053 + return val; 1.4054 +} 1.4055 + 1.4056 +CSSValue* 1.4057 +nsComputedDOMStyle::DoGetPageBreakInside() 1.4058 +{ 1.4059 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4060 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mBreakInside, 1.4061 + nsCSSProps::kPageBreakInsideKTable)); 1.4062 + return val; 1.4063 +} 1.4064 + 1.4065 +CSSValue* 1.4066 +nsComputedDOMStyle::DoGetTouchAction() 1.4067 +{ 1.4068 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4069 + 1.4070 + int32_t intValue = StyleDisplay()->mTouchAction; 1.4071 + 1.4072 + // None and Auto and Manipulation values aren't allowed 1.4073 + // to be in conjunction with other values. 1.4074 + // But there are all checks in CSSParserImpl::ParseTouchAction 1.4075 + nsAutoString valueStr; 1.4076 + nsStyleUtil::AppendBitmaskCSSValue(eCSSProperty_touch_action, intValue, 1.4077 + NS_STYLE_TOUCH_ACTION_NONE, NS_STYLE_TOUCH_ACTION_MANIPULATION, 1.4078 + valueStr); 1.4079 + val->SetString(valueStr); 1.4080 + return val; 1.4081 +} 1.4082 + 1.4083 +CSSValue* 1.4084 +nsComputedDOMStyle::DoGetHeight() 1.4085 +{ 1.4086 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4087 + 1.4088 + bool calcHeight = false; 1.4089 + 1.4090 + if (mInnerFrame) { 1.4091 + calcHeight = true; 1.4092 + 1.4093 + const nsStyleDisplay* displayData = StyleDisplay(); 1.4094 + if (displayData->mDisplay == NS_STYLE_DISPLAY_INLINE && 1.4095 + !(mInnerFrame->IsFrameOfType(nsIFrame::eReplaced)) && 1.4096 + // An outer SVG frame should behave the same as eReplaced in this case 1.4097 + mInnerFrame->GetType() != nsGkAtoms::svgOuterSVGFrame) { 1.4098 + 1.4099 + calcHeight = false; 1.4100 + } 1.4101 + } 1.4102 + 1.4103 + if (calcHeight) { 1.4104 + AssertFlushedPendingReflows(); 1.4105 + nsMargin adjustedValues = GetAdjustedValuesForBoxSizing(); 1.4106 + val->SetAppUnits(mInnerFrame->GetContentRect().height + 1.4107 + adjustedValues.TopBottom()); 1.4108 + } else { 1.4109 + const nsStylePosition *positionData = StylePosition(); 1.4110 + 1.4111 + nscoord minHeight = 1.4112 + StyleCoordToNSCoord(positionData->mMinHeight, 1.4113 + &nsComputedDOMStyle::GetCBContentHeight, 0, true); 1.4114 + 1.4115 + nscoord maxHeight = 1.4116 + StyleCoordToNSCoord(positionData->mMaxHeight, 1.4117 + &nsComputedDOMStyle::GetCBContentHeight, 1.4118 + nscoord_MAX, true); 1.4119 + 1.4120 + SetValueToCoord(val, positionData->mHeight, true, nullptr, nullptr, 1.4121 + minHeight, maxHeight); 1.4122 + } 1.4123 + 1.4124 + return val; 1.4125 +} 1.4126 + 1.4127 +CSSValue* 1.4128 +nsComputedDOMStyle::DoGetWidth() 1.4129 +{ 1.4130 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4131 + 1.4132 + bool calcWidth = false; 1.4133 + 1.4134 + if (mInnerFrame) { 1.4135 + calcWidth = true; 1.4136 + 1.4137 + const nsStyleDisplay *displayData = StyleDisplay(); 1.4138 + if (displayData->mDisplay == NS_STYLE_DISPLAY_INLINE && 1.4139 + !(mInnerFrame->IsFrameOfType(nsIFrame::eReplaced)) && 1.4140 + // An outer SVG frame should behave the same as eReplaced in this case 1.4141 + mInnerFrame->GetType() != nsGkAtoms::svgOuterSVGFrame) { 1.4142 + 1.4143 + calcWidth = false; 1.4144 + } 1.4145 + } 1.4146 + 1.4147 + if (calcWidth) { 1.4148 + AssertFlushedPendingReflows(); 1.4149 + nsMargin adjustedValues = GetAdjustedValuesForBoxSizing(); 1.4150 + val->SetAppUnits(mInnerFrame->GetContentRect().width + 1.4151 + adjustedValues.LeftRight()); 1.4152 + } else { 1.4153 + const nsStylePosition *positionData = StylePosition(); 1.4154 + 1.4155 + nscoord minWidth = 1.4156 + StyleCoordToNSCoord(positionData->mMinWidth, 1.4157 + &nsComputedDOMStyle::GetCBContentWidth, 0, true); 1.4158 + 1.4159 + nscoord maxWidth = 1.4160 + StyleCoordToNSCoord(positionData->mMaxWidth, 1.4161 + &nsComputedDOMStyle::GetCBContentWidth, 1.4162 + nscoord_MAX, true); 1.4163 + 1.4164 + SetValueToCoord(val, positionData->mWidth, true, nullptr, 1.4165 + nsCSSProps::kWidthKTable, minWidth, maxWidth); 1.4166 + } 1.4167 + 1.4168 + return val; 1.4169 +} 1.4170 + 1.4171 +CSSValue* 1.4172 +nsComputedDOMStyle::DoGetMaxHeight() 1.4173 +{ 1.4174 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4175 + SetValueToCoord(val, StylePosition()->mMaxHeight, true, 1.4176 + &nsComputedDOMStyle::GetCBContentHeight); 1.4177 + return val; 1.4178 +} 1.4179 + 1.4180 +CSSValue* 1.4181 +nsComputedDOMStyle::DoGetMaxWidth() 1.4182 +{ 1.4183 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4184 + SetValueToCoord(val, StylePosition()->mMaxWidth, true, 1.4185 + &nsComputedDOMStyle::GetCBContentWidth, 1.4186 + nsCSSProps::kWidthKTable); 1.4187 + return val; 1.4188 +} 1.4189 + 1.4190 +CSSValue* 1.4191 +nsComputedDOMStyle::DoGetMinHeight() 1.4192 +{ 1.4193 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4194 + SetValueToCoord(val, StylePosition()->mMinHeight, true, 1.4195 + &nsComputedDOMStyle::GetCBContentHeight); 1.4196 + return val; 1.4197 +} 1.4198 + 1.4199 +CSSValue* 1.4200 +nsComputedDOMStyle::DoGetMinWidth() 1.4201 +{ 1.4202 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4203 + SetValueToCoord(val, StylePosition()->mMinWidth, true, 1.4204 + &nsComputedDOMStyle::GetCBContentWidth, 1.4205 + nsCSSProps::kWidthKTable); 1.4206 + return val; 1.4207 +} 1.4208 + 1.4209 +CSSValue* 1.4210 +nsComputedDOMStyle::DoGetMixBlendMode() 1.4211 +{ 1.4212 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.4213 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleDisplay()->mMixBlendMode, 1.4214 + nsCSSProps::kBlendModeKTable)); 1.4215 + return val; 1.4216 +} 1.4217 + 1.4218 +CSSValue* 1.4219 +nsComputedDOMStyle::DoGetLeft() 1.4220 +{ 1.4221 + return GetOffsetWidthFor(NS_SIDE_LEFT); 1.4222 +} 1.4223 + 1.4224 +CSSValue* 1.4225 +nsComputedDOMStyle::DoGetRight() 1.4226 +{ 1.4227 + return GetOffsetWidthFor(NS_SIDE_RIGHT); 1.4228 +} 1.4229 + 1.4230 +CSSValue* 1.4231 +nsComputedDOMStyle::DoGetTop() 1.4232 +{ 1.4233 + return GetOffsetWidthFor(NS_SIDE_TOP); 1.4234 +} 1.4235 + 1.4236 +nsDOMCSSValueList* 1.4237 +nsComputedDOMStyle::GetROCSSValueList(bool aCommaDelimited) 1.4238 +{ 1.4239 + nsDOMCSSValueList *valueList = new nsDOMCSSValueList(aCommaDelimited, true); 1.4240 + NS_ASSERTION(valueList != 0, "ran out of memory"); 1.4241 + 1.4242 + return valueList; 1.4243 +} 1.4244 + 1.4245 +CSSValue* 1.4246 +nsComputedDOMStyle::GetOffsetWidthFor(mozilla::css::Side aSide) 1.4247 +{ 1.4248 + const nsStyleDisplay* display = StyleDisplay(); 1.4249 + 1.4250 + AssertFlushedPendingReflows(); 1.4251 + 1.4252 + uint8_t position = display->mPosition; 1.4253 + if (!mOuterFrame) { 1.4254 + // GetRelativeOffset and GetAbsoluteOffset don't handle elements 1.4255 + // without frames in any sensible way. GetStaticOffset, however, 1.4256 + // is perfect for that case. 1.4257 + position = NS_STYLE_POSITION_STATIC; 1.4258 + } 1.4259 + 1.4260 + switch (position) { 1.4261 + case NS_STYLE_POSITION_STATIC: 1.4262 + return GetStaticOffset(aSide); 1.4263 + case NS_STYLE_POSITION_RELATIVE: 1.4264 + return GetRelativeOffset(aSide); 1.4265 + case NS_STYLE_POSITION_STICKY: 1.4266 + return GetStickyOffset(aSide); 1.4267 + case NS_STYLE_POSITION_ABSOLUTE: 1.4268 + case NS_STYLE_POSITION_FIXED: 1.4269 + return GetAbsoluteOffset(aSide); 1.4270 + default: 1.4271 + NS_ERROR("Invalid position"); 1.4272 + return nullptr; 1.4273 + } 1.4274 +} 1.4275 + 1.4276 +CSSValue* 1.4277 +nsComputedDOMStyle::GetAbsoluteOffset(mozilla::css::Side aSide) 1.4278 +{ 1.4279 + MOZ_ASSERT(mOuterFrame, "need a frame, so we can call GetContainingBlock()"); 1.4280 + 1.4281 + nsIFrame* container = mOuterFrame->GetContainingBlock(); 1.4282 + nsMargin margin = mOuterFrame->GetUsedMargin(); 1.4283 + nsMargin border = container->GetUsedBorder(); 1.4284 + nsMargin scrollbarSizes(0, 0, 0, 0); 1.4285 + nsRect rect = mOuterFrame->GetRect(); 1.4286 + nsRect containerRect = container->GetRect(); 1.4287 + 1.4288 + if (container->GetType() == nsGkAtoms::viewportFrame) { 1.4289 + // For absolutely positioned frames scrollbars are taken into 1.4290 + // account by virtue of getting a containing block that does 1.4291 + // _not_ include the scrollbars. For fixed positioned frames, 1.4292 + // the containing block is the viewport, which _does_ include 1.4293 + // scrollbars. We have to do some extra work. 1.4294 + // the first child in the default frame list is what we want 1.4295 + nsIFrame* scrollingChild = container->GetFirstPrincipalChild(); 1.4296 + nsIScrollableFrame *scrollFrame = do_QueryFrame(scrollingChild); 1.4297 + if (scrollFrame) { 1.4298 + scrollbarSizes = scrollFrame->GetActualScrollbarSizes(); 1.4299 + } 1.4300 + } 1.4301 + 1.4302 + nscoord offset = 0; 1.4303 + switch (aSide) { 1.4304 + case NS_SIDE_TOP: 1.4305 + offset = rect.y - margin.top - border.top - scrollbarSizes.top; 1.4306 + 1.4307 + break; 1.4308 + case NS_SIDE_RIGHT: 1.4309 + offset = containerRect.width - rect.width - 1.4310 + rect.x - margin.right - border.right - scrollbarSizes.right; 1.4311 + 1.4312 + break; 1.4313 + case NS_SIDE_BOTTOM: 1.4314 + offset = containerRect.height - rect.height - 1.4315 + rect.y - margin.bottom - border.bottom - scrollbarSizes.bottom; 1.4316 + 1.4317 + break; 1.4318 + case NS_SIDE_LEFT: 1.4319 + offset = rect.x - margin.left - border.left - scrollbarSizes.left; 1.4320 + 1.4321 + break; 1.4322 + default: 1.4323 + NS_ERROR("Invalid side"); 1.4324 + break; 1.4325 + } 1.4326 + 1.4327 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4328 + val->SetAppUnits(offset); 1.4329 + return val; 1.4330 +} 1.4331 + 1.4332 +static_assert(NS_SIDE_TOP == 0 && NS_SIDE_RIGHT == 1 && 1.4333 + NS_SIDE_BOTTOM == 2 && NS_SIDE_LEFT == 3, 1.4334 + "box side constants not as expected for NS_OPPOSITE_SIDE"); 1.4335 +#define NS_OPPOSITE_SIDE(s_) mozilla::css::Side(((s_) + 2) & 3) 1.4336 + 1.4337 +CSSValue* 1.4338 +nsComputedDOMStyle::GetRelativeOffset(mozilla::css::Side aSide) 1.4339 +{ 1.4340 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4341 + 1.4342 + const nsStylePosition* positionData = StylePosition(); 1.4343 + int32_t sign = 1; 1.4344 + nsStyleCoord coord = positionData->mOffset.Get(aSide); 1.4345 + 1.4346 + NS_ASSERTION(coord.GetUnit() == eStyleUnit_Coord || 1.4347 + coord.GetUnit() == eStyleUnit_Percent || 1.4348 + coord.GetUnit() == eStyleUnit_Auto || 1.4349 + coord.IsCalcUnit(), 1.4350 + "Unexpected unit"); 1.4351 + 1.4352 + if (coord.GetUnit() == eStyleUnit_Auto) { 1.4353 + coord = positionData->mOffset.Get(NS_OPPOSITE_SIDE(aSide)); 1.4354 + sign = -1; 1.4355 + } 1.4356 + PercentageBaseGetter baseGetter; 1.4357 + if (aSide == NS_SIDE_LEFT || aSide == NS_SIDE_RIGHT) { 1.4358 + baseGetter = &nsComputedDOMStyle::GetCBContentWidth; 1.4359 + } else { 1.4360 + baseGetter = &nsComputedDOMStyle::GetCBContentHeight; 1.4361 + } 1.4362 + 1.4363 + val->SetAppUnits(sign * StyleCoordToNSCoord(coord, baseGetter, 0, false)); 1.4364 + return val; 1.4365 +} 1.4366 + 1.4367 +CSSValue* 1.4368 +nsComputedDOMStyle::GetStickyOffset(mozilla::css::Side aSide) 1.4369 +{ 1.4370 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4371 + 1.4372 + const nsStylePosition* positionData = StylePosition(); 1.4373 + nsStyleCoord coord = positionData->mOffset.Get(aSide); 1.4374 + 1.4375 + NS_ASSERTION(coord.GetUnit() == eStyleUnit_Coord || 1.4376 + coord.GetUnit() == eStyleUnit_Percent || 1.4377 + coord.GetUnit() == eStyleUnit_Auto || 1.4378 + coord.IsCalcUnit(), 1.4379 + "Unexpected unit"); 1.4380 + 1.4381 + if (coord.GetUnit() == eStyleUnit_Auto) { 1.4382 + val->SetIdent(eCSSKeyword_auto); 1.4383 + return val; 1.4384 + } 1.4385 + PercentageBaseGetter baseGetter; 1.4386 + if (aSide == NS_SIDE_LEFT || aSide == NS_SIDE_RIGHT) { 1.4387 + baseGetter = &nsComputedDOMStyle::GetScrollFrameContentWidth; 1.4388 + } else { 1.4389 + baseGetter = &nsComputedDOMStyle::GetScrollFrameContentHeight; 1.4390 + } 1.4391 + 1.4392 + val->SetAppUnits(StyleCoordToNSCoord(coord, baseGetter, 0, false)); 1.4393 + return val; 1.4394 +} 1.4395 + 1.4396 + 1.4397 +CSSValue* 1.4398 +nsComputedDOMStyle::GetStaticOffset(mozilla::css::Side aSide) 1.4399 + 1.4400 +{ 1.4401 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4402 + SetValueToCoord(val, StylePosition()->mOffset.Get(aSide), false); 1.4403 + return val; 1.4404 +} 1.4405 + 1.4406 +CSSValue* 1.4407 +nsComputedDOMStyle::GetPaddingWidthFor(mozilla::css::Side aSide) 1.4408 +{ 1.4409 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.4410 + 1.4411 + if (!mInnerFrame) { 1.4412 + SetValueToCoord(val, StylePadding()->mPadding.Get(aSide), true); 1.4413 + } else { 1.4414 + AssertFlushedPendingReflows(); 1.4415 + 1.4416 + val->SetAppUnits(mInnerFrame->GetUsedPadding().Side(aSide)); 1.4417 + } 1.4418 + 1.4419 + return val; 1.4420 +} 1.4421 + 1.4422 +bool 1.4423 +nsComputedDOMStyle::GetLineHeightCoord(nscoord& aCoord) 1.4424 +{ 1.4425 + AssertFlushedPendingReflows(); 1.4426 + 1.4427 + nscoord blockHeight = NS_AUTOHEIGHT; 1.4428 + if (StyleText()->mLineHeight.GetUnit() == eStyleUnit_Enumerated) { 1.4429 + if (!mInnerFrame) 1.4430 + return false; 1.4431 + 1.4432 + if (nsLayoutUtils::IsNonWrapperBlock(mInnerFrame)) { 1.4433 + blockHeight = mInnerFrame->GetContentRect().height; 1.4434 + } else { 1.4435 + GetCBContentHeight(blockHeight); 1.4436 + } 1.4437 + } 1.4438 + 1.4439 + // lie about font size inflation since we lie about font size (since 1.4440 + // the inflation only applies to text) 1.4441 + aCoord = nsHTMLReflowState::CalcLineHeight(mContent, mStyleContextHolder, 1.4442 + blockHeight, 1.0f); 1.4443 + 1.4444 + // CalcLineHeight uses font->mFont.size, but we want to use 1.4445 + // font->mSize as the font size. Adjust for that. Also adjust for 1.4446 + // the text zoom, if any. 1.4447 + const nsStyleFont* font = StyleFont(); 1.4448 + float fCoord = float(aCoord); 1.4449 + if (font->mAllowZoom) { 1.4450 + fCoord /= mPresShell->GetPresContext()->TextZoom(); 1.4451 + } 1.4452 + if (font->mFont.size != font->mSize) { 1.4453 + fCoord = fCoord * (float(font->mSize) / float(font->mFont.size)); 1.4454 + } 1.4455 + aCoord = NSToCoordRound(fCoord); 1.4456 + 1.4457 + return true; 1.4458 +} 1.4459 + 1.4460 +CSSValue* 1.4461 +nsComputedDOMStyle::GetBorderColorsFor(mozilla::css::Side aSide) 1.4462 +{ 1.4463 + const nsStyleBorder *border = StyleBorder(); 1.4464 + 1.4465 + if (border->mBorderColors) { 1.4466 + nsBorderColors* borderColors = border->mBorderColors[aSide]; 1.4467 + if (borderColors) { 1.4468 + nsDOMCSSValueList *valueList = GetROCSSValueList(false); 1.4469 + 1.4470 + do { 1.4471 + nsROCSSPrimitiveValue *primitive = new nsROCSSPrimitiveValue; 1.4472 + 1.4473 + SetToRGBAColor(primitive, borderColors->mColor); 1.4474 + 1.4475 + valueList->AppendCSSValue(primitive); 1.4476 + borderColors = borderColors->mNext; 1.4477 + } while (borderColors); 1.4478 + 1.4479 + return valueList; 1.4480 + } 1.4481 + } 1.4482 + 1.4483 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4484 + val->SetIdent(eCSSKeyword_none); 1.4485 + return val; 1.4486 +} 1.4487 + 1.4488 +CSSValue* 1.4489 +nsComputedDOMStyle::GetBorderWidthFor(mozilla::css::Side aSide) 1.4490 +{ 1.4491 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.4492 + 1.4493 + nscoord width; 1.4494 + if (mInnerFrame) { 1.4495 + AssertFlushedPendingReflows(); 1.4496 + width = mInnerFrame->GetUsedBorder().Side(aSide); 1.4497 + } else { 1.4498 + width = StyleBorder()->GetComputedBorderWidth(aSide); 1.4499 + } 1.4500 + val->SetAppUnits(width); 1.4501 + 1.4502 + return val; 1.4503 +} 1.4504 + 1.4505 +CSSValue* 1.4506 +nsComputedDOMStyle::GetBorderColorFor(mozilla::css::Side aSide) 1.4507 +{ 1.4508 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.4509 + 1.4510 + nscolor color; 1.4511 + bool foreground; 1.4512 + StyleBorder()->GetBorderColor(aSide, color, foreground); 1.4513 + if (foreground) { 1.4514 + color = StyleColor()->mColor; 1.4515 + } 1.4516 + 1.4517 + SetToRGBAColor(val, color); 1.4518 + return val; 1.4519 +} 1.4520 + 1.4521 +CSSValue* 1.4522 +nsComputedDOMStyle::GetMarginWidthFor(mozilla::css::Side aSide) 1.4523 +{ 1.4524 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.4525 + 1.4526 + if (!mInnerFrame) { 1.4527 + SetValueToCoord(val, StyleMargin()->mMargin.Get(aSide), false); 1.4528 + } else { 1.4529 + AssertFlushedPendingReflows(); 1.4530 + 1.4531 + // For tables, GetUsedMargin always returns an empty margin, so we 1.4532 + // should read the margin from the outer table frame instead. 1.4533 + val->SetAppUnits(mOuterFrame->GetUsedMargin().Side(aSide)); 1.4534 + NS_ASSERTION(mOuterFrame == mInnerFrame || 1.4535 + mInnerFrame->GetUsedMargin() == nsMargin(0, 0, 0, 0), 1.4536 + "Inner tables must have zero margins"); 1.4537 + } 1.4538 + 1.4539 + return val; 1.4540 +} 1.4541 + 1.4542 +CSSValue* 1.4543 +nsComputedDOMStyle::GetBorderStyleFor(mozilla::css::Side aSide) 1.4544 +{ 1.4545 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.4546 + val->SetIdent( 1.4547 + nsCSSProps::ValueToKeywordEnum(StyleBorder()->GetBorderStyle(aSide), 1.4548 + nsCSSProps::kBorderStyleKTable)); 1.4549 + return val; 1.4550 +} 1.4551 + 1.4552 +void 1.4553 +nsComputedDOMStyle::SetValueToCoord(nsROCSSPrimitiveValue* aValue, 1.4554 + const nsStyleCoord& aCoord, 1.4555 + bool aClampNegativeCalc, 1.4556 + PercentageBaseGetter aPercentageBaseGetter, 1.4557 + const KTableValue aTable[], 1.4558 + nscoord aMinAppUnits, 1.4559 + nscoord aMaxAppUnits) 1.4560 +{ 1.4561 + NS_PRECONDITION(aValue, "Must have a value to work with"); 1.4562 + 1.4563 + switch (aCoord.GetUnit()) { 1.4564 + case eStyleUnit_Normal: 1.4565 + aValue->SetIdent(eCSSKeyword_normal); 1.4566 + break; 1.4567 + 1.4568 + case eStyleUnit_Auto: 1.4569 + aValue->SetIdent(eCSSKeyword_auto); 1.4570 + break; 1.4571 + 1.4572 + case eStyleUnit_Percent: 1.4573 + { 1.4574 + nscoord percentageBase; 1.4575 + if (aPercentageBaseGetter && 1.4576 + (this->*aPercentageBaseGetter)(percentageBase)) { 1.4577 + nscoord val = NSCoordSaturatingMultiply(percentageBase, 1.4578 + aCoord.GetPercentValue()); 1.4579 + aValue->SetAppUnits(std::max(aMinAppUnits, std::min(val, aMaxAppUnits))); 1.4580 + } else { 1.4581 + aValue->SetPercent(aCoord.GetPercentValue()); 1.4582 + } 1.4583 + } 1.4584 + break; 1.4585 + 1.4586 + case eStyleUnit_Factor: 1.4587 + aValue->SetNumber(aCoord.GetFactorValue()); 1.4588 + break; 1.4589 + 1.4590 + case eStyleUnit_Coord: 1.4591 + { 1.4592 + nscoord val = aCoord.GetCoordValue(); 1.4593 + aValue->SetAppUnits(std::max(aMinAppUnits, std::min(val, aMaxAppUnits))); 1.4594 + } 1.4595 + break; 1.4596 + 1.4597 + case eStyleUnit_Integer: 1.4598 + aValue->SetNumber(aCoord.GetIntValue()); 1.4599 + break; 1.4600 + 1.4601 + case eStyleUnit_Enumerated: 1.4602 + NS_ASSERTION(aTable, "Must have table to handle this case"); 1.4603 + aValue->SetIdent(nsCSSProps::ValueToKeywordEnum(aCoord.GetIntValue(), 1.4604 + aTable)); 1.4605 + break; 1.4606 + 1.4607 + case eStyleUnit_None: 1.4608 + aValue->SetIdent(eCSSKeyword_none); 1.4609 + break; 1.4610 + 1.4611 + case eStyleUnit_Calc: 1.4612 + nscoord percentageBase; 1.4613 + if (!aCoord.CalcHasPercent()) { 1.4614 + nscoord val = nsRuleNode::ComputeCoordPercentCalc(aCoord, 0); 1.4615 + if (aClampNegativeCalc && val < 0) { 1.4616 + NS_ABORT_IF_FALSE(aCoord.IsCalcUnit(), 1.4617 + "parser should have rejected value"); 1.4618 + val = 0; 1.4619 + } 1.4620 + aValue->SetAppUnits(std::max(aMinAppUnits, std::min(val, aMaxAppUnits))); 1.4621 + } else if (aPercentageBaseGetter && 1.4622 + (this->*aPercentageBaseGetter)(percentageBase)) { 1.4623 + nscoord val = 1.4624 + nsRuleNode::ComputeCoordPercentCalc(aCoord, percentageBase); 1.4625 + if (aClampNegativeCalc && val < 0) { 1.4626 + NS_ABORT_IF_FALSE(aCoord.IsCalcUnit(), 1.4627 + "parser should have rejected value"); 1.4628 + val = 0; 1.4629 + } 1.4630 + aValue->SetAppUnits(std::max(aMinAppUnits, std::min(val, aMaxAppUnits))); 1.4631 + } else { 1.4632 + nsStyleCoord::Calc *calc = aCoord.GetCalcValue(); 1.4633 + SetValueToCalc(calc, aValue); 1.4634 + } 1.4635 + break; 1.4636 + 1.4637 + case eStyleUnit_Degree: 1.4638 + aValue->SetDegree(aCoord.GetAngleValue()); 1.4639 + break; 1.4640 + 1.4641 + case eStyleUnit_Grad: 1.4642 + aValue->SetGrad(aCoord.GetAngleValue()); 1.4643 + break; 1.4644 + 1.4645 + case eStyleUnit_Radian: 1.4646 + aValue->SetRadian(aCoord.GetAngleValue()); 1.4647 + break; 1.4648 + 1.4649 + case eStyleUnit_Turn: 1.4650 + aValue->SetTurn(aCoord.GetAngleValue()); 1.4651 + break; 1.4652 + 1.4653 + case eStyleUnit_FlexFraction: { 1.4654 + nsAutoString tmpStr; 1.4655 + nsStyleUtil::AppendCSSNumber(aCoord.GetFlexFractionValue(), tmpStr); 1.4656 + tmpStr.AppendLiteral("fr"); 1.4657 + aValue->SetString(tmpStr); 1.4658 + break; 1.4659 + } 1.4660 + 1.4661 + default: 1.4662 + NS_ERROR("Can't handle this unit"); 1.4663 + break; 1.4664 + } 1.4665 +} 1.4666 + 1.4667 +nscoord 1.4668 +nsComputedDOMStyle::StyleCoordToNSCoord(const nsStyleCoord& aCoord, 1.4669 + PercentageBaseGetter aPercentageBaseGetter, 1.4670 + nscoord aDefaultValue, 1.4671 + bool aClampNegativeCalc) 1.4672 +{ 1.4673 + NS_PRECONDITION(aPercentageBaseGetter, "Must have a percentage base getter"); 1.4674 + if (aCoord.GetUnit() == eStyleUnit_Coord) { 1.4675 + return aCoord.GetCoordValue(); 1.4676 + } 1.4677 + if (aCoord.GetUnit() == eStyleUnit_Percent || aCoord.IsCalcUnit()) { 1.4678 + nscoord percentageBase; 1.4679 + if ((this->*aPercentageBaseGetter)(percentageBase)) { 1.4680 + nscoord result = 1.4681 + nsRuleNode::ComputeCoordPercentCalc(aCoord, percentageBase); 1.4682 + if (aClampNegativeCalc && result < 0) { 1.4683 + NS_ABORT_IF_FALSE(aCoord.IsCalcUnit(), 1.4684 + "parser should have rejected value"); 1.4685 + result = 0; 1.4686 + } 1.4687 + return result; 1.4688 + } 1.4689 + // Fall through to returning aDefaultValue if we have no percentage base. 1.4690 + } 1.4691 + 1.4692 + return aDefaultValue; 1.4693 +} 1.4694 + 1.4695 +bool 1.4696 +nsComputedDOMStyle::GetCBContentWidth(nscoord& aWidth) 1.4697 +{ 1.4698 + if (!mOuterFrame) { 1.4699 + return false; 1.4700 + } 1.4701 + 1.4702 + AssertFlushedPendingReflows(); 1.4703 + 1.4704 + nsIFrame* container = mOuterFrame->GetContainingBlock(); 1.4705 + aWidth = container->GetContentRect().width; 1.4706 + return true; 1.4707 +} 1.4708 + 1.4709 +bool 1.4710 +nsComputedDOMStyle::GetCBContentHeight(nscoord& aHeight) 1.4711 +{ 1.4712 + if (!mOuterFrame) { 1.4713 + return false; 1.4714 + } 1.4715 + 1.4716 + AssertFlushedPendingReflows(); 1.4717 + 1.4718 + nsIFrame* container = mOuterFrame->GetContainingBlock(); 1.4719 + aHeight = container->GetContentRect().height; 1.4720 + return true; 1.4721 +} 1.4722 + 1.4723 +bool 1.4724 +nsComputedDOMStyle::GetScrollFrameContentWidth(nscoord& aWidth) 1.4725 +{ 1.4726 + if (!mOuterFrame) { 1.4727 + return false; 1.4728 + } 1.4729 + 1.4730 + AssertFlushedPendingReflows(); 1.4731 + 1.4732 + nsIScrollableFrame* scrollableFrame = 1.4733 + nsLayoutUtils::GetNearestScrollableFrame(mOuterFrame->GetParent(), 1.4734 + nsLayoutUtils::SCROLLABLE_SAME_DOC | 1.4735 + nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN); 1.4736 + 1.4737 + if (!scrollableFrame) { 1.4738 + return false; 1.4739 + } 1.4740 + aWidth = 1.4741 + scrollableFrame->GetScrolledFrame()->GetContentRectRelativeToSelf().width; 1.4742 + return true; 1.4743 +} 1.4744 + 1.4745 +bool 1.4746 +nsComputedDOMStyle::GetScrollFrameContentHeight(nscoord& aHeight) 1.4747 +{ 1.4748 + if (!mOuterFrame) { 1.4749 + return false; 1.4750 + } 1.4751 + 1.4752 + AssertFlushedPendingReflows(); 1.4753 + 1.4754 + nsIScrollableFrame* scrollableFrame = 1.4755 + nsLayoutUtils::GetNearestScrollableFrame(mOuterFrame->GetParent(), 1.4756 + nsLayoutUtils::SCROLLABLE_SAME_DOC | 1.4757 + nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN); 1.4758 + 1.4759 + if (!scrollableFrame) { 1.4760 + return false; 1.4761 + } 1.4762 + aHeight = 1.4763 + scrollableFrame->GetScrolledFrame()->GetContentRectRelativeToSelf().height; 1.4764 + return true; 1.4765 +} 1.4766 + 1.4767 +bool 1.4768 +nsComputedDOMStyle::GetFrameBorderRectWidth(nscoord& aWidth) 1.4769 +{ 1.4770 + if (!mInnerFrame) { 1.4771 + return false; 1.4772 + } 1.4773 + 1.4774 + AssertFlushedPendingReflows(); 1.4775 + 1.4776 + aWidth = mInnerFrame->GetSize().width; 1.4777 + return true; 1.4778 +} 1.4779 + 1.4780 +bool 1.4781 +nsComputedDOMStyle::GetFrameBorderRectHeight(nscoord& aHeight) 1.4782 +{ 1.4783 + if (!mInnerFrame) { 1.4784 + return false; 1.4785 + } 1.4786 + 1.4787 + AssertFlushedPendingReflows(); 1.4788 + 1.4789 + aHeight = mInnerFrame->GetSize().height; 1.4790 + return true; 1.4791 +} 1.4792 + 1.4793 +bool 1.4794 +nsComputedDOMStyle::GetFrameBoundsWidthForTransform(nscoord& aWidth) 1.4795 +{ 1.4796 + // We need a frame to work with. 1.4797 + if (!mInnerFrame) { 1.4798 + return false; 1.4799 + } 1.4800 + 1.4801 + AssertFlushedPendingReflows(); 1.4802 + 1.4803 + aWidth = nsDisplayTransform::GetFrameBoundsForTransform(mInnerFrame).width; 1.4804 + return true; 1.4805 +} 1.4806 + 1.4807 +bool 1.4808 +nsComputedDOMStyle::GetFrameBoundsHeightForTransform(nscoord& aHeight) 1.4809 +{ 1.4810 + // We need a frame to work with. 1.4811 + if (!mInnerFrame) { 1.4812 + return false; 1.4813 + } 1.4814 + 1.4815 + AssertFlushedPendingReflows(); 1.4816 + 1.4817 + aHeight = nsDisplayTransform::GetFrameBoundsForTransform(mInnerFrame).height; 1.4818 + return true; 1.4819 +} 1.4820 + 1.4821 +CSSValue* 1.4822 +nsComputedDOMStyle::GetSVGPaintFor(bool aFill) 1.4823 +{ 1.4824 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.4825 + 1.4826 + const nsStyleSVG* svg = StyleSVG(); 1.4827 + const nsStyleSVGPaint* paint = nullptr; 1.4828 + 1.4829 + if (aFill) 1.4830 + paint = &svg->mFill; 1.4831 + else 1.4832 + paint = &svg->mStroke; 1.4833 + 1.4834 + nsAutoString paintString; 1.4835 + 1.4836 + switch (paint->mType) { 1.4837 + case eStyleSVGPaintType_None: 1.4838 + { 1.4839 + val->SetIdent(eCSSKeyword_none); 1.4840 + break; 1.4841 + } 1.4842 + case eStyleSVGPaintType_Color: 1.4843 + { 1.4844 + SetToRGBAColor(val, paint->mPaint.mColor); 1.4845 + break; 1.4846 + } 1.4847 + case eStyleSVGPaintType_Server: 1.4848 + { 1.4849 + nsDOMCSSValueList *valueList = GetROCSSValueList(false); 1.4850 + valueList->AppendCSSValue(val); 1.4851 + 1.4852 + nsROCSSPrimitiveValue* fallback = new nsROCSSPrimitiveValue; 1.4853 + valueList->AppendCSSValue(fallback); 1.4854 + 1.4855 + val->SetURI(paint->mPaint.mPaintServer); 1.4856 + SetToRGBAColor(fallback, paint->mFallbackColor); 1.4857 + return valueList; 1.4858 + } 1.4859 + case eStyleSVGPaintType_ContextFill: 1.4860 + { 1.4861 + val->SetIdent(eCSSKeyword_context_fill); 1.4862 + break; 1.4863 + } 1.4864 + case eStyleSVGPaintType_ContextStroke: 1.4865 + { 1.4866 + val->SetIdent(eCSSKeyword_context_stroke); 1.4867 + break; 1.4868 + } 1.4869 + } 1.4870 + 1.4871 + return val; 1.4872 +} 1.4873 + 1.4874 +CSSValue* 1.4875 +nsComputedDOMStyle::DoGetFill() 1.4876 +{ 1.4877 + return GetSVGPaintFor(true); 1.4878 +} 1.4879 + 1.4880 +CSSValue* 1.4881 +nsComputedDOMStyle::DoGetStroke() 1.4882 +{ 1.4883 + return GetSVGPaintFor(false); 1.4884 +} 1.4885 + 1.4886 +CSSValue* 1.4887 +nsComputedDOMStyle::DoGetMarkerEnd() 1.4888 +{ 1.4889 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.4890 + 1.4891 + const nsStyleSVG* svg = StyleSVG(); 1.4892 + 1.4893 + if (svg->mMarkerEnd) 1.4894 + val->SetURI(svg->mMarkerEnd); 1.4895 + else 1.4896 + val->SetIdent(eCSSKeyword_none); 1.4897 + 1.4898 + return val; 1.4899 +} 1.4900 + 1.4901 +CSSValue* 1.4902 +nsComputedDOMStyle::DoGetMarkerMid() 1.4903 +{ 1.4904 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.4905 + 1.4906 + const nsStyleSVG* svg = StyleSVG(); 1.4907 + 1.4908 + if (svg->mMarkerMid) 1.4909 + val->SetURI(svg->mMarkerMid); 1.4910 + else 1.4911 + val->SetIdent(eCSSKeyword_none); 1.4912 + 1.4913 + return val; 1.4914 +} 1.4915 + 1.4916 +CSSValue* 1.4917 +nsComputedDOMStyle::DoGetMarkerStart() 1.4918 +{ 1.4919 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.4920 + 1.4921 + const nsStyleSVG* svg = StyleSVG(); 1.4922 + 1.4923 + if (svg->mMarkerStart) 1.4924 + val->SetURI(svg->mMarkerStart); 1.4925 + else 1.4926 + val->SetIdent(eCSSKeyword_none); 1.4927 + 1.4928 + return val; 1.4929 +} 1.4930 + 1.4931 +CSSValue* 1.4932 +nsComputedDOMStyle::DoGetStrokeDasharray() 1.4933 +{ 1.4934 + const nsStyleSVG* svg = StyleSVG(); 1.4935 + 1.4936 + if (!svg->mStrokeDasharrayLength || !svg->mStrokeDasharray) { 1.4937 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.4938 + val->SetIdent(eCSSKeyword_none); 1.4939 + return val; 1.4940 + } 1.4941 + 1.4942 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.4943 + 1.4944 + for (uint32_t i = 0; i < svg->mStrokeDasharrayLength; i++) { 1.4945 + nsROCSSPrimitiveValue* dash = new nsROCSSPrimitiveValue; 1.4946 + valueList->AppendCSSValue(dash); 1.4947 + 1.4948 + SetValueToCoord(dash, svg->mStrokeDasharray[i], true); 1.4949 + } 1.4950 + 1.4951 + return valueList; 1.4952 +} 1.4953 + 1.4954 +CSSValue* 1.4955 +nsComputedDOMStyle::DoGetStrokeDashoffset() 1.4956 +{ 1.4957 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.4958 + SetValueToCoord(val, StyleSVG()->mStrokeDashoffset, false); 1.4959 + return val; 1.4960 +} 1.4961 + 1.4962 +CSSValue* 1.4963 +nsComputedDOMStyle::DoGetStrokeWidth() 1.4964 +{ 1.4965 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.4966 + SetValueToCoord(val, StyleSVG()->mStrokeWidth, true); 1.4967 + return val; 1.4968 +} 1.4969 + 1.4970 +CSSValue* 1.4971 +nsComputedDOMStyle::DoGetVectorEffect() 1.4972 +{ 1.4973 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4974 + val->SetIdent(nsCSSProps::ValueToKeywordEnum(StyleSVGReset()->mVectorEffect, 1.4975 + nsCSSProps::kVectorEffectKTable)); 1.4976 + return val; 1.4977 +} 1.4978 + 1.4979 +CSSValue* 1.4980 +nsComputedDOMStyle::DoGetFillOpacity() 1.4981 +{ 1.4982 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4983 + val->SetNumber(StyleSVG()->mFillOpacity); 1.4984 + return val; 1.4985 +} 1.4986 + 1.4987 +CSSValue* 1.4988 +nsComputedDOMStyle::DoGetFloodOpacity() 1.4989 +{ 1.4990 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4991 + val->SetNumber(StyleSVGReset()->mFloodOpacity); 1.4992 + return val; 1.4993 +} 1.4994 + 1.4995 +CSSValue* 1.4996 +nsComputedDOMStyle::DoGetStopOpacity() 1.4997 +{ 1.4998 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.4999 + val->SetNumber(StyleSVGReset()->mStopOpacity); 1.5000 + return val; 1.5001 +} 1.5002 + 1.5003 +CSSValue* 1.5004 +nsComputedDOMStyle::DoGetStrokeMiterlimit() 1.5005 +{ 1.5006 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5007 + val->SetNumber(StyleSVG()->mStrokeMiterlimit); 1.5008 + return val; 1.5009 +} 1.5010 + 1.5011 +CSSValue* 1.5012 +nsComputedDOMStyle::DoGetStrokeOpacity() 1.5013 +{ 1.5014 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5015 + val->SetNumber(StyleSVG()->mStrokeOpacity); 1.5016 + return val; 1.5017 +} 1.5018 + 1.5019 +CSSValue* 1.5020 +nsComputedDOMStyle::DoGetClipRule() 1.5021 +{ 1.5022 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5023 + val->SetIdent(nsCSSProps::ValueToKeywordEnum( 1.5024 + StyleSVG()->mClipRule, nsCSSProps::kFillRuleKTable)); 1.5025 + return val; 1.5026 +} 1.5027 + 1.5028 +CSSValue* 1.5029 +nsComputedDOMStyle::DoGetFillRule() 1.5030 +{ 1.5031 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5032 + val->SetIdent(nsCSSProps::ValueToKeywordEnum( 1.5033 + StyleSVG()->mFillRule, nsCSSProps::kFillRuleKTable)); 1.5034 + return val; 1.5035 +} 1.5036 + 1.5037 +CSSValue* 1.5038 +nsComputedDOMStyle::DoGetStrokeLinecap() 1.5039 +{ 1.5040 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5041 + val->SetIdent( 1.5042 + nsCSSProps::ValueToKeywordEnum(StyleSVG()->mStrokeLinecap, 1.5043 + nsCSSProps::kStrokeLinecapKTable)); 1.5044 + return val; 1.5045 +} 1.5046 + 1.5047 +CSSValue* 1.5048 +nsComputedDOMStyle::DoGetStrokeLinejoin() 1.5049 +{ 1.5050 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5051 + val->SetIdent( 1.5052 + nsCSSProps::ValueToKeywordEnum(StyleSVG()->mStrokeLinejoin, 1.5053 + nsCSSProps::kStrokeLinejoinKTable)); 1.5054 + return val; 1.5055 +} 1.5056 + 1.5057 +CSSValue* 1.5058 +nsComputedDOMStyle::DoGetTextAnchor() 1.5059 +{ 1.5060 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5061 + val->SetIdent( 1.5062 + nsCSSProps::ValueToKeywordEnum(StyleSVG()->mTextAnchor, 1.5063 + nsCSSProps::kTextAnchorKTable)); 1.5064 + return val; 1.5065 +} 1.5066 + 1.5067 +CSSValue* 1.5068 +nsComputedDOMStyle::DoGetColorInterpolation() 1.5069 +{ 1.5070 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5071 + val->SetIdent( 1.5072 + nsCSSProps::ValueToKeywordEnum(StyleSVG()->mColorInterpolation, 1.5073 + nsCSSProps::kColorInterpolationKTable)); 1.5074 + return val; 1.5075 +} 1.5076 + 1.5077 +CSSValue* 1.5078 +nsComputedDOMStyle::DoGetColorInterpolationFilters() 1.5079 +{ 1.5080 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5081 + val->SetIdent( 1.5082 + nsCSSProps::ValueToKeywordEnum(StyleSVG()->mColorInterpolationFilters, 1.5083 + nsCSSProps::kColorInterpolationKTable)); 1.5084 + return val; 1.5085 +} 1.5086 + 1.5087 +CSSValue* 1.5088 +nsComputedDOMStyle::DoGetDominantBaseline() 1.5089 +{ 1.5090 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5091 + val->SetIdent( 1.5092 + nsCSSProps::ValueToKeywordEnum(StyleSVGReset()->mDominantBaseline, 1.5093 + nsCSSProps::kDominantBaselineKTable)); 1.5094 + return val; 1.5095 +} 1.5096 + 1.5097 +CSSValue* 1.5098 +nsComputedDOMStyle::DoGetImageRendering() 1.5099 +{ 1.5100 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5101 + val->SetIdent( 1.5102 + nsCSSProps::ValueToKeywordEnum(StyleSVG()->mImageRendering, 1.5103 + nsCSSProps::kImageRenderingKTable)); 1.5104 + return val; 1.5105 +} 1.5106 + 1.5107 +CSSValue* 1.5108 +nsComputedDOMStyle::DoGetShapeRendering() 1.5109 +{ 1.5110 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5111 + val->SetIdent( 1.5112 + nsCSSProps::ValueToKeywordEnum(StyleSVG()->mShapeRendering, 1.5113 + nsCSSProps::kShapeRenderingKTable)); 1.5114 + return val; 1.5115 +} 1.5116 + 1.5117 +CSSValue* 1.5118 +nsComputedDOMStyle::DoGetTextRendering() 1.5119 +{ 1.5120 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5121 + val->SetIdent( 1.5122 + nsCSSProps::ValueToKeywordEnum(StyleSVG()->mTextRendering, 1.5123 + nsCSSProps::kTextRenderingKTable)); 1.5124 + return val; 1.5125 +} 1.5126 + 1.5127 +CSSValue* 1.5128 +nsComputedDOMStyle::DoGetFloodColor() 1.5129 +{ 1.5130 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5131 + SetToRGBAColor(val, StyleSVGReset()->mFloodColor); 1.5132 + return val; 1.5133 +} 1.5134 + 1.5135 +CSSValue* 1.5136 +nsComputedDOMStyle::DoGetLightingColor() 1.5137 +{ 1.5138 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5139 + SetToRGBAColor(val, StyleSVGReset()->mLightingColor); 1.5140 + return val; 1.5141 +} 1.5142 + 1.5143 +CSSValue* 1.5144 +nsComputedDOMStyle::DoGetStopColor() 1.5145 +{ 1.5146 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5147 + SetToRGBAColor(val, StyleSVGReset()->mStopColor); 1.5148 + return val; 1.5149 +} 1.5150 + 1.5151 +CSSValue* 1.5152 +nsComputedDOMStyle::DoGetClipPath() 1.5153 +{ 1.5154 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.5155 + 1.5156 + const nsStyleSVGReset* svg = StyleSVGReset(); 1.5157 + 1.5158 + if (svg->mClipPath) 1.5159 + val->SetURI(svg->mClipPath); 1.5160 + else 1.5161 + val->SetIdent(eCSSKeyword_none); 1.5162 + 1.5163 + return val; 1.5164 +} 1.5165 + 1.5166 +void 1.5167 +nsComputedDOMStyle::SetCssTextToCoord(nsAString& aCssText, 1.5168 + const nsStyleCoord& aCoord) 1.5169 +{ 1.5170 + nsROCSSPrimitiveValue* value = new nsROCSSPrimitiveValue; 1.5171 + bool clampNegativeCalc = true; 1.5172 + SetValueToCoord(value, aCoord, clampNegativeCalc); 1.5173 + value->GetCssText(aCssText); 1.5174 + delete value; 1.5175 +} 1.5176 + 1.5177 +CSSValue* 1.5178 +nsComputedDOMStyle::CreatePrimitiveValueForStyleFilter( 1.5179 + const nsStyleFilter& aStyleFilter) 1.5180 +{ 1.5181 + nsROCSSPrimitiveValue* value = new nsROCSSPrimitiveValue; 1.5182 + // Handle url(). 1.5183 + if (aStyleFilter.GetType() == NS_STYLE_FILTER_URL) { 1.5184 + value->SetURI(aStyleFilter.GetURL()); 1.5185 + return value; 1.5186 + } 1.5187 + 1.5188 + // Filter function name and opening parenthesis. 1.5189 + nsAutoString filterFunctionString; 1.5190 + AppendASCIItoUTF16( 1.5191 + nsCSSProps::ValueToKeyword(aStyleFilter.GetType(), 1.5192 + nsCSSProps::kFilterFunctionKTable), 1.5193 + filterFunctionString); 1.5194 + filterFunctionString.AppendLiteral("("); 1.5195 + 1.5196 + nsAutoString argumentString; 1.5197 + if (aStyleFilter.GetType() == NS_STYLE_FILTER_DROP_SHADOW) { 1.5198 + // Handle drop-shadow() 1.5199 + nsRefPtr<CSSValue> shadowValue = 1.5200 + GetCSSShadowArray(aStyleFilter.GetDropShadow(), 1.5201 + StyleColor()->mColor, 1.5202 + false); 1.5203 + ErrorResult dummy; 1.5204 + shadowValue->GetCssText(argumentString, dummy); 1.5205 + } else { 1.5206 + // Filter function argument. 1.5207 + SetCssTextToCoord(argumentString, aStyleFilter.GetFilterParameter()); 1.5208 + } 1.5209 + filterFunctionString.Append(argumentString); 1.5210 + 1.5211 + // Filter function closing parenthesis. 1.5212 + filterFunctionString.AppendLiteral(")"); 1.5213 + 1.5214 + value->SetString(filterFunctionString); 1.5215 + return value; 1.5216 +} 1.5217 + 1.5218 +CSSValue* 1.5219 +nsComputedDOMStyle::DoGetFilter() 1.5220 +{ 1.5221 + const nsTArray<nsStyleFilter>& filters = StyleSVGReset()->mFilters; 1.5222 + 1.5223 + if (filters.IsEmpty()) { 1.5224 + nsROCSSPrimitiveValue* value = new nsROCSSPrimitiveValue; 1.5225 + value->SetIdent(eCSSKeyword_none); 1.5226 + return value; 1.5227 + } 1.5228 + 1.5229 + nsDOMCSSValueList* valueList = GetROCSSValueList(false); 1.5230 + for(uint32_t i = 0; i < filters.Length(); i++) { 1.5231 + CSSValue* value = CreatePrimitiveValueForStyleFilter(filters[i]); 1.5232 + valueList->AppendCSSValue(value); 1.5233 + } 1.5234 + return valueList; 1.5235 +} 1.5236 + 1.5237 +CSSValue* 1.5238 +nsComputedDOMStyle::DoGetMask() 1.5239 +{ 1.5240 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.5241 + 1.5242 + const nsStyleSVGReset* svg = StyleSVGReset(); 1.5243 + 1.5244 + if (svg->mMask) 1.5245 + val->SetURI(svg->mMask); 1.5246 + else 1.5247 + val->SetIdent(eCSSKeyword_none); 1.5248 + 1.5249 + return val; 1.5250 +} 1.5251 + 1.5252 +CSSValue* 1.5253 +nsComputedDOMStyle::DoGetMaskType() 1.5254 +{ 1.5255 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5256 + val->SetIdent( 1.5257 + nsCSSProps::ValueToKeywordEnum(StyleSVGReset()->mMaskType, 1.5258 + nsCSSProps::kMaskTypeKTable)); 1.5259 + return val; 1.5260 +} 1.5261 + 1.5262 +CSSValue* 1.5263 +nsComputedDOMStyle::DoGetPaintOrder() 1.5264 +{ 1.5265 + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; 1.5266 + nsAutoString string; 1.5267 + uint8_t paintOrder = StyleSVG()->mPaintOrder; 1.5268 + nsStyleUtil::AppendPaintOrderValue(paintOrder, string); 1.5269 + val->SetString(string); 1.5270 + return val; 1.5271 +} 1.5272 + 1.5273 +CSSValue* 1.5274 +nsComputedDOMStyle::DoGetTransitionDelay() 1.5275 +{ 1.5276 + const nsStyleDisplay* display = StyleDisplay(); 1.5277 + 1.5278 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.5279 + 1.5280 + NS_ABORT_IF_FALSE(display->mTransitionDelayCount > 0, 1.5281 + "first item must be explicit"); 1.5282 + uint32_t i = 0; 1.5283 + do { 1.5284 + const nsTransition *transition = &display->mTransitions[i]; 1.5285 + nsROCSSPrimitiveValue* delay = new nsROCSSPrimitiveValue; 1.5286 + valueList->AppendCSSValue(delay); 1.5287 + delay->SetTime((float)transition->GetDelay() / (float)PR_MSEC_PER_SEC); 1.5288 + } while (++i < display->mTransitionDelayCount); 1.5289 + 1.5290 + return valueList; 1.5291 +} 1.5292 + 1.5293 +CSSValue* 1.5294 +nsComputedDOMStyle::DoGetTransitionDuration() 1.5295 +{ 1.5296 + const nsStyleDisplay* display = StyleDisplay(); 1.5297 + 1.5298 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.5299 + 1.5300 + NS_ABORT_IF_FALSE(display->mTransitionDurationCount > 0, 1.5301 + "first item must be explicit"); 1.5302 + uint32_t i = 0; 1.5303 + do { 1.5304 + const nsTransition *transition = &display->mTransitions[i]; 1.5305 + nsROCSSPrimitiveValue* duration = new nsROCSSPrimitiveValue; 1.5306 + valueList->AppendCSSValue(duration); 1.5307 + 1.5308 + duration->SetTime((float)transition->GetDuration() / (float)PR_MSEC_PER_SEC); 1.5309 + } while (++i < display->mTransitionDurationCount); 1.5310 + 1.5311 + return valueList; 1.5312 +} 1.5313 + 1.5314 +CSSValue* 1.5315 +nsComputedDOMStyle::DoGetTransitionProperty() 1.5316 +{ 1.5317 + const nsStyleDisplay* display = StyleDisplay(); 1.5318 + 1.5319 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.5320 + 1.5321 + NS_ABORT_IF_FALSE(display->mTransitionPropertyCount > 0, 1.5322 + "first item must be explicit"); 1.5323 + uint32_t i = 0; 1.5324 + do { 1.5325 + const nsTransition *transition = &display->mTransitions[i]; 1.5326 + nsROCSSPrimitiveValue* property = new nsROCSSPrimitiveValue; 1.5327 + valueList->AppendCSSValue(property); 1.5328 + nsCSSProperty cssprop = transition->GetProperty(); 1.5329 + if (cssprop == eCSSPropertyExtra_all_properties) 1.5330 + property->SetIdent(eCSSKeyword_all); 1.5331 + else if (cssprop == eCSSPropertyExtra_no_properties) 1.5332 + property->SetIdent(eCSSKeyword_none); 1.5333 + else if (cssprop == eCSSProperty_UNKNOWN) 1.5334 + { 1.5335 + nsAutoString escaped; 1.5336 + nsStyleUtil::AppendEscapedCSSIdent( 1.5337 + nsDependentAtomString(transition->GetUnknownProperty()), escaped); 1.5338 + property->SetString(escaped); // really want SetIdent 1.5339 + } 1.5340 + else 1.5341 + property->SetString(nsCSSProps::GetStringValue(cssprop)); 1.5342 + } while (++i < display->mTransitionPropertyCount); 1.5343 + 1.5344 + return valueList; 1.5345 +} 1.5346 + 1.5347 +void 1.5348 +nsComputedDOMStyle::AppendTimingFunction(nsDOMCSSValueList *aValueList, 1.5349 + const nsTimingFunction& aTimingFunction) 1.5350 +{ 1.5351 + nsROCSSPrimitiveValue* timingFunction = new nsROCSSPrimitiveValue; 1.5352 + aValueList->AppendCSSValue(timingFunction); 1.5353 + 1.5354 + nsAutoString tmp; 1.5355 + 1.5356 + if (aTimingFunction.mType == nsTimingFunction::Function) { 1.5357 + // set the value from the cubic-bezier control points 1.5358 + // (We could try to regenerate the keywords if we want.) 1.5359 + tmp.AppendLiteral("cubic-bezier("); 1.5360 + tmp.AppendFloat(aTimingFunction.mFunc.mX1); 1.5361 + tmp.AppendLiteral(", "); 1.5362 + tmp.AppendFloat(aTimingFunction.mFunc.mY1); 1.5363 + tmp.AppendLiteral(", "); 1.5364 + tmp.AppendFloat(aTimingFunction.mFunc.mX2); 1.5365 + tmp.AppendLiteral(", "); 1.5366 + tmp.AppendFloat(aTimingFunction.mFunc.mY2); 1.5367 + tmp.AppendLiteral(")"); 1.5368 + } else { 1.5369 + tmp.AppendLiteral("steps("); 1.5370 + tmp.AppendInt(aTimingFunction.mSteps); 1.5371 + if (aTimingFunction.mType == nsTimingFunction::StepStart) { 1.5372 + tmp.AppendLiteral(", start)"); 1.5373 + } else { 1.5374 + tmp.AppendLiteral(", end)"); 1.5375 + } 1.5376 + } 1.5377 + timingFunction->SetString(tmp); 1.5378 +} 1.5379 + 1.5380 +CSSValue* 1.5381 +nsComputedDOMStyle::DoGetTransitionTimingFunction() 1.5382 +{ 1.5383 + const nsStyleDisplay* display = StyleDisplay(); 1.5384 + 1.5385 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.5386 + 1.5387 + NS_ABORT_IF_FALSE(display->mTransitionTimingFunctionCount > 0, 1.5388 + "first item must be explicit"); 1.5389 + uint32_t i = 0; 1.5390 + do { 1.5391 + AppendTimingFunction(valueList, 1.5392 + display->mTransitions[i].GetTimingFunction()); 1.5393 + } while (++i < display->mTransitionTimingFunctionCount); 1.5394 + 1.5395 + return valueList; 1.5396 +} 1.5397 + 1.5398 +CSSValue* 1.5399 +nsComputedDOMStyle::DoGetAnimationName() 1.5400 +{ 1.5401 + const nsStyleDisplay* display = StyleDisplay(); 1.5402 + 1.5403 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.5404 + 1.5405 + NS_ABORT_IF_FALSE(display->mAnimationNameCount > 0, 1.5406 + "first item must be explicit"); 1.5407 + uint32_t i = 0; 1.5408 + do { 1.5409 + const nsAnimation *animation = &display->mAnimations[i]; 1.5410 + nsROCSSPrimitiveValue* property = new nsROCSSPrimitiveValue; 1.5411 + valueList->AppendCSSValue(property); 1.5412 + 1.5413 + const nsString& name = animation->GetName(); 1.5414 + if (name.IsEmpty()) { 1.5415 + property->SetIdent(eCSSKeyword_none); 1.5416 + } else { 1.5417 + nsAutoString escaped; 1.5418 + nsStyleUtil::AppendEscapedCSSIdent(animation->GetName(), escaped); 1.5419 + property->SetString(escaped); // really want SetIdent 1.5420 + } 1.5421 + } while (++i < display->mAnimationNameCount); 1.5422 + 1.5423 + return valueList; 1.5424 +} 1.5425 + 1.5426 +CSSValue* 1.5427 +nsComputedDOMStyle::DoGetAnimationDelay() 1.5428 +{ 1.5429 + const nsStyleDisplay* display = StyleDisplay(); 1.5430 + 1.5431 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.5432 + 1.5433 + NS_ABORT_IF_FALSE(display->mAnimationDelayCount > 0, 1.5434 + "first item must be explicit"); 1.5435 + uint32_t i = 0; 1.5436 + do { 1.5437 + const nsAnimation *animation = &display->mAnimations[i]; 1.5438 + nsROCSSPrimitiveValue* delay = new nsROCSSPrimitiveValue; 1.5439 + valueList->AppendCSSValue(delay); 1.5440 + delay->SetTime((float)animation->GetDelay() / (float)PR_MSEC_PER_SEC); 1.5441 + } while (++i < display->mAnimationDelayCount); 1.5442 + 1.5443 + return valueList; 1.5444 +} 1.5445 + 1.5446 +CSSValue* 1.5447 +nsComputedDOMStyle::DoGetAnimationDuration() 1.5448 +{ 1.5449 + const nsStyleDisplay* display = StyleDisplay(); 1.5450 + 1.5451 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.5452 + 1.5453 + NS_ABORT_IF_FALSE(display->mAnimationDurationCount > 0, 1.5454 + "first item must be explicit"); 1.5455 + uint32_t i = 0; 1.5456 + do { 1.5457 + const nsAnimation *animation = &display->mAnimations[i]; 1.5458 + nsROCSSPrimitiveValue* duration = new nsROCSSPrimitiveValue; 1.5459 + valueList->AppendCSSValue(duration); 1.5460 + 1.5461 + duration->SetTime((float)animation->GetDuration() / (float)PR_MSEC_PER_SEC); 1.5462 + } while (++i < display->mAnimationDurationCount); 1.5463 + 1.5464 + return valueList; 1.5465 +} 1.5466 + 1.5467 +CSSValue* 1.5468 +nsComputedDOMStyle::DoGetAnimationTimingFunction() 1.5469 +{ 1.5470 + const nsStyleDisplay* display = StyleDisplay(); 1.5471 + 1.5472 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.5473 + 1.5474 + NS_ABORT_IF_FALSE(display->mAnimationTimingFunctionCount > 0, 1.5475 + "first item must be explicit"); 1.5476 + uint32_t i = 0; 1.5477 + do { 1.5478 + AppendTimingFunction(valueList, 1.5479 + display->mAnimations[i].GetTimingFunction()); 1.5480 + } while (++i < display->mAnimationTimingFunctionCount); 1.5481 + 1.5482 + return valueList; 1.5483 +} 1.5484 + 1.5485 +CSSValue* 1.5486 +nsComputedDOMStyle::DoGetAnimationDirection() 1.5487 +{ 1.5488 + const nsStyleDisplay* display = StyleDisplay(); 1.5489 + 1.5490 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.5491 + 1.5492 + NS_ABORT_IF_FALSE(display->mAnimationDirectionCount > 0, 1.5493 + "first item must be explicit"); 1.5494 + uint32_t i = 0; 1.5495 + do { 1.5496 + const nsAnimation *animation = &display->mAnimations[i]; 1.5497 + nsROCSSPrimitiveValue* direction = new nsROCSSPrimitiveValue; 1.5498 + valueList->AppendCSSValue(direction); 1.5499 + direction->SetIdent( 1.5500 + nsCSSProps::ValueToKeywordEnum(animation->GetDirection(), 1.5501 + nsCSSProps::kAnimationDirectionKTable)); 1.5502 + } while (++i < display->mAnimationDirectionCount); 1.5503 + 1.5504 + return valueList; 1.5505 +} 1.5506 + 1.5507 +CSSValue* 1.5508 +nsComputedDOMStyle::DoGetAnimationFillMode() 1.5509 +{ 1.5510 + const nsStyleDisplay* display = StyleDisplay(); 1.5511 + 1.5512 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.5513 + 1.5514 + NS_ABORT_IF_FALSE(display->mAnimationFillModeCount > 0, 1.5515 + "first item must be explicit"); 1.5516 + uint32_t i = 0; 1.5517 + do { 1.5518 + const nsAnimation *animation = &display->mAnimations[i]; 1.5519 + nsROCSSPrimitiveValue* fillMode = new nsROCSSPrimitiveValue; 1.5520 + valueList->AppendCSSValue(fillMode); 1.5521 + fillMode->SetIdent( 1.5522 + nsCSSProps::ValueToKeywordEnum(animation->GetFillMode(), 1.5523 + nsCSSProps::kAnimationFillModeKTable)); 1.5524 + } while (++i < display->mAnimationFillModeCount); 1.5525 + 1.5526 + return valueList; 1.5527 +} 1.5528 + 1.5529 +CSSValue* 1.5530 +nsComputedDOMStyle::DoGetAnimationIterationCount() 1.5531 +{ 1.5532 + const nsStyleDisplay* display = StyleDisplay(); 1.5533 + 1.5534 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.5535 + 1.5536 + NS_ABORT_IF_FALSE(display->mAnimationIterationCountCount > 0, 1.5537 + "first item must be explicit"); 1.5538 + uint32_t i = 0; 1.5539 + do { 1.5540 + const nsAnimation *animation = &display->mAnimations[i]; 1.5541 + nsROCSSPrimitiveValue* iterationCount = new nsROCSSPrimitiveValue; 1.5542 + valueList->AppendCSSValue(iterationCount); 1.5543 + 1.5544 + float f = animation->GetIterationCount(); 1.5545 + /* Need a nasty hack here to work around an optimizer bug in gcc 1.5546 + 4.2 on Mac, which somehow gets confused when directly comparing 1.5547 + a float to the return value of NS_IEEEPositiveInfinity when 1.5548 + building 32-bit builds. */ 1.5549 +#ifdef XP_MACOSX 1.5550 + volatile 1.5551 +#endif 1.5552 + float inf = NS_IEEEPositiveInfinity(); 1.5553 + if (f == inf) { 1.5554 + iterationCount->SetIdent(eCSSKeyword_infinite); 1.5555 + } else { 1.5556 + iterationCount->SetNumber(f); 1.5557 + } 1.5558 + } while (++i < display->mAnimationIterationCountCount); 1.5559 + 1.5560 + return valueList; 1.5561 +} 1.5562 + 1.5563 +CSSValue* 1.5564 +nsComputedDOMStyle::DoGetAnimationPlayState() 1.5565 +{ 1.5566 + const nsStyleDisplay* display = StyleDisplay(); 1.5567 + 1.5568 + nsDOMCSSValueList *valueList = GetROCSSValueList(true); 1.5569 + 1.5570 + NS_ABORT_IF_FALSE(display->mAnimationPlayStateCount > 0, 1.5571 + "first item must be explicit"); 1.5572 + uint32_t i = 0; 1.5573 + do { 1.5574 + const nsAnimation *animation = &display->mAnimations[i]; 1.5575 + nsROCSSPrimitiveValue* playState = new nsROCSSPrimitiveValue; 1.5576 + valueList->AppendCSSValue(playState); 1.5577 + playState->SetIdent( 1.5578 + nsCSSProps::ValueToKeywordEnum(animation->GetPlayState(), 1.5579 + nsCSSProps::kAnimationPlayStateKTable)); 1.5580 + } while (++i < display->mAnimationPlayStateCount); 1.5581 + 1.5582 + return valueList; 1.5583 +} 1.5584 + 1.5585 +static void 1.5586 +MarkComputedStyleMapDirty(const char* aPref, void* aData) 1.5587 +{ 1.5588 + static_cast<nsComputedStyleMap*>(aData)->MarkDirty(); 1.5589 +} 1.5590 + 1.5591 +CSSValue* 1.5592 +nsComputedDOMStyle::DoGetCustomProperty(const nsAString& aPropertyName) 1.5593 +{ 1.5594 + MOZ_ASSERT(nsCSSProps::IsCustomPropertyName(aPropertyName)); 1.5595 + 1.5596 + const nsStyleVariables* variables = StyleVariables(); 1.5597 + 1.5598 + nsString variableValue; 1.5599 + const nsAString& name = Substring(aPropertyName, 1.5600 + CSS_CUSTOM_NAME_PREFIX_LENGTH); 1.5601 + if (!variables->mVariables.Get(name, variableValue)) { 1.5602 + return nullptr; 1.5603 + } 1.5604 + 1.5605 + nsROCSSPrimitiveValue* val = new nsROCSSPrimitiveValue; 1.5606 + val->SetString(variableValue); 1.5607 + 1.5608 + return val; 1.5609 +} 1.5610 + 1.5611 +/* static */ nsComputedStyleMap* 1.5612 +nsComputedDOMStyle::GetComputedStyleMap() 1.5613 +{ 1.5614 + static nsComputedStyleMap map = { 1.5615 + { 1.5616 +#define COMPUTED_STYLE_PROP(prop_, method_) \ 1.5617 + { eCSSProperty_##prop_, &nsComputedDOMStyle::DoGet##method_ }, 1.5618 +#include "nsComputedDOMStylePropertyList.h" 1.5619 +#undef COMPUTED_STYLE_PROP 1.5620 + } 1.5621 + }; 1.5622 + return ↦ 1.5623 +} 1.5624 + 1.5625 +/* static */ void 1.5626 +nsComputedDOMStyle::RegisterPrefChangeCallbacks() 1.5627 +{ 1.5628 + // Note that this will register callbacks for all properties with prefs, not 1.5629 + // just those that are implemented on computed style objects, as it's not 1.5630 + // easy to grab specific property data from nsCSSPropList.h based on the 1.5631 + // entries iterated in nsComputedDOMStylePropertyList.h. 1.5632 + nsComputedStyleMap* data = GetComputedStyleMap(); 1.5633 +#define REGISTER_CALLBACK(pref_) \ 1.5634 + if (pref_[0]) { \ 1.5635 + Preferences::RegisterCallback(MarkComputedStyleMapDirty, pref_, data); \ 1.5636 + } 1.5637 +#define CSS_PROP(prop_, id_, method_, flags_, pref_, parsevariant_, \ 1.5638 + kwtable_, stylestruct_, stylestructoffset_, animtype_) \ 1.5639 + REGISTER_CALLBACK(pref_) 1.5640 +#include "nsCSSPropList.h" 1.5641 +#undef CSS_PROP 1.5642 +#undef REGISTER_CALLBACK 1.5643 +} 1.5644 + 1.5645 +/* static */ void 1.5646 +nsComputedDOMStyle::UnregisterPrefChangeCallbacks() 1.5647 +{ 1.5648 + nsComputedStyleMap* data = GetComputedStyleMap(); 1.5649 +#define UNREGISTER_CALLBACK(pref_) \ 1.5650 + if (pref_[0]) { \ 1.5651 + Preferences::UnregisterCallback(MarkComputedStyleMapDirty, pref_, data); \ 1.5652 + } 1.5653 +#define CSS_PROP(prop_, id_, method_, flags_, pref_, parsevariant_, \ 1.5654 + kwtable_, stylestruct_, stylestructoffset_, animtype_) \ 1.5655 + UNREGISTER_CALLBACK(pref_) 1.5656 +#include "nsCSSPropList.h" 1.5657 +#undef CSS_PROP 1.5658 +#undef UNREGISTER_CALLBACK 1.5659 +}