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 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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 "Internals.h"
30 #include "AXObjectCache.h"
31 #include "AnimationController.h"
32 #include "ApplicationCacheStorage.h"
33 #include "BackForwardController.h"
34 #include "CachedResourceLoader.h"
36 #include "ChromeClient.h"
37 #include "ClientRect.h"
38 #include "ClientRectList.h"
39 #include "ContentDistributor.h"
41 #include "DOMStringList.h"
42 #include "DOMWindow.h"
44 #include "DocumentMarker.h"
45 #include "DocumentMarkerController.h"
48 #include "EventHandler.h"
49 #include "ExceptionCode.h"
50 #include "FormController.h"
51 #include "FrameLoader.h"
52 #include "FrameView.h"
53 #include "HTMLInputElement.h"
54 #include "HTMLNames.h"
55 #include "HTMLPlugInElement.h"
56 #include "HTMLSelectElement.h"
57 #include "HTMLTextAreaElement.h"
58 #include "HistoryController.h"
59 #include "HistoryItem.h"
60 #include "InspectorClient.h"
61 #include "InspectorController.h"
62 #include "InspectorForwarding.h"
63 #include "InspectorFrontendClientLocal.h"
64 #include "InspectorInstrumentation.h"
65 #include "InspectorOverlay.h"
66 #include "InstrumentingAgents.h"
68 #include "InternalSettings.h"
70 #include "MainFrame.h"
71 #include "MallocStatistics.h"
72 #include "MediaPlayer.h"
73 #include "MediaSessionManager.h"
74 #include "MemoryCache.h"
75 #include "MemoryInfo.h"
77 #include "PrintContext.h"
78 #include "PseudoElement.h"
80 #include "RenderEmbeddedObject.h"
81 #include "RenderMenuList.h"
82 #include "RenderTreeAsText.h"
83 #include "RenderView.h"
84 #include "RuntimeEnabledFeatures.h"
85 #include "SchemeRegistry.h"
86 #include "ScrollingCoordinator.h"
87 #include "SerializedScriptValue.h"
89 #include "ShadowRoot.h"
90 #include "SpellChecker.h"
91 #include "StaticNodeList.h"
92 #include "StyleSheetContents.h"
93 #include "TextIterator.h"
94 #include "TreeScope.h"
95 #include "TypeConversions.h"
96 #include "ViewportArguments.h"
97 #include "WebConsoleAgent.h"
98 #include "WorkerThread.h"
99 #include <bytecode/CodeBlock.h>
100 #include <inspector/InspectorAgentBase.h>
101 #include <inspector/InspectorValues.h>
102 #include <runtime/JSCInlines.h>
103 #include <runtime/JSCJSValue.h>
104 #include <wtf/text/CString.h>
105 #include <wtf/text/StringBuffer.h>
107 #if ENABLE(INPUT_TYPE_COLOR)
108 #include "ColorChooser.h"
111 #if ENABLE(BATTERY_STATUS)
112 #include "BatteryController.h"
115 #if ENABLE(PROXIMITY_EVENTS)
116 #include "DeviceProximityController.h"
119 #if ENABLE(MOUSE_CURSOR_SCALE)
120 #include <wtf/dtoa.h>
123 #if ENABLE(ENCRYPTED_MEDIA_V2)
128 #if ENABLE(VIDEO_TRACK)
129 #include "CaptionUserPreferences.h"
130 #include "PageGroup.h"
134 #include "HTMLMediaElement.h"
135 #include "TimeRanges.h"
138 #if ENABLE(SPEECH_SYNTHESIS)
139 #include "DOMWindowSpeechSynthesis.h"
140 #include "PlatformSpeechSynthesizerMock.h"
141 #include "SpeechSynthesis.h"
144 #if ENABLE(VIBRATION)
145 #include "Vibration.h"
148 #if ENABLE(MEDIA_STREAM)
149 #include "MockMediaStreamCenter.h"
150 #include "RTCPeerConnection.h"
151 #include "RTCPeerConnectionHandlerMock.h"
152 #include "UserMediaClientMock.h"
155 #if ENABLE(MEDIA_SOURCE)
156 #include "MockMediaPlayerMediaSource.h"
159 using JSC::CodeBlock;
160 using JSC::FunctionExecutable;
161 using JSC::JSFunction;
163 using JSC::ScriptExecutable;
164 using JSC::StackVisitor;
166 using namespace Inspector;
170 using namespace HTMLNames;
172 #if ENABLE(INSPECTOR)
173 class InspectorFrontendClientDummy : public InspectorFrontendClientLocal {
175 InspectorFrontendClientDummy(InspectorController*, Page*);
176 virtual ~InspectorFrontendClientDummy() { }
177 virtual void attachWindow(DockSide) override { }
178 virtual void detachWindow() override { }
180 virtual String localizedStringsURL() override { return String(); }
182 virtual void bringToFront() override { }
183 virtual void closeWindow() override { }
185 virtual void inspectedURLChanged(const String&) override { }
188 virtual void setAttachedWindowHeight(unsigned) override { }
189 virtual void setAttachedWindowWidth(unsigned) override { }
190 virtual void setToolbarHeight(unsigned) override { }
193 InspectorFrontendClientDummy::InspectorFrontendClientDummy(InspectorController* controller, Page* page)
194 : InspectorFrontendClientLocal(controller, page, std::make_unique<InspectorFrontendClientLocal::Settings>())
198 class InspectorFrontendChannelDummy : public InspectorFrontendChannel {
200 explicit InspectorFrontendChannelDummy(Page*);
201 virtual ~InspectorFrontendChannelDummy() { }
202 virtual bool sendMessageToFrontend(const String& message) override;
205 Page* m_frontendPage;
208 InspectorFrontendChannelDummy::InspectorFrontendChannelDummy(Page* page)
209 : m_frontendPage(page)
213 bool InspectorFrontendChannelDummy::sendMessageToFrontend(const String& message)
215 return InspectorClient::doDispatchMessageOnFrontendPage(m_frontendPage, message);
217 #endif // ENABLE(INSPECTOR)
219 static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerTypes& result)
221 if (markerType.isEmpty() || equalIgnoringCase(markerType, "all"))
222 result = DocumentMarker::AllMarkers();
223 else if (equalIgnoringCase(markerType, "Spelling"))
224 result = DocumentMarker::Spelling;
225 else if (equalIgnoringCase(markerType, "Grammar"))
226 result = DocumentMarker::Grammar;
227 else if (equalIgnoringCase(markerType, "TextMatch"))
228 result = DocumentMarker::TextMatch;
229 else if (equalIgnoringCase(markerType, "Replacement"))
230 result = DocumentMarker::Replacement;
231 else if (equalIgnoringCase(markerType, "CorrectionIndicator"))
232 result = DocumentMarker::CorrectionIndicator;
233 else if (equalIgnoringCase(markerType, "RejectedCorrection"))
234 result = DocumentMarker::RejectedCorrection;
235 else if (equalIgnoringCase(markerType, "Autocorrected"))
236 result = DocumentMarker::Autocorrected;
237 else if (equalIgnoringCase(markerType, "SpellCheckingExemption"))
238 result = DocumentMarker::SpellCheckingExemption;
239 else if (equalIgnoringCase(markerType, "DeletedAutocorrection"))
240 result = DocumentMarker::DeletedAutocorrection;
241 else if (equalIgnoringCase(markerType, "DictationAlternatives"))
242 result = DocumentMarker::DictationAlternatives;
243 #if ENABLE(TELEPHONE_NUMBER_DETECTION)
244 else if (equalIgnoringCase(markerType, "TelephoneNumber"))
245 result = DocumentMarker::TelephoneNumber;
253 const char* Internals::internalsId = "internals";
255 PassRefPtr<Internals> Internals::create(Document* document)
257 return adoptRef(new Internals(document));
260 Internals::~Internals()
264 void Internals::resetToConsistentState(Page* page)
268 page->setPageScaleFactor(1, IntPoint(0, 0));
269 page->setPagination(Pagination());
271 FrameView* mainFrameView = page->mainFrame().view();
273 mainFrameView->setHeaderHeight(0);
274 mainFrameView->setFooterHeight(0);
275 page->setTopContentInset(0);
278 TextRun::setAllowsRoundingHacks(false);
279 WebCore::overrideUserPreferredLanguages(Vector<String>());
280 WebCore::Settings::setUsesOverlayScrollbars(false);
281 #if ENABLE(INSPECTOR)
282 page->inspectorController().setProfilerEnabled(false);
284 #if ENABLE(VIDEO_TRACK)
285 page->group().captionPreferences()->setCaptionsStyleSheetOverride(emptyString());
286 page->group().captionPreferences()->setTestingMode(false);
288 if (!page->mainFrame().editor().isContinuousSpellCheckingEnabled())
289 page->mainFrame().editor().toggleContinuousSpellChecking();
290 if (page->mainFrame().editor().isOverwriteModeEnabled())
291 page->mainFrame().editor().toggleOverwriteModeEnabled();
292 cacheStorage().setDefaultOriginQuota(ApplicationCacheStorage::noQuota());
294 MediaSessionManager::sharedManager().resetRestrictions();
296 #if HAVE(ACCESSIBILITY)
297 AXObjectCache::setEnhancedUserInterfaceAccessibility(false);
298 AXObjectCache::disableAccessibility();
302 Internals::Internals(Document* document)
303 : ContextDestructionObserver(document)
305 #if ENABLE(VIDEO_TRACK)
306 if (document && document->page())
307 document->page()->group().captionPreferences()->setTestingMode(true);
310 #if ENABLE(MEDIA_STREAM)
311 MockMediaStreamCenter::registerMockMediaStreamCenter();
312 enableMockRTCPeerConnectionHandler();
313 WebCore::provideUserMediaTo(document->page(), new UserMediaClientMock());
317 Document* Internals::contextDocument() const
319 return toDocument(scriptExecutionContext());
322 Frame* Internals::frame() const
324 if (!contextDocument())
326 return contextDocument()->frame();
329 InternalSettings* Internals::settings() const
331 Document* document = contextDocument();
334 Page* page = document->page();
337 return InternalSettings::from(page);
340 unsigned Internals::workerThreadCount() const
342 return WorkerThread::workerThreadCount();
345 String Internals::address(Node* node)
348 sprintf(buf, "%p", node);
353 bool Internals::isPreloaded(const String& url)
355 Document* document = contextDocument();
356 return document->cachedResourceLoader()->isPreloaded(url);
359 bool Internals::isLoadingFromMemoryCache(const String& url)
361 if (!contextDocument() || !contextDocument()->page())
363 CachedResource* resource = memoryCache()->resourceForURL(contextDocument()->completeURL(url), contextDocument()->page()->sessionID());
364 return resource && resource->status() == CachedResource::Cached;
368 Node* Internals::treeScopeRootNode(Node* node, ExceptionCode& ec)
371 ec = INVALID_ACCESS_ERR;
375 return &node->treeScope().rootNode();
378 Node* Internals::parentTreeScope(Node* node, ExceptionCode& ec)
381 ec = INVALID_ACCESS_ERR;
384 const TreeScope* parentTreeScope = node->treeScope().parentTreeScope();
385 return parentTreeScope ? &parentTreeScope->rootNode() : nullptr;
388 unsigned Internals::lastSpatialNavigationCandidateCount(ExceptionCode& ec) const
390 if (!contextDocument() || !contextDocument()->page()) {
391 ec = INVALID_ACCESS_ERR;
395 return contextDocument()->page()->lastSpatialNavigationCandidateCount();
398 unsigned Internals::numberOfActiveAnimations() const
400 return frame()->animation().numberOfActiveAnimations(frame()->document());
403 bool Internals::animationsAreSuspended(ExceptionCode& ec) const
405 Document* document = contextDocument();
406 if (!document || !document->frame()) {
407 ec = INVALID_ACCESS_ERR;
411 return document->frame()->animation().isSuspended();
414 void Internals::suspendAnimations(ExceptionCode& ec) const
416 Document* document = contextDocument();
417 if (!document || !document->frame()) {
418 ec = INVALID_ACCESS_ERR;
422 document->frame()->animation().suspendAnimations();
425 void Internals::resumeAnimations(ExceptionCode& ec) const
427 Document* document = contextDocument();
428 if (!document || !document->frame()) {
429 ec = INVALID_ACCESS_ERR;
433 document->frame()->animation().resumeAnimations();
436 bool Internals::pauseAnimationAtTimeOnElement(const String& animationName, double pauseTime, Element* element, ExceptionCode& ec)
438 if (!element || pauseTime < 0) {
439 ec = INVALID_ACCESS_ERR;
442 return frame()->animation().pauseAnimationAtTime(element->renderer(), AtomicString(animationName), pauseTime);
445 bool Internals::pauseAnimationAtTimeOnPseudoElement(const String& animationName, double pauseTime, Element* element, const String& pseudoId, ExceptionCode& ec)
447 if (!element || pauseTime < 0) {
448 ec = INVALID_ACCESS_ERR;
452 if (pseudoId != "before" && pseudoId != "after") {
453 ec = INVALID_ACCESS_ERR;
457 PseudoElement* pseudoElement = pseudoId == "before" ? element->beforePseudoElement() : element->afterPseudoElement();
458 if (!pseudoElement) {
459 ec = INVALID_ACCESS_ERR;
463 return frame()->animation().pauseAnimationAtTime(pseudoElement->renderer(), AtomicString(animationName), pauseTime);
466 bool Internals::pauseTransitionAtTimeOnElement(const String& propertyName, double pauseTime, Element* element, ExceptionCode& ec)
468 if (!element || pauseTime < 0) {
469 ec = INVALID_ACCESS_ERR;
472 return frame()->animation().pauseTransitionAtTime(element->renderer(), propertyName, pauseTime);
475 bool Internals::pauseTransitionAtTimeOnPseudoElement(const String& property, double pauseTime, Element* element, const String& pseudoId, ExceptionCode& ec)
477 if (!element || pauseTime < 0) {
478 ec = INVALID_ACCESS_ERR;
482 if (pseudoId != "before" && pseudoId != "after") {
483 ec = INVALID_ACCESS_ERR;
487 PseudoElement* pseudoElement = pseudoId == "before" ? element->beforePseudoElement() : element->afterPseudoElement();
488 if (!pseudoElement) {
489 ec = INVALID_ACCESS_ERR;
493 return frame()->animation().pauseTransitionAtTime(pseudoElement->renderer(), property, pauseTime);
497 bool Internals::attached(Node* node, ExceptionCode& ec)
500 ec = INVALID_ACCESS_ERR;
507 String Internals::elementRenderTreeAsText(Element* element, ExceptionCode& ec)
510 ec = INVALID_ACCESS_ERR;
514 element->document().updateStyleIfNeeded();
516 String representation = externalRepresentation(element);
517 if (representation.isEmpty()) {
518 ec = INVALID_ACCESS_ERR;
522 return representation;
525 PassRefPtr<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisitedInfo(Node* node, ExceptionCode& ec) const
528 ec = INVALID_ACCESS_ERR;
532 bool allowVisitedStyle = true;
533 return CSSComputedStyleDeclaration::create(node, allowVisitedStyle);
536 Node* Internals::ensureShadowRoot(Element* host, ExceptionCode& ec)
539 ec = INVALID_ACCESS_ERR;
543 if (ShadowRoot* shadowRoot = host->shadowRoot())
546 return host->createShadowRoot(ec).get();
549 Node* Internals::createShadowRoot(Element* host, ExceptionCode& ec)
552 ec = INVALID_ACCESS_ERR;
555 return host->createShadowRoot(ec).get();
558 Node* Internals::shadowRoot(Element* host, ExceptionCode& ec)
561 ec = INVALID_ACCESS_ERR;
564 return host->shadowRoot();
567 String Internals::shadowRootType(const Node* root, ExceptionCode& ec) const
569 if (!root || !root->isShadowRoot()) {
570 ec = INVALID_ACCESS_ERR;
574 switch (toShadowRoot(root)->type()) {
575 case ShadowRoot::UserAgentShadowRoot:
576 return String("UserAgentShadowRoot");
578 ASSERT_NOT_REACHED();
579 return String("Unknown");
583 Element* Internals::includerFor(Node*, ExceptionCode& ec)
585 ec = INVALID_ACCESS_ERR;
589 String Internals::shadowPseudoId(Element* element, ExceptionCode& ec)
592 ec = INVALID_ACCESS_ERR;
596 return element->shadowPseudoId().string();
599 void Internals::setShadowPseudoId(Element* element, const String& id, ExceptionCode& ec)
602 ec = INVALID_ACCESS_ERR;
606 return element->setPseudo(id);
609 String Internals::visiblePlaceholder(Element* element)
611 if (element && isHTMLTextFormControlElement(*element)) {
612 if (toHTMLTextFormControlElement(*element).placeholderShouldBeVisible())
613 return toHTMLTextFormControlElement(*element).placeholderElement()->textContent();
619 #if ENABLE(INPUT_TYPE_COLOR)
620 void Internals::selectColorInColorChooser(Element* element, const String& colorValue)
622 if (!isHTMLInputElement(element))
624 HTMLInputElement* inputElement = element->toInputElement();
627 inputElement->selectColorInColorChooser(Color(colorValue));
631 Vector<String> Internals::formControlStateOfPreviousHistoryItem(ExceptionCode& ec)
633 HistoryItem* mainItem = frame()->loader().history().previousItem();
635 ec = INVALID_ACCESS_ERR;
636 return Vector<String>();
638 String uniqueName = frame()->tree().uniqueName();
639 if (mainItem->target() != uniqueName && !mainItem->childItemWithTarget(uniqueName)) {
640 ec = INVALID_ACCESS_ERR;
641 return Vector<String>();
643 return mainItem->target() == uniqueName ? mainItem->documentState() : mainItem->childItemWithTarget(uniqueName)->documentState();
646 void Internals::setFormControlStateOfPreviousHistoryItem(const Vector<String>& state, ExceptionCode& ec)
648 HistoryItem* mainItem = frame()->loader().history().previousItem();
650 ec = INVALID_ACCESS_ERR;
653 String uniqueName = frame()->tree().uniqueName();
654 if (mainItem->target() == uniqueName)
655 mainItem->setDocumentState(state);
656 else if (HistoryItem* subItem = mainItem->childItemWithTarget(uniqueName))
657 subItem->setDocumentState(state);
659 ec = INVALID_ACCESS_ERR;
662 #if ENABLE(SPEECH_SYNTHESIS)
663 void Internals::enableMockSpeechSynthesizer()
665 Document* document = contextDocument();
666 if (!document || !document->domWindow())
668 SpeechSynthesis* synthesis = DOMWindowSpeechSynthesis::speechSynthesis(document->domWindow());
672 synthesis->setPlatformSynthesizer(std::make_unique<PlatformSpeechSynthesizerMock>(synthesis));
676 #if ENABLE(MEDIA_STREAM)
677 void Internals::enableMockRTCPeerConnectionHandler()
679 RTCPeerConnectionHandler::create = RTCPeerConnectionHandlerMock::create;
683 PassRefPtr<ClientRect> Internals::absoluteCaretBounds(ExceptionCode& ec)
685 Document* document = contextDocument();
686 if (!document || !document->frame()) {
687 ec = INVALID_ACCESS_ERR;
688 return ClientRect::create();
691 return ClientRect::create(document->frame()->selection().absoluteCaretBounds());
694 PassRefPtr<ClientRect> Internals::boundingBox(Element* element, ExceptionCode& ec)
697 ec = INVALID_ACCESS_ERR;
698 return ClientRect::create();
701 element->document().updateLayoutIgnorePendingStylesheets();
702 auto renderer = element->renderer();
704 return ClientRect::create();
705 return ClientRect::create(renderer->absoluteBoundingBoxRectIgnoringTransforms());
708 PassRefPtr<ClientRectList> Internals::inspectorHighlightRects(ExceptionCode& ec)
710 #if ENABLE(INSPECTOR)
711 Document* document = contextDocument();
712 if (!document || !document->page()) {
713 ec = INVALID_ACCESS_ERR;
714 return ClientRectList::create();
718 document->page()->inspectorController().getHighlight(&highlight);
719 return ClientRectList::create(highlight.quads);
722 return ClientRectList::create();
726 String Internals::inspectorHighlightObject(ExceptionCode& ec)
728 #if ENABLE(INSPECTOR)
729 Document* document = contextDocument();
730 if (!document || !document->page()) {
731 ec = INVALID_ACCESS_ERR;
734 RefPtr<InspectorObject> object = document->page()->inspectorController().buildObjectForHighlightedNode();
735 return object ? object->toJSONString() : String();
742 unsigned Internals::markerCountForNode(Node* node, const String& markerType, ExceptionCode& ec)
745 ec = INVALID_ACCESS_ERR;
749 DocumentMarker::MarkerTypes markerTypes = 0;
750 if (!markerTypesFrom(markerType, markerTypes)) {
755 node->document().frame()->editor().updateEditorUINowIfScheduled();
757 return node->document().markers().markersFor(node, markerTypes).size();
760 DocumentMarker* Internals::markerAt(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
762 node->document().updateLayoutIgnorePendingStylesheets();
764 ec = INVALID_ACCESS_ERR;
768 DocumentMarker::MarkerTypes markerTypes = 0;
769 if (!markerTypesFrom(markerType, markerTypes)) {
774 node->document().frame()->editor().updateEditorUINowIfScheduled();
776 Vector<DocumentMarker*> markers = node->document().markers().markersFor(node, markerTypes);
777 if (markers.size() <= index)
779 return markers[index];
782 PassRefPtr<Range> Internals::markerRangeForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
784 DocumentMarker* marker = markerAt(node, markerType, index, ec);
787 return Range::create(node->document(), node, marker->startOffset(), node, marker->endOffset());
790 String Internals::markerDescriptionForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec)
792 DocumentMarker* marker = markerAt(node, markerType, index, ec);
795 return marker->description();
798 void Internals::addTextMatchMarker(const Range* range, bool isActive)
800 range->ownerDocument().updateLayoutIgnorePendingStylesheets();
801 range->ownerDocument().markers().addTextMatchMarker(range, isActive);
804 void Internals::setScrollViewPosition(long x, long y, ExceptionCode& ec)
806 Document* document = contextDocument();
807 if (!document || !document->view()) {
808 ec = INVALID_ACCESS_ERR;
812 FrameView* frameView = document->view();
813 bool constrainsScrollingToContentEdgeOldValue = frameView->constrainsScrollingToContentEdge();
814 bool scrollbarsSuppressedOldValue = frameView->scrollbarsSuppressed();
816 frameView->setConstrainsScrollingToContentEdge(false);
817 frameView->setScrollbarsSuppressed(false);
818 frameView->setScrollOffsetFromInternals(IntPoint(x, y));
819 frameView->setScrollbarsSuppressed(scrollbarsSuppressedOldValue);
820 frameView->setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue);
823 void Internals::setPagination(const String& mode, int gap, int pageLength, ExceptionCode& ec)
825 Document* document = contextDocument();
826 if (!document || !document->page()) {
827 ec = INVALID_ACCESS_ERR;
830 Page* page = document->page();
832 Pagination pagination;
833 if (mode == "Unpaginated")
834 pagination.mode = Pagination::Unpaginated;
835 else if (mode == "LeftToRightPaginated")
836 pagination.mode = Pagination::LeftToRightPaginated;
837 else if (mode == "RightToLeftPaginated")
838 pagination.mode = Pagination::RightToLeftPaginated;
839 else if (mode == "TopToBottomPaginated")
840 pagination.mode = Pagination::TopToBottomPaginated;
841 else if (mode == "BottomToTopPaginated")
842 pagination.mode = Pagination::BottomToTopPaginated;
848 pagination.gap = gap;
849 pagination.pageLength = pageLength;
850 page->setPagination(pagination);
853 String Internals::configurationForViewport(float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight, ExceptionCode& ec)
855 Document* document = contextDocument();
856 if (!document || !document->page()) {
857 ec = INVALID_ACCESS_ERR;
860 Page* page = document->page();
862 const int defaultLayoutWidthForNonMobilePages = 980;
864 ViewportArguments arguments = page->viewportArguments();
865 ViewportAttributes attributes = computeViewportAttributes(arguments, defaultLayoutWidthForNonMobilePages, deviceWidth, deviceHeight, devicePixelRatio, IntSize(availableWidth, availableHeight));
866 restrictMinimumScaleFactorToViewportSize(attributes, IntSize(availableWidth, availableHeight), devicePixelRatio);
867 restrictScaleFactorToInitialScaleIfNotUserScalable(attributes);
869 return "viewport size " + String::number(attributes.layoutSize.width()) + "x" + String::number(attributes.layoutSize.height()) + " scale " + String::number(attributes.initialScale) + " with limits [" + String::number(attributes.minimumScale) + ", " + String::number(attributes.maximumScale) + "] and userScalable " + (attributes.userScalable ? "true" : "false");
872 bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionCode& ec)
875 ec = INVALID_ACCESS_ERR;
879 if (HTMLInputElement* inputElement = textField->toInputElement())
880 return inputElement->lastChangeWasUserEdit();
882 // FIXME: We should be using hasTagName instead but Windows port doesn't link QualifiedNames properly.
883 if (textField->tagName() == "TEXTAREA")
884 return toHTMLTextAreaElement(textField)->lastChangeWasUserEdit();
886 ec = INVALID_NODE_TYPE_ERR;
890 bool Internals::elementShouldAutoComplete(Element* element, ExceptionCode& ec)
893 ec = INVALID_ACCESS_ERR;
897 if (HTMLInputElement* inputElement = element->toInputElement())
898 return inputElement->shouldAutocomplete();
900 ec = INVALID_NODE_TYPE_ERR;
904 String Internals::suggestedValue(Element* element, ExceptionCode& ec)
907 ec = INVALID_ACCESS_ERR;
911 HTMLInputElement* inputElement = element->toInputElement();
913 ec = INVALID_NODE_TYPE_ERR;
917 return inputElement->suggestedValue();
920 void Internals::setSuggestedValue(Element* element, const String& value, ExceptionCode& ec)
923 ec = INVALID_ACCESS_ERR;
927 HTMLInputElement* inputElement = element->toInputElement();
929 ec = INVALID_NODE_TYPE_ERR;
933 inputElement->setSuggestedValue(value);
936 void Internals::setEditingValue(Element* element, const String& value, ExceptionCode& ec)
939 ec = INVALID_ACCESS_ERR;
943 HTMLInputElement* inputElement = element->toInputElement();
945 ec = INVALID_NODE_TYPE_ERR;
949 inputElement->setEditingValue(value);
952 void Internals::setAutofilled(Element* element, bool enabled, ExceptionCode& ec)
954 HTMLInputElement* inputElement = element->toInputElement();
956 ec = INVALID_ACCESS_ERR;
959 inputElement->setAutofilled(enabled);
962 void Internals::scrollElementToRect(Element* element, long x, long y, long w, long h, ExceptionCode& ec)
964 if (!element || !element->document().view()) {
965 ec = INVALID_ACCESS_ERR;
968 FrameView* frameView = element->document().view();
969 frameView->scrollElementToRect(element, IntRect(x, y, w, h));
972 void Internals::paintControlTints(ExceptionCode& ec)
974 Document* document = contextDocument();
975 if (!document || !document->view()) {
976 ec = INVALID_ACCESS_ERR;
980 FrameView* frameView = document->view();
981 frameView->paintControlTints();
984 PassRefPtr<Range> Internals::rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionCode& ec)
987 ec = INVALID_ACCESS_ERR;
991 return TextIterator::rangeFromLocationAndLength(scope, rangeLocation, rangeLength);
994 unsigned Internals::locationFromRange(Element* scope, const Range* range, ExceptionCode& ec)
996 if (!scope || !range) {
997 ec = INVALID_ACCESS_ERR;
1001 size_t location = 0;
1002 size_t unusedLength = 0;
1003 TextIterator::getLocationAndLengthFromRange(scope, range, location, unusedLength);
1007 unsigned Internals::lengthFromRange(Element* scope, const Range* range, ExceptionCode& ec)
1009 if (!scope || !range) {
1010 ec = INVALID_ACCESS_ERR;
1014 size_t unusedLocation = 0;
1016 TextIterator::getLocationAndLengthFromRange(scope, range, unusedLocation, length);
1020 String Internals::rangeAsText(const Range* range, ExceptionCode& ec)
1023 ec = INVALID_ACCESS_ERR;
1027 return range->text();
1030 void Internals::setDelegatesScrolling(bool enabled, ExceptionCode& ec)
1032 Document* document = contextDocument();
1033 // Delegate scrolling is valid only on mainframe's view.
1034 if (!document || !document->view() || !document->page() || &document->page()->mainFrame() != document->frame()) {
1035 ec = INVALID_ACCESS_ERR;
1039 document->view()->setDelegatesScrolling(enabled);
1042 int Internals::lastSpellCheckRequestSequence(ExceptionCode& ec)
1044 Document* document = contextDocument();
1045 if (!document || !document->frame()) {
1046 ec = INVALID_ACCESS_ERR;
1050 return document->frame()->editor().spellChecker().lastRequestSequence();
1053 int Internals::lastSpellCheckProcessedSequence(ExceptionCode& ec)
1055 Document* document = contextDocument();
1056 if (!document || !document->frame()) {
1057 ec = INVALID_ACCESS_ERR;
1061 return document->frame()->editor().spellChecker().lastProcessedSequence();
1064 Vector<String> Internals::userPreferredLanguages() const
1066 return WebCore::userPreferredLanguages();
1069 void Internals::setUserPreferredLanguages(const Vector<String>& languages)
1071 WebCore::overrideUserPreferredLanguages(languages);
1074 unsigned Internals::wheelEventHandlerCount(ExceptionCode& ec)
1076 Document* document = contextDocument();
1078 ec = INVALID_ACCESS_ERR;
1082 return document->wheelEventHandlerCount();
1085 unsigned Internals::touchEventHandlerCount(ExceptionCode& ec)
1087 Document* document = contextDocument();
1089 ec = INVALID_ACCESS_ERR;
1093 const TouchEventTargetSet* touchHandlers = document->touchEventTargets();
1098 for (TouchEventTargetSet::const_iterator iter = touchHandlers->begin(); iter != touchHandlers->end(); ++iter)
1099 count += iter->value;
1103 // FIXME: Remove the document argument. It is almost always the same as
1104 // contextDocument(), with the exception of a few tests that pass a
1105 // different document, and could just make the call through another Internals
1106 // instance instead.
1107 PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int centerX, int centerY, unsigned topPadding, unsigned rightPadding,
1108 unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionCode& ec) const
1110 if (!document || !document->frame() || !document->frame()->view()) {
1111 ec = INVALID_ACCESS_ERR;
1115 Frame* frame = document->frame();
1116 FrameView* frameView = document->view();
1117 RenderView* renderView = document->renderView();
1121 document->updateLayoutIgnorePendingStylesheets();
1123 float zoomFactor = frame->pageZoomFactor();
1124 LayoutPoint point = roundedLayoutPoint(FloatPoint(centerX * zoomFactor + frameView->scrollX(), centerY * zoomFactor + frameView->scrollY()));
1126 HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
1128 hitType |= HitTestRequest::IgnoreClipping;
1129 if (!allowShadowContent)
1130 hitType |= HitTestRequest::DisallowShadowContent;
1131 if (allowChildFrameContent)
1132 hitType |= HitTestRequest::AllowChildFrameContent;
1134 HitTestRequest request(hitType);
1136 // When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
1137 if (!request.ignoreClipping() && !frameView->visibleContentRect().intersects(HitTestLocation::rectForPoint(point, topPadding, rightPadding, bottomPadding, leftPadding)))
1140 Vector<Ref<Node>> matches;
1142 // Need padding to trigger a rect based hit test, but we want to return a NodeList
1143 // so we special case this.
1144 if (!topPadding && !rightPadding && !bottomPadding && !leftPadding) {
1145 HitTestResult result(point);
1146 renderView->hitTest(request, result);
1147 if (result.innerNode())
1148 matches.append(*result.innerNode()->deprecatedShadowAncestorNode());
1150 HitTestResult result(point, topPadding, rightPadding, bottomPadding, leftPadding);
1151 renderView->hitTest(request, result);
1153 const HitTestResult::NodeSet& nodeSet = result.rectBasedTestResult();
1154 matches.reserveInitialCapacity(nodeSet.size());
1155 for (auto it = nodeSet.begin(), end = nodeSet.end(); it != end; ++it)
1156 matches.uncheckedAppend(*it->get());
1159 return StaticNodeList::adopt(matches);
1162 class GetCallerCodeBlockFunctor {
1164 GetCallerCodeBlockFunctor()
1170 StackVisitor::Status operator()(StackVisitor& visitor)
1173 if (m_iterations < 2)
1174 return StackVisitor::Continue;
1176 m_codeBlock = visitor->codeBlock();
1177 return StackVisitor::Done;
1180 CodeBlock* codeBlock() const { return m_codeBlock; }
1184 CodeBlock* m_codeBlock;
1187 String Internals::parserMetaData(Deprecated::ScriptValue value)
1189 JSC::VM& vm = contextDocument()->vm();
1190 JSC::ExecState* exec = vm.topCallFrame;
1191 JSC::JSValue code = value.jsValue();
1192 ScriptExecutable* executable;
1194 if (!code || code.isNull() || code.isUndefined()) {
1195 GetCallerCodeBlockFunctor iter;
1196 exec->iterate(iter);
1197 CodeBlock* codeBlock = iter.codeBlock();
1198 executable = codeBlock->ownerExecutable();
1199 } else if (code.isFunction()) {
1200 JSFunction* funcObj = JSC::jsCast<JSFunction*>(code.toObject(exec));
1201 executable = funcObj->jsExecutable();
1205 unsigned startLine = executable->lineNo();
1206 unsigned startColumn = executable->startColumn();
1207 unsigned endLine = executable->lastLine();
1208 unsigned endColumn = executable->endColumn();
1210 StringBuilder result;
1212 if (executable->isFunctionExecutable()) {
1213 FunctionExecutable* funcExecutable = reinterpret_cast<FunctionExecutable*>(executable);
1214 String inferredName = funcExecutable->inferredName().string();
1215 result.append("function \"");
1216 result.append(inferredName);
1217 result.append("\"");
1218 } else if (executable->isEvalExecutable())
1219 result.append("eval");
1221 ASSERT(executable->isProgramExecutable());
1222 result.append("program");
1225 result.append(" { ");
1226 result.appendNumber(startLine);
1228 result.appendNumber(startColumn);
1229 result.append(" - ");
1230 result.appendNumber(endLine);
1232 result.appendNumber(endColumn);
1233 result.append(" }");
1235 return result.toString();
1238 void Internals::setBatteryStatus(const String& eventType, bool charging, double chargingTime, double dischargingTime, double level, ExceptionCode& ec)
1240 Document* document = contextDocument();
1241 if (!document || !document->page()) {
1242 ec = INVALID_ACCESS_ERR;
1246 #if ENABLE(BATTERY_STATUS)
1247 BatteryController::from(document->page())->didChangeBatteryStatus(eventType, BatteryStatus::create(charging, chargingTime, dischargingTime, level));
1249 UNUSED_PARAM(eventType);
1250 UNUSED_PARAM(charging);
1251 UNUSED_PARAM(chargingTime);
1252 UNUSED_PARAM(dischargingTime);
1253 UNUSED_PARAM(level);
1257 void Internals::setDeviceProximity(const String& eventType, double value, double min, double max, ExceptionCode& ec)
1259 Document* document = contextDocument();
1260 if (!document || !document->page()) {
1261 ec = INVALID_ACCESS_ERR;
1265 #if ENABLE(PROXIMITY_EVENTS)
1266 DeviceProximityController::from(document->page())->didChangeDeviceProximity(value, min, max);
1268 UNUSED_PARAM(eventType);
1269 UNUSED_PARAM(value);
1275 void Internals::updateEditorUINowIfScheduled()
1277 if (Document* document = contextDocument()) {
1278 if (Frame* frame = document->frame())
1279 frame->editor().updateEditorUINowIfScheduled();
1283 Node* Internals::findEditingDeleteButton()
1285 Document* document = contextDocument();
1286 if (!document || !document->frame())
1289 updateEditorUINowIfScheduled();
1291 // FIXME: We shouldn't pollute the id namespace with this name.
1292 return document->getElementById(String(ASCIILiteral("WebKit-Editing-Delete-Button")));
1295 bool Internals::hasSpellingMarker(int from, int length, ExceptionCode&)
1297 Document* document = contextDocument();
1298 if (!document || !document->frame())
1301 updateEditorUINowIfScheduled();
1303 return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
1306 bool Internals::hasAutocorrectedMarker(int from, int length, ExceptionCode&)
1308 Document* document = contextDocument();
1309 if (!document || !document->frame())
1312 updateEditorUINowIfScheduled();
1314 return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Autocorrected, from, length);
1317 void Internals::setContinuousSpellCheckingEnabled(bool enabled, ExceptionCode&)
1319 if (!contextDocument() || !contextDocument()->frame())
1322 if (enabled != contextDocument()->frame()->editor().isContinuousSpellCheckingEnabled())
1323 contextDocument()->frame()->editor().toggleContinuousSpellChecking();
1326 void Internals::setAutomaticQuoteSubstitutionEnabled(bool enabled, ExceptionCode&)
1328 if (!contextDocument() || !contextDocument()->frame())
1331 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1332 if (enabled != contextDocument()->frame()->editor().isAutomaticQuoteSubstitutionEnabled())
1333 contextDocument()->frame()->editor().toggleAutomaticQuoteSubstitution();
1335 UNUSED_PARAM(enabled);
1339 void Internals::setAutomaticLinkDetectionEnabled(bool enabled, ExceptionCode&)
1341 if (!contextDocument() || !contextDocument()->frame())
1344 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1345 if (enabled != contextDocument()->frame()->editor().isAutomaticLinkDetectionEnabled())
1346 contextDocument()->frame()->editor().toggleAutomaticLinkDetection();
1348 UNUSED_PARAM(enabled);
1352 void Internals::setAutomaticDashSubstitutionEnabled(bool enabled, ExceptionCode&)
1354 if (!contextDocument() || !contextDocument()->frame())
1357 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1358 if (enabled != contextDocument()->frame()->editor().isAutomaticDashSubstitutionEnabled())
1359 contextDocument()->frame()->editor().toggleAutomaticDashSubstitution();
1361 UNUSED_PARAM(enabled);
1365 void Internals::setAutomaticTextReplacementEnabled(bool enabled, ExceptionCode&)
1367 if (!contextDocument() || !contextDocument()->frame())
1370 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1371 if (enabled != contextDocument()->frame()->editor().isAutomaticTextReplacementEnabled())
1372 contextDocument()->frame()->editor().toggleAutomaticTextReplacement();
1374 UNUSED_PARAM(enabled);
1378 void Internals::setAutomaticSpellingCorrectionEnabled(bool enabled, ExceptionCode&)
1380 if (!contextDocument() || !contextDocument()->frame())
1383 #if USE(AUTOMATIC_TEXT_REPLACEMENT)
1384 if (enabled != contextDocument()->frame()->editor().isAutomaticSpellingCorrectionEnabled())
1385 contextDocument()->frame()->editor().toggleAutomaticSpellingCorrection();
1387 UNUSED_PARAM(enabled);
1391 bool Internals::isOverwriteModeEnabled(ExceptionCode&)
1393 Document* document = contextDocument();
1394 if (!document || !document->frame())
1397 return document->frame()->editor().isOverwriteModeEnabled();
1400 void Internals::toggleOverwriteModeEnabled(ExceptionCode&)
1402 Document* document = contextDocument();
1403 if (!document || !document->frame())
1406 document->frame()->editor().toggleOverwriteModeEnabled();
1409 unsigned Internals::countMatchesForText(const String& text, unsigned findOptions, const String& markMatches, ExceptionCode&)
1411 Document* document = contextDocument();
1412 if (!document || !document->frame())
1415 bool mark = markMatches == "mark";
1416 return document->frame()->editor().countMatchesForText(text, nullptr, findOptions, 1000, mark, nullptr);
1419 const ProfilesArray& Internals::consoleProfiles() const
1421 return contextDocument()->page()->console().profiles();
1424 unsigned Internals::numberOfLiveNodes() const
1426 unsigned nodeCount = 0;
1427 for (auto* document : Document::allDocuments())
1428 nodeCount += document->referencingNodeCount();
1432 unsigned Internals::numberOfLiveDocuments() const
1434 return Document::allDocuments().size();
1437 #if ENABLE(INSPECTOR)
1438 Vector<String> Internals::consoleMessageArgumentCounts() const
1440 Document* document = contextDocument();
1441 if (!document || !document->page())
1442 return Vector<String>();
1444 InstrumentingAgents* instrumentingAgents = instrumentationForPage(document->page());
1445 if (!instrumentingAgents)
1446 return Vector<String>();
1448 InspectorConsoleAgent* consoleAgent = instrumentingAgents->webConsoleAgent();
1450 return Vector<String>();
1452 Vector<unsigned> counts = consoleAgent->consoleMessageArgumentCounts();
1453 Vector<String> result(counts.size());
1454 for (size_t i = 0; i < counts.size(); i++)
1455 result[i] = String::number(counts[i]);
1459 PassRefPtr<DOMWindow> Internals::openDummyInspectorFrontend(const String& url)
1461 Page* page = contextDocument()->frame()->page();
1464 DOMWindow* window = page->mainFrame().document()->domWindow();
1467 m_frontendWindow = window->open(url, "", "", *window, *window);
1468 ASSERT(m_frontendWindow);
1470 Page* frontendPage = m_frontendWindow->document()->page();
1471 ASSERT(frontendPage);
1473 auto frontendClient = std::make_unique<InspectorFrontendClientDummy>(&page->inspectorController(), frontendPage);
1475 frontendPage->inspectorController().setInspectorFrontendClient(std::move(frontendClient));
1477 m_frontendChannel = adoptPtr(new InspectorFrontendChannelDummy(frontendPage));
1479 page->inspectorController().connectFrontend(m_frontendChannel.get());
1481 return m_frontendWindow;
1484 void Internals::closeDummyInspectorFrontend()
1486 Page* page = contextDocument()->frame()->page();
1488 ASSERT(m_frontendWindow);
1490 page->inspectorController().disconnectFrontend(InspectorDisconnectReason::InspectorDestroyed);
1492 m_frontendChannel.release();
1494 m_frontendWindow->close(m_frontendWindow->scriptExecutionContext());
1495 m_frontendWindow.release();
1498 void Internals::setJavaScriptProfilingEnabled(bool enabled, ExceptionCode& ec)
1500 Page* page = contextDocument()->frame()->page();
1502 ec = INVALID_ACCESS_ERR;
1506 page->inspectorController().setProfilerEnabled(enabled);
1509 void Internals::setInspectorIsUnderTest(bool isUnderTest, ExceptionCode& ec)
1511 Page* page = contextDocument()->frame()->page();
1513 ec = INVALID_ACCESS_ERR;
1517 page->inspectorController().setIsUnderTest(isUnderTest);
1519 #endif // ENABLE(INSPECTOR)
1521 bool Internals::hasGrammarMarker(int from, int length, ExceptionCode&)
1523 Document* document = contextDocument();
1524 if (!document || !document->frame())
1527 return document->frame()->editor().selectionStartHasMarkerFor(DocumentMarker::Grammar, from, length);
1530 unsigned Internals::numberOfScrollableAreas(ExceptionCode&)
1532 Document* document = contextDocument();
1533 if (!document || !document->frame())
1537 Frame* frame = document->frame();
1538 if (frame->view()->scrollableAreas())
1539 count += frame->view()->scrollableAreas()->size();
1541 for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
1542 if (child->view() && child->view()->scrollableAreas())
1543 count += child->view()->scrollableAreas()->size();
1549 bool Internals::isPageBoxVisible(int pageNumber, ExceptionCode& ec)
1551 Document* document = contextDocument();
1553 ec = INVALID_ACCESS_ERR;
1557 return document->isPageBoxVisible(pageNumber);
1560 // FIXME: Remove the document argument. It is almost always the same as
1561 // contextDocument(), with the exception of a few tests that pass a
1562 // different document, and could just make the call through another Internals
1563 // instance instead.
1564 String Internals::layerTreeAsText(Document* document, ExceptionCode& ec) const
1566 return layerTreeAsText(document, 0, ec);
1569 String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionCode& ec) const
1571 if (!document || !document->frame()) {
1572 ec = INVALID_ACCESS_ERR;
1576 LayerTreeFlags layerTreeFlags = 0;
1577 if (flags & LAYER_TREE_INCLUDES_VISIBLE_RECTS)
1578 layerTreeFlags |= LayerTreeFlagsIncludeVisibleRects;
1579 if (flags & LAYER_TREE_INCLUDES_TILE_CACHES)
1580 layerTreeFlags |= LayerTreeFlagsIncludeTileCaches;
1581 if (flags & LAYER_TREE_INCLUDES_REPAINT_RECTS)
1582 layerTreeFlags |= LayerTreeFlagsIncludeRepaintRects;
1583 if (flags & LAYER_TREE_INCLUDES_PAINTING_PHASES)
1584 layerTreeFlags |= LayerTreeFlagsIncludePaintingPhases;
1585 if (flags & LAYER_TREE_INCLUDES_CONTENT_LAYERS)
1586 layerTreeFlags |= LayerTreeFlagsIncludeContentLayers;
1588 return document->frame()->layerTreeAsText(layerTreeFlags);
1591 String Internals::repaintRectsAsText(ExceptionCode& ec) const
1593 Document* document = contextDocument();
1594 if (!document || !document->frame()) {
1595 ec = INVALID_ACCESS_ERR;
1599 return document->frame()->trackedRepaintRectsAsText();
1602 String Internals::scrollingStateTreeAsText(ExceptionCode& ec) const
1604 Document* document = contextDocument();
1605 if (!document || !document->frame()) {
1606 ec = INVALID_ACCESS_ERR;
1610 Page* page = document->page();
1614 return page->scrollingStateTreeAsText();
1617 String Internals::mainThreadScrollingReasons(ExceptionCode& ec) const
1619 Document* document = contextDocument();
1620 if (!document || !document->frame()) {
1621 ec = INVALID_ACCESS_ERR;
1625 Page* page = document->page();
1629 return page->synchronousScrollingReasonsAsText();
1632 PassRefPtr<ClientRectList> Internals::nonFastScrollableRects(ExceptionCode& ec) const
1634 Document* document = contextDocument();
1635 if (!document || !document->frame()) {
1636 ec = INVALID_ACCESS_ERR;
1640 Page* page = document->page();
1644 return page->nonFastScrollableRects(document->frame());
1647 void Internals::garbageCollectDocumentResources(ExceptionCode& ec) const
1649 Document* document = contextDocument();
1651 ec = INVALID_ACCESS_ERR;
1655 CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader();
1656 if (!cachedResourceLoader)
1658 cachedResourceLoader->garbageCollectDocumentResources();
1661 void Internals::allowRoundingHacks() const
1663 TextRun::setAllowsRoundingHacks(true);
1666 void Internals::insertAuthorCSS(const String& css, ExceptionCode& ec) const
1668 Document* document = contextDocument();
1670 ec = INVALID_ACCESS_ERR;
1674 auto parsedSheet = StyleSheetContents::create(*document);
1675 parsedSheet.get().setIsUserStyleSheet(false);
1676 parsedSheet.get().parseString(css);
1677 document->styleSheetCollection().addAuthorSheet(std::move(parsedSheet));
1680 void Internals::insertUserCSS(const String& css, ExceptionCode& ec) const
1682 Document* document = contextDocument();
1684 ec = INVALID_ACCESS_ERR;
1688 auto parsedSheet = StyleSheetContents::create(*document);
1689 parsedSheet.get().setIsUserStyleSheet(true);
1690 parsedSheet.get().parseString(css);
1691 document->styleSheetCollection().addUserSheet(std::move(parsedSheet));
1694 String Internals::counterValue(Element* element)
1699 return counterValueForElement(element);
1702 int Internals::pageNumber(Element* element, float pageWidth, float pageHeight)
1707 return PrintContext::pageNumberForElement(element, FloatSize(pageWidth, pageHeight));
1710 Vector<String> Internals::iconURLs(Document* document, int iconTypesMask) const
1712 Vector<IconURL> iconURLs = document->iconURLs(iconTypesMask);
1713 Vector<String> array;
1715 Vector<IconURL>::const_iterator iter(iconURLs.begin());
1716 for (; iter != iconURLs.end(); ++iter)
1717 array.append(iter->m_iconURL.string());
1722 Vector<String> Internals::shortcutIconURLs() const
1724 return iconURLs(contextDocument(), Favicon);
1727 Vector<String> Internals::allIconURLs() const
1729 return iconURLs(contextDocument(), Favicon | TouchIcon | TouchPrecomposedIcon);
1732 int Internals::numberOfPages(float pageWidth, float pageHeight)
1737 return PrintContext::numberOfPages(frame(), FloatSize(pageWidth, pageHeight));
1740 String Internals::pageProperty(String propertyName, int pageNumber, ExceptionCode& ec) const
1743 ec = INVALID_ACCESS_ERR;
1747 return PrintContext::pageProperty(frame(), propertyName.utf8().data(), pageNumber);
1750 String Internals::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft, ExceptionCode& ec) const
1753 ec = INVALID_ACCESS_ERR;
1757 return PrintContext::pageSizeAndMarginsInPixels(frame(), pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft);
1760 void Internals::setPageScaleFactor(float scaleFactor, int x, int y, ExceptionCode& ec)
1762 Document* document = contextDocument();
1763 if (!document || !document->page()) {
1764 ec = INVALID_ACCESS_ERR;
1767 Page* page = document->page();
1768 page->setPageScaleFactor(scaleFactor, IntPoint(x, y));
1771 void Internals::setHeaderHeight(float height)
1773 Document* document = contextDocument();
1774 if (!document || !document->view())
1777 FrameView* frameView = document->view();
1778 frameView->setHeaderHeight(height);
1781 void Internals::setFooterHeight(float height)
1783 Document* document = contextDocument();
1784 if (!document || !document->view())
1787 FrameView* frameView = document->view();
1788 frameView->setFooterHeight(height);
1791 void Internals::setTopContentInset(float contentInset)
1793 Document* document = contextDocument();
1797 Page* page = document->page();
1798 page->setTopContentInset(contentInset);
1801 #if ENABLE(FULLSCREEN_API)
1802 void Internals::webkitWillEnterFullScreenForElement(Element* element)
1804 Document* document = contextDocument();
1807 document->webkitWillEnterFullScreenForElement(element);
1810 void Internals::webkitDidEnterFullScreenForElement(Element* element)
1812 Document* document = contextDocument();
1815 document->webkitDidEnterFullScreenForElement(element);
1818 void Internals::webkitWillExitFullScreenForElement(Element* element)
1820 Document* document = contextDocument();
1823 document->webkitWillExitFullScreenForElement(element);
1826 void Internals::webkitDidExitFullScreenForElement(Element* element)
1828 Document* document = contextDocument();
1831 document->webkitDidExitFullScreenForElement(element);
1835 void Internals::setApplicationCacheOriginQuota(unsigned long long quota)
1837 Document* document = contextDocument();
1840 cacheStorage().storeUpdatedQuotaForOrigin(document->securityOrigin(), quota);
1843 void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
1845 SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
1848 void Internals::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme)
1850 SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme);
1853 PassRefPtr<MallocStatistics> Internals::mallocStatistics() const
1855 return MallocStatistics::create();
1858 PassRefPtr<TypeConversions> Internals::typeConversions() const
1860 return TypeConversions::create();
1863 PassRefPtr<MemoryInfo> Internals::memoryInfo() const
1865 return MemoryInfo::create();
1868 Vector<String> Internals::getReferencedFilePaths() const
1870 frame()->loader().history().saveDocumentAndScrollState();
1871 return FormController::getReferencedFilePaths(frame()->loader().history().currentItem()->documentState());
1874 void Internals::startTrackingRepaints(ExceptionCode& ec)
1876 Document* document = contextDocument();
1877 if (!document || !document->view()) {
1878 ec = INVALID_ACCESS_ERR;
1882 FrameView* frameView = document->view();
1883 frameView->setTracksRepaints(true);
1886 void Internals::stopTrackingRepaints(ExceptionCode& ec)
1888 Document* document = contextDocument();
1889 if (!document || !document->view()) {
1890 ec = INVALID_ACCESS_ERR;
1894 FrameView* frameView = document->view();
1895 frameView->setTracksRepaints(false);
1899 static const char* cursorTypeToString(Cursor::Type cursorType)
1901 switch (cursorType) {
1902 case Cursor::Pointer: return "Pointer";
1903 case Cursor::Cross: return "Cross";
1904 case Cursor::Hand: return "Hand";
1905 case Cursor::IBeam: return "IBeam";
1906 case Cursor::Wait: return "Wait";
1907 case Cursor::Help: return "Help";
1908 case Cursor::EastResize: return "EastResize";
1909 case Cursor::NorthResize: return "NorthResize";
1910 case Cursor::NorthEastResize: return "NorthEastResize";
1911 case Cursor::NorthWestResize: return "NorthWestResize";
1912 case Cursor::SouthResize: return "SouthResize";
1913 case Cursor::SouthEastResize: return "SouthEastResize";
1914 case Cursor::SouthWestResize: return "SouthWestResize";
1915 case Cursor::WestResize: return "WestResize";
1916 case Cursor::NorthSouthResize: return "NorthSouthResize";
1917 case Cursor::EastWestResize: return "EastWestResize";
1918 case Cursor::NorthEastSouthWestResize: return "NorthEastSouthWestResize";
1919 case Cursor::NorthWestSouthEastResize: return "NorthWestSouthEastResize";
1920 case Cursor::ColumnResize: return "ColumnResize";
1921 case Cursor::RowResize: return "RowResize";
1922 case Cursor::MiddlePanning: return "MiddlePanning";
1923 case Cursor::EastPanning: return "EastPanning";
1924 case Cursor::NorthPanning: return "NorthPanning";
1925 case Cursor::NorthEastPanning: return "NorthEastPanning";
1926 case Cursor::NorthWestPanning: return "NorthWestPanning";
1927 case Cursor::SouthPanning: return "SouthPanning";
1928 case Cursor::SouthEastPanning: return "SouthEastPanning";
1929 case Cursor::SouthWestPanning: return "SouthWestPanning";
1930 case Cursor::WestPanning: return "WestPanning";
1931 case Cursor::Move: return "Move";
1932 case Cursor::VerticalText: return "VerticalText";
1933 case Cursor::Cell: return "Cell";
1934 case Cursor::ContextMenu: return "ContextMenu";
1935 case Cursor::Alias: return "Alias";
1936 case Cursor::Progress: return "Progress";
1937 case Cursor::NoDrop: return "NoDrop";
1938 case Cursor::Copy: return "Copy";
1939 case Cursor::None: return "None";
1940 case Cursor::NotAllowed: return "NotAllowed";
1941 case Cursor::ZoomIn: return "ZoomIn";
1942 case Cursor::ZoomOut: return "ZoomOut";
1943 case Cursor::Grab: return "Grab";
1944 case Cursor::Grabbing: return "Grabbing";
1945 case Cursor::Custom: return "Custom";
1948 ASSERT_NOT_REACHED();
1953 String Internals::getCurrentCursorInfo(ExceptionCode& ec)
1955 Document* document = contextDocument();
1956 if (!document || !document->frame()) {
1957 ec = INVALID_ACCESS_ERR;
1962 Cursor cursor = document->frame()->eventHandler().currentMouseCursor();
1964 StringBuilder result;
1965 result.append("type=");
1966 result.append(cursorTypeToString(cursor.type()));
1967 result.append(" hotSpot=");
1968 result.appendNumber(cursor.hotSpot().x());
1970 result.appendNumber(cursor.hotSpot().y());
1971 if (cursor.image()) {
1972 FloatSize size = cursor.image()->size();
1973 result.append(" image=");
1974 result.appendNumber(size.width());
1976 result.appendNumber(size.height());
1978 #if ENABLE(MOUSE_CURSOR_SCALE)
1979 if (cursor.imageScaleFactor() != 1) {
1980 result.append(" scale=");
1981 NumberToStringBuffer buffer;
1982 result.append(numberToFixedPrecisionString(cursor.imageScaleFactor(), 8, buffer, true));
1985 return result.toString();
1987 return "FAIL: Cursor details not available on this platform.";
1991 PassRefPtr<ArrayBuffer> Internals::serializeObject(PassRefPtr<SerializedScriptValue> value) const
1993 Vector<uint8_t> bytes = value->data();
1994 return ArrayBuffer::create(bytes.data(), bytes.size());
1997 PassRefPtr<SerializedScriptValue> Internals::deserializeBuffer(PassRefPtr<ArrayBuffer> buffer) const
1999 Vector<uint8_t> bytes;
2000 bytes.append(static_cast<const uint8_t*>(buffer->data()), buffer->byteLength());
2001 return SerializedScriptValue::adopt(bytes);
2004 void Internals::setUsesOverlayScrollbars(bool enabled)
2006 WebCore::Settings::setUsesOverlayScrollbars(enabled);
2009 void Internals::forceReload(bool endToEnd)
2011 frame()->loader().reload(endToEnd);
2014 #if ENABLE(ENCRYPTED_MEDIA_V2)
2015 void Internals::initializeMockCDM()
2017 CDM::registerCDMFactory(MockCDM::create, MockCDM::supportsKeySystem, MockCDM::supportsKeySystemAndMimeType);
2021 String Internals::markerTextForListItem(Element* element, ExceptionCode& ec)
2024 ec = INVALID_ACCESS_ERR;
2027 return WebCore::markerTextForListItem(element);
2030 String Internals::getImageSourceURL(Element* element, ExceptionCode& ec)
2033 ec = INVALID_ACCESS_ERR;
2036 return element->imageSourceURL();
2040 void Internals::simulateAudioInterruption(Node* node)
2043 HTMLMediaElement* element = toHTMLMediaElement(node);
2044 element->player()->simulateAudioInterruption();
2051 bool Internals::isSelectPopupVisible(Node* node)
2053 if (!isHTMLSelectElement(node))
2056 HTMLSelectElement* select = toHTMLSelectElement(node);
2058 auto renderer = select->renderer();
2059 if (!renderer->isMenuList())
2063 RenderMenuList* menuList = toRenderMenuList(renderer);
2064 return menuList->popupIsVisible();
2067 #endif // !PLATFORM(IOS)
2070 String Internals::captionsStyleSheetOverride(ExceptionCode& ec)
2072 Document* document = contextDocument();
2073 if (!document || !document->page()) {
2074 ec = INVALID_ACCESS_ERR;
2075 return emptyString();
2078 #if ENABLE(VIDEO_TRACK)
2079 return document->page()->group().captionPreferences()->captionsStyleSheetOverride();
2081 return emptyString();
2085 void Internals::setCaptionsStyleSheetOverride(const String& override, ExceptionCode& ec)
2087 Document* document = contextDocument();
2088 if (!document || !document->page()) {
2089 ec = INVALID_ACCESS_ERR;
2093 #if ENABLE(VIDEO_TRACK)
2094 document->page()->group().captionPreferences()->setCaptionsStyleSheetOverride(override);
2096 UNUSED_PARAM(override);
2100 void Internals::setPrimaryAudioTrackLanguageOverride(const String& language, ExceptionCode& ec)
2102 Document* document = contextDocument();
2103 if (!document || !document->page()) {
2104 ec = INVALID_ACCESS_ERR;
2108 #if ENABLE(VIDEO_TRACK)
2109 document->page()->group().captionPreferences()->setPrimaryAudioTrackLanguageOverride(language);
2111 UNUSED_PARAM(language);
2115 void Internals::setCaptionDisplayMode(const String& mode, ExceptionCode& ec)
2117 Document* document = contextDocument();
2118 if (!document || !document->page()) {
2119 ec = INVALID_ACCESS_ERR;
2123 #if ENABLE(VIDEO_TRACK)
2124 CaptionUserPreferences* captionPreferences = document->page()->group().captionPreferences();
2126 if (equalIgnoringCase(mode, "Automatic"))
2127 captionPreferences->setCaptionDisplayMode(CaptionUserPreferences::Automatic);
2128 else if (equalIgnoringCase(mode, "ForcedOnly"))
2129 captionPreferences->setCaptionDisplayMode(CaptionUserPreferences::ForcedOnly);
2130 else if (equalIgnoringCase(mode, "AlwaysOn"))
2131 captionPreferences->setCaptionDisplayMode(CaptionUserPreferences::AlwaysOn);
2140 PassRefPtr<TimeRanges> Internals::createTimeRanges(Float32Array* startTimes, Float32Array* endTimes)
2142 ASSERT(startTimes && endTimes);
2143 ASSERT(startTimes->length() == endTimes->length());
2144 RefPtr<TimeRanges> ranges = TimeRanges::create();
2146 unsigned count = std::min(startTimes->length(), endTimes->length());
2147 for (unsigned i = 0; i < count; ++i)
2148 ranges->add(startTimes->item(i), endTimes->item(i));
2152 double Internals::closestTimeToTimeRanges(double time, TimeRanges* ranges)
2154 return ranges->nearest(time);
2158 PassRefPtr<ClientRect> Internals::selectionBounds(ExceptionCode& ec)
2160 Document* document = contextDocument();
2161 if (!document || !document->frame()) {
2162 ec = INVALID_ACCESS_ERR;
2163 return ClientRect::create();
2166 return ClientRect::create(document->frame()->selection().selectionBounds());
2169 #if ENABLE(VIBRATION)
2170 bool Internals::isVibrating()
2172 Page* page = contextDocument()->page();
2175 return Vibration::from(page)->isVibrating();
2179 bool Internals::isPluginUnavailabilityIndicatorObscured(Element* element, ExceptionCode& ec)
2182 ec = INVALID_ACCESS_ERR;
2186 auto renderer = element->renderer();
2187 if (!renderer || !renderer->isEmbeddedObject()) {
2188 ec = INVALID_ACCESS_ERR;
2192 RenderEmbeddedObject* embed = toRenderEmbeddedObject(renderer);
2193 return embed->isReplacementObscured();
2196 bool Internals::isPluginSnapshotted(Element* element, ExceptionCode& ec)
2199 ec = INVALID_ACCESS_ERR;
2202 HTMLPlugInElement* pluginElement = toHTMLPlugInElement(element);
2203 return pluginElement->displayState() <= HTMLPlugInElement::DisplayingSnapshot;
2206 #if ENABLE(MEDIA_SOURCE)
2207 void Internals::initializeMockMediaSource()
2209 #if USE(AVFOUNDATION)
2210 WebCore::Settings::setAVFoundationEnabled(false);
2212 MediaPlayerFactorySupport::callRegisterMediaEngine(MockMediaPlayerMediaSource::registerMediaEngine);
2217 void Internals::beginMediaSessionInterruption()
2219 MediaSessionManager::sharedManager().beginInterruption(MediaSession::SystemInterruption);
2222 void Internals::endMediaSessionInterruption(const String& flagsString)
2224 MediaSession::EndInterruptionFlags flags = MediaSession::NoFlags;
2226 if (equalIgnoringCase(flagsString, "MayResumePlaying"))
2227 flags = MediaSession::MayResumePlaying;
2229 MediaSessionManager::sharedManager().endInterruption(flags);
2232 void Internals::applicationWillEnterForeground() const
2234 MediaSessionManager::sharedManager().applicationWillEnterForeground();
2237 void Internals::applicationWillEnterBackground() const
2239 MediaSessionManager::sharedManager().applicationWillEnterBackground();
2242 void Internals::setMediaSessionRestrictions(const String& mediaTypeString, const String& restrictionsString, ExceptionCode& ec)
2244 MediaSession::MediaType mediaType = MediaSession::None;
2245 if (equalIgnoringCase(mediaTypeString, "Video"))
2246 mediaType = MediaSession::Video;
2247 else if (equalIgnoringCase(mediaTypeString, "Audio"))
2248 mediaType = MediaSession::Audio;
2249 else if (equalIgnoringCase(mediaTypeString, "WebAudio"))
2250 mediaType = MediaSession::WebAudio;
2252 ec = INVALID_ACCESS_ERR;
2256 MediaSessionManager::SessionRestrictions restrictions = MediaSessionManager::sharedManager().restrictions(mediaType);
2257 MediaSessionManager::sharedManager().removeRestriction(mediaType, restrictions);
2259 restrictions = MediaSessionManager::NoRestrictions;
2261 if (equalIgnoringCase(restrictionsString, "ConcurrentPlaybackNotPermitted"))
2262 restrictions = MediaSessionManager::ConcurrentPlaybackNotPermitted;
2263 if (equalIgnoringCase(restrictionsString, "InlineVideoPlaybackRestricted"))
2264 restrictions += MediaSessionManager::InlineVideoPlaybackRestricted;
2265 if (equalIgnoringCase(restrictionsString, "MetadataPreloadingNotPermitted"))
2266 restrictions += MediaSessionManager::MetadataPreloadingNotPermitted;
2267 if (equalIgnoringCase(restrictionsString, "AutoPreloadingNotPermitted"))
2268 restrictions += MediaSessionManager::AutoPreloadingNotPermitted;
2269 if (equalIgnoringCase(restrictionsString, "BackgroundPlaybackNotPermitted"))
2270 restrictions += MediaSessionManager::BackgroundPlaybackNotPermitted;
2272 MediaSessionManager::sharedManager().addRestriction(mediaType, restrictions);
2275 void Internals::postRemoteControlCommand(const String& commandString, ExceptionCode& ec)
2277 MediaSession::RemoteControlCommandType command;
2279 if (equalIgnoringCase(commandString, "Play"))
2280 command = MediaSession::PlayCommand;
2281 else if (equalIgnoringCase(commandString, "Pause"))
2282 command = MediaSession::PauseCommand;
2283 else if (equalIgnoringCase(commandString, "Stop"))
2284 command = MediaSession::StopCommand;
2285 else if (equalIgnoringCase(commandString, "TogglePlayPause"))
2286 command = MediaSession::TogglePlayPauseCommand;
2287 else if (equalIgnoringCase(commandString, "BeginSeekingBackward"))
2288 command = MediaSession::BeginSeekingBackwardCommand;
2289 else if (equalIgnoringCase(commandString, "EndSeekingBackward"))
2290 command = MediaSession::EndSeekingBackwardCommand;
2291 else if (equalIgnoringCase(commandString, "BeginSeekingForward"))
2292 command = MediaSession::BeginSeekingForwardCommand;
2293 else if (equalIgnoringCase(commandString, "EndSeekingForward"))
2294 command = MediaSession::EndSeekingForwardCommand;
2296 ec = INVALID_ACCESS_ERR;
2300 MediaSessionManager::sharedManager().didReceiveRemoteControlCommand(command);
2302 #endif // ENABLE(VIDEO)
2304 void Internals::simulateSystemSleep() const
2307 MediaSessionManager::sharedManager().systemWillSleep();
2311 void Internals::simulateSystemWake() const
2314 MediaSessionManager::sharedManager().systemDidWake();