diff options
Diffstat (limited to 'Source/WebKit2/WebProcess/InjectedBundle/DOM')
8 files changed, 526 insertions, 106 deletions
diff --git a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleCSSStyleDeclarationHandle.cpp b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleCSSStyleDeclarationHandle.cpp new file mode 100644 index 000000000..2a8f17a4a --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleCSSStyleDeclarationHandle.cpp @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2014 Apple 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 INC. 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 INC. 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 "InjectedBundleCSSStyleDeclarationHandle.h" + +#include <WebCore/CSSStyleDeclaration.h> +#include <wtf/HashMap.h> +#include <wtf/NeverDestroyed.h> + +using namespace WebCore; + +namespace WebKit { + +typedef HashMap<CSSStyleDeclaration*, InjectedBundleCSSStyleDeclarationHandle*> DOMHandleCache; + +static DOMHandleCache& domHandleCache() +{ + static NeverDestroyed<DOMHandleCache> cache; + return cache; +} + +PassRefPtr<InjectedBundleCSSStyleDeclarationHandle> InjectedBundleCSSStyleDeclarationHandle::getOrCreate(CSSStyleDeclaration* styleDeclaration) +{ + if (!styleDeclaration) + return nullptr; + + DOMHandleCache::AddResult result = domHandleCache().add(styleDeclaration, nullptr); + if (!result.isNewEntry) + return PassRefPtr<InjectedBundleCSSStyleDeclarationHandle>(result.iterator->value); + + auto styleDeclarationHandle = adoptRef(*new InjectedBundleCSSStyleDeclarationHandle(*styleDeclaration)); + result.iterator->value = styleDeclarationHandle.ptr(); + return WTFMove(styleDeclarationHandle); +} + +InjectedBundleCSSStyleDeclarationHandle::InjectedBundleCSSStyleDeclarationHandle(CSSStyleDeclaration& styleDeclaration) + : m_styleDeclaration(styleDeclaration) +{ +} + +InjectedBundleCSSStyleDeclarationHandle::~InjectedBundleCSSStyleDeclarationHandle() +{ + domHandleCache().remove(m_styleDeclaration.ptr()); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleCSSStyleDeclarationHandle.h b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleCSSStyleDeclarationHandle.h new file mode 100644 index 000000000..84c93c1ed --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleCSSStyleDeclarationHandle.h @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2014 Apple 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 INC. 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 INC. 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. + */ + +#ifndef InjectedBundleCSSStyleDeclarationHandle_h +#define InjectedBundleCSSStyleDeclarationHandle_h + +#include "APIObject.h" +#include <wtf/PassRefPtr.h> +#include <wtf/Ref.h> + +namespace WebCore { +class CSSStyleDeclaration; +} + +namespace WebKit { + +class InjectedBundleCSSStyleDeclarationHandle : public API::ObjectImpl<API::Object::Type::BundleCSSStyleDeclarationHandle> { +public: + static PassRefPtr<InjectedBundleCSSStyleDeclarationHandle> getOrCreate(WebCore::CSSStyleDeclaration*); + virtual ~InjectedBundleCSSStyleDeclarationHandle(); + +private: + InjectedBundleCSSStyleDeclarationHandle(WebCore::CSSStyleDeclaration&); + + Ref<WebCore::CSSStyleDeclaration> m_styleDeclaration; +}; + +} // namespace WebKit + +#endif // InjectedBundleCSSStyleDeclarationHandle_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleFileHandle.cpp b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleFileHandle.cpp new file mode 100644 index 000000000..193403a4e --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleFileHandle.cpp @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2015 Apple 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 INC. 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 INC. 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 "InjectedBundleFileHandle.h" + +#include <WebCore/File.h> +#include <wtf/HashMap.h> +#include <wtf/NeverDestroyed.h> + +using namespace WebCore; + +namespace WebKit { + +typedef HashMap<File*, InjectedBundleFileHandle*> DOMHandleCache; + +static DOMHandleCache& domHandleCache() +{ + static NeverDestroyed<DOMHandleCache> cache; + return cache; +} + +RefPtr<InjectedBundleFileHandle> InjectedBundleFileHandle::create(const String& path) +{ + auto file = File::create(path); + return adoptRef(new InjectedBundleFileHandle(file.get())); +} + +RefPtr<InjectedBundleFileHandle> InjectedBundleFileHandle::getOrCreate(File* file) +{ + if (!file) + return nullptr; + + DOMHandleCache::AddResult result = domHandleCache().add(file, nullptr); + if (!result.isNewEntry) + return RefPtr<InjectedBundleFileHandle>(result.iterator->value); + + RefPtr<InjectedBundleFileHandle> fileHandle = adoptRef(new InjectedBundleFileHandle(*file)); + result.iterator->value = fileHandle.get(); + return fileHandle; +} + +InjectedBundleFileHandle::InjectedBundleFileHandle(File& file) + : m_file(file) +{ +} + +InjectedBundleFileHandle::~InjectedBundleFileHandle() +{ + domHandleCache().remove(m_file.ptr()); +} + +File* InjectedBundleFileHandle::coreFile() +{ + return m_file.ptr(); +} + +} // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleFileHandle.h b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleFileHandle.h new file mode 100644 index 000000000..c0bb79884 --- /dev/null +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleFileHandle.h @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2015 Apple 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 INC. 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 INC. 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. + */ + +#ifndef InjectedBundleFileHandle_h +#define InjectedBundleFileHandle_h + +#include "APIObject.h" +#include <wtf/Forward.h> +#include <wtf/RefPtr.h> + +namespace WebCore { +class File; +} + +namespace WebKit { + +class InjectedBundleFileHandle : public API::ObjectImpl<API::Object::Type::BundleFileHandle> { +public: + static RefPtr<InjectedBundleFileHandle> create(const WTF::String&); + static RefPtr<InjectedBundleFileHandle> getOrCreate(WebCore::File*); + + virtual ~InjectedBundleFileHandle(); + + WebCore::File* coreFile(); + +private: + InjectedBundleFileHandle(WebCore::File&); + + Ref<WebCore::File> m_file; +}; + +} // namespace WebKit + +#endif // InjectedBundleFileHandle_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp index ccff2b36f..c91af8eaf 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.cpp @@ -26,6 +26,7 @@ #include "config.h" #include "InjectedBundleNodeHandle.h" +#include "InjectedBundleRangeHandle.h" #include "ShareableBitmap.h" #include "WebFrame.h" #include "WebFrameLoaderClient.h" @@ -46,7 +47,10 @@ #include <WebCore/JSNode.h> #include <WebCore/Node.h> #include <WebCore/Page.h> +#include <WebCore/Position.h> +#include <WebCore/Range.h> #include <WebCore/RenderObject.h> +#include <WebCore/VisiblePosition.h> #include <wtf/HashMap.h> #include <wtf/NeverDestroyed.h> #include <wtf/text/WTFString.h> @@ -64,78 +68,81 @@ static DOMHandleCache& domHandleCache() return cache; } -PassRefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::getOrCreate(JSContextRef, JSObjectRef object) +RefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::getOrCreate(JSContextRef, JSObjectRef object) { - Node* node = toNode(toJS(object)); + Node* node = JSNode::toWrapped(*toJS(object)->vm(), toJS(object)); return getOrCreate(node); } -PassRefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::getOrCreate(Node* node) +RefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::getOrCreate(Node* node) { if (!node) - return 0; + return nullptr; - DOMHandleCache::AddResult result = domHandleCache().add(node, nullptr); + return InjectedBundleNodeHandle::getOrCreate(*node); +} + +Ref<InjectedBundleNodeHandle> InjectedBundleNodeHandle::getOrCreate(Node& node) +{ + DOMHandleCache::AddResult result = domHandleCache().add(&node, nullptr); if (!result.isNewEntry) - return PassRefPtr<InjectedBundleNodeHandle>(result.iterator->value); + return Ref<InjectedBundleNodeHandle>(*result.iterator->value); - RefPtr<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::create(node); - result.iterator->value = nodeHandle.get(); - return nodeHandle.release(); + Ref<InjectedBundleNodeHandle> nodeHandle = InjectedBundleNodeHandle::create(node); + result.iterator->value = nodeHandle.ptr(); + return nodeHandle; } -PassRefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::create(Node* node) +Ref<InjectedBundleNodeHandle> InjectedBundleNodeHandle::create(Node& node) { - return adoptRef(new InjectedBundleNodeHandle(node)); + return adoptRef(*new InjectedBundleNodeHandle(node)); } -InjectedBundleNodeHandle::InjectedBundleNodeHandle(Node* node) +InjectedBundleNodeHandle::InjectedBundleNodeHandle(Node& node) : m_node(node) { } InjectedBundleNodeHandle::~InjectedBundleNodeHandle() { - domHandleCache().remove(m_node.get()); + domHandleCache().remove(m_node.ptr()); } -Node* InjectedBundleNodeHandle::coreNode() const +Node* InjectedBundleNodeHandle::coreNode() { - return m_node.get(); + return m_node.ptr(); } -PassRefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::document() +Ref<InjectedBundleNodeHandle> InjectedBundleNodeHandle::document() { - return getOrCreate(&m_node->document()); + return getOrCreate(m_node->document()); } // Additional DOM Operations // Note: These should only be operations that are not exposed to JavaScript. -IntRect InjectedBundleNodeHandle::elementBounds() const +IntRect InjectedBundleNodeHandle::elementBounds() { - if (!m_node->isElementNode()) + if (!is<Element>(m_node)) return IntRect(); - return toElement(m_node.get())->boundsInRootViewSpace(); + return downcast<Element>(m_node.get()).boundsInRootViewSpace(); } -IntRect InjectedBundleNodeHandle::renderRect(bool* isReplaced) const +IntRect InjectedBundleNodeHandle::renderRect(bool* isReplaced) { - return m_node.get()->pixelSnappedRenderRect(isReplaced); + return m_node->pixelSnappedRenderRect(isReplaced); } -static PassRefPtr<WebImage> imageForRect(FrameView* frameView, const IntRect& rect, SnapshotOptions options) +static RefPtr<WebImage> imageForRect(FrameView* frameView, const IntRect& rect, SnapshotOptions options) { IntSize bitmapSize = rect.size(); float scaleFactor = frameView->frame().page()->deviceScaleFactor(); bitmapSize.scale(scaleFactor); - RefPtr<WebImage> snapshot = WebImage::create(bitmapSize, snapshotOptionsToImageOptions(options)); - if (!snapshot->bitmap()) - return 0; + auto snapshot = WebImage::create(bitmapSize, snapshotOptionsToImageOptions(options)); - auto graphicsContext = snapshot->bitmap()->createGraphicsContext(); + auto graphicsContext = snapshot->bitmap().createGraphicsContext(); graphicsContext->clearRect(IntRect(IntPoint(), bitmapSize)); graphicsContext->applyDeviceScaleFactor(scaleFactor); graphicsContext->translate(-rect.x(), -rect.y()); @@ -144,122 +151,181 @@ static PassRefPtr<WebImage> imageForRect(FrameView* frameView, const IntRect& re if (options & SnapshotOptionsExcludeSelectionHighlighting) shouldPaintSelection = FrameView::ExcludeSelection; - frameView->paintContentsForSnapshot(graphicsContext.get(), rect, shouldPaintSelection, FrameView::DocumentCoordinates); + PaintBehavior paintBehavior = frameView->paintBehavior() | PaintBehaviorFlattenCompositingLayers; + if (options & SnapshotOptionsForceBlackText) + paintBehavior |= PaintBehaviorForceBlackText; + if (options & SnapshotOptionsForceWhiteText) + paintBehavior |= PaintBehaviorForceWhiteText; - return snapshot.release(); + PaintBehavior oldPaintBehavior = frameView->paintBehavior(); + frameView->setPaintBehavior(paintBehavior); + frameView->paintContentsForSnapshot(*graphicsContext.get(), rect, shouldPaintSelection, FrameView::DocumentCoordinates); + frameView->setPaintBehavior(oldPaintBehavior); + + return snapshot; } -PassRefPtr<WebImage> InjectedBundleNodeHandle::renderedImage(SnapshotOptions options) +RefPtr<WebImage> InjectedBundleNodeHandle::renderedImage(SnapshotOptions options) { Frame* frame = m_node->document().frame(); if (!frame) - return 0; + return nullptr; FrameView* frameView = frame->view(); if (!frameView) - return 0; + return nullptr; m_node->document().updateLayout(); RenderObject* renderer = m_node->renderer(); if (!renderer) - return 0; + return nullptr; LayoutRect topLevelRect; - IntRect paintingRect = pixelSnappedIntRect(renderer->paintingRootRect(topLevelRect)); + IntRect paintingRect = snappedIntRect(renderer->paintingRootRect(topLevelRect)); - frameView->setNodeToDraw(m_node.get()); - RefPtr<WebImage> image = imageForRect(frameView, paintingRect, options); + frameView->setNodeToDraw(m_node.ptr()); + auto image = imageForRect(frameView, paintingRect, options); frameView->setNodeToDraw(0); - return image.release(); + return image; +} + +RefPtr<InjectedBundleRangeHandle> InjectedBundleNodeHandle::visibleRange() +{ + VisiblePosition start = firstPositionInNode(m_node.ptr()); + VisiblePosition end = lastPositionInNode(m_node.ptr()); + + RefPtr<Range> range = makeRange(start, end); + return InjectedBundleRangeHandle::getOrCreate(range.get()); } void InjectedBundleNodeHandle::setHTMLInputElementValueForUser(const String& value) { - if (!isHTMLInputElement(m_node.get())) + if (!is<HTMLInputElement>(m_node)) + return; + + downcast<HTMLInputElement>(m_node.get()).setValueForUser(value); +} + +void InjectedBundleNodeHandle::setHTMLInputElementSpellcheckEnabled(bool enabled) +{ + if (!is<HTMLInputElement>(m_node)) return; - toHTMLInputElement(m_node.get())->setValueForUser(value); + downcast<HTMLInputElement>(m_node.get()).setSpellcheckDisabledExceptTextReplacement(!enabled); } -bool InjectedBundleNodeHandle::isHTMLInputElementAutofilled() const +bool InjectedBundleNodeHandle::isHTMLInputElementAutoFilled() const { - if (!isHTMLInputElement(m_node.get())) + if (!is<HTMLInputElement>(m_node)) return false; - return toHTMLInputElement(m_node.get())->isAutofilled(); + return downcast<HTMLInputElement>(m_node.get()).isAutoFilled(); } -void InjectedBundleNodeHandle::setHTMLInputElementAutofilled(bool filled) +void InjectedBundleNodeHandle::setHTMLInputElementAutoFilled(bool filled) { - if (!isHTMLInputElement(m_node.get())) + if (!is<HTMLInputElement>(m_node)) return; - toHTMLInputElement(m_node.get())->setAutofilled(filled); + downcast<HTMLInputElement>(m_node.get()).setAutoFilled(filled); +} + +bool InjectedBundleNodeHandle::isHTMLInputElementAutoFillButtonEnabled() const +{ + if (!is<HTMLInputElement>(m_node)) + return false; + + return downcast<HTMLInputElement>(m_node.get()).autoFillButtonType() != AutoFillButtonType::None; +} + +void InjectedBundleNodeHandle::setHTMLInputElementAutoFillButtonEnabled(AutoFillButtonType autoFillButtonType) +{ + if (!is<HTMLInputElement>(m_node)) + return; + + downcast<HTMLInputElement>(m_node.get()).setShowAutoFillButton(autoFillButtonType); +} + +IntRect InjectedBundleNodeHandle::htmlInputElementAutoFillButtonBounds() +{ + if (!is<HTMLInputElement>(m_node)) + return IntRect(); + + auto autoFillButton = downcast<HTMLInputElement>(m_node.get()).autoFillButtonElement(); + if (!autoFillButton) + return IntRect(); + + return autoFillButton->boundsInRootViewSpace(); } bool InjectedBundleNodeHandle::htmlInputElementLastChangeWasUserEdit() { - if (!isHTMLInputElement(m_node.get())) + if (!is<HTMLInputElement>(m_node)) return false; - return toHTMLInputElement(m_node.get())->lastChangeWasUserEdit(); + return downcast<HTMLInputElement>(m_node.get()).lastChangeWasUserEdit(); } bool InjectedBundleNodeHandle::htmlTextAreaElementLastChangeWasUserEdit() { - if (!isHTMLTextAreaElement(m_node.get())) + if (!is<HTMLTextAreaElement>(m_node)) + return false; + + return downcast<HTMLTextAreaElement>(m_node.get()).lastChangeWasUserEdit(); +} + +bool InjectedBundleNodeHandle::isTextField() const +{ + if (!is<HTMLInputElement>(m_node)) return false; - return toHTMLTextAreaElement(m_node.get())->lastChangeWasUserEdit(); + return downcast<HTMLInputElement>(m_node.get()).isText(); } -PassRefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::htmlTableCellElementCellAbove() +RefPtr<InjectedBundleNodeHandle> InjectedBundleNodeHandle::htmlTableCellElementCellAbove() { - if (!m_node->hasTagName(tdTag)) - return 0; + if (!is<HTMLTableCellElement>(m_node)) + return nullptr; - return getOrCreate(static_cast<HTMLTableCellElement*>(m_node.get())->cellAbove()); + return getOrCreate(downcast<HTMLTableCellElement>(m_node.get()).cellAbove()); } -PassRefPtr<WebFrame> InjectedBundleNodeHandle::documentFrame() +RefPtr<WebFrame> InjectedBundleNodeHandle::documentFrame() { if (!m_node->isDocumentNode()) - return 0; + return nullptr; - Frame* frame = static_cast<Document*>(m_node.get())->frame(); + Frame* frame = downcast<Document>(m_node.get()).frame(); if (!frame) - return 0; + return nullptr; - WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader().client()); - return webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0; + return WebFrame::fromCoreFrame(*frame); } -PassRefPtr<WebFrame> InjectedBundleNodeHandle::htmlFrameElementContentFrame() +RefPtr<WebFrame> InjectedBundleNodeHandle::htmlFrameElementContentFrame() { - if (!m_node->hasTagName(frameTag)) - return 0; + if (!is<HTMLFrameElement>(m_node)) + return nullptr; - Frame* frame = static_cast<HTMLFrameElement*>(m_node.get())->contentFrame(); + Frame* frame = downcast<HTMLFrameElement>(m_node.get()).contentFrame(); if (!frame) - return 0; + return nullptr; - WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader().client()); - return webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0; + return WebFrame::fromCoreFrame(*frame); } -PassRefPtr<WebFrame> InjectedBundleNodeHandle::htmlIFrameElementContentFrame() +RefPtr<WebFrame> InjectedBundleNodeHandle::htmlIFrameElementContentFrame() { - if (!m_node->hasTagName(iframeTag)) - return 0; + if (!is<HTMLIFrameElement>(m_node)) + return nullptr; - Frame* frame = toHTMLIFrameElement(m_node.get())->contentFrame(); + Frame* frame = downcast<HTMLIFrameElement>(m_node.get()).contentFrame(); if (!frame) - return 0; + return nullptr; - WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader().client()); - return webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0; + return WebFrame::fromCoreFrame(*frame); } } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.h b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.h index 4cb3ec93c..6d4850094 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.h +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleNodeHandle.h @@ -23,63 +23,68 @@ * THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef InjectedBundleNodeHandle_h -#define InjectedBundleNodeHandle_h +#pragma once #include "APIObject.h" #include "ImageOptions.h" #include <JavaScriptCore/JSBase.h> #include <wtf/Forward.h> -#include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> namespace WebCore { - class IntRect; - class Node; +class IntRect; +class Node; +enum class AutoFillButtonType : uint8_t; } namespace WebKit { +class InjectedBundleRangeHandle; class InjectedBundleScriptWorld; class WebFrame; class WebImage; class InjectedBundleNodeHandle : public API::ObjectImpl<API::Object::Type::BundleNodeHandle> { public: - static PassRefPtr<InjectedBundleNodeHandle> getOrCreate(JSContextRef, JSObjectRef); - static PassRefPtr<InjectedBundleNodeHandle> getOrCreate(WebCore::Node*); + static RefPtr<InjectedBundleNodeHandle> getOrCreate(JSContextRef, JSObjectRef); + static RefPtr<InjectedBundleNodeHandle> getOrCreate(WebCore::Node*); + static Ref<InjectedBundleNodeHandle> getOrCreate(WebCore::Node&); virtual ~InjectedBundleNodeHandle(); - WebCore::Node* coreNode() const; + WebCore::Node* coreNode(); // Convenience DOM Operations - PassRefPtr<InjectedBundleNodeHandle> document(); + Ref<InjectedBundleNodeHandle> document(); // Additional DOM Operations // Note: These should only be operations that are not exposed to JavaScript. - WebCore::IntRect elementBounds() const; - WebCore::IntRect renderRect(bool*) const; - PassRefPtr<WebImage> renderedImage(SnapshotOptions); + WebCore::IntRect elementBounds(); + WebCore::IntRect renderRect(bool*); + RefPtr<WebImage> renderedImage(SnapshotOptions); + RefPtr<InjectedBundleRangeHandle> visibleRange(); void setHTMLInputElementValueForUser(const String&); - bool isHTMLInputElementAutofilled() const; - void setHTMLInputElementAutofilled(bool); + void setHTMLInputElementSpellcheckEnabled(bool); + bool isHTMLInputElementAutoFilled() const; + void setHTMLInputElementAutoFilled(bool); + bool isHTMLInputElementAutoFillButtonEnabled() const; + void setHTMLInputElementAutoFillButtonEnabled(WebCore::AutoFillButtonType); + WebCore::IntRect htmlInputElementAutoFillButtonBounds(); bool htmlInputElementLastChangeWasUserEdit(); bool htmlTextAreaElementLastChangeWasUserEdit(); + bool isTextField() const; - PassRefPtr<InjectedBundleNodeHandle> htmlTableCellElementCellAbove(); + RefPtr<InjectedBundleNodeHandle> htmlTableCellElementCellAbove(); - PassRefPtr<WebFrame> documentFrame(); - PassRefPtr<WebFrame> htmlFrameElementContentFrame(); - PassRefPtr<WebFrame> htmlIFrameElementContentFrame(); + RefPtr<WebFrame> documentFrame(); + RefPtr<WebFrame> htmlFrameElementContentFrame(); + RefPtr<WebFrame> htmlIFrameElementContentFrame(); private: - static PassRefPtr<InjectedBundleNodeHandle> create(WebCore::Node*); - InjectedBundleNodeHandle(WebCore::Node*); + static Ref<InjectedBundleNodeHandle> create(WebCore::Node&); + InjectedBundleNodeHandle(WebCore::Node&); - RefPtr<WebCore::Node> m_node; + Ref<WebCore::Node> m_node; }; } // namespace WebKit - -#endif // InjectedBundleNodeHandle_h diff --git a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.cpp b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.cpp index 9b947d103..1a34a9144 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.cpp +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2010 Apple Inc. All rights reserved. + * Copyright (C) 2010, 2015-2016 Apple Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,9 +26,22 @@ #include "config.h" #include "InjectedBundleRangeHandle.h" +#include "InjectedBundleNodeHandle.h" +#include "ShareableBitmap.h" +#include "WebImage.h" #include <JavaScriptCore/APICast.h> +#include <JavaScriptCore/HeapInlines.h> +#include <WebCore/Document.h> +#include <WebCore/FloatRect.h> +#include <WebCore/Frame.h> +#include <WebCore/FrameSelection.h> +#include <WebCore/FrameView.h> +#include <WebCore/GraphicsContext.h> +#include <WebCore/IntRect.h> #include <WebCore/JSRange.h> +#include <WebCore/Page.h> #include <WebCore/Range.h> +#include <WebCore/VisibleSelection.h> #include <wtf/HashMap.h> #include <wtf/NeverDestroyed.h> @@ -44,9 +57,9 @@ static DOMHandleCache& domHandleCache() return cache; } -PassRefPtr<InjectedBundleRangeHandle> InjectedBundleRangeHandle::getOrCreate(JSContextRef, JSObjectRef object) +PassRefPtr<InjectedBundleRangeHandle> InjectedBundleRangeHandle::getOrCreate(JSContextRef context, JSObjectRef object) { - Range* range = toRange(toJS(object)); + Range* range = JSRange::toWrapped(toJS(context)->vm(), toJS(object)); return getOrCreate(range); } @@ -59,14 +72,14 @@ PassRefPtr<InjectedBundleRangeHandle> InjectedBundleRangeHandle::getOrCreate(Ran if (!result.isNewEntry) return PassRefPtr<InjectedBundleRangeHandle>(result.iterator->value); - RefPtr<InjectedBundleRangeHandle> rangeHandle = InjectedBundleRangeHandle::create(range); - result.iterator->value = rangeHandle.get(); - return rangeHandle.release(); + auto rangeHandle = InjectedBundleRangeHandle::create(range); + result.iterator->value = rangeHandle.ptr(); + return WTFMove(rangeHandle); } -PassRefPtr<InjectedBundleRangeHandle> InjectedBundleRangeHandle::create(Range* range) +Ref<InjectedBundleRangeHandle> InjectedBundleRangeHandle::create(Range* range) { - return adoptRef(new InjectedBundleRangeHandle(range)); + return adoptRef(*new InjectedBundleRangeHandle(range)); } InjectedBundleRangeHandle::InjectedBundleRangeHandle(Range* range) @@ -84,4 +97,72 @@ Range* InjectedBundleRangeHandle::coreRange() const return m_range.get(); } +Ref<InjectedBundleNodeHandle> InjectedBundleRangeHandle::document() +{ + return InjectedBundleNodeHandle::getOrCreate(m_range->ownerDocument()); +} + +WebCore::IntRect InjectedBundleRangeHandle::boundingRectInWindowCoordinates() const +{ + FloatRect boundingRect = m_range->absoluteBoundingRect(); + Frame* frame = m_range->ownerDocument().frame(); + return frame->view()->contentsToWindow(enclosingIntRect(boundingRect)); +} + +PassRefPtr<WebImage> InjectedBundleRangeHandle::renderedImage(SnapshotOptions options) +{ + Document& ownerDocument = m_range->ownerDocument(); + Frame* frame = ownerDocument.frame(); + if (!frame) + return nullptr; + + FrameView* frameView = frame->view(); + if (!frameView) + return nullptr; + + Ref<Frame> protector(*frame); + + VisibleSelection oldSelection = frame->selection().selection(); + frame->selection().setSelection(VisibleSelection(*m_range)); + + float scaleFactor = (options & SnapshotOptionsExcludeDeviceScaleFactor) ? 1 : frame->page()->deviceScaleFactor(); + IntRect paintRect = enclosingIntRect(m_range->absoluteBoundingRect()); + IntSize backingStoreSize = paintRect.size(); + backingStoreSize.scale(scaleFactor); + + RefPtr<ShareableBitmap> backingStore = ShareableBitmap::createShareable(backingStoreSize, ShareableBitmap::SupportsAlpha); + if (!backingStore) + return nullptr; + + auto graphicsContext = backingStore->createGraphicsContext(); + graphicsContext->scale(scaleFactor); + + paintRect.move(frameView->frameRect().x(), frameView->frameRect().y()); + paintRect.moveBy(-frameView->scrollPosition()); + + graphicsContext->translate(-paintRect.x(), -paintRect.y()); + + PaintBehavior oldPaintBehavior = frameView->paintBehavior(); + PaintBehavior paintBehavior = oldPaintBehavior | PaintBehaviorSelectionOnly | PaintBehaviorFlattenCompositingLayers; + if (options & SnapshotOptionsForceBlackText) + paintBehavior |= PaintBehaviorForceBlackText; + if (options & SnapshotOptionsForceWhiteText) + paintBehavior |= PaintBehaviorForceWhiteText; + + frameView->setPaintBehavior(paintBehavior); + ownerDocument.updateLayout(); + + frameView->paint(*graphicsContext, paintRect); + frameView->setPaintBehavior(oldPaintBehavior); + + frame->selection().setSelection(oldSelection); + + return WebImage::create(backingStore.releaseNonNull()); +} + +String InjectedBundleRangeHandle::text() const +{ + return m_range->text(); +} + } // namespace WebKit diff --git a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.h b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.h index 7695b4366..647b1c244 100644 --- a/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.h +++ b/Source/WebKit2/WebProcess/InjectedBundle/DOM/InjectedBundleRangeHandle.h @@ -27,17 +27,22 @@ #define InjectedBundleRangeHandle_h #include "APIObject.h" +#include "ImageOptions.h" #include <JavaScriptCore/JSBase.h> +#include <wtf/Forward.h> #include <wtf/PassRefPtr.h> #include <wtf/RefPtr.h> namespace WebCore { - class Range; +class IntRect; +class Range; } namespace WebKit { +class InjectedBundleNodeHandle; class InjectedBundleScriptWorld; +class WebImage; class InjectedBundleRangeHandle : public API::ObjectImpl<API::Object::Type::BundleRangeHandle> { public: @@ -46,10 +51,16 @@ public: virtual ~InjectedBundleRangeHandle(); + Ref<InjectedBundleNodeHandle> document(); + + WebCore::IntRect boundingRectInWindowCoordinates() const; + PassRefPtr<WebImage> renderedImage(SnapshotOptions); + String text() const; + WebCore::Range* coreRange() const; private: - static PassRefPtr<InjectedBundleRangeHandle> create(WebCore::Range*); + static Ref<InjectedBundleRangeHandle> create(WebCore::Range*); InjectedBundleRangeHandle(WebCore::Range*); RefPtr<WebCore::Range> m_range; |