Line data Source code
1 : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 : /* This Source Code Form is subject to the terms of the Mozilla Public
4 : * License, v. 2.0. If a copy of the MPL was not distributed with this
5 : * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 :
7 : #include "mozilla/ServoBindings.h"
8 :
9 : #include "ChildIterator.h"
10 : #include "ErrorReporter.h"
11 : #include "GeckoProfiler.h"
12 : #include "gfxFontFamilyList.h"
13 : #include "gfxFontFeatures.h"
14 : #include "nsAnimationManager.h"
15 : #include "nsAttrValueInlines.h"
16 : #include "nsCSSFrameConstructor.h"
17 : #include "nsCSSProps.h"
18 : #include "nsCSSPseudoElements.h"
19 : #include "nsContentUtils.h"
20 : #include "nsDOMTokenList.h"
21 : #include "nsDeviceContext.h"
22 : #include "nsIContentInlines.h"
23 : #include "nsICrashReporter.h"
24 : #include "nsIDocumentInlines.h"
25 : #include "nsILoadContext.h"
26 : #include "nsIFrame.h"
27 : #include "nsIMemoryReporter.h"
28 : #include "nsIMozBrowserFrame.h"
29 : #include "nsINode.h"
30 : #include "nsIPresShell.h"
31 : #include "nsIPresShellInlines.h"
32 : #include "nsIPrincipal.h"
33 : #include "nsIURI.h"
34 : #include "nsFontMetrics.h"
35 : #include "nsHTMLStyleSheet.h"
36 : #include "nsMappedAttributes.h"
37 : #include "nsMediaFeatures.h"
38 : #include "nsNameSpaceManager.h"
39 : #include "nsNetUtil.h"
40 : #include "nsProxyRelease.h"
41 : #include "nsString.h"
42 : #include "nsStyleStruct.h"
43 : #include "nsStyleUtil.h"
44 : #include "nsSVGElement.h"
45 : #include "nsTArray.h"
46 : #include "nsTransitionManager.h"
47 : #include "nsWindowSizes.h"
48 :
49 : #include "mozilla/CORSMode.h"
50 : #include "mozilla/DeclarationBlock.h"
51 : #include "mozilla/EffectCompositor.h"
52 : #include "mozilla/EffectSet.h"
53 : #include "mozilla/EventStates.h"
54 : #include "mozilla/FontPropertyTypes.h"
55 : #include "mozilla/Keyframe.h"
56 : #include "mozilla/Mutex.h"
57 : #include "mozilla/Preferences.h"
58 : #include "mozilla/ServoElementSnapshot.h"
59 : #include "mozilla/RestyleManager.h"
60 : #include "mozilla/SizeOfState.h"
61 : #include "mozilla/StyleAnimationValue.h"
62 : #include "mozilla/SystemGroup.h"
63 : #include "mozilla/ServoTraversalStatistics.h"
64 : #include "mozilla/Telemetry.h"
65 : #include "mozilla/RWLock.h"
66 : #include "mozilla/dom/Element.h"
67 : #include "mozilla/dom/ElementInlines.h"
68 : #include "mozilla/dom/HTMLTableCellElement.h"
69 : #include "mozilla/dom/HTMLBodyElement.h"
70 : #include "mozilla/dom/HTMLSlotElement.h"
71 : #include "mozilla/dom/MediaList.h"
72 : #include "mozilla/LookAndFeel.h"
73 : #include "mozilla/URLExtraData.h"
74 : #include "mozilla/dom/CSSMozDocumentRule.h"
75 :
76 : #if defined(MOZ_MEMORY)
77 : # include "mozmemory.h"
78 : #endif
79 :
80 : using namespace mozilla;
81 : using namespace mozilla::css;
82 : using namespace mozilla::dom;
83 :
84 : #define SERVO_ARC_TYPE(name_, type_) \
85 : already_AddRefed<type_> \
86 : type_##Strong::Consume() { \
87 : RefPtr<type_> result; \
88 : result.swap(mPtr); \
89 : return result.forget(); \
90 : }
91 : #include "mozilla/ServoArcTypeList.h"
92 5420 : SERVO_ARC_TYPE(ComputedStyle, ComputedStyle)
93 : #undef SERVO_ARC_TYPE
94 :
95 : // Definitions of the global traversal stats.
96 : bool ServoTraversalStatistics::sActive = false;
97 : ServoTraversalStatistics ServoTraversalStatistics::sSingleton;
98 :
99 : static RWLock* sServoFFILock = nullptr;
100 :
101 : static
102 : const nsFont*
103 163 : ThreadSafeGetDefaultFontHelper(const nsPresContext* aPresContext,
104 : nsAtom* aLanguage, uint8_t aGenericId)
105 : {
106 163 : bool needsCache = false;
107 : const nsFont* retval;
108 :
109 : {
110 0 : AutoReadLock guard(*sServoFFILock);
111 163 : retval = aPresContext->GetDefaultFont(aGenericId, aLanguage, &needsCache);
112 : }
113 163 : if (!needsCache) {
114 : return retval;
115 : }
116 : {
117 0 : AutoWriteLock guard(*sServoFFILock);
118 0 : retval = aPresContext->GetDefaultFont(aGenericId, aLanguage, nullptr);
119 : }
120 0 : return retval;
121 : }
122 :
123 : void
124 110 : AssertIsMainThreadOrServoLangFontPrefsCacheLocked()
125 : {
126 0 : MOZ_ASSERT(NS_IsMainThread() || sServoFFILock->LockedForWritingByCurrentThread());
127 110 : }
128 :
129 :
130 : /*
131 : * Does this child count as significant for selector matching?
132 : *
133 : * See nsStyleUtil::IsSignificantChild for details.
134 : */
135 : bool
136 12 : Gecko_IsSignificantChild(RawGeckoNodeBorrowed aNode,
137 : bool aWhitespaceIsSignificant)
138 : {
139 0 : return nsStyleUtil::ThreadSafeIsSignificantChild(aNode->AsContent(),
140 12 : aWhitespaceIsSignificant);
141 : }
142 :
143 : RawGeckoNodeBorrowedOrNull
144 0 : Gecko_GetLastChild(RawGeckoNodeBorrowed aNode)
145 : {
146 0 : return aNode->GetLastChild();
147 : }
148 :
149 : RawGeckoNodeBorrowedOrNull
150 12461 : Gecko_GetFlattenedTreeParentNode(RawGeckoNodeBorrowed aNode)
151 : {
152 12463 : return aNode->GetFlattenedTreeParentNodeForStyle();
153 : }
154 :
155 : RawGeckoElementBorrowedOrNull
156 48 : Gecko_GetBeforeOrAfterPseudo(RawGeckoElementBorrowed aElement, bool aIsBefore)
157 : {
158 0 : MOZ_ASSERT(aElement);
159 48 : MOZ_ASSERT(aElement->HasProperties());
160 :
161 : return aIsBefore
162 : ? nsLayoutUtils::GetBeforePseudo(aElement)
163 48 : : nsLayoutUtils::GetAfterPseudo(aElement);
164 : }
165 :
166 : nsTArray<nsIContent*>*
167 146 : Gecko_GetAnonymousContentForElement(RawGeckoElementBorrowed aElement)
168 : {
169 0 : nsIAnonymousContentCreator* ac = do_QueryFrame(aElement->GetPrimaryFrame());
170 146 : if (!ac) {
171 : return nullptr;
172 : }
173 :
174 0 : auto* array = new nsTArray<nsIContent*>();
175 0 : nsContentUtils::AppendNativeAnonymousChildren(aElement, *array, 0);
176 8 : return array;
177 : }
178 :
179 : void
180 8 : Gecko_DestroyAnonymousContentList(nsTArray<nsIContent*>* aAnonContent)
181 : {
182 0 : MOZ_ASSERT(aAnonContent);
183 0 : delete aAnonContent;
184 8 : }
185 :
186 : const nsTArray<RefPtr<nsINode>>*
187 0 : Gecko_GetAssignedNodes(RawGeckoElementBorrowed aElement)
188 : {
189 0 : MOZ_ASSERT(HTMLSlotElement::FromNode(aElement));
190 0 : return &static_cast<const HTMLSlotElement*>(aElement)->AssignedNodes();
191 : }
192 :
193 : void
194 0 : Gecko_ComputedStyle_Init(
195 : mozilla::ComputedStyle* aStyle,
196 : const mozilla::ComputedStyle* aParentContext,
197 : RawGeckoPresContextBorrowed aPresContext,
198 : const ServoComputedData* aValues,
199 : mozilla::CSSPseudoElementType aPseudoType,
200 : nsAtom* aPseudoTag)
201 : {
202 1156 : auto* presContext = const_cast<nsPresContext*>(aPresContext);
203 : new (KnownNotNull, aStyle) mozilla::ComputedStyle(
204 : presContext, aPseudoTag, aPseudoType,
205 1156 : ServoComputedDataForgotten(aValues));
206 0 : }
207 :
208 1157 : ServoComputedData::ServoComputedData(
209 0 : const ServoComputedDataForgotten aValue)
210 : {
211 1157 : PodAssign(this, aValue.mPtr);
212 1157 : }
213 :
214 884 : MOZ_DEFINE_MALLOC_ENCLOSING_SIZE_OF(ServoStyleStructsMallocEnclosingSizeOf)
215 :
216 : void
217 104 : ServoComputedData::AddSizeOfExcludingThis(nsWindowSizes& aSizes) const
218 : {
219 : // Note: GetStyleFoo() returns a pointer to an nsStyleFoo that sits within a
220 : // servo_arc::Arc, i.e. it is preceded by a word-sized refcount. So we need
221 : // to measure it with a function that can handle an interior pointer. We use
222 : // ServoStyleStructsEnclosingMallocSizeOf to clearly identify in DMD's
223 : // output the memory measured here.
224 : #define STYLE_STRUCT(name_) \
225 : static_assert(alignof(nsStyle##name_) <= sizeof(size_t), \
226 : "alignment will break AddSizeOfExcludingThis()"); \
227 : const void* p##name_ = GetStyle##name_(); \
228 : if (!aSizes.mState.HaveSeenPtr(p##name_)) { \
229 : aSizes.mStyleSizes.NS_STYLE_SIZES_FIELD(name_) += \
230 : ServoStyleStructsMallocEnclosingSizeOf(p##name_); \
231 : }
232 : #include "nsStyleStructList.h"
233 : #undef STYLE_STRUCT
234 :
235 104 : if (visited_style.mPtr && !aSizes.mState.HaveSeenPtr(visited_style.mPtr)) {
236 0 : visited_style.mPtr->AddSizeOfIncludingThis(
237 0 : aSizes, &aSizes.mLayoutComputedValuesVisited);
238 : }
239 :
240 : // Measurement of the following members may be added later if DMD finds it is
241 : // worthwhile:
242 : // - custom_properties
243 : // - writing_mode
244 : // - rules
245 : // - font_computation_data
246 104 : }
247 :
248 : void
249 574 : Gecko_ComputedStyle_Destroy(mozilla::ComputedStyle* aStyle)
250 : {
251 0 : aStyle->~ComputedStyle();
252 0 : }
253 :
254 : void
255 33365 : Gecko_ConstructStyleChildrenIterator(
256 : RawGeckoElementBorrowed aElement,
257 : RawGeckoStyleChildrenIteratorBorrowedMut aIterator)
258 : {
259 33365 : MOZ_ASSERT(aElement);
260 0 : MOZ_ASSERT(aIterator);
261 33365 : new (aIterator) StyleChildrenIterator(aElement);
262 0 : }
263 :
264 : void
265 33365 : Gecko_DestroyStyleChildrenIterator(
266 : RawGeckoStyleChildrenIteratorBorrowedMut aIterator)
267 : {
268 0 : MOZ_ASSERT(aIterator);
269 :
270 33365 : aIterator->~StyleChildrenIterator();
271 33365 : }
272 :
273 : RawGeckoNodeBorrowed
274 84422 : Gecko_GetNextStyleChild(RawGeckoStyleChildrenIteratorBorrowedMut aIterator)
275 : {
276 0 : MOZ_ASSERT(aIterator);
277 84422 : return aIterator->GetNextChild();
278 : }
279 :
280 : bool
281 543 : Gecko_IsPrivateBrowsingEnabled(const nsIDocument* aDoc)
282 : {
283 0 : MOZ_ASSERT(aDoc);
284 543 : MOZ_ASSERT(NS_IsMainThread());
285 :
286 543 : nsILoadContext* loadContext = aDoc->GetLoadContext();
287 543 : return loadContext && loadContext->UsePrivateBrowsing();
288 : }
289 :
290 : EventStates::ServoType
291 0 : Gecko_ElementState(RawGeckoElementBorrowed aElement)
292 : {
293 0 : return aElement->StyleState().ServoValue();
294 : }
295 :
296 : bool
297 3076 : Gecko_IsRootElement(RawGeckoElementBorrowed aElement)
298 : {
299 0 : return aElement->OwnerDoc()->GetRootElement() == aElement;
300 : }
301 :
302 : // Dirtiness tracking.
303 : void
304 0 : Gecko_SetNodeFlags(RawGeckoNodeBorrowed aNode, uint32_t aFlags)
305 : {
306 235 : const_cast<nsINode*>(aNode)->SetFlags(aFlags);
307 235 : }
308 :
309 : void
310 0 : Gecko_UnsetNodeFlags(RawGeckoNodeBorrowed aNode, uint32_t aFlags)
311 : {
312 0 : const_cast<nsINode*>(aNode)->UnsetFlags(aFlags);
313 349 : }
314 :
315 : void
316 1 : Gecko_NoteDirtyElement(RawGeckoElementBorrowed aElement)
317 : {
318 0 : MOZ_ASSERT(NS_IsMainThread());
319 0 : const_cast<Element*>(aElement)->NoteDirtyForServo();
320 1 : }
321 :
322 : void
323 2 : Gecko_NoteDirtySubtreeForInvalidation(RawGeckoElementBorrowed aElement)
324 : {
325 0 : MOZ_ASSERT(NS_IsMainThread());
326 0 : const_cast<Element*>(aElement)->NoteDirtySubtreeForServo();
327 2 : }
328 :
329 : void
330 10 : Gecko_NoteAnimationOnlyDirtyElement(RawGeckoElementBorrowed aElement)
331 : {
332 0 : MOZ_ASSERT(NS_IsMainThread());
333 0 : const_cast<Element*>(aElement)->NoteAnimationOnlyDirtyForServo();
334 10 : }
335 :
336 5 : bool Gecko_AnimationNameMayBeReferencedFromStyle(
337 : RawGeckoPresContextBorrowed aPresContext,
338 : nsAtom* aName)
339 : {
340 5 : MOZ_ASSERT(aPresContext);
341 15 : return aPresContext->AnimationManager()->AnimationMayBeReferenced(aName);
342 : }
343 :
344 : CSSPseudoElementType
345 949 : Gecko_GetImplementedPseudo(RawGeckoElementBorrowed aElement)
346 : {
347 949 : return aElement->GetPseudoElementType();
348 : }
349 :
350 : uint32_t
351 45 : Gecko_CalcStyleDifference(ComputedStyleBorrowed aOldStyle,
352 : ComputedStyleBorrowed aNewStyle,
353 : bool* aAnyStyleStructChanged,
354 : bool* aOnlyResetStructsChanged)
355 : {
356 0 : MOZ_ASSERT(aOldStyle);
357 45 : MOZ_ASSERT(aNewStyle);
358 :
359 : uint32_t equalStructs;
360 : nsChangeHint result = const_cast<ComputedStyle*>(aOldStyle)->
361 45 : CalcStyleDifference(const_cast<ComputedStyle*>(aNewStyle), &equalStructs);
362 :
363 45 : *aAnyStyleStructChanged =
364 45 : equalStructs != StyleStructConstants::kAllStructsMask;
365 :
366 0 : const auto kInheritedStructsMask = StyleStructConstants::kInheritedStructsMask;
367 45 : *aOnlyResetStructsChanged =
368 45 : (equalStructs & kInheritedStructsMask) == kInheritedStructsMask;
369 :
370 0 : return result;
371 : }
372 :
373 : const ServoElementSnapshot*
374 78 : Gecko_GetElementSnapshot(const ServoElementSnapshotTable* aTable,
375 : const Element* aElement)
376 : {
377 78 : MOZ_ASSERT(aTable);
378 1 : MOZ_ASSERT(aElement);
379 :
380 78 : return aTable->Get(const_cast<Element*>(aElement));
381 : }
382 :
383 : bool
384 0 : Gecko_HaveSeenPtr(SeenPtrs* aTable, const void* aPtr)
385 : {
386 0 : MOZ_ASSERT(NS_IsMainThread());
387 0 : MOZ_ASSERT(aTable);
388 : // Empty Rust allocations are indicated by small values up to the alignment
389 : // of the relevant type. We shouldn't see anything like that here.
390 0 : MOZ_ASSERT(uintptr_t(aPtr) > 16);
391 :
392 0 : return aTable->HaveSeenPtr(aPtr);
393 : }
394 :
395 : RawServoDeclarationBlockStrongBorrowedOrNull
396 31 : Gecko_GetStyleAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
397 : {
398 0 : DeclarationBlock* decl = aElement->GetInlineStyleDeclaration();
399 31 : if (!decl) {
400 : return nullptr;
401 : }
402 8 : return decl->RefRawStrong();
403 : }
404 :
405 : void
406 31 : Gecko_UnsetDirtyStyleAttr(RawGeckoElementBorrowed aElement)
407 : {
408 31 : DeclarationBlock* decl = aElement->GetInlineStyleDeclaration();
409 31 : if (!decl) {
410 : return;
411 : }
412 8 : decl->UnsetDirty();
413 : }
414 :
415 : static const RawServoDeclarationBlockStrong*
416 : AsRefRawStrong(const RefPtr<RawServoDeclarationBlock>& aDecl)
417 : {
418 : static_assert(sizeof(RefPtr<RawServoDeclarationBlock>) ==
419 : sizeof(RawServoDeclarationBlockStrong),
420 : "RefPtr should just be a pointer");
421 : return reinterpret_cast<const RawServoDeclarationBlockStrong*>(&aDecl);
422 : }
423 :
424 : RawServoDeclarationBlockStrongBorrowedOrNull
425 1030 : Gecko_GetHTMLPresentationAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
426 : {
427 1030 : const nsMappedAttributes* attrs = aElement->GetMappedAttributes();
428 1031 : if (!attrs) {
429 1005 : auto* svg = nsSVGElement::FromNodeOrNull(aElement);
430 0 : if (svg) {
431 41 : if (auto decl = svg->GetContentDeclarationBlock()) {
432 38 : return decl->RefRawStrong();
433 : }
434 : }
435 : return nullptr;
436 : }
437 :
438 26 : return AsRefRawStrong(attrs->GetServoStyle());
439 : }
440 :
441 : RawServoDeclarationBlockStrongBorrowedOrNull
442 1030 : Gecko_GetExtraContentStyleDeclarations(RawGeckoElementBorrowed aElement)
443 : {
444 1030 : if (!aElement->IsAnyOfHTMLElements(nsGkAtoms::td, nsGkAtoms::th)) {
445 : return nullptr;
446 : }
447 0 : const HTMLTableCellElement* cell = static_cast<const HTMLTableCellElement*>(aElement);
448 0 : if (nsMappedAttributes* attrs = cell->GetMappedAttributesInheritedFromTable()) {
449 0 : return AsRefRawStrong(attrs->GetServoStyle());
450 : }
451 : return nullptr;
452 : }
453 :
454 : RawServoDeclarationBlockStrongBorrowedOrNull
455 0 : Gecko_GetUnvisitedLinkAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
456 : {
457 0 : nsHTMLStyleSheet* sheet = aElement->OwnerDoc()->GetAttributeStyleSheet();
458 0 : if (!sheet) {
459 : return nullptr;
460 : }
461 :
462 0 : return AsRefRawStrong(sheet->GetServoUnvisitedLinkDecl());
463 : }
464 :
465 0 : StyleSheet* Gecko_StyleSheet_Clone(
466 : const StyleSheet* aSheet,
467 : const StyleSheet* aNewParentSheet)
468 : {
469 0 : MOZ_ASSERT(aSheet);
470 0 : MOZ_ASSERT(aSheet->GetParentSheet(), "Should only be used for @import");
471 0 : MOZ_ASSERT(aNewParentSheet, "Wat");
472 :
473 : RefPtr<StyleSheet> newSheet =
474 0 : aSheet->Clone(nullptr, nullptr, nullptr, nullptr);
475 :
476 : // NOTE(emilio): This code runs in the StylesheetInner constructor, which
477 : // means that the inner pointer of `aNewParentSheet` still points to the old
478 : // one.
479 : //
480 : // So we _don't_ update neither the parent pointer of the stylesheet, nor the
481 : // child list (yet). This is fixed up in that same constructor.
482 0 : return static_cast<StyleSheet*>(newSheet.forget().take());
483 : }
484 :
485 : void
486 201 : Gecko_StyleSheet_AddRef(const StyleSheet* aSheet)
487 : {
488 0 : MOZ_ASSERT(NS_IsMainThread());
489 0 : const_cast<StyleSheet*>(aSheet)->AddRef();
490 201 : }
491 :
492 : void
493 104 : Gecko_StyleSheet_Release(const StyleSheet* aSheet)
494 : {
495 0 : MOZ_ASSERT(NS_IsMainThread());
496 104 : const_cast<StyleSheet*>(aSheet)->Release();
497 104 : }
498 :
499 : RawServoDeclarationBlockStrongBorrowedOrNull
500 0 : Gecko_GetVisitedLinkAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
501 : {
502 0 : nsHTMLStyleSheet* sheet = aElement->OwnerDoc()->GetAttributeStyleSheet();
503 0 : if (!sheet) {
504 : return nullptr;
505 : }
506 :
507 0 : return AsRefRawStrong(sheet->GetServoVisitedLinkDecl());
508 : }
509 :
510 : RawServoDeclarationBlockStrongBorrowedOrNull
511 0 : Gecko_GetActiveLinkAttrDeclarationBlock(RawGeckoElementBorrowed aElement)
512 : {
513 0 : nsHTMLStyleSheet* sheet = aElement->OwnerDoc()->GetAttributeStyleSheet();
514 0 : if (!sheet) {
515 : return nullptr;
516 : }
517 :
518 0 : return AsRefRawStrong(sheet->GetServoActiveLinkDecl());
519 : }
520 :
521 : static CSSPseudoElementType
522 0 : GetPseudoTypeFromElementForAnimation(const Element*& aElementOrPseudo) {
523 14 : if (aElementOrPseudo->IsGeneratedContentContainerForBefore()) {
524 0 : aElementOrPseudo = aElementOrPseudo->GetParent()->AsElement();
525 0 : return CSSPseudoElementType::before;
526 : }
527 :
528 14 : if (aElementOrPseudo->IsGeneratedContentContainerForAfter()) {
529 0 : aElementOrPseudo = aElementOrPseudo->GetParent()->AsElement();
530 0 : return CSSPseudoElementType::after;
531 : }
532 :
533 : return CSSPseudoElementType::NotPseudo;
534 : }
535 :
536 : bool
537 6 : Gecko_GetAnimationRule(RawGeckoElementBorrowed aElement,
538 : EffectCompositor::CascadeLevel aCascadeLevel,
539 : RawServoAnimationValueMapBorrowedMut aAnimationValues)
540 : {
541 6 : MOZ_ASSERT(aElement);
542 :
543 6 : nsIDocument* doc = aElement->GetComposedDoc();
544 6 : if (!doc) {
545 : return false;
546 : }
547 6 : nsPresContext* presContext = doc->GetPresContext();
548 12 : if (!presContext || !presContext->IsDynamic()) {
549 : // For print or print preview, ignore animations.
550 : return false;
551 : }
552 :
553 : CSSPseudoElementType pseudoType =
554 6 : GetPseudoTypeFromElementForAnimation(aElement);
555 :
556 : return presContext->EffectCompositor()
557 12 : ->GetServoAnimationRule(aElement,
558 : pseudoType,
559 : aCascadeLevel,
560 6 : aAnimationValues);
561 : }
562 :
563 : bool
564 39 : Gecko_StyleAnimationsEquals(RawGeckoStyleAnimationListBorrowed aA,
565 : RawGeckoStyleAnimationListBorrowed aB)
566 : {
567 0 : return *aA == *aB;
568 : }
569 :
570 : void
571 0 : Gecko_CopyAnimationNames(RawGeckoStyleAnimationListBorrowedMut aDest,
572 : RawGeckoStyleAnimationListBorrowed aSrc)
573 : {
574 0 : size_t srcLength = aSrc->Length();
575 0 : aDest->EnsureLengthAtLeast(srcLength);
576 :
577 0 : for (size_t index = 0; index < srcLength; index++) {
578 0 : (*aDest)[index].SetName((*aSrc)[index].GetName());
579 : }
580 0 : }
581 :
582 : void
583 1 : Gecko_SetAnimationName(StyleAnimation* aStyleAnimation,
584 : nsAtom* aAtom)
585 : {
586 1 : MOZ_ASSERT(aStyleAnimation);
587 :
588 2 : aStyleAnimation->SetName(already_AddRefed<nsAtom>(aAtom));
589 0 : }
590 :
591 : void
592 0 : Gecko_UpdateAnimations(RawGeckoElementBorrowed aElement,
593 : ComputedStyleBorrowedOrNull aOldComputedData,
594 : ComputedStyleBorrowedOrNull aComputedData,
595 : UpdateAnimationsTasks aTasks)
596 : {
597 0 : MOZ_ASSERT(NS_IsMainThread());
598 3 : MOZ_ASSERT(aElement);
599 :
600 3 : if (!aElement->IsInComposedDoc()) {
601 0 : return;
602 : }
603 :
604 0 : nsPresContext* presContext = nsContentUtils::GetContextForContent(aElement);
605 6 : if (!presContext || !presContext->IsDynamic()) {
606 : return;
607 : }
608 :
609 0 : nsAutoAnimationMutationBatch mb(aElement->OwnerDoc());
610 :
611 : CSSPseudoElementType pseudoType =
612 3 : GetPseudoTypeFromElementForAnimation(aElement);
613 :
614 3 : if (aTasks & UpdateAnimationsTasks::CSSAnimations) {
615 : presContext->AnimationManager()->
616 2 : UpdateAnimations(const_cast<dom::Element*>(aElement), pseudoType,
617 1 : aComputedData);
618 : }
619 :
620 : // aComputedData might be nullptr if the target element is now in a
621 : // display:none subtree. We still call Gecko_UpdateAnimations in this case
622 : // because we need to stop CSS animations in the display:none subtree.
623 : // However, we don't need to update transitions since they are stopped by
624 : // RestyleManager::AnimationsWithDestroyedFrame so we just return early
625 : // here.
626 3 : if (!aComputedData) {
627 0 : return;
628 : }
629 :
630 0 : if (aTasks & UpdateAnimationsTasks::CSSTransitions) {
631 0 : MOZ_ASSERT(aOldComputedData);
632 : presContext->TransitionManager()->
633 4 : UpdateTransitions(const_cast<dom::Element*>(aElement), pseudoType,
634 : *aOldComputedData,
635 0 : *aComputedData);
636 : }
637 :
638 3 : if (aTasks & UpdateAnimationsTasks::EffectProperties) {
639 0 : presContext->EffectCompositor()->UpdateEffectProperties(
640 0 : aComputedData, const_cast<dom::Element*>(aElement), pseudoType);
641 : }
642 :
643 3 : if (aTasks & UpdateAnimationsTasks::CascadeResults) {
644 0 : EffectSet* effectSet = EffectSet::GetEffectSet(aElement, pseudoType);
645 : // CSS animations/transitions might have been destroyed as part of the above
646 : // steps so before updating cascade results, we check if there are still any
647 : // animations to update.
648 0 : if (effectSet) {
649 : // We call UpdateCascadeResults directly (intead of
650 : // MaybeUpdateCascadeResults) since we know for sure that the cascade has
651 : // changed, but we were unable to call MarkCascadeUpdated when we noticed
652 : // it since we avoid mutating state as part of the Servo parallel
653 : // traversal.
654 0 : presContext->EffectCompositor()
655 : ->UpdateCascadeResults(*effectSet,
656 : const_cast<Element*>(aElement),
657 0 : pseudoType);
658 : }
659 : }
660 :
661 3 : if (aTasks & UpdateAnimationsTasks::DisplayChangedFromNone) {
662 : presContext->EffectCompositor()
663 0 : ->RequestRestyle(const_cast<Element*>(aElement),
664 : pseudoType,
665 : EffectCompositor::RestyleType::Standard,
666 0 : EffectCompositor::CascadeLevel::Animations);
667 : }
668 : }
669 :
670 : bool
671 0 : Gecko_ElementHasAnimations(RawGeckoElementBorrowed aElement)
672 : {
673 : CSSPseudoElementType pseudoType =
674 0 : GetPseudoTypeFromElementForAnimation(aElement);
675 :
676 0 : return !!EffectSet::GetEffectSet(aElement, pseudoType);
677 : }
678 :
679 : bool
680 0 : Gecko_ElementHasCSSAnimations(RawGeckoElementBorrowed aElement)
681 : {
682 : CSSPseudoElementType pseudoType =
683 0 : GetPseudoTypeFromElementForAnimation(aElement);
684 : nsAnimationManager::CSSAnimationCollection* collection =
685 : nsAnimationManager::CSSAnimationCollection
686 0 : ::GetAnimationCollection(aElement, pseudoType);
687 :
688 0 : return collection && !collection->mAnimations.IsEmpty();
689 : }
690 :
691 : bool
692 0 : Gecko_ElementHasCSSTransitions(RawGeckoElementBorrowed aElement)
693 : {
694 : CSSPseudoElementType pseudoType =
695 0 : GetPseudoTypeFromElementForAnimation(aElement);
696 : nsTransitionManager::CSSTransitionCollection* collection =
697 : nsTransitionManager::CSSTransitionCollection
698 0 : ::GetAnimationCollection(aElement, pseudoType);
699 :
700 0 : return collection && !collection->mAnimations.IsEmpty();
701 : }
702 :
703 : size_t
704 0 : Gecko_ElementTransitions_Length(RawGeckoElementBorrowed aElement)
705 : {
706 : CSSPseudoElementType pseudoType =
707 5 : GetPseudoTypeFromElementForAnimation(aElement);
708 : nsTransitionManager::CSSTransitionCollection* collection =
709 : nsTransitionManager::CSSTransitionCollection
710 5 : ::GetAnimationCollection(aElement, pseudoType);
711 :
712 5 : return collection ? collection->mAnimations.Length() : 0;
713 : }
714 :
715 : static CSSTransition*
716 0 : GetCurrentTransitionAt(RawGeckoElementBorrowed aElement, size_t aIndex)
717 : {
718 : CSSPseudoElementType pseudoType =
719 0 : GetPseudoTypeFromElementForAnimation(aElement);
720 : nsTransitionManager::CSSTransitionCollection* collection =
721 : nsTransitionManager::CSSTransitionCollection
722 0 : ::GetAnimationCollection(aElement, pseudoType);
723 0 : if (!collection) {
724 : return nullptr;
725 : }
726 0 : nsTArray<RefPtr<CSSTransition>>& transitions = collection->mAnimations;
727 0 : return aIndex < transitions.Length()
728 0 : ? transitions[aIndex].get()
729 : : nullptr;
730 : }
731 :
732 : nsCSSPropertyID
733 0 : Gecko_ElementTransitions_PropertyAt(RawGeckoElementBorrowed aElement,
734 : size_t aIndex)
735 : {
736 0 : CSSTransition* transition = GetCurrentTransitionAt(aElement, aIndex);
737 0 : return transition ? transition->TransitionProperty()
738 0 : : nsCSSPropertyID::eCSSProperty_UNKNOWN;
739 : }
740 :
741 : RawServoAnimationValueBorrowedOrNull
742 0 : Gecko_ElementTransitions_EndValueAt(RawGeckoElementBorrowed aElement,
743 : size_t aIndex)
744 : {
745 : CSSTransition* transition = GetCurrentTransitionAt(aElement,
746 0 : aIndex);
747 0 : return transition ? transition->ToValue().mServo.get() : nullptr;
748 : }
749 :
750 : double
751 4 : Gecko_GetProgressFromComputedTiming(RawGeckoComputedTimingBorrowed aComputedTiming)
752 : {
753 0 : return aComputedTiming->mProgress.Value();
754 : }
755 :
756 : double
757 4 : Gecko_GetPositionInSegment(RawGeckoAnimationPropertySegmentBorrowed aSegment,
758 : double aProgress,
759 : ComputedTimingFunction::BeforeFlag aBeforeFlag)
760 : {
761 4 : MOZ_ASSERT(aSegment->mFromKey < aSegment->mToKey,
762 : "The segment from key should be less than to key");
763 :
764 0 : double positionInSegment = (aProgress - aSegment->mFromKey) /
765 : // To avoid floating precision inaccuracies, make
766 : // sure we calculate both the numerator and
767 : // denominator using double precision.
768 0 : (double(aSegment->mToKey) - aSegment->mFromKey);
769 :
770 4 : return ComputedTimingFunction::GetPortion(aSegment->mTimingFunction,
771 : positionInSegment,
772 0 : aBeforeFlag);
773 : }
774 :
775 : RawServoAnimationValueBorrowedOrNull
776 0 : Gecko_AnimationGetBaseStyle(void* aBaseStyles, nsCSSPropertyID aProperty)
777 : {
778 : auto base =
779 : static_cast<nsRefPtrHashtable<nsUint32HashKey, RawServoAnimationValue>*>
780 0 : (aBaseStyles);
781 0 : return base->GetWeak(aProperty);
782 : }
783 :
784 : void
785 280 : Gecko_FillAllImageLayers(nsStyleImageLayers* aLayers, uint32_t aMaxLen)
786 : {
787 280 : aLayers->FillAllLayers(aMaxLen);
788 0 : }
789 :
790 : bool
791 0 : Gecko_IsDocumentBody(RawGeckoElementBorrowed aElement)
792 : {
793 0 : nsIDocument* doc = aElement->GetUncomposedDoc();
794 0 : return doc && doc->GetBodyElement() == aElement;
795 : }
796 :
797 : nscolor
798 384 : Gecko_GetLookAndFeelSystemColor(int32_t aId,
799 : RawGeckoPresContextBorrowed aPresContext)
800 : {
801 768 : bool useStandinsForNativeColors = aPresContext && !aPresContext->IsChrome();
802 : nscolor result;
803 384 : LookAndFeel::ColorID colorId = static_cast<LookAndFeel::ColorID>(aId);
804 0 : AutoWriteLock guard(*sServoFFILock);
805 384 : LookAndFeel::GetColor(colorId, useStandinsForNativeColors, &result);
806 768 : return result;
807 : }
808 :
809 : bool
810 0 : Gecko_MatchLang(RawGeckoElementBorrowed aElement,
811 : nsAtom* aOverrideLang,
812 : bool aHasOverrideLang,
813 : const char16_t* aValue)
814 : {
815 0 : MOZ_ASSERT(!(aOverrideLang && !aHasOverrideLang),
816 : "aHasOverrideLang should only be set when aOverrideLang is null");
817 0 : MOZ_ASSERT(aValue, "null lang parameter");
818 0 : if (!aValue || !*aValue) {
819 : return false;
820 : }
821 :
822 : // We have to determine the language of the current element. Since
823 : // this is currently no property and since the language is inherited
824 : // from the parent we have to be prepared to look at all parent
825 : // nodes. The language itself is encoded in the LANG attribute.
826 0 : if (auto* language = aHasOverrideLang ? aOverrideLang : aElement->GetLang()) {
827 0 : return nsStyleUtil::DashMatchCompare(nsDependentAtomString(language),
828 0 : nsDependentString(aValue),
829 0 : nsASCIICaseInsensitiveStringComparator());
830 : }
831 :
832 : // Try to get the language from the HTTP header or if this
833 : // is missing as well from the preferences.
834 : // The content language can be a comma-separated list of
835 : // language codes.
836 0 : nsAutoString language;
837 0 : aElement->OwnerDoc()->GetContentLanguage(language);
838 :
839 0 : nsDependentString langString(aValue);
840 0 : language.StripWhitespace();
841 0 : for (auto const& lang : language.Split(char16_t(','))) {
842 0 : if (nsStyleUtil::DashMatchCompare(lang,
843 : langString,
844 0 : nsASCIICaseInsensitiveStringComparator())) {
845 0 : return true;
846 : }
847 : }
848 0 : return false;
849 : }
850 :
851 : nsAtom*
852 1030 : Gecko_GetXMLLangValue(RawGeckoElementBorrowed aElement)
853 : {
854 : const nsAttrValue* attr =
855 2062 : aElement->GetParsedAttr(nsGkAtoms::lang, kNameSpaceID_XML);
856 :
857 1032 : if (!attr) {
858 : return nullptr;
859 : }
860 :
861 0 : MOZ_ASSERT(attr->Type() == nsAttrValue::eAtom);
862 :
863 0 : RefPtr<nsAtom> atom = attr->GetAtomValue();
864 0 : return atom.forget().take();
865 : }
866 :
867 : nsIDocument::DocumentTheme
868 775 : Gecko_GetDocumentLWTheme(const nsIDocument* aDocument)
869 : {
870 0 : return aDocument->ThreadSafeGetDocumentLWTheme();
871 : }
872 :
873 : bool
874 0 : Gecko_IsTableBorderNonzero(RawGeckoElementBorrowed aElement)
875 : {
876 0 : if (!aElement->IsHTMLElement(nsGkAtoms::table)) {
877 : return false;
878 : }
879 0 : const nsAttrValue *val = aElement->GetParsedAttr(nsGkAtoms::border);
880 0 : return val && (val->Type() != nsAttrValue::eInteger ||
881 0 : val->GetIntegerValue() != 0);
882 : }
883 :
884 : bool
885 0 : Gecko_IsBrowserFrame(RawGeckoElementBorrowed aElement)
886 : {
887 : nsIMozBrowserFrame* browserFrame =
888 0 : const_cast<Element*>(aElement)->GetAsMozBrowserFrame();
889 0 : return browserFrame && browserFrame->GetReallyIsBrowser();
890 : }
891 :
892 : template <typename Implementor>
893 : static nsAtom*
894 0 : AtomAttrValue(Implementor* aElement, nsAtom* aName)
895 : {
896 10769 : const nsAttrValue* attr = aElement->GetParsedAttr(aName);
897 10773 : return attr ? attr->GetAtomValue() : nullptr;
898 : }
899 :
900 : template <typename Implementor>
901 : static nsAtom*
902 0 : LangValue(Implementor* aElement)
903 : {
904 : // TODO(emilio): Deduplicate a bit with nsIContent::GetLang().
905 : const nsAttrValue* attr =
906 0 : aElement->GetParsedAttr(nsGkAtoms::lang, kNameSpaceID_XML);
907 0 : if (!attr && aElement->SupportsLangAttr()) {
908 0 : attr = aElement->GetParsedAttr(nsGkAtoms::lang);
909 : }
910 :
911 0 : if (!attr) {
912 : return nullptr;
913 : }
914 :
915 0 : MOZ_ASSERT(attr->Type() == nsAttrValue::eAtom);
916 0 : RefPtr<nsAtom> atom = attr->GetAtomValue();
917 0 : return atom.forget().take();
918 : }
919 :
920 : template <typename Implementor, typename MatchFn>
921 : static bool
922 0 : DoMatch(Implementor* aElement, nsAtom* aNS, nsAtom* aName, MatchFn aMatch)
923 : {
924 30789 : if (MOZ_LIKELY(aNS)) {
925 30789 : int32_t ns = aNS == nsGkAtoms::_empty
926 30830 : ? kNameSpaceID_None
927 : : nsContentUtils::NameSpaceManager()->GetNameSpaceID(
928 0 : aNS, aElement->IsInChromeDocument());
929 :
930 0 : MOZ_ASSERT(ns == nsContentUtils::NameSpaceManager()->GetNameSpaceID(
931 : aNS, aElement->IsInChromeDocument()));
932 0 : NS_ENSURE_TRUE(ns != kNameSpaceID_Unknown, false);
933 30793 : const nsAttrValue* value = aElement->GetParsedAttr(aName, ns);
934 0 : return value && aMatch(value);
935 : }
936 :
937 : // No namespace means any namespace - we have to check them all. :-(
938 : BorrowedAttrInfo attrInfo;
939 0 : for (uint32_t i = 0; (attrInfo = aElement->GetAttrInfoAt(i)); ++i) {
940 0 : if (attrInfo.mName->LocalName() != aName) {
941 : continue;
942 : }
943 0 : if (aMatch(attrInfo.mValue)) {
944 : return true;
945 : }
946 : }
947 : return false;
948 : }
949 :
950 : template <typename Implementor>
951 : static bool
952 : HasAttr(Implementor* aElement, nsAtom* aNS, nsAtom* aName)
953 : {
954 : auto match = [](const nsAttrValue* aValue) { return true; };
955 5655 : return DoMatch(aElement, aNS, aName, match);
956 : }
957 :
958 : template <typename Implementor>
959 : static bool
960 24517 : AttrEquals(Implementor* aElement, nsAtom* aNS, nsAtom* aName, nsAtom* aStr,
961 : bool aIgnoreCase)
962 : {
963 3732 : auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
964 1866 : return aValue->Equals(aStr, aIgnoreCase ? eIgnoreCase : eCaseMatters);
965 26383 : };
966 0 : return DoMatch(aElement, aNS, aName, match);
967 : }
968 :
969 : #define WITH_COMPARATOR(ignore_case_, c_, expr_) \
970 : if (ignore_case_) { \
971 : const nsCaseInsensitiveStringComparator c_ \
972 : = nsCaseInsensitiveStringComparator(); \
973 : return expr_; \
974 : } else { \
975 : const nsDefaultStringComparator c_; \
976 : return expr_; \
977 : }
978 :
979 :
980 : template <typename Implementor>
981 : static bool
982 0 : AttrDashEquals(Implementor* aElement, nsAtom* aNS, nsAtom* aName,
983 : nsAtom* aStr, bool aIgnoreCase)
984 : {
985 0 : auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
986 0 : nsAutoString str;
987 0 : aValue->ToString(str);
988 0 : WITH_COMPARATOR(aIgnoreCase, c,
989 : nsStyleUtil::DashMatchCompare(str, nsDependentAtomString(aStr), c))
990 0 : };
991 0 : return DoMatch(aElement, aNS, aName, match);
992 : }
993 :
994 : template <typename Implementor>
995 : static bool
996 0 : AttrIncludes(Implementor* aElement, nsAtom* aNS, nsAtom* aName,
997 : nsAtom* aStr, bool aIgnoreCase)
998 : {
999 237 : auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
1000 158 : nsAutoString str;
1001 79 : aValue->ToString(str);
1002 0 : WITH_COMPARATOR(aIgnoreCase, c,
1003 : nsStyleUtil::ValueIncludes(str, nsDependentAtomString(aStr), c))
1004 602 : };
1005 0 : return DoMatch(aElement, aNS, aName, match);
1006 : }
1007 :
1008 : template <typename Implementor>
1009 : static bool
1010 0 : AttrHasSubstring(Implementor* aElement, nsAtom* aNS, nsAtom* aName,
1011 : nsAtom* aStr, bool aIgnoreCase)
1012 : {
1013 0 : auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
1014 0 : nsAutoString str;
1015 0 : aValue->ToString(str);
1016 0 : WITH_COMPARATOR(aIgnoreCase, c,
1017 : FindInReadable(nsDependentAtomString(aStr), str, c))
1018 0 : };
1019 0 : return DoMatch(aElement, aNS, aName, match);
1020 : }
1021 :
1022 : template <typename Implementor>
1023 : static bool
1024 0 : AttrHasPrefix(Implementor* aElement, nsAtom* aNS, nsAtom* aName,
1025 : nsAtom* aStr, bool aIgnoreCase)
1026 : {
1027 36 : auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
1028 24 : nsAutoString str;
1029 12 : aValue->ToString(str);
1030 0 : WITH_COMPARATOR(aIgnoreCase, c,
1031 : StringBeginsWith(str, nsDependentAtomString(aStr), c))
1032 17 : };
1033 0 : return DoMatch(aElement, aNS, aName, match);
1034 : }
1035 :
1036 : template <typename Implementor>
1037 : static bool
1038 0 : AttrHasSuffix(Implementor* aElement, nsAtom* aNS, nsAtom* aName,
1039 : nsAtom* aStr, bool aIgnoreCase)
1040 : {
1041 0 : auto match = [aStr, aIgnoreCase](const nsAttrValue* aValue) {
1042 0 : nsAutoString str;
1043 0 : aValue->ToString(str);
1044 0 : WITH_COMPARATOR(aIgnoreCase, c,
1045 : StringEndsWith(str, nsDependentAtomString(aStr), c))
1046 1 : };
1047 0 : return DoMatch(aElement, aNS, aName, match);
1048 : }
1049 :
1050 : /**
1051 : * Returns whether an element contains a class in its class list or not.
1052 : */
1053 : template <typename Implementor>
1054 : static bool
1055 4745 : HasClass(Implementor* aElement, nsAtom* aClass, bool aIgnoreCase)
1056 : {
1057 4745 : const nsAttrValue* attr = aElement->DoGetClasses();
1058 4745 : if (!attr) {
1059 : return false;
1060 : }
1061 :
1062 4745 : return attr->Contains(aClass, aIgnoreCase ? eIgnoreCase : eCaseMatters);
1063 : }
1064 :
1065 : /**
1066 : * Gets the class or class list (if any) of the implementor. The calling
1067 : * convention here is rather hairy, and is optimized for getting Servo the
1068 : * information it needs for hot calls.
1069 : *
1070 : * The return value indicates the number of classes. If zero, neither outparam
1071 : * is valid. If one, the class_ outparam is filled with the atom of the class.
1072 : * If two or more, the classList outparam is set to point to an array of atoms
1073 : * representing the class list.
1074 : *
1075 : * The array is borrowed and the atoms are not addrefed. These values can be
1076 : * invalidated by any DOM mutation. Use them in a tight scope.
1077 : */
1078 : template <typename Implementor>
1079 : static uint32_t
1080 3022 : ClassOrClassList(Implementor* aElement, nsAtom** aClass, nsAtom*** aClassList)
1081 : {
1082 3022 : const nsAttrValue* attr = aElement->DoGetClasses();
1083 3022 : if (!attr) {
1084 : return 0;
1085 : }
1086 :
1087 : // For class values with only whitespace, Gecko just stores a string. For the
1088 : // purposes of the style system, there is no class in this case.
1089 0 : nsAttrValue::ValueType type = attr->Type();
1090 3022 : if (MOZ_UNLIKELY(type == nsAttrValue::eString)) {
1091 0 : MOZ_ASSERT(nsContentUtils::TrimWhitespace<nsContentUtils::IsHTMLWhitespace>(
1092 : attr->GetStringValue()).IsEmpty());
1093 : return 0;
1094 : }
1095 :
1096 : // Single tokens are generally stored as an atom. Check that case.
1097 0 : if (type == nsAttrValue::eAtom) {
1098 2369 : *aClass = attr->GetAtomValue();
1099 2369 : return 1;
1100 : }
1101 :
1102 : // At this point we should have an atom array. It is likely, but not
1103 : // guaranteed, that we have two or more elements in the array.
1104 0 : MOZ_ASSERT(type == nsAttrValue::eAtomArray);
1105 0 : nsTArray<RefPtr<nsAtom>>* atomArray = attr->GetAtomArrayValue();
1106 1306 : uint32_t length = atomArray->Length();
1107 :
1108 : // Special case: zero elements.
1109 653 : if (length == 0) {
1110 : return 0;
1111 : }
1112 :
1113 : // Special case: one element.
1114 653 : if (length == 1) {
1115 0 : *aClass = atomArray->ElementAt(0);
1116 0 : return 1;
1117 : }
1118 :
1119 : // General case: Two or more elements.
1120 : //
1121 : // Note: We could also expose this array as an array of nsCOMPtrs, since
1122 : // bindgen knows what those look like, and eliminate the reinterpret_cast.
1123 : // But it's not obvious that that would be preferable.
1124 : static_assert(sizeof(RefPtr<nsAtom>) == sizeof(nsAtom*), "Bad simplification");
1125 : static_assert(alignof(RefPtr<nsAtom>) == alignof(nsAtom*), "Bad simplification");
1126 :
1127 1306 : RefPtr<nsAtom>* elements = atomArray->Elements();
1128 653 : nsAtom** rawElements = reinterpret_cast<nsAtom**>(elements);
1129 653 : *aClassList = rawElements;
1130 1306 : return atomArray->Length();
1131 : }
1132 :
1133 : #define SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS(prefix_, implementor_) \
1134 : nsAtom* prefix_##AtomAttrValue(implementor_ aElement, nsAtom* aName) \
1135 : { \
1136 : return AtomAttrValue(aElement, aName); \
1137 : } \
1138 : nsAtom* prefix_##LangValue(implementor_ aElement) \
1139 : { \
1140 : return LangValue(aElement); \
1141 : } \
1142 : bool prefix_##HasAttr(implementor_ aElement, nsAtom* aNS, nsAtom* aName) \
1143 : { \
1144 : return HasAttr(aElement, aNS, aName); \
1145 : } \
1146 : bool prefix_##AttrEquals(implementor_ aElement, nsAtom* aNS, \
1147 : nsAtom* aName, nsAtom* aStr, bool aIgnoreCase) \
1148 : { \
1149 : return AttrEquals(aElement, aNS, aName, aStr, aIgnoreCase); \
1150 : } \
1151 : bool prefix_##AttrDashEquals(implementor_ aElement, nsAtom* aNS, \
1152 : nsAtom* aName, nsAtom* aStr, bool aIgnoreCase) \
1153 : { \
1154 : return AttrDashEquals(aElement, aNS, aName, aStr, aIgnoreCase); \
1155 : } \
1156 : bool prefix_##AttrIncludes(implementor_ aElement, nsAtom* aNS, \
1157 : nsAtom* aName, nsAtom* aStr, bool aIgnoreCase) \
1158 : { \
1159 : return AttrIncludes(aElement, aNS, aName, aStr, aIgnoreCase); \
1160 : } \
1161 : bool prefix_##AttrHasSubstring(implementor_ aElement, nsAtom* aNS, \
1162 : nsAtom* aName, nsAtom* aStr, bool aIgnoreCase) \
1163 : { \
1164 : return AttrHasSubstring(aElement, aNS, aName, aStr, aIgnoreCase); \
1165 : } \
1166 : bool prefix_##AttrHasPrefix(implementor_ aElement, nsAtom* aNS, \
1167 : nsAtom* aName, nsAtom* aStr, bool aIgnoreCase) \
1168 : { \
1169 : return AttrHasPrefix(aElement, aNS, aName, aStr, aIgnoreCase); \
1170 : } \
1171 : bool prefix_##AttrHasSuffix(implementor_ aElement, nsAtom* aNS, \
1172 : nsAtom* aName, nsAtom* aStr, bool aIgnoreCase) \
1173 : { \
1174 : return AttrHasSuffix(aElement, aNS, aName, aStr, aIgnoreCase); \
1175 : } \
1176 : uint32_t prefix_##ClassOrClassList(implementor_ aElement, nsAtom** aClass, \
1177 : nsAtom*** aClassList) \
1178 : { \
1179 : return ClassOrClassList(aElement, aClass, aClassList); \
1180 : } \
1181 : bool prefix_##HasClass(implementor_ aElement, nsAtom* aClass, bool aIgnoreCase)\
1182 : { \
1183 : return HasClass(aElement, aClass, aIgnoreCase); \
1184 : } \
1185 :
1186 :
1187 53574 : SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_, RawGeckoElementBorrowed)
1188 1409 : SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS(Gecko_Snapshot, const ServoElementSnapshot*)
1189 :
1190 : #undef SERVO_IMPL_ELEMENT_ATTR_MATCHING_FUNCTIONS
1191 :
1192 : nsAtom*
1193 0 : Gecko_Atomize(const char* aString, uint32_t aLength)
1194 : {
1195 52026 : return NS_Atomize(nsDependentCSubstring(aString, aLength)).take();
1196 : }
1197 :
1198 : nsAtom*
1199 0 : Gecko_Atomize16(const nsAString* aString)
1200 : {
1201 0 : return NS_Atomize(*aString).take();
1202 : }
1203 :
1204 : void
1205 0 : Gecko_AddRefAtom(nsAtom* aAtom)
1206 : {
1207 0 : NS_ADDREF(aAtom);
1208 41802 : }
1209 :
1210 : void
1211 0 : Gecko_ReleaseAtom(nsAtom* aAtom)
1212 : {
1213 0 : NS_RELEASE(aAtom);
1214 0 : }
1215 :
1216 : void
1217 0 : Gecko_nsTArray_FontFamilyName_AppendNamed(nsTArray<FontFamilyName>* aNames,
1218 : nsAtom* aName,
1219 : bool aQuoted)
1220 : {
1221 6 : FontFamilyName family;
1222 3 : aName->ToString(family.mName);
1223 0 : if (aQuoted) {
1224 0 : family.mType = eFamily_named_quoted;
1225 : }
1226 :
1227 0 : aNames->AppendElement(family);
1228 0 : }
1229 :
1230 : void
1231 10 : Gecko_nsTArray_FontFamilyName_AppendGeneric(nsTArray<FontFamilyName>* aNames,
1232 : FontFamilyType aType)
1233 : {
1234 0 : aNames->AppendElement(FontFamilyName(aType));
1235 10 : }
1236 :
1237 : SharedFontList*
1238 10 : Gecko_SharedFontList_Create()
1239 : {
1240 0 : RefPtr<SharedFontList> fontlist = new SharedFontList();
1241 0 : return fontlist.forget().take();
1242 : }
1243 :
1244 0 : MOZ_DEFINE_MALLOC_SIZE_OF(GeckoSharedFontListMallocSizeOf)
1245 :
1246 : size_t
1247 0 : Gecko_SharedFontList_SizeOfIncludingThisIfUnshared(SharedFontList* aFontlist)
1248 : {
1249 0 : MOZ_ASSERT(NS_IsMainThread());
1250 0 : return aFontlist->SizeOfIncludingThisIfUnshared(GeckoSharedFontListMallocSizeOf);
1251 : }
1252 :
1253 : size_t
1254 0 : Gecko_SharedFontList_SizeOfIncludingThis(SharedFontList* aFontlist)
1255 : {
1256 0 : MOZ_ASSERT(NS_IsMainThread());
1257 0 : return aFontlist->SizeOfIncludingThis(GeckoSharedFontListMallocSizeOf);
1258 : }
1259 :
1260 0 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(mozilla::SharedFontList, SharedFontList);
1261 :
1262 : void
1263 0 : Gecko_CopyFontFamilyFrom(nsFont* dst, const nsFont* src)
1264 : {
1265 1 : dst->fontlist = src->fontlist;
1266 0 : }
1267 :
1268 : void
1269 0 : Gecko_nsFont_InitSystem(nsFont* aDest, int32_t aFontId,
1270 : const nsStyleFont* aFont, RawGeckoPresContextBorrowed aPresContext)
1271 : {
1272 0 : const nsFont* defaultVariableFont = ThreadSafeGetDefaultFontHelper(aPresContext, aFont->mLanguage,
1273 81 : kPresContext_DefaultVariableFont_ID);
1274 :
1275 : // We have passed uninitialized memory to this function,
1276 : // initialize it. We can't simply return an nsFont because then
1277 : // we need to know its size beforehand. Servo cannot initialize nsFont
1278 : // itself, so this will do.
1279 0 : nsFont* system = new (aDest) nsFont(*defaultVariableFont);
1280 :
1281 81 : MOZ_RELEASE_ASSERT(system);
1282 :
1283 81 : *aDest = *defaultVariableFont;
1284 81 : LookAndFeel::FontID fontID = static_cast<LookAndFeel::FontID>(aFontId);
1285 :
1286 162 : AutoWriteLock guard(*sServoFFILock);
1287 : nsLayoutUtils::ComputeSystemFont(aDest, fontID, aPresContext,
1288 81 : defaultVariableFont);
1289 0 : }
1290 :
1291 : void
1292 0 : Gecko_nsFont_Destroy(nsFont* aDest)
1293 : {
1294 0 : aDest->~nsFont();
1295 0 : }
1296 :
1297 : gfxFontFeatureValueSet*
1298 0 : Gecko_ConstructFontFeatureValueSet()
1299 : {
1300 0 : return new gfxFontFeatureValueSet();
1301 : }
1302 :
1303 : nsTArray<unsigned int>*
1304 0 : Gecko_AppendFeatureValueHashEntry(gfxFontFeatureValueSet* aFontFeatureValues,
1305 : nsAtom* aFamily, uint32_t aAlternate, nsAtom* aName)
1306 : {
1307 0 : MOZ_ASSERT(NS_IsMainThread());
1308 : static_assert(sizeof(unsigned int) == sizeof(uint32_t),
1309 : "sizeof unsigned int and uint32_t must be the same");
1310 : return aFontFeatureValues->AppendFeatureValueHashEntry(
1311 0 : nsDependentAtomString(aFamily),
1312 0 : nsDependentAtomString(aName),
1313 : aAlternate
1314 0 : );
1315 : }
1316 :
1317 : void
1318 0 : Gecko_nsFont_SetFontFeatureValuesLookup(nsFont* aFont,
1319 : const RawGeckoPresContext* aPresContext)
1320 : {
1321 0 : aFont->featureValueLookup = aPresContext->GetFontFeatureValuesLookup();
1322 0 : }
1323 :
1324 : float
1325 81 : Gecko_FontStretch_ToFloat(mozilla::FontStretch aStretch)
1326 : {
1327 : // Servo represents percentages with 1. being 100%.
1328 0 : return aStretch.Percentage() / 100.0f;
1329 : }
1330 :
1331 : void
1332 81 : Gecko_FontStretch_SetFloat(mozilla::FontStretch* aStretch, float aFloat)
1333 : {
1334 : // Servo represents percentages with 1. being 100%.
1335 : //
1336 : // Also, the font code assumes a given maximum that style doesn't really need
1337 : // to know about. So clamp here at the boundary.
1338 0 : *aStretch = FontStretch(std::min(aFloat * 100.0f, float(FontStretch::kMax)));
1339 81 : }
1340 :
1341 : void
1342 81 : Gecko_FontSlantStyle_SetNormal(mozilla::FontSlantStyle* aStyle)
1343 : {
1344 0 : *aStyle = mozilla::FontSlantStyle::Normal();
1345 0 : }
1346 :
1347 : void
1348 0 : Gecko_FontSlantStyle_SetItalic(mozilla::FontSlantStyle* aStyle)
1349 : {
1350 0 : *aStyle = mozilla::FontSlantStyle::Italic();
1351 0 : }
1352 :
1353 : void
1354 0 : Gecko_FontSlantStyle_SetOblique(mozilla::FontSlantStyle* aStyle,
1355 : float aAngleInDegrees)
1356 : {
1357 0 : *aStyle = mozilla::FontSlantStyle::Oblique(aAngleInDegrees);
1358 0 : }
1359 :
1360 : void
1361 81 : Gecko_FontSlantStyle_Get(mozilla::FontSlantStyle aStyle,
1362 : bool* aNormal,
1363 : bool* aItalic,
1364 : float* aObliqueAngle)
1365 : {
1366 81 : *aNormal = aStyle.IsNormal();
1367 0 : *aItalic = aStyle.IsItalic();
1368 81 : if (aStyle.IsOblique()) {
1369 0 : *aObliqueAngle = aStyle.ObliqueAngle();
1370 : }
1371 81 : }
1372 :
1373 : float
1374 0 : Gecko_FontWeight_ToFloat(mozilla::FontWeight aWeight)
1375 : {
1376 84 : return aWeight.ToFloat();
1377 : }
1378 :
1379 : void
1380 0 : Gecko_FontWeight_SetFloat(mozilla::FontWeight* aWeight,
1381 : float aFloat)
1382 : {
1383 86 : *aWeight = mozilla::FontWeight(aFloat);
1384 86 : }
1385 :
1386 : void
1387 81 : Gecko_nsFont_ResetFontFeatureValuesLookup(nsFont* aFont)
1388 : {
1389 0 : aFont->featureValueLookup = nullptr;
1390 0 : }
1391 :
1392 :
1393 : void
1394 81 : Gecko_ClearAlternateValues(nsFont* aFont, size_t aLength)
1395 : {
1396 0 : aFont->alternateValues.Clear();
1397 81 : aFont->alternateValues.SetCapacity(aLength);
1398 81 : }
1399 :
1400 : void
1401 0 : Gecko_AppendAlternateValues(nsFont* aFont, uint32_t aAlternateName, nsAtom* aAtom)
1402 : {
1403 0 : aFont->alternateValues.AppendElement(gfxAlternateValue {
1404 : aAlternateName,
1405 0 : nsDependentAtomString(aAtom)
1406 0 : });
1407 0 : }
1408 :
1409 : void
1410 1 : Gecko_CopyAlternateValuesFrom(nsFont* aDest, const nsFont* aSrc)
1411 : {
1412 0 : aDest->alternateValues.Clear();
1413 0 : aDest->alternateValues.AppendElements(aSrc->alternateValues);
1414 1 : aDest->featureValueLookup = aSrc->featureValueLookup;
1415 1 : }
1416 :
1417 : void
1418 0 : Gecko_SetImageOrientation(nsStyleVisibility* aVisibility,
1419 : uint8_t aOrientation, bool aFlip)
1420 : {
1421 : aVisibility->mImageOrientation =
1422 0 : nsStyleImageOrientation::CreateAsOrientationAndFlip(aOrientation, aFlip);
1423 0 : }
1424 :
1425 : void
1426 0 : Gecko_SetImageOrientationAsFromImage(nsStyleVisibility* aVisibility)
1427 : {
1428 0 : aVisibility->mImageOrientation = nsStyleImageOrientation::CreateAsFromImage();
1429 0 : }
1430 :
1431 : void
1432 0 : Gecko_CopyImageOrientationFrom(nsStyleVisibility* aDst,
1433 : const nsStyleVisibility* aSrc)
1434 : {
1435 0 : aDst->mImageOrientation = aSrc->mImageOrientation;
1436 0 : }
1437 :
1438 : void
1439 0 : Gecko_SetCounterStyleToName(CounterStylePtr* aPtr, nsAtom* aName,
1440 : RawGeckoPresContextBorrowed aPresContext)
1441 : {
1442 : // Try resolving the counter style if possible, and keep it unresolved
1443 : // otherwise.
1444 0 : CounterStyleManager* manager = aPresContext->CounterStyleManager();
1445 0 : RefPtr<nsAtom> name = already_AddRefed<nsAtom>(aName);
1446 0 : if (CounterStyle* style = manager->GetCounterStyle(name)) {
1447 0 : *aPtr = style;
1448 : } else {
1449 0 : *aPtr = name.forget();
1450 : }
1451 0 : }
1452 :
1453 : void
1454 0 : Gecko_SetCounterStyleToSymbols(CounterStylePtr* aPtr, uint8_t aSymbolsType,
1455 : nsACString const* const* aSymbols,
1456 : uint32_t aSymbolsCount)
1457 : {
1458 0 : nsTArray<nsString> symbols(aSymbolsCount);
1459 0 : for (uint32_t i = 0; i < aSymbolsCount; i++) {
1460 0 : symbols.AppendElement(NS_ConvertUTF8toUTF16(*aSymbols[i]));
1461 : }
1462 0 : *aPtr = new AnonymousCounterStyle(aSymbolsType, std::move(symbols));
1463 0 : }
1464 :
1465 : void
1466 0 : Gecko_SetCounterStyleToString(CounterStylePtr* aPtr, const nsACString* aSymbol)
1467 : {
1468 0 : *aPtr = new AnonymousCounterStyle(NS_ConvertUTF8toUTF16(*aSymbol));
1469 0 : }
1470 :
1471 : void
1472 0 : Gecko_CopyCounterStyle(CounterStylePtr* aDst, const CounterStylePtr* aSrc)
1473 : {
1474 0 : *aDst = *aSrc;
1475 0 : }
1476 :
1477 : nsAtom*
1478 0 : Gecko_CounterStyle_GetName(const CounterStylePtr* aPtr)
1479 : {
1480 0 : if (!aPtr->IsResolved()) {
1481 0 : return aPtr->AsAtom();
1482 : }
1483 0 : return (*aPtr)->GetStyleName();
1484 : }
1485 :
1486 : const AnonymousCounterStyle*
1487 0 : Gecko_CounterStyle_GetAnonymous(const CounterStylePtr* aPtr)
1488 : {
1489 0 : return aPtr->AsAnonymous();
1490 : }
1491 :
1492 : already_AddRefed<css::URLValue>
1493 0 : ServoBundledURI::IntoCssUrl()
1494 : {
1495 0 : MOZ_ASSERT(mExtraData->GetReferrer());
1496 280 : MOZ_ASSERT(mExtraData->GetPrincipal());
1497 :
1498 : RefPtr<css::URLValue> urlValue =
1499 0 : new css::URLValue(mURLString, do_AddRef(mExtraData));
1500 280 : return urlValue.forget();
1501 : }
1502 :
1503 : already_AddRefed<css::ImageValue>
1504 394 : ServoBundledURI::IntoCssImage(mozilla::CORSMode aCorsMode)
1505 : {
1506 : RefPtr<css::ImageValue> urlValue =
1507 1182 : new css::ImageValue(mURLString, do_AddRef(mExtraData), aCorsMode);
1508 788 : return urlValue.forget();
1509 : }
1510 :
1511 : void
1512 112 : Gecko_SetNullImageValue(nsStyleImage* aImage)
1513 : {
1514 0 : MOZ_ASSERT(aImage);
1515 112 : aImage->SetNull();
1516 112 : }
1517 :
1518 : void
1519 33 : Gecko_SetGradientImageValue(nsStyleImage* aImage, nsStyleGradient* aGradient)
1520 : {
1521 0 : MOZ_ASSERT(aImage);
1522 0 : aImage->SetGradientData(aGradient);
1523 33 : }
1524 :
1525 0 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::ImageValue, ImageValue);
1526 :
1527 : static already_AddRefed<nsStyleImageRequest>
1528 0 : CreateStyleImageRequest(nsStyleImageRequest::Mode aModeFlags,
1529 : mozilla::css::ImageValue* aImageValue)
1530 : {
1531 : RefPtr<nsStyleImageRequest> req =
1532 158 : new nsStyleImageRequest(aModeFlags, aImageValue);
1533 158 : return req.forget();
1534 : }
1535 :
1536 : mozilla::css::ImageValue*
1537 394 : Gecko_ImageValue_Create(ServoBundledURI aURI)
1538 : {
1539 : // Bug 1434963: Change this to accept a CORS mode from the caller.
1540 788 : return aURI.IntoCssImage(mozilla::CORSMode::CORS_NONE).take();
1541 : }
1542 :
1543 0 : MOZ_DEFINE_MALLOC_SIZE_OF(GeckoImageValueMallocSizeOf)
1544 :
1545 : size_t
1546 0 : Gecko_ImageValue_SizeOfIncludingThis(mozilla::css::ImageValue* aImageValue)
1547 : {
1548 0 : MOZ_ASSERT(NS_IsMainThread());
1549 0 : return aImageValue->SizeOfIncludingThis(GeckoImageValueMallocSizeOf);
1550 : }
1551 :
1552 : void
1553 9 : Gecko_SetLayerImageImageValue(nsStyleImage* aImage,
1554 : mozilla::css::ImageValue* aImageValue)
1555 : {
1556 9 : MOZ_ASSERT(aImage && aImageValue);
1557 :
1558 : RefPtr<nsStyleImageRequest> req =
1559 0 : CreateStyleImageRequest(nsStyleImageRequest::Mode::Track, aImageValue);
1560 9 : aImage->SetImageRequest(req.forget());
1561 9 : }
1562 :
1563 : void
1564 0 : Gecko_SetImageElement(nsStyleImage* aImage, nsAtom* aAtom) {
1565 0 : MOZ_ASSERT(aImage);
1566 0 : aImage->SetElementId(do_AddRef(aAtom));
1567 0 : }
1568 :
1569 : void
1570 0 : Gecko_CopyImageValueFrom(nsStyleImage* aImage, const nsStyleImage* aOther)
1571 : {
1572 0 : MOZ_ASSERT(aImage);
1573 0 : MOZ_ASSERT(aOther);
1574 :
1575 0 : *aImage = *aOther;
1576 0 : }
1577 :
1578 : void
1579 0 : Gecko_InitializeImageCropRect(nsStyleImage* aImage)
1580 : {
1581 0 : MOZ_ASSERT(aImage);
1582 0 : aImage->SetCropRect(MakeUnique<nsStyleSides>());
1583 0 : }
1584 :
1585 : void
1586 77 : Gecko_SetCursorArrayLength(nsStyleUserInterface* aStyleUI, size_t aLen)
1587 : {
1588 0 : aStyleUI->mCursorImages.Clear();
1589 0 : aStyleUI->mCursorImages.SetLength(aLen);
1590 77 : }
1591 :
1592 : void
1593 0 : Gecko_SetCursorImageValue(nsCursorImage* aCursor,
1594 : mozilla::css::ImageValue* aImageValue)
1595 : {
1596 0 : MOZ_ASSERT(aCursor && aImageValue);
1597 :
1598 : aCursor->mImage =
1599 0 : CreateStyleImageRequest(nsStyleImageRequest::Mode::Discard, aImageValue);
1600 0 : }
1601 :
1602 : void
1603 0 : Gecko_CopyCursorArrayFrom(nsStyleUserInterface* aDest,
1604 : const nsStyleUserInterface* aSrc)
1605 : {
1606 0 : aDest->mCursorImages = aSrc->mCursorImages;
1607 0 : }
1608 :
1609 : void
1610 2 : Gecko_SetContentDataImageValue(nsStyleContentData* aContent,
1611 : mozilla::css::ImageValue* aImageValue)
1612 : {
1613 0 : MOZ_ASSERT(aContent && aImageValue);
1614 :
1615 : RefPtr<nsStyleImageRequest> req =
1616 0 : CreateStyleImageRequest(nsStyleImageRequest::Mode::Track, aImageValue);
1617 2 : aContent->SetImageRequest(req.forget());
1618 2 : }
1619 :
1620 : nsStyleContentData::CounterFunction*
1621 0 : Gecko_SetCounterFunction(nsStyleContentData* aContent, nsStyleContentType aType)
1622 : {
1623 : RefPtr<nsStyleContentData::CounterFunction>
1624 0 : counterFunc = new nsStyleContentData::CounterFunction();
1625 0 : nsStyleContentData::CounterFunction* ptr = counterFunc;
1626 0 : aContent->SetCounters(aType, counterFunc.forget());
1627 0 : return ptr;
1628 : }
1629 :
1630 : nsStyleGradient*
1631 0 : Gecko_CreateGradient(uint8_t aShape,
1632 : uint8_t aSize,
1633 : bool aRepeating,
1634 : bool aLegacySyntax,
1635 : bool aMozLegacySyntax,
1636 : uint32_t aStopCount)
1637 : {
1638 33 : nsStyleGradient* result = new nsStyleGradient();
1639 :
1640 33 : result->mShape = aShape;
1641 33 : result->mSize = aSize;
1642 33 : result->mRepeating = aRepeating;
1643 33 : result->mLegacySyntax = aLegacySyntax;
1644 0 : result->mMozLegacySyntax = aMozLegacySyntax;
1645 :
1646 0 : result->mAngle.SetNoneValue();
1647 0 : result->mBgPosX.SetNoneValue();
1648 0 : result->mBgPosY.SetNoneValue();
1649 0 : result->mRadiusX.SetNoneValue();
1650 0 : result->mRadiusY.SetNoneValue();
1651 :
1652 0 : nsStyleGradientStop dummyStop = {
1653 0 : nsStyleCoord(eStyleUnit_None),
1654 0 : StyleComplexColor::FromColor(NS_RGB(0, 0, 0)),
1655 0 : 0
1656 : };
1657 109 :
1658 0 : for (uint32_t i = 0; i < aStopCount; i++) {
1659 : result->mStops.AppendElement(dummyStop);
1660 : }
1661 0 :
1662 : return result;
1663 : }
1664 :
1665 0 : const nsStyleImageRequest*
1666 : Gecko_GetImageRequest(const nsStyleImage* aImage)
1667 0 : {
1668 0 : MOZ_ASSERT(aImage);
1669 : return aImage->ImageRequest();
1670 : }
1671 :
1672 0 : nsAtom*
1673 : Gecko_GetImageElement(const nsStyleImage* aImage)
1674 0 : {
1675 0 : MOZ_ASSERT(aImage && aImage->GetType() == eStyleImageType_Element);
1676 : return const_cast<nsAtom*>(aImage->GetElementId());
1677 : }
1678 :
1679 0 : const nsStyleGradient*
1680 : Gecko_GetGradientImageValue(const nsStyleImage* aImage)
1681 0 : {
1682 0 : MOZ_ASSERT(aImage && aImage->GetType() == eStyleImageType_Gradient);
1683 : return aImage->GetGradientData();
1684 : }
1685 :
1686 52 : void
1687 : Gecko_SetListStyleImageNone(nsStyleList* aList)
1688 0 : {
1689 52 : aList->mListStyleImage = nullptr;
1690 : }
1691 :
1692 0 : void
1693 : Gecko_SetListStyleImageImageValue(nsStyleList* aList,
1694 : mozilla::css::ImageValue* aImageValue)
1695 0 : {
1696 : MOZ_ASSERT(aList && aImageValue);
1697 :
1698 0 : aList->mListStyleImage =
1699 68 : CreateStyleImageRequest(nsStyleImageRequest::Mode(0), aImageValue);
1700 : }
1701 :
1702 6 : void
1703 : Gecko_CopyListStyleImageFrom(nsStyleList* aList, const nsStyleList* aSource)
1704 0 : {
1705 0 : aList->mListStyleImage = aSource->mListStyleImage;
1706 : }
1707 :
1708 0 : void
1709 : Gecko_EnsureTArrayCapacity(void* aArray, size_t aCapacity, size_t aElemSize)
1710 : {
1711 : auto base =
1712 119 : reinterpret_cast<nsTArray_base<nsTArrayInfallibleAllocator,
1713 : nsTArray_CopyWithMemutils>*>(aArray);
1714 0 :
1715 119 : base->EnsureCapacity<nsTArrayInfallibleAllocator>(aCapacity, aElemSize);
1716 : }
1717 :
1718 0 : void
1719 : Gecko_ClearPODTArray(void* aArray, size_t aElementSize, size_t aElementAlign)
1720 : {
1721 : auto base =
1722 0 : reinterpret_cast<nsTArray_base<nsTArrayInfallibleAllocator,
1723 : nsTArray_CopyWithMemutils>*>(aArray);
1724 0 :
1725 0 : base->template ShiftData<nsTArrayInfallibleAllocator>(0, base->Length(), 0,
1726 0 : aElementSize, aElementAlign);
1727 : }
1728 0 :
1729 : void Gecko_ResizeTArrayForStrings(nsTArray<nsString>* aArray, uint32_t aLength)
1730 0 : {
1731 0 : aArray->SetLength(aLength);
1732 : }
1733 :
1734 0 : void
1735 : Gecko_SetStyleGridTemplate(UniquePtr<nsStyleGridTemplate>* aGridTemplate,
1736 : nsStyleGridTemplate* aValue)
1737 0 : {
1738 0 : aGridTemplate->reset(aValue);
1739 : }
1740 :
1741 0 : nsStyleGridTemplate*
1742 : Gecko_CreateStyleGridTemplate(uint32_t aTrackSizes, uint32_t aNameSize)
1743 0 : {
1744 0 : nsStyleGridTemplate* result = new nsStyleGridTemplate;
1745 0 : result->mMinTrackSizingFunctions.SetLength(aTrackSizes);
1746 0 : result->mMaxTrackSizingFunctions.SetLength(aTrackSizes);
1747 0 : result->mLineNameLists.SetLength(aNameSize);
1748 : return result;
1749 : }
1750 :
1751 0 : void
1752 : Gecko_CopyStyleGridTemplateValues(UniquePtr<nsStyleGridTemplate>* aGridTemplate,
1753 : const nsStyleGridTemplate* aOther)
1754 34 : {
1755 0 : if (aOther) {
1756 : *aGridTemplate = MakeUnique<nsStyleGridTemplate>(*aOther);
1757 0 : } else {
1758 : *aGridTemplate = nullptr;
1759 34 : }
1760 : }
1761 :
1762 0 : mozilla::css::GridTemplateAreasValue*
1763 : Gecko_NewGridTemplateAreasValue(uint32_t aAreas, uint32_t aTemplates, uint32_t aColumns)
1764 0 : {
1765 0 : RefPtr<mozilla::css::GridTemplateAreasValue> value = new mozilla::css::GridTemplateAreasValue;
1766 0 : value->mNamedAreas.SetLength(aAreas);
1767 0 : value->mTemplates.SetLength(aTemplates);
1768 0 : value->mNColumns = aColumns;
1769 : return value.forget().take();
1770 : }
1771 0 :
1772 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(mozilla::css::GridTemplateAreasValue, GridTemplateAreasValue);
1773 :
1774 0 : void
1775 : Gecko_ClearAndResizeStyleContents(nsStyleContent* aContent, uint32_t aHowMany)
1776 9 : {
1777 0 : aContent->AllocateContents(aHowMany);
1778 : }
1779 :
1780 0 : void
1781 : Gecko_CopyStyleContentsFrom(nsStyleContent* aContent, const nsStyleContent* aOther)
1782 0 : {
1783 : uint32_t count = aOther->ContentCount();
1784 0 :
1785 : aContent->AllocateContents(count);
1786 0 :
1787 0 : for (uint32_t i = 0; i < count; ++i) {
1788 : aContent->ContentAt(i) = aOther->ContentAt(i);
1789 0 : }
1790 : }
1791 :
1792 0 : void
1793 : Gecko_ClearAndResizeCounterIncrements(nsStyleContent* aContent, uint32_t aHowMany)
1794 0 : {
1795 0 : aContent->AllocateCounterIncrements(aHowMany);
1796 : }
1797 :
1798 0 : void
1799 : Gecko_CopyCounterIncrementsFrom(nsStyleContent* aContent, const nsStyleContent* aOther)
1800 0 : {
1801 : uint32_t count = aOther->CounterIncrementCount();
1802 0 :
1803 : aContent->AllocateCounterIncrements(count);
1804 0 :
1805 0 : for (uint32_t i = 0; i < count; ++i) {
1806 0 : const nsStyleCounterData& data = aOther->CounterIncrementAt(i);
1807 : aContent->SetCounterIncrementAt(i, data.mCounter, data.mValue);
1808 0 : }
1809 : }
1810 :
1811 0 : void
1812 : Gecko_ClearAndResizeCounterResets(nsStyleContent* aContent, uint32_t aHowMany)
1813 0 : {
1814 0 : aContent->AllocateCounterResets(aHowMany);
1815 : }
1816 :
1817 0 : void
1818 : Gecko_CopyCounterResetsFrom(nsStyleContent* aContent, const nsStyleContent* aOther)
1819 0 : {
1820 : uint32_t count = aOther->CounterResetCount();
1821 0 :
1822 : aContent->AllocateCounterResets(count);
1823 0 :
1824 0 : for (uint32_t i = 0; i < count; ++i) {
1825 0 : const nsStyleCounterData& data = aOther->CounterResetAt(i);
1826 : aContent->SetCounterResetAt(i, data.mCounter, data.mValue);
1827 0 : }
1828 : }
1829 :
1830 0 : void
1831 : Gecko_EnsureImageLayersLength(nsStyleImageLayers* aLayers, size_t aLen,
1832 : nsStyleImageLayers::LayerType aLayerType)
1833 0 : {
1834 : size_t oldLength = aLayers->mLayers.Length();
1835 322 :
1836 : aLayers->mLayers.EnsureLengthAtLeast(aLen);
1837 322 :
1838 0 : for (size_t i = oldLength; i < aLen; ++i) {
1839 : aLayers->mLayers[i].Initialize(aLayerType);
1840 322 : }
1841 : }
1842 :
1843 : template <typename StyleType>
1844 0 : static void
1845 : EnsureStyleAutoArrayLength(StyleType* aArray, size_t aLen)
1846 0 : {
1847 : size_t oldLength = aArray->Length();
1848 139 :
1849 : aArray->EnsureLengthAtLeast(aLen);
1850 0 :
1851 4 : for (size_t i = oldLength; i < aLen; ++i) {
1852 : (*aArray)[i].SetInitialValues();
1853 139 : }
1854 : }
1855 :
1856 0 : void
1857 : Gecko_EnsureStyleAnimationArrayLength(void* aArray, size_t aLen)
1858 : {
1859 0 : auto base =
1860 16 : static_cast<nsStyleAutoArray<StyleAnimation>*>(aArray);
1861 16 : EnsureStyleAutoArrayLength(base, aLen);
1862 : }
1863 :
1864 123 : void
1865 : Gecko_EnsureStyleTransitionArrayLength(void* aArray, size_t aLen)
1866 : {
1867 0 : auto base =
1868 123 : reinterpret_cast<nsStyleAutoArray<StyleTransition>*>(aArray);
1869 123 : EnsureStyleAutoArrayLength(base, aLen);
1870 : }
1871 :
1872 0 : void
1873 : Gecko_ClearWillChange(nsStyleDisplay* aDisplay, size_t aLength)
1874 0 : {
1875 0 : aDisplay->mWillChange.Clear();
1876 0 : aDisplay->mWillChange.SetCapacity(aLength);
1877 : }
1878 :
1879 0 : void
1880 : Gecko_AppendWillChange(nsStyleDisplay* aDisplay, nsAtom* aAtom)
1881 0 : {
1882 0 : aDisplay->mWillChange.AppendElement(aAtom);
1883 : }
1884 :
1885 0 : void
1886 : Gecko_CopyWillChangeFrom(nsStyleDisplay* aDest, nsStyleDisplay* aSrc)
1887 0 : {
1888 0 : aDest->mWillChange.Clear();
1889 0 : aDest->mWillChange.AppendElements(aSrc->mWillChange);
1890 : }
1891 :
1892 : enum class KeyframeSearchDirection {
1893 : Forwards,
1894 : Backwards,
1895 : };
1896 :
1897 : enum class KeyframeInsertPosition {
1898 : Prepend,
1899 : LastForOffset,
1900 : };
1901 :
1902 0 : static Keyframe*
1903 : GetOrCreateKeyframe(nsTArray<Keyframe>* aKeyframes,
1904 : float aOffset,
1905 : const nsTimingFunction* aTimingFunction,
1906 : KeyframeSearchDirection aSearchDirection,
1907 : KeyframeInsertPosition aInsertPosition)
1908 0 : {
1909 0 : MOZ_ASSERT(aKeyframes, "The keyframe array should be valid");
1910 0 : MOZ_ASSERT(aTimingFunction, "The timing function should be valid");
1911 : MOZ_ASSERT(aOffset >= 0. && aOffset <= 1.,
1912 : "The offset should be in the range of [0.0, 1.0]");
1913 :
1914 0 : size_t keyframeIndex;
1915 : switch (aSearchDirection) {
1916 0 : case KeyframeSearchDirection::Forwards:
1917 : if (nsAnimationManager::FindMatchingKeyframe(*aKeyframes,
1918 : aOffset,
1919 : *aTimingFunction,
1920 0 : keyframeIndex)) {
1921 : return &(*aKeyframes)[keyframeIndex];
1922 : }
1923 : break;
1924 0 : case KeyframeSearchDirection::Backwards:
1925 : if (nsAnimationManager::FindMatchingKeyframe(Reversed(*aKeyframes),
1926 : aOffset,
1927 : *aTimingFunction,
1928 0 : keyframeIndex)) {
1929 : return &(*aKeyframes)[aKeyframes->Length() - 1 - keyframeIndex];
1930 0 : }
1931 0 : keyframeIndex = aKeyframes->Length() - 1;
1932 : break;
1933 : }
1934 :
1935 0 : Keyframe* keyframe =
1936 : aKeyframes->InsertElementAt(
1937 : aInsertPosition == KeyframeInsertPosition::Prepend
1938 0 : ? 0
1939 0 : : keyframeIndex);
1940 0 : keyframe->mOffset.emplace(aOffset);
1941 0 : if (aTimingFunction->mType != nsTimingFunction::Type::Linear) {
1942 0 : keyframe->mTimingFunction.emplace();
1943 : keyframe->mTimingFunction->Init(*aTimingFunction);
1944 : }
1945 :
1946 : return keyframe;
1947 : }
1948 :
1949 0 : Keyframe*
1950 : Gecko_GetOrCreateKeyframeAtStart(nsTArray<Keyframe>* aKeyframes,
1951 : float aOffset,
1952 : const nsTimingFunction* aTimingFunction)
1953 0 : {
1954 : MOZ_ASSERT(aKeyframes->IsEmpty() ||
1955 : aKeyframes->ElementAt(0).mOffset.value() >= aOffset,
1956 : "The offset should be less than or equal to the first keyframe's "
1957 : "offset if there are exisiting keyframes");
1958 :
1959 : return GetOrCreateKeyframe(aKeyframes,
1960 : aOffset,
1961 : aTimingFunction,
1962 0 : KeyframeSearchDirection::Forwards,
1963 : KeyframeInsertPosition::Prepend);
1964 : }
1965 :
1966 0 : Keyframe*
1967 : Gecko_GetOrCreateInitialKeyframe(nsTArray<Keyframe>* aKeyframes,
1968 : const nsTimingFunction* aTimingFunction)
1969 : {
1970 : return GetOrCreateKeyframe(aKeyframes,
1971 : 0.,
1972 : aTimingFunction,
1973 0 : KeyframeSearchDirection::Forwards,
1974 : KeyframeInsertPosition::LastForOffset);
1975 : }
1976 :
1977 0 : Keyframe*
1978 : Gecko_GetOrCreateFinalKeyframe(nsTArray<Keyframe>* aKeyframes,
1979 : const nsTimingFunction* aTimingFunction)
1980 : {
1981 : return GetOrCreateKeyframe(aKeyframes,
1982 : 1.,
1983 : aTimingFunction,
1984 0 : KeyframeSearchDirection::Backwards,
1985 : KeyframeInsertPosition::LastForOffset);
1986 : }
1987 :
1988 0 : PropertyValuePair*
1989 : Gecko_AppendPropertyValuePair(nsTArray<PropertyValuePair>* aProperties,
1990 : nsCSSPropertyID aProperty)
1991 0 : {
1992 0 : MOZ_ASSERT(aProperties);
1993 : return aProperties->AppendElement(PropertyValuePair {aProperty});
1994 : }
1995 :
1996 0 : void
1997 : Gecko_ResetStyleCoord(nsStyleUnit* aUnit, nsStyleUnion* aValue)
1998 0 : {
1999 0 : nsStyleCoord::Reset(*aUnit, *aValue);
2000 : }
2001 :
2002 0 : void
2003 : Gecko_SetStyleCoordCalcValue(nsStyleUnit* aUnit, nsStyleUnion* aValue, nsStyleCoord::CalcValue aCalc)
2004 : {
2005 0 : // Calc units should be cleaned up first
2006 136 : MOZ_ASSERT(*aUnit != nsStyleUnit::eStyleUnit_Calc);
2007 68 : nsStyleCoord::Calc* calcRef = new nsStyleCoord::Calc();
2008 0 : calcRef->mLength = aCalc.mLength;
2009 68 : calcRef->mPercent = aCalc.mPercent;
2010 68 : calcRef->mHasPercent = aCalc.mHasPercent;
2011 0 : *aUnit = nsStyleUnit::eStyleUnit_Calc;
2012 0 : aValue->mPointer = calcRef;
2013 0 : calcRef->AddRef();
2014 : }
2015 :
2016 0 : void
2017 : Gecko_CopyShapeSourceFrom(mozilla::StyleShapeSource* aDst, const mozilla::StyleShapeSource* aSrc)
2018 0 : {
2019 0 : MOZ_ASSERT(aDst);
2020 : MOZ_ASSERT(aSrc);
2021 0 :
2022 0 : *aDst = *aSrc;
2023 : }
2024 :
2025 0 : void
2026 : Gecko_DestroyShapeSource(mozilla::StyleShapeSource* aShape)
2027 0 : {
2028 0 : aShape->~StyleShapeSource();
2029 : }
2030 :
2031 0 : void
2032 : Gecko_StyleShapeSource_SetURLValue(StyleShapeSource* aShape, URLValue* aURL)
2033 0 : {
2034 0 : aShape->SetURL(aURL);
2035 : }
2036 :
2037 0 : void
2038 : Gecko_NewBasicShape(mozilla::StyleShapeSource* aShape,
2039 : mozilla::StyleBasicShapeType aType)
2040 0 : {
2041 0 : aShape->SetBasicShape(MakeUnique<mozilla::StyleBasicShape>(aType),
2042 0 : StyleGeometryBox::NoBox);
2043 : }
2044 :
2045 0 : void
2046 : Gecko_NewShapeImage(mozilla::StyleShapeSource* aShape)
2047 0 : {
2048 0 : aShape->SetShapeImage(MakeUnique<nsStyleImage>());
2049 : }
2050 :
2051 0 : void
2052 : Gecko_ResetFilters(nsStyleEffects* effects, size_t new_len)
2053 0 : {
2054 0 : effects->mFilters.Clear();
2055 0 : effects->mFilters.SetLength(new_len);
2056 : }
2057 :
2058 0 : void
2059 : Gecko_CopyFiltersFrom(nsStyleEffects* aSrc, nsStyleEffects* aDest)
2060 0 : {
2061 0 : aDest->mFilters = aSrc->mFilters;
2062 : }
2063 :
2064 0 : void
2065 : Gecko_nsStyleFilter_SetURLValue(nsStyleFilter* aEffects, URLValue* aURL)
2066 0 : {
2067 0 : aEffects->SetURL(aURL);
2068 : }
2069 :
2070 0 : void
2071 : Gecko_nsStyleSVGPaint_CopyFrom(nsStyleSVGPaint* aDest, const nsStyleSVGPaint* aSrc)
2072 0 : {
2073 0 : *aDest = *aSrc;
2074 : }
2075 :
2076 0 : void
2077 : Gecko_nsStyleSVGPaint_SetURLValue(nsStyleSVGPaint* aPaint, URLValue* aURL)
2078 0 : {
2079 0 : aPaint->SetPaintServer(aURL);
2080 : }
2081 89 :
2082 : void Gecko_nsStyleSVGPaint_Reset(nsStyleSVGPaint* aPaint)
2083 89 : {
2084 0 : aPaint->SetNone();
2085 : }
2086 :
2087 0 : void
2088 : Gecko_nsStyleSVG_SetDashArrayLength(nsStyleSVG* aSvg, uint32_t aLen)
2089 0 : {
2090 0 : aSvg->mStrokeDasharray.Clear();
2091 0 : aSvg->mStrokeDasharray.SetLength(aLen);
2092 : }
2093 :
2094 0 : void
2095 : Gecko_nsStyleSVG_CopyDashArray(nsStyleSVG* aDst, const nsStyleSVG* aSrc)
2096 0 : {
2097 0 : aDst->mStrokeDasharray = aSrc->mStrokeDasharray;
2098 : }
2099 :
2100 0 : void
2101 : Gecko_nsStyleSVG_SetContextPropertiesLength(nsStyleSVG* aSvg, uint32_t aLen)
2102 0 : {
2103 0 : aSvg->mContextProps.Clear();
2104 75 : aSvg->mContextProps.SetLength(aLen);
2105 : }
2106 :
2107 0 : void
2108 : Gecko_nsStyleSVG_CopyContextProperties(nsStyleSVG* aDst, const nsStyleSVG* aSrc)
2109 0 : {
2110 0 : aDst->mContextProps = aSrc->mContextProps;
2111 0 : aDst->mContextPropsBits = aSrc->mContextPropsBits;
2112 : }
2113 :
2114 :
2115 0 : css::URLValue*
2116 : Gecko_NewURLValue(ServoBundledURI aURI)
2117 0 : {
2118 396 : RefPtr<css::URLValue> url = aURI.IntoCssUrl();
2119 : return url.forget().take();
2120 : }
2121 0 :
2122 : MOZ_DEFINE_MALLOC_SIZE_OF(GeckoURLValueMallocSizeOf)
2123 :
2124 0 : size_t
2125 : Gecko_URLValue_SizeOfIncludingThis(URLValue* aURL)
2126 0 : {
2127 0 : MOZ_ASSERT(NS_IsMainThread());
2128 : return aURL->SizeOfIncludingThis(GeckoURLValueMallocSizeOf);
2129 : }
2130 :
2131 0 : void
2132 : Gecko_GetComputedURLSpec(const URLValueData* aURL, nsCString* aOut)
2133 0 : {
2134 0 : MOZ_ASSERT(aURL);
2135 0 : MOZ_ASSERT(aOut);
2136 0 : if (aURL->IsLocalRef()) {
2137 0 : aOut->Assign(aURL->GetString());
2138 : return;
2139 0 : }
2140 0 : if (nsIURI* uri = aURL->GetURI()) {
2141 0 : nsresult rv = uri->GetSpec(*aOut);
2142 : if (NS_SUCCEEDED(rv)) {
2143 : return;
2144 : }
2145 : }
2146 0 :
2147 : aOut->AssignLiteral("about:invalid");
2148 : }
2149 1007 :
2150 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(css::URLValue, CSSURLValue);
2151 1846 :
2152 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(URLExtraData, URLExtraData);
2153 0 :
2154 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsStyleCoord::Calc, Calc);
2155 :
2156 37 : nsCSSShadowArray*
2157 : Gecko_NewCSSShadowArray(uint32_t aLen)
2158 74 : {
2159 0 : RefPtr<nsCSSShadowArray> arr = new(aLen) nsCSSShadowArray(aLen);
2160 : return arr.forget().take();
2161 : }
2162 0 :
2163 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsCSSShadowArray, CSSShadowArray);
2164 :
2165 0 : nsStyleQuoteValues*
2166 : Gecko_NewStyleQuoteValues(uint32_t aLen)
2167 0 : {
2168 0 : RefPtr<nsStyleQuoteValues> values = new nsStyleQuoteValues;
2169 0 : values->mQuotePairs.SetLength(aLen);
2170 : return values.forget().take();
2171 : }
2172 0 :
2173 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsStyleQuoteValues, QuoteValues);
2174 :
2175 0 : nsCSSValueSharedList*
2176 : Gecko_NewCSSValueSharedList(uint32_t aLen)
2177 39 : {
2178 0 : RefPtr<nsCSSValueSharedList> list = new nsCSSValueSharedList;
2179 0 : if (aLen == 0) {
2180 : return list.forget().take();
2181 : }
2182 13 :
2183 0 : list->mHead = new nsCSSValueList;
2184 0 : nsCSSValueList* cur = list->mHead;
2185 1 : for (uint32_t i = 0; i < aLen - 1; i++) {
2186 2 : cur->mNext = new nsCSSValueList;
2187 : cur = cur->mNext;
2188 : }
2189 0 :
2190 : return list.forget().take();
2191 : }
2192 :
2193 0 : nsCSSValueSharedList*
2194 : Gecko_NewNoneTransform()
2195 0 : {
2196 0 : RefPtr<nsCSSValueSharedList> list = new nsCSSValueSharedList;
2197 0 : list->mHead = new nsCSSValueList;
2198 0 : list->mHead->mValue.SetNoneValue();
2199 : return list.forget().take();
2200 : }
2201 :
2202 0 : void
2203 : Gecko_CSSValue_SetNumber(nsCSSValueBorrowedMut aCSSValue, float aNumber)
2204 0 : {
2205 10 : aCSSValue->SetFloatValue(aNumber, eCSSUnit_Number);
2206 : }
2207 :
2208 0 : float
2209 : Gecko_CSSValue_GetNumber(nsCSSValueBorrowed aCSSValue)
2210 0 : {
2211 : return aCSSValue->GetFloatValue();
2212 : }
2213 :
2214 0 : void
2215 : Gecko_CSSValue_SetKeyword(nsCSSValueBorrowedMut aCSSValue, nsCSSKeyword aKeyword)
2216 0 : {
2217 15 : aCSSValue->SetEnumValue(aKeyword);
2218 : }
2219 :
2220 0 : nsCSSKeyword
2221 : Gecko_CSSValue_GetKeyword(nsCSSValueBorrowed aCSSValue)
2222 0 : {
2223 : return aCSSValue->GetKeywordValue();
2224 : }
2225 :
2226 0 : void
2227 : Gecko_CSSValue_SetPercentage(nsCSSValueBorrowedMut aCSSValue, float aPercent)
2228 0 : {
2229 2 : aCSSValue->SetPercentValue(aPercent);
2230 : }
2231 :
2232 0 : float
2233 : Gecko_CSSValue_GetPercentage(nsCSSValueBorrowed aCSSValue)
2234 0 : {
2235 : return aCSSValue->GetPercentValue();
2236 : }
2237 :
2238 0 : void
2239 : Gecko_CSSValue_SetPixelLength(nsCSSValueBorrowedMut aCSSValue, float aLen)
2240 0 : {
2241 : MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Null ||
2242 4 : aCSSValue->GetUnit() == eCSSUnit_Pixel);
2243 4 : aCSSValue->SetFloatValue(aLen, eCSSUnit_Pixel);
2244 : }
2245 :
2246 0 : void
2247 : Gecko_CSSValue_SetCalc(nsCSSValueBorrowedMut aCSSValue, nsStyleCoord::CalcValue aCalc)
2248 0 : {
2249 0 : aCSSValue->SetCalcValue(&aCalc);
2250 : }
2251 :
2252 0 : nsStyleCoord::CalcValue
2253 : Gecko_CSSValue_GetCalc(nsCSSValueBorrowed aCSSValue)
2254 0 : {
2255 : return aCSSValue->GetCalcValue();
2256 : }
2257 :
2258 0 : void
2259 : Gecko_CSSValue_SetFunction(nsCSSValueBorrowedMut aCSSValue, int32_t aLen)
2260 0 : {
2261 15 : nsCSSValue::Array* arr = nsCSSValue::Array::Create(aLen);
2262 15 : aCSSValue->SetArrayValue(arr, eCSSUnit_Function);
2263 : }
2264 :
2265 0 : void
2266 : Gecko_CSSValue_SetString(nsCSSValueBorrowedMut aCSSValue,
2267 : const uint8_t* aString, uint32_t aLength,
2268 : nsCSSUnit aUnit)
2269 0 : {
2270 0 : MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Null);
2271 : nsString string;
2272 0 : nsDependentCSubstring slice(reinterpret_cast<const char*>(aString),
2273 0 : aLength);
2274 0 : AppendUTF8toUTF16(slice, string);
2275 0 : aCSSValue->SetStringValue(string, aUnit);
2276 : }
2277 :
2278 0 : void
2279 : Gecko_CSSValue_SetStringFromAtom(nsCSSValueBorrowedMut aCSSValue,
2280 : nsAtom* aAtom, nsCSSUnit aUnit)
2281 0 : {
2282 0 : aCSSValue->SetStringValue(nsDependentAtomString(aAtom), aUnit);
2283 : }
2284 :
2285 0 : void
2286 : Gecko_CSSValue_SetAtomIdent(nsCSSValueBorrowedMut aCSSValue, nsAtom* aAtom)
2287 0 : {
2288 0 : aCSSValue->SetAtomIdentValue(already_AddRefed<nsAtom>(aAtom));
2289 : }
2290 :
2291 0 : void
2292 : Gecko_CSSValue_SetArray(nsCSSValueBorrowedMut aCSSValue, int32_t aLength)
2293 0 : {
2294 : MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Null);
2295 0 : RefPtr<nsCSSValue::Array> array
2296 0 : = nsCSSValue::Array::Create(aLength);
2297 0 : aCSSValue->SetArrayValue(array, eCSSUnit_Array);
2298 : }
2299 :
2300 0 : void
2301 : Gecko_CSSValue_SetURL(nsCSSValueBorrowedMut aCSSValue, URLValue* aURL)
2302 0 : {
2303 0 : MOZ_ASSERT(aCSSValue->GetUnit() == eCSSUnit_Null);
2304 0 : aCSSValue->SetURLValue(aURL);
2305 : }
2306 :
2307 0 : void
2308 : Gecko_CSSValue_SetInt(nsCSSValueBorrowedMut aCSSValue,
2309 : int32_t aInteger, nsCSSUnit aUnit)
2310 0 : {
2311 0 : aCSSValue->SetIntValue(aInteger, aUnit);
2312 : }
2313 :
2314 0 : void
2315 : Gecko_CSSValue_SetFloat(nsCSSValueBorrowedMut aCSSValue,
2316 : float aValue, nsCSSUnit aUnit)
2317 0 : {
2318 0 : aCSSValue->SetFloatValue(aValue, aUnit);
2319 : }
2320 :
2321 31 : nsCSSValueBorrowedMut
2322 : Gecko_CSSValue_GetArrayItem(nsCSSValueBorrowedMut aCSSValue, int32_t aIndex)
2323 1 : {
2324 : return &aCSSValue->GetArrayValue()->Item(aIndex);
2325 : }
2326 :
2327 0 : nsCSSValueBorrowed
2328 : Gecko_CSSValue_GetArrayItemConst(nsCSSValueBorrowed aCSSValue, int32_t aIndex)
2329 0 : {
2330 : return &aCSSValue->GetArrayValue()->Item(aIndex);
2331 : }
2332 :
2333 0 : void
2334 : Gecko_CSSValue_SetPair(nsCSSValueBorrowedMut aCSSValue,
2335 : nsCSSValueBorrowed aXValue, nsCSSValueBorrowed aYValue)
2336 0 : {
2337 0 : MOZ_ASSERT(NS_IsMainThread());
2338 0 : aCSSValue->SetPairValue(*aXValue, *aYValue);
2339 : }
2340 :
2341 0 : void
2342 : Gecko_CSSValue_SetList(nsCSSValueBorrowedMut aCSSValue, uint32_t aLen)
2343 0 : {
2344 0 : MOZ_ASSERT(NS_IsMainThread());
2345 0 : nsCSSValueList* item = aCSSValue->SetListValue();
2346 0 : for (uint32_t i = 1; i < aLen; ++i) {
2347 0 : item->mNext = new nsCSSValueList;
2348 : item = item->mNext;
2349 0 : }
2350 : }
2351 :
2352 0 : void
2353 : Gecko_CSSValue_SetPairList(nsCSSValueBorrowedMut aCSSValue, uint32_t aLen)
2354 0 : {
2355 0 : MOZ_ASSERT(NS_IsMainThread());
2356 0 : nsCSSValuePairList* item = aCSSValue->SetPairListValue();
2357 0 : for (uint32_t i = 1; i < aLen; ++i) {
2358 0 : item->mNext = new nsCSSValuePairList;
2359 : item = item->mNext;
2360 0 : }
2361 : }
2362 :
2363 0 : void
2364 : Gecko_CSSValue_InitSharedList(nsCSSValueBorrowedMut aCSSValue,
2365 : uint32_t aLen)
2366 0 : {
2367 : MOZ_ASSERT(aLen > 0, "Must create at least one nsCSSValueList (mHead)");
2368 0 :
2369 0 : nsCSSValueSharedList* list = new nsCSSValueSharedList;
2370 0 : aCSSValue->SetSharedListValue(list);
2371 0 : list->mHead = new nsCSSValueList;
2372 0 : nsCSSValueList* cur = list->mHead;
2373 0 : for (uint32_t i = 1; i < aLen; ++i) {
2374 0 : cur->mNext = new nsCSSValueList;
2375 : cur = cur->mNext;
2376 0 : }
2377 : }
2378 :
2379 0 : void
2380 : Gecko_CSSValue_Drop(nsCSSValueBorrowedMut aCSSValue)
2381 446 : {
2382 0 : aCSSValue->~nsCSSValue();
2383 : }
2384 :
2385 0 : void
2386 : Gecko_CSSValue_SetFontStretch(nsCSSValueBorrowedMut aCSSValue,
2387 : float stretch)
2388 0 : {
2389 0 : aCSSValue->SetFontStretch(
2390 0 : FontStretch(std::min(stretch * 100.0f, float(FontStretch::kMax))));
2391 : }
2392 :
2393 : // FIXME(emilio): This function should probably have `Oblique` in its name.
2394 0 : void
2395 : Gecko_CSSValue_SetFontSlantStyle(nsCSSValueBorrowedMut aCSSValue,
2396 : float aAngle)
2397 0 : {
2398 0 : aCSSValue->SetFontSlantStyle(mozilla::FontSlantStyle::Oblique(aAngle));
2399 : }
2400 :
2401 0 : void
2402 : Gecko_CSSValue_SetFontWeight(nsCSSValueBorrowedMut aCSSValue,
2403 : float weight)
2404 0 : {
2405 0 : aCSSValue->SetFontWeight(mozilla::FontWeight(weight));
2406 : }
2407 :
2408 0 : void
2409 : Gecko_nsStyleFont_SetLang(nsStyleFont* aFont, nsAtom* aAtom)
2410 0 : {
2411 0 : already_AddRefed<nsAtom> atom = already_AddRefed<nsAtom>(aAtom);
2412 0 : aFont->mLanguage = atom;
2413 0 : aFont->mExplicitLanguage = true;
2414 : }
2415 :
2416 0 : void
2417 : Gecko_nsStyleFont_CopyLangFrom(nsStyleFont* aFont, const nsStyleFont* aSource)
2418 0 : {
2419 0 : aFont->mLanguage = aSource->mLanguage;
2420 : }
2421 :
2422 0 : void
2423 : Gecko_nsStyleFont_FixupNoneGeneric(nsStyleFont* aFont,
2424 : RawGeckoPresContextBorrowed aPresContext)
2425 : {
2426 0 : const nsFont* defaultVariableFont =
2427 0 : ThreadSafeGetDefaultFontHelper(aPresContext, aFont->mLanguage,
2428 0 : kPresContext_DefaultVariableFont_ID);
2429 0 : nsLayoutUtils::FixupNoneGeneric(&aFont->mFont, aPresContext,
2430 0 : aFont->mGenericID, defaultVariableFont);
2431 : }
2432 :
2433 0 : void
2434 : Gecko_nsStyleFont_PrefillDefaultForGeneric(nsStyleFont* aFont,
2435 : RawGeckoPresContextBorrowed aPresContext,
2436 : uint8_t aGenericId)
2437 164 : {
2438 82 : const nsFont* defaultFont = ThreadSafeGetDefaultFontHelper(aPresContext, aFont->mLanguage,
2439 : aGenericId);
2440 : // In case of just the language changing, the parent could have had no generic,
2441 : // which Gecko just does regular cascading with. Do the same.
2442 82 : // This can only happen in the case where the language changed but the family did not
2443 0 : if (aGenericId != kGenericFont_NONE) {
2444 : aFont->mFont.fontlist = defaultFont->fontlist;
2445 82 : } else {
2446 : aFont->mFont.fontlist.SetDefaultFontType(defaultFont->fontlist.GetDefaultFontType());
2447 82 : }
2448 : }
2449 :
2450 89 : void
2451 : Gecko_nsStyleFont_FixupMinFontSize(nsStyleFont* aFont,
2452 : RawGeckoPresContextBorrowed aPresContext)
2453 : {
2454 89 : nscoord minFontSize;
2455 : bool needsCache = false;
2456 :
2457 178 : {
2458 178 : AutoReadLock guard(*sServoFFILock);
2459 : minFontSize = aPresContext->MinFontSize(aFont->mLanguage, &needsCache);
2460 : }
2461 89 :
2462 0 : if (needsCache) {
2463 0 : AutoWriteLock guard(*sServoFFILock);
2464 : minFontSize = aPresContext->MinFontSize(aFont->mLanguage, nullptr);
2465 : }
2466 89 :
2467 0 : nsLayoutUtils::ApplyMinFontSize(aFont, aPresContext, minFontSize);
2468 : }
2469 :
2470 0 : void
2471 : FontSizePrefs::CopyFrom(const LangGroupFontPrefs& prefs)
2472 0 : {
2473 0 : mDefaultVariableSize = prefs.mDefaultVariableFont.size;
2474 0 : mDefaultFixedSize = prefs.mDefaultFixedFont.size;
2475 0 : mDefaultSerifSize = prefs.mDefaultSerifFont.size;
2476 0 : mDefaultSansSerifSize = prefs.mDefaultSansSerifFont.size;
2477 0 : mDefaultMonospaceSize = prefs.mDefaultMonospaceFont.size;
2478 0 : mDefaultCursiveSize = prefs.mDefaultCursiveFont.size;
2479 0 : mDefaultFantasySize = prefs.mDefaultFantasyFont.size;
2480 : }
2481 :
2482 0 : FontSizePrefs
2483 : Gecko_GetBaseSize(nsAtom* aLanguage)
2484 0 : {
2485 0 : LangGroupFontPrefs prefs;
2486 : RefPtr<nsAtom> langGroupAtom = StaticPresData::Get()->GetUncachedLangGroup(aLanguage);
2487 0 :
2488 : prefs.Initialize(langGroupAtom);
2489 0 : FontSizePrefs sizes;
2490 : sizes.CopyFrom(prefs);
2491 0 :
2492 : return sizes;
2493 : }
2494 :
2495 0 : RawGeckoElementBorrowedOrNull
2496 : Gecko_GetBindingParent(RawGeckoElementBorrowed aElement)
2497 0 : {
2498 104091 : nsIContent* parent = aElement->GetBindingParent();
2499 : return parent ? parent->AsElement() : nullptr;
2500 : }
2501 :
2502 6587 : RawServoAuthorStylesBorrowedOrNull
2503 : Gecko_XBLBinding_GetRawServoStyles(RawGeckoXBLBindingBorrowed aXBLBinding)
2504 0 : {
2505 : return aXBLBinding->GetServoStyles();
2506 : }
2507 :
2508 0 : bool
2509 : Gecko_XBLBinding_InheritsStyle(RawGeckoXBLBindingBorrowed aXBLBinding)
2510 0 : {
2511 : return aXBLBinding->InheritsStyle();
2512 : }
2513 1 :
2514 : static StaticRefPtr<UACacheReporter> gUACacheReporter;
2515 :
2516 0 : void
2517 : InitializeServo()
2518 1 : {
2519 0 : URLExtraData::InitDummy();
2520 : Servo_Initialize(URLExtraData::Dummy());
2521 2 :
2522 0 : gUACacheReporter = new UACacheReporter();
2523 : RegisterWeakMemoryReporter(gUACacheReporter);
2524 0 :
2525 0 : sServoFFILock = new RWLock("Servo::FFILock");
2526 : }
2527 :
2528 0 : void
2529 : ShutdownServo()
2530 0 : {
2531 : MOZ_ASSERT(sServoFFILock);
2532 0 :
2533 0 : UnregisterWeakMemoryReporter(gUACacheReporter);
2534 : gUACacheReporter = nullptr;
2535 0 :
2536 0 : delete sServoFFILock;
2537 0 : Servo_Shutdown();
2538 : }
2539 :
2540 : namespace mozilla {
2541 :
2542 0 : void
2543 : AssertIsMainThreadOrServoFontMetricsLocked()
2544 0 : {
2545 0 : if (!NS_IsMainThread()) {
2546 : MOZ_ASSERT(sServoFFILock &&
2547 : sServoFFILock->LockedForWritingByCurrentThread());
2548 0 : }
2549 : }
2550 :
2551 : } // namespace mozilla
2552 :
2553 2 : GeckoFontMetrics
2554 : Gecko_GetFontMetrics(RawGeckoPresContextBorrowed aPresContext,
2555 : bool aIsVertical,
2556 : const nsStyleFont* aFont,
2557 : nscoord aFontSize,
2558 : bool aUseUserFontSet)
2559 0 : {
2560 : AutoWriteLock guard(*sServoFFILock);
2561 : GeckoFontMetrics ret;
2562 :
2563 : // Getting font metrics can require some main thread only work to be
2564 : // done, such as work that needs to touch non-threadsafe refcounted
2565 : // objects (like the DOM FontFace/FontFaceSet objects), network loads, etc.
2566 : //
2567 : // To handle this work, font code checks whether we are in a Servo traversal
2568 : // and if so, appends PostTraversalTasks to the current ServoStyleSet
2569 : // to be performed immediately after the traversal is finished. This
2570 : // works well for starting downloadable font loads, since we don't have
2571 : // those fonts available to get metrics for anyway. Platform fonts and
2572 : // ArrayBuffer-backed FontFace objects are handled synchronously.
2573 2 :
2574 2 : nsPresContext* presContext = const_cast<nsPresContext*>(aPresContext);
2575 4 : presContext->SetUsesExChUnits(true);
2576 : RefPtr<nsFontMetrics> fm = nsLayoutUtils::GetMetricsFor(
2577 4 : presContext, aIsVertical, aFont, aFontSize, aUseUserFontSet,
2578 : nsLayoutUtils::FlushUserFontSet::No);
2579 0 :
2580 : ret.mXSize = fm->XHeight();
2581 0 : gfxFloat zeroWidth = fm->GetThebesFontGroup()->GetFirstValidFont()->
2582 2 : GetMetrics(fm->Orientation()).zeroOrAveCharWidth;
2583 0 : ret.mChSize = ceil(aPresContext->AppUnitsPerDevPixel() * zeroWidth);
2584 : return ret;
2585 : }
2586 :
2587 0 : int32_t
2588 : Gecko_GetAppUnitsPerPhysicalInch(RawGeckoPresContextBorrowed aPresContext)
2589 0 : {
2590 0 : nsPresContext* presContext = const_cast<nsPresContext*>(aPresContext);
2591 : return presContext->DeviceContext()->AppUnitsPerPhysicalInch();
2592 : }
2593 0 :
2594 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(SheetLoadDataHolder, SheetLoadDataHolder);
2595 :
2596 0 : void
2597 : Gecko_StyleSheet_FinishAsyncParse(SheetLoadDataHolder* aData,
2598 : RawServoStyleSheetContentsStrong aSheetContents)
2599 0 : {
2600 0 : RefPtr<SheetLoadDataHolder> loadData = aData;
2601 0 : RefPtr<RawServoStyleSheetContents> sheetContents = aSheetContents.Consume();
2602 0 : NS_DispatchToMainThread(NS_NewRunnableFunction(__func__,
2603 0 : [d = std::move(loadData),
2604 0 : s = std::move(sheetContents)]() mutable {
2605 0 : MOZ_ASSERT(NS_IsMainThread());
2606 0 : d->get()->mSheet->FinishAsyncParse(s.forget());
2607 0 : }));
2608 : }
2609 :
2610 0 : static already_AddRefed<StyleSheet>
2611 : LoadImportSheet(css::Loader* aLoader,
2612 : StyleSheet* aParent,
2613 : SheetLoadData* aParentLoadData,
2614 : css::LoaderReusableStyleSheets* aReusableSheets,
2615 : css::URLValue* aURL,
2616 : already_AddRefed<RawServoMediaList> aMediaList)
2617 8 : {
2618 8 : MOZ_ASSERT(NS_IsMainThread());
2619 8 : MOZ_ASSERT(aLoader, "Should've catched this before");
2620 8 : MOZ_ASSERT(aParent, "Only used for @import, so parent should exist!");
2621 : MOZ_ASSERT(aURL, "Invalid URLs shouldn't be loaded!");
2622 32 :
2623 0 : RefPtr<dom::MediaList> media = new MediaList(std::move(aMediaList));
2624 0 : nsCOMPtr<nsIURI> uri = aURL->GetURI();
2625 : nsresult rv = uri ? NS_OK : NS_ERROR_FAILURE;
2626 0 :
2627 8 : StyleSheet* previousFirstChild = aParent->GetFirstChild();
2628 0 : if (NS_SUCCEEDED(rv)) {
2629 : rv = aLoader->LoadChildSheet(aParent, aParentLoadData, uri, media, aReusableSheets);
2630 : }
2631 24 :
2632 0 : if (NS_FAILED(rv) ||
2633 0 : !aParent->GetFirstChild() ||
2634 : aParent->GetFirstChild() == previousFirstChild) {
2635 : // Servo and Gecko have different ideas of what a valid URL is, so we might
2636 : // get in here with a URL string that NS_NewURI can't handle. We may also
2637 : // reach here via an import cycle. For the import cycle case, we need some
2638 : // sheet object per spec, even if its empty. DevTools uses the URI to
2639 : // realize it has hit an import cycle, so we mark it complete to make the
2640 : // sheet readable from JS.
2641 0 : RefPtr<StyleSheet> emptySheet =
2642 : aParent->CreateEmptyChildSheet(media.forget());
2643 : // Make a dummy URI if we don't have one because some methods assume
2644 0 : // non-null URIs.
2645 0 : if (!uri) {
2646 : NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("about:invalid"));
2647 0 : }
2648 0 : emptySheet->SetURIs(uri, uri, uri);
2649 0 : emptySheet->SetPrincipal(aURL->mExtraData->GetPrincipal());
2650 0 : emptySheet->SetComplete();
2651 0 : aParent->PrependStyleSheet(emptySheet);
2652 : return emptySheet.forget();
2653 : }
2654 :
2655 0 : RefPtr<StyleSheet> sheet =
2656 0 : static_cast<StyleSheet*>(aParent->GetFirstChild());
2657 : return sheet.forget();
2658 : }
2659 :
2660 8 : StyleSheet*
2661 : Gecko_LoadStyleSheet(css::Loader* aLoader,
2662 : StyleSheet* aParent,
2663 : SheetLoadData* aParentLoadData,
2664 : css::LoaderReusableStyleSheets* aReusableSheets,
2665 : ServoBundledURI aServoURL,
2666 : RawServoMediaListStrong aMediaList)
2667 8 : {
2668 24 : MOZ_ASSERT(NS_IsMainThread());
2669 16 : RefPtr<css::URLValue> url = aServoURL.IntoCssUrl();
2670 32 : return LoadImportSheet(aLoader, aParent, aParentLoadData, aReusableSheets,
2671 : url, aMediaList.Consume()).take();
2672 : }
2673 :
2674 0 : void
2675 : Gecko_LoadStyleSheetAsync(css::SheetLoadDataHolder* aParentData,
2676 : ServoBundledURI aServoURL,
2677 : RawServoMediaListStrong aMediaList,
2678 : RawServoImportRuleStrong aImportRule)
2679 0 : {
2680 0 : RefPtr<SheetLoadDataHolder> loadData = aParentData;
2681 0 : RefPtr<css::URLValue> urlVal = aServoURL.IntoCssUrl();
2682 0 : RefPtr<RawServoMediaList> mediaList = aMediaList.Consume();
2683 0 : RefPtr<RawServoImportRule> importRule = aImportRule.Consume();
2684 0 : NS_DispatchToMainThread(NS_NewRunnableFunction(__func__,
2685 0 : [data = std::move(loadData),
2686 0 : url = std::move(urlVal),
2687 0 : media = std::move(mediaList),
2688 0 : import = std::move(importRule)]() mutable {
2689 0 : MOZ_ASSERT(NS_IsMainThread());
2690 : SheetLoadData* d = data->get();
2691 0 : RefPtr<StyleSheet> sheet =
2692 0 : LoadImportSheet(d->mLoader, d->mSheet, d, nullptr, url, media.forget());
2693 0 : Servo_ImportRule_SetSheet(import, sheet);
2694 0 : }));
2695 : }
2696 :
2697 0 : nsCSSKeyword
2698 : Gecko_LookupCSSKeyword(const uint8_t* aString, uint32_t aLength)
2699 0 : {
2700 0 : nsDependentCSubstring keyword(reinterpret_cast<const char*>(aString), aLength);
2701 : return nsCSSKeywords::LookupKeyword(keyword);
2702 : }
2703 :
2704 0 : const char*
2705 : Gecko_CSSKeywordString(nsCSSKeyword aKeyword, uint32_t* aLength)
2706 0 : {
2707 0 : MOZ_ASSERT(NS_IsMainThread());
2708 0 : MOZ_ASSERT(aLength);
2709 0 : const nsCString& value = nsCSSKeywords::GetStringValue(aKeyword);
2710 0 : *aLength = value.Length();
2711 : return value.get();
2712 : }
2713 :
2714 0 : void
2715 : Gecko_AddPropertyToSet(nsCSSPropertyIDSetBorrowedMut aPropertySet,
2716 : nsCSSPropertyID aProperty)
2717 0 : {
2718 0 : aPropertySet->AddProperty(aProperty);
2719 : }
2720 0 :
2721 : NS_IMPL_THREADSAFE_FFI_REFCOUNTING(nsCSSValueSharedList, CSSValueSharedList);
2722 :
2723 : #define STYLE_STRUCT(name) \
2724 : \
2725 : void \
2726 : Gecko_Construct_Default_nsStyle##name(nsStyle##name* ptr, \
2727 : const nsPresContext* pres_context) \
2728 : { \
2729 : new (ptr) nsStyle##name(pres_context); \
2730 : } \
2731 : \
2732 : void \
2733 : Gecko_CopyConstruct_nsStyle##name(nsStyle##name* ptr, \
2734 : const nsStyle##name* other) \
2735 : { \
2736 : new (ptr) nsStyle##name(*other); \
2737 : } \
2738 : \
2739 : void \
2740 : Gecko_Destroy_nsStyle##name(nsStyle##name* ptr) \
2741 : { \
2742 : ptr->~nsStyle##name(); \
2743 : }
2744 :
2745 3 : void
2746 : Gecko_RegisterProfilerThread(const char* name)
2747 3 : {
2748 3 : PROFILER_REGISTER_THREAD(name);
2749 : }
2750 :
2751 0 : void
2752 : Gecko_UnregisterProfilerThread()
2753 0 : {
2754 0 : PROFILER_UNREGISTER_THREAD();
2755 : }
2756 :
2757 0 : bool
2758 : Gecko_DocumentRule_UseForPresentation(RawGeckoPresContextBorrowed aPresContext,
2759 : const nsACString* aPattern,
2760 : css::URLMatchingFunction aURLMatchingFunction)
2761 0 : {
2762 : MOZ_ASSERT(NS_IsMainThread());
2763 0 :
2764 0 : nsIDocument *doc = aPresContext->Document();
2765 0 : nsIURI *docURI = doc->GetDocumentURI();
2766 0 : nsAutoCString docURISpec;
2767 : if (docURI) {
2768 0 : // If GetSpec fails (due to OOM) just skip these URI-specific CSS rules.
2769 0 : nsresult rv = docURI->GetSpec(docURISpec);
2770 : NS_ENSURE_SUCCESS(rv, false);
2771 : }
2772 :
2773 0 : return CSSMozDocumentRule::Match(doc, docURI, docURISpec, *aPattern,
2774 : aURLMatchingFunction);
2775 : }
2776 :
2777 3 : void
2778 : Gecko_SetJemallocThreadLocalArena(bool enabled)
2779 : {
2780 3 : #if defined(MOZ_MEMORY)
2781 : jemalloc_thread_local_arena(enabled);
2782 3 : #endif
2783 : }
2784 :
2785 : #include "nsStyleStructList.h"
2786 :
2787 : #undef STYLE_STRUCT
2788 :
2789 0 : bool
2790 : Gecko_ErrorReportingEnabled(const StyleSheet* aSheet, const Loader* aLoader)
2791 0 : {
2792 : return ErrorReporter::ShouldReportErrors(aSheet, aLoader);
2793 : }
2794 :
2795 0 : void
2796 : Gecko_ReportUnexpectedCSSError(const StyleSheet* aSheet,
2797 : const Loader* aLoader,
2798 : nsIURI* aURI,
2799 : const char* message,
2800 : const char* param,
2801 : uint32_t paramLen,
2802 : const char* prefix,
2803 : const char* prefixParam,
2804 : uint32_t prefixParamLen,
2805 : const char* suffix,
2806 : const char* source,
2807 : uint32_t sourceLen,
2808 : uint32_t lineNumber,
2809 : uint32_t colNumber)
2810 0 : {
2811 : MOZ_RELEASE_ASSERT(NS_IsMainThread());
2812 0 :
2813 : ErrorReporter reporter(aSheet, aLoader, aURI);
2814 0 :
2815 0 : if (prefix) {
2816 0 : if (prefixParam) {
2817 0 : nsDependentCSubstring paramValue(prefixParam, prefixParamLen);
2818 0 : nsAutoString wideParam = NS_ConvertUTF8toUTF16(paramValue);
2819 : reporter.ReportUnexpectedUnescaped(prefix, wideParam);
2820 0 : } else {
2821 : reporter.ReportUnexpected(prefix);
2822 : }
2823 : }
2824 0 :
2825 0 : if (param) {
2826 0 : nsDependentCSubstring paramValue(param, paramLen);
2827 0 : nsAutoString wideParam = NS_ConvertUTF8toUTF16(paramValue);
2828 : reporter.ReportUnexpectedUnescaped(message, wideParam);
2829 0 : } else {
2830 : reporter.ReportUnexpected(message);
2831 : }
2832 0 :
2833 0 : if (suffix) {
2834 : reporter.ReportUnexpected(suffix);
2835 0 : }
2836 0 : nsDependentCSubstring sourceValue(source, sourceLen);
2837 0 : reporter.OutputError(lineNumber, colNumber, sourceValue);
2838 : }
2839 :
2840 0 : void
2841 : Gecko_AddBufferToCrashReport(const void* addr, size_t len)
2842 0 : {
2843 0 : MOZ_ASSERT(NS_IsMainThread());
2844 0 : nsCOMPtr<nsICrashReporter> cr = do_GetService("@mozilla.org/toolkit/crash-reporter;1");
2845 0 : NS_ENSURE_TRUE_VOID(cr);
2846 : cr->RegisterAppMemory((uint64_t) addr, len);
2847 : }
2848 :
2849 0 : void
2850 : Gecko_AnnotateCrashReport(const char* key_str, const char* value_str)
2851 0 : {
2852 0 : MOZ_ASSERT(NS_IsMainThread());
2853 0 : nsDependentCString key(key_str);
2854 0 : nsDependentCString value(value_str);
2855 0 : nsCOMPtr<nsICrashReporter> cr = do_GetService("@mozilla.org/toolkit/crash-reporter;1");
2856 0 : NS_ENSURE_TRUE_VOID(cr);
2857 : cr->AnnotateCrashReport(key, value);
2858 : }
2859 :
2860 1 : void
2861 : Gecko_ContentList_AppendAll(
2862 : nsSimpleContentList* aList,
2863 : const Element** aElements,
2864 : size_t aLength)
2865 1 : {
2866 4 : MOZ_ASSERT(NS_IsMainThread());
2867 1 : MOZ_ASSERT(aElements);
2868 1 : MOZ_ASSERT(aLength);
2869 : MOZ_ASSERT(aList);
2870 1 :
2871 : aList->SetCapacity(aLength);
2872 1 :
2873 24 : for (size_t i = 0; i < aLength; ++i) {
2874 : aList->AppendElement(const_cast<Element*>(aElements[i]));
2875 4 : }
2876 : }
2877 :
2878 8 : const nsTArray<Element*>*
2879 : Gecko_Document_GetElementsWithId(const nsIDocument* aDoc, nsAtom* aId)
2880 8 : {
2881 0 : MOZ_ASSERT(aDoc);
2882 : MOZ_ASSERT(aId);
2883 0 :
2884 : return aDoc->GetAllElementsForId(nsDependentAtomString(aId));
2885 : }
2886 :
2887 0 : const nsTArray<Element*>*
2888 : Gecko_ShadowRoot_GetElementsWithId(const ShadowRoot* aShadowRoot, nsAtom* aId)
2889 0 : {
2890 0 : MOZ_ASSERT(aShadowRoot);
2891 : MOZ_ASSERT(aId);
2892 0 :
2893 : return aShadowRoot->GetAllElementsForId(nsDependentAtomString(aId));
2894 : }
2895 :
2896 0 : bool
2897 : Gecko_GetBoolPrefValue(const char* aPrefName)
2898 11 : {
2899 0 : MOZ_ASSERT(NS_IsMainThread());
2900 : return Preferences::GetBool(aPrefName);
2901 : }
2902 :
2903 0 : bool
2904 : Gecko_IsInServoTraversal()
2905 0 : {
2906 : return ServoStyleSet::IsInServoTraversal();
2907 : }
2908 :
2909 710 : bool
2910 : Gecko_IsMainThread()
2911 710 : {
2912 0 : return NS_IsMainThread();
2913 : }
|