haikuwebkit/Source/WebCore/page/ImageOverlayController.h

104 lines
3.6 KiB
C
Raw Permalink Normal View History

Allow some image overlay content to render in fully transparent image elements https://bugs.webkit.org/show_bug.cgi?id=223781 <rdar://problem/75886351> Reviewed by Tim Horton. Source/WebCore: Introduce `ImageOverlayController`, and use it to render selections in image overlay content when the image overlay's host element is fully transparent. Test: fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Add plumbing to allow `ImageOverlayController` to uninstall its `PageOverlay` when the document is about to be detached. See `ImageOverlayController::` below. * editing/SelectionRectGatherer.cpp: (WebCore::SelectionRectGatherer::Notifier::~Notifier): Have `SelectionRectGatherer` notify the image overlay controller as well, when selection rects change. * page/ChromeClient.h: (WebCore::ChromeClient::needsImageOverlayControllerForSelectionPainting const): Add a new client hook that returns whether or not we should use `ImageOverlayController` to paint selections. If not (i.e. we're on iOS, where we use UIKit to draw selections in the UI process), then we'll never install page overlays, since `selectionRectsDidChange` is effectively a no-op. * page/ImageOverlayController.cpp: Added. (WebCore::ImageOverlayController::ImageOverlayController): (WebCore::ImageOverlayController::selectionRectsDidChange): When selection rects change, if the selection is inside an image overlay whose host is completely transparent (or very close to being completely transparent), then remember the selection rects along with the renderer's background color, and use this to render selection highlights separately, in a `PageOverlay`. (WebCore::ImageOverlayController::documentDetached): If the `Document` containing the current rendered overlay selection is detached, immediately uninstall the current `PageOverlay`. This ensures that the overlays don't persist through navigation. (WebCore::ImageOverlayController::installPageOverlayIfNeeded): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Helper methods to add or remove the `PageOverlay` from the current `Page`. (WebCore::ImageOverlayController::willMoveToPage): Uninstall the current page overlay if needed. (WebCore::ImageOverlayController::drawRect): Use the information stored in `ImageOverlayController::selectionRectsDidChange` to render custom selection rects. * page/ImageOverlayController.h: Added. * page/Page.cpp: * page/Page.h: Add an `ImageOverlayController` to the `Page`. (WebCore::Page::imageOverlayController): Source/WebKit: Implement a new chrome client hook. See WebCore ChangeLog for more information. * WebProcess/WebCoreSupport/WebChromeClient.h: LayoutTests: Adjust an existing layout test so that it actually checks what it was intended to check; add a new layout test to cover the changes in this bug. * fast/images/image-extraction/mac/select-word-in-draggable-image-overlay.html: Drive-by fix: remove some extraneous imported scripts from this layout test, and additionally simplify the test so that it doesn't rely on event sender to select text. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay-expected-mismatch.html: Added. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html: Added. Add a new layout test with a fully transparent image element that covers a div of the same size, with a background image that is identical to the image element's image. This emulates the behavior of certain websites that prompted this fallback image overlay rendering codepath in the first place. Canonical link: https://commits.webkit.org/235820@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-26 21:23:17 +00:00
/*
* Copyright (C) 2021 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.
*/
#pragma once
#include "Color.h"
Non-unified build fixes, late-ish May 2021 edition https://bugs.webkit.org/show_bug.cgi?id=225990 Unreviewed non-unified build fixes. Source/JavaScriptCore: * jit/CCallHelpers.cpp: Add missing LinkBuffer.h header. Source/WebCore: No new tests needed. * Modules/indexeddb/server/MemoryObjectStore.cpp: Add missing pal/SessioID.h header. * Modules/webaudio/OfflineAudioContext.cpp: Add missing OfflineAudioCompletionEvent.h header. * Modules/webaudio/OfflineAudioContext.h: Add missing wtf/UniqueRef.h header. * Modules/websockets/WebSocketDeflateFramer.h: Add missing WebSocketExtensionProcessor.h header, remove wtf/text/WTFString.h as it is already included by the former. * bindings/js/JSDOMConvertEnumeration.h: Add missing JSDOMGlobalObject.h header. * contentextensions/DFANode.cpp: Add missing wtf/HashMap.h header. * html/HTMLFrameElement.cpp: Add missing HTMLParserIdioms.h header. * html/HTMLHRElement.cpp: Ditto. * html/HTMLIFrameElement.cpp: Ditto. * html/HTMLLIElement.cpp: Ditto. * html/HTMLMetaElement.cpp: Add missing HTMLParserIdioms.h, Frame.h, and FrameView.h headers. * html/HTMLOutputElement.cpp: (WebCore::HTMLOutputElement::parseAttribute): Add missing HTMLNames:: namespace prefix in usage of HTMLNames::forAttr. (WebCore::HTMLOutputElement::htmlFor): Ditto. * html/OffscreenCanvas.cpp: Add missing RuntimeEnabledFeatures.h header. * layout/formattingContexts/FormattingGeometry.cpp: Add missing FormattingQuirks.h header. * layout/formattingContexts/FormattingQuirks.cpp: Add missing FormattingGeometry.h header. * layout/formattingContexts/block/BlockFormattingGeometry.cpp: Add missing BlockFormattingContext.h, BlockFormattingQuirks.h, and BlockMarginCollapse.h headers; remove unneeded BlockFormattingState.h and FormattingContext.h headers. * layout/formattingContexts/block/BlockFormattingGeometry.h: Add missing forward declaration for BlockFormattingContext. * layout/formattingContexts/block/BlockFormattingQuirks.cpp: Add missing BlockFormattingContext.h and BlockMarginCollapse.h headers, remove unneeded BlockFormattingState.h header. * layout/formattingContexts/block/PrecomputedBlockMarginCollapse.cpp: Add missing BlockFormattingContext.h and BlockFormattingQuirks.h headers, remove unneeded BlockFormattingState.h header. * layout/formattingContexts/block/tablewrapper/TableWrapperBlockFormattingContext.cpp: Add missing BlockMarginCollapse.h header. * layout/formattingContexts/block/tablewrapper/TableWrapperBlockFormattingQuirks.cpp: Add missing TableWrapperBlockFormattingContext.h header. * layout/formattingContexts/block/tablewrapper/TableWrapperBlockFormattingQuirks.h: Add missing forward declaration for TableWrapperBlockFormattingContext. * layout/formattingContexts/flex/FlexFormattingGeometry.cpp: Add missing FlexFormattingContext.h header, remove unneeded FlexFormattingState.h and FormattingContext.h headers. * layout/formattingContexts/flex/FlexFormattingGeometry.h: Add missing forward declaration for FlexFormattingContext. * layout/formattingContexts/inline/InlineFormattingGeometry.cpp: Add missing InlineFormattingContext.h header, remove unneeded InlineLineBox.h header. * layout/formattingContexts/inline/InlineFormattingGeometry.h: Add missing InlineLineBox.h and InlineLineBuilder.h headers, add missing forward declaration for InlineFormattingContext. * layout/formattingContexts/inline/InlineFormattingQuirks.cpp: Add missing InlineFormattingContext.h header. * layout/formattingContexts/inline/InlineFormattingQuirks.h: Add missing InlineLineBox.h header, add missing forward declaration for InlineFormattingContext. * layout/formattingContexts/inline/InlineLineBuilder.cpp: Add missing InlineFormattingQuirks.h header. * layout/formattingContexts/table/TableFormattingGeometry.cpp: Add missing TableFormattingContext.h header, remove unneeded TableFormattingState.h header. * layout/formattingContexts/table/TableFormattingGeometry.h: Add missing TableGrid.h header, add missing forward declaration for TableFormattingContext. * layout/formattingContexts/table/TableFormattingQuirks.cpp: Add missing TableFormattingContext.h header. * layout/formattingContexts/table/TableFormattingQuirks.h: Add missing forward declaration for TableFormattingContext. * layout/formattingContexts/table/TableLayout.cpp: Add missing TableFormattingGeometry.h header. * page/FrameViewLayoutContext.cpp: Add missing StyleScope.h header. * page/ImageOverlayController.h: Add missing LayoutRect.h header. * page/PageConfiguration.h: Add missing wtf/HashSet.h header. * platform/network/soup/SoupNetworkSession.cpp: Add missing wtf/text/StringHash.h header. * style/StyleScopeRuleSets.cpp: Add missing StyleScope.h header. * style/Styleable.cpp: Ditto. * svg/SVGDocumentExtensions.cpp: Add missing SVGUseElement.h header. * svg/SVGDocumentExtensions.h: Add missing wtf/WeakHashSet.h header, add missing forward declaration for SVGUseElement. * workers/WorkerGlobalScope.cpp: Add missing FontCustomPlatformData.h header. Source/WebKit: * NetworkProcess/PreconnectTask.h: Add missing forward declaration for NetworkSession. * NetworkProcess/WebStorage/LocalStorageDatabase.h: Add missing wtf/HashMap.h header, remove unneeded wtf/RefCounted.h header. * Shared/WebPageCreationParameters.cpp: (WebKit::WebPageCreationParameters::decode): Add missing WebCore:: namespace prefix to usage of WebCore::MediaProducer::MutedStateFlags. Canonical link: https://commits.webkit.org/238000@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277858 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-21 13:52:45 +00:00
#include "LayoutRect.h"
Allow some image overlay content to render in fully transparent image elements https://bugs.webkit.org/show_bug.cgi?id=223781 <rdar://problem/75886351> Reviewed by Tim Horton. Source/WebCore: Introduce `ImageOverlayController`, and use it to render selections in image overlay content when the image overlay's host element is fully transparent. Test: fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Add plumbing to allow `ImageOverlayController` to uninstall its `PageOverlay` when the document is about to be detached. See `ImageOverlayController::` below. * editing/SelectionRectGatherer.cpp: (WebCore::SelectionRectGatherer::Notifier::~Notifier): Have `SelectionRectGatherer` notify the image overlay controller as well, when selection rects change. * page/ChromeClient.h: (WebCore::ChromeClient::needsImageOverlayControllerForSelectionPainting const): Add a new client hook that returns whether or not we should use `ImageOverlayController` to paint selections. If not (i.e. we're on iOS, where we use UIKit to draw selections in the UI process), then we'll never install page overlays, since `selectionRectsDidChange` is effectively a no-op. * page/ImageOverlayController.cpp: Added. (WebCore::ImageOverlayController::ImageOverlayController): (WebCore::ImageOverlayController::selectionRectsDidChange): When selection rects change, if the selection is inside an image overlay whose host is completely transparent (or very close to being completely transparent), then remember the selection rects along with the renderer's background color, and use this to render selection highlights separately, in a `PageOverlay`. (WebCore::ImageOverlayController::documentDetached): If the `Document` containing the current rendered overlay selection is detached, immediately uninstall the current `PageOverlay`. This ensures that the overlays don't persist through navigation. (WebCore::ImageOverlayController::installPageOverlayIfNeeded): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Helper methods to add or remove the `PageOverlay` from the current `Page`. (WebCore::ImageOverlayController::willMoveToPage): Uninstall the current page overlay if needed. (WebCore::ImageOverlayController::drawRect): Use the information stored in `ImageOverlayController::selectionRectsDidChange` to render custom selection rects. * page/ImageOverlayController.h: Added. * page/Page.cpp: * page/Page.h: Add an `ImageOverlayController` to the `Page`. (WebCore::Page::imageOverlayController): Source/WebKit: Implement a new chrome client hook. See WebCore ChangeLog for more information. * WebProcess/WebCoreSupport/WebChromeClient.h: LayoutTests: Adjust an existing layout test so that it actually checks what it was intended to check; add a new layout test to cover the changes in this bug. * fast/images/image-extraction/mac/select-word-in-draggable-image-overlay.html: Drive-by fix: remove some extraneous imported scripts from this layout test, and additionally simplify the test so that it doesn't rely on event sender to select text. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay-expected-mismatch.html: Added. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html: Added. Add a new layout test with a fully transparent image element that covers a div of the same size, with a background image that is identical to the image element's image. This emulates the behavior of certain websites that prompted this fallback image overlay rendering codepath in the first place. Canonical link: https://commits.webkit.org/235820@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-26 21:23:17 +00:00
#include "PageOverlay.h"
#include <wtf/Vector.h>
#include <wtf/WeakPtr.h>
[macOS] Support painting data detector highlights inside image overlays https://bugs.webkit.org/show_bug.cgi?id=226227 Reviewed by Tim Horton. Add support for painting data detector highlights inside image overlays by leveraging `DataDetectorHighlight`. See comments below for more details. * SourcesCocoa.txt: * WebCore.xcodeproj/project.pbxproj: * editing/Editor.cpp: (WebCore::scanForTelephoneNumbers): Avoid painting service-controls-based telephone number highlights for selected text inside image overlays, in order to avoid painting a redundant data detector highlight for telephone numbers in image overlays. * html/HTMLElement.cpp: (WebCore::imageOverlayDataDetectorClassName): (WebCore::HTMLElement::isImageOverlayDataDetectorResult const): (WebCore::HTMLElement::updateWithImageExtractionResult): * html/HTMLElement.h: * html/shadow/imageOverlay.css: (div.image-overlay-data-detector-result): Add support for injecting elements in the DOM that represent data detection results; these are transformed and overlaid on the image in the same way as existing text containers. Note that we lay out these elements on top of text, but make them invisible to hit-testing unless the `IgnoreCSSPointerEventsProperty` option is specified. We'll take advantage of this behavior in a future patch. * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): (WebCore::ImageOverlayController::drawRect): (WebCore::ImageOverlayController::platformHandleMouseEvent): * page/ImageOverlayController.h: Refactor the image overlay controller, such that we install the page overlay if there is any selection inside the image overlay (as opposed to only when we need to use this overlay to paint the text selection for transparent images). If data detectors are present, we'll additionally set up out `DataDetectorHighlight`s (one for each data detection result container). * page/mac/ImageOverlayControllerMac.mm: Added. (WebCore::ImageOverlayController::updateDataDetectorHighlights): Traverse the image overlay's subtree in search of container elements that correspond to data detection results; for each of these elements, we create a new `DataDetectorHighlight` using the element's bounds, and save the pair in `m_dataDetectorContainersAndHighlights`. Note that we hold a weak pointer to the container element, such that there's no risk of leaking any of these data detection result containers (or their documents). (WebCore::ImageOverlayController::platformHandleMouseEvent): (WebCore::ImageOverlayController::handleDataDetectorAction): Add a FIXME referencing the next patch in the sequence. (WebCore::ImageOverlayController::clearDataDetectorHighlights): * platform/mac/DataDetectorHighlight.h: * platform/mac/DataDetectorHighlight.mm: (WebCore::DataDetectorHighlight::createForImageOverlay): Add a helper method to create a `DataDetectorHighlight` for image overlays. Canonical link: https://commits.webkit.org/238171@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278121 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-26 20:06:32 +00:00
#if PLATFORM(MAC)
#include "DataDetectorHighlight.h"
#endif
Allow some image overlay content to render in fully transparent image elements https://bugs.webkit.org/show_bug.cgi?id=223781 <rdar://problem/75886351> Reviewed by Tim Horton. Source/WebCore: Introduce `ImageOverlayController`, and use it to render selections in image overlay content when the image overlay's host element is fully transparent. Test: fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Add plumbing to allow `ImageOverlayController` to uninstall its `PageOverlay` when the document is about to be detached. See `ImageOverlayController::` below. * editing/SelectionRectGatherer.cpp: (WebCore::SelectionRectGatherer::Notifier::~Notifier): Have `SelectionRectGatherer` notify the image overlay controller as well, when selection rects change. * page/ChromeClient.h: (WebCore::ChromeClient::needsImageOverlayControllerForSelectionPainting const): Add a new client hook that returns whether or not we should use `ImageOverlayController` to paint selections. If not (i.e. we're on iOS, where we use UIKit to draw selections in the UI process), then we'll never install page overlays, since `selectionRectsDidChange` is effectively a no-op. * page/ImageOverlayController.cpp: Added. (WebCore::ImageOverlayController::ImageOverlayController): (WebCore::ImageOverlayController::selectionRectsDidChange): When selection rects change, if the selection is inside an image overlay whose host is completely transparent (or very close to being completely transparent), then remember the selection rects along with the renderer's background color, and use this to render selection highlights separately, in a `PageOverlay`. (WebCore::ImageOverlayController::documentDetached): If the `Document` containing the current rendered overlay selection is detached, immediately uninstall the current `PageOverlay`. This ensures that the overlays don't persist through navigation. (WebCore::ImageOverlayController::installPageOverlayIfNeeded): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Helper methods to add or remove the `PageOverlay` from the current `Page`. (WebCore::ImageOverlayController::willMoveToPage): Uninstall the current page overlay if needed. (WebCore::ImageOverlayController::drawRect): Use the information stored in `ImageOverlayController::selectionRectsDidChange` to render custom selection rects. * page/ImageOverlayController.h: Added. * page/Page.cpp: * page/Page.h: Add an `ImageOverlayController` to the `Page`. (WebCore::Page::imageOverlayController): Source/WebKit: Implement a new chrome client hook. See WebCore ChangeLog for more information. * WebProcess/WebCoreSupport/WebChromeClient.h: LayoutTests: Adjust an existing layout test so that it actually checks what it was intended to check; add a new layout test to cover the changes in this bug. * fast/images/image-extraction/mac/select-word-in-draggable-image-overlay.html: Drive-by fix: remove some extraneous imported scripts from this layout test, and additionally simplify the test so that it doesn't rely on event sender to select text. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay-expected-mismatch.html: Added. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html: Added. Add a new layout test with a fully transparent image element that covers a div of the same size, with a background image that is identical to the image element's image. This emulates the behavior of certain websites that prompted this fallback image overlay rendering codepath in the first place. Canonical link: https://commits.webkit.org/235820@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-26 21:23:17 +00:00
namespace WebCore {
class Document;
[macOS] Data detector highlights should appear when hovering inside image overlays https://bugs.webkit.org/show_bug.cgi?id=226507 Reviewed by Tim Horton. Refactor some logic in ImageOverlayController, such that the overlay is installed if _either_ selection painting is required, or data detector highlights for the image overlay host element exist; additionally, add plumbing to allow the ImageOverlayController to install a page overlay when the element under the mouse is inside an image overlay. * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Drive-by fix: use `imageOverlayControllerIfExists` instead of `imageOverlayController` to avoid unnecessarily creating a new ImageOverlayController when detaching a Document. * page/EventHandler.cpp: (WebCore::EventHandler::clear): Refactor logic for clearing out `m_elementUnderMouse` into a separate helper, and call it from these two places. This new helper clears out `m_elementUnderMouse` and additionally notifies the page's image overlay controller (only if it has already been constructed). (WebCore::EventHandler::updateMouseEventTargetNode): Call out to the page's image overlay controller when changing `m_elementUnderMouse`. (WebCore::EventHandler::clearElementUnderMouse): * page/EventHandler.h: * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): Refactor ImageOverlayController so that it only installs its page overlay if either: 1. Selection painting is needed for selected text inside an image overlay, or... 2. The cursor is over an image overlay host element with data detection results. To achieve this, we maintain a weak pointer to the image overlay host that contains the selection separately from the weak pointer to the image overlay host that contains data detectors, and is the element currently under the mouse cursor. Drive-by fix: also ignore selection updates due to temporary selections triggered as a result of gathering dictionary popup info. (WebCore::ImageOverlayController::documentDetached): (WebCore::ImageOverlayController::uninstallPageOverlay): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Split this into two functions: `uninstallPageOverlayIfNeeded`, which removes and destroys the PageOverlay if it is no longer needed (i.e. the overlay is required for neither selection painting nor data detectors). (WebCore::ImageOverlayController::willMoveToPage): (WebCore::ImageOverlayController::drawRect): (WebCore::ImageOverlayController::elementUnderMouseDidChange): * page/ImageOverlayController.h: Rename `m_imageOverlayBounds` to `m_selectionClipRect` to make it clear that this is only used during selection painting, and rename `m_overlaySelectionQuads` to just `m_selectionQuads` for conciseness. * page/Page.h: (WebCore::Page::imageOverlayControllerIfExists): Add a version of this getter that does not initialize the ImageOverlayController if it didn't already exist. See call sites in EventHandler and Document. * page/mac/ImageOverlayControllerMac.mm: (WebCore::ImageOverlayController::clearDataDetectorHighlights): Additionally clear out `m_hostElementForDataDetectors`. (WebCore::ImageOverlayController::elementUnderMouseDidChange): Update data detector highlights whenever the element under the mouse is over content inside an image overlay. Note that we effectively ignore this method call in the case where we're clearing out `m_elementUnderMouse` for a different Document than the one containing `m_hostElementForDataDetectors`, which prevents us from erroneously hiding data detectors when `m_elementUnderMouse` is removed or otherwise cleared out in a different Document. Canonical link: https://commits.webkit.org/238364@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278331 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-06-01 22:36:56 +00:00
class Element;
Allow some image overlay content to render in fully transparent image elements https://bugs.webkit.org/show_bug.cgi?id=223781 <rdar://problem/75886351> Reviewed by Tim Horton. Source/WebCore: Introduce `ImageOverlayController`, and use it to render selections in image overlay content when the image overlay's host element is fully transparent. Test: fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Add plumbing to allow `ImageOverlayController` to uninstall its `PageOverlay` when the document is about to be detached. See `ImageOverlayController::` below. * editing/SelectionRectGatherer.cpp: (WebCore::SelectionRectGatherer::Notifier::~Notifier): Have `SelectionRectGatherer` notify the image overlay controller as well, when selection rects change. * page/ChromeClient.h: (WebCore::ChromeClient::needsImageOverlayControllerForSelectionPainting const): Add a new client hook that returns whether or not we should use `ImageOverlayController` to paint selections. If not (i.e. we're on iOS, where we use UIKit to draw selections in the UI process), then we'll never install page overlays, since `selectionRectsDidChange` is effectively a no-op. * page/ImageOverlayController.cpp: Added. (WebCore::ImageOverlayController::ImageOverlayController): (WebCore::ImageOverlayController::selectionRectsDidChange): When selection rects change, if the selection is inside an image overlay whose host is completely transparent (or very close to being completely transparent), then remember the selection rects along with the renderer's background color, and use this to render selection highlights separately, in a `PageOverlay`. (WebCore::ImageOverlayController::documentDetached): If the `Document` containing the current rendered overlay selection is detached, immediately uninstall the current `PageOverlay`. This ensures that the overlays don't persist through navigation. (WebCore::ImageOverlayController::installPageOverlayIfNeeded): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Helper methods to add or remove the `PageOverlay` from the current `Page`. (WebCore::ImageOverlayController::willMoveToPage): Uninstall the current page overlay if needed. (WebCore::ImageOverlayController::drawRect): Use the information stored in `ImageOverlayController::selectionRectsDidChange` to render custom selection rects. * page/ImageOverlayController.h: Added. * page/Page.cpp: * page/Page.h: Add an `ImageOverlayController` to the `Page`. (WebCore::Page::imageOverlayController): Source/WebKit: Implement a new chrome client hook. See WebCore ChangeLog for more information. * WebProcess/WebCoreSupport/WebChromeClient.h: LayoutTests: Adjust an existing layout test so that it actually checks what it was intended to check; add a new layout test to cover the changes in this bug. * fast/images/image-extraction/mac/select-word-in-draggable-image-overlay.html: Drive-by fix: remove some extraneous imported scripts from this layout test, and additionally simplify the test so that it doesn't rely on event sender to select text. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay-expected-mismatch.html: Added. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html: Added. Add a new layout test with a fully transparent image element that covers a div of the same size, with a background image that is identical to the image element's image. This emulates the behavior of certain websites that prompted this fallback image overlay rendering codepath in the first place. Canonical link: https://commits.webkit.org/235820@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-26 21:23:17 +00:00
class Frame;
class GraphicsContext;
[macOS] Support painting data detector highlights inside image overlays https://bugs.webkit.org/show_bug.cgi?id=226227 Reviewed by Tim Horton. Add support for painting data detector highlights inside image overlays by leveraging `DataDetectorHighlight`. See comments below for more details. * SourcesCocoa.txt: * WebCore.xcodeproj/project.pbxproj: * editing/Editor.cpp: (WebCore::scanForTelephoneNumbers): Avoid painting service-controls-based telephone number highlights for selected text inside image overlays, in order to avoid painting a redundant data detector highlight for telephone numbers in image overlays. * html/HTMLElement.cpp: (WebCore::imageOverlayDataDetectorClassName): (WebCore::HTMLElement::isImageOverlayDataDetectorResult const): (WebCore::HTMLElement::updateWithImageExtractionResult): * html/HTMLElement.h: * html/shadow/imageOverlay.css: (div.image-overlay-data-detector-result): Add support for injecting elements in the DOM that represent data detection results; these are transformed and overlaid on the image in the same way as existing text containers. Note that we lay out these elements on top of text, but make them invisible to hit-testing unless the `IgnoreCSSPointerEventsProperty` option is specified. We'll take advantage of this behavior in a future patch. * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): (WebCore::ImageOverlayController::drawRect): (WebCore::ImageOverlayController::platformHandleMouseEvent): * page/ImageOverlayController.h: Refactor the image overlay controller, such that we install the page overlay if there is any selection inside the image overlay (as opposed to only when we need to use this overlay to paint the text selection for transparent images). If data detectors are present, we'll additionally set up out `DataDetectorHighlight`s (one for each data detection result container). * page/mac/ImageOverlayControllerMac.mm: Added. (WebCore::ImageOverlayController::updateDataDetectorHighlights): Traverse the image overlay's subtree in search of container elements that correspond to data detection results; for each of these elements, we create a new `DataDetectorHighlight` using the element's bounds, and save the pair in `m_dataDetectorContainersAndHighlights`. Note that we hold a weak pointer to the container element, such that there's no risk of leaking any of these data detection result containers (or their documents). (WebCore::ImageOverlayController::platformHandleMouseEvent): (WebCore::ImageOverlayController::handleDataDetectorAction): Add a FIXME referencing the next patch in the sequence. (WebCore::ImageOverlayController::clearDataDetectorHighlights): * platform/mac/DataDetectorHighlight.h: * platform/mac/DataDetectorHighlight.mm: (WebCore::DataDetectorHighlight::createForImageOverlay): Add a helper method to create a `DataDetectorHighlight` for image overlays. Canonical link: https://commits.webkit.org/238171@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278121 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-26 20:06:32 +00:00
class HTMLElement;
Allow some image overlay content to render in fully transparent image elements https://bugs.webkit.org/show_bug.cgi?id=223781 <rdar://problem/75886351> Reviewed by Tim Horton. Source/WebCore: Introduce `ImageOverlayController`, and use it to render selections in image overlay content when the image overlay's host element is fully transparent. Test: fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Add plumbing to allow `ImageOverlayController` to uninstall its `PageOverlay` when the document is about to be detached. See `ImageOverlayController::` below. * editing/SelectionRectGatherer.cpp: (WebCore::SelectionRectGatherer::Notifier::~Notifier): Have `SelectionRectGatherer` notify the image overlay controller as well, when selection rects change. * page/ChromeClient.h: (WebCore::ChromeClient::needsImageOverlayControllerForSelectionPainting const): Add a new client hook that returns whether or not we should use `ImageOverlayController` to paint selections. If not (i.e. we're on iOS, where we use UIKit to draw selections in the UI process), then we'll never install page overlays, since `selectionRectsDidChange` is effectively a no-op. * page/ImageOverlayController.cpp: Added. (WebCore::ImageOverlayController::ImageOverlayController): (WebCore::ImageOverlayController::selectionRectsDidChange): When selection rects change, if the selection is inside an image overlay whose host is completely transparent (or very close to being completely transparent), then remember the selection rects along with the renderer's background color, and use this to render selection highlights separately, in a `PageOverlay`. (WebCore::ImageOverlayController::documentDetached): If the `Document` containing the current rendered overlay selection is detached, immediately uninstall the current `PageOverlay`. This ensures that the overlays don't persist through navigation. (WebCore::ImageOverlayController::installPageOverlayIfNeeded): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Helper methods to add or remove the `PageOverlay` from the current `Page`. (WebCore::ImageOverlayController::willMoveToPage): Uninstall the current page overlay if needed. (WebCore::ImageOverlayController::drawRect): Use the information stored in `ImageOverlayController::selectionRectsDidChange` to render custom selection rects. * page/ImageOverlayController.h: Added. * page/Page.cpp: * page/Page.h: Add an `ImageOverlayController` to the `Page`. (WebCore::Page::imageOverlayController): Source/WebKit: Implement a new chrome client hook. See WebCore ChangeLog for more information. * WebProcess/WebCoreSupport/WebChromeClient.h: LayoutTests: Adjust an existing layout test so that it actually checks what it was intended to check; add a new layout test to cover the changes in this bug. * fast/images/image-extraction/mac/select-word-in-draggable-image-overlay.html: Drive-by fix: remove some extraneous imported scripts from this layout test, and additionally simplify the test so that it doesn't rely on event sender to select text. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay-expected-mismatch.html: Added. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html: Added. Add a new layout test with a fully transparent image element that covers a div of the same size, with a background image that is identical to the image element's image. This emulates the behavior of certain websites that prompted this fallback image overlay rendering codepath in the first place. Canonical link: https://commits.webkit.org/235820@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-26 21:23:17 +00:00
class IntRect;
[macOS] ImageOverlayController should paint selection quads instead of bounding rects https://bugs.webkit.org/show_bug.cgi?id=225585 <rdar://problem/77725745> Reviewed by Tim Horton. Source/WebCore: Teach `SelectionRectGatherer` (now renamed to `SelectionGeometryGatherer`) to emit quads, rather than bounding rects around each quad. We use these quads in `ImageOverlayController` to render selection quads via page overlay (i.e., in the case where the image containing the overlay is transparent). Test: fast/images/image-extraction/mac/select-rotated-transparent-image-overlay.html * Headers.cmake: * SourcesCocoa.txt: * WebCore.xcodeproj/project.pbxproj: * editing/SelectionGeometryGatherer.cpp: Renamed from Source/WebCore/editing/SelectionRectGatherer.cpp. Rename `SelectionRectGatherer` to `SelectionGeometryGatherer`, to reflect the fact that this helper class now aggregates both selection quads and gap rects. (WebCore::SelectionGeometryGatherer::SelectionGeometryGatherer): (WebCore::SelectionGeometryGatherer::addQuad): Rename `addRect` to `addQuad`, and make it take a `FloatQuad` instead. (WebCore::SelectionGeometryGatherer::addGapRects): (WebCore::SelectionGeometryGatherer::Notifier::Notifier): (WebCore::SelectionGeometryGatherer::Notifier::~Notifier): (WebCore::SelectionGeometryGatherer::boundingRects const): (WebCore::SelectionGeometryGatherer::clearAndCreateNotifier): * editing/SelectionGeometryGatherer.h: Renamed from Source/WebCore/editing/SelectionRectGatherer.h. (WebCore::SelectionGeometryGatherer::setTextOnly): (WebCore::SelectionGeometryGatherer::isTextOnly const): * html/HTMLElement.cpp: (WebCore::HTMLElement::updateWithImageExtractionResult): Minor tweak - don't add any margin around the word when the line only contains a single word. * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): Rename `selectionRectsDidChange` to `selectionQuadsDidChange`, and take a `FloatQuad` in absolute coordinates instead of a `LayoutRect`. Store these quads in `m_overlaySelectionQuads` (also renamed from `m_overlaySelectionRects`). (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): (WebCore::ImageOverlayController::drawRect): Make a few changes when painting selections using the `ImageOverlayController`: 1. Instead of painting with `fillRect()`, coalesce all of the collected selection quads into a single `Path` object, and pass that `Path` into `fillPath()`. This allows us to render each piece of selected content as a quad instead of a bounding rect, and additionally prevents us from rendering overlapping selections when using `ImageOverlayController`. 2. Clip selections to the absolute bounds of the image overlay host element's renderer, which prevents the new selection quads from spilling out of the host element. (WebCore::ImageOverlayController::selectionRectsDidChange): Deleted. * page/ImageOverlayController.h: * rendering/RenderSelectionInfo.cpp: (WebCore::RenderSelectionInfo::RenderSelectionInfo): * rendering/RenderSelectionInfo.h: (WebCore::RenderSelectionInfo::collectedSelectionQuads const): (WebCore::RenderSelectionInfo::collectedSelectionRects const): Deleted. More minor refactoring: rename `collectedSelectionRects` to `collectedSelectionQuads`, and make it take the original `FloatQuad` instead of the quad's bounding box. * rendering/RenderText.cpp: (WebCore::RenderText::collectSelectionGeometriesForLineBoxes): * rendering/RenderText.h: * rendering/SelectionRangeData.cpp: (WebCore::SelectionRangeData::SelectionRangeData): (WebCore::SelectionRangeData::set): (WebCore::SelectionRangeData::apply): * rendering/SelectionRangeData.h: LayoutTests: Add a new layout test to cover the change. Currently, the below test case renders a visible selection rect in the image overlay since we render the bounding rect of the overlay text quad, which intersects with the image overlay's bounds. However, the text quad is positioned outside of the image overlay, so there shouldn't be any visible selection rect. As such, this test is expected to render the same content as a plain image (even without an image overlay). Unfortunately, I couldn't write a matching ref-test for the case where the selection rect is inside the bounds of the image overlay, since doing so led to tiny subpixel differences between the transparent image case (using `ImageOverlayController`) and the regular image overlay selection case. * fast/images/image-extraction/mac/select-rotated-transparent-image-overlay-expected.html: Added. * fast/images/image-extraction/mac/select-rotated-transparent-image-overlay.html: Added. Canonical link: https://commits.webkit.org/237541@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277274 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-10 18:10:03 +00:00
class FloatQuad;
Allow some image overlay content to render in fully transparent image elements https://bugs.webkit.org/show_bug.cgi?id=223781 <rdar://problem/75886351> Reviewed by Tim Horton. Source/WebCore: Introduce `ImageOverlayController`, and use it to render selections in image overlay content when the image overlay's host element is fully transparent. Test: fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Add plumbing to allow `ImageOverlayController` to uninstall its `PageOverlay` when the document is about to be detached. See `ImageOverlayController::` below. * editing/SelectionRectGatherer.cpp: (WebCore::SelectionRectGatherer::Notifier::~Notifier): Have `SelectionRectGatherer` notify the image overlay controller as well, when selection rects change. * page/ChromeClient.h: (WebCore::ChromeClient::needsImageOverlayControllerForSelectionPainting const): Add a new client hook that returns whether or not we should use `ImageOverlayController` to paint selections. If not (i.e. we're on iOS, where we use UIKit to draw selections in the UI process), then we'll never install page overlays, since `selectionRectsDidChange` is effectively a no-op. * page/ImageOverlayController.cpp: Added. (WebCore::ImageOverlayController::ImageOverlayController): (WebCore::ImageOverlayController::selectionRectsDidChange): When selection rects change, if the selection is inside an image overlay whose host is completely transparent (or very close to being completely transparent), then remember the selection rects along with the renderer's background color, and use this to render selection highlights separately, in a `PageOverlay`. (WebCore::ImageOverlayController::documentDetached): If the `Document` containing the current rendered overlay selection is detached, immediately uninstall the current `PageOverlay`. This ensures that the overlays don't persist through navigation. (WebCore::ImageOverlayController::installPageOverlayIfNeeded): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Helper methods to add or remove the `PageOverlay` from the current `Page`. (WebCore::ImageOverlayController::willMoveToPage): Uninstall the current page overlay if needed. (WebCore::ImageOverlayController::drawRect): Use the information stored in `ImageOverlayController::selectionRectsDidChange` to render custom selection rects. * page/ImageOverlayController.h: Added. * page/Page.cpp: * page/Page.h: Add an `ImageOverlayController` to the `Page`. (WebCore::Page::imageOverlayController): Source/WebKit: Implement a new chrome client hook. See WebCore ChangeLog for more information. * WebProcess/WebCoreSupport/WebChromeClient.h: LayoutTests: Adjust an existing layout test so that it actually checks what it was intended to check; add a new layout test to cover the changes in this bug. * fast/images/image-extraction/mac/select-word-in-draggable-image-overlay.html: Drive-by fix: remove some extraneous imported scripts from this layout test, and additionally simplify the test so that it doesn't rely on event sender to select text. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay-expected-mismatch.html: Added. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html: Added. Add a new layout test with a fully transparent image element that covers a div of the same size, with a background image that is identical to the image element's image. This emulates the behavior of certain websites that prompted this fallback image overlay rendering codepath in the first place. Canonical link: https://commits.webkit.org/235820@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-26 21:23:17 +00:00
class Page;
class RenderElement;
struct GapRects;
[macOS] Support painting data detector highlights inside image overlays https://bugs.webkit.org/show_bug.cgi?id=226227 Reviewed by Tim Horton. Add support for painting data detector highlights inside image overlays by leveraging `DataDetectorHighlight`. See comments below for more details. * SourcesCocoa.txt: * WebCore.xcodeproj/project.pbxproj: * editing/Editor.cpp: (WebCore::scanForTelephoneNumbers): Avoid painting service-controls-based telephone number highlights for selected text inside image overlays, in order to avoid painting a redundant data detector highlight for telephone numbers in image overlays. * html/HTMLElement.cpp: (WebCore::imageOverlayDataDetectorClassName): (WebCore::HTMLElement::isImageOverlayDataDetectorResult const): (WebCore::HTMLElement::updateWithImageExtractionResult): * html/HTMLElement.h: * html/shadow/imageOverlay.css: (div.image-overlay-data-detector-result): Add support for injecting elements in the DOM that represent data detection results; these are transformed and overlaid on the image in the same way as existing text containers. Note that we lay out these elements on top of text, but make them invisible to hit-testing unless the `IgnoreCSSPointerEventsProperty` option is specified. We'll take advantage of this behavior in a future patch. * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): (WebCore::ImageOverlayController::drawRect): (WebCore::ImageOverlayController::platformHandleMouseEvent): * page/ImageOverlayController.h: Refactor the image overlay controller, such that we install the page overlay if there is any selection inside the image overlay (as opposed to only when we need to use this overlay to paint the text selection for transparent images). If data detectors are present, we'll additionally set up out `DataDetectorHighlight`s (one for each data detection result container). * page/mac/ImageOverlayControllerMac.mm: Added. (WebCore::ImageOverlayController::updateDataDetectorHighlights): Traverse the image overlay's subtree in search of container elements that correspond to data detection results; for each of these elements, we create a new `DataDetectorHighlight` using the element's bounds, and save the pair in `m_dataDetectorContainersAndHighlights`. Note that we hold a weak pointer to the container element, such that there's no risk of leaking any of these data detection result containers (or their documents). (WebCore::ImageOverlayController::platformHandleMouseEvent): (WebCore::ImageOverlayController::handleDataDetectorAction): Add a FIXME referencing the next patch in the sequence. (WebCore::ImageOverlayController::clearDataDetectorHighlights): * platform/mac/DataDetectorHighlight.h: * platform/mac/DataDetectorHighlight.mm: (WebCore::DataDetectorHighlight::createForImageOverlay): Add a helper method to create a `DataDetectorHighlight` for image overlays. Canonical link: https://commits.webkit.org/238171@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278121 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-26 20:06:32 +00:00
class ImageOverlayController final : private PageOverlay::Client
#if PLATFORM(MAC)
, DataDetectorHighlightClient
#endif
{
Allow some image overlay content to render in fully transparent image elements https://bugs.webkit.org/show_bug.cgi?id=223781 <rdar://problem/75886351> Reviewed by Tim Horton. Source/WebCore: Introduce `ImageOverlayController`, and use it to render selections in image overlay content when the image overlay's host element is fully transparent. Test: fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Add plumbing to allow `ImageOverlayController` to uninstall its `PageOverlay` when the document is about to be detached. See `ImageOverlayController::` below. * editing/SelectionRectGatherer.cpp: (WebCore::SelectionRectGatherer::Notifier::~Notifier): Have `SelectionRectGatherer` notify the image overlay controller as well, when selection rects change. * page/ChromeClient.h: (WebCore::ChromeClient::needsImageOverlayControllerForSelectionPainting const): Add a new client hook that returns whether or not we should use `ImageOverlayController` to paint selections. If not (i.e. we're on iOS, where we use UIKit to draw selections in the UI process), then we'll never install page overlays, since `selectionRectsDidChange` is effectively a no-op. * page/ImageOverlayController.cpp: Added. (WebCore::ImageOverlayController::ImageOverlayController): (WebCore::ImageOverlayController::selectionRectsDidChange): When selection rects change, if the selection is inside an image overlay whose host is completely transparent (or very close to being completely transparent), then remember the selection rects along with the renderer's background color, and use this to render selection highlights separately, in a `PageOverlay`. (WebCore::ImageOverlayController::documentDetached): If the `Document` containing the current rendered overlay selection is detached, immediately uninstall the current `PageOverlay`. This ensures that the overlays don't persist through navigation. (WebCore::ImageOverlayController::installPageOverlayIfNeeded): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Helper methods to add or remove the `PageOverlay` from the current `Page`. (WebCore::ImageOverlayController::willMoveToPage): Uninstall the current page overlay if needed. (WebCore::ImageOverlayController::drawRect): Use the information stored in `ImageOverlayController::selectionRectsDidChange` to render custom selection rects. * page/ImageOverlayController.h: Added. * page/Page.cpp: * page/Page.h: Add an `ImageOverlayController` to the `Page`. (WebCore::Page::imageOverlayController): Source/WebKit: Implement a new chrome client hook. See WebCore ChangeLog for more information. * WebProcess/WebCoreSupport/WebChromeClient.h: LayoutTests: Adjust an existing layout test so that it actually checks what it was intended to check; add a new layout test to cover the changes in this bug. * fast/images/image-extraction/mac/select-word-in-draggable-image-overlay.html: Drive-by fix: remove some extraneous imported scripts from this layout test, and additionally simplify the test so that it doesn't rely on event sender to select text. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay-expected-mismatch.html: Added. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html: Added. Add a new layout test with a fully transparent image element that covers a div of the same size, with a background image that is identical to the image element's image. This emulates the behavior of certain websites that prompted this fallback image overlay rendering codepath in the first place. Canonical link: https://commits.webkit.org/235820@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-26 21:23:17 +00:00
WTF_MAKE_FAST_ALLOCATED;
public:
explicit ImageOverlayController(Page&);
[macOS] ImageOverlayController should paint selection quads instead of bounding rects https://bugs.webkit.org/show_bug.cgi?id=225585 <rdar://problem/77725745> Reviewed by Tim Horton. Source/WebCore: Teach `SelectionRectGatherer` (now renamed to `SelectionGeometryGatherer`) to emit quads, rather than bounding rects around each quad. We use these quads in `ImageOverlayController` to render selection quads via page overlay (i.e., in the case where the image containing the overlay is transparent). Test: fast/images/image-extraction/mac/select-rotated-transparent-image-overlay.html * Headers.cmake: * SourcesCocoa.txt: * WebCore.xcodeproj/project.pbxproj: * editing/SelectionGeometryGatherer.cpp: Renamed from Source/WebCore/editing/SelectionRectGatherer.cpp. Rename `SelectionRectGatherer` to `SelectionGeometryGatherer`, to reflect the fact that this helper class now aggregates both selection quads and gap rects. (WebCore::SelectionGeometryGatherer::SelectionGeometryGatherer): (WebCore::SelectionGeometryGatherer::addQuad): Rename `addRect` to `addQuad`, and make it take a `FloatQuad` instead. (WebCore::SelectionGeometryGatherer::addGapRects): (WebCore::SelectionGeometryGatherer::Notifier::Notifier): (WebCore::SelectionGeometryGatherer::Notifier::~Notifier): (WebCore::SelectionGeometryGatherer::boundingRects const): (WebCore::SelectionGeometryGatherer::clearAndCreateNotifier): * editing/SelectionGeometryGatherer.h: Renamed from Source/WebCore/editing/SelectionRectGatherer.h. (WebCore::SelectionGeometryGatherer::setTextOnly): (WebCore::SelectionGeometryGatherer::isTextOnly const): * html/HTMLElement.cpp: (WebCore::HTMLElement::updateWithImageExtractionResult): Minor tweak - don't add any margin around the word when the line only contains a single word. * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): Rename `selectionRectsDidChange` to `selectionQuadsDidChange`, and take a `FloatQuad` in absolute coordinates instead of a `LayoutRect`. Store these quads in `m_overlaySelectionQuads` (also renamed from `m_overlaySelectionRects`). (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): (WebCore::ImageOverlayController::drawRect): Make a few changes when painting selections using the `ImageOverlayController`: 1. Instead of painting with `fillRect()`, coalesce all of the collected selection quads into a single `Path` object, and pass that `Path` into `fillPath()`. This allows us to render each piece of selected content as a quad instead of a bounding rect, and additionally prevents us from rendering overlapping selections when using `ImageOverlayController`. 2. Clip selections to the absolute bounds of the image overlay host element's renderer, which prevents the new selection quads from spilling out of the host element. (WebCore::ImageOverlayController::selectionRectsDidChange): Deleted. * page/ImageOverlayController.h: * rendering/RenderSelectionInfo.cpp: (WebCore::RenderSelectionInfo::RenderSelectionInfo): * rendering/RenderSelectionInfo.h: (WebCore::RenderSelectionInfo::collectedSelectionQuads const): (WebCore::RenderSelectionInfo::collectedSelectionRects const): Deleted. More minor refactoring: rename `collectedSelectionRects` to `collectedSelectionQuads`, and make it take the original `FloatQuad` instead of the quad's bounding box. * rendering/RenderText.cpp: (WebCore::RenderText::collectSelectionGeometriesForLineBoxes): * rendering/RenderText.h: * rendering/SelectionRangeData.cpp: (WebCore::SelectionRangeData::SelectionRangeData): (WebCore::SelectionRangeData::set): (WebCore::SelectionRangeData::apply): * rendering/SelectionRangeData.h: LayoutTests: Add a new layout test to cover the change. Currently, the below test case renders a visible selection rect in the image overlay since we render the bounding rect of the overlay text quad, which intersects with the image overlay's bounds. However, the text quad is positioned outside of the image overlay, so there shouldn't be any visible selection rect. As such, this test is expected to render the same content as a plain image (even without an image overlay). Unfortunately, I couldn't write a matching ref-test for the case where the selection rect is inside the bounds of the image overlay, since doing so led to tiny subpixel differences between the transparent image case (using `ImageOverlayController`) and the regular image overlay selection case. * fast/images/image-extraction/mac/select-rotated-transparent-image-overlay-expected.html: Added. * fast/images/image-extraction/mac/select-rotated-transparent-image-overlay.html: Added. Canonical link: https://commits.webkit.org/237541@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@277274 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-10 18:10:03 +00:00
void selectionQuadsDidChange(Frame&, const Vector<FloatQuad>&);
[macOS] Data detector highlights should appear when hovering inside image overlays https://bugs.webkit.org/show_bug.cgi?id=226507 Reviewed by Tim Horton. Refactor some logic in ImageOverlayController, such that the overlay is installed if _either_ selection painting is required, or data detector highlights for the image overlay host element exist; additionally, add plumbing to allow the ImageOverlayController to install a page overlay when the element under the mouse is inside an image overlay. * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Drive-by fix: use `imageOverlayControllerIfExists` instead of `imageOverlayController` to avoid unnecessarily creating a new ImageOverlayController when detaching a Document. * page/EventHandler.cpp: (WebCore::EventHandler::clear): Refactor logic for clearing out `m_elementUnderMouse` into a separate helper, and call it from these two places. This new helper clears out `m_elementUnderMouse` and additionally notifies the page's image overlay controller (only if it has already been constructed). (WebCore::EventHandler::updateMouseEventTargetNode): Call out to the page's image overlay controller when changing `m_elementUnderMouse`. (WebCore::EventHandler::clearElementUnderMouse): * page/EventHandler.h: * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): Refactor ImageOverlayController so that it only installs its page overlay if either: 1. Selection painting is needed for selected text inside an image overlay, or... 2. The cursor is over an image overlay host element with data detection results. To achieve this, we maintain a weak pointer to the image overlay host that contains the selection separately from the weak pointer to the image overlay host that contains data detectors, and is the element currently under the mouse cursor. Drive-by fix: also ignore selection updates due to temporary selections triggered as a result of gathering dictionary popup info. (WebCore::ImageOverlayController::documentDetached): (WebCore::ImageOverlayController::uninstallPageOverlay): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Split this into two functions: `uninstallPageOverlayIfNeeded`, which removes and destroys the PageOverlay if it is no longer needed (i.e. the overlay is required for neither selection painting nor data detectors). (WebCore::ImageOverlayController::willMoveToPage): (WebCore::ImageOverlayController::drawRect): (WebCore::ImageOverlayController::elementUnderMouseDidChange): * page/ImageOverlayController.h: Rename `m_imageOverlayBounds` to `m_selectionClipRect` to make it clear that this is only used during selection painting, and rename `m_overlaySelectionQuads` to just `m_selectionQuads` for conciseness. * page/Page.h: (WebCore::Page::imageOverlayControllerIfExists): Add a version of this getter that does not initialize the ImageOverlayController if it didn't already exist. See call sites in EventHandler and Document. * page/mac/ImageOverlayControllerMac.mm: (WebCore::ImageOverlayController::clearDataDetectorHighlights): Additionally clear out `m_hostElementForDataDetectors`. (WebCore::ImageOverlayController::elementUnderMouseDidChange): Update data detector highlights whenever the element under the mouse is over content inside an image overlay. Note that we effectively ignore this method call in the case where we're clearing out `m_elementUnderMouse` for a different Document than the one containing `m_hostElementForDataDetectors`, which prevents us from erroneously hiding data detectors when `m_elementUnderMouse` is removed or otherwise cleared out in a different Document. Canonical link: https://commits.webkit.org/238364@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278331 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-06-01 22:36:56 +00:00
void elementUnderMouseDidChange(Frame&, Element*);
Allow some image overlay content to render in fully transparent image elements https://bugs.webkit.org/show_bug.cgi?id=223781 <rdar://problem/75886351> Reviewed by Tim Horton. Source/WebCore: Introduce `ImageOverlayController`, and use it to render selections in image overlay content when the image overlay's host element is fully transparent. Test: fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Add plumbing to allow `ImageOverlayController` to uninstall its `PageOverlay` when the document is about to be detached. See `ImageOverlayController::` below. * editing/SelectionRectGatherer.cpp: (WebCore::SelectionRectGatherer::Notifier::~Notifier): Have `SelectionRectGatherer` notify the image overlay controller as well, when selection rects change. * page/ChromeClient.h: (WebCore::ChromeClient::needsImageOverlayControllerForSelectionPainting const): Add a new client hook that returns whether or not we should use `ImageOverlayController` to paint selections. If not (i.e. we're on iOS, where we use UIKit to draw selections in the UI process), then we'll never install page overlays, since `selectionRectsDidChange` is effectively a no-op. * page/ImageOverlayController.cpp: Added. (WebCore::ImageOverlayController::ImageOverlayController): (WebCore::ImageOverlayController::selectionRectsDidChange): When selection rects change, if the selection is inside an image overlay whose host is completely transparent (or very close to being completely transparent), then remember the selection rects along with the renderer's background color, and use this to render selection highlights separately, in a `PageOverlay`. (WebCore::ImageOverlayController::documentDetached): If the `Document` containing the current rendered overlay selection is detached, immediately uninstall the current `PageOverlay`. This ensures that the overlays don't persist through navigation. (WebCore::ImageOverlayController::installPageOverlayIfNeeded): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Helper methods to add or remove the `PageOverlay` from the current `Page`. (WebCore::ImageOverlayController::willMoveToPage): Uninstall the current page overlay if needed. (WebCore::ImageOverlayController::drawRect): Use the information stored in `ImageOverlayController::selectionRectsDidChange` to render custom selection rects. * page/ImageOverlayController.h: Added. * page/Page.cpp: * page/Page.h: Add an `ImageOverlayController` to the `Page`. (WebCore::Page::imageOverlayController): Source/WebKit: Implement a new chrome client hook. See WebCore ChangeLog for more information. * WebProcess/WebCoreSupport/WebChromeClient.h: LayoutTests: Adjust an existing layout test so that it actually checks what it was intended to check; add a new layout test to cover the changes in this bug. * fast/images/image-extraction/mac/select-word-in-draggable-image-overlay.html: Drive-by fix: remove some extraneous imported scripts from this layout test, and additionally simplify the test so that it doesn't rely on event sender to select text. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay-expected-mismatch.html: Added. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html: Added. Add a new layout test with a fully transparent image element that covers a div of the same size, with a background image that is identical to the image element's image. This emulates the behavior of certain websites that prompted this fallback image overlay rendering codepath in the first place. Canonical link: https://commits.webkit.org/235820@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-26 21:23:17 +00:00
void documentDetached(const Document&);
private:
void willMoveToPage(PageOverlay&, Page*) final;
void didMoveToPage(PageOverlay&, Page*) final { }
void drawRect(PageOverlay&, GraphicsContext&, const IntRect& dirtyRect) final;
[macOS] Support painting data detector highlights inside image overlays https://bugs.webkit.org/show_bug.cgi?id=226227 Reviewed by Tim Horton. Add support for painting data detector highlights inside image overlays by leveraging `DataDetectorHighlight`. See comments below for more details. * SourcesCocoa.txt: * WebCore.xcodeproj/project.pbxproj: * editing/Editor.cpp: (WebCore::scanForTelephoneNumbers): Avoid painting service-controls-based telephone number highlights for selected text inside image overlays, in order to avoid painting a redundant data detector highlight for telephone numbers in image overlays. * html/HTMLElement.cpp: (WebCore::imageOverlayDataDetectorClassName): (WebCore::HTMLElement::isImageOverlayDataDetectorResult const): (WebCore::HTMLElement::updateWithImageExtractionResult): * html/HTMLElement.h: * html/shadow/imageOverlay.css: (div.image-overlay-data-detector-result): Add support for injecting elements in the DOM that represent data detection results; these are transformed and overlaid on the image in the same way as existing text containers. Note that we lay out these elements on top of text, but make them invisible to hit-testing unless the `IgnoreCSSPointerEventsProperty` option is specified. We'll take advantage of this behavior in a future patch. * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): (WebCore::ImageOverlayController::drawRect): (WebCore::ImageOverlayController::platformHandleMouseEvent): * page/ImageOverlayController.h: Refactor the image overlay controller, such that we install the page overlay if there is any selection inside the image overlay (as opposed to only when we need to use this overlay to paint the text selection for transparent images). If data detectors are present, we'll additionally set up out `DataDetectorHighlight`s (one for each data detection result container). * page/mac/ImageOverlayControllerMac.mm: Added. (WebCore::ImageOverlayController::updateDataDetectorHighlights): Traverse the image overlay's subtree in search of container elements that correspond to data detection results; for each of these elements, we create a new `DataDetectorHighlight` using the element's bounds, and save the pair in `m_dataDetectorContainersAndHighlights`. Note that we hold a weak pointer to the container element, such that there's no risk of leaking any of these data detection result containers (or their documents). (WebCore::ImageOverlayController::platformHandleMouseEvent): (WebCore::ImageOverlayController::handleDataDetectorAction): Add a FIXME referencing the next patch in the sequence. (WebCore::ImageOverlayController::clearDataDetectorHighlights): * platform/mac/DataDetectorHighlight.h: * platform/mac/DataDetectorHighlight.mm: (WebCore::DataDetectorHighlight::createForImageOverlay): Add a helper method to create a `DataDetectorHighlight` for image overlays. Canonical link: https://commits.webkit.org/238171@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278121 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-26 20:06:32 +00:00
bool mouseEvent(PageOverlay&, const PlatformMouseEvent& event) final { return platformHandleMouseEvent(event); }
Allow some image overlay content to render in fully transparent image elements https://bugs.webkit.org/show_bug.cgi?id=223781 <rdar://problem/75886351> Reviewed by Tim Horton. Source/WebCore: Introduce `ImageOverlayController`, and use it to render selections in image overlay content when the image overlay's host element is fully transparent. Test: fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Add plumbing to allow `ImageOverlayController` to uninstall its `PageOverlay` when the document is about to be detached. See `ImageOverlayController::` below. * editing/SelectionRectGatherer.cpp: (WebCore::SelectionRectGatherer::Notifier::~Notifier): Have `SelectionRectGatherer` notify the image overlay controller as well, when selection rects change. * page/ChromeClient.h: (WebCore::ChromeClient::needsImageOverlayControllerForSelectionPainting const): Add a new client hook that returns whether or not we should use `ImageOverlayController` to paint selections. If not (i.e. we're on iOS, where we use UIKit to draw selections in the UI process), then we'll never install page overlays, since `selectionRectsDidChange` is effectively a no-op. * page/ImageOverlayController.cpp: Added. (WebCore::ImageOverlayController::ImageOverlayController): (WebCore::ImageOverlayController::selectionRectsDidChange): When selection rects change, if the selection is inside an image overlay whose host is completely transparent (or very close to being completely transparent), then remember the selection rects along with the renderer's background color, and use this to render selection highlights separately, in a `PageOverlay`. (WebCore::ImageOverlayController::documentDetached): If the `Document` containing the current rendered overlay selection is detached, immediately uninstall the current `PageOverlay`. This ensures that the overlays don't persist through navigation. (WebCore::ImageOverlayController::installPageOverlayIfNeeded): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Helper methods to add or remove the `PageOverlay` from the current `Page`. (WebCore::ImageOverlayController::willMoveToPage): Uninstall the current page overlay if needed. (WebCore::ImageOverlayController::drawRect): Use the information stored in `ImageOverlayController::selectionRectsDidChange` to render custom selection rects. * page/ImageOverlayController.h: Added. * page/Page.cpp: * page/Page.h: Add an `ImageOverlayController` to the `Page`. (WebCore::Page::imageOverlayController): Source/WebKit: Implement a new chrome client hook. See WebCore ChangeLog for more information. * WebProcess/WebCoreSupport/WebChromeClient.h: LayoutTests: Adjust an existing layout test so that it actually checks what it was intended to check; add a new layout test to cover the changes in this bug. * fast/images/image-extraction/mac/select-word-in-draggable-image-overlay.html: Drive-by fix: remove some extraneous imported scripts from this layout test, and additionally simplify the test so that it doesn't rely on event sender to select text. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay-expected-mismatch.html: Added. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html: Added. Add a new layout test with a fully transparent image element that covers a div of the same size, with a background image that is identical to the image element's image. This emulates the behavior of certain websites that prompted this fallback image overlay rendering codepath in the first place. Canonical link: https://commits.webkit.org/235820@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-26 21:23:17 +00:00
bool shouldUsePageOverlayToPaintSelection(const RenderElement&);
PageOverlay& installPageOverlayIfNeeded();
void uninstallPageOverlayIfNeeded();
[macOS] Data detector highlights should appear when hovering inside image overlays https://bugs.webkit.org/show_bug.cgi?id=226507 Reviewed by Tim Horton. Refactor some logic in ImageOverlayController, such that the overlay is installed if _either_ selection painting is required, or data detector highlights for the image overlay host element exist; additionally, add plumbing to allow the ImageOverlayController to install a page overlay when the element under the mouse is inside an image overlay. * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Drive-by fix: use `imageOverlayControllerIfExists` instead of `imageOverlayController` to avoid unnecessarily creating a new ImageOverlayController when detaching a Document. * page/EventHandler.cpp: (WebCore::EventHandler::clear): Refactor logic for clearing out `m_elementUnderMouse` into a separate helper, and call it from these two places. This new helper clears out `m_elementUnderMouse` and additionally notifies the page's image overlay controller (only if it has already been constructed). (WebCore::EventHandler::updateMouseEventTargetNode): Call out to the page's image overlay controller when changing `m_elementUnderMouse`. (WebCore::EventHandler::clearElementUnderMouse): * page/EventHandler.h: * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): Refactor ImageOverlayController so that it only installs its page overlay if either: 1. Selection painting is needed for selected text inside an image overlay, or... 2. The cursor is over an image overlay host element with data detection results. To achieve this, we maintain a weak pointer to the image overlay host that contains the selection separately from the weak pointer to the image overlay host that contains data detectors, and is the element currently under the mouse cursor. Drive-by fix: also ignore selection updates due to temporary selections triggered as a result of gathering dictionary popup info. (WebCore::ImageOverlayController::documentDetached): (WebCore::ImageOverlayController::uninstallPageOverlay): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Split this into two functions: `uninstallPageOverlayIfNeeded`, which removes and destroys the PageOverlay if it is no longer needed (i.e. the overlay is required for neither selection painting nor data detectors). (WebCore::ImageOverlayController::willMoveToPage): (WebCore::ImageOverlayController::drawRect): (WebCore::ImageOverlayController::elementUnderMouseDidChange): * page/ImageOverlayController.h: Rename `m_imageOverlayBounds` to `m_selectionClipRect` to make it clear that this is only used during selection painting, and rename `m_overlaySelectionQuads` to just `m_selectionQuads` for conciseness. * page/Page.h: (WebCore::Page::imageOverlayControllerIfExists): Add a version of this getter that does not initialize the ImageOverlayController if it didn't already exist. See call sites in EventHandler and Document. * page/mac/ImageOverlayControllerMac.mm: (WebCore::ImageOverlayController::clearDataDetectorHighlights): Additionally clear out `m_hostElementForDataDetectors`. (WebCore::ImageOverlayController::elementUnderMouseDidChange): Update data detector highlights whenever the element under the mouse is over content inside an image overlay. Note that we effectively ignore this method call in the case where we're clearing out `m_elementUnderMouse` for a different Document than the one containing `m_hostElementForDataDetectors`, which prevents us from erroneously hiding data detectors when `m_elementUnderMouse` is removed or otherwise cleared out in a different Document. Canonical link: https://commits.webkit.org/238364@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278331 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-06-01 22:36:56 +00:00
void uninstallPageOverlay();
Allow some image overlay content to render in fully transparent image elements https://bugs.webkit.org/show_bug.cgi?id=223781 <rdar://problem/75886351> Reviewed by Tim Horton. Source/WebCore: Introduce `ImageOverlayController`, and use it to render selections in image overlay content when the image overlay's host element is fully transparent. Test: fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Add plumbing to allow `ImageOverlayController` to uninstall its `PageOverlay` when the document is about to be detached. See `ImageOverlayController::` below. * editing/SelectionRectGatherer.cpp: (WebCore::SelectionRectGatherer::Notifier::~Notifier): Have `SelectionRectGatherer` notify the image overlay controller as well, when selection rects change. * page/ChromeClient.h: (WebCore::ChromeClient::needsImageOverlayControllerForSelectionPainting const): Add a new client hook that returns whether or not we should use `ImageOverlayController` to paint selections. If not (i.e. we're on iOS, where we use UIKit to draw selections in the UI process), then we'll never install page overlays, since `selectionRectsDidChange` is effectively a no-op. * page/ImageOverlayController.cpp: Added. (WebCore::ImageOverlayController::ImageOverlayController): (WebCore::ImageOverlayController::selectionRectsDidChange): When selection rects change, if the selection is inside an image overlay whose host is completely transparent (or very close to being completely transparent), then remember the selection rects along with the renderer's background color, and use this to render selection highlights separately, in a `PageOverlay`. (WebCore::ImageOverlayController::documentDetached): If the `Document` containing the current rendered overlay selection is detached, immediately uninstall the current `PageOverlay`. This ensures that the overlays don't persist through navigation. (WebCore::ImageOverlayController::installPageOverlayIfNeeded): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Helper methods to add or remove the `PageOverlay` from the current `Page`. (WebCore::ImageOverlayController::willMoveToPage): Uninstall the current page overlay if needed. (WebCore::ImageOverlayController::drawRect): Use the information stored in `ImageOverlayController::selectionRectsDidChange` to render custom selection rects. * page/ImageOverlayController.h: Added. * page/Page.cpp: * page/Page.h: Add an `ImageOverlayController` to the `Page`. (WebCore::Page::imageOverlayController): Source/WebKit: Implement a new chrome client hook. See WebCore ChangeLog for more information. * WebProcess/WebCoreSupport/WebChromeClient.h: LayoutTests: Adjust an existing layout test so that it actually checks what it was intended to check; add a new layout test to cover the changes in this bug. * fast/images/image-extraction/mac/select-word-in-draggable-image-overlay.html: Drive-by fix: remove some extraneous imported scripts from this layout test, and additionally simplify the test so that it doesn't rely on event sender to select text. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay-expected-mismatch.html: Added. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html: Added. Add a new layout test with a fully transparent image element that covers a div of the same size, with a background image that is identical to the image element's image. This emulates the behavior of certain websites that prompted this fallback image overlay rendering codepath in the first place. Canonical link: https://commits.webkit.org/235820@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-26 21:23:17 +00:00
[macOS] Support painting data detector highlights inside image overlays https://bugs.webkit.org/show_bug.cgi?id=226227 Reviewed by Tim Horton. Add support for painting data detector highlights inside image overlays by leveraging `DataDetectorHighlight`. See comments below for more details. * SourcesCocoa.txt: * WebCore.xcodeproj/project.pbxproj: * editing/Editor.cpp: (WebCore::scanForTelephoneNumbers): Avoid painting service-controls-based telephone number highlights for selected text inside image overlays, in order to avoid painting a redundant data detector highlight for telephone numbers in image overlays. * html/HTMLElement.cpp: (WebCore::imageOverlayDataDetectorClassName): (WebCore::HTMLElement::isImageOverlayDataDetectorResult const): (WebCore::HTMLElement::updateWithImageExtractionResult): * html/HTMLElement.h: * html/shadow/imageOverlay.css: (div.image-overlay-data-detector-result): Add support for injecting elements in the DOM that represent data detection results; these are transformed and overlaid on the image in the same way as existing text containers. Note that we lay out these elements on top of text, but make them invisible to hit-testing unless the `IgnoreCSSPointerEventsProperty` option is specified. We'll take advantage of this behavior in a future patch. * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): (WebCore::ImageOverlayController::drawRect): (WebCore::ImageOverlayController::platformHandleMouseEvent): * page/ImageOverlayController.h: Refactor the image overlay controller, such that we install the page overlay if there is any selection inside the image overlay (as opposed to only when we need to use this overlay to paint the text selection for transparent images). If data detectors are present, we'll additionally set up out `DataDetectorHighlight`s (one for each data detection result container). * page/mac/ImageOverlayControllerMac.mm: Added. (WebCore::ImageOverlayController::updateDataDetectorHighlights): Traverse the image overlay's subtree in search of container elements that correspond to data detection results; for each of these elements, we create a new `DataDetectorHighlight` using the element's bounds, and save the pair in `m_dataDetectorContainersAndHighlights`. Note that we hold a weak pointer to the container element, such that there's no risk of leaking any of these data detection result containers (or their documents). (WebCore::ImageOverlayController::platformHandleMouseEvent): (WebCore::ImageOverlayController::handleDataDetectorAction): Add a FIXME referencing the next patch in the sequence. (WebCore::ImageOverlayController::clearDataDetectorHighlights): * platform/mac/DataDetectorHighlight.h: * platform/mac/DataDetectorHighlight.mm: (WebCore::DataDetectorHighlight::createForImageOverlay): Add a helper method to create a `DataDetectorHighlight` for image overlays. Canonical link: https://commits.webkit.org/238171@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278121 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-26 20:06:32 +00:00
#if PLATFORM(MAC)
void updateDataDetectorHighlights(const HTMLElement&);
void clearDataDetectorHighlights();
bool handleDataDetectorAction(const HTMLElement&, const IntPoint&);
DataDetectorHighlight* activeHighlight() const final { return m_activeDataDetectorHighlight.get(); }
#endif
[macOS] Data detector highlights should appear when hovering inside image overlays https://bugs.webkit.org/show_bug.cgi?id=226507 Reviewed by Tim Horton. Refactor some logic in ImageOverlayController, such that the overlay is installed if _either_ selection painting is required, or data detector highlights for the image overlay host element exist; additionally, add plumbing to allow the ImageOverlayController to install a page overlay when the element under the mouse is inside an image overlay. * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Drive-by fix: use `imageOverlayControllerIfExists` instead of `imageOverlayController` to avoid unnecessarily creating a new ImageOverlayController when detaching a Document. * page/EventHandler.cpp: (WebCore::EventHandler::clear): Refactor logic for clearing out `m_elementUnderMouse` into a separate helper, and call it from these two places. This new helper clears out `m_elementUnderMouse` and additionally notifies the page's image overlay controller (only if it has already been constructed). (WebCore::EventHandler::updateMouseEventTargetNode): Call out to the page's image overlay controller when changing `m_elementUnderMouse`. (WebCore::EventHandler::clearElementUnderMouse): * page/EventHandler.h: * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): Refactor ImageOverlayController so that it only installs its page overlay if either: 1. Selection painting is needed for selected text inside an image overlay, or... 2. The cursor is over an image overlay host element with data detection results. To achieve this, we maintain a weak pointer to the image overlay host that contains the selection separately from the weak pointer to the image overlay host that contains data detectors, and is the element currently under the mouse cursor. Drive-by fix: also ignore selection updates due to temporary selections triggered as a result of gathering dictionary popup info. (WebCore::ImageOverlayController::documentDetached): (WebCore::ImageOverlayController::uninstallPageOverlay): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Split this into two functions: `uninstallPageOverlayIfNeeded`, which removes and destroys the PageOverlay if it is no longer needed (i.e. the overlay is required for neither selection painting nor data detectors). (WebCore::ImageOverlayController::willMoveToPage): (WebCore::ImageOverlayController::drawRect): (WebCore::ImageOverlayController::elementUnderMouseDidChange): * page/ImageOverlayController.h: Rename `m_imageOverlayBounds` to `m_selectionClipRect` to make it clear that this is only used during selection painting, and rename `m_overlaySelectionQuads` to just `m_selectionQuads` for conciseness. * page/Page.h: (WebCore::Page::imageOverlayControllerIfExists): Add a version of this getter that does not initialize the ImageOverlayController if it didn't already exist. See call sites in EventHandler and Document. * page/mac/ImageOverlayControllerMac.mm: (WebCore::ImageOverlayController::clearDataDetectorHighlights): Additionally clear out `m_hostElementForDataDetectors`. (WebCore::ImageOverlayController::elementUnderMouseDidChange): Update data detector highlights whenever the element under the mouse is over content inside an image overlay. Note that we effectively ignore this method call in the case where we're clearing out `m_elementUnderMouse` for a different Document than the one containing `m_hostElementForDataDetectors`, which prevents us from erroneously hiding data detectors when `m_elementUnderMouse` is removed or otherwise cleared out in a different Document. Canonical link: https://commits.webkit.org/238364@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278331 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-06-01 22:36:56 +00:00
void platformUpdateElementUnderMouse(Frame&, Element* elementUnderMouse);
[macOS] Support painting data detector highlights inside image overlays https://bugs.webkit.org/show_bug.cgi?id=226227 Reviewed by Tim Horton. Add support for painting data detector highlights inside image overlays by leveraging `DataDetectorHighlight`. See comments below for more details. * SourcesCocoa.txt: * WebCore.xcodeproj/project.pbxproj: * editing/Editor.cpp: (WebCore::scanForTelephoneNumbers): Avoid painting service-controls-based telephone number highlights for selected text inside image overlays, in order to avoid painting a redundant data detector highlight for telephone numbers in image overlays. * html/HTMLElement.cpp: (WebCore::imageOverlayDataDetectorClassName): (WebCore::HTMLElement::isImageOverlayDataDetectorResult const): (WebCore::HTMLElement::updateWithImageExtractionResult): * html/HTMLElement.h: * html/shadow/imageOverlay.css: (div.image-overlay-data-detector-result): Add support for injecting elements in the DOM that represent data detection results; these are transformed and overlaid on the image in the same way as existing text containers. Note that we lay out these elements on top of text, but make them invisible to hit-testing unless the `IgnoreCSSPointerEventsProperty` option is specified. We'll take advantage of this behavior in a future patch. * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): (WebCore::ImageOverlayController::drawRect): (WebCore::ImageOverlayController::platformHandleMouseEvent): * page/ImageOverlayController.h: Refactor the image overlay controller, such that we install the page overlay if there is any selection inside the image overlay (as opposed to only when we need to use this overlay to paint the text selection for transparent images). If data detectors are present, we'll additionally set up out `DataDetectorHighlight`s (one for each data detection result container). * page/mac/ImageOverlayControllerMac.mm: Added. (WebCore::ImageOverlayController::updateDataDetectorHighlights): Traverse the image overlay's subtree in search of container elements that correspond to data detection results; for each of these elements, we create a new `DataDetectorHighlight` using the element's bounds, and save the pair in `m_dataDetectorContainersAndHighlights`. Note that we hold a weak pointer to the container element, such that there's no risk of leaking any of these data detection result containers (or their documents). (WebCore::ImageOverlayController::platformHandleMouseEvent): (WebCore::ImageOverlayController::handleDataDetectorAction): Add a FIXME referencing the next patch in the sequence. (WebCore::ImageOverlayController::clearDataDetectorHighlights): * platform/mac/DataDetectorHighlight.h: * platform/mac/DataDetectorHighlight.mm: (WebCore::DataDetectorHighlight::createForImageOverlay): Add a helper method to create a `DataDetectorHighlight` for image overlays. Canonical link: https://commits.webkit.org/238171@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278121 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-26 20:06:32 +00:00
bool platformHandleMouseEvent(const PlatformMouseEvent&);
Allow some image overlay content to render in fully transparent image elements https://bugs.webkit.org/show_bug.cgi?id=223781 <rdar://problem/75886351> Reviewed by Tim Horton. Source/WebCore: Introduce `ImageOverlayController`, and use it to render selections in image overlay content when the image overlay's host element is fully transparent. Test: fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Add plumbing to allow `ImageOverlayController` to uninstall its `PageOverlay` when the document is about to be detached. See `ImageOverlayController::` below. * editing/SelectionRectGatherer.cpp: (WebCore::SelectionRectGatherer::Notifier::~Notifier): Have `SelectionRectGatherer` notify the image overlay controller as well, when selection rects change. * page/ChromeClient.h: (WebCore::ChromeClient::needsImageOverlayControllerForSelectionPainting const): Add a new client hook that returns whether or not we should use `ImageOverlayController` to paint selections. If not (i.e. we're on iOS, where we use UIKit to draw selections in the UI process), then we'll never install page overlays, since `selectionRectsDidChange` is effectively a no-op. * page/ImageOverlayController.cpp: Added. (WebCore::ImageOverlayController::ImageOverlayController): (WebCore::ImageOverlayController::selectionRectsDidChange): When selection rects change, if the selection is inside an image overlay whose host is completely transparent (or very close to being completely transparent), then remember the selection rects along with the renderer's background color, and use this to render selection highlights separately, in a `PageOverlay`. (WebCore::ImageOverlayController::documentDetached): If the `Document` containing the current rendered overlay selection is detached, immediately uninstall the current `PageOverlay`. This ensures that the overlays don't persist through navigation. (WebCore::ImageOverlayController::installPageOverlayIfNeeded): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Helper methods to add or remove the `PageOverlay` from the current `Page`. (WebCore::ImageOverlayController::willMoveToPage): Uninstall the current page overlay if needed. (WebCore::ImageOverlayController::drawRect): Use the information stored in `ImageOverlayController::selectionRectsDidChange` to render custom selection rects. * page/ImageOverlayController.h: Added. * page/Page.cpp: * page/Page.h: Add an `ImageOverlayController` to the `Page`. (WebCore::Page::imageOverlayController): Source/WebKit: Implement a new chrome client hook. See WebCore ChangeLog for more information. * WebProcess/WebCoreSupport/WebChromeClient.h: LayoutTests: Adjust an existing layout test so that it actually checks what it was intended to check; add a new layout test to cover the changes in this bug. * fast/images/image-extraction/mac/select-word-in-draggable-image-overlay.html: Drive-by fix: remove some extraneous imported scripts from this layout test, and additionally simplify the test so that it doesn't rely on event sender to select text. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay-expected-mismatch.html: Added. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html: Added. Add a new layout test with a fully transparent image element that covers a div of the same size, with a background image that is identical to the image element's image. This emulates the behavior of certain websites that prompted this fallback image overlay rendering codepath in the first place. Canonical link: https://commits.webkit.org/235820@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-26 21:23:17 +00:00
WeakPtr<Page> m_page;
RefPtr<PageOverlay> m_overlay;
[macOS] Data detector highlights should appear when hovering inside image overlays https://bugs.webkit.org/show_bug.cgi?id=226507 Reviewed by Tim Horton. Refactor some logic in ImageOverlayController, such that the overlay is installed if _either_ selection painting is required, or data detector highlights for the image overlay host element exist; additionally, add plumbing to allow the ImageOverlayController to install a page overlay when the element under the mouse is inside an image overlay. * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Drive-by fix: use `imageOverlayControllerIfExists` instead of `imageOverlayController` to avoid unnecessarily creating a new ImageOverlayController when detaching a Document. * page/EventHandler.cpp: (WebCore::EventHandler::clear): Refactor logic for clearing out `m_elementUnderMouse` into a separate helper, and call it from these two places. This new helper clears out `m_elementUnderMouse` and additionally notifies the page's image overlay controller (only if it has already been constructed). (WebCore::EventHandler::updateMouseEventTargetNode): Call out to the page's image overlay controller when changing `m_elementUnderMouse`. (WebCore::EventHandler::clearElementUnderMouse): * page/EventHandler.h: * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): Refactor ImageOverlayController so that it only installs its page overlay if either: 1. Selection painting is needed for selected text inside an image overlay, or... 2. The cursor is over an image overlay host element with data detection results. To achieve this, we maintain a weak pointer to the image overlay host that contains the selection separately from the weak pointer to the image overlay host that contains data detectors, and is the element currently under the mouse cursor. Drive-by fix: also ignore selection updates due to temporary selections triggered as a result of gathering dictionary popup info. (WebCore::ImageOverlayController::documentDetached): (WebCore::ImageOverlayController::uninstallPageOverlay): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Split this into two functions: `uninstallPageOverlayIfNeeded`, which removes and destroys the PageOverlay if it is no longer needed (i.e. the overlay is required for neither selection painting nor data detectors). (WebCore::ImageOverlayController::willMoveToPage): (WebCore::ImageOverlayController::drawRect): (WebCore::ImageOverlayController::elementUnderMouseDidChange): * page/ImageOverlayController.h: Rename `m_imageOverlayBounds` to `m_selectionClipRect` to make it clear that this is only used during selection painting, and rename `m_overlaySelectionQuads` to just `m_selectionQuads` for conciseness. * page/Page.h: (WebCore::Page::imageOverlayControllerIfExists): Add a version of this getter that does not initialize the ImageOverlayController if it didn't already exist. See call sites in EventHandler and Document. * page/mac/ImageOverlayControllerMac.mm: (WebCore::ImageOverlayController::clearDataDetectorHighlights): Additionally clear out `m_hostElementForDataDetectors`. (WebCore::ImageOverlayController::elementUnderMouseDidChange): Update data detector highlights whenever the element under the mouse is over content inside an image overlay. Note that we effectively ignore this method call in the case where we're clearing out `m_elementUnderMouse` for a different Document than the one containing `m_hostElementForDataDetectors`, which prevents us from erroneously hiding data detectors when `m_elementUnderMouse` is removed or otherwise cleared out in a different Document. Canonical link: https://commits.webkit.org/238364@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278331 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-06-01 22:36:56 +00:00
WeakPtr<HTMLElement> m_hostElementForSelection;
Vector<FloatQuad> m_selectionQuads;
LayoutRect m_selectionClipRect;
Allow some image overlay content to render in fully transparent image elements https://bugs.webkit.org/show_bug.cgi?id=223781 <rdar://problem/75886351> Reviewed by Tim Horton. Source/WebCore: Introduce `ImageOverlayController`, and use it to render selections in image overlay content when the image overlay's host element is fully transparent. Test: fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Add plumbing to allow `ImageOverlayController` to uninstall its `PageOverlay` when the document is about to be detached. See `ImageOverlayController::` below. * editing/SelectionRectGatherer.cpp: (WebCore::SelectionRectGatherer::Notifier::~Notifier): Have `SelectionRectGatherer` notify the image overlay controller as well, when selection rects change. * page/ChromeClient.h: (WebCore::ChromeClient::needsImageOverlayControllerForSelectionPainting const): Add a new client hook that returns whether or not we should use `ImageOverlayController` to paint selections. If not (i.e. we're on iOS, where we use UIKit to draw selections in the UI process), then we'll never install page overlays, since `selectionRectsDidChange` is effectively a no-op. * page/ImageOverlayController.cpp: Added. (WebCore::ImageOverlayController::ImageOverlayController): (WebCore::ImageOverlayController::selectionRectsDidChange): When selection rects change, if the selection is inside an image overlay whose host is completely transparent (or very close to being completely transparent), then remember the selection rects along with the renderer's background color, and use this to render selection highlights separately, in a `PageOverlay`. (WebCore::ImageOverlayController::documentDetached): If the `Document` containing the current rendered overlay selection is detached, immediately uninstall the current `PageOverlay`. This ensures that the overlays don't persist through navigation. (WebCore::ImageOverlayController::installPageOverlayIfNeeded): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Helper methods to add or remove the `PageOverlay` from the current `Page`. (WebCore::ImageOverlayController::willMoveToPage): Uninstall the current page overlay if needed. (WebCore::ImageOverlayController::drawRect): Use the information stored in `ImageOverlayController::selectionRectsDidChange` to render custom selection rects. * page/ImageOverlayController.h: Added. * page/Page.cpp: * page/Page.h: Add an `ImageOverlayController` to the `Page`. (WebCore::Page::imageOverlayController): Source/WebKit: Implement a new chrome client hook. See WebCore ChangeLog for more information. * WebProcess/WebCoreSupport/WebChromeClient.h: LayoutTests: Adjust an existing layout test so that it actually checks what it was intended to check; add a new layout test to cover the changes in this bug. * fast/images/image-extraction/mac/select-word-in-draggable-image-overlay.html: Drive-by fix: remove some extraneous imported scripts from this layout test, and additionally simplify the test so that it doesn't rely on event sender to select text. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay-expected-mismatch.html: Added. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html: Added. Add a new layout test with a fully transparent image element that covers a div of the same size, with a background image that is identical to the image element's image. This emulates the behavior of certain websites that prompted this fallback image overlay rendering codepath in the first place. Canonical link: https://commits.webkit.org/235820@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-26 21:23:17 +00:00
Color m_selectionBackgroundColor { Color::transparentBlack };
[macOS] Support painting data detector highlights inside image overlays https://bugs.webkit.org/show_bug.cgi?id=226227 Reviewed by Tim Horton. Add support for painting data detector highlights inside image overlays by leveraging `DataDetectorHighlight`. See comments below for more details. * SourcesCocoa.txt: * WebCore.xcodeproj/project.pbxproj: * editing/Editor.cpp: (WebCore::scanForTelephoneNumbers): Avoid painting service-controls-based telephone number highlights for selected text inside image overlays, in order to avoid painting a redundant data detector highlight for telephone numbers in image overlays. * html/HTMLElement.cpp: (WebCore::imageOverlayDataDetectorClassName): (WebCore::HTMLElement::isImageOverlayDataDetectorResult const): (WebCore::HTMLElement::updateWithImageExtractionResult): * html/HTMLElement.h: * html/shadow/imageOverlay.css: (div.image-overlay-data-detector-result): Add support for injecting elements in the DOM that represent data detection results; these are transformed and overlaid on the image in the same way as existing text containers. Note that we lay out these elements on top of text, but make them invisible to hit-testing unless the `IgnoreCSSPointerEventsProperty` option is specified. We'll take advantage of this behavior in a future patch. * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): (WebCore::ImageOverlayController::drawRect): (WebCore::ImageOverlayController::platformHandleMouseEvent): * page/ImageOverlayController.h: Refactor the image overlay controller, such that we install the page overlay if there is any selection inside the image overlay (as opposed to only when we need to use this overlay to paint the text selection for transparent images). If data detectors are present, we'll additionally set up out `DataDetectorHighlight`s (one for each data detection result container). * page/mac/ImageOverlayControllerMac.mm: Added. (WebCore::ImageOverlayController::updateDataDetectorHighlights): Traverse the image overlay's subtree in search of container elements that correspond to data detection results; for each of these elements, we create a new `DataDetectorHighlight` using the element's bounds, and save the pair in `m_dataDetectorContainersAndHighlights`. Note that we hold a weak pointer to the container element, such that there's no risk of leaking any of these data detection result containers (or their documents). (WebCore::ImageOverlayController::platformHandleMouseEvent): (WebCore::ImageOverlayController::handleDataDetectorAction): Add a FIXME referencing the next patch in the sequence. (WebCore::ImageOverlayController::clearDataDetectorHighlights): * platform/mac/DataDetectorHighlight.h: * platform/mac/DataDetectorHighlight.mm: (WebCore::DataDetectorHighlight::createForImageOverlay): Add a helper method to create a `DataDetectorHighlight` for image overlays. Canonical link: https://commits.webkit.org/238171@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278121 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-26 20:06:32 +00:00
#if PLATFORM(MAC)
using ContainerAndHighlight = std::pair<WeakPtr<HTMLElement>, Ref<DataDetectorHighlight>>;
Vector<ContainerAndHighlight> m_dataDetectorContainersAndHighlights;
RefPtr<DataDetectorHighlight> m_activeDataDetectorHighlight;
[macOS] Data detector highlights should appear when hovering inside image overlays https://bugs.webkit.org/show_bug.cgi?id=226507 Reviewed by Tim Horton. Refactor some logic in ImageOverlayController, such that the overlay is installed if _either_ selection painting is required, or data detector highlights for the image overlay host element exist; additionally, add plumbing to allow the ImageOverlayController to install a page overlay when the element under the mouse is inside an image overlay. * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Drive-by fix: use `imageOverlayControllerIfExists` instead of `imageOverlayController` to avoid unnecessarily creating a new ImageOverlayController when detaching a Document. * page/EventHandler.cpp: (WebCore::EventHandler::clear): Refactor logic for clearing out `m_elementUnderMouse` into a separate helper, and call it from these two places. This new helper clears out `m_elementUnderMouse` and additionally notifies the page's image overlay controller (only if it has already been constructed). (WebCore::EventHandler::updateMouseEventTargetNode): Call out to the page's image overlay controller when changing `m_elementUnderMouse`. (WebCore::EventHandler::clearElementUnderMouse): * page/EventHandler.h: * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): Refactor ImageOverlayController so that it only installs its page overlay if either: 1. Selection painting is needed for selected text inside an image overlay, or... 2. The cursor is over an image overlay host element with data detection results. To achieve this, we maintain a weak pointer to the image overlay host that contains the selection separately from the weak pointer to the image overlay host that contains data detectors, and is the element currently under the mouse cursor. Drive-by fix: also ignore selection updates due to temporary selections triggered as a result of gathering dictionary popup info. (WebCore::ImageOverlayController::documentDetached): (WebCore::ImageOverlayController::uninstallPageOverlay): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Split this into two functions: `uninstallPageOverlayIfNeeded`, which removes and destroys the PageOverlay if it is no longer needed (i.e. the overlay is required for neither selection painting nor data detectors). (WebCore::ImageOverlayController::willMoveToPage): (WebCore::ImageOverlayController::drawRect): (WebCore::ImageOverlayController::elementUnderMouseDidChange): * page/ImageOverlayController.h: Rename `m_imageOverlayBounds` to `m_selectionClipRect` to make it clear that this is only used during selection painting, and rename `m_overlaySelectionQuads` to just `m_selectionQuads` for conciseness. * page/Page.h: (WebCore::Page::imageOverlayControllerIfExists): Add a version of this getter that does not initialize the ImageOverlayController if it didn't already exist. See call sites in EventHandler and Document. * page/mac/ImageOverlayControllerMac.mm: (WebCore::ImageOverlayController::clearDataDetectorHighlights): Additionally clear out `m_hostElementForDataDetectors`. (WebCore::ImageOverlayController::elementUnderMouseDidChange): Update data detector highlights whenever the element under the mouse is over content inside an image overlay. Note that we effectively ignore this method call in the case where we're clearing out `m_elementUnderMouse` for a different Document than the one containing `m_hostElementForDataDetectors`, which prevents us from erroneously hiding data detectors when `m_elementUnderMouse` is removed or otherwise cleared out in a different Document. Canonical link: https://commits.webkit.org/238364@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278331 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-06-01 22:36:56 +00:00
WeakPtr<HTMLElement> m_hostElementForDataDetectors;
[macOS] Support painting data detector highlights inside image overlays https://bugs.webkit.org/show_bug.cgi?id=226227 Reviewed by Tim Horton. Add support for painting data detector highlights inside image overlays by leveraging `DataDetectorHighlight`. See comments below for more details. * SourcesCocoa.txt: * WebCore.xcodeproj/project.pbxproj: * editing/Editor.cpp: (WebCore::scanForTelephoneNumbers): Avoid painting service-controls-based telephone number highlights for selected text inside image overlays, in order to avoid painting a redundant data detector highlight for telephone numbers in image overlays. * html/HTMLElement.cpp: (WebCore::imageOverlayDataDetectorClassName): (WebCore::HTMLElement::isImageOverlayDataDetectorResult const): (WebCore::HTMLElement::updateWithImageExtractionResult): * html/HTMLElement.h: * html/shadow/imageOverlay.css: (div.image-overlay-data-detector-result): Add support for injecting elements in the DOM that represent data detection results; these are transformed and overlaid on the image in the same way as existing text containers. Note that we lay out these elements on top of text, but make them invisible to hit-testing unless the `IgnoreCSSPointerEventsProperty` option is specified. We'll take advantage of this behavior in a future patch. * page/ImageOverlayController.cpp: (WebCore::ImageOverlayController::selectionQuadsDidChange): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): (WebCore::ImageOverlayController::drawRect): (WebCore::ImageOverlayController::platformHandleMouseEvent): * page/ImageOverlayController.h: Refactor the image overlay controller, such that we install the page overlay if there is any selection inside the image overlay (as opposed to only when we need to use this overlay to paint the text selection for transparent images). If data detectors are present, we'll additionally set up out `DataDetectorHighlight`s (one for each data detection result container). * page/mac/ImageOverlayControllerMac.mm: Added. (WebCore::ImageOverlayController::updateDataDetectorHighlights): Traverse the image overlay's subtree in search of container elements that correspond to data detection results; for each of these elements, we create a new `DataDetectorHighlight` using the element's bounds, and save the pair in `m_dataDetectorContainersAndHighlights`. Note that we hold a weak pointer to the container element, such that there's no risk of leaking any of these data detection result containers (or their documents). (WebCore::ImageOverlayController::platformHandleMouseEvent): (WebCore::ImageOverlayController::handleDataDetectorAction): Add a FIXME referencing the next patch in the sequence. (WebCore::ImageOverlayController::clearDataDetectorHighlights): * platform/mac/DataDetectorHighlight.h: * platform/mac/DataDetectorHighlight.mm: (WebCore::DataDetectorHighlight::createForImageOverlay): Add a helper method to create a `DataDetectorHighlight` for image overlays. Canonical link: https://commits.webkit.org/238171@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@278121 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-05-26 20:06:32 +00:00
#endif
Allow some image overlay content to render in fully transparent image elements https://bugs.webkit.org/show_bug.cgi?id=223781 <rdar://problem/75886351> Reviewed by Tim Horton. Source/WebCore: Introduce `ImageOverlayController`, and use it to render selections in image overlay content when the image overlay's host element is fully transparent. Test: fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html * Sources.txt: * WebCore.xcodeproj/project.pbxproj: * dom/Document.cpp: (WebCore::Document::willBeRemovedFromFrame): Add plumbing to allow `ImageOverlayController` to uninstall its `PageOverlay` when the document is about to be detached. See `ImageOverlayController::` below. * editing/SelectionRectGatherer.cpp: (WebCore::SelectionRectGatherer::Notifier::~Notifier): Have `SelectionRectGatherer` notify the image overlay controller as well, when selection rects change. * page/ChromeClient.h: (WebCore::ChromeClient::needsImageOverlayControllerForSelectionPainting const): Add a new client hook that returns whether or not we should use `ImageOverlayController` to paint selections. If not (i.e. we're on iOS, where we use UIKit to draw selections in the UI process), then we'll never install page overlays, since `selectionRectsDidChange` is effectively a no-op. * page/ImageOverlayController.cpp: Added. (WebCore::ImageOverlayController::ImageOverlayController): (WebCore::ImageOverlayController::selectionRectsDidChange): When selection rects change, if the selection is inside an image overlay whose host is completely transparent (or very close to being completely transparent), then remember the selection rects along with the renderer's background color, and use this to render selection highlights separately, in a `PageOverlay`. (WebCore::ImageOverlayController::documentDetached): If the `Document` containing the current rendered overlay selection is detached, immediately uninstall the current `PageOverlay`. This ensures that the overlays don't persist through navigation. (WebCore::ImageOverlayController::installPageOverlayIfNeeded): (WebCore::ImageOverlayController::uninstallPageOverlayIfNeeded): Helper methods to add or remove the `PageOverlay` from the current `Page`. (WebCore::ImageOverlayController::willMoveToPage): Uninstall the current page overlay if needed. (WebCore::ImageOverlayController::drawRect): Use the information stored in `ImageOverlayController::selectionRectsDidChange` to render custom selection rects. * page/ImageOverlayController.h: Added. * page/Page.cpp: * page/Page.h: Add an `ImageOverlayController` to the `Page`. (WebCore::Page::imageOverlayController): Source/WebKit: Implement a new chrome client hook. See WebCore ChangeLog for more information. * WebProcess/WebCoreSupport/WebChromeClient.h: LayoutTests: Adjust an existing layout test so that it actually checks what it was intended to check; add a new layout test to cover the changes in this bug. * fast/images/image-extraction/mac/select-word-in-draggable-image-overlay.html: Drive-by fix: remove some extraneous imported scripts from this layout test, and additionally simplify the test so that it doesn't rely on event sender to select text. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay-expected-mismatch.html: Added. * fast/images/image-extraction/mac/select-word-in-transparent-image-overlay.html: Added. Add a new layout test with a fully transparent image element that covers a div of the same size, with a background image that is identical to the image element's image. This emulates the behavior of certain websites that prompted this fallback image overlay rendering codepath in the first place. Canonical link: https://commits.webkit.org/235820@main git-svn-id: https://svn.webkit.org/repository/webkit/trunk@275112 268f45cc-cd09-0410-ab3c-d52691b4dbfc
2021-03-26 21:23:17 +00:00
};
} // namespace WebCore