/* * Copyright (C) 2012 Google Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "config.h" #include "Internals.h" #include "BackForwardController.h" #include "CachedResourceLoader.h" #include "Chrome.h" #include "ChromeClient.h" #include "ClientRect.h" #include "ClientRectList.h" #include "ComposedShadowTreeWalker.h" #include "Cursor.h" #include "DOMStringList.h" #include "DOMWindow.h" #include "Document.h" #include "DocumentMarker.h" #include "DocumentMarkerController.h" #include "Element.h" #include "ElementShadow.h" #include "EventHandler.h" #include "ExceptionCode.h" #include "FormController.h" #include "Frame.h" #include "FrameView.h" #include "HTMLContentElement.h" #include "HTMLInputElement.h" #include "HTMLNames.h" #include "HTMLTextAreaElement.h" #include "HistoryItem.h" #include "InspectorClient.h" #include "InspectorConsoleAgent.h" #include "InspectorController.h" #include "InspectorCounters.h" #include "InspectorFrontendChannel.h" #include "InspectorFrontendClientLocal.h" #include "InspectorInstrumentation.h" #include "InspectorOverlay.h" #include "InstrumentingAgents.h" #include "InternalSettings.h" #include "IntRect.h" #include "Language.h" #include "MallocStatistics.h" #include "MockPagePopupDriver.h" #include "NodeRenderingContext.h" #include "Page.h" #include "PrintContext.h" #include "Range.h" #include "RenderObject.h" #include "RenderTreeAsText.h" #include "RuntimeEnabledFeatures.h" #include "SchemeRegistry.h" #include "SelectRuleFeatureSet.h" #include "SerializedScriptValue.h" #include "Settings.h" #include "ShadowRoot.h" #include "SpellChecker.h" #include "TextIterator.h" #include "TreeScope.h" #include "ViewportArguments.h" #include #if ENABLE(INPUT_TYPE_COLOR) #include "ColorChooser.h" #endif #if ENABLE(BATTERY_STATUS) #include "BatteryController.h" #endif #if ENABLE(NETWORK_INFO) #include "NetworkInfo.h" #include "NetworkInfoController.h" #endif #if ENABLE(PAGE_POPUP) #include "PagePopupController.h" #endif #if ENABLE(TOUCH_ADJUSTMENT) #include "WebKitPoint.h" #endif #if PLATFORM(CHROMIUM) #include "FilterOperation.h" #include "FilterOperations.h" #include "GraphicsLayer.h" #include "GraphicsLayerChromium.h" #include "RenderLayerBacking.h" #endif namespace WebCore { #if ENABLE(PAGE_POPUP) static MockPagePopupDriver* s_pagePopupDriver = 0; #endif using namespace HTMLNames; #if ENABLE(INSPECTOR) class InspectorFrontendClientDummy : public InspectorFrontendClientLocal { public: InspectorFrontendClientDummy(InspectorController*, Page*); virtual ~InspectorFrontendClientDummy() { } virtual void attachWindow() OVERRIDE { } virtual void detachWindow() OVERRIDE { } virtual String localizedStringsURL() OVERRIDE { return String(); } virtual String hiddenPanels() OVERRIDE { return String(); } virtual void bringToFront() OVERRIDE { } virtual void closeWindow() OVERRIDE { } virtual void inspectedURLChanged(const String&) OVERRIDE { } protected: virtual void setAttachedWindowHeight(unsigned) OVERRIDE { } }; InspectorFrontendClientDummy::InspectorFrontendClientDummy(InspectorController* controller, Page* page) : InspectorFrontendClientLocal(controller, page, adoptPtr(new InspectorFrontendClientLocal::Settings())) { } class InspectorFrontendChannelDummy : public InspectorFrontendChannel { public: explicit InspectorFrontendChannelDummy(Page*); virtual ~InspectorFrontendChannelDummy() { } virtual bool sendMessageToFrontend(const String& message) OVERRIDE; private: Page* m_frontendPage; }; InspectorFrontendChannelDummy::InspectorFrontendChannelDummy(Page* page) : m_frontendPage(page) { } bool InspectorFrontendChannelDummy::sendMessageToFrontend(const String& message) { return InspectorClient::doDispatchMessageOnFrontendPage(m_frontendPage, message); } #endif // ENABLE(INSPECTOR) static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerTypes& result) { if (markerType.isEmpty() || equalIgnoringCase(markerType, "all")) result = DocumentMarker::AllMarkers(); else if (equalIgnoringCase(markerType, "Spelling")) result = DocumentMarker::Spelling; else if (equalIgnoringCase(markerType, "Grammar")) result = DocumentMarker::Grammar; else if (equalIgnoringCase(markerType, "TextMatch")) result = DocumentMarker::TextMatch; else if (equalIgnoringCase(markerType, "Replacement")) result = DocumentMarker::Replacement; else if (equalIgnoringCase(markerType, "CorrectionIndicator")) result = DocumentMarker::CorrectionIndicator; else if (equalIgnoringCase(markerType, "RejectedCorrection")) result = DocumentMarker::RejectedCorrection; else if (equalIgnoringCase(markerType, "Autocorrected")) result = DocumentMarker::Autocorrected; else if (equalIgnoringCase(markerType, "SpellCheckingExemption")) result = DocumentMarker::SpellCheckingExemption; else if (equalIgnoringCase(markerType, "DeletedAutocorrection")) result = DocumentMarker::DeletedAutocorrection; else if (equalIgnoringCase(markerType, "DictationAlternatives")) result = DocumentMarker::DictationAlternatives; else return false; return true; } static SpellChecker* spellchecker(Document* document) { if (!document || !document->frame() || !document->frame()->editor()) return 0; return document->frame()->editor()->spellChecker(); } const char* Internals::internalsId = "internals"; PassRefPtr Internals::create(Document* document) { return adoptRef(new Internals(document)); } Internals::~Internals() { } void Internals::resetToConsistentState(Page* page) { ASSERT(page); page->setPageScaleFactor(1, IntPoint(0, 0)); page->setPagination(Pagination()); TextRun::setAllowsRoundingHacks(false); WebCore::overrideUserPreferredLanguages(Vector()); WebCore::Settings::setUsesOverlayScrollbars(false); #if ENABLE(PAGE_POPUP) delete s_pagePopupDriver; s_pagePopupDriver = 0; if (page->chrome()) page->chrome()->client()->resetPagePopupDriver(); #endif #if ENABLE(INSPECTOR) && ENABLE(JAVASCRIPT_DEBUGGER) if (page->inspectorController()) page->inspectorController()->setProfilerEnabled(false); #endif } Internals::Internals(Document* document) : ContextDestructionObserver(document) { } Document* Internals::contextDocument() const { return static_cast(scriptExecutionContext()); } Frame* Internals::frame() const { if (!contextDocument()) return 0; return contextDocument()->frame(); } InternalSettings* Internals::settings() const { Document* document = contextDocument(); if (!document) return 0; Page* page = document->page(); if (!page) return 0; return InternalSettings::from(page); } String Internals::address(Node* node) { char buf[32]; sprintf(buf, "%p", node); return String(buf); } bool Internals::isPreloaded(Document* document, const String& url) { if (!document) return false; return document->cachedResourceLoader()->isPreloaded(url); } PassRefPtr Internals::createContentElement(Document* document, ExceptionCode& ec) { if (!document) { ec = INVALID_ACCESS_ERR; return 0; } return HTMLContentElement::create(document); } Element* Internals::getElementByIdInShadowRoot(Node* shadowRoot, const String& id, ExceptionCode& ec) { if (!shadowRoot || !shadowRoot->isShadowRoot()) { ec = INVALID_ACCESS_ERR; return 0; } return toShadowRoot(shadowRoot)->getElementById(id); } bool Internals::isValidContentSelect(Element* insertionPoint, ExceptionCode& ec) { if (!insertionPoint || !insertionPoint->isInsertionPoint()) { ec = INVALID_ACCESS_ERR; return false; } return toInsertionPoint(insertionPoint)->isSelectValid(); } Node* Internals::treeScopeRootNode(Node* node, ExceptionCode& ec) { if (!node) { ec = INVALID_ACCESS_ERR; return 0; } return node->treeScope()->rootNode(); } Node* Internals::parentTreeScope(Node* node, ExceptionCode& ec) { if (!node) { ec = INVALID_ACCESS_ERR; return 0; } const TreeScope* parentTreeScope = node->treeScope()->parentTreeScope(); return parentTreeScope ? parentTreeScope->rootNode() : 0; } bool Internals::hasSelectorForIdInShadow(Element* host, const String& idValue, ExceptionCode& ec) { if (!host || !host->shadow()) { ec = INVALID_ACCESS_ERR; return 0; } host->shadow()->ensureSelectFeatureSetCollected(); return host->shadow()->selectRuleFeatureSet().hasSelectorForId(idValue); } bool Internals::hasSelectorForClassInShadow(Element* host, const String& className, ExceptionCode& ec) { if (!host || !host->shadow()) { ec = INVALID_ACCESS_ERR; return 0; } host->shadow()->ensureSelectFeatureSetCollected(); return host->shadow()->selectRuleFeatureSet().hasSelectorForClass(className); } bool Internals::hasSelectorForAttributeInShadow(Element* host, const String& attributeName, ExceptionCode& ec) { if (!host || !host->shadow()) { ec = INVALID_ACCESS_ERR; return 0; } host->shadow()->ensureSelectFeatureSetCollected(); return host->shadow()->selectRuleFeatureSet().hasSelectorForAttribute(attributeName); } bool Internals::hasSelectorForPseudoClassInShadow(Element* host, const String& pseudoClass, ExceptionCode& ec) { if (!host || !host->shadow()) { ec = INVALID_ACCESS_ERR; return 0; } host->shadow()->ensureSelectFeatureSetCollected(); const SelectRuleFeatureSet& featureSet = host->shadow()->selectRuleFeatureSet(); if (pseudoClass == "checked") return featureSet.hasSelectorForChecked(); if (pseudoClass == "enabled") return featureSet.hasSelectorForEnabled(); if (pseudoClass == "disabled") return featureSet.hasSelectorForDisabled(); if (pseudoClass == "indeterminate") return featureSet.hasSelectorForIndeterminate(); if (pseudoClass == "link") return featureSet.hasSelectorForLink(); if (pseudoClass == "target") return featureSet.hasSelectorForTarget(); if (pseudoClass == "visited") return featureSet.hasSelectorForVisited(); ASSERT_NOT_REACHED(); return false; } bool Internals::hasShadowInsertionPoint(const Node* root, ExceptionCode& ec) const { if (root && root->isShadowRoot()) return toShadowRoot(root)->hasShadowInsertionPoint(); ec = INVALID_ACCESS_ERR; return 0; } bool Internals::hasContentElement(const Node* root, ExceptionCode& ec) const { if (root && root->isShadowRoot()) return toShadowRoot(root)->hasContentElement(); ec = INVALID_ACCESS_ERR; return 0; } size_t Internals::countElementShadow(const Node* root, ExceptionCode& ec) const { if (!root || !root->isShadowRoot()) { ec = INVALID_ACCESS_ERR; return 0; } return toShadowRoot(root)->countElementShadow(); } bool Internals::attached(Node* node, ExceptionCode& ec) { if (!node) { ec = INVALID_ACCESS_ERR; return false; } return node->attached(); } Node* Internals::nextSiblingByWalker(Node* node, ExceptionCode& ec) { if (!node) { ec = INVALID_ACCESS_ERR; return 0; } ComposedShadowTreeWalker walker(node); walker.nextSibling(); return walker.get(); } Node* Internals::firstChildByWalker(Node* node, ExceptionCode& ec) { if (!node) { ec = INVALID_ACCESS_ERR; return 0; } ComposedShadowTreeWalker walker(node); walker.firstChild(); return walker.get(); } Node* Internals::lastChildByWalker(Node* node, ExceptionCode& ec) { if (!node) { ec = INVALID_ACCESS_ERR; return 0; } ComposedShadowTreeWalker walker(node); walker.lastChild(); return walker.get(); } Node* Internals::nextNodeByWalker(Node* node, ExceptionCode& ec) { if (!node) { ec = INVALID_ACCESS_ERR; return 0; } ComposedShadowTreeWalker walker(node); walker.next(); return walker.get(); } Node* Internals::previousNodeByWalker(Node* node, ExceptionCode& ec) { if (!node) { ec = INVALID_ACCESS_ERR; return 0; } ComposedShadowTreeWalker walker(node); walker.previous(); return walker.get(); } String Internals::elementRenderTreeAsText(Element* element, ExceptionCode& ec) { if (!element) { ec = INVALID_ACCESS_ERR; return String(); } String representation = externalRepresentation(element); if (representation.isEmpty()) { ec = INVALID_ACCESS_ERR; return String(); } return representation; } size_t Internals::numberOfScopedHTMLStyleChildren(const Node* scope, ExceptionCode& ec) const { if (scope && (scope->isElementNode() || scope->isShadowRoot())) #if ENABLE(STYLE_SCOPED) return scope->numberOfScopedHTMLStyleChildren(); #else return 0; #endif ec = INVALID_ACCESS_ERR; return 0; } Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::ensureShadowRoot(Element* host, ExceptionCode& ec) { if (!host) { ec = INVALID_ACCESS_ERR; return 0; } if (ElementShadow* shadow = host->shadow()) return shadow->youngestShadowRoot(); return ShadowRoot::create(host, ec).get(); } Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::shadowRoot(Element* host, ExceptionCode& ec) { // FIXME: Internals::shadowRoot() in tests should be converted to youngestShadowRoot() or oldestShadowRoot(). // https://bugs.webkit.org/show_bug.cgi?id=78465 return youngestShadowRoot(host, ec); } Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::youngestShadowRoot(Element* host, ExceptionCode& ec) { if (!host) { ec = INVALID_ACCESS_ERR; return 0; } if (ElementShadow* shadow = host->shadow()) return shadow->youngestShadowRoot(); return 0; } Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::oldestShadowRoot(Element* host, ExceptionCode& ec) { if (!host) { ec = INVALID_ACCESS_ERR; return 0; } if (ElementShadow* shadow = host->shadow()) return shadow->oldestShadowRoot(); return 0; } Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::youngerShadowRoot(Node* shadow, ExceptionCode& ec) { if (!shadow || !shadow->isShadowRoot()) { ec = INVALID_ACCESS_ERR; return 0; } return toShadowRoot(shadow)->youngerShadowRoot(); } Internals::ShadowRootIfShadowDOMEnabledOrNode* Internals::olderShadowRoot(Node* shadow, ExceptionCode& ec) { if (!shadow || !shadow->isShadowRoot()) { ec = INVALID_ACCESS_ERR; return 0; } return toShadowRoot(shadow)->olderShadowRoot(); } String Internals::shadowRootType(const Node* root, ExceptionCode& ec) const { if (!root || !root->isShadowRoot()) { ec = INVALID_ACCESS_ERR; return String(); } switch (toShadowRoot(root)->type()) { case ShadowRoot::UserAgentShadowRoot: return String("UserAgentShadowRoot"); case ShadowRoot::AuthorShadowRoot: return String("AuthorShadowRoot"); default: ASSERT_NOT_REACHED(); return String("Unknown"); } } Element* Internals::includerFor(Node* node, ExceptionCode& ec) { if (!node) { ec = INVALID_ACCESS_ERR; return 0; } return NodeRenderingContext(node).insertionPoint(); } String Internals::shadowPseudoId(Element* element, ExceptionCode& ec) { if (!element) { ec = INVALID_ACCESS_ERR; return String(); } return element->shadowPseudoId().string(); } void Internals::setShadowPseudoId(Element* element, const String& id, ExceptionCode& ec) { if (!element) { ec = INVALID_ACCESS_ERR; return; } return element->setPseudo(id); } String Internals::visiblePlaceholder(Element* element) { HTMLTextFormControlElement* textControl = toTextFormControl(element); if (textControl && textControl->placeholderShouldBeVisible()) return textControl->placeholderElement()->textContent(); return String(); } #if ENABLE(INPUT_TYPE_COLOR) void Internals::selectColorInColorChooser(Element* element, const String& colorValue) { if (!element->hasTagName(inputTag)) return; HTMLInputElement* inputElement = element->toInputElement(); if (!inputElement) return; inputElement->selectColorInColorChooser(Color(colorValue)); } #endif PassRefPtr Internals::formControlStateOfPreviousHistoryItem(ExceptionCode& ec) { HistoryItem* mainItem = frame()->loader()->history()->previousItem(); if (!mainItem) { ec = INVALID_ACCESS_ERR; return 0; } String uniqueName = frame()->tree()->uniqueName(); if (mainItem->target() != uniqueName && !mainItem->childItemWithTarget(uniqueName)) { ec = INVALID_ACCESS_ERR; return 0; } const Vector& state = mainItem->target() == uniqueName ? mainItem->documentState() : mainItem->childItemWithTarget(uniqueName)->documentState(); RefPtr stringList = DOMStringList::create(); for (unsigned i = 0; i < state.size(); ++i) stringList->append(state[i]); return stringList.release(); } void Internals::setFormControlStateOfPreviousHistoryItem(PassRefPtr state, ExceptionCode& ec) { HistoryItem* mainItem = frame()->loader()->history()->previousItem(); if (!state || !mainItem) { ec = INVALID_ACCESS_ERR; return; } String uniqueName = frame()->tree()->uniqueName(); if (mainItem->target() == uniqueName) mainItem->setDocumentState(*state.get()); else if (HistoryItem* subItem = mainItem->childItemWithTarget(uniqueName)) subItem->setDocumentState(*state.get()); else ec = INVALID_ACCESS_ERR; } void Internals::setEnableMockPagePopup(bool enabled, ExceptionCode& ec) { #if ENABLE(PAGE_POPUP) Document* document = contextDocument(); if (!document || !document->page() || !document->page()->chrome()) return; Page* page = document->page(); if (!enabled) { page->chrome()->client()->resetPagePopupDriver(); return; } if (!s_pagePopupDriver) s_pagePopupDriver = MockPagePopupDriver::create(page->mainFrame()).leakPtr(); page->chrome()->client()->setPagePopupDriver(s_pagePopupDriver); #else UNUSED_PARAM(enabled); UNUSED_PARAM(ec); #endif } #if ENABLE(PAGE_POPUP) PassRefPtr Internals::pagePopupController() { return s_pagePopupDriver ? s_pagePopupDriver->pagePopupController() : 0; } #endif PassRefPtr Internals::absoluteCaretBounds(Document* document, ExceptionCode& ec) { if (!document || !document->frame() || !document->frame()->selection()) { ec = INVALID_ACCESS_ERR; return ClientRect::create(); } return ClientRect::create(document->frame()->selection()->absoluteCaretBounds()); } PassRefPtr Internals::boundingBox(Element* element, ExceptionCode& ec) { if (!element) { ec = INVALID_ACCESS_ERR; return ClientRect::create(); } element->document()->updateLayoutIgnorePendingStylesheets(); RenderObject* renderer = element->renderer(); if (!renderer) return ClientRect::create(); return ClientRect::create(renderer->absoluteBoundingBoxRectIgnoringTransforms()); } PassRefPtr Internals::inspectorHighlightRects(Document* document, ExceptionCode& ec) { #if ENABLE(INSPECTOR) if (!document || !document->page() || !document->page()->inspectorController()) { ec = INVALID_ACCESS_ERR; return ClientRectList::create(); } Highlight highlight; document->page()->inspectorController()->getHighlight(&highlight); return ClientRectList::create(highlight.quads); #else UNUSED_PARAM(document); UNUSED_PARAM(ec); return ClientRectList::create(); #endif } #if PLATFORM(CHROMIUM) void Internals::setBackgroundBlurOnNode(Node* node, int blurLength, ExceptionCode& ec) { if (!node) { ec = INVALID_ACCESS_ERR; return; } RenderObject* renderObject = node->renderer(); if (!renderObject) { ec = INVALID_NODE_TYPE_ERR; return; } RenderLayer* renderLayer = renderObject->enclosingLayer(); if (!renderLayer || !renderLayer->isComposited()) { ec = INVALID_STATE_ERR; return; } GraphicsLayer* graphicsLayer = renderLayer->backing()->graphicsLayer(); if (!graphicsLayer) { ec = INVALID_NODE_TYPE_ERR; return; } FilterOperations filters; filters.operations().append(BlurFilterOperation::create(Length(blurLength, Fixed), FilterOperation::BLUR)); static_cast(graphicsLayer)->setBackgroundFilters(filters); } #else void Internals::setBackgroundBlurOnNode(Node*, int, ExceptionCode&) { } #endif unsigned Internals::markerCountForNode(Node* node, const String& markerType, ExceptionCode& ec) { if (!node) { ec = INVALID_ACCESS_ERR; return 0; } DocumentMarker::MarkerTypes markerTypes = 0; if (!markerTypesFrom(markerType, markerTypes)) { ec = SYNTAX_ERR; return 0; } return node->document()->markers()->markersFor(node, markerTypes).size(); } DocumentMarker* Internals::markerAt(Node* node, const String& markerType, unsigned index, ExceptionCode& ec) { if (!node) { ec = INVALID_ACCESS_ERR; return 0; } DocumentMarker::MarkerTypes markerTypes = 0; if (!markerTypesFrom(markerType, markerTypes)) { ec = SYNTAX_ERR; return 0; } Vector markers = node->document()->markers()->markersFor(node, markerTypes); if (markers.size() <= index) return 0; return markers[index]; } PassRefPtr Internals::markerRangeForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec) { DocumentMarker* marker = markerAt(node, markerType, index, ec); if (!marker) return 0; return Range::create(node->document(), node, marker->startOffset(), node, marker->endOffset()); } String Internals::markerDescriptionForNode(Node* node, const String& markerType, unsigned index, ExceptionCode& ec) { DocumentMarker* marker = markerAt(node, markerType, index, ec); if (!marker) return String(); return marker->description(); } void Internals::addTextMatchMarker(const Range* range, bool isActive) { range->ownerDocument()->updateLayoutIgnorePendingStylesheets(); range->ownerDocument()->markers()->addTextMatchMarker(range, isActive); } void Internals::setScrollViewPosition(Document* document, long x, long y, ExceptionCode& ec) { if (!document || !document->view()) { ec = INVALID_ACCESS_ERR; return; } FrameView* frameView = document->view(); bool constrainsScrollingToContentEdgeOldValue = frameView->constrainsScrollingToContentEdge(); bool scrollbarsSuppressedOldValue = frameView->scrollbarsSuppressed(); frameView->setConstrainsScrollingToContentEdge(false); frameView->setScrollbarsSuppressed(false); frameView->setScrollOffsetFromInternals(IntPoint(x, y)); frameView->setScrollbarsSuppressed(scrollbarsSuppressedOldValue); frameView->setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue); } void Internals::setPagination(Document* document, const String& mode, int gap, int pageLength, ExceptionCode& ec) { if (!document || !document->page()) { ec = INVALID_ACCESS_ERR; return; } Page* page = document->page(); Pagination pagination; if (mode == "Unpaginated") pagination.mode = Pagination::Unpaginated; else if (mode == "LeftToRightPaginated") pagination.mode = Pagination::LeftToRightPaginated; else if (mode == "RightToLeftPaginated") pagination.mode = Pagination::RightToLeftPaginated; else if (mode == "TopToBottomPaginated") pagination.mode = Pagination::TopToBottomPaginated; else if (mode == "BottomToTopPaginated") pagination.mode = Pagination::BottomToTopPaginated; else { ec = SYNTAX_ERR; return; } pagination.gap = gap; pagination.pageLength = pageLength; page->setPagination(pagination); } String Internals::configurationForViewport(Document* document, float devicePixelRatio, int deviceWidth, int deviceHeight, int availableWidth, int availableHeight, ExceptionCode& ec) { if (!document || !document->page()) { ec = INVALID_ACCESS_ERR; return String(); } Page* page = document->page(); const int defaultLayoutWidthForNonMobilePages = 980; ViewportArguments arguments = page->viewportArguments(); ViewportAttributes attributes = computeViewportAttributes(arguments, defaultLayoutWidthForNonMobilePages, deviceWidth, deviceHeight, devicePixelRatio, IntSize(availableWidth, availableHeight)); restrictMinimumScaleFactorToViewportSize(attributes, IntSize(availableWidth, availableHeight), devicePixelRatio); restrictScaleFactorToInitialScaleIfNotUserScalable(attributes); return "viewport size " + String::number(attributes.layoutSize.width()) + "x" + String::number(attributes.layoutSize.height()) + " scale " + String::number(attributes.initialScale) + " with limits [" + String::number(attributes.minimumScale) + ", " + String::number(attributes.maximumScale) + "] and userScalable " + (attributes.userScalable ? "true" : "false"); } bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionCode& ec) { if (!textField) { ec = INVALID_ACCESS_ERR; return false; } if (HTMLInputElement* inputElement = textField->toInputElement()) return inputElement->lastChangeWasUserEdit(); // FIXME: We should be using hasTagName instead but Windows port doesn't link QualifiedNames properly. if (textField->tagName() == "TEXTAREA") return static_cast(textField)->lastChangeWasUserEdit(); ec = INVALID_NODE_TYPE_ERR; return false; } String Internals::suggestedValue(Element* element, ExceptionCode& ec) { if (!element) { ec = INVALID_ACCESS_ERR; return String(); } HTMLInputElement* inputElement = element->toInputElement(); if (!inputElement) { ec = INVALID_NODE_TYPE_ERR; return String(); } return inputElement->suggestedValue(); } void Internals::setSuggestedValue(Element* element, const String& value, ExceptionCode& ec) { if (!element) { ec = INVALID_ACCESS_ERR; return; } HTMLInputElement* inputElement = element->toInputElement(); if (!inputElement) { ec = INVALID_NODE_TYPE_ERR; return; } inputElement->setSuggestedValue(value); } void Internals::setEditingValue(Element* element, const String& value, ExceptionCode& ec) { if (!element) { ec = INVALID_ACCESS_ERR; return; } HTMLInputElement* inputElement = element->toInputElement(); if (!inputElement) { ec = INVALID_NODE_TYPE_ERR; return; } inputElement->setEditingValue(value); } void Internals::scrollElementToRect(Element* element, long x, long y, long w, long h, ExceptionCode& ec) { if (!element || !element->document() || !element->document()->view()) { ec = INVALID_ACCESS_ERR; return; } FrameView* frameView = element->document()->view(); frameView->scrollElementToRect(element, IntRect(x, y, w, h)); } void Internals::paintControlTints(Document* document, ExceptionCode& ec) { if (!document || !document->view()) { ec = INVALID_ACCESS_ERR; return; } FrameView* frameView = document->view(); frameView->paintControlTints(); } PassRefPtr Internals::rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionCode& ec) { if (!scope) { ec = INVALID_ACCESS_ERR; return 0; } return TextIterator::rangeFromLocationAndLength(scope, rangeLocation, rangeLength); } unsigned Internals::locationFromRange(Element* scope, const Range* range, ExceptionCode& ec) { if (!scope || !range) { ec = INVALID_ACCESS_ERR; return 0; } size_t location = 0; size_t unusedLength = 0; TextIterator::getLocationAndLengthFromRange(scope, range, location, unusedLength); return location; } unsigned Internals::lengthFromRange(Element* scope, const Range* range, ExceptionCode& ec) { if (!scope || !range) { ec = INVALID_ACCESS_ERR; return 0; } size_t unusedLocation = 0; size_t length = 0; TextIterator::getLocationAndLengthFromRange(scope, range, unusedLocation, length); return length; } String Internals::rangeAsText(const Range* range, ExceptionCode& ec) { if (!range) { ec = INVALID_ACCESS_ERR; return String(); } return range->text(); } void Internals::setDelegatesScrolling(bool enabled, Document* document, ExceptionCode& ec) { // Delegate scrolling is valid only on mainframe's view. if (!document || !document->view() || !document->page() || document->page()->mainFrame() != document->frame()) { ec = INVALID_ACCESS_ERR; return; } document->view()->setDelegatesScrolling(enabled); } #if ENABLE(TOUCH_ADJUSTMENT) PassRefPtr Internals::touchPositionAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionCode& ec) { if (!document || !document->frame()) { ec = INVALID_ACCESS_ERR; return 0; } IntSize radius(width / 2, height / 2); IntPoint point(x + radius.width(), y + radius.height()); Node* targetNode; IntPoint adjustedPoint; bool foundNode = document->frame()->eventHandler()->bestClickableNodeForTouchPoint(point, radius, adjustedPoint, targetNode); if (foundNode) return WebKitPoint::create(adjustedPoint.x(), adjustedPoint.y()); return 0; } Node* Internals::touchNodeAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionCode& ec) { if (!document || !document->frame()) { ec = INVALID_ACCESS_ERR; return 0; } IntSize radius(width / 2, height / 2); IntPoint point(x + radius.width(), y + radius.height()); Node* targetNode; IntPoint adjustedPoint; document->frame()->eventHandler()->bestClickableNodeForTouchPoint(point, radius, adjustedPoint, targetNode); return targetNode; } PassRefPtr Internals::touchPositionAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document* document, ExceptionCode& ec) { if (!document || !document->frame()) { ec = INVALID_ACCESS_ERR; return 0; } IntSize radius(width / 2, height / 2); IntPoint point(x + radius.width(), y + radius.height()); Node* targetNode = 0; IntPoint adjustedPoint; bool foundNode = document->frame()->eventHandler()->bestContextMenuNodeForTouchPoint(point, radius, adjustedPoint, targetNode); if (foundNode) return WebKitPoint::create(adjustedPoint.x(), adjustedPoint.y()); return WebKitPoint::create(x, y); } Node* Internals::touchNodeAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document* document, ExceptionCode& ec) { if (!document || !document->frame()) { ec = INVALID_ACCESS_ERR; return 0; } IntSize radius(width / 2, height / 2); IntPoint point(x + radius.width(), y + radius.height()); Node* targetNode = 0; IntPoint adjustedPoint; document->frame()->eventHandler()->bestContextMenuNodeForTouchPoint(point, radius, adjustedPoint, targetNode); return targetNode; } PassRefPtr Internals::bestZoomableAreaForTouchPoint(long x, long y, long width, long height, Document* document, ExceptionCode& ec) { if (!document || !document->frame()) { ec = INVALID_ACCESS_ERR; return 0; } IntSize radius(width / 2, height / 2); IntPoint point(x + radius.width(), y + radius.height()); Node* targetNode; IntRect zoomableArea; bool foundNode = document->frame()->eventHandler()->bestZoomableAreaForTouchPoint(point, radius, zoomableArea, targetNode); if (foundNode) return ClientRect::create(zoomableArea); return 0; } #endif int Internals::lastSpellCheckRequestSequence(Document* document, ExceptionCode& ec) { SpellChecker* checker = spellchecker(document); if (!checker) { ec = INVALID_ACCESS_ERR; return -1; } return checker->lastRequestSequence(); } int Internals::lastSpellCheckProcessedSequence(Document* document, ExceptionCode& ec) { SpellChecker* checker = spellchecker(document); if (!checker) { ec = INVALID_ACCESS_ERR; return -1; } return checker->lastProcessedSequence(); } Vector Internals::userPreferredLanguages() const { return WebCore::userPreferredLanguages(); } void Internals::setUserPreferredLanguages(const Vector& languages) { WebCore::overrideUserPreferredLanguages(languages); } unsigned Internals::wheelEventHandlerCount(Document* document, ExceptionCode& ec) { if (!document) { ec = INVALID_ACCESS_ERR; return 0; } return document->wheelEventHandlerCount(); } unsigned Internals::touchEventHandlerCount(Document* document, ExceptionCode& ec) { if (!document) { ec = INVALID_ACCESS_ERR; return 0; } return document->touchEventHandlerCount(); } PassRefPtr Internals::nodesFromRect(Document* document, int x, int y, unsigned topPadding, unsigned rightPadding, unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, ExceptionCode& ec) const { if (!document || !document->frame() || !document->frame()->view()) { ec = INVALID_ACCESS_ERR; return 0; } return document->nodesFromRect(x, y, topPadding, rightPadding, bottomPadding, leftPadding, ignoreClipping, allowShadowContent); } void Internals::emitInspectorDidBeginFrame() { InspectorInstrumentation::didBeginFrame(contextDocument()->frame()->page()); } void Internals::emitInspectorDidCancelFrame() { InspectorInstrumentation::didCancelFrame(contextDocument()->frame()->page()); } void Internals::setBatteryStatus(Document* document, const String& eventType, bool charging, double chargingTime, double dischargingTime, double level, ExceptionCode& ec) { if (!document || !document->page()) { ec = INVALID_ACCESS_ERR; return; } #if ENABLE(BATTERY_STATUS) BatteryController::from(document->page())->didChangeBatteryStatus(eventType, BatteryStatus::create(charging, chargingTime, dischargingTime, level)); #else UNUSED_PARAM(eventType); UNUSED_PARAM(charging); UNUSED_PARAM(chargingTime); UNUSED_PARAM(dischargingTime); UNUSED_PARAM(level); #endif } void Internals::setNetworkInformation(Document* document, const String& eventType, double bandwidth, bool metered, ExceptionCode& ec) { if (!document || !document->page()) { ec = INVALID_ACCESS_ERR; return; } #if ENABLE(NETWORK_INFO) NetworkInfoController::from(document->page())->didChangeNetworkInformation(eventType, NetworkInfo::create(bandwidth, metered)); #else UNUSED_PARAM(eventType); UNUSED_PARAM(bandwidth); UNUSED_PARAM(metered); #endif } bool Internals::hasSpellingMarker(Document* document, int from, int length, ExceptionCode&) { if (!document || !document->frame()) return 0; return document->frame()->editor()->selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length); } bool Internals::hasAutocorrectedMarker(Document* document, int from, int length, ExceptionCode&) { if (!document || !document->frame()) return 0; return document->frame()->editor()->selectionStartHasMarkerFor(DocumentMarker::Autocorrected, from, length); } #if ENABLE(INSPECTOR) unsigned Internals::numberOfLiveNodes() const { return InspectorCounters::counterValue(InspectorCounters::NodeCounter); } unsigned Internals::numberOfLiveDocuments() const { return InspectorCounters::counterValue(InspectorCounters::DocumentCounter); } Vector Internals::consoleMessageArgumentCounts(Document* document) const { InstrumentingAgents* instrumentingAgents = instrumentationForPage(document->page()); if (!instrumentingAgents) return Vector(); InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent(); if (!consoleAgent) return Vector(); Vector counts = consoleAgent->consoleMessageArgumentCounts(); Vector result(counts.size()); for (size_t i = 0; i < counts.size(); i++) result[i] = String::number(counts[i]); return result; } PassRefPtr Internals::openDummyInspectorFrontend(const String& url) { Page* page = contextDocument()->frame()->page(); ASSERT(page); DOMWindow* window = page->mainFrame()->document()->domWindow(); ASSERT(window); m_frontendWindow = window->open(url, "", "", window, window); ASSERT(m_frontendWindow); Page* frontendPage = m_frontendWindow->document()->page(); ASSERT(frontendPage); OwnPtr frontendClient = adoptPtr(new InspectorFrontendClientDummy(page->inspectorController(), frontendPage)); frontendPage->inspectorController()->setInspectorFrontendClient(frontendClient.release()); m_frontendChannel = adoptPtr(new InspectorFrontendChannelDummy(frontendPage)); page->inspectorController()->connectFrontend(m_frontendChannel.get()); return m_frontendWindow; } void Internals::closeDummyInspectorFrontend() { Page* page = contextDocument()->frame()->page(); ASSERT(page); ASSERT(m_frontendWindow); page->inspectorController()->disconnectFrontend(); m_frontendChannel.release(); m_frontendWindow->close(m_frontendWindow->scriptExecutionContext()); m_frontendWindow.release(); } void Internals::setInspectorResourcesDataSizeLimits(int maximumResourcesContentSize, int maximumSingleResourceContentSize, ExceptionCode& ec) { Page* page = contextDocument()->frame()->page(); if (!page || !page->inspectorController()) { ec = INVALID_ACCESS_ERR; return; } page->inspectorController()->setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize); } void Internals::setJavaScriptProfilingEnabled(bool enabled, ExceptionCode& ec) { Page* page = contextDocument()->frame()->page(); if (!page || !page->inspectorController()) { ec = INVALID_ACCESS_ERR; return; } page->inspectorController()->setProfilerEnabled(enabled); } #endif // ENABLE(INSPECTOR) bool Internals::hasGrammarMarker(Document* document, int from, int length, ExceptionCode&) { if (!document || !document->frame()) return 0; return document->frame()->editor()->selectionStartHasMarkerFor(DocumentMarker::Grammar, from, length); } unsigned Internals::numberOfScrollableAreas(Document* document, ExceptionCode&) { unsigned count = 0; Frame* frame = document->frame(); if (frame->view()->scrollableAreas()) count += frame->view()->scrollableAreas()->size(); for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) { if (child->view() && child->view()->scrollableAreas()) count += child->view()->scrollableAreas()->size(); } return count; } bool Internals::isPageBoxVisible(Document* document, int pageNumber, ExceptionCode& ec) { if (!document) { ec = INVALID_ACCESS_ERR; return false; } return document->isPageBoxVisible(pageNumber); } void Internals::suspendAnimations(Document* document, ExceptionCode& ec) const { if (!document || !document->frame()) { ec = INVALID_ACCESS_ERR; return; } AnimationController* controller = document->frame()->animation(); if (!controller) return; controller->suspendAnimations(); } void Internals::resumeAnimations(Document* document, ExceptionCode& ec) const { if (!document || !document->frame()) { ec = INVALID_ACCESS_ERR; return; } AnimationController* controller = document->frame()->animation(); if (!controller) return; controller->resumeAnimations(); } String Internals::layerTreeAsText(Document* document, ExceptionCode& ec) const { return layerTreeAsText(document, 0, ec); } String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionCode& ec) const { if (!document || !document->frame()) { ec = INVALID_ACCESS_ERR; return String(); } LayerTreeFlags layerTreeFlags = 0; if (flags & LAYER_TREE_INCLUDES_VISIBLE_RECTS) layerTreeFlags |= LayerTreeFlagsIncludeVisibleRects; if (flags & LAYER_TREE_INCLUDES_TILE_CACHES) layerTreeFlags |= LayerTreeFlagsIncludeTileCaches; if (flags & LAYER_TREE_INCLUDES_REPAINT_RECTS) layerTreeFlags |= LayerTreeFlagsIncludeRepaintRects; return document->frame()->layerTreeAsText(layerTreeFlags); } String Internals::repaintRectsAsText(Document* document, ExceptionCode& ec) const { if (!document || !document->frame()) { ec = INVALID_ACCESS_ERR; return String(); } return document->frame()->trackedRepaintRectsAsText(); } String Internals::scrollingStateTreeAsText(Document* document, ExceptionCode& ec) const { if (!document || !document->frame()) { ec = INVALID_ACCESS_ERR; return String(); } Page* page = document->page(); if (!page) return String(); return page->scrollingStateTreeAsText(); } void Internals::garbageCollectDocumentResources(Document* document, ExceptionCode& ec) const { if (!document) { ec = INVALID_ACCESS_ERR; return; } CachedResourceLoader* cachedResourceLoader = document->cachedResourceLoader(); if (!cachedResourceLoader) return; cachedResourceLoader->garbageCollectDocumentResources(); } void Internals::allowRoundingHacks() const { TextRun::setAllowsRoundingHacks(true); } String Internals::counterValue(Element* element) { if (!element) return String(); return counterValueForElement(element); } int Internals::pageNumber(Element* element, float pageWidth, float pageHeight) { if (!element) return 0; return PrintContext::pageNumberForElement(element, FloatSize(pageWidth, pageHeight)); } PassRefPtr Internals::iconURLs(Document* document) const { Vector iconURLs = document->iconURLs(); RefPtr stringList = DOMStringList::create(); Vector::const_iterator iter(iconURLs.begin()); for (; iter != iconURLs.end(); ++iter) stringList->append(iter->m_iconURL.string()); return stringList.release(); } int Internals::numberOfPages(float pageWidth, float pageHeight) { if (!frame()) return -1; return PrintContext::numberOfPages(frame(), FloatSize(pageWidth, pageHeight)); } String Internals::pageProperty(String propertyName, int pageNumber, ExceptionCode& ec) const { if (!frame()) { ec = INVALID_ACCESS_ERR; return String(); } return PrintContext::pageProperty(frame(), propertyName.utf8().data(), pageNumber); } String Internals::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft, ExceptionCode& ec) const { if (!frame()) { ec = INVALID_ACCESS_ERR; return String(); } return PrintContext::pageSizeAndMarginsInPixels(frame(), pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft); } void Internals::setPageScaleFactor(float scaleFactor, int x, int y, ExceptionCode& ec) { Document* document = contextDocument(); if (!document || !document->page()) { ec = INVALID_ACCESS_ERR; return; } Page* page = document->page(); page->setPageScaleFactor(scaleFactor, IntPoint(x, y)); } #if ENABLE(FULLSCREEN_API) void Internals::webkitWillEnterFullScreenForElement(Document* document, Element* element) { if (!document) return; document->webkitWillEnterFullScreenForElement(element); } void Internals::webkitDidEnterFullScreenForElement(Document* document, Element* element) { if (!document) return; document->webkitDidEnterFullScreenForElement(element); } void Internals::webkitWillExitFullScreenForElement(Document* document, Element* element) { if (!document) return; document->webkitWillExitFullScreenForElement(element); } void Internals::webkitDidExitFullScreenForElement(Document* document, Element* element) { if (!document) return; document->webkitDidExitFullScreenForElement(element); } #endif void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme) { SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme); } void Internals::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme) { SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme); } PassRefPtr Internals::mallocStatistics() const { return MallocStatistics::create(); } PassRefPtr Internals::getReferencedFilePaths() const { RefPtr stringList = DOMStringList::create(); frame()->loader()->history()->saveDocumentAndScrollState(); const Vector& filePaths = FormController::getReferencedFilePaths(frame()->loader()->history()->currentItem()->documentState()); for (size_t i = 0; i < filePaths.size(); ++i) stringList->append(filePaths[i]); return stringList.release(); } void Internals::startTrackingRepaints(Document* document, ExceptionCode& ec) { if (!document || !document->view()) { ec = INVALID_ACCESS_ERR; return; } FrameView* frameView = document->view(); frameView->setTracksRepaints(true); } void Internals::stopTrackingRepaints(Document* document, ExceptionCode& ec) { if (!document || !document->view()) { ec = INVALID_ACCESS_ERR; return; } FrameView* frameView = document->view(); frameView->setTracksRepaints(false); } #if USE(LAZY_NATIVE_CURSOR) static const char* cursorTypeToString(Cursor::Type cursorType) { switch (cursorType) { case Cursor::Pointer: return "Pointer"; case Cursor::Cross: return "Cross"; case Cursor::Hand: return "Hand"; case Cursor::IBeam: return "IBeam"; case Cursor::Wait: return "Wait"; case Cursor::Help: return "Help"; case Cursor::EastResize: return "EastResize"; case Cursor::NorthResize: return "NorthResize"; case Cursor::NorthEastResize: return "NorthEastResize"; case Cursor::NorthWestResize: return "NorthWestResize"; case Cursor::SouthResize: return "SouthResize"; case Cursor::SouthEastResize: return "SouthEastResize"; case Cursor::SouthWestResize: return "SouthWestResize"; case Cursor::WestResize: return "WestResize"; case Cursor::NorthSouthResize: return "NorthSouthResize"; case Cursor::EastWestResize: return "EastWestResize"; case Cursor::NorthEastSouthWestResize: return "NorthEastSouthWestResize"; case Cursor::NorthWestSouthEastResize: return "NorthWestSouthEastResize"; case Cursor::ColumnResize: return "ColumnResize"; case Cursor::RowResize: return "RowResize"; case Cursor::MiddlePanning: return "MiddlePanning"; case Cursor::EastPanning: return "EastPanning"; case Cursor::NorthPanning: return "NorthPanning"; case Cursor::NorthEastPanning: return "NorthEastPanning"; case Cursor::NorthWestPanning: return "NorthWestPanning"; case Cursor::SouthPanning: return "SouthPanning"; case Cursor::SouthEastPanning: return "SouthEastPanning"; case Cursor::SouthWestPanning: return "SouthWestPanning"; case Cursor::WestPanning: return "WestPanning"; case Cursor::Move: return "Move"; case Cursor::VerticalText: return "VerticalText"; case Cursor::Cell: return "Cell"; case Cursor::ContextMenu: return "ContextMenu"; case Cursor::Alias: return "Alias"; case Cursor::Progress: return "Progress"; case Cursor::NoDrop: return "NoDrop"; case Cursor::Copy: return "Copy"; case Cursor::None: return "None"; case Cursor::NotAllowed: return "NotAllowed"; case Cursor::ZoomIn: return "ZoomIn"; case Cursor::ZoomOut: return "ZoomOut"; case Cursor::Grab: return "Grab"; case Cursor::Grabbing: return "Grabbing"; case Cursor::Custom: return "Custom"; } ASSERT_NOT_REACHED(); return "UNKNOWN"; } #endif String Internals::getCurrentCursorInfo(Document* document, ExceptionCode& ec) { if (!document || !document->frame()) { ec = INVALID_ACCESS_ERR; return String(); } Cursor cursor = document->frame()->eventHandler()->currentMouseCursor(); #if USE(LAZY_NATIVE_CURSOR) StringBuilder result; result.append("type="); result.append(cursorTypeToString(cursor.type())); result.append(" hotSpot="); result.appendNumber(cursor.hotSpot().x()); result.append(","); result.appendNumber(cursor.hotSpot().y()); if (cursor.image()) { IntSize size = cursor.image()->size(); result.append(" image="); result.appendNumber(size.width()); result.append("x"); result.appendNumber(size.height()); } return result.toString(); #else return "FAIL: Cursor details not available on this platform."; #endif } PassRefPtr Internals::serializeObject(PassRefPtr value) const { String stringValue = value->toWireString(); return ArrayBuffer::create(static_cast(stringValue.impl()->characters()), stringValue.sizeInBytes()); } PassRefPtr Internals::deserializeBuffer(PassRefPtr buffer) const { String value(static_cast(buffer->data()), buffer->byteLength() / sizeof(UChar)); return SerializedScriptValue::createFromWire(value); } void Internals::setUsesOverlayScrollbars(bool enabled) { WebCore::Settings::setUsesOverlayScrollbars(enabled); } }