Home | History | Annotate | Download | only in testing
      1 /*
      2  * Copyright (C) 2012 Google Inc. All rights reserved.
      3  * Copyright (C) 2013 Apple Inc. All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *
      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.
     14  *
     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.
     25  */
     26 
     27 #include "config.h"
     28 #include "core/testing/Internals.h"
     29 
     30 #include "bindings/v8/ExceptionMessages.h"
     31 #include "bindings/v8/ExceptionState.h"
     32 #include "bindings/v8/ScriptFunction.h"
     33 #include "bindings/v8/ScriptPromise.h"
     34 #include "bindings/v8/ScriptPromiseResolver.h"
     35 #include "bindings/v8/SerializedScriptValue.h"
     36 #include "bindings/v8/V8ThrowException.h"
     37 #include "core/InternalRuntimeFlags.h"
     38 #include "core/animation/AnimationTimeline.h"
     39 #include "core/css/StyleSheetContents.h"
     40 #include "core/css/resolver/StyleResolver.h"
     41 #include "core/css/resolver/StyleResolverStats.h"
     42 #include "core/css/resolver/ViewportStyleResolver.h"
     43 #include "core/dom/ClientRect.h"
     44 #include "core/dom/ClientRectList.h"
     45 #include "core/dom/DOMStringList.h"
     46 #include "core/dom/Document.h"
     47 #include "core/dom/DocumentMarker.h"
     48 #include "core/dom/DocumentMarkerController.h"
     49 #include "core/dom/Element.h"
     50 #include "core/dom/ExceptionCode.h"
     51 #include "core/dom/FullscreenElementStack.h"
     52 #include "core/dom/NodeRenderStyle.h"
     53 #include "core/dom/PseudoElement.h"
     54 #include "core/dom/Range.h"
     55 #include "core/dom/StaticNodeList.h"
     56 #include "core/dom/TreeScope.h"
     57 #include "core/dom/ViewportDescription.h"
     58 #include "core/dom/shadow/ComposedTreeWalker.h"
     59 #include "core/dom/shadow/ElementShadow.h"
     60 #include "core/dom/shadow/SelectRuleFeatureSet.h"
     61 #include "core/dom/shadow/ShadowRoot.h"
     62 #include "core/editing/Editor.h"
     63 #include "core/editing/PlainTextRange.h"
     64 #include "core/editing/SpellCheckRequester.h"
     65 #include "core/editing/SpellChecker.h"
     66 #include "core/editing/SurroundingText.h"
     67 #include "core/editing/TextIterator.h"
     68 #include "core/fetch/MemoryCache.h"
     69 #include "core/fetch/ResourceFetcher.h"
     70 #include "core/frame/DOMPoint.h"
     71 #include "core/frame/LocalDOMWindow.h"
     72 #include "core/frame/EventHandlerRegistry.h"
     73 #include "core/frame/FrameView.h"
     74 #include "core/frame/LocalFrame.h"
     75 #include "core/frame/Settings.h"
     76 #include "core/html/HTMLContentElement.h"
     77 #include "core/html/HTMLIFrameElement.h"
     78 #include "core/html/HTMLInputElement.h"
     79 #include "core/html/HTMLMediaElement.h"
     80 #include "core/html/HTMLSelectElement.h"
     81 #include "core/html/HTMLTextAreaElement.h"
     82 #include "core/html/forms/FormController.h"
     83 #include "core/html/shadow/ShadowElementNames.h"
     84 #include "core/html/shadow/TextControlInnerElements.h"
     85 #include "core/inspector/InspectorClient.h"
     86 #include "core/inspector/InspectorConsoleAgent.h"
     87 #include "core/inspector/InspectorController.h"
     88 #include "core/inspector/InspectorCounters.h"
     89 #include "core/inspector/InspectorFrontendChannel.h"
     90 #include "core/inspector/InspectorInstrumentation.h"
     91 #include "core/inspector/InspectorOverlay.h"
     92 #include "core/inspector/InstrumentingAgents.h"
     93 #include "core/loader/FrameLoader.h"
     94 #include "core/loader/HistoryItem.h"
     95 #include "core/page/Chrome.h"
     96 #include "core/page/ChromeClient.h"
     97 #include "core/page/EventHandler.h"
     98 #include "core/page/FocusController.h"
     99 #include "core/page/NetworkStateNotifier.h"
    100 #include "core/page/Page.h"
    101 #include "core/page/PagePopupController.h"
    102 #include "core/page/PrintContext.h"
    103 #include "core/rendering/RenderLayer.h"
    104 #include "core/rendering/RenderMenuList.h"
    105 #include "core/rendering/RenderObject.h"
    106 #include "core/rendering/RenderTreeAsText.h"
    107 #include "core/rendering/RenderView.h"
    108 #include "core/rendering/compositing/CompositedLayerMapping.h"
    109 #include "core/rendering/compositing/RenderLayerCompositor.h"
    110 #include "core/testing/GCObservation.h"
    111 #include "core/testing/InternalProfilers.h"
    112 #include "core/testing/InternalSettings.h"
    113 #include "core/testing/LayerRect.h"
    114 #include "core/testing/LayerRectList.h"
    115 #include "core/testing/MallocStatistics.h"
    116 #include "core/testing/MockPagePopupDriver.h"
    117 #include "core/testing/TypeConversions.h"
    118 #include "core/workers/WorkerThread.h"
    119 #include "platform/Cursor.h"
    120 #include "platform/Language.h"
    121 #include "platform/RuntimeEnabledFeatures.h"
    122 #include "platform/TraceEvent.h"
    123 #include "platform/geometry/IntRect.h"
    124 #include "platform/geometry/LayoutRect.h"
    125 #include "platform/graphics/GraphicsLayer.h"
    126 #include "platform/graphics/filters/FilterOperation.h"
    127 #include "platform/graphics/filters/FilterOperations.h"
    128 #include "platform/weborigin/SchemeRegistry.h"
    129 #include "public/platform/Platform.h"
    130 #include "public/platform/WebConnectionType.h"
    131 #include "public/platform/WebGraphicsContext3D.h"
    132 #include "public/platform/WebGraphicsContext3DProvider.h"
    133 #include "public/platform/WebLayer.h"
    134 #include "wtf/InstanceCounter.h"
    135 #include "wtf/PassOwnPtr.h"
    136 #include "wtf/dtoa.h"
    137 #include "wtf/text/StringBuffer.h"
    138 #include <v8.h>
    139 
    140 namespace WebCore {
    141 
    142 // FIXME: oilpan: These will be removed soon.
    143 static MockPagePopupDriver* s_pagePopupDriver = 0;
    144 
    145 using namespace HTMLNames;
    146 
    147 static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerTypes& result)
    148 {
    149     if (markerType.isEmpty() || equalIgnoringCase(markerType, "all"))
    150         result = DocumentMarker::AllMarkers();
    151     else if (equalIgnoringCase(markerType, "Spelling"))
    152         result =  DocumentMarker::Spelling;
    153     else if (equalIgnoringCase(markerType, "Grammar"))
    154         result =  DocumentMarker::Grammar;
    155     else if (equalIgnoringCase(markerType, "TextMatch"))
    156         result =  DocumentMarker::TextMatch;
    157     else
    158         return false;
    159 
    160     return true;
    161 }
    162 
    163 static SpellCheckRequester* spellCheckRequester(Document* document)
    164 {
    165     if (!document || !document->frame())
    166         return 0;
    167     return &document->frame()->spellChecker().spellCheckRequester();
    168 }
    169 
    170 const char* Internals::internalsId = "internals";
    171 
    172 PassRefPtrWillBeRawPtr<Internals> Internals::create(Document* document)
    173 {
    174     return adoptRefWillBeNoop(new Internals(document));
    175 }
    176 
    177 Internals::~Internals()
    178 {
    179 }
    180 
    181 void Internals::resetToConsistentState(Page* page)
    182 {
    183     ASSERT(page);
    184 
    185     page->setDeviceScaleFactor(1);
    186     page->setIsCursorVisible(true);
    187     page->setPageScaleFactor(1, IntPoint(0, 0));
    188     TextRun::setAllowsRoundingHacks(false);
    189     WebCore::overrideUserPreferredLanguages(Vector<AtomicString>());
    190     delete s_pagePopupDriver;
    191     s_pagePopupDriver = 0;
    192     page->chrome().client().resetPagePopupDriver();
    193     if (!page->deprecatedLocalMainFrame()->spellChecker().isContinuousSpellCheckingEnabled())
    194         page->deprecatedLocalMainFrame()->spellChecker().toggleContinuousSpellChecking();
    195     if (page->deprecatedLocalMainFrame()->editor().isOverwriteModeEnabled())
    196         page->deprecatedLocalMainFrame()->editor().toggleOverwriteModeEnabled();
    197 
    198     if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
    199         scrollingCoordinator->reset();
    200 
    201     page->deprecatedLocalMainFrame()->view()->clear();
    202 }
    203 
    204 Internals::Internals(Document* document)
    205     : ContextLifecycleObserver(document)
    206     , m_runtimeFlags(InternalRuntimeFlags::create())
    207 {
    208 }
    209 
    210 Document* Internals::contextDocument() const
    211 {
    212     return toDocument(executionContext());
    213 }
    214 
    215 LocalFrame* Internals::frame() const
    216 {
    217     if (!contextDocument())
    218         return 0;
    219     return contextDocument()->frame();
    220 }
    221 
    222 InternalSettings* Internals::settings() const
    223 {
    224     Document* document = contextDocument();
    225     if (!document)
    226         return 0;
    227     Page* page = document->page();
    228     if (!page)
    229         return 0;
    230     return InternalSettings::from(*page);
    231 }
    232 
    233 InternalRuntimeFlags* Internals::runtimeFlags() const
    234 {
    235     return m_runtimeFlags.get();
    236 }
    237 
    238 InternalProfilers* Internals::profilers()
    239 {
    240     if (!m_profilers)
    241         m_profilers = InternalProfilers::create();
    242     return m_profilers.get();
    243 }
    244 
    245 unsigned Internals::workerThreadCount() const
    246 {
    247     return WorkerThread::workerThreadCount();
    248 }
    249 
    250 String Internals::address(Node* node)
    251 {
    252     char buf[32];
    253     sprintf(buf, "%p", node);
    254 
    255     return String(buf);
    256 }
    257 
    258 PassRefPtrWillBeRawPtr<GCObservation> Internals::observeGC(ScriptValue scriptValue)
    259 {
    260     v8::Handle<v8::Value> observedValue = scriptValue.v8Value();
    261     ASSERT(!observedValue.IsEmpty());
    262     if (observedValue->IsNull() || observedValue->IsUndefined()) {
    263         V8ThrowException::throwTypeError("value to observe is null or undefined", v8::Isolate::GetCurrent());
    264         return nullptr;
    265     }
    266 
    267     return GCObservation::create(observedValue);
    268 }
    269 
    270 unsigned Internals::updateStyleAndReturnAffectedElementCount(ExceptionState& exceptionState) const
    271 {
    272     Document* document = contextDocument();
    273     if (!document) {
    274         exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
    275         return 0;
    276     }
    277 
    278     unsigned beforeCount = document->styleEngine()->resolverAccessCount();
    279     document->updateRenderTreeIfNeeded();
    280     return document->styleEngine()->resolverAccessCount() - beforeCount;
    281 }
    282 
    283 unsigned Internals::needsLayoutCount(ExceptionState& exceptionState) const
    284 {
    285     LocalFrame* contextFrame = frame();
    286     if (!contextFrame) {
    287         exceptionState.throwDOMException(InvalidAccessError, "No context frame is available.");
    288         return 0;
    289     }
    290 
    291     bool isPartial;
    292     unsigned needsLayoutObjects;
    293     unsigned totalObjects;
    294     contextFrame->countObjectsNeedingLayout(needsLayoutObjects, totalObjects, isPartial);
    295     return needsLayoutObjects;
    296 }
    297 
    298 bool Internals::isPreloaded(const String& url)
    299 {
    300     Document* document = contextDocument();
    301     return document->fetcher()->isPreloaded(url);
    302 }
    303 
    304 bool Internals::isLoadingFromMemoryCache(const String& url)
    305 {
    306     if (!contextDocument())
    307         return false;
    308     Resource* resource = memoryCache()->resourceForURL(contextDocument()->completeURL(url));
    309     return resource && resource->status() == Resource::Cached;
    310 }
    311 
    312 void Internals::crash()
    313 {
    314     CRASH();
    315 }
    316 
    317 void Internals::setStyleResolverStatsEnabled(bool enabled)
    318 {
    319     Document* document = contextDocument();
    320     if (enabled)
    321         document->ensureStyleResolver().enableStats(StyleResolver::ReportSlowStats);
    322     else
    323         document->ensureStyleResolver().disableStats();
    324 }
    325 
    326 String Internals::styleResolverStatsReport(ExceptionState& exceptionState) const
    327 {
    328     Document* document = contextDocument();
    329     if (!document->ensureStyleResolver().stats()) {
    330         exceptionState.throwDOMException(InvalidStateError, "Style resolver stats not enabled");
    331         return String();
    332     }
    333     return document->ensureStyleResolver().stats()->report();
    334 }
    335 
    336 String Internals::styleResolverStatsTotalsReport(ExceptionState& exceptionState) const
    337 {
    338     Document* document = contextDocument();
    339     if (!document->ensureStyleResolver().statsTotals()) {
    340         exceptionState.throwDOMException(InvalidStateError, "Style resolver stats not enabled");
    341         return String();
    342     }
    343     return document->ensureStyleResolver().statsTotals()->report();
    344 }
    345 
    346 bool Internals::isSharingStyle(Element* element1, Element* element2, ExceptionState& exceptionState) const
    347 {
    348     if (!element1 || !element2) {
    349         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(element1 ? 2 : 1, "Element"));
    350         return false;
    351     }
    352     return element1->renderStyle() == element2->renderStyle();
    353 }
    354 
    355 bool Internals::isValidContentSelect(Element* insertionPoint, ExceptionState& exceptionState)
    356 {
    357     if (!insertionPoint || !insertionPoint->isInsertionPoint()) {
    358         exceptionState.throwDOMException(InvalidAccessError, "The insertion point provided is invalid.");
    359         return false;
    360     }
    361 
    362     return isHTMLContentElement(*insertionPoint) && toHTMLContentElement(*insertionPoint).isSelectValid();
    363 }
    364 
    365 Node* Internals::treeScopeRootNode(Node* node, ExceptionState& exceptionState)
    366 {
    367     if (!node) {
    368         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
    369         return 0;
    370     }
    371 
    372     return &node->treeScope().rootNode();
    373 }
    374 
    375 Node* Internals::parentTreeScope(Node* node, ExceptionState& exceptionState)
    376 {
    377     if (!node) {
    378         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
    379         return 0;
    380     }
    381     const TreeScope* parentTreeScope = node->treeScope().parentTreeScope();
    382     return parentTreeScope ? &parentTreeScope->rootNode() : 0;
    383 }
    384 
    385 bool Internals::hasSelectorForIdInShadow(Element* host, const AtomicString& idValue, ExceptionState& exceptionState)
    386 {
    387     if (!host || !host->shadow()) {
    388         exceptionState.throwDOMException(InvalidAccessError, "The host element provided is invalid, or does not have a shadow.");
    389         return 0;
    390     }
    391 
    392     return host->shadow()->ensureSelectFeatureSet().hasSelectorForId(idValue);
    393 }
    394 
    395 bool Internals::hasSelectorForClassInShadow(Element* host, const AtomicString& className, ExceptionState& exceptionState)
    396 {
    397     if (!host || !host->shadow()) {
    398         exceptionState.throwDOMException(InvalidAccessError, "The host element provided is invalid, or does not have a shadow.");
    399         return 0;
    400     }
    401 
    402     return host->shadow()->ensureSelectFeatureSet().hasSelectorForClass(className);
    403 }
    404 
    405 bool Internals::hasSelectorForAttributeInShadow(Element* host, const AtomicString& attributeName, ExceptionState& exceptionState)
    406 {
    407     if (!host || !host->shadow()) {
    408         exceptionState.throwDOMException(InvalidAccessError, "The host element provided is invalid, or does not have a shadow.");
    409         return 0;
    410     }
    411 
    412     return host->shadow()->ensureSelectFeatureSet().hasSelectorForAttribute(attributeName);
    413 }
    414 
    415 bool Internals::hasSelectorForPseudoClassInShadow(Element* host, const String& pseudoClass, ExceptionState& exceptionState)
    416 {
    417     if (!host || !host->shadow()) {
    418         exceptionState.throwDOMException(InvalidAccessError, "The host element provided is invalid, or does not have a shadow.");
    419         return 0;
    420     }
    421 
    422     const SelectRuleFeatureSet& featureSet = host->shadow()->ensureSelectFeatureSet();
    423     if (pseudoClass == "checked")
    424         return featureSet.hasSelectorForChecked();
    425     if (pseudoClass == "enabled")
    426         return featureSet.hasSelectorForEnabled();
    427     if (pseudoClass == "disabled")
    428         return featureSet.hasSelectorForDisabled();
    429     if (pseudoClass == "indeterminate")
    430         return featureSet.hasSelectorForIndeterminate();
    431     if (pseudoClass == "link")
    432         return featureSet.hasSelectorForLink();
    433     if (pseudoClass == "target")
    434         return featureSet.hasSelectorForTarget();
    435     if (pseudoClass == "visited")
    436         return featureSet.hasSelectorForVisited();
    437 
    438     ASSERT_NOT_REACHED();
    439     return false;
    440 }
    441 
    442 unsigned short Internals::compareTreeScopePosition(const Node* node1, const Node* node2, ExceptionState& exceptionState) const
    443 {
    444     if (!node1 || !node2) {
    445         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(node1 ? 2 : 1, "Node"));
    446         return 0;
    447     }
    448     const TreeScope* treeScope1 = node1->isDocumentNode() ? static_cast<const TreeScope*>(toDocument(node1)) :
    449         node1->isShadowRoot() ? static_cast<const TreeScope*>(toShadowRoot(node1)) : 0;
    450     const TreeScope* treeScope2 = node2->isDocumentNode() ? static_cast<const TreeScope*>(toDocument(node2)) :
    451         node2->isShadowRoot() ? static_cast<const TreeScope*>(toShadowRoot(node2)) : 0;
    452     if (!treeScope1 || !treeScope2) {
    453         exceptionState.throwDOMException(InvalidAccessError, String::format("The %s node is neither a document node, nor a shadow root.", treeScope1 ? "second" : "first"));
    454         return 0;
    455     }
    456     return treeScope1->comparePosition(*treeScope2);
    457 }
    458 
    459 unsigned Internals::numberOfActiveAnimations() const
    460 {
    461     LocalFrame* contextFrame = frame();
    462     Document* document = contextFrame->document();
    463     return document->timeline().numberOfActiveAnimationsForTesting();
    464 }
    465 
    466 void Internals::pauseAnimations(double pauseTime, ExceptionState& exceptionState)
    467 {
    468     if (pauseTime < 0) {
    469         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::indexExceedsMinimumBound("pauseTime", pauseTime, 0.0));
    470         return;
    471     }
    472 
    473     frame()->view()->updateLayoutAndStyleForPainting();
    474     frame()->document()->timeline().pauseAnimationsForTesting(pauseTime);
    475 }
    476 
    477 bool Internals::hasShadowInsertionPoint(const Node* root, ExceptionState& exceptionState) const
    478 {
    479     if (root && root->isShadowRoot())
    480         return toShadowRoot(root)->containsShadowElements();
    481 
    482     exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
    483     return 0;
    484 }
    485 
    486 bool Internals::hasContentElement(const Node* root, ExceptionState& exceptionState) const
    487 {
    488     if (root && root->isShadowRoot())
    489         return toShadowRoot(root)->containsContentElements();
    490 
    491     exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
    492     return 0;
    493 }
    494 
    495 size_t Internals::countElementShadow(const Node* root, ExceptionState& exceptionState) const
    496 {
    497     if (!root || !root->isShadowRoot()) {
    498         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
    499         return 0;
    500     }
    501     return toShadowRoot(root)->childShadowRootCount();
    502 }
    503 
    504 Node* Internals::nextSiblingByWalker(Node* node, ExceptionState& exceptionState)
    505 {
    506     if (!node) {
    507         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
    508         return 0;
    509     }
    510     ComposedTreeWalker walker(node);
    511     walker.nextSibling();
    512     return walker.get();
    513 }
    514 
    515 Node* Internals::firstChildByWalker(Node* node, ExceptionState& exceptionState)
    516 {
    517     if (!node) {
    518         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
    519         return 0;
    520     }
    521     ComposedTreeWalker walker(node);
    522     walker.firstChild();
    523     return walker.get();
    524 }
    525 
    526 Node* Internals::lastChildByWalker(Node* node, ExceptionState& exceptionState)
    527 {
    528     if (!node) {
    529         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
    530         return 0;
    531     }
    532     ComposedTreeWalker walker(node);
    533     walker.lastChild();
    534     return walker.get();
    535 }
    536 
    537 Node* Internals::nextNodeByWalker(Node* node, ExceptionState& exceptionState)
    538 {
    539     if (!node) {
    540         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
    541         return 0;
    542     }
    543     ComposedTreeWalker walker(node);
    544     walker.next();
    545     return walker.get();
    546 }
    547 
    548 Node* Internals::previousNodeByWalker(Node* node, ExceptionState& exceptionState)
    549 {
    550     if (!node) {
    551         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
    552         return 0;
    553     }
    554     ComposedTreeWalker walker(node);
    555     walker.previous();
    556     return walker.get();
    557 }
    558 
    559 String Internals::elementRenderTreeAsText(Element* element, ExceptionState& exceptionState)
    560 {
    561     if (!element) {
    562         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
    563         return String();
    564     }
    565 
    566     String representation = externalRepresentation(element);
    567     if (representation.isEmpty()) {
    568         exceptionState.throwDOMException(InvalidAccessError, "The element provided has no external representation.");
    569         return String();
    570     }
    571 
    572     return representation;
    573 }
    574 
    575 PassRefPtrWillBeRawPtr<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisitedInfo(Node* node, ExceptionState& exceptionState) const
    576 {
    577     if (!node) {
    578         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
    579         return nullptr;
    580     }
    581 
    582     bool allowVisitedStyle = true;
    583     return CSSComputedStyleDeclaration::create(node, allowVisitedStyle);
    584 }
    585 
    586 ShadowRoot* Internals::shadowRoot(Element* host, ExceptionState& exceptionState)
    587 {
    588     // FIXME: Internals::shadowRoot() in tests should be converted to youngestShadowRoot() or oldestShadowRoot().
    589     // https://bugs.webkit.org/show_bug.cgi?id=78465
    590     return youngestShadowRoot(host, exceptionState);
    591 }
    592 
    593 ShadowRoot* Internals::youngestShadowRoot(Element* host, ExceptionState& exceptionState)
    594 {
    595     if (!host) {
    596         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
    597         return 0;
    598     }
    599 
    600     if (ElementShadow* shadow = host->shadow())
    601         return shadow->youngestShadowRoot();
    602     return 0;
    603 }
    604 
    605 ShadowRoot* Internals::oldestShadowRoot(Element* host, ExceptionState& exceptionState)
    606 {
    607     if (!host) {
    608         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
    609         return 0;
    610     }
    611 
    612     if (ElementShadow* shadow = host->shadow())
    613         return shadow->oldestShadowRoot();
    614     return 0;
    615 }
    616 
    617 ShadowRoot* Internals::youngerShadowRoot(Node* shadow, ExceptionState& exceptionState)
    618 {
    619     if (!shadow || !shadow->isShadowRoot()) {
    620         exceptionState.throwDOMException(InvalidAccessError, "The node provided is not a valid shadow root.");
    621         return 0;
    622     }
    623 
    624     return toShadowRoot(shadow)->youngerShadowRoot();
    625 }
    626 
    627 String Internals::shadowRootType(const Node* root, ExceptionState& exceptionState) const
    628 {
    629     if (!root || !root->isShadowRoot()) {
    630         exceptionState.throwDOMException(InvalidAccessError, "The node provided is not a valid shadow root.");
    631         return String();
    632     }
    633 
    634     switch (toShadowRoot(root)->type()) {
    635     case ShadowRoot::UserAgentShadowRoot:
    636         return String("UserAgentShadowRoot");
    637     case ShadowRoot::AuthorShadowRoot:
    638         return String("AuthorShadowRoot");
    639     default:
    640         ASSERT_NOT_REACHED();
    641         return String("Unknown");
    642     }
    643 }
    644 
    645 const AtomicString& Internals::shadowPseudoId(Element* element, ExceptionState& exceptionState)
    646 {
    647     if (!element) {
    648         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
    649         return nullAtom;
    650     }
    651 
    652     return element->shadowPseudoId();
    653 }
    654 
    655 void Internals::setShadowPseudoId(Element* element, const AtomicString& id, ExceptionState& exceptionState)
    656 {
    657     if (!element) {
    658         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
    659         return;
    660     }
    661 
    662     return element->setShadowPseudoId(id);
    663 }
    664 
    665 String Internals::visiblePlaceholder(Element* element)
    666 {
    667     if (element && isHTMLTextFormControlElement(*element)) {
    668         if (toHTMLTextFormControlElement(element)->placeholderShouldBeVisible())
    669             return toHTMLTextFormControlElement(element)->placeholderElement()->textContent();
    670     }
    671 
    672     return String();
    673 }
    674 
    675 void Internals::selectColorInColorChooser(Element* element, const String& colorValue)
    676 {
    677     ASSERT(element);
    678     if (!isHTMLInputElement(*element))
    679         return;
    680     Color color;
    681     if (!color.setFromString(colorValue))
    682         return;
    683     toHTMLInputElement(*element).selectColorInColorChooser(color);
    684 }
    685 
    686 bool Internals::hasAutofocusRequest(Document* document)
    687 {
    688     if (!document)
    689         document = contextDocument();
    690     return document->autofocusElement();
    691 }
    692 
    693 bool Internals::hasAutofocusRequest()
    694 {
    695     return hasAutofocusRequest(0);
    696 }
    697 
    698 Vector<String> Internals::formControlStateOfHistoryItem(ExceptionState& exceptionState)
    699 {
    700     HistoryItem* mainItem = frame()->loader().currentItem();
    701     if (!mainItem) {
    702         exceptionState.throwDOMException(InvalidAccessError, "No history item is available.");
    703         return Vector<String>();
    704     }
    705     return mainItem->documentState();
    706 }
    707 
    708 void Internals::setFormControlStateOfHistoryItem(const Vector<String>& state, ExceptionState& exceptionState)
    709 {
    710     HistoryItem* mainItem = frame()->loader().currentItem();
    711     if (!mainItem) {
    712         exceptionState.throwDOMException(InvalidAccessError, "No history item is available.");
    713         return;
    714     }
    715     mainItem->clearDocumentState();
    716     mainItem->setDocumentState(state);
    717 }
    718 
    719 void Internals::setEnableMockPagePopup(bool enabled, ExceptionState& exceptionState)
    720 {
    721     Document* document = contextDocument();
    722     if (!document || !document->page())
    723         return;
    724     Page* page = document->page();
    725     if (!enabled) {
    726         page->chrome().client().resetPagePopupDriver();
    727         return;
    728     }
    729     if (!s_pagePopupDriver)
    730         s_pagePopupDriver = MockPagePopupDriver::create(page->deprecatedLocalMainFrame()).leakPtr();
    731     page->chrome().client().setPagePopupDriver(s_pagePopupDriver);
    732 }
    733 
    734 PassRefPtrWillBeRawPtr<PagePopupController> Internals::pagePopupController()
    735 {
    736     return s_pagePopupDriver ? s_pagePopupDriver->pagePopupController() : 0;
    737 }
    738 
    739 PassRefPtrWillBeRawPtr<ClientRect> Internals::unscaledViewportRect(ExceptionState& exceptionState)
    740 {
    741     Document* document = contextDocument();
    742     if (!document || !document->view()) {
    743         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's viewport cannot be retrieved." : "No context document can be obtained.");
    744         return ClientRect::create();
    745     }
    746 
    747     return ClientRect::create(document->view()->visibleContentRect());
    748 }
    749 
    750 PassRefPtrWillBeRawPtr<ClientRect> Internals::absoluteCaretBounds(ExceptionState& exceptionState)
    751 {
    752     Document* document = contextDocument();
    753     if (!document || !document->frame()) {
    754         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "No context document can be obtained.");
    755         return ClientRect::create();
    756     }
    757 
    758     return ClientRect::create(document->frame()->selection().absoluteCaretBounds());
    759 }
    760 
    761 PassRefPtrWillBeRawPtr<ClientRect> Internals::boundingBox(Element* element, ExceptionState& exceptionState)
    762 {
    763     if (!element) {
    764         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
    765         return ClientRect::create();
    766     }
    767 
    768     element->document().updateLayoutIgnorePendingStylesheets();
    769     RenderObject* renderer = element->renderer();
    770     if (!renderer)
    771         return ClientRect::create();
    772     return ClientRect::create(renderer->absoluteBoundingBoxRectIgnoringTransforms());
    773 }
    774 
    775 unsigned Internals::markerCountForNode(Node* node, const String& markerType, ExceptionState& exceptionState)
    776 {
    777     if (!node) {
    778         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
    779         return 0;
    780     }
    781 
    782     DocumentMarker::MarkerTypes markerTypes = 0;
    783     if (!markerTypesFrom(markerType, markerTypes)) {
    784         exceptionState.throwDOMException(SyntaxError, "The marker type provided ('" + markerType + "') is invalid.");
    785         return 0;
    786     }
    787 
    788     return node->document().markers().markersFor(node, markerTypes).size();
    789 }
    790 
    791 unsigned Internals::activeMarkerCountForNode(Node* node, ExceptionState& exceptionState)
    792 {
    793     if (!node) {
    794         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
    795         return 0;
    796     }
    797 
    798     // Only TextMatch markers can be active.
    799     DocumentMarker::MarkerType markerType = DocumentMarker::TextMatch;
    800     WillBeHeapVector<DocumentMarker*> markers = node->document().markers().markersFor(node, markerType);
    801 
    802     unsigned activeMarkerCount = 0;
    803     for (WillBeHeapVector<DocumentMarker*>::iterator iter = markers.begin(); iter != markers.end(); ++iter) {
    804         if ((*iter)->activeMatch())
    805             activeMarkerCount++;
    806     }
    807 
    808     return activeMarkerCount;
    809 }
    810 
    811 DocumentMarker* Internals::markerAt(Node* node, const String& markerType, unsigned index, ExceptionState& exceptionState)
    812 {
    813     if (!node) {
    814         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
    815         return 0;
    816     }
    817 
    818     DocumentMarker::MarkerTypes markerTypes = 0;
    819     if (!markerTypesFrom(markerType, markerTypes)) {
    820         exceptionState.throwDOMException(SyntaxError, "The marker type provided ('" + markerType + "') is invalid.");
    821         return 0;
    822     }
    823 
    824     WillBeHeapVector<DocumentMarker*> markers = node->document().markers().markersFor(node, markerTypes);
    825     if (markers.size() <= index)
    826         return 0;
    827     return markers[index];
    828 }
    829 
    830 PassRefPtrWillBeRawPtr<Range> Internals::markerRangeForNode(Node* node, const String& markerType, unsigned index, ExceptionState& exceptionState)
    831 {
    832     DocumentMarker* marker = markerAt(node, markerType, index, exceptionState);
    833     if (!marker)
    834         return nullptr;
    835     return Range::create(node->document(), node, marker->startOffset(), node, marker->endOffset());
    836 }
    837 
    838 String Internals::markerDescriptionForNode(Node* node, const String& markerType, unsigned index, ExceptionState& exceptionState)
    839 {
    840     DocumentMarker* marker = markerAt(node, markerType, index, exceptionState);
    841     if (!marker)
    842         return String();
    843     return marker->description();
    844 }
    845 
    846 void Internals::addTextMatchMarker(const Range* range, bool isActive)
    847 {
    848     range->ownerDocument().updateLayoutIgnorePendingStylesheets();
    849     range->ownerDocument().markers().addTextMatchMarker(range, isActive);
    850 }
    851 
    852 void Internals::setMarkersActive(Node* node, unsigned startOffset, unsigned endOffset, bool active, ExceptionState& exceptionState)
    853 {
    854     if (!node) {
    855         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Node"));
    856         return;
    857     }
    858 
    859     node->document().markers().setMarkersActive(node, startOffset, endOffset, active);
    860 }
    861 
    862 void Internals::setMarkedTextMatchesAreHighlighted(Document* document, bool highlight, ExceptionState&)
    863 {
    864     if (!document || !document->frame())
    865         return;
    866 
    867     document->frame()->editor().setMarkedTextMatchesAreHighlighted(highlight);
    868 }
    869 
    870 void Internals::setScrollViewPosition(Document* document, long x, long y, ExceptionState& exceptionState)
    871 {
    872     if (!document || !document->view()) {
    873         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's view cannot be retrieved." : "The document provided is invalid.");
    874         return;
    875     }
    876 
    877     FrameView* frameView = document->view();
    878     bool constrainsScrollingToContentEdgeOldValue = frameView->constrainsScrollingToContentEdge();
    879     bool scrollbarsSuppressedOldValue = frameView->scrollbarsSuppressed();
    880 
    881     frameView->setConstrainsScrollingToContentEdge(false);
    882     frameView->setScrollbarsSuppressed(false);
    883     frameView->setScrollOffsetFromInternals(IntPoint(x, y));
    884     frameView->setScrollbarsSuppressed(scrollbarsSuppressedOldValue);
    885     frameView->setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue);
    886 }
    887 
    888 String Internals::viewportAsText(Document* document, float, int availableWidth, int availableHeight, ExceptionState& exceptionState)
    889 {
    890     if (!document || !document->page()) {
    891         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's page cannot be retrieved." : "The document provided is invalid.");
    892         return String();
    893     }
    894 
    895     document->updateLayoutIgnorePendingStylesheets();
    896 
    897     Page* page = document->page();
    898 
    899     // Update initial viewport size.
    900     IntSize initialViewportSize(availableWidth, availableHeight);
    901     document->page()->deprecatedLocalMainFrame()->view()->setFrameRect(IntRect(IntPoint::zero(), initialViewportSize));
    902 
    903     ViewportDescription description = page->viewportDescription();
    904     PageScaleConstraints constraints = description.resolve(initialViewportSize, Length());
    905 
    906     constraints.fitToContentsWidth(constraints.layoutSize.width(), availableWidth);
    907 
    908     StringBuilder builder;
    909 
    910     builder.appendLiteral("viewport size ");
    911     builder.append(String::number(constraints.layoutSize.width()));
    912     builder.append('x');
    913     builder.append(String::number(constraints.layoutSize.height()));
    914 
    915     builder.appendLiteral(" scale ");
    916     builder.append(String::number(constraints.initialScale));
    917     builder.appendLiteral(" with limits [");
    918     builder.append(String::number(constraints.minimumScale));
    919     builder.appendLiteral(", ");
    920     builder.append(String::number(constraints.maximumScale));
    921 
    922     builder.appendLiteral("] and userScalable ");
    923     builder.append(description.userZoom ? "true" : "false");
    924 
    925     return builder.toString();
    926 }
    927 
    928 bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionState& exceptionState)
    929 {
    930     if (!textField) {
    931         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
    932         return false;
    933     }
    934 
    935     if (isHTMLInputElement(*textField))
    936         return toHTMLInputElement(*textField).lastChangeWasUserEdit();
    937 
    938     if (isHTMLTextAreaElement(*textField))
    939         return toHTMLTextAreaElement(*textField).lastChangeWasUserEdit();
    940 
    941     exceptionState.throwDOMException(InvalidNodeTypeError, "The element provided is not a TEXTAREA.");
    942     return false;
    943 }
    944 
    945 bool Internals::elementShouldAutoComplete(Element* element, ExceptionState& exceptionState)
    946 {
    947     if (!element) {
    948         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
    949         return false;
    950     }
    951 
    952     if (isHTMLInputElement(*element))
    953         return toHTMLInputElement(*element).shouldAutocomplete();
    954 
    955     exceptionState.throwDOMException(InvalidNodeTypeError, "The element provided is not an INPUT.");
    956     return false;
    957 }
    958 
    959 String Internals::suggestedValue(Element* element, ExceptionState& exceptionState)
    960 {
    961     if (!element) {
    962         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
    963         return String();
    964     }
    965 
    966     if (!element->isFormControlElement()) {
    967         exceptionState.throwDOMException(InvalidNodeTypeError, "The element provided is not a form control element.");
    968         return String();
    969     }
    970 
    971     String suggestedValue;
    972     if (isHTMLInputElement(*element))
    973         suggestedValue = toHTMLInputElement(*element).suggestedValue();
    974 
    975     if (isHTMLTextAreaElement(*element))
    976         suggestedValue = toHTMLTextAreaElement(*element).suggestedValue();
    977 
    978     if (isHTMLSelectElement(*element))
    979         suggestedValue = toHTMLSelectElement(*element).suggestedValue();
    980 
    981     return suggestedValue;
    982 }
    983 
    984 void Internals::setSuggestedValue(Element* element, const String& value, ExceptionState& exceptionState)
    985 {
    986     if (!element) {
    987         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
    988         return;
    989     }
    990 
    991     if (!element->isFormControlElement()) {
    992         exceptionState.throwDOMException(InvalidNodeTypeError, "The element provided is not a form control element.");
    993         return;
    994     }
    995 
    996     if (isHTMLInputElement(*element))
    997         toHTMLInputElement(*element).setSuggestedValue(value);
    998 
    999     if (isHTMLTextAreaElement(*element))
   1000         toHTMLTextAreaElement(*element).setSuggestedValue(value);
   1001 
   1002     if (isHTMLSelectElement(*element))
   1003         toHTMLSelectElement(*element).setSuggestedValue(value);
   1004 }
   1005 
   1006 void Internals::setEditingValue(Element* element, const String& value, ExceptionState& exceptionState)
   1007 {
   1008     if (!element) {
   1009         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
   1010         return;
   1011     }
   1012 
   1013     if (!isHTMLInputElement(*element)) {
   1014         exceptionState.throwDOMException(InvalidNodeTypeError, "The element provided is not an INPUT.");
   1015         return;
   1016     }
   1017 
   1018     toHTMLInputElement(*element).setEditingValue(value);
   1019 }
   1020 
   1021 void Internals::setAutofilled(Element* element, bool enabled, ExceptionState& exceptionState)
   1022 {
   1023     if (!element->isFormControlElement()) {
   1024         exceptionState.throwDOMException(InvalidNodeTypeError, "The element provided is not a form control element.");
   1025         return;
   1026     }
   1027     toHTMLFormControlElement(element)->setAutofilled(enabled);
   1028 }
   1029 
   1030 void Internals::scrollElementToRect(Element* element, long x, long y, long w, long h, ExceptionState& exceptionState)
   1031 {
   1032     if (!element || !element->document().view()) {
   1033         exceptionState.throwDOMException(InvalidNodeTypeError, element ? "No view can be obtained from the provided element's document." : ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
   1034         return;
   1035     }
   1036     FrameView* frameView = element->document().view();
   1037     frameView->scrollElementToRect(element, IntRect(x, y, w, h));
   1038 }
   1039 
   1040 PassRefPtrWillBeRawPtr<Range> Internals::rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionState& exceptionState)
   1041 {
   1042     if (!scope) {
   1043         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
   1044         return nullptr;
   1045     }
   1046 
   1047     // TextIterator depends on Layout information, make sure layout it up to date.
   1048     scope->document().updateLayoutIgnorePendingStylesheets();
   1049 
   1050     return PlainTextRange(rangeLocation, rangeLocation + rangeLength).createRange(*scope);
   1051 }
   1052 
   1053 unsigned Internals::locationFromRange(Element* scope, const Range* range, ExceptionState& exceptionState)
   1054 {
   1055     if (!scope || !range) {
   1056         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(scope ? 2 : 1, scope ? "Range" : "Element"));
   1057         return 0;
   1058     }
   1059 
   1060     // PlainTextRange depends on Layout information, make sure layout it up to date.
   1061     scope->document().updateLayoutIgnorePendingStylesheets();
   1062 
   1063     return PlainTextRange::create(*scope, *range).start();
   1064 }
   1065 
   1066 unsigned Internals::lengthFromRange(Element* scope, const Range* range, ExceptionState& exceptionState)
   1067 {
   1068     if (!scope || !range) {
   1069         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(scope ? 2 : 1, scope ? "Range" : "Element"));
   1070         return 0;
   1071     }
   1072 
   1073     // PlainTextRange depends on Layout information, make sure layout it up to date.
   1074     scope->document().updateLayoutIgnorePendingStylesheets();
   1075 
   1076     return PlainTextRange::create(*scope, *range).length();
   1077 }
   1078 
   1079 String Internals::rangeAsText(const Range* range, ExceptionState& exceptionState)
   1080 {
   1081     if (!range) {
   1082         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Range"));
   1083         return String();
   1084     }
   1085 
   1086     return range->text();
   1087 }
   1088 
   1089 PassRefPtrWillBeRawPtr<DOMPoint> Internals::touchPositionAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
   1090 {
   1091     if (!document || !document->frame()) {
   1092         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
   1093         return nullptr;
   1094     }
   1095 
   1096     document->updateLayout();
   1097 
   1098     IntSize radius(width / 2, height / 2);
   1099     IntPoint point(x + radius.width(), y + radius.height());
   1100 
   1101     Node* targetNode;
   1102     IntPoint adjustedPoint;
   1103 
   1104     bool foundNode = document->frame()->eventHandler().bestClickableNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
   1105     if (foundNode)
   1106         return DOMPoint::create(adjustedPoint.x(), adjustedPoint.y());
   1107 
   1108     return nullptr;
   1109 }
   1110 
   1111 Node* Internals::touchNodeAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
   1112 {
   1113     if (!document || !document->frame()) {
   1114         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
   1115         return 0;
   1116     }
   1117 
   1118     document->updateLayout();
   1119 
   1120     IntSize radius(width / 2, height / 2);
   1121     IntPoint point(x + radius.width(), y + radius.height());
   1122 
   1123     Node* targetNode;
   1124     IntPoint adjustedPoint;
   1125     document->frame()->eventHandler().bestClickableNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
   1126     return targetNode;
   1127 }
   1128 
   1129 PassRefPtrWillBeRawPtr<DOMPoint> Internals::touchPositionAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
   1130 {
   1131     if (!document || !document->frame()) {
   1132         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
   1133         return nullptr;
   1134     }
   1135 
   1136     document->updateLayout();
   1137 
   1138     IntSize radius(width / 2, height / 2);
   1139     IntPoint point(x + radius.width(), y + radius.height());
   1140 
   1141     Node* targetNode = 0;
   1142     IntPoint adjustedPoint;
   1143 
   1144     bool foundNode = document->frame()->eventHandler().bestContextMenuNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
   1145     if (foundNode)
   1146         return DOMPoint::create(adjustedPoint.x(), adjustedPoint.y());
   1147 
   1148     return DOMPoint::create(x, y);
   1149 }
   1150 
   1151 Node* Internals::touchNodeAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
   1152 {
   1153     if (!document || !document->frame()) {
   1154         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
   1155         return 0;
   1156     }
   1157 
   1158     document->updateLayout();
   1159 
   1160     IntSize radius(width / 2, height / 2);
   1161     IntPoint point(x + radius.width(), y + radius.height());
   1162 
   1163     Node* targetNode = 0;
   1164     IntPoint adjustedPoint;
   1165     document->frame()->eventHandler().bestContextMenuNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
   1166     return targetNode;
   1167 }
   1168 
   1169 PassRefPtrWillBeRawPtr<ClientRect> Internals::bestZoomableAreaForTouchPoint(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
   1170 {
   1171     if (!document || !document->frame()) {
   1172         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
   1173         return nullptr;
   1174     }
   1175 
   1176     document->updateLayout();
   1177 
   1178     IntSize radius(width / 2, height / 2);
   1179     IntPoint point(x + radius.width(), y + radius.height());
   1180 
   1181     Node* targetNode;
   1182     IntRect zoomableArea;
   1183     bool foundNode = document->frame()->eventHandler().bestZoomableAreaForTouchPoint(point, radius, zoomableArea, targetNode);
   1184     if (foundNode)
   1185         return ClientRect::create(zoomableArea);
   1186 
   1187     return nullptr;
   1188 }
   1189 
   1190 
   1191 int Internals::lastSpellCheckRequestSequence(Document* document, ExceptionState& exceptionState)
   1192 {
   1193     SpellCheckRequester* requester = spellCheckRequester(document);
   1194 
   1195     if (!requester) {
   1196         exceptionState.throwDOMException(InvalidAccessError, "No spell check requestor can be obtained for the provided document.");
   1197         return -1;
   1198     }
   1199 
   1200     return requester->lastRequestSequence();
   1201 }
   1202 
   1203 int Internals::lastSpellCheckProcessedSequence(Document* document, ExceptionState& exceptionState)
   1204 {
   1205     SpellCheckRequester* requester = spellCheckRequester(document);
   1206 
   1207     if (!requester) {
   1208         exceptionState.throwDOMException(InvalidAccessError, "No spell check requestor can be obtained for the provided document.");
   1209         return -1;
   1210     }
   1211 
   1212     return requester->lastProcessedSequence();
   1213 }
   1214 
   1215 Vector<AtomicString> Internals::userPreferredLanguages() const
   1216 {
   1217     return WebCore::userPreferredLanguages();
   1218 }
   1219 
   1220 // Optimally, the bindings generator would pass a Vector<AtomicString> here but
   1221 // this is not supported yet.
   1222 void Internals::setUserPreferredLanguages(const Vector<String>& languages)
   1223 {
   1224     Vector<AtomicString> atomicLanguages;
   1225     for (size_t i = 0; i < languages.size(); ++i)
   1226         atomicLanguages.append(AtomicString(languages[i]));
   1227     WebCore::overrideUserPreferredLanguages(atomicLanguages);
   1228 }
   1229 
   1230 unsigned Internals::activeDOMObjectCount(Document* document, ExceptionState& exceptionState)
   1231 {
   1232     if (!document) {
   1233         exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
   1234         return 0;
   1235     }
   1236 
   1237     return document->activeDOMObjectCount();
   1238 }
   1239 
   1240 static unsigned eventHandlerCount(Document& document, EventHandlerRegistry::EventHandlerClass handlerClass)
   1241 {
   1242     if (!document.frameHost())
   1243         return 0;
   1244     EventHandlerRegistry* registry = &document.frameHost()->eventHandlerRegistry();
   1245     unsigned count = 0;
   1246     const EventTargetSet* targets = registry->eventHandlerTargets(handlerClass);
   1247     if (targets) {
   1248         for (EventTargetSet::const_iterator iter = targets->begin(); iter != targets->end(); ++iter)
   1249             count += iter->value;
   1250     }
   1251     return count;
   1252 }
   1253 
   1254 unsigned Internals::wheelEventHandlerCount(Document* document, ExceptionState& exceptionState)
   1255 {
   1256     if (!document) {
   1257         exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
   1258         return 0;
   1259     }
   1260 
   1261     return eventHandlerCount(*document, EventHandlerRegistry::WheelEvent);
   1262 }
   1263 
   1264 unsigned Internals::scrollEventHandlerCount(Document* document, ExceptionState& exceptionState)
   1265 {
   1266     if (!document) {
   1267         exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
   1268         return 0;
   1269     }
   1270 
   1271     return eventHandlerCount(*document, EventHandlerRegistry::ScrollEvent);
   1272 }
   1273 
   1274 unsigned Internals::touchEventHandlerCount(Document* document, ExceptionState& exceptionState)
   1275 {
   1276     if (!document) {
   1277         exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
   1278         return 0;
   1279     }
   1280 
   1281     const TouchEventTargetSet* touchHandlers = document->touchEventTargets();
   1282     if (!touchHandlers)
   1283         return 0;
   1284 
   1285     unsigned count = 0;
   1286     for (TouchEventTargetSet::const_iterator iter = touchHandlers->begin(); iter != touchHandlers->end(); ++iter)
   1287         count += iter->value;
   1288     return count;
   1289 }
   1290 
   1291 static RenderLayer* findRenderLayerForGraphicsLayer(RenderLayer* searchRoot, GraphicsLayer* graphicsLayer, IntSize* layerOffset, String* layerType)
   1292 {
   1293     *layerOffset = IntSize();
   1294     if (searchRoot->hasCompositedLayerMapping() && graphicsLayer == searchRoot->compositedLayerMapping()->mainGraphicsLayer()) {
   1295         CompositedLayerMappingPtr compositedLayerMapping = searchRoot->compositedLayerMapping();
   1296         LayoutSize offset = compositedLayerMapping->contentOffsetInCompositingLayer();
   1297         *layerOffset = IntSize(offset.width(), offset.height());
   1298         return searchRoot;
   1299     }
   1300 
   1301     GraphicsLayer* layerForScrolling = searchRoot->scrollableArea() ? searchRoot->scrollableArea()->layerForScrolling() : 0;
   1302     if (graphicsLayer == layerForScrolling) {
   1303         *layerType = "scrolling";
   1304         return searchRoot;
   1305     }
   1306 
   1307     if (searchRoot->compositingState() == PaintsIntoGroupedBacking) {
   1308         GraphicsLayer* squashingLayer = searchRoot->groupedMapping()->squashingLayer();
   1309         if (graphicsLayer == squashingLayer) {
   1310             *layerType ="squashing";
   1311             *layerOffset = -searchRoot->offsetFromSquashingLayerOrigin();
   1312             return searchRoot;
   1313         }
   1314     }
   1315 
   1316     GraphicsLayer* layerForHorizontalScrollbar = searchRoot->scrollableArea() ? searchRoot->scrollableArea()->layerForHorizontalScrollbar() : 0;
   1317     if (graphicsLayer == layerForHorizontalScrollbar) {
   1318         *layerType = "horizontalScrollbar";
   1319         return searchRoot;
   1320     }
   1321 
   1322     GraphicsLayer* layerForVerticalScrollbar = searchRoot->scrollableArea() ? searchRoot->scrollableArea()->layerForVerticalScrollbar() : 0;
   1323     if (graphicsLayer == layerForVerticalScrollbar) {
   1324         *layerType = "verticalScrollbar";
   1325         return searchRoot;
   1326     }
   1327 
   1328     GraphicsLayer* layerForScrollCorner = searchRoot->scrollableArea() ? searchRoot->scrollableArea()->layerForScrollCorner() : 0;
   1329     if (graphicsLayer == layerForScrollCorner) {
   1330         *layerType = "scrollCorner";
   1331         return searchRoot;
   1332     }
   1333 
   1334     // Search right to left to increase the chances that we'll choose the top-most layers in a
   1335     // grouped mapping for squashing.
   1336     for (RenderLayer* child = searchRoot->lastChild(); child; child = child->previousSibling()) {
   1337         RenderLayer* foundLayer = findRenderLayerForGraphicsLayer(child, graphicsLayer, layerOffset, layerType);
   1338         if (foundLayer)
   1339             return foundLayer;
   1340     }
   1341 
   1342     return 0;
   1343 }
   1344 
   1345 // Given a vector of rects, merge those that are adjacent, leaving empty rects
   1346 // in the place of no longer used slots. This is intended to simplify the list
   1347 // of rects returned by an SkRegion (which have been split apart for sorting
   1348 // purposes). No attempt is made to do this efficiently (eg. by relying on the
   1349 // sort criteria of SkRegion).
   1350 static void mergeRects(blink::WebVector<blink::WebRect>& rects)
   1351 {
   1352     for (size_t i = 0; i < rects.size(); ++i) {
   1353         if (rects[i].isEmpty())
   1354             continue;
   1355         bool updated;
   1356         do {
   1357             updated = false;
   1358             for (size_t j = i+1; j < rects.size(); ++j) {
   1359                 if (rects[j].isEmpty())
   1360                     continue;
   1361                 // Try to merge rects[j] into rects[i] along the 4 possible edges.
   1362                 if (rects[i].y == rects[j].y && rects[i].height == rects[j].height) {
   1363                     if (rects[i].x + rects[i].width == rects[j].x) {
   1364                         rects[i].width += rects[j].width;
   1365                         rects[j] = blink::WebRect();
   1366                         updated = true;
   1367                     } else if (rects[i].x == rects[j].x + rects[j].width) {
   1368                         rects[i].x = rects[j].x;
   1369                         rects[i].width += rects[j].width;
   1370                         rects[j] = blink::WebRect();
   1371                         updated = true;
   1372                     }
   1373                 } else if (rects[i].x == rects[j].x && rects[i].width == rects[j].width) {
   1374                     if (rects[i].y + rects[i].height == rects[j].y) {
   1375                         rects[i].height += rects[j].height;
   1376                         rects[j] = blink::WebRect();
   1377                         updated = true;
   1378                     } else if (rects[i].y == rects[j].y + rects[j].height) {
   1379                         rects[i].y = rects[j].y;
   1380                         rects[i].height += rects[j].height;
   1381                         rects[j] = blink::WebRect();
   1382                         updated = true;
   1383                     }
   1384                 }
   1385             }
   1386         } while (updated);
   1387     }
   1388 }
   1389 
   1390 static void accumulateLayerRectList(RenderLayerCompositor* compositor, GraphicsLayer* graphicsLayer, LayerRectList* rects)
   1391 {
   1392     blink::WebVector<blink::WebRect> layerRects = graphicsLayer->platformLayer()->touchEventHandlerRegion();
   1393     if (!layerRects.isEmpty()) {
   1394         mergeRects(layerRects);
   1395         String layerType;
   1396         IntSize layerOffset;
   1397         RenderLayer* renderLayer = findRenderLayerForGraphicsLayer(compositor->rootRenderLayer(), graphicsLayer, &layerOffset, &layerType);
   1398         Node* node = renderLayer ? renderLayer->renderer()->node() : 0;
   1399         for (size_t i = 0; i < layerRects.size(); ++i) {
   1400             if (!layerRects[i].isEmpty()) {
   1401                 rects->append(node, layerType, layerOffset.width(), layerOffset.height(), ClientRect::create(layerRects[i]));
   1402             }
   1403         }
   1404     }
   1405 
   1406     size_t numChildren = graphicsLayer->children().size();
   1407     for (size_t i = 0; i < numChildren; ++i)
   1408         accumulateLayerRectList(compositor, graphicsLayer->children()[i], rects);
   1409 }
   1410 
   1411 PassRefPtrWillBeRawPtr<LayerRectList> Internals::touchEventTargetLayerRects(Document* document, ExceptionState& exceptionState)
   1412 {
   1413     if (!document || !document->view() || !document->page() || document != contextDocument()) {
   1414         exceptionState.throwDOMException(InvalidAccessError, "The document provided is invalid.");
   1415         return nullptr;
   1416     }
   1417 
   1418     // Do any pending layout and compositing update (which may call touchEventTargetRectsChange) to ensure this
   1419     // really takes any previous changes into account.
   1420     forceCompositingUpdate(document, exceptionState);
   1421     if (exceptionState.hadException())
   1422         return nullptr;
   1423 
   1424     if (RenderView* view = document->renderView()) {
   1425         if (RenderLayerCompositor* compositor = view->compositor()) {
   1426             if (GraphicsLayer* rootLayer = compositor->rootGraphicsLayer()) {
   1427                 RefPtrWillBeRawPtr<LayerRectList> rects = LayerRectList::create();
   1428                 accumulateLayerRectList(compositor, rootLayer, rects.get());
   1429                 return rects;
   1430             }
   1431         }
   1432     }
   1433 
   1434     return nullptr;
   1435 }
   1436 
   1437 PassRefPtrWillBeRawPtr<StaticNodeList> Internals::nodesFromRect(Document* document, int centerX, int centerY, unsigned topPadding, unsigned rightPadding,
   1438     unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionState& exceptionState) const
   1439 {
   1440     if (!document || !document->frame() || !document->frame()->view()) {
   1441         exceptionState.throwDOMException(InvalidAccessError, "No view can be obtained from the provided document.");
   1442         return nullptr;
   1443     }
   1444 
   1445     LocalFrame* frame = document->frame();
   1446     FrameView* frameView = document->view();
   1447     RenderView* renderView = document->renderView();
   1448 
   1449     if (!renderView)
   1450         return nullptr;
   1451 
   1452     float zoomFactor = frame->pageZoomFactor();
   1453     LayoutPoint point = roundedLayoutPoint(FloatPoint(centerX * zoomFactor + frameView->scrollX(), centerY * zoomFactor + frameView->scrollY()));
   1454 
   1455     HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
   1456     if (ignoreClipping)
   1457         hitType |= HitTestRequest::IgnoreClipping;
   1458     if (!allowShadowContent)
   1459         hitType |= HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent;
   1460     if (allowChildFrameContent)
   1461         hitType |= HitTestRequest::AllowChildFrameContent;
   1462 
   1463     HitTestRequest request(hitType);
   1464 
   1465     // When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
   1466     if (!request.ignoreClipping() && !frameView->visibleContentRect().intersects(HitTestLocation::rectForPoint(point, topPadding, rightPadding, bottomPadding, leftPadding)))
   1467         return nullptr;
   1468 
   1469     WillBeHeapVector<RefPtrWillBeMember<Node> > matches;
   1470 
   1471     // Need padding to trigger a rect based hit test, but we want to return a NodeList
   1472     // so we special case this.
   1473     if (!topPadding && !rightPadding && !bottomPadding && !leftPadding) {
   1474         HitTestResult result(point);
   1475         renderView->hitTest(request, result);
   1476         if (result.innerNode())
   1477             matches.append(result.innerNode()->deprecatedShadowAncestorNode());
   1478     } else {
   1479         HitTestResult result(point, topPadding, rightPadding, bottomPadding, leftPadding);
   1480         renderView->hitTest(request, result);
   1481         copyToVector(result.rectBasedTestResult(), matches);
   1482     }
   1483 
   1484     return StaticNodeList::adopt(matches);
   1485 }
   1486 
   1487 void Internals::emitInspectorDidBeginFrame(int frameId)
   1488 {
   1489     contextDocument()->page()->inspectorController().didBeginFrame(frameId);
   1490 }
   1491 
   1492 void Internals::emitInspectorDidCancelFrame()
   1493 {
   1494     contextDocument()->page()->inspectorController().didCancelFrame();
   1495 }
   1496 
   1497 bool Internals::hasSpellingMarker(Document* document, int from, int length, ExceptionState&)
   1498 {
   1499     if (!document || !document->frame())
   1500         return 0;
   1501 
   1502     return document->frame()->spellChecker().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
   1503 }
   1504 
   1505 void Internals::setContinuousSpellCheckingEnabled(bool enabled, ExceptionState&)
   1506 {
   1507     if (!contextDocument() || !contextDocument()->frame())
   1508         return;
   1509 
   1510     if (enabled != contextDocument()->frame()->spellChecker().isContinuousSpellCheckingEnabled())
   1511         contextDocument()->frame()->spellChecker().toggleContinuousSpellChecking();
   1512 }
   1513 
   1514 bool Internals::isOverwriteModeEnabled(Document* document, ExceptionState&)
   1515 {
   1516     if (!document || !document->frame())
   1517         return 0;
   1518 
   1519     return document->frame()->editor().isOverwriteModeEnabled();
   1520 }
   1521 
   1522 void Internals::toggleOverwriteModeEnabled(Document* document, ExceptionState&)
   1523 {
   1524     if (!document || !document->frame())
   1525         return;
   1526 
   1527     document->frame()->editor().toggleOverwriteModeEnabled();
   1528 }
   1529 
   1530 unsigned Internals::numberOfLiveNodes() const
   1531 {
   1532     return InspectorCounters::counterValue(InspectorCounters::NodeCounter);
   1533 }
   1534 
   1535 unsigned Internals::numberOfLiveDocuments() const
   1536 {
   1537     return InspectorCounters::counterValue(InspectorCounters::DocumentCounter);
   1538 }
   1539 
   1540 String Internals::dumpRefCountedInstanceCounts() const
   1541 {
   1542     return WTF::dumpRefCountedInstanceCounts();
   1543 }
   1544 
   1545 Vector<String> Internals::consoleMessageArgumentCounts(Document* document) const
   1546 {
   1547     InstrumentingAgents* instrumentingAgents = instrumentationForPage(document->page());
   1548     if (!instrumentingAgents)
   1549         return Vector<String>();
   1550     InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent();
   1551     if (!consoleAgent)
   1552         return Vector<String>();
   1553     Vector<unsigned> counts = consoleAgent->consoleMessageArgumentCounts();
   1554     Vector<String> result(counts.size());
   1555     for (size_t i = 0; i < counts.size(); i++)
   1556         result[i] = String::number(counts[i]);
   1557     return result;
   1558 }
   1559 
   1560 Vector<unsigned long> Internals::setMemoryCacheCapacities(unsigned long minDeadBytes, unsigned long maxDeadBytes, unsigned long totalBytes)
   1561 {
   1562     Vector<unsigned long> result;
   1563     result.append(memoryCache()->minDeadCapacity());
   1564     result.append(memoryCache()->maxDeadCapacity());
   1565     result.append(memoryCache()->capacity());
   1566     memoryCache()->setCapacities(minDeadBytes, maxDeadBytes, totalBytes);
   1567     return result;
   1568 }
   1569 
   1570 void Internals::setInspectorResourcesDataSizeLimits(int maximumResourcesContentSize, int maximumSingleResourceContentSize, ExceptionState& exceptionState)
   1571 {
   1572     Page* page = contextDocument()->frame()->page();
   1573     if (!page) {
   1574         exceptionState.throwDOMException(InvalidAccessError, "No page can be obtained from the current context document.");
   1575         return;
   1576     }
   1577     page->inspectorController().setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize);
   1578 }
   1579 
   1580 bool Internals::hasGrammarMarker(Document* document, int from, int length, ExceptionState&)
   1581 {
   1582     if (!document || !document->frame())
   1583         return 0;
   1584 
   1585     return document->frame()->spellChecker().selectionStartHasMarkerFor(DocumentMarker::Grammar, from, length);
   1586 }
   1587 
   1588 unsigned Internals::numberOfScrollableAreas(Document* document, ExceptionState&)
   1589 {
   1590     unsigned count = 0;
   1591     LocalFrame* frame = document->frame();
   1592     if (frame->view()->scrollableAreas())
   1593         count += frame->view()->scrollableAreas()->size();
   1594 
   1595     for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
   1596         if (child->isLocalFrame() && toLocalFrame(child)->view() && toLocalFrame(child)->view()->scrollableAreas())
   1597             count += toLocalFrame(child)->view()->scrollableAreas()->size();
   1598     }
   1599 
   1600     return count;
   1601 }
   1602 
   1603 bool Internals::isPageBoxVisible(Document* document, int pageNumber, ExceptionState& exceptionState)
   1604 {
   1605     if (!document) {
   1606         exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
   1607         return false;
   1608     }
   1609 
   1610     return document->isPageBoxVisible(pageNumber);
   1611 }
   1612 
   1613 String Internals::layerTreeAsText(Document* document, ExceptionState& exceptionState) const
   1614 {
   1615     return layerTreeAsText(document, 0, exceptionState);
   1616 }
   1617 
   1618 String Internals::elementLayerTreeAsText(Element* element, ExceptionState& exceptionState) const
   1619 {
   1620     if (!element) {
   1621         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
   1622         return String();
   1623     }
   1624 
   1625     FrameView* frameView = element->document().view();
   1626     frameView->updateLayoutAndStyleForPainting();
   1627 
   1628     return elementLayerTreeAsText(element, 0, exceptionState);
   1629 }
   1630 
   1631 bool Internals::scrollsWithRespectTo(Element* element1, Element* element2, ExceptionState& exceptionState)
   1632 {
   1633     if (!element1 || !element2) {
   1634         exceptionState.throwDOMException(InvalidAccessError, String::format("The %s element provided is invalid.", element1 ? "second" : "first"));
   1635         return 0;
   1636     }
   1637 
   1638     element1->document().updateLayout();
   1639 
   1640     RenderObject* renderer1 = element1->renderer();
   1641     RenderObject* renderer2 = element2->renderer();
   1642     if (!renderer1 || !renderer1->isBox()) {
   1643         exceptionState.throwDOMException(InvalidAccessError, renderer1 ? "The first provided element's renderer is not a box." : "The first provided element has no renderer.");
   1644         return 0;
   1645     }
   1646     if (!renderer2 || !renderer2->isBox()) {
   1647         exceptionState.throwDOMException(InvalidAccessError, renderer2 ? "The second provided element's renderer is not a box." : "The second provided element has no renderer.");
   1648         return 0;
   1649     }
   1650 
   1651     RenderLayer* layer1 = toRenderBox(renderer1)->layer();
   1652     RenderLayer* layer2 = toRenderBox(renderer2)->layer();
   1653     if (!layer1 || !layer2) {
   1654         exceptionState.throwDOMException(InvalidAccessError, String::format("No render layer can be obtained from the %s provided element.", layer1 ? "second" : "first"));
   1655         return 0;
   1656     }
   1657 
   1658     return layer1->scrollsWithRespectTo(layer2);
   1659 }
   1660 
   1661 bool Internals::isUnclippedDescendant(Element* element, ExceptionState& exceptionState)
   1662 {
   1663     if (!element) {
   1664         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
   1665         return 0;
   1666     }
   1667 
   1668     element->document().view()->updateLayoutAndStyleForPainting();
   1669 
   1670     RenderObject* renderer = element->renderer();
   1671     if (!renderer || !renderer->isBox()) {
   1672         exceptionState.throwDOMException(InvalidAccessError, renderer ? "The provided element's renderer is not a box." : "The provided element has no renderer.");
   1673         return 0;
   1674     }
   1675 
   1676     RenderLayer* layer = toRenderBox(renderer)->layer();
   1677     if (!layer) {
   1678         exceptionState.throwDOMException(InvalidAccessError, "No render layer can be obtained from the provided element.");
   1679         return 0;
   1680     }
   1681 
   1682     // We used to compute isUnclippedDescendant only when acceleratedCompositingForOverflowScrollEnabled,
   1683     // but now we compute it all the time.
   1684     // FIXME: Remove this if statement and rebaseline the tests that make this assumption.
   1685     if (!layer->compositor()->acceleratedCompositingForOverflowScrollEnabled())
   1686         return false;
   1687 
   1688     return layer->compositingInputs().isUnclippedDescendant;
   1689 }
   1690 
   1691 String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionState& exceptionState) const
   1692 {
   1693     if (!document || !document->frame()) {
   1694         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
   1695         return String();
   1696     }
   1697 
   1698     document->view()->updateLayoutAndStyleForPainting();
   1699 
   1700     return document->frame()->layerTreeAsText(flags);
   1701 }
   1702 
   1703 String Internals::elementLayerTreeAsText(Element* element, unsigned flags, ExceptionState& exceptionState) const
   1704 {
   1705     if (!element) {
   1706         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
   1707         return String();
   1708     }
   1709 
   1710     element->document().updateLayout();
   1711 
   1712     RenderObject* renderer = element->renderer();
   1713     if (!renderer || !renderer->isBox()) {
   1714         exceptionState.throwDOMException(InvalidAccessError, renderer ? "The provided element's renderer is not a box." : "The provided element has no renderer.");
   1715         return String();
   1716     }
   1717 
   1718     RenderLayer* layer = toRenderBox(renderer)->layer();
   1719     if (!layer
   1720         || !layer->hasCompositedLayerMapping()
   1721         || !layer->compositedLayerMapping()->mainGraphicsLayer()) {
   1722         // Don't raise exception in these cases which may be normally used in tests.
   1723         return String();
   1724     }
   1725 
   1726     return layer->compositedLayerMapping()->mainGraphicsLayer()->layerTreeAsText(flags);
   1727 }
   1728 
   1729 static RenderLayer* getRenderLayerForElement(Element* element, ExceptionState& exceptionState)
   1730 {
   1731     if (!element) {
   1732         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
   1733         return 0;
   1734     }
   1735 
   1736     RenderObject* renderer = element->renderer();
   1737     if (!renderer || !renderer->isBox()) {
   1738         exceptionState.throwDOMException(InvalidAccessError, renderer ? "The provided element's renderer is not a box." : "The provided element has no renderer.");
   1739         return 0;
   1740     }
   1741 
   1742     RenderLayer* layer = toRenderBox(renderer)->layer();
   1743     if (!layer) {
   1744         exceptionState.throwDOMException(InvalidAccessError, "No render layer can be obtained from the provided element.");
   1745         return 0;
   1746     }
   1747 
   1748     return layer;
   1749 }
   1750 
   1751 String Internals::repaintRectsAsText(Document* document, ExceptionState& exceptionState) const
   1752 {
   1753     if (!document || !document->frame()) {
   1754         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
   1755         return String();
   1756     }
   1757 
   1758     return document->frame()->trackedRepaintRectsAsText();
   1759 }
   1760 
   1761 PassRefPtrWillBeRawPtr<ClientRectList> Internals::repaintRects(Element* element, ExceptionState& exceptionState) const
   1762 {
   1763     if (!element) {
   1764         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
   1765         return nullptr;
   1766     }
   1767 
   1768     element->document().frame()->view()->updateLayoutAndStyleForPainting();
   1769 
   1770     if (RenderLayer* layer = getRenderLayerForElement(element, exceptionState)) {
   1771         if (layer->compositingState() == PaintsIntoOwnBacking) {
   1772             OwnPtr<Vector<FloatRect> > rects = layer->collectTrackedRepaintRects();
   1773             ASSERT(rects.get());
   1774             Vector<FloatQuad> quads(rects->size());
   1775             for (size_t i = 0; i < rects->size(); ++i)
   1776                 quads[i] = FloatRect(rects->at(i));
   1777             return ClientRectList::create(quads);
   1778         }
   1779     }
   1780 
   1781     exceptionState.throwDOMException(InvalidAccessError, "The provided element is not composited.");
   1782     return nullptr;
   1783 }
   1784 
   1785 String Internals::scrollingStateTreeAsText(Document* document, ExceptionState& exceptionState) const
   1786 {
   1787     return String();
   1788 }
   1789 
   1790 String Internals::mainThreadScrollingReasons(Document* document, ExceptionState& exceptionState) const
   1791 {
   1792     if (!document || !document->frame()) {
   1793         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
   1794         return String();
   1795     }
   1796 
   1797     document->frame()->view()->updateLayoutAndStyleForPainting();
   1798 
   1799     Page* page = document->page();
   1800     if (!page)
   1801         return String();
   1802 
   1803     return page->mainThreadScrollingReasonsAsText();
   1804 }
   1805 
   1806 PassRefPtrWillBeRawPtr<ClientRectList> Internals::nonFastScrollableRects(Document* document, ExceptionState& exceptionState) const
   1807 {
   1808     if (!document || !document->frame()) {
   1809         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
   1810         return nullptr;
   1811     }
   1812 
   1813     Page* page = document->page();
   1814     if (!page)
   1815         return nullptr;
   1816 
   1817     return page->nonFastScrollableRects(document->frame());
   1818 }
   1819 
   1820 void Internals::garbageCollectDocumentResources(Document* document, ExceptionState& exceptionState) const
   1821 {
   1822     if (!document) {
   1823         exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
   1824         return;
   1825     }
   1826     ResourceFetcher* fetcher = document->fetcher();
   1827     if (!fetcher)
   1828         return;
   1829     fetcher->garbageCollectDocumentResources();
   1830 }
   1831 
   1832 void Internals::evictAllResources() const
   1833 {
   1834     memoryCache()->evictResources();
   1835 }
   1836 
   1837 void Internals::allowRoundingHacks() const
   1838 {
   1839     TextRun::setAllowsRoundingHacks(true);
   1840 }
   1841 
   1842 String Internals::counterValue(Element* element)
   1843 {
   1844     if (!element)
   1845         return String();
   1846 
   1847     return counterValueForElement(element);
   1848 }
   1849 
   1850 int Internals::pageNumber(Element* element, float pageWidth, float pageHeight)
   1851 {
   1852     if (!element)
   1853         return 0;
   1854 
   1855     return PrintContext::pageNumberForElement(element, FloatSize(pageWidth, pageHeight));
   1856 }
   1857 
   1858 Vector<String> Internals::iconURLs(Document* document, int iconTypesMask) const
   1859 {
   1860     Vector<IconURL> iconURLs = document->iconURLs(iconTypesMask);
   1861     Vector<String> array;
   1862 
   1863     Vector<IconURL>::const_iterator iter(iconURLs.begin());
   1864     for (; iter != iconURLs.end(); ++iter)
   1865         array.append(iter->m_iconURL.string());
   1866 
   1867     return array;
   1868 }
   1869 
   1870 Vector<String> Internals::shortcutIconURLs(Document* document) const
   1871 {
   1872     return iconURLs(document, Favicon);
   1873 }
   1874 
   1875 Vector<String> Internals::allIconURLs(Document* document) const
   1876 {
   1877     return iconURLs(document, Favicon | TouchIcon | TouchPrecomposedIcon);
   1878 }
   1879 
   1880 int Internals::numberOfPages(float pageWidth, float pageHeight)
   1881 {
   1882     if (!frame())
   1883         return -1;
   1884 
   1885     return PrintContext::numberOfPages(frame(), FloatSize(pageWidth, pageHeight));
   1886 }
   1887 
   1888 String Internals::pageProperty(String propertyName, int pageNumber, ExceptionState& exceptionState) const
   1889 {
   1890     if (!frame()) {
   1891         exceptionState.throwDOMException(InvalidAccessError, "No frame is available.");
   1892         return String();
   1893     }
   1894 
   1895     return PrintContext::pageProperty(frame(), propertyName.utf8().data(), pageNumber);
   1896 }
   1897 
   1898 String Internals::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft, ExceptionState& exceptionState) const
   1899 {
   1900     if (!frame()) {
   1901         exceptionState.throwDOMException(InvalidAccessError, "No frame is available.");
   1902         return String();
   1903     }
   1904 
   1905     return PrintContext::pageSizeAndMarginsInPixels(frame(), pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft);
   1906 }
   1907 
   1908 void Internals::setDeviceScaleFactor(float scaleFactor, ExceptionState& exceptionState)
   1909 {
   1910     Document* document = contextDocument();
   1911     if (!document || !document->page()) {
   1912         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's page cannot be retrieved." : "No context document can be obtained.");
   1913         return;
   1914     }
   1915     Page* page = document->page();
   1916     page->setDeviceScaleFactor(scaleFactor);
   1917 }
   1918 
   1919 void Internals::setIsCursorVisible(Document* document, bool isVisible, ExceptionState& exceptionState)
   1920 {
   1921     if (!document || !document->page()) {
   1922         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's page cannot be retrieved." : "No context document can be obtained.");
   1923         return;
   1924     }
   1925     document->page()->setIsCursorVisible(isVisible);
   1926 }
   1927 
   1928 void Internals::webkitWillEnterFullScreenForElement(Document* document, Element* element)
   1929 {
   1930     if (!document)
   1931         return;
   1932     FullscreenElementStack::from(*document).webkitWillEnterFullScreenForElement(element);
   1933 }
   1934 
   1935 void Internals::webkitDidEnterFullScreenForElement(Document* document, Element* element)
   1936 {
   1937     if (!document)
   1938         return;
   1939     FullscreenElementStack::from(*document).webkitDidEnterFullScreenForElement(element);
   1940 }
   1941 
   1942 void Internals::webkitWillExitFullScreenForElement(Document* document, Element* element)
   1943 {
   1944     if (!document)
   1945         return;
   1946     FullscreenElementStack::from(*document).webkitWillExitFullScreenForElement(element);
   1947 }
   1948 
   1949 void Internals::webkitDidExitFullScreenForElement(Document* document, Element* element)
   1950 {
   1951     if (!document)
   1952         return;
   1953     FullscreenElementStack::from(*document).webkitDidExitFullScreenForElement(element);
   1954 }
   1955 
   1956 void Internals::mediaPlayerRequestFullscreen(HTMLMediaElement* mediaElement)
   1957 {
   1958     mediaElement->mediaPlayerRequestFullscreen();
   1959 }
   1960 
   1961 void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
   1962 {
   1963     SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
   1964 }
   1965 
   1966 void Internals::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme)
   1967 {
   1968     SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme);
   1969 }
   1970 
   1971 PassRefPtrWillBeRawPtr<MallocStatistics> Internals::mallocStatistics() const
   1972 {
   1973     return MallocStatistics::create();
   1974 }
   1975 
   1976 PassRefPtrWillBeRawPtr<TypeConversions> Internals::typeConversions() const
   1977 {
   1978     return TypeConversions::create();
   1979 }
   1980 
   1981 Vector<String> Internals::getReferencedFilePaths() const
   1982 {
   1983     return frame()->loader().currentItem()->getReferencedFilePaths();
   1984 }
   1985 
   1986 void Internals::startTrackingRepaints(Document* document, ExceptionState& exceptionState)
   1987 {
   1988     if (!document || !document->view()) {
   1989         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's view cannot be retrieved." : "The document provided is invalid.");
   1990         return;
   1991     }
   1992 
   1993     FrameView* frameView = document->view();
   1994     frameView->updateLayoutAndStyleForPainting();
   1995     frameView->setTracksPaintInvalidations(true);
   1996 }
   1997 
   1998 void Internals::stopTrackingRepaints(Document* document, ExceptionState& exceptionState)
   1999 {
   2000     if (!document || !document->view()) {
   2001         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's view cannot be retrieved." : "The document provided is invalid.");
   2002         return;
   2003     }
   2004 
   2005     FrameView* frameView = document->view();
   2006     frameView->updateLayoutAndStyleForPainting();
   2007     frameView->setTracksPaintInvalidations(false);
   2008 }
   2009 
   2010 void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(ExceptionState& exceptionState)
   2011 {
   2012     updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(0, exceptionState);
   2013 }
   2014 
   2015 void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node* node, ExceptionState& exceptionState)
   2016 {
   2017     Document* document;
   2018     if (!node) {
   2019         document = contextDocument();
   2020     } else if (node->isDocumentNode()) {
   2021         document = toDocument(node);
   2022     } else if (isHTMLIFrameElement(*node)) {
   2023         document = toHTMLIFrameElement(*node).contentDocument();
   2024     } else {
   2025         exceptionState.throwTypeError("The node provided is neither a document nor an IFrame.");
   2026         return;
   2027     }
   2028     document->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasksSynchronously);
   2029 }
   2030 
   2031 void Internals::forceFullRepaint(Document* document, ExceptionState& exceptionState)
   2032 {
   2033     if (!document || !document->view()) {
   2034         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's view cannot be retrieved." : "The document provided is invalid.");
   2035         return;
   2036     }
   2037 
   2038     if (RenderView *renderView = document->renderView())
   2039         renderView->repaintViewAndCompositedLayers();
   2040 }
   2041 
   2042 PassRefPtrWillBeRawPtr<ClientRectList> Internals::draggableRegions(Document* document, ExceptionState& exceptionState)
   2043 {
   2044     return annotatedRegions(document, true, exceptionState);
   2045 }
   2046 
   2047 PassRefPtrWillBeRawPtr<ClientRectList> Internals::nonDraggableRegions(Document* document, ExceptionState& exceptionState)
   2048 {
   2049     return annotatedRegions(document, false, exceptionState);
   2050 }
   2051 
   2052 PassRefPtrWillBeRawPtr<ClientRectList> Internals::annotatedRegions(Document* document, bool draggable, ExceptionState& exceptionState)
   2053 {
   2054     if (!document || !document->view()) {
   2055         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's view cannot be retrieved." : "The document provided is invalid.");
   2056         return ClientRectList::create();
   2057     }
   2058 
   2059     document->updateLayout();
   2060     document->view()->updateAnnotatedRegions();
   2061     Vector<AnnotatedRegionValue> regions = document->annotatedRegions();
   2062 
   2063     Vector<FloatQuad> quads;
   2064     for (size_t i = 0; i < regions.size(); ++i) {
   2065         if (regions[i].draggable == draggable)
   2066             quads.append(FloatQuad(regions[i].bounds));
   2067     }
   2068     return ClientRectList::create(quads);
   2069 }
   2070 
   2071 static const char* cursorTypeToString(Cursor::Type cursorType)
   2072 {
   2073     switch (cursorType) {
   2074     case Cursor::Pointer: return "Pointer";
   2075     case Cursor::Cross: return "Cross";
   2076     case Cursor::Hand: return "Hand";
   2077     case Cursor::IBeam: return "IBeam";
   2078     case Cursor::Wait: return "Wait";
   2079     case Cursor::Help: return "Help";
   2080     case Cursor::EastResize: return "EastResize";
   2081     case Cursor::NorthResize: return "NorthResize";
   2082     case Cursor::NorthEastResize: return "NorthEastResize";
   2083     case Cursor::NorthWestResize: return "NorthWestResize";
   2084     case Cursor::SouthResize: return "SouthResize";
   2085     case Cursor::SouthEastResize: return "SouthEastResize";
   2086     case Cursor::SouthWestResize: return "SouthWestResize";
   2087     case Cursor::WestResize: return "WestResize";
   2088     case Cursor::NorthSouthResize: return "NorthSouthResize";
   2089     case Cursor::EastWestResize: return "EastWestResize";
   2090     case Cursor::NorthEastSouthWestResize: return "NorthEastSouthWestResize";
   2091     case Cursor::NorthWestSouthEastResize: return "NorthWestSouthEastResize";
   2092     case Cursor::ColumnResize: return "ColumnResize";
   2093     case Cursor::RowResize: return "RowResize";
   2094     case Cursor::MiddlePanning: return "MiddlePanning";
   2095     case Cursor::EastPanning: return "EastPanning";
   2096     case Cursor::NorthPanning: return "NorthPanning";
   2097     case Cursor::NorthEastPanning: return "NorthEastPanning";
   2098     case Cursor::NorthWestPanning: return "NorthWestPanning";
   2099     case Cursor::SouthPanning: return "SouthPanning";
   2100     case Cursor::SouthEastPanning: return "SouthEastPanning";
   2101     case Cursor::SouthWestPanning: return "SouthWestPanning";
   2102     case Cursor::WestPanning: return "WestPanning";
   2103     case Cursor::Move: return "Move";
   2104     case Cursor::VerticalText: return "VerticalText";
   2105     case Cursor::Cell: return "Cell";
   2106     case Cursor::ContextMenu: return "ContextMenu";
   2107     case Cursor::Alias: return "Alias";
   2108     case Cursor::Progress: return "Progress";
   2109     case Cursor::NoDrop: return "NoDrop";
   2110     case Cursor::Copy: return "Copy";
   2111     case Cursor::None: return "None";
   2112     case Cursor::NotAllowed: return "NotAllowed";
   2113     case Cursor::ZoomIn: return "ZoomIn";
   2114     case Cursor::ZoomOut: return "ZoomOut";
   2115     case Cursor::Grab: return "Grab";
   2116     case Cursor::Grabbing: return "Grabbing";
   2117     case Cursor::Custom: return "Custom";
   2118     }
   2119 
   2120     ASSERT_NOT_REACHED();
   2121     return "UNKNOWN";
   2122 }
   2123 
   2124 String Internals::getCurrentCursorInfo(Document* document, ExceptionState& exceptionState)
   2125 {
   2126     if (!document || !document->frame()) {
   2127         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "The document provided is invalid.");
   2128         return String();
   2129     }
   2130 
   2131     Cursor cursor = document->frame()->eventHandler().currentMouseCursor();
   2132 
   2133     StringBuilder result;
   2134     result.append("type=");
   2135     result.append(cursorTypeToString(cursor.type()));
   2136     result.append(" hotSpot=");
   2137     result.appendNumber(cursor.hotSpot().x());
   2138     result.append(",");
   2139     result.appendNumber(cursor.hotSpot().y());
   2140     if (cursor.image()) {
   2141         IntSize size = cursor.image()->size();
   2142         result.append(" image=");
   2143         result.appendNumber(size.width());
   2144         result.append("x");
   2145         result.appendNumber(size.height());
   2146     }
   2147     if (cursor.imageScaleFactor() != 1) {
   2148         result.append(" scale=");
   2149         NumberToStringBuffer buffer;
   2150         result.append(numberToFixedPrecisionString(cursor.imageScaleFactor(), 8, buffer, true));
   2151     }
   2152 
   2153     return result.toString();
   2154 }
   2155 
   2156 PassRefPtr<ArrayBuffer> Internals::serializeObject(PassRefPtr<SerializedScriptValue> value) const
   2157 {
   2158     String stringValue = value->toWireString();
   2159     RefPtr<ArrayBuffer> buffer = ArrayBuffer::createUninitialized(stringValue.length(), sizeof(UChar));
   2160     stringValue.copyTo(static_cast<UChar*>(buffer->data()), 0, stringValue.length());
   2161     return buffer.release();
   2162 }
   2163 
   2164 PassRefPtr<SerializedScriptValue> Internals::deserializeBuffer(PassRefPtr<ArrayBuffer> buffer) const
   2165 {
   2166     String value(static_cast<const UChar*>(buffer->data()), buffer->byteLength() / sizeof(UChar));
   2167     return SerializedScriptValue::createFromWire(value);
   2168 }
   2169 
   2170 void Internals::forceReload(bool endToEnd)
   2171 {
   2172     frame()->loader().reload(endToEnd ? EndToEndReload : NormalReload);
   2173 }
   2174 
   2175 PassRefPtrWillBeRawPtr<ClientRect> Internals::selectionBounds(ExceptionState& exceptionState)
   2176 {
   2177     Document* document = contextDocument();
   2178     if (!document || !document->frame()) {
   2179         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's frame cannot be retrieved." : "No context document can be obtained.");
   2180         return nullptr;
   2181     }
   2182 
   2183     return ClientRect::create(document->frame()->selection().bounds());
   2184 }
   2185 
   2186 String Internals::markerTextForListItem(Element* element, ExceptionState& exceptionState)
   2187 {
   2188     if (!element) {
   2189         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
   2190         return String();
   2191     }
   2192     return WebCore::markerTextForListItem(element);
   2193 }
   2194 
   2195 String Internals::getImageSourceURL(Element* element, ExceptionState& exceptionState)
   2196 {
   2197     if (!element) {
   2198         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
   2199         return String();
   2200     }
   2201     return element->imageSourceURL();
   2202 }
   2203 
   2204 String Internals::baseURL(Document* document, ExceptionState& exceptionState)
   2205 {
   2206     if (!document) {
   2207         exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
   2208         return String();
   2209     }
   2210 
   2211     return document->baseURL().string();
   2212 }
   2213 
   2214 bool Internals::isSelectPopupVisible(Node* node)
   2215 {
   2216     ASSERT(node);
   2217     if (!isHTMLSelectElement(*node))
   2218         return false;
   2219 
   2220     HTMLSelectElement& select = toHTMLSelectElement(*node);
   2221 
   2222     RenderObject* renderer = select.renderer();
   2223     if (!renderer || !renderer->isMenuList())
   2224         return false;
   2225 
   2226     RenderMenuList* menuList = toRenderMenuList(renderer);
   2227     return menuList->popupIsVisible();
   2228 }
   2229 
   2230 bool Internals::loseSharedGraphicsContext3D()
   2231 {
   2232     OwnPtr<blink::WebGraphicsContext3DProvider> sharedProvider = adoptPtr(blink::Platform::current()->createSharedOffscreenGraphicsContext3DProvider());
   2233     if (!sharedProvider)
   2234         return false;
   2235     blink::WebGraphicsContext3D* sharedContext = sharedProvider->context3d();
   2236     sharedContext->loseContextCHROMIUM(GL_GUILTY_CONTEXT_RESET_EXT, GL_INNOCENT_CONTEXT_RESET_EXT);
   2237     // To prevent tests that call loseSharedGraphicsContext3D from being
   2238     // flaky, we call finish so that the context is guaranteed to be lost
   2239     // synchronously (i.e. before returning).
   2240     sharedContext->finish();
   2241     return true;
   2242 }
   2243 
   2244 void Internals::forceCompositingUpdate(Document* document, ExceptionState& exceptionState)
   2245 {
   2246     // Hit when running content_shell with --expose-internals-for-testing.
   2247     DisableCompositingQueryAsserts disabler;
   2248 
   2249     if (!document || !document->renderView()) {
   2250         exceptionState.throwDOMException(InvalidAccessError, document ? "The document's render view cannot be retrieved." : "The document provided is invalid.");
   2251         return;
   2252     }
   2253 
   2254     document->frame()->view()->updateLayoutAndStyleForPainting();
   2255 }
   2256 
   2257 void Internals::setZoomFactor(float factor)
   2258 {
   2259     frame()->setPageZoomFactor(factor);
   2260 }
   2261 
   2262 void Internals::setShouldRevealPassword(Element* element, bool reveal, ExceptionState& exceptionState)
   2263 {
   2264     if (!isHTMLInputElement(element)) {
   2265         exceptionState.throwDOMException(InvalidAccessError, ExceptionMessages::argumentNullOrIncorrectType(1, "Element"));
   2266         return;
   2267     }
   2268 
   2269     return toHTMLInputElement(*element).setShouldRevealPassword(reveal);
   2270 }
   2271 
   2272 namespace {
   2273 
   2274 class AddOneFunction : public ScriptFunction {
   2275 public:
   2276     static PassOwnPtr<ScriptFunction> create(ExecutionContext* context)
   2277     {
   2278         return adoptPtr(new AddOneFunction(toIsolate(context)));
   2279     }
   2280 
   2281 private:
   2282     AddOneFunction(v8::Isolate* isolate)
   2283         : ScriptFunction(isolate)
   2284     {
   2285     }
   2286 
   2287     virtual ScriptValue call(ScriptValue value) OVERRIDE
   2288     {
   2289         v8::Local<v8::Value> v8Value = value.v8Value();
   2290         ASSERT(v8Value->IsNumber());
   2291         int intValue = v8Value.As<v8::Integer>()->Value();
   2292         ScriptValue result  = ScriptValue(ScriptState::current(isolate()), v8::Integer::New(isolate(), intValue + 1));
   2293         return result;
   2294     }
   2295 };
   2296 
   2297 } // namespace
   2298 
   2299 ScriptPromise Internals::createPromise(ScriptState* scriptState)
   2300 {
   2301     return ScriptPromiseResolver::create(scriptState)->promise();
   2302 }
   2303 
   2304 ScriptPromise Internals::createResolvedPromise(ScriptState* scriptState, ScriptValue value)
   2305 {
   2306     RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
   2307     ScriptPromise promise = resolver->promise();
   2308     resolver->resolve(value);
   2309     return promise;
   2310 }
   2311 
   2312 ScriptPromise Internals::createRejectedPromise(ScriptState* scriptState, ScriptValue value)
   2313 {
   2314     RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
   2315     ScriptPromise promise = resolver->promise();
   2316     resolver->reject(value);
   2317     return promise;
   2318 }
   2319 
   2320 ScriptPromise Internals::addOneToPromise(ExecutionContext* context, ScriptPromise promise)
   2321 {
   2322     return promise.then(AddOneFunction::create(context));
   2323 }
   2324 
   2325 void Internals::trace(Visitor* visitor)
   2326 {
   2327     visitor->trace(m_runtimeFlags);
   2328     visitor->trace(m_profilers);
   2329 }
   2330 
   2331 void Internals::setValueForUser(Element* element, const String& value)
   2332 {
   2333     toHTMLInputElement(element)->setValueForUser(value);
   2334 }
   2335 
   2336 String Internals::textSurroundingNode(Node* node, int x, int y, unsigned long maxLength)
   2337 {
   2338     if (!node)
   2339         return String();
   2340     blink::WebPoint point(x, y);
   2341     SurroundingText surroundingText(VisiblePosition(node->renderer()->positionForPoint(static_cast<IntPoint>(point))).deepEquivalent().parentAnchoredEquivalent(), maxLength);
   2342     return surroundingText.content();
   2343 }
   2344 
   2345 void Internals::setFocused(bool focused)
   2346 {
   2347     frame()->page()->focusController().setFocused(focused);
   2348 }
   2349 
   2350 bool Internals::ignoreLayoutWithPendingStylesheets(Document* document, ExceptionState& exceptionState)
   2351 {
   2352     if (!document) {
   2353         exceptionState.throwDOMException(InvalidAccessError, "No context document is available.");
   2354         return false;
   2355     }
   2356 
   2357     return document->ignoreLayoutWithPendingStylesheets();
   2358 }
   2359 
   2360 void Internals::setNetworkStateNotifierTestOnly(bool testOnly)
   2361 {
   2362     networkStateNotifier().setTestUpdatesOnly(testOnly);
   2363 }
   2364 
   2365 void Internals::setNetworkConnectionInfo(const String& type, ExceptionState& exceptionState)
   2366 {
   2367     blink::WebConnectionType webtype;
   2368     if (type == "cellular") {
   2369         webtype = blink::ConnectionTypeCellular;
   2370     } else if (type == "bluetooth") {
   2371         webtype = blink::ConnectionTypeBluetooth;
   2372     } else if (type == "ethernet") {
   2373         webtype = blink::ConnectionTypeEthernet;
   2374     } else if (type == "wifi") {
   2375         webtype = blink::ConnectionTypeWifi;
   2376     } else if (type == "other") {
   2377         webtype = blink::ConnectionTypeOther;
   2378     } else if (type == "none") {
   2379         webtype = blink::ConnectionTypeNone;
   2380     } else {
   2381         exceptionState.throwDOMException(NotFoundError, ExceptionMessages::failedToEnumerate("connection type", type));
   2382         return;
   2383     }
   2384     networkStateNotifier().setWebConnectionTypeForTest(webtype);
   2385 }
   2386 
   2387 } // namespace WebCore
   2388