2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * Copyright (C) 2013 Apple Inc. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #include "core/testing/Internals.h"
30 #include "bindings/core/v8/ExceptionMessages.h"
31 #include "bindings/core/v8/ExceptionState.h"
32 #include "bindings/core/v8/ScriptFunction.h"
33 #include "bindings/core/v8/ScriptPromise.h"
34 #include "bindings/core/v8/ScriptPromiseResolver.h"
35 #include "bindings/core/v8/SerializedScriptValue.h"
36 #include "bindings/core/v8/SerializedScriptValueFactory.h"
37 #include "bindings/core/v8/V8IteratorResultValue.h"
38 #include "bindings/core/v8/V8ThrowException.h"
39 #include "core/HTMLNames.h"
40 #include "core/SVGNames.h"
41 #include "core/animation/AnimationTimeline.h"
42 #include "core/css/StyleSheetContents.h"
43 #include "core/css/resolver/StyleResolver.h"
44 #include "core/css/resolver/StyleResolverStats.h"
45 #include "core/css/resolver/ViewportStyleResolver.h"
46 #include "core/dom/ClientRect.h"
47 #include "core/dom/ClientRectList.h"
48 #include "core/dom/DOMArrayBuffer.h"
49 #include "core/dom/DOMPoint.h"
50 #include "core/dom/DOMStringList.h"
51 #include "core/dom/Document.h"
52 #include "core/dom/Element.h"
53 #include "core/dom/ExceptionCode.h"
54 #include "core/dom/Iterator.h"
55 #include "core/dom/NodeComputedStyle.h"
56 #include "core/dom/PseudoElement.h"
57 #include "core/dom/Range.h"
58 #include "core/dom/StaticNodeList.h"
59 #include "core/dom/StyleEngine.h"
60 #include "core/dom/TreeScope.h"
61 #include "core/dom/ViewportDescription.h"
62 #include "core/dom/shadow/ComposedTreeTraversal.h"
63 #include "core/dom/shadow/ElementShadow.h"
64 #include "core/dom/shadow/SelectRuleFeatureSet.h"
65 #include "core/dom/shadow/ShadowRoot.h"
66 #include "core/editing/Editor.h"
67 #include "core/editing/PlainTextRange.h"
68 #include "core/editing/SurroundingText.h"
69 #include "core/editing/iterators/TextIterator.h"
70 #include "core/editing/markers/DocumentMarker.h"
71 #include "core/editing/markers/DocumentMarkerController.h"
72 #include "core/editing/serializers/Serialization.h"
73 #include "core/editing/spellcheck/SpellCheckRequester.h"
74 #include "core/editing/spellcheck/SpellChecker.h"
75 #include "core/fetch/MemoryCache.h"
76 #include "core/fetch/ResourceFetcher.h"
77 #include "core/frame/EventHandlerRegistry.h"
78 #include "core/frame/FrameConsole.h"
79 #include "core/frame/FrameView.h"
80 #include "core/frame/LocalDOMWindow.h"
81 #include "core/frame/LocalFrame.h"
82 #include "core/frame/Settings.h"
83 #include "core/html/HTMLContentElement.h"
84 #include "core/html/HTMLIFrameElement.h"
85 #include "core/html/HTMLImageElement.h"
86 #include "core/html/HTMLInputElement.h"
87 #include "core/html/HTMLMediaElement.h"
88 #include "core/html/HTMLSelectElement.h"
89 #include "core/html/HTMLTextAreaElement.h"
90 #include "core/html/canvas/CanvasFontCache.h"
91 #include "core/html/canvas/CanvasRenderingContext.h"
92 #include "core/html/forms/FormController.h"
93 #include "core/html/shadow/ShadowElementNames.h"
94 #include "core/html/shadow/TextControlInnerElements.h"
95 #include "core/input/EventHandler.h"
96 #include "core/inspector/ConsoleMessageStorage.h"
97 #include "core/inspector/InspectorConsoleAgent.h"
98 #include "core/inspector/InspectorFrontendChannel.h"
99 #include "core/inspector/InspectorInstrumentation.h"
100 #include "core/inspector/InstanceCounters.h"
101 #include "core/inspector/InstrumentingAgents.h"
102 #include "core/layout/LayoutMenuList.h"
103 #include "core/layout/LayoutObject.h"
104 #include "core/layout/LayoutTreeAsText.h"
105 #include "core/layout/LayoutView.h"
106 #include "core/layout/compositing/CompositedDeprecatedPaintLayerMapping.h"
107 #include "core/layout/compositing/DeprecatedPaintLayerCompositor.h"
108 #include "core/loader/FrameLoader.h"
109 #include "core/loader/HistoryItem.h"
110 #include "core/page/ChromeClient.h"
111 #include "core/page/FocusController.h"
112 #include "core/page/NetworkStateNotifier.h"
113 #include "core/page/Page.h"
114 #include "core/page/PrintContext.h"
115 #include "core/page/scrolling/ScrollState.h"
116 #include "core/paint/DeprecatedPaintLayer.h"
117 #include "core/svg/SVGImageElement.h"
118 #include "core/testing/DictionaryTest.h"
119 #include "core/testing/GCObservation.h"
120 #include "core/testing/InternalRuntimeFlags.h"
121 #include "core/testing/InternalSettings.h"
122 #include "core/testing/LayerRect.h"
123 #include "core/testing/LayerRectList.h"
124 #include "core/testing/PrivateScriptTest.h"
125 #include "core/testing/TypeConversions.h"
126 #include "core/testing/UnionTypesTest.h"
127 #include "core/workers/WorkerThread.h"
128 #include "platform/Cursor.h"
129 #include "platform/Language.h"
130 #include "platform/PlatformKeyboardEvent.h"
131 #include "platform/RuntimeEnabledFeatures.h"
132 #include "platform/TraceEvent.h"
133 #include "platform/geometry/IntRect.h"
134 #include "platform/geometry/LayoutRect.h"
135 #include "platform/graphics/GraphicsLayer.h"
136 #include "platform/graphics/filters/FilterOperation.h"
137 #include "platform/graphics/filters/FilterOperations.h"
138 #include "platform/heap/Handle.h"
139 #include "platform/weborigin/SchemeRegistry.h"
140 #include "public/platform/Platform.h"
141 #include "public/platform/WebConnectionType.h"
142 #include "public/platform/WebGraphicsContext3D.h"
143 #include "public/platform/WebGraphicsContext3DProvider.h"
144 #include "public/platform/WebLayer.h"
145 #include "wtf/InstanceCounter.h"
146 #include "wtf/PassOwnPtr.h"
147 #include "wtf/dtoa.h"
148 #include "wtf/text/StringBuffer.h"
155 class InternalsIterationSource final
: public ValueIterable
<int>::IterationSource
{
157 bool next(ScriptState
* scriptState
, int& value
, ExceptionState
& exceptionState
) override
161 value
= m_index
* m_index
;
168 static bool markerTypesFrom(const String
& markerType
, DocumentMarker::MarkerTypes
& result
)
170 if (markerType
.isEmpty() || equalIgnoringCase(markerType
, "all"))
171 result
= DocumentMarker::AllMarkers();
172 else if (equalIgnoringCase(markerType
, "Spelling"))
173 result
= DocumentMarker::Spelling
;
174 else if (equalIgnoringCase(markerType
, "Grammar"))
175 result
= DocumentMarker::Grammar
;
176 else if (equalIgnoringCase(markerType
, "TextMatch"))
177 result
= DocumentMarker::TextMatch
;
184 static SpellCheckRequester
* spellCheckRequester(Document
* document
)
186 if (!document
|| !document
->frame())
188 return &document
->frame()->spellChecker().spellCheckRequester();
191 const char* Internals::internalsId
= "internals";
193 Internals
* Internals::create(ScriptState
* scriptState
)
195 return new Internals(scriptState
);
198 Internals::~Internals()
202 void Internals::resetToConsistentState(Page
* page
)
206 page
->setDeviceScaleFactor(1);
207 page
->setIsCursorVisible(true);
208 page
->setPageScaleFactor(1);
209 page
->deprecatedLocalMainFrame()->view()->layoutViewportScrollableArea()->setScrollPosition(IntPoint(0, 0), ProgrammaticScroll
);
210 overrideUserPreferredLanguages(Vector
<AtomicString
>());
211 if (!page
->deprecatedLocalMainFrame()->spellChecker().isContinuousSpellCheckingEnabled())
212 page
->deprecatedLocalMainFrame()->spellChecker().toggleContinuousSpellChecking();
213 if (page
->deprecatedLocalMainFrame()->editor().isOverwriteModeEnabled())
214 page
->deprecatedLocalMainFrame()->editor().toggleOverwriteModeEnabled();
216 if (ScrollingCoordinator
* scrollingCoordinator
= page
->scrollingCoordinator())
217 scrollingCoordinator
->reset();
219 page
->deprecatedLocalMainFrame()->view()->clear();
220 PlatformKeyboardEvent::setCurrentCapsLockState(PlatformKeyboardEvent::OverrideCapsLockState::Default
);
223 Internals::Internals(ScriptState
* scriptState
)
224 : ContextLifecycleObserver(scriptState
->executionContext())
225 , m_runtimeFlags(InternalRuntimeFlags::create())
229 Document
* Internals::contextDocument() const
231 return toDocument(executionContext());
234 LocalFrame
* Internals::frame() const
236 if (!contextDocument())
238 return contextDocument()->frame();
241 InternalSettings
* Internals::settings() const
243 Document
* document
= contextDocument();
246 Page
* page
= document
->page();
249 return InternalSettings::from(*page
);
252 InternalRuntimeFlags
* Internals::runtimeFlags() const
254 return m_runtimeFlags
.get();
257 unsigned Internals::workerThreadCount() const
259 return WorkerThread::workerThreadCount();
262 String
Internals::address(Node
* node
)
265 sprintf(buf
, "%p", node
);
270 GCObservation
* Internals::observeGC(ScriptValue scriptValue
)
272 v8::Local
<v8::Value
> observedValue
= scriptValue
.v8Value();
273 ASSERT(!observedValue
.IsEmpty());
274 if (observedValue
->IsNull() || observedValue
->IsUndefined()) {
275 V8ThrowException::throwTypeError(v8::Isolate::GetCurrent(), "value to observe is null or undefined");
279 return GCObservation::create(observedValue
);
282 unsigned Internals::updateStyleAndReturnAffectedElementCount(ExceptionState
& exceptionState
) const
284 Document
* document
= contextDocument();
286 exceptionState
.throwDOMException(InvalidAccessError
, "No context document is available.");
290 unsigned beforeCount
= document
->styleEngine().resolverAccessCount();
291 document
->updateLayoutTreeIfNeeded();
292 return document
->styleEngine().resolverAccessCount() - beforeCount
;
295 unsigned Internals::needsLayoutCount(ExceptionState
& exceptionState
) const
297 LocalFrame
* contextFrame
= frame();
299 exceptionState
.throwDOMException(InvalidAccessError
, "No context frame is available.");
304 unsigned needsLayoutObjects
;
305 unsigned totalObjects
;
306 contextFrame
->view()->countObjectsNeedingLayout(needsLayoutObjects
, totalObjects
, isPartial
);
307 return needsLayoutObjects
;
310 unsigned Internals::hitTestCount(Document
* doc
, ExceptionState
& exceptionState
) const
313 exceptionState
.throwDOMException(InvalidAccessError
, "Must supply document to check");
317 return doc
->layoutView()->hitTestCount();
320 unsigned Internals::hitTestCacheHits(Document
* doc
, ExceptionState
& exceptionState
) const
323 exceptionState
.throwDOMException(InvalidAccessError
, "Must supply document to check");
327 return doc
->layoutView()->hitTestCacheHits();
330 Element
* Internals::elementFromPoint(Document
* doc
, double x
, double y
, bool ignoreClipping
, bool allowChildFrameContent
, ExceptionState
& exceptionState
) const
333 exceptionState
.throwDOMException(InvalidAccessError
, "Must supply document to check");
337 if (!doc
->layoutView())
340 HitTestRequest::HitTestRequestType hitType
= HitTestRequest::ReadOnly
| HitTestRequest::Active
;
342 hitType
|= HitTestRequest::IgnoreClipping
;
343 if (allowChildFrameContent
)
344 hitType
|= HitTestRequest::AllowChildFrameContent
;
346 HitTestRequest
request(hitType
);
348 return doc
->hitTestPoint(x
, y
, request
);
351 void Internals::clearHitTestCache(Document
* doc
, ExceptionState
& exceptionState
) const
354 exceptionState
.throwDOMException(InvalidAccessError
, "Must supply document to check");
358 if (!doc
->layoutView())
361 doc
->layoutView()->clearHitTestCache();
364 bool Internals::isPreloaded(const String
& url
)
366 return isPreloadedBy(url
, contextDocument());
369 bool Internals::isPreloadedBy(const String
& url
, Document
* document
)
373 return document
->fetcher()->isPreloaded(document
->completeURL(url
));
376 bool Internals::isLoadingFromMemoryCache(const String
& url
)
378 if (!contextDocument())
380 const String cacheIdentifier
= contextDocument()->fetcher()->getCacheIdentifier();
381 Resource
* resource
= memoryCache()->resourceForURL(contextDocument()->completeURL(url
), cacheIdentifier
);
382 return resource
&& resource
->status() == Resource::Cached
;
385 bool Internals::isSharingStyle(Element
* element1
, Element
* element2
) const
387 ASSERT(element1
&& element2
);
388 return element1
->computedStyle() == element2
->computedStyle();
391 bool Internals::isValidContentSelect(Element
* insertionPoint
, ExceptionState
& exceptionState
)
393 ASSERT(insertionPoint
);
394 if (!insertionPoint
->isInsertionPoint()) {
395 exceptionState
.throwDOMException(InvalidAccessError
, "The element is not an insertion point.");
399 return isHTMLContentElement(*insertionPoint
) && toHTMLContentElement(*insertionPoint
).isSelectValid();
402 Node
* Internals::treeScopeRootNode(Node
* node
)
405 return &node
->treeScope().rootNode();
408 Node
* Internals::parentTreeScope(Node
* node
)
411 const TreeScope
* parentTreeScope
= node
->treeScope().parentTreeScope();
412 return parentTreeScope
? &parentTreeScope
->rootNode() : 0;
415 bool Internals::hasSelectorForIdInShadow(Element
* host
, const AtomicString
& idValue
, ExceptionState
& exceptionState
)
418 if (!host
->shadow()) {
419 exceptionState
.throwDOMException(InvalidAccessError
, "The host element does not have a shadow.");
423 return host
->shadow()->ensureSelectFeatureSet().hasSelectorForId(idValue
);
426 bool Internals::hasSelectorForClassInShadow(Element
* host
, const AtomicString
& className
, ExceptionState
& exceptionState
)
429 if (!host
->shadow()) {
430 exceptionState
.throwDOMException(InvalidAccessError
, "The host element does not have a shadow.");
434 return host
->shadow()->ensureSelectFeatureSet().hasSelectorForClass(className
);
437 bool Internals::hasSelectorForAttributeInShadow(Element
* host
, const AtomicString
& attributeName
, ExceptionState
& exceptionState
)
440 if (!host
->shadow()) {
441 exceptionState
.throwDOMException(InvalidAccessError
, "The host element does not have a shadow.");
445 return host
->shadow()->ensureSelectFeatureSet().hasSelectorForAttribute(attributeName
);
448 unsigned short Internals::compareTreeScopePosition(const Node
* node1
, const Node
* node2
, ExceptionState
& exceptionState
) const
450 ASSERT(node1
&& node2
);
451 const TreeScope
* treeScope1
= node1
->isDocumentNode() ? static_cast<const TreeScope
*>(toDocument(node1
)) :
452 node1
->isShadowRoot() ? static_cast<const TreeScope
*>(toShadowRoot(node1
)) : 0;
453 const TreeScope
* treeScope2
= node2
->isDocumentNode() ? static_cast<const TreeScope
*>(toDocument(node2
)) :
454 node2
->isShadowRoot() ? static_cast<const TreeScope
*>(toShadowRoot(node2
)) : 0;
455 if (!treeScope1
|| !treeScope2
) {
456 exceptionState
.throwDOMException(InvalidAccessError
, String::format("The %s node is neither a document node, nor a shadow root.", treeScope1
? "second" : "first"));
459 return treeScope1
->comparePosition(*treeScope2
);
462 void Internals::pauseAnimations(double pauseTime
, ExceptionState
& exceptionState
)
465 exceptionState
.throwDOMException(InvalidAccessError
, ExceptionMessages::indexExceedsMinimumBound("pauseTime", pauseTime
, 0.0));
469 frame()->view()->updateAllLifecyclePhases();
470 frame()->document()->timeline().pauseAnimationsForTesting(pauseTime
);
473 bool Internals::isCompositedAnimation(Animation
* animation
)
475 return animation
->hasActiveAnimationsOnCompositor();
478 void Internals::disableCompositedAnimation(Animation
* animation
)
480 animation
->disableCompositedAnimationForTesting();
483 void Internals::advanceTimeForImage(Element
* image
, double deltaTimeInSeconds
, ExceptionState
& exceptionState
)
486 if (deltaTimeInSeconds
< 0) {
487 exceptionState
.throwDOMException(InvalidAccessError
, ExceptionMessages::indexExceedsMinimumBound("deltaTimeInSeconds", deltaTimeInSeconds
, 0.0));
491 ImageResource
* resource
= nullptr;
492 if (isHTMLImageElement(*image
)) {
493 resource
= toHTMLImageElement(*image
).cachedImage();
494 } else if (isSVGImageElement(*image
)) {
495 resource
= toSVGImageElement(*image
).cachedImage();
497 exceptionState
.throwDOMException(InvalidAccessError
, "The element provided is not a image element.");
501 if (!resource
|| !resource
->hasImage()) {
502 exceptionState
.throwDOMException(InvalidAccessError
, "The image resource is not available.");
506 Image
* imageData
= resource
->image();
507 if (!imageData
->isBitmapImage()) {
508 exceptionState
.throwDOMException(InvalidAccessError
, "The image resource is not a BitmapImage type.");
512 imageData
->advanceTime(deltaTimeInSeconds
);
515 void Internals::advanceImageAnimation(Element
* image
, ExceptionState
& exceptionState
)
519 ImageResource
* resource
= nullptr;
520 if (isHTMLImageElement(*image
)) {
521 resource
= toHTMLImageElement(*image
).cachedImage();
522 } else if (isSVGImageElement(*image
)) {
523 resource
= toSVGImageElement(*image
).cachedImage();
525 exceptionState
.throwDOMException(InvalidAccessError
, "The element provided is not a image element.");
529 if (!resource
|| !resource
->hasImage()) {
530 exceptionState
.throwDOMException(InvalidAccessError
, "The image resource is not available.");
534 Image
* imageData
= resource
->image();
535 imageData
->advanceAnimationForTesting();
538 bool Internals::hasShadowInsertionPoint(const Node
* root
, ExceptionState
& exceptionState
) const
541 if (!root
->isShadowRoot()) {
542 exceptionState
.throwDOMException(InvalidAccessError
, "The node argument is not a shadow root.");
545 return toShadowRoot(root
)->containsShadowElements();
548 bool Internals::hasContentElement(const Node
* root
, ExceptionState
& exceptionState
) const
551 if (!root
->isShadowRoot()) {
552 exceptionState
.throwDOMException(InvalidAccessError
, "The node argument is not a shadow root.");
555 return toShadowRoot(root
)->containsContentElements();
558 size_t Internals::countElementShadow(const Node
* root
, ExceptionState
& exceptionState
) const
561 if (!root
->isShadowRoot()) {
562 exceptionState
.throwDOMException(InvalidAccessError
, "The node argument is not a shadow root.");
565 return toShadowRoot(root
)->childShadowRootCount();
568 Node
* Internals::nextSiblingInComposedTree(Node
* node
, ExceptionState
& exceptionState
)
571 if (!node
->canParticipateInComposedTree()) {
572 exceptionState
.throwDOMException(InvalidAccessError
, "The node argument doesn't particite in the composed tree.");
575 return ComposedTreeTraversal::nextSibling(*node
);
578 Node
* Internals::firstChildInComposedTree(Node
* node
, ExceptionState
& exceptionState
)
581 if (!node
->canParticipateInComposedTree()) {
582 exceptionState
.throwDOMException(InvalidAccessError
, "The node argument doesn't particite in the composed tree");
585 return ComposedTreeTraversal::firstChild(*node
);
588 Node
* Internals::lastChildInComposedTree(Node
* node
, ExceptionState
& exceptionState
)
591 if (!node
->canParticipateInComposedTree()) {
592 exceptionState
.throwDOMException(InvalidAccessError
, "The node argument doesn't particite in the composed tree.");
595 return ComposedTreeTraversal::lastChild(*node
);
598 Node
* Internals::nextInComposedTree(Node
* node
, ExceptionState
& exceptionState
)
601 if (!node
->canParticipateInComposedTree()) {
602 exceptionState
.throwDOMException(InvalidAccessError
, "The node argument doesn't particite in the composed tree.");
605 return ComposedTreeTraversal::next(*node
);
608 Node
* Internals::previousInComposedTree(Node
* node
, ExceptionState
& exceptionState
)
611 if (!node
->canParticipateInComposedTree()) {
612 exceptionState
.throwDOMException(InvalidAccessError
, "The node argument doesn't particite in the composed tree.");
615 return ComposedTreeTraversal::previous(*node
);
618 String
Internals::elementLayoutTreeAsText(Element
* element
, ExceptionState
& exceptionState
)
621 String representation
= externalRepresentation(element
);
622 if (representation
.isEmpty()) {
623 exceptionState
.throwDOMException(InvalidAccessError
, "The element provided has no external representation.");
627 return representation
;
630 PassRefPtrWillBeRawPtr
<CSSStyleDeclaration
> Internals::computedStyleIncludingVisitedInfo(Node
* node
) const
633 bool allowVisitedStyle
= true;
634 return CSSComputedStyleDeclaration::create(node
, allowVisitedStyle
);
637 PassRefPtrWillBeRawPtr
<ShadowRoot
> Internals::createUserAgentShadowRoot(Element
* host
)
640 return PassRefPtrWillBeRawPtr
<ShadowRoot
>(host
->ensureUserAgentShadowRoot());
643 ShadowRoot
* Internals::shadowRoot(Element
* host
)
645 // FIXME: Internals::shadowRoot() in tests should be converted to youngestShadowRoot() or oldestShadowRoot().
646 // https://bugs.webkit.org/show_bug.cgi?id=78465
647 return youngestShadowRoot(host
);
650 ShadowRoot
* Internals::youngestShadowRoot(Element
* host
)
653 if (ElementShadow
* shadow
= host
->shadow())
654 return shadow
->youngestShadowRoot();
658 ShadowRoot
* Internals::oldestShadowRoot(Element
* host
)
661 if (ElementShadow
* shadow
= host
->shadow())
662 return shadow
->oldestShadowRoot();
666 ShadowRoot
* Internals::youngerShadowRoot(Node
* shadow
, ExceptionState
& exceptionState
)
669 if (!shadow
->isShadowRoot()) {
670 exceptionState
.throwDOMException(InvalidAccessError
, "The node provided is not a shadow root.");
674 return toShadowRoot(shadow
)->youngerShadowRoot();
677 String
Internals::shadowRootType(const Node
* root
, ExceptionState
& exceptionState
) const
680 if (!root
->isShadowRoot()) {
681 exceptionState
.throwDOMException(InvalidAccessError
, "The node provided is not a shadow root.");
685 switch (toShadowRoot(root
)->type()) {
686 case ShadowRootType::UserAgent
:
687 return String("UserAgentShadowRoot");
688 case ShadowRootType::OpenByDefault
:
689 return String("OpenByDefaultShadowRoot");
690 case ShadowRootType::Open
:
691 return String("OpenShadowRoot");
692 case ShadowRootType::Closed
:
693 return String("ClosedShadowRoot");
695 ASSERT_NOT_REACHED();
696 return String("Unknown");
700 const AtomicString
& Internals::shadowPseudoId(Element
* element
)
703 return element
->shadowPseudoId();
706 String
Internals::visiblePlaceholder(Element
* element
)
708 if (element
&& isHTMLTextFormControlElement(*element
)) {
709 const HTMLTextFormControlElement
& textFormControlElement
= toHTMLTextFormControlElement(*element
);
710 if (!textFormControlElement
.isPlaceholderVisible())
712 if (HTMLElement
* placeholderElement
= textFormControlElement
.placeholderElement())
713 return placeholderElement
->textContent();
719 void Internals::selectColorInColorChooser(Element
* element
, const String
& colorValue
)
722 if (!isHTMLInputElement(*element
))
725 if (!color
.setFromString(colorValue
))
727 toHTMLInputElement(*element
).selectColorInColorChooser(color
);
730 void Internals::endColorChooser(Element
* element
)
733 if (!isHTMLInputElement(*element
))
735 toHTMLInputElement(*element
).endColorChooser();
738 bool Internals::hasAutofocusRequest(Document
* document
)
741 document
= contextDocument();
742 return document
->autofocusElement();
745 bool Internals::hasAutofocusRequest()
747 return hasAutofocusRequest(0);
750 Vector
<String
> Internals::formControlStateOfHistoryItem(ExceptionState
& exceptionState
)
752 HistoryItem
* mainItem
= frame()->loader().currentItem();
754 exceptionState
.throwDOMException(InvalidAccessError
, "No history item is available.");
755 return Vector
<String
>();
757 return mainItem
->documentState();
760 void Internals::setFormControlStateOfHistoryItem(const Vector
<String
>& state
, ExceptionState
& exceptionState
)
762 HistoryItem
* mainItem
= frame()->loader().currentItem();
764 exceptionState
.throwDOMException(InvalidAccessError
, "No history item is available.");
767 mainItem
->clearDocumentState();
768 mainItem
->setDocumentState(state
);
771 DOMWindow
* Internals::pagePopupWindow() const
773 Document
* document
= contextDocument();
776 if (Page
* page
= document
->page())
777 return page
->chromeClient().pagePopupWindowForTesting();
781 ClientRect
* Internals::absoluteCaretBounds(ExceptionState
& exceptionState
)
783 Document
* document
= contextDocument();
784 if (!document
|| !document
->frame()) {
785 exceptionState
.throwDOMException(InvalidAccessError
, document
? "The document's frame cannot be retrieved." : "No context document can be obtained.");
786 return ClientRect::create();
789 return ClientRect::create(document
->frame()->selection().absoluteCaretBounds());
792 ClientRect
* Internals::boundingBox(Element
* element
)
796 element
->document().updateLayoutIgnorePendingStylesheets();
797 LayoutObject
* layoutObject
= element
->layoutObject();
799 return ClientRect::create();
800 return ClientRect::create(layoutObject
->absoluteBoundingBoxRectIgnoringTransforms());
803 unsigned Internals::markerCountForNode(Node
* node
, const String
& markerType
, ExceptionState
& exceptionState
)
806 DocumentMarker::MarkerTypes markerTypes
= 0;
807 if (!markerTypesFrom(markerType
, markerTypes
)) {
808 exceptionState
.throwDOMException(SyntaxError
, "The marker type provided ('" + markerType
+ "') is invalid.");
812 return node
->document().markers().markersFor(node
, markerTypes
).size();
815 unsigned Internals::activeMarkerCountForNode(Node
* node
)
819 // Only TextMatch markers can be active.
820 DocumentMarker::MarkerType markerType
= DocumentMarker::TextMatch
;
821 DocumentMarkerVector markers
= node
->document().markers().markersFor(node
, markerType
);
823 unsigned activeMarkerCount
= 0;
824 for (const auto& marker
: markers
) {
825 if (marker
->activeMatch())
829 return activeMarkerCount
;
832 DocumentMarker
* Internals::markerAt(Node
* node
, const String
& markerType
, unsigned index
, ExceptionState
& exceptionState
)
835 DocumentMarker::MarkerTypes markerTypes
= 0;
836 if (!markerTypesFrom(markerType
, markerTypes
)) {
837 exceptionState
.throwDOMException(SyntaxError
, "The marker type provided ('" + markerType
+ "') is invalid.");
841 DocumentMarkerVector markers
= node
->document().markers().markersFor(node
, markerTypes
);
842 if (markers
.size() <= index
)
844 return markers
[index
];
847 PassRefPtrWillBeRawPtr
<Range
> Internals::markerRangeForNode(Node
* node
, const String
& markerType
, unsigned index
, ExceptionState
& exceptionState
)
850 DocumentMarker
* marker
= markerAt(node
, markerType
, index
, exceptionState
);
853 return Range::create(node
->document(), node
, marker
->startOffset(), node
, marker
->endOffset());
856 String
Internals::markerDescriptionForNode(Node
* node
, const String
& markerType
, unsigned index
, ExceptionState
& exceptionState
)
858 DocumentMarker
* marker
= markerAt(node
, markerType
, index
, exceptionState
);
861 return marker
->description();
864 void Internals::addTextMatchMarker(const Range
* range
, bool isActive
)
867 range
->ownerDocument().updateLayoutIgnorePendingStylesheets();
868 range
->ownerDocument().markers().addTextMatchMarker(range
, isActive
);
871 void Internals::setMarkersActive(Node
* node
, unsigned startOffset
, unsigned endOffset
, bool active
)
874 node
->document().markers().setMarkersActive(node
, startOffset
, endOffset
, active
);
877 void Internals::setMarkedTextMatchesAreHighlighted(Document
* document
, bool highlight
)
879 if (!document
|| !document
->frame())
882 document
->frame()->editor().setMarkedTextMatchesAreHighlighted(highlight
);
885 void Internals::setFrameViewPosition(Document
* document
, long x
, long y
, ExceptionState
& exceptionState
)
888 if (!document
->view()) {
889 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
893 FrameView
* frameView
= document
->view();
894 bool scrollbarsSuppressedOldValue
= frameView
->scrollbarsSuppressed();
896 frameView
->setScrollbarsSuppressed(false);
897 frameView
->setScrollOffsetFromInternals(IntPoint(x
, y
));
898 frameView
->setScrollbarsSuppressed(scrollbarsSuppressedOldValue
);
901 String
Internals::viewportAsText(Document
* document
, float, int availableWidth
, int availableHeight
, ExceptionState
& exceptionState
)
904 if (!document
->page()) {
905 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
909 document
->updateLayoutIgnorePendingStylesheets();
911 Page
* page
= document
->page();
913 // Update initial viewport size.
914 IntSize
initialViewportSize(availableWidth
, availableHeight
);
915 document
->page()->deprecatedLocalMainFrame()->view()->setFrameRect(IntRect(IntPoint::zero(), initialViewportSize
));
917 ViewportDescription description
= page
->viewportDescription();
918 PageScaleConstraints constraints
= description
.resolve(initialViewportSize
, Length());
920 constraints
.fitToContentsWidth(constraints
.layoutSize
.width(), availableWidth
);
921 constraints
.resolveAutoInitialScale();
923 StringBuilder builder
;
925 builder
.appendLiteral("viewport size ");
926 builder
.append(String::number(constraints
.layoutSize
.width()));
928 builder
.append(String::number(constraints
.layoutSize
.height()));
930 builder
.appendLiteral(" scale ");
931 builder
.append(String::number(constraints
.initialScale
));
932 builder
.appendLiteral(" with limits [");
933 builder
.append(String::number(constraints
.minimumScale
));
934 builder
.appendLiteral(", ");
935 builder
.append(String::number(constraints
.maximumScale
));
937 builder
.appendLiteral("] and userScalable ");
938 builder
.append(description
.userZoom
? "true" : "false");
940 return builder
.toString();
943 bool Internals::wasLastChangeUserEdit(Element
* textField
, ExceptionState
& exceptionState
)
946 if (isHTMLInputElement(*textField
))
947 return toHTMLInputElement(*textField
).lastChangeWasUserEdit();
949 if (isHTMLTextAreaElement(*textField
))
950 return toHTMLTextAreaElement(*textField
).lastChangeWasUserEdit();
952 exceptionState
.throwDOMException(InvalidNodeTypeError
, "The element provided is not a TEXTAREA.");
956 bool Internals::elementShouldAutoComplete(Element
* element
, ExceptionState
& exceptionState
)
959 if (isHTMLInputElement(*element
))
960 return toHTMLInputElement(*element
).shouldAutocomplete();
962 exceptionState
.throwDOMException(InvalidNodeTypeError
, "The element provided is not an INPUT.");
966 String
Internals::suggestedValue(Element
* element
, ExceptionState
& exceptionState
)
969 if (!element
->isFormControlElement()) {
970 exceptionState
.throwDOMException(InvalidNodeTypeError
, "The element provided is not a form control element.");
974 String suggestedValue
;
975 if (isHTMLInputElement(*element
))
976 suggestedValue
= toHTMLInputElement(*element
).suggestedValue();
978 if (isHTMLTextAreaElement(*element
))
979 suggestedValue
= toHTMLTextAreaElement(*element
).suggestedValue();
981 if (isHTMLSelectElement(*element
))
982 suggestedValue
= toHTMLSelectElement(*element
).suggestedValue();
984 return suggestedValue
;
987 void Internals::setSuggestedValue(Element
* element
, const String
& value
, ExceptionState
& exceptionState
)
990 if (!element
->isFormControlElement()) {
991 exceptionState
.throwDOMException(InvalidNodeTypeError
, "The element provided is not a form control element.");
995 if (isHTMLInputElement(*element
))
996 toHTMLInputElement(*element
).setSuggestedValue(value
);
998 if (isHTMLTextAreaElement(*element
))
999 toHTMLTextAreaElement(*element
).setSuggestedValue(value
);
1001 if (isHTMLSelectElement(*element
))
1002 toHTMLSelectElement(*element
).setSuggestedValue(value
);
1005 void Internals::setEditingValue(Element
* element
, const String
& value
, ExceptionState
& exceptionState
)
1008 if (!isHTMLInputElement(*element
)) {
1009 exceptionState
.throwDOMException(InvalidNodeTypeError
, "The element provided is not an INPUT.");
1013 toHTMLInputElement(*element
).setEditingValue(value
);
1016 void Internals::setAutofilled(Element
* element
, bool enabled
, ExceptionState
& exceptionState
)
1019 if (!element
->isFormControlElement()) {
1020 exceptionState
.throwDOMException(InvalidNodeTypeError
, "The element provided is not a form control element.");
1023 toHTMLFormControlElement(element
)->setAutofilled(enabled
);
1026 void Internals::scrollElementToRect(Element
* element
, long x
, long y
, long w
, long h
, ExceptionState
& exceptionState
)
1029 if (!element
->document().view()) {
1030 exceptionState
.throwDOMException(InvalidNodeTypeError
, element
? "No view can be obtained from the provided element's document." : ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
1034 FrameView
* mainFrame
= toLocalFrame(element
->document().page()->mainFrame())->view();
1035 mainFrame
->frame().document()->updateLayoutIgnorePendingStylesheets();
1037 FrameView
* elementView
= element
->document().view();
1038 IntRect boundsInRootFrame
= elementView
->contentsToRootFrame(pixelSnappedIntRect(element
->boundingBox()));
1039 IntRect boundsInRootContent
= mainFrame
->frameToContents(boundsInRootFrame
);
1040 mainFrame
->scrollableArea()->scrollIntoRect(LayoutRect(boundsInRootContent
), FloatRect(x
, y
, w
, h
));
1043 PassRefPtrWillBeRawPtr
<Range
> Internals::rangeFromLocationAndLength(Element
* scope
, int rangeLocation
, int rangeLength
)
1047 // TextIterator depends on Layout information, make sure layout it up to date.
1048 scope
->document().updateLayoutIgnorePendingStylesheets();
1050 return createRange(PlainTextRange(rangeLocation
, rangeLocation
+ rangeLength
).createRange(*scope
));
1053 unsigned Internals::locationFromRange(Element
* scope
, const Range
* range
)
1055 ASSERT(scope
&& range
);
1056 // PlainTextRange depends on Layout information, make sure layout it up to date.
1057 scope
->document().updateLayoutIgnorePendingStylesheets();
1059 return PlainTextRange::create(*scope
, *range
).start();
1062 unsigned Internals::lengthFromRange(Element
* scope
, const Range
* range
)
1064 ASSERT(scope
&& range
);
1065 // PlainTextRange depends on Layout information, make sure layout it up to date.
1066 scope
->document().updateLayoutIgnorePendingStylesheets();
1068 return PlainTextRange::create(*scope
, *range
).length();
1071 String
Internals::rangeAsText(const Range
* range
)
1074 return range
->text();
1077 // FIXME: The next four functions are very similar - combine them once
1078 // bestClickableNode/bestContextMenuNode have been combined..
1080 DOMPoint
* Internals::touchPositionAdjustedToBestClickableNode(long x
, long y
, long width
, long height
, Document
* document
, ExceptionState
& exceptionState
)
1083 if (!document
->frame()) {
1084 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
1088 document
->updateLayout();
1090 IntSize
radius(width
/ 2, height
/ 2);
1091 IntPoint
point(x
+ radius
.width(), y
+ radius
.height());
1093 EventHandler
& eventHandler
= document
->frame()->eventHandler();
1094 IntPoint hitTestPoint
= document
->frame()->view()->rootFrameToContents(point
);
1095 HitTestResult result
= eventHandler
.hitTestResultAtPoint(hitTestPoint
, HitTestRequest::ReadOnly
| HitTestRequest::Active
| HitTestRequest::ListBased
, LayoutSize(radius
));
1097 Node
* targetNode
= 0;
1098 IntPoint adjustedPoint
;
1100 bool foundNode
= eventHandler
.bestClickableNodeForHitTestResult(result
, adjustedPoint
, targetNode
);
1102 return DOMPoint::create(adjustedPoint
.x(), adjustedPoint
.y());
1107 Node
* Internals::touchNodeAdjustedToBestClickableNode(long x
, long y
, long width
, long height
, Document
* document
, ExceptionState
& exceptionState
)
1110 if (!document
->frame()) {
1111 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
1115 document
->updateLayout();
1117 IntSize
radius(width
/ 2, height
/ 2);
1118 IntPoint
point(x
+ radius
.width(), y
+ radius
.height());
1120 EventHandler
& eventHandler
= document
->frame()->eventHandler();
1121 IntPoint hitTestPoint
= document
->frame()->view()->rootFrameToContents(point
);
1122 HitTestResult result
= eventHandler
.hitTestResultAtPoint(hitTestPoint
, HitTestRequest::ReadOnly
| HitTestRequest::Active
| HitTestRequest::ListBased
, LayoutSize(radius
));
1124 Node
* targetNode
= 0;
1125 IntPoint adjustedPoint
;
1126 document
->frame()->eventHandler().bestClickableNodeForHitTestResult(result
, adjustedPoint
, targetNode
);
1130 DOMPoint
* Internals::touchPositionAdjustedToBestContextMenuNode(long x
, long y
, long width
, long height
, Document
* document
, ExceptionState
& exceptionState
)
1133 if (!document
->frame()) {
1134 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
1138 document
->updateLayout();
1140 IntSize
radius(width
/ 2, height
/ 2);
1141 IntPoint
point(x
+ radius
.width(), y
+ radius
.height());
1143 EventHandler
& eventHandler
= document
->frame()->eventHandler();
1144 IntPoint hitTestPoint
= document
->frame()->view()->rootFrameToContents(point
);
1145 HitTestResult result
= eventHandler
.hitTestResultAtPoint(hitTestPoint
, HitTestRequest::ReadOnly
| HitTestRequest::Active
| HitTestRequest::ListBased
, LayoutSize(radius
));
1147 Node
* targetNode
= 0;
1148 IntPoint adjustedPoint
;
1150 bool foundNode
= eventHandler
.bestContextMenuNodeForHitTestResult(result
, adjustedPoint
, targetNode
);
1152 return DOMPoint::create(adjustedPoint
.x(), adjustedPoint
.y());
1154 return DOMPoint::create(x
, y
);
1157 Node
* Internals::touchNodeAdjustedToBestContextMenuNode(long x
, long y
, long width
, long height
, Document
* document
, ExceptionState
& exceptionState
)
1160 if (!document
->frame()) {
1161 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
1165 document
->updateLayout();
1167 IntSize
radius(width
/ 2, height
/ 2);
1168 IntPoint
point(x
+ radius
.width(), y
+ radius
.height());
1170 EventHandler
& eventHandler
= document
->frame()->eventHandler();
1171 IntPoint hitTestPoint
= document
->frame()->view()->rootFrameToContents(point
);
1172 HitTestResult result
= eventHandler
.hitTestResultAtPoint(hitTestPoint
, HitTestRequest::ReadOnly
| HitTestRequest::Active
| HitTestRequest::ListBased
, LayoutSize(radius
));
1174 Node
* targetNode
= 0;
1175 IntPoint adjustedPoint
;
1176 eventHandler
.bestContextMenuNodeForHitTestResult(result
, adjustedPoint
, targetNode
);
1180 ClientRect
* Internals::bestZoomableAreaForTouchPoint(long x
, long y
, long width
, long height
, Document
* document
, ExceptionState
& exceptionState
)
1183 if (!document
->frame()) {
1184 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
1188 document
->updateLayout();
1190 IntSize
radius(width
/ 2, height
/ 2);
1191 IntPoint
point(x
+ radius
.width(), y
+ radius
.height());
1193 Node
* targetNode
= 0;
1194 IntRect zoomableArea
;
1195 bool foundNode
= document
->frame()->eventHandler().bestZoomableAreaForTouchPoint(point
, radius
, zoomableArea
, targetNode
);
1197 return ClientRect::create(zoomableArea
);
1203 int Internals::lastSpellCheckRequestSequence(Document
* document
, ExceptionState
& exceptionState
)
1205 SpellCheckRequester
* requester
= spellCheckRequester(document
);
1208 exceptionState
.throwDOMException(InvalidAccessError
, "No spell check requestor can be obtained for the provided document.");
1212 return requester
->lastRequestSequence();
1215 int Internals::lastSpellCheckProcessedSequence(Document
* document
, ExceptionState
& exceptionState
)
1217 SpellCheckRequester
* requester
= spellCheckRequester(document
);
1220 exceptionState
.throwDOMException(InvalidAccessError
, "No spell check requestor can be obtained for the provided document.");
1224 return requester
->lastProcessedSequence();
1227 Vector
<AtomicString
> Internals::userPreferredLanguages() const
1229 return blink::userPreferredLanguages();
1232 // Optimally, the bindings generator would pass a Vector<AtomicString> here but
1233 // this is not supported yet.
1234 void Internals::setUserPreferredLanguages(const Vector
<String
>& languages
)
1236 Vector
<AtomicString
> atomicLanguages
;
1237 for (size_t i
= 0; i
< languages
.size(); ++i
)
1238 atomicLanguages
.append(AtomicString(languages
[i
]));
1239 overrideUserPreferredLanguages(atomicLanguages
);
1242 unsigned Internals::activeDOMObjectCount(Document
* document
)
1245 return document
->activeDOMObjectCount();
1248 static unsigned eventHandlerCount(Document
& document
, EventHandlerRegistry::EventHandlerClass handlerClass
)
1250 if (!document
.frameHost())
1252 EventHandlerRegistry
* registry
= &document
.frameHost()->eventHandlerRegistry();
1254 const EventTargetSet
* targets
= registry
->eventHandlerTargets(handlerClass
);
1256 for (const auto& target
: *targets
)
1257 count
+= target
.value
;
1262 unsigned Internals::wheelEventHandlerCount(Document
* document
)
1265 return eventHandlerCount(*document
, EventHandlerRegistry::WheelEvent
);
1268 unsigned Internals::scrollEventHandlerCount(Document
* document
)
1271 return eventHandlerCount(*document
, EventHandlerRegistry::ScrollEvent
);
1274 unsigned Internals::touchEventHandlerCount(Document
* document
)
1277 return eventHandlerCount(*document
, EventHandlerRegistry::TouchEvent
);
1280 static DeprecatedPaintLayer
* findLayerForGraphicsLayer(DeprecatedPaintLayer
* searchRoot
, GraphicsLayer
* graphicsLayer
, IntSize
* layerOffset
, String
* layerType
)
1282 *layerOffset
= IntSize();
1283 if (searchRoot
->hasCompositedDeprecatedPaintLayerMapping() && graphicsLayer
== searchRoot
->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()) {
1284 // If the |graphicsLayer| sets the scrollingContent layer as its
1285 // scroll parent, consider it belongs to the scrolling layer and
1286 // mark the layer type as "scrolling".
1287 if (!searchRoot
->layoutObject()->hasTransformRelatedProperty() && searchRoot
->scrollParent() && searchRoot
->parent() == searchRoot
->scrollParent()) {
1288 *layerType
= "scrolling";
1289 // For hit-test rect visualization to work, the hit-test rect should
1290 // be relative to the scrolling layer and in this case the hit-test
1291 // rect is relative to the element's own GraphicsLayer. So we will have
1292 // to adjust the rect to be relative to the scrolling layer here.
1293 // Only when the element's offsetParent == scroller's offsetParent we
1294 // can compute the element's relative position to the scrolling content
1296 if (searchRoot
->layoutObject()->offsetParent() == searchRoot
->parent()->layoutObject()->offsetParent()) {
1297 LayoutBoxModelObject
* current
= searchRoot
->layoutObject();
1298 LayoutBoxModelObject
* parent
= searchRoot
->parent()->layoutObject();
1299 layerOffset
->setWidth((parent
->offsetLeft() - current
->offsetLeft()).toInt());
1300 layerOffset
->setHeight((parent
->offsetTop() - current
->offsetTop()).toInt());
1301 return searchRoot
->parent();
1306 DeprecatedPaintLayer::mapRectToPaintBackingCoordinates(searchRoot
->layoutObject(), rect
);
1307 *layerOffset
= IntSize(rect
.x(), rect
.y());
1311 // If the |graphicsLayer| is a scroller's scrollingContent layer,
1312 // consider this is a scrolling layer.
1313 GraphicsLayer
* layerForScrolling
= searchRoot
->scrollableArea() ? searchRoot
->scrollableArea()->layerForScrolling() : 0;
1314 if (graphicsLayer
== layerForScrolling
) {
1315 *layerType
= "scrolling";
1319 if (searchRoot
->compositingState() == PaintsIntoGroupedBacking
) {
1320 GraphicsLayer
* squashingLayer
= searchRoot
->groupedMapping()->squashingLayer();
1321 if (graphicsLayer
== squashingLayer
) {
1322 *layerType
="squashing";
1324 DeprecatedPaintLayer::mapRectToPaintBackingCoordinates(searchRoot
->layoutObject(), rect
);
1325 *layerOffset
= IntSize(rect
.x(), rect
.y());
1330 GraphicsLayer
* layerForHorizontalScrollbar
= searchRoot
->scrollableArea() ? searchRoot
->scrollableArea()->layerForHorizontalScrollbar() : 0;
1331 if (graphicsLayer
== layerForHorizontalScrollbar
) {
1332 *layerType
= "horizontalScrollbar";
1336 GraphicsLayer
* layerForVerticalScrollbar
= searchRoot
->scrollableArea() ? searchRoot
->scrollableArea()->layerForVerticalScrollbar() : 0;
1337 if (graphicsLayer
== layerForVerticalScrollbar
) {
1338 *layerType
= "verticalScrollbar";
1342 GraphicsLayer
* layerForScrollCorner
= searchRoot
->scrollableArea() ? searchRoot
->scrollableArea()->layerForScrollCorner() : 0;
1343 if (graphicsLayer
== layerForScrollCorner
) {
1344 *layerType
= "scrollCorner";
1348 // Search right to left to increase the chances that we'll choose the top-most layers in a
1349 // grouped mapping for squashing.
1350 for (DeprecatedPaintLayer
* child
= searchRoot
->lastChild(); child
; child
= child
->previousSibling()) {
1351 DeprecatedPaintLayer
* foundLayer
= findLayerForGraphicsLayer(child
, graphicsLayer
, layerOffset
, layerType
);
1359 // Given a vector of rects, merge those that are adjacent, leaving empty rects
1360 // in the place of no longer used slots. This is intended to simplify the list
1361 // of rects returned by an SkRegion (which have been split apart for sorting
1362 // purposes). No attempt is made to do this efficiently (eg. by relying on the
1363 // sort criteria of SkRegion).
1364 static void mergeRects(WebVector
<blink::WebRect
>& rects
)
1366 for (size_t i
= 0; i
< rects
.size(); ++i
) {
1367 if (rects
[i
].isEmpty())
1372 for (size_t j
= i
+1; j
< rects
.size(); ++j
) {
1373 if (rects
[j
].isEmpty())
1375 // Try to merge rects[j] into rects[i] along the 4 possible edges.
1376 if (rects
[i
].y
== rects
[j
].y
&& rects
[i
].height
== rects
[j
].height
) {
1377 if (rects
[i
].x
+ rects
[i
].width
== rects
[j
].x
) {
1378 rects
[i
].width
+= rects
[j
].width
;
1379 rects
[j
] = blink::WebRect();
1381 } else if (rects
[i
].x
== rects
[j
].x
+ rects
[j
].width
) {
1382 rects
[i
].x
= rects
[j
].x
;
1383 rects
[i
].width
+= rects
[j
].width
;
1384 rects
[j
] = blink::WebRect();
1387 } else if (rects
[i
].x
== rects
[j
].x
&& rects
[i
].width
== rects
[j
].width
) {
1388 if (rects
[i
].y
+ rects
[i
].height
== rects
[j
].y
) {
1389 rects
[i
].height
+= rects
[j
].height
;
1390 rects
[j
] = blink::WebRect();
1392 } else if (rects
[i
].y
== rects
[j
].y
+ rects
[j
].height
) {
1393 rects
[i
].y
= rects
[j
].y
;
1394 rects
[i
].height
+= rects
[j
].height
;
1395 rects
[j
] = blink::WebRect();
1404 static void accumulateLayerRectList(DeprecatedPaintLayerCompositor
* compositor
, GraphicsLayer
* graphicsLayer
, LayerRectList
* rects
)
1406 WebVector
<blink::WebRect
> layerRects
= graphicsLayer
->platformLayer()->touchEventHandlerRegion();
1407 if (!layerRects
.isEmpty()) {
1408 mergeRects(layerRects
);
1410 IntSize layerOffset
;
1411 DeprecatedPaintLayer
* paintLayer
= findLayerForGraphicsLayer(compositor
->rootLayer(), graphicsLayer
, &layerOffset
, &layerType
);
1412 Node
* node
= paintLayer
? paintLayer
->layoutObject()->node() : 0;
1413 for (size_t i
= 0; i
< layerRects
.size(); ++i
) {
1414 if (!layerRects
[i
].isEmpty()) {
1415 rects
->append(node
, layerType
, layerOffset
.width(), layerOffset
.height(), ClientRect::create(layerRects
[i
]));
1420 size_t numChildren
= graphicsLayer
->children().size();
1421 for (size_t i
= 0; i
< numChildren
; ++i
)
1422 accumulateLayerRectList(compositor
, graphicsLayer
->children()[i
], rects
);
1425 LayerRectList
* Internals::touchEventTargetLayerRects(Document
* document
, ExceptionState
& exceptionState
)
1428 if (!document
->view() || !document
->page() || document
!= contextDocument()) {
1429 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
1433 // Do any pending layout and compositing update (which may call touchEventTargetRectsChange) to ensure this
1434 // really takes any previous changes into account.
1435 forceCompositingUpdate(document
, exceptionState
);
1436 if (exceptionState
.hadException())
1439 if (LayoutView
* view
= document
->layoutView()) {
1440 if (DeprecatedPaintLayerCompositor
* compositor
= view
->compositor()) {
1441 if (GraphicsLayer
* rootLayer
= compositor
->rootGraphicsLayer()) {
1442 LayerRectList
* rects
= LayerRectList::create();
1443 accumulateLayerRectList(compositor
, rootLayer
, rects
);
1452 bool Internals::executeCommand(Document
* document
, const String
& name
, const String
& value
, ExceptionState
& exceptionState
)
1455 if (!document
->frame()) {
1456 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
1460 LocalFrame
* frame
= document
->frame();
1461 return frame
->editor().executeCommand(name
, value
);
1464 AtomicString
Internals::htmlNamespace()
1466 return HTMLNames::xhtmlNamespaceURI
;
1469 Vector
<AtomicString
> Internals::htmlTags()
1471 Vector
<AtomicString
> tags(HTMLNames::HTMLTagsCount
);
1472 OwnPtr
<const HTMLQualifiedName
*[]> qualifiedNames
= HTMLNames::getHTMLTags();
1473 for (size_t i
= 0; i
< HTMLNames::HTMLTagsCount
; ++i
)
1474 tags
[i
] = qualifiedNames
[i
]->localName();
1478 AtomicString
Internals::svgNamespace()
1480 return SVGNames::svgNamespaceURI
;
1483 Vector
<AtomicString
> Internals::svgTags()
1485 Vector
<AtomicString
> tags(SVGNames::SVGTagsCount
);
1486 OwnPtr
<const SVGQualifiedName
*[]> qualifiedNames
= SVGNames::getSVGTags();
1487 for (size_t i
= 0; i
< SVGNames::SVGTagsCount
; ++i
)
1488 tags
[i
] = qualifiedNames
[i
]->localName();
1492 PassRefPtrWillBeRawPtr
<StaticNodeList
> Internals::nodesFromRect(Document
* document
, int centerX
, int centerY
, unsigned topPadding
, unsigned rightPadding
,
1493 unsigned bottomPadding
, unsigned leftPadding
, bool ignoreClipping
, bool allowChildFrameContent
, ExceptionState
& exceptionState
) const
1496 if (!document
->frame() || !document
->frame()->view()) {
1497 exceptionState
.throwDOMException(InvalidAccessError
, "No view can be obtained from the provided document.");
1501 LocalFrame
* frame
= document
->frame();
1502 FrameView
* frameView
= document
->view();
1503 LayoutView
* layoutView
= document
->layoutView();
1508 float zoomFactor
= frame
->pageZoomFactor();
1509 LayoutPoint point
= roundedLayoutPoint(FloatPoint(centerX
* zoomFactor
+ frameView
->scrollX(), centerY
* zoomFactor
+ frameView
->scrollY()));
1511 HitTestRequest::HitTestRequestType hitType
= HitTestRequest::ReadOnly
| HitTestRequest::Active
| HitTestRequest::ListBased
;
1513 hitType
|= HitTestRequest::IgnoreClipping
;
1514 if (allowChildFrameContent
)
1515 hitType
|= HitTestRequest::AllowChildFrameContent
;
1517 HitTestRequest
request(hitType
);
1519 // When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
1520 if (!request
.ignoreClipping() && !frameView
->visibleContentRect().intersects(HitTestLocation::rectForPoint(point
, topPadding
, rightPadding
, bottomPadding
, leftPadding
)))
1523 WillBeHeapVector
<RefPtrWillBeMember
<Node
>> matches
;
1524 HitTestResult
result(request
, point
, topPadding
, rightPadding
, bottomPadding
, leftPadding
);
1525 layoutView
->hitTest(result
);
1526 copyToVector(result
.listBasedTestResult(), matches
);
1528 return StaticNodeList::adopt(matches
);
1531 bool Internals::hasSpellingMarker(Document
* document
, int from
, int length
)
1534 if (!document
->frame())
1537 return document
->frame()->spellChecker().selectionStartHasMarkerFor(DocumentMarker::Spelling
, from
, length
);
1540 void Internals::setContinuousSpellCheckingEnabled(bool enabled
)
1542 if (!contextDocument() || !contextDocument()->frame())
1545 if (enabled
!= contextDocument()->frame()->spellChecker().isContinuousSpellCheckingEnabled())
1546 contextDocument()->frame()->spellChecker().toggleContinuousSpellChecking();
1549 bool Internals::isOverwriteModeEnabled(Document
* document
)
1552 if (!document
->frame())
1555 return document
->frame()->editor().isOverwriteModeEnabled();
1558 void Internals::toggleOverwriteModeEnabled(Document
* document
)
1561 if (!document
->frame())
1564 document
->frame()->editor().toggleOverwriteModeEnabled();
1567 unsigned Internals::numberOfLiveNodes() const
1569 return InstanceCounters::counterValue(InstanceCounters::NodeCounter
);
1572 unsigned Internals::numberOfLiveDocuments() const
1574 return InstanceCounters::counterValue(InstanceCounters::DocumentCounter
);
1577 String
Internals::dumpRefCountedInstanceCounts() const
1579 return WTF::dumpRefCountedInstanceCounts();
1582 Vector
<String
> Internals::consoleMessageArgumentCounts(Document
* document
) const
1584 FrameHost
* host
= document
->frameHost();
1586 return Vector
<String
>();
1588 Vector
<unsigned> counts
= host
->consoleMessageStorage().argumentCounts();
1589 Vector
<String
> result(counts
.size());
1590 for (size_t i
= 0; i
< counts
.size(); i
++)
1591 result
[i
] = String::number(counts
[i
]);
1595 Vector
<unsigned long> Internals::setMemoryCacheCapacities(unsigned long minDeadBytes
, unsigned long maxDeadBytes
, unsigned long totalBytes
)
1597 Vector
<unsigned long> result
;
1598 result
.append(memoryCache()->minDeadCapacity());
1599 result
.append(memoryCache()->maxDeadCapacity());
1600 result
.append(memoryCache()->capacity());
1601 memoryCache()->setCapacities(minDeadBytes
, maxDeadBytes
, totalBytes
);
1605 bool Internals::hasGrammarMarker(Document
* document
, int from
, int length
)
1608 if (!document
->frame())
1611 return document
->frame()->spellChecker().selectionStartHasMarkerFor(DocumentMarker::Grammar
, from
, length
);
1614 unsigned Internals::numberOfScrollableAreas(Document
* document
)
1617 if (!document
->frame())
1621 LocalFrame
* frame
= document
->frame();
1622 if (frame
->view()->scrollableAreas())
1623 count
+= frame
->view()->scrollableAreas()->size();
1625 for (Frame
* child
= frame
->tree().firstChild(); child
; child
= child
->tree().nextSibling()) {
1626 if (child
->isLocalFrame() && toLocalFrame(child
)->view() && toLocalFrame(child
)->view()->scrollableAreas())
1627 count
+= toLocalFrame(child
)->view()->scrollableAreas()->size();
1633 bool Internals::isPageBoxVisible(Document
* document
, int pageNumber
)
1636 return document
->isPageBoxVisible(pageNumber
);
1639 String
Internals::layerTreeAsText(Document
* document
, ExceptionState
& exceptionState
) const
1641 return layerTreeAsText(document
, 0, exceptionState
);
1644 String
Internals::elementLayerTreeAsText(Element
* element
, ExceptionState
& exceptionState
) const
1647 FrameView
* frameView
= element
->document().view();
1648 frameView
->updateAllLifecyclePhases();
1650 return elementLayerTreeAsText(element
, 0, exceptionState
);
1653 bool Internals::scrollsWithRespectTo(Element
* element1
, Element
* element2
, ExceptionState
& exceptionState
)
1655 ASSERT(element1
&& element2
);
1656 element1
->document().view()->updateAllLifecyclePhases();
1658 LayoutObject
* layoutObject1
= element1
->layoutObject();
1659 LayoutObject
* layoutObject2
= element2
->layoutObject();
1660 if (!layoutObject1
|| !layoutObject1
->isBox()) {
1661 exceptionState
.throwDOMException(InvalidAccessError
, layoutObject1
? "The first provided element's layoutObject is not a box." : "The first provided element has no layoutObject.");
1664 if (!layoutObject2
|| !layoutObject2
->isBox()) {
1665 exceptionState
.throwDOMException(InvalidAccessError
, layoutObject2
? "The second provided element's layoutObject is not a box." : "The second provided element has no layoutObject.");
1669 DeprecatedPaintLayer
* layer1
= toLayoutBox(layoutObject1
)->layer();
1670 DeprecatedPaintLayer
* layer2
= toLayoutBox(layoutObject2
)->layer();
1671 if (!layer1
|| !layer2
) {
1672 exceptionState
.throwDOMException(InvalidAccessError
, String::format("No DeprecatedPaintLayer can be obtained from the %s provided element.", layer1
? "second" : "first"));
1676 return layer1
->scrollsWithRespectTo(layer2
);
1679 String
Internals::layerTreeAsText(Document
* document
, unsigned flags
, ExceptionState
& exceptionState
) const
1682 if (!document
->frame()) {
1683 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
1687 document
->view()->updateAllLifecyclePhases();
1689 return document
->frame()->layerTreeAsText(flags
);
1692 String
Internals::elementLayerTreeAsText(Element
* element
, unsigned flags
, ExceptionState
& exceptionState
) const
1695 element
->document().updateLayout();
1697 LayoutObject
* layoutObject
= element
->layoutObject();
1698 if (!layoutObject
|| !layoutObject
->isBox()) {
1699 exceptionState
.throwDOMException(InvalidAccessError
, layoutObject
? "The provided element's layoutObject is not a box." : "The provided element has no layoutObject.");
1703 DeprecatedPaintLayer
* layer
= toLayoutBox(layoutObject
)->layer();
1705 || !layer
->hasCompositedDeprecatedPaintLayerMapping()
1706 || !layer
->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()) {
1707 // Don't raise exception in these cases which may be normally used in tests.
1711 return layer
->compositedDeprecatedPaintLayerMapping()->mainGraphicsLayer()->layerTreeAsText(flags
);
1714 String
Internals::scrollingStateTreeAsText(Document
*) const
1719 String
Internals::mainThreadScrollingReasons(Document
* document
, ExceptionState
& exceptionState
) const
1722 if (!document
->frame()) {
1723 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
1727 document
->frame()->view()->updateAllLifecyclePhases();
1729 Page
* page
= document
->page();
1733 return page
->mainThreadScrollingReasonsAsText();
1736 ClientRectList
* Internals::nonFastScrollableRects(Document
* document
, ExceptionState
& exceptionState
) const
1739 if (!document
->frame()) {
1740 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
1744 Page
* page
= document
->page();
1748 return page
->nonFastScrollableRects(document
->frame());
1751 void Internals::garbageCollectDocumentResources(Document
* document
) const
1754 ResourceFetcher
* fetcher
= document
->fetcher();
1757 fetcher
->garbageCollectDocumentResources();
1760 void Internals::evictAllResources() const
1762 memoryCache()->evictResources();
1765 String
Internals::counterValue(Element
* element
)
1770 return counterValueForElement(element
);
1773 int Internals::pageNumber(Element
* element
, float pageWidth
, float pageHeight
)
1778 return PrintContext::pageNumberForElement(element
, FloatSize(pageWidth
, pageHeight
));
1781 Vector
<String
> Internals::iconURLs(Document
* document
, int iconTypesMask
) const
1783 Vector
<IconURL
> iconURLs
= document
->iconURLs(iconTypesMask
);
1784 Vector
<String
> array
;
1786 for (auto& iconURL
: iconURLs
)
1787 array
.append(iconURL
.m_iconURL
.string());
1792 Vector
<String
> Internals::shortcutIconURLs(Document
* document
) const
1794 return iconURLs(document
, Favicon
);
1797 Vector
<String
> Internals::allIconURLs(Document
* document
) const
1799 return iconURLs(document
, Favicon
| TouchIcon
| TouchPrecomposedIcon
);
1802 int Internals::numberOfPages(float pageWidth
, float pageHeight
)
1807 return PrintContext::numberOfPages(frame(), FloatSize(pageWidth
, pageHeight
));
1810 String
Internals::pageProperty(String propertyName
, int pageNumber
, ExceptionState
& exceptionState
) const
1813 exceptionState
.throwDOMException(InvalidAccessError
, "No frame is available.");
1817 return PrintContext::pageProperty(frame(), propertyName
.utf8().data(), pageNumber
);
1820 String
Internals::pageSizeAndMarginsInPixels(int pageNumber
, int width
, int height
, int marginTop
, int marginRight
, int marginBottom
, int marginLeft
, ExceptionState
& exceptionState
) const
1823 exceptionState
.throwDOMException(InvalidAccessError
, "No frame is available.");
1827 return PrintContext::pageSizeAndMarginsInPixels(frame(), pageNumber
, width
, height
, marginTop
, marginRight
, marginBottom
, marginLeft
);
1830 void Internals::setDeviceScaleFactor(float scaleFactor
, ExceptionState
& exceptionState
)
1832 Document
* document
= contextDocument();
1833 if (!document
|| !document
->page()) {
1834 exceptionState
.throwDOMException(InvalidAccessError
, document
? "The document's page cannot be retrieved." : "No context document can be obtained.");
1837 Page
* page
= document
->page();
1838 page
->setDeviceScaleFactor(scaleFactor
);
1841 void Internals::setPageScaleFactor(float scaleFactor
, ExceptionState
& exceptionState
)
1843 Document
* document
= contextDocument();
1844 if (!document
|| !document
->page()) {
1845 exceptionState
.throwDOMException(InvalidAccessError
, document
? "The document's page cannot be retrieved." : "No context document can be obtained.");
1848 Page
* page
= document
->page();
1849 page
->frameHost().visualViewport().setScale(scaleFactor
);
1852 void Internals::setPageScaleFactorLimits(float minScaleFactor
, float maxScaleFactor
, ExceptionState
& exceptionState
)
1854 Document
* document
= contextDocument();
1855 if (!document
|| !document
->page()) {
1856 exceptionState
.throwDOMException(InvalidAccessError
, document
? "The document's page cannot be retrieved." : "No context document can be obtained.");
1860 Page
* page
= document
->page();
1861 page
->frameHost().setDefaultPageScaleLimits(minScaleFactor
, maxScaleFactor
);
1864 bool Internals::magnifyScaleAroundAnchor(float scaleFactor
, float x
, float y
)
1866 return frame()->host()->visualViewport().magnifyScaleAroundAnchor(scaleFactor
, FloatPoint(x
, y
));
1869 void Internals::setIsCursorVisible(Document
* document
, bool isVisible
, ExceptionState
& exceptionState
)
1872 if (!document
->page()) {
1873 exceptionState
.throwDOMException(InvalidAccessError
, "No context document can be obtained.");
1876 document
->page()->setIsCursorVisible(isVisible
);
1879 double Internals::effectiveMediaVolume(HTMLMediaElement
* mediaElement
)
1881 ASSERT(mediaElement
);
1882 return mediaElement
->effectiveMediaVolume();
1885 void Internals::mediaPlayerRemoteRouteAvailabilityChanged(HTMLMediaElement
* mediaElement
, bool available
)
1887 ASSERT(mediaElement
);
1888 mediaElement
->remoteRouteAvailabilityChanged(available
);
1891 void Internals::mediaPlayerPlayingRemotelyChanged(HTMLMediaElement
* mediaElement
, bool remote
)
1893 ASSERT(mediaElement
);
1895 mediaElement
->connectedToRemoteDevice();
1897 mediaElement
->disconnectedFromRemoteDevice();
1900 void Internals::setAllowHiddenVolumeControls(HTMLMediaElement
* mediaElement
, bool allow
)
1902 ASSERT(mediaElement
);
1903 mediaElement
->setAllowHiddenVolumeControls(allow
);
1906 void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String
& scheme
)
1908 SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme
);
1911 void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String
& scheme
, const Vector
<String
>& policyAreas
)
1913 uint32_t policyAreasEnum
= SchemeRegistry::PolicyAreaNone
;
1914 for (const auto& policyArea
: policyAreas
) {
1915 if (policyArea
== "img")
1916 policyAreasEnum
|= SchemeRegistry::PolicyAreaImage
;
1917 else if (policyArea
== "style")
1918 policyAreasEnum
|= SchemeRegistry::PolicyAreaStyle
;
1920 SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(
1921 scheme
, static_cast<SchemeRegistry::PolicyAreas
>(policyAreasEnum
));
1924 void Internals::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String
& scheme
)
1926 SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme
);
1929 TypeConversions
* Internals::typeConversions() const
1931 return TypeConversions::create();
1934 PrivateScriptTest
* Internals::privateScriptTest() const
1936 return PrivateScriptTest::create(frame()->document());
1939 DictionaryTest
* Internals::dictionaryTest() const
1941 return DictionaryTest::create();
1944 UnionTypesTest
* Internals::unionTypesTest() const
1946 return UnionTypesTest::create();
1949 Vector
<String
> Internals::getReferencedFilePaths() const
1951 return frame()->loader().currentItem()->getReferencedFilePaths();
1954 void Internals::startTrackingRepaints(Document
* document
, ExceptionState
& exceptionState
)
1957 if (!document
->view()) {
1958 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
1962 FrameView
* frameView
= document
->view();
1963 frameView
->updateAllLifecyclePhases();
1964 frameView
->setTracksPaintInvalidations(true);
1967 void Internals::stopTrackingRepaints(Document
* document
, ExceptionState
& exceptionState
)
1970 if (!document
->view()) {
1971 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
1975 FrameView
* frameView
= document
->view();
1976 frameView
->updateAllLifecyclePhases();
1977 frameView
->setTracksPaintInvalidations(false);
1980 void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node
* node
, ExceptionState
& exceptionState
)
1984 document
= contextDocument();
1985 } else if (node
->isDocumentNode()) {
1986 document
= toDocument(node
);
1987 } else if (isHTMLIFrameElement(*node
)) {
1988 document
= toHTMLIFrameElement(*node
).contentDocument();
1990 exceptionState
.throwTypeError("The node provided is neither a document nor an IFrame.");
1993 document
->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasksSynchronously
);
1996 void Internals::forceFullRepaint(Document
* document
, ExceptionState
& exceptionState
)
1999 if (!document
->view()) {
2000 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
2004 if (LayoutView
*layoutView
= document
->layoutView())
2005 layoutView
->invalidatePaintForViewAndCompositedLayers();
2008 void Internals::startTrackingPaintInvalidationObjects()
2010 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
2011 toLocalFrame(frame()->page()->mainFrame())->view()->layoutView()->layer()->graphicsLayerBacking()->displayItemList()->startTrackingPaintInvalidationObjects();
2014 void Internals::stopTrackingPaintInvalidationObjects()
2016 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
2017 toLocalFrame(frame()->page()->mainFrame())->view()->layoutView()->layer()->graphicsLayerBacking()->displayItemList()->stopTrackingPaintInvalidationObjects();
2020 Vector
<String
> Internals::trackedPaintInvalidationObjects()
2022 ASSERT(RuntimeEnabledFeatures::slimmingPaintV2Enabled());
2023 return toLocalFrame(frame()->page()->mainFrame())->view()->layoutView()->layer()->graphicsLayerBacking()->displayItemList()->trackedPaintInvalidationObjects();
2026 ClientRectList
* Internals::draggableRegions(Document
* document
, ExceptionState
& exceptionState
)
2028 return annotatedRegions(document
, true, exceptionState
);
2031 ClientRectList
* Internals::nonDraggableRegions(Document
* document
, ExceptionState
& exceptionState
)
2033 return annotatedRegions(document
, false, exceptionState
);
2036 ClientRectList
* Internals::annotatedRegions(Document
* document
, bool draggable
, ExceptionState
& exceptionState
)
2039 if (!document
->view()) {
2040 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
2041 return ClientRectList::create();
2044 document
->updateLayout();
2045 document
->view()->updateAnnotatedRegions();
2046 Vector
<AnnotatedRegionValue
> regions
= document
->annotatedRegions();
2048 Vector
<FloatQuad
> quads
;
2049 for (size_t i
= 0; i
< regions
.size(); ++i
) {
2050 if (regions
[i
].draggable
== draggable
)
2051 quads
.append(FloatQuad(FloatRect(regions
[i
].bounds
)));
2053 return ClientRectList::create(quads
);
2056 static const char* cursorTypeToString(Cursor::Type cursorType
)
2058 switch (cursorType
) {
2059 case Cursor::Pointer
: return "Pointer";
2060 case Cursor::Cross
: return "Cross";
2061 case Cursor::Hand
: return "Hand";
2062 case Cursor::IBeam
: return "IBeam";
2063 case Cursor::Wait
: return "Wait";
2064 case Cursor::Help
: return "Help";
2065 case Cursor::EastResize
: return "EastResize";
2066 case Cursor::NorthResize
: return "NorthResize";
2067 case Cursor::NorthEastResize
: return "NorthEastResize";
2068 case Cursor::NorthWestResize
: return "NorthWestResize";
2069 case Cursor::SouthResize
: return "SouthResize";
2070 case Cursor::SouthEastResize
: return "SouthEastResize";
2071 case Cursor::SouthWestResize
: return "SouthWestResize";
2072 case Cursor::WestResize
: return "WestResize";
2073 case Cursor::NorthSouthResize
: return "NorthSouthResize";
2074 case Cursor::EastWestResize
: return "EastWestResize";
2075 case Cursor::NorthEastSouthWestResize
: return "NorthEastSouthWestResize";
2076 case Cursor::NorthWestSouthEastResize
: return "NorthWestSouthEastResize";
2077 case Cursor::ColumnResize
: return "ColumnResize";
2078 case Cursor::RowResize
: return "RowResize";
2079 case Cursor::MiddlePanning
: return "MiddlePanning";
2080 case Cursor::EastPanning
: return "EastPanning";
2081 case Cursor::NorthPanning
: return "NorthPanning";
2082 case Cursor::NorthEastPanning
: return "NorthEastPanning";
2083 case Cursor::NorthWestPanning
: return "NorthWestPanning";
2084 case Cursor::SouthPanning
: return "SouthPanning";
2085 case Cursor::SouthEastPanning
: return "SouthEastPanning";
2086 case Cursor::SouthWestPanning
: return "SouthWestPanning";
2087 case Cursor::WestPanning
: return "WestPanning";
2088 case Cursor::Move
: return "Move";
2089 case Cursor::VerticalText
: return "VerticalText";
2090 case Cursor::Cell
: return "Cell";
2091 case Cursor::ContextMenu
: return "ContextMenu";
2092 case Cursor::Alias
: return "Alias";
2093 case Cursor::Progress
: return "Progress";
2094 case Cursor::NoDrop
: return "NoDrop";
2095 case Cursor::Copy
: return "Copy";
2096 case Cursor::None
: return "None";
2097 case Cursor::NotAllowed
: return "NotAllowed";
2098 case Cursor::ZoomIn
: return "ZoomIn";
2099 case Cursor::ZoomOut
: return "ZoomOut";
2100 case Cursor::Grab
: return "Grab";
2101 case Cursor::Grabbing
: return "Grabbing";
2102 case Cursor::Custom
: return "Custom";
2105 ASSERT_NOT_REACHED();
2109 String
Internals::getCurrentCursorInfo()
2111 Cursor cursor
= frame()->page()->chromeClient().lastSetCursorForTesting();
2113 StringBuilder result
;
2114 result
.appendLiteral("type=");
2115 result
.append(cursorTypeToString(cursor
.type()));
2116 result
.appendLiteral(" hotSpot=");
2117 result
.appendNumber(cursor
.hotSpot().x());
2119 result
.appendNumber(cursor
.hotSpot().y());
2120 if (cursor
.image()) {
2121 IntSize size
= cursor
.image()->size();
2122 result
.appendLiteral(" image=");
2123 result
.appendNumber(size
.width());
2125 result
.appendNumber(size
.height());
2127 if (cursor
.imageScaleFactor() != 1) {
2128 result
.appendLiteral(" scale=");
2129 NumberToStringBuffer buffer
;
2130 result
.append(numberToFixedPrecisionString(cursor
.imageScaleFactor(), 8, buffer
, true));
2133 return result
.toString();
2136 bool Internals::cursorUpdatePending() const
2138 return frame()->eventHandler().cursorUpdatePending();
2141 PassRefPtr
<DOMArrayBuffer
> Internals::serializeObject(PassRefPtr
<SerializedScriptValue
> value
) const
2143 String stringValue
= value
->toWireString();
2144 RefPtr
<DOMArrayBuffer
> buffer
= DOMArrayBuffer::createUninitialized(stringValue
.length(), sizeof(UChar
));
2145 stringValue
.copyTo(static_cast<UChar
*>(buffer
->data()), 0, stringValue
.length());
2146 return buffer
.release();
2149 PassRefPtr
<SerializedScriptValue
> Internals::deserializeBuffer(PassRefPtr
<DOMArrayBuffer
> buffer
) const
2151 String
value(static_cast<const UChar
*>(buffer
->data()), buffer
->byteLength() / sizeof(UChar
));
2152 return SerializedScriptValueFactory::instance().createFromWire(value
);
2155 void Internals::forceReload(bool endToEnd
)
2157 frame()->reload(endToEnd
? FrameLoadTypeReloadFromOrigin
: FrameLoadTypeReload
, NotClientRedirect
);
2160 ClientRect
* Internals::selectionBounds(ExceptionState
& exceptionState
)
2162 Document
* document
= contextDocument();
2163 if (!document
|| !document
->frame()) {
2164 exceptionState
.throwDOMException(InvalidAccessError
, document
? "The document's frame cannot be retrieved." : "No context document can be obtained.");
2168 return ClientRect::create(FloatRect(document
->frame()->selection().bounds()));
2171 String
Internals::markerTextForListItem(Element
* element
)
2174 return blink::markerTextForListItem(element
);
2177 String
Internals::getImageSourceURL(Element
* element
)
2180 return element
->imageSourceURL();
2183 String
Internals::selectMenuListText(HTMLSelectElement
* select
)
2186 LayoutObject
* layoutObject
= select
->layoutObject();
2187 if (!layoutObject
|| !layoutObject
->isMenuList())
2190 LayoutMenuList
* menuList
= toLayoutMenuList(layoutObject
);
2191 return menuList
->text();
2194 bool Internals::isSelectPopupVisible(Node
* node
)
2197 if (!isHTMLSelectElement(*node
))
2199 return toHTMLSelectElement(*node
).popupIsVisible();
2202 bool Internals::selectPopupItemStyleIsRtl(Node
* node
, int itemIndex
)
2204 if (!node
|| !isHTMLSelectElement(*node
))
2207 HTMLSelectElement
& select
= toHTMLSelectElement(*node
);
2208 if (itemIndex
< 0 || static_cast<size_t>(itemIndex
) >= select
.listItems().size())
2210 const ComputedStyle
* itemStyle
= select
.itemComputedStyle(*select
.listItems()[itemIndex
]);
2211 return itemStyle
&& itemStyle
->direction() == RTL
;
2214 int Internals::selectPopupItemStyleFontHeight(Node
* node
, int itemIndex
)
2216 if (!node
|| !isHTMLSelectElement(*node
))
2219 HTMLSelectElement
& select
= toHTMLSelectElement(*node
);
2220 if (itemIndex
< 0 || static_cast<size_t>(itemIndex
) >= select
.listItems().size())
2222 const ComputedStyle
* itemStyle
= select
.itemComputedStyle(*select
.listItems()[itemIndex
]);
2223 return itemStyle
? itemStyle
->font().fontMetrics().height() : 0;
2226 void Internals::resetTypeAheadSession(HTMLSelectElement
* select
)
2229 select
->resetTypeAheadSessionForTesting();
2232 bool Internals::loseSharedGraphicsContext3D()
2234 OwnPtr
<WebGraphicsContext3DProvider
> sharedProvider
= adoptPtr(Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
2235 if (!sharedProvider
)
2237 WebGraphicsContext3D
* sharedContext
= sharedProvider
->context3d();
2238 sharedContext
->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_EXT
, GL_INNOCENT_CONTEXT_RESET_EXT
);
2239 // To prevent tests that call loseSharedGraphicsContext3D from being
2240 // flaky, we call finish so that the context is guaranteed to be lost
2241 // synchronously (i.e. before returning).
2242 sharedContext
->finish();
2246 void Internals::forceCompositingUpdate(Document
* document
, ExceptionState
& exceptionState
)
2249 if (!document
->layoutView()) {
2250 exceptionState
.throwDOMException(InvalidAccessError
, "The document provided is invalid.");
2254 document
->frame()->view()->updateAllLifecyclePhases();
2257 void Internals::setZoomFactor(float factor
)
2259 frame()->setPageZoomFactor(factor
);
2262 void Internals::setShouldRevealPassword(Element
* element
, bool reveal
, ExceptionState
& exceptionState
)
2265 if (!isHTMLInputElement(element
)) {
2266 exceptionState
.throwDOMException(InvalidNodeTypeError
, "The element provided is not an INPUT.");
2270 return toHTMLInputElement(*element
).setShouldRevealPassword(reveal
);
2275 class AddOneFunction
: public ScriptFunction
{
2277 static v8::Local
<v8::Function
> createFunction(ScriptState
* scriptState
)
2279 AddOneFunction
* self
= new AddOneFunction(scriptState
);
2280 return self
->bindToV8Function();
2284 explicit AddOneFunction(ScriptState
* scriptState
)
2285 : ScriptFunction(scriptState
)
2289 ScriptValue
call(ScriptValue value
) override
2291 v8::Local
<v8::Value
> v8Value
= value
.v8Value();
2292 ASSERT(v8Value
->IsNumber());
2293 int intValue
= v8Value
.As
<v8::Integer
>()->Value();
2294 return ScriptValue(scriptState(), v8::Integer::New(scriptState()->isolate(), intValue
+ 1));
2300 ScriptPromise
Internals::createResolvedPromise(ScriptState
* scriptState
, ScriptValue value
)
2302 ScriptPromiseResolver
* resolver
= ScriptPromiseResolver::create(scriptState
);
2303 ScriptPromise promise
= resolver
->promise();
2304 resolver
->resolve(value
);
2308 ScriptPromise
Internals::createRejectedPromise(ScriptState
* scriptState
, ScriptValue value
)
2310 ScriptPromiseResolver
* resolver
= ScriptPromiseResolver::create(scriptState
);
2311 ScriptPromise promise
= resolver
->promise();
2312 resolver
->reject(value
);
2316 ScriptPromise
Internals::addOneToPromise(ScriptState
* scriptState
, ScriptPromise promise
)
2318 return promise
.then(AddOneFunction::createFunction(scriptState
));
2321 ScriptPromise
Internals::promiseCheck(ScriptState
* scriptState
, long arg1
, bool arg2
, const Dictionary
& arg3
, const String
& arg4
, const Vector
<String
>& arg5
, ExceptionState
& exceptionState
)
2324 return ScriptPromise::cast(scriptState
, v8String(scriptState
->isolate(), "done"));
2325 exceptionState
.throwDOMException(InvalidStateError
, "Thrown from the native implementation.");
2326 return ScriptPromise();
2329 ScriptPromise
Internals::promiseCheckWithoutExceptionState(ScriptState
* scriptState
, const Dictionary
& arg1
, const String
& arg2
, const Vector
<String
>& arg3
)
2331 return ScriptPromise::cast(scriptState
, v8String(scriptState
->isolate(), "done"));
2334 ScriptPromise
Internals::promiseCheckRange(ScriptState
* scriptState
, long arg1
)
2336 return ScriptPromise::cast(scriptState
, v8String(scriptState
->isolate(), "done"));
2339 ScriptPromise
Internals::promiseCheckOverload(ScriptState
* scriptState
, Location
*)
2341 return ScriptPromise::cast(scriptState
, v8String(scriptState
->isolate(), "done"));
2344 ScriptPromise
Internals::promiseCheckOverload(ScriptState
* scriptState
, Document
*)
2346 return ScriptPromise::cast(scriptState
, v8String(scriptState
->isolate(), "done"));
2349 ScriptPromise
Internals::promiseCheckOverload(ScriptState
* scriptState
, Location
*, long, long)
2351 return ScriptPromise::cast(scriptState
, v8String(scriptState
->isolate(), "done"));
2354 DEFINE_TRACE(Internals
)
2356 visitor
->trace(m_runtimeFlags
);
2357 ContextLifecycleObserver::trace(visitor
);
2360 void Internals::setValueForUser(Element
* element
, const String
& value
)
2362 toHTMLInputElement(element
)->setValueForUser(value
);
2365 String
Internals::textSurroundingNode(Node
* node
, int x
, int y
, unsigned long maxLength
)
2367 if (!node
|| !node
->layoutObject())
2369 blink::WebPoint
point(x
, y
);
2370 SurroundingText
surroundingText(createVisiblePosition(node
->layoutObject()->positionForPoint(static_cast<IntPoint
>(point
))).deepEquivalent().parentAnchoredEquivalent(), maxLength
);
2371 return surroundingText
.content();
2374 void Internals::setFocused(bool focused
)
2376 frame()->page()->focusController().setFocused(focused
);
2379 void Internals::setInitialFocus(bool reverse
)
2381 frame()->document()->setFocusedElement(nullptr);
2382 frame()->page()->focusController().setInitialFocus(reverse
? WebFocusTypeBackward
: WebFocusTypeForward
);
2385 bool Internals::ignoreLayoutWithPendingStylesheets(Document
* document
)
2388 return document
->ignoreLayoutWithPendingStylesheets();
2391 void Internals::setNetworkStateNotifierTestOnly(bool testOnly
)
2393 networkStateNotifier().setTestUpdatesOnly(testOnly
);
2396 void Internals::setNetworkConnectionInfo(const String
& type
, double downlinkMaxMbps
, ExceptionState
& exceptionState
)
2398 WebConnectionType webtype
;
2399 if (type
== "cellular") {
2400 webtype
= WebConnectionTypeCellular
;
2401 } else if (type
== "bluetooth") {
2402 webtype
= WebConnectionTypeBluetooth
;
2403 } else if (type
== "ethernet") {
2404 webtype
= WebConnectionTypeEthernet
;
2405 } else if (type
== "wifi") {
2406 webtype
= WebConnectionTypeWifi
;
2407 } else if (type
== "wimax") {
2408 webtype
= WebConnectionTypeWimax
;
2409 } else if (type
== "other") {
2410 webtype
= WebConnectionTypeOther
;
2411 } else if (type
== "none") {
2412 webtype
= WebConnectionTypeNone
;
2413 } else if (type
== "unknown") {
2414 webtype
= WebConnectionTypeUnknown
;
2416 exceptionState
.throwDOMException(NotFoundError
, ExceptionMessages::failedToEnumerate("connection type", type
));
2419 networkStateNotifier().setWebConnectionForTest(webtype
, downlinkMaxMbps
);
2422 unsigned Internals::countHitRegions(CanvasRenderingContext
* context
)
2424 return context
->hitRegionsCount();
2427 bool Internals::isInCanvasFontCache(Document
* document
, const String
& fontString
)
2429 return document
->canvasFontCache()->isInCache(fontString
);
2432 unsigned Internals::canvasFontCacheMaxFonts()
2434 return CanvasFontCache::maxFonts();
2437 ClientRect
* Internals::boundsInViewportSpace(Element
* element
)
2440 return ClientRect::create(element
->boundsInViewportSpace());
2443 void Internals::setScrollChain(
2444 ScrollState
* scrollState
, const WillBeHeapVector
<RefPtrWillBeMember
<Element
>>& elements
, ExceptionState
&)
2446 WillBeHeapDeque
<RefPtrWillBeMember
<Element
>> scrollChain
;
2447 for (size_t i
= 0; i
< elements
.size(); ++i
)
2448 scrollChain
.append(elements
[i
]);
2449 scrollState
->setScrollChain(scrollChain
);
2452 void Internals::forceBlinkGCWithoutV8GC()
2454 ThreadState::current()->setGCState(ThreadState::FullGCScheduled
);
2457 String
Internals::selectedHTMLForClipboard()
2459 return frame()->selection().selectedHTMLForClipboard();
2462 String
Internals::selectedTextForClipboard()
2464 return frame()->selection().selectedTextForClipboard();
2467 void Internals::setVisualViewportOffset(int x
, int y
)
2469 frame()->host()->visualViewport().setLocation(FloatPoint(x
, y
));
2472 ValueIterable
<int>::IterationSource
* Internals::startIteration(ScriptState
*, ExceptionState
&)
2474 return new InternalsIterationSource();
2477 bool Internals::isUseCounted(Document
* document
, int useCounterId
)
2479 if (useCounterId
< 0 || useCounterId
>= UseCounter::NumberOfFeatures
)
2481 return UseCounter::isCounted(*document
, static_cast<UseCounter::Feature
>(useCounterId
));
2484 String
Internals::unscopeableAttribute()
2486 return "unscopeableAttribute";
2489 String
Internals::unscopeableMethod()
2491 return "unscopeableMethod";
2494 ClientRectList
* Internals::focusRingRects(Element
* element
)
2496 Vector
<LayoutRect
> rects
;
2497 if (element
&& element
->layoutObject())
2498 element
->layoutObject()->addOutlineRects(rects
, LayoutPoint(), LayoutObject::IncludeBlockVisualOverflow
);
2499 return ClientRectList::create(rects
);
2502 ClientRectList
* Internals::outlineRects(Element
* element
)
2504 Vector
<LayoutRect
> rects
;
2505 if (element
&& element
->layoutObject())
2506 element
->layoutObject()->addOutlineRects(rects
, LayoutPoint(), LayoutObject::DontIncludeBlockVisualOverflow
);
2507 return ClientRectList::create(rects
);
2510 void Internals::setCapsLockState(bool enabled
)
2512 PlatformKeyboardEvent::setCurrentCapsLockState(enabled
?
2513 PlatformKeyboardEvent::OverrideCapsLockState::On
: PlatformKeyboardEvent::OverrideCapsLockState::Off
);
2516 void Internals::setSelectionPaintingWithoutSelectionGapsEnabled(bool enabled
)
2518 RuntimeEnabledFeatures::setSelectionPaintingWithoutSelectionGapsEnabled(enabled
);
2521 bool Internals::setScrollbarVisibilityInScrollableArea(Node
* node
, bool visible
)
2523 LayoutObject
* layoutObject
= node
->layoutObject();
2526 DeprecatedPaintLayer
* layer
= layoutObject
->enclosingLayer();
2529 ScrollableArea
* scrollableArea
= layer
->scrollableArea();
2530 if (!scrollableArea
)
2532 ScrollAnimator
* animator
= layer
->scrollableArea()->scrollAnimator();
2536 return animator
->setScrollbarsVisibleForTesting(visible
);
2539 void Internals::forceRestrictIFramePermissions()
2541 RuntimeEnabledFeatures::setRestrictIFramePermissionsEnabled(true);
2544 } // namespace blink