[iOS] Expose SPI to access the current sentence boundary and selection state
[WebKit-https.git] / Source / WebKit / WebProcess / WebPage / ios / WebPageIOS.mm
index c1502ac..c74a636 100644 (file)
 #import <WebCore/HTMLFormElement.h>
 #import <WebCore/HTMLImageElement.h>
 #import <WebCore/HTMLInputElement.h>
+#import <WebCore/HTMLLabelElement.h>
 #import <WebCore/HTMLOptGroupElement.h>
 #import <WebCore/HTMLOptionElement.h>
 #import <WebCore/HTMLParserIdioms.h>
 #import <WebCore/HTMLSelectElement.h>
+#import <WebCore/HTMLSummaryElement.h>
 #import <WebCore/HTMLTextAreaElement.h>
 #import <WebCore/HTMLTextFormControlElement.h>
 #import <WebCore/HistoryItem.h>
@@ -238,12 +240,13 @@ void WebPage::platformEditorState(Frame& frame, EditorState& result, IncludePost
         // FIXME: We should disallow replace when the string contains only CJ characters.
         postLayoutData.isReplaceAllowed = result.isContentEditable && !result.isInPasswordField && !selectedText.isAllSpecialCharacters<isHTMLSpace>();
     }
+    postLayoutData.atStartOfSentence = frame.selection().selectionAtSentenceStart();
     postLayoutData.insideFixedPosition = startNodeIsInsideFixedPosition || endNodeIsInsideFixedPosition;
     if (!selection.isNone()) {
         if (m_focusedElement && m_focusedElement->renderer()) {
-            postLayoutData.selectionClipRect = view->contentsToRootView(m_focusedElement->renderer()->absoluteBoundingBoxRect());
+            postLayoutData.focusedElementRect = view->contentsToRootView(m_focusedElement->renderer()->absoluteBoundingBoxRect());
             postLayoutData.caretColor = m_focusedElement->renderer()->style().caretColor();
-            postLayoutData.elementIsTransparent = m_focusedElement->renderer()->isTransparentRespectingParentFrames();
+            postLayoutData.elementIsTransparentOrFullyClipped = m_focusedElement->renderer()->isTransparentOrFullyClippedRespectingParentFrames();
         }
         computeEditableRootHasContentAndPlainText(selection, postLayoutData);
     }
@@ -725,7 +728,8 @@ void WebPage::sendTapHighlightForNodeIfNecessary(uint64_t requestID, Node* node)
         if (is<RenderBox>(*renderer))
             borderRadii = downcast<RenderBox>(*renderer).borderRadii();
 
-        send(Messages::WebPageProxy::DidGetTapHighlightGeometries(requestID, highlightColor, quads, roundedIntSize(borderRadii.topLeft()), roundedIntSize(borderRadii.topRight()), roundedIntSize(borderRadii.bottomLeft()), roundedIntSize(borderRadii.bottomRight())));
+        bool nodeHasBuiltInClickHandling = is<HTMLFormControlElement>(*node) || is<HTMLAnchorElement>(*node) || is<HTMLLabelElement>(*node) || is<HTMLSummaryElement>(*node) || node->isLink();
+        send(Messages::WebPageProxy::DidGetTapHighlightGeometries(requestID, highlightColor, quads, roundedIntSize(borderRadii.topLeft()), roundedIntSize(borderRadii.topRight()), roundedIntSize(borderRadii.bottomLeft()), roundedIntSize(borderRadii.bottomRight()), nodeHasBuiltInClickHandling));
     }
 #else
     UNUSED_PARAM(requestID);
@@ -1821,14 +1825,14 @@ void WebPage::replaceDictatedText(const String& oldText, const String& newText)
         position = position.previous();
     if (position.isNull())
         position = startOfDocument(static_cast<Node*>(frame.document()->documentElement()));
-    RefPtr<Range> range = Range::create(*frame.document(), position, frame.selection().selection().start());
+    auto range = Range::create(*frame.document(), position, frame.selection().selection().start());
 
-    if (plainTextReplacingNoBreakSpace(range.get()) != oldText)
+    if (plainTextReplacingNoBreakSpace(range.ptr()) != oldText)
         return;
 
     // We don't want to notify the client that the selection has changed until we are done inserting the new text.
     frame.editor().setIgnoreSelectionChanges(true);
-    frame.selection().setSelectedRange(range.get(), UPSTREAM, WebCore::FrameSelection::ShouldCloseTyping::Yes);
+    frame.selection().setSelectedRange(range.ptr(), UPSTREAM, WebCore::FrameSelection::ShouldCloseTyping::Yes);
     frame.editor().insertText(newText, 0);
     frame.editor().setIgnoreSelectionChanges(false);
 }
@@ -2137,17 +2141,15 @@ void WebPage::getPositionInformation(const InteractionInformationRequest& reques
                     }
 
                     if (request.includeLinkIndicator) {
-                        RefPtr<Range> linkRange = rangeOfContents(*linkElement);
-                        if (linkRange) {
-                            float deviceScaleFactor = corePage()->deviceScaleFactor();
-                            const float marginInPoints = 4;
+                        auto linkRange = rangeOfContents(*linkElement);
+                        float deviceScaleFactor = corePage()->deviceScaleFactor();
+                        const float marginInPoints = 4;
 
-                            RefPtr<TextIndicator> textIndicator = TextIndicator::createWithRange(*linkRange, TextIndicatorOptionTightlyFitContent | TextIndicatorOptionRespectTextColor | TextIndicatorOptionPaintBackgrounds | TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges |
-                                TextIndicatorOptionIncludeMarginIfRangeMatchesSelection, TextIndicatorPresentationTransition::None, FloatSize(marginInPoints * deviceScaleFactor, marginInPoints * deviceScaleFactor));
+                        auto textIndicator = TextIndicator::createWithRange(linkRange.get(), TextIndicatorOptionTightlyFitContent | TextIndicatorOptionRespectTextColor | TextIndicatorOptionPaintBackgrounds | TextIndicatorOptionUseBoundingRectAndPaintAllContentForComplexRanges |
+                            TextIndicatorOptionIncludeMarginIfRangeMatchesSelection, TextIndicatorPresentationTransition::None, FloatSize(marginInPoints * deviceScaleFactor, marginInPoints * deviceScaleFactor));
 
-                            if (textIndicator)
-                                info.linkIndicator = textIndicator->data();
-                        }
+                        if (textIndicator)
+                            info.linkIndicator = textIndicator->data();
                     }
 
 #if ENABLE(DATA_DETECTION)
@@ -2157,7 +2159,7 @@ void WebPage::getPositionInformation(const InteractionInformationRequest& reques
                         info.dataDetectorIdentifier = DataDetection::dataDetectorIdentifier(*element);
                         info.dataDetectorResults = element->document().frame()->dataDetectionResults();
                         if (DataDetection::requiresExtendedContext(*element)) {
-                            RefPtr<Range> linkRange = Range::create(element->document());
+                            auto linkRange = Range::create(element->document());
                             linkRange->selectNodeContents(*element);
                             info.textBefore = plainTextReplacingNoBreakSpace(rangeExpandedByCharactersInDirectionAtWordBoundary(linkRange->startPosition(), dataDetectionExtendedContextLength, DirectionBackward).get(), TextIteratorDefaultBehavior, true);
                             info.textAfter = plainTextReplacingNoBreakSpace(rangeExpandedByCharactersInDirectionAtWordBoundary(linkRange->endPosition(), dataDetectionExtendedContextLength, DirectionForward).get(), TextIteratorDefaultBehavior, true);
@@ -2182,7 +2184,7 @@ void WebPage::getPositionInformation(const InteractionInformationRequest& reques
                                     // FIXME: Only select ExtendedColor on images known to need wide gamut
                                     ShareableBitmap::Configuration bitmapConfiguration;
                                     bitmapConfiguration.colorSpace.cgColorSpace = screenColorSpace(m_page->mainFrame().view());
-                                    if (RefPtr<ShareableBitmap> sharedBitmap = ShareableBitmap::createShareable(IntSize(bitmapSize), bitmapConfiguration)) {
+                                    if (auto sharedBitmap = ShareableBitmap::createShareable(IntSize(bitmapSize), bitmapConfiguration)) {
                                         auto graphicsContext = sharedBitmap->createGraphicsContext();
                                         graphicsContext->drawImage(*image, FloatRect(0, 0, bitmapSize.width(), bitmapSize.height()));
                                         info.image = sharedBitmap;
@@ -2364,13 +2366,13 @@ void WebPage::getFocusedElementInformation(FocusedElementInformation& informatio
 {
     layoutIfNeeded();
 
-    information.elementInteractionLocation = m_lastInteractionLocation;
+    information.lastInteractionLocation = m_lastInteractionLocation;
 
     if (auto* renderer = m_focusedElement->renderer()) {
         auto& elementFrame = m_page->focusController().focusedOrMainFrame();
         information.elementRect = elementRectInRootViewCoordinates(*m_focusedElement, elementFrame);
         information.nodeFontSize = renderer->style().fontDescription().computedSize();
-        information.elementIsTransparent = renderer->isTransparentRespectingParentFrames();
+        information.elementIsTransparentOrFullyClipped = renderer->isTransparentOrFullyClippedRespectingParentFrames();
 
         bool inFixed = false;
         renderer->localToContainerPoint(FloatPoint(), nullptr, UseTransforms, &inFixed);
@@ -2383,13 +2385,6 @@ void WebPage::getFocusedElementInformation(FocusedElementInformation& informatio
             frameView->setCustomFixedPositionLayoutRect(frameView->renderView()->documentRect());
             information.elementRect = frameView->contentsToRootView(renderer->absoluteBoundingBoxRect());
             frameView->setCustomFixedPositionLayoutRect(currentFixedPositionRect);
-            
-            if (!information.elementRect.contains(m_lastInteractionLocation))
-                information.elementInteractionLocation = information.elementRect.location();
-        } else {
-            // Don't use the selection rect if interaction was outside the element rect.
-            if (!information.elementRect.contains(m_lastInteractionLocation))
-                information.elementInteractionLocation = { };
         }
     } else
         information.elementRect = IntRect();
@@ -2988,7 +2983,7 @@ void WebPage::updateVisibleContentRects(const VisibleContentRectUpdateInfo& visi
             m_oldestNonStableUpdateVisibleContentRectsTimestamp = oldestTimestamp;
     }
 
-    float scaleToUse = scaleFromUIProcess.value_or(m_page->pageScaleFactor());
+    float scaleToUse = scaleFromUIProcess.valueOr(m_page->pageScaleFactor());
     FloatRect exposedContentRect = visibleContentRectUpdateInfo.exposedContentRect();
     FloatRect adjustedExposedContentRect = adjustExposedRectForNewScale(exposedContentRect, visibleContentRectUpdateInfo.scale(), scaleToUse);
     m_drawingArea->setExposedContentRect(adjustedExposedContentRect);
@@ -3127,6 +3122,11 @@ void WebPage::hardwareKeyboardAvailabilityChanged()
         focusedFrame->eventHandler().capsLockStateMayHaveChanged();
 }
 
+void WebPage::updateStringForFind(const String& findString)
+{
+    send(Messages::WebPageProxy::UpdateStringForFind(findString));
+}
+
 #if USE(QUICK_LOOK)
 void WebPage::didReceivePasswordForQuickLookDocument(const String& password)
 {