Diff
Modified: trunk/Source/WebCore/ChangeLog (251599 => 251600)
--- trunk/Source/WebCore/ChangeLog 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebCore/ChangeLog 2019-10-25 20:41:15 UTC (rev 251600)
@@ -1,3 +1,43 @@
+2019-10-24 Ryosuke Niwa <rn...@webkit.org>
+
+ Add exclusion rules to text manipulation SPI
+ https://bugs.webkit.org/show_bug.cgi?id=203398
+ <rdar://problem/56567256>
+
+ Reviewed by Wenson Hsieh.
+
+ This patch adds the ability to define a ordered set of rules to exclude or include content an element of
+ a certain name or one with a certain attribute value.
+
+ Also made completeManipulation return more detailed errors for debugging purposes.
+
+ Tests: TextManipulation.StartTextManipulationApplySingleExcluionRuleForElement
+ TextManipulation.StartTextManipulationApplyInclusionExclusionRulesForAttributes
+ TextManipulation.CompleteTextManipulationFailWhenExclusionIsViolated
+
+ * editing/TextManipulationController.cpp:
+ (WebCore::TextManipulationController::ExclusionRule::match const): Added.
+ (WebCore::ExclusionRuleMatcher): Added. This class is responsible for figuring out whether a given node
+ is excluded or included in the text manipulation.
+ (WebCore::ExclusionRuleMatcher::ExclusionRuleMatcher): Added.
+ (WebCore::ExclusionRuleMatcher::isExcluded): Added.
+ (WebCore::ExclusionRuleMatcher::typeForElement): Added.
+ (WebCore::TextManipulationController::startObservingParagraphs): Added a Vector of ExclusionRule as
+ an argument.
+ (WebCore::TextManipulationController::completeManipulation):
+ (WebCore::TextManipulationController::replace):
+ * editing/TextManipulationController.h:
+ (WebCore::TextManipulationController::ExclusionRule): Added.
+ (WebCore::TextManipulationController::ManipulationResult): Added.
+ (WebCore::TextManipulationController::ManipulationToken::encode const): Include isExcluded boolean.
+ (WebCore::TextManipulationController::ManipulationToken::decode): Ditto.
+ (WebCore::TextManipulationController::ExclusionRule::encode const): Added.
+ (WebCore::TextManipulationController::ExclusionRule::decode): Added.
+ (WebCore::TextManipulationController::ExclusionRule::ElementRule::encode const): Added.
+ (WebCore::TextManipulationController::ExclusionRule::ElementRule::decode): Added.
+ (WebCore::TextManipulationController::ExclusionRule::AttributeRule::encode const): Added.
+ (WebCore::TextManipulationController::ExclusionRule::AttributeRule::decode): Added.
+
2019-10-25 Simon Fraser <simon.fra...@apple.com>
Move code around in CSSCalculationValue.cpp
Modified: trunk/Source/WebCore/editing/TextManipulationController.cpp (251599 => 251600)
--- trunk/Source/WebCore/editing/TextManipulationController.cpp 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebCore/editing/TextManipulationController.cpp 2019-10-25 20:41:15 UTC (rev 251600)
@@ -26,7 +26,9 @@
#include "config.h"
#include "TextManipulationController.h"
+#include "CharacterData.h"
#include "Editing.h"
+#include "ElementAncestorIterator.h"
#include "ScriptDisallowedScope.h"
#include "TextIterator.h"
#include "VisibleUnits.h"
@@ -33,12 +35,77 @@
namespace WebCore {
+inline bool TextManipulationController::ExclusionRule::match(const Element& element) const
+{
+ return switchOn(rule, [&element] (ElementRule rule) {
+ return rule.localName == element.localName();
+ }, [&element] (AttributeRule rule) {
+ return equalIgnoringASCIICase(element.getAttribute(rule.name), rule.value);
+ });
+}
+
+class ExclusionRuleMatcher {
+public:
+ using ExclusionRule = TextManipulationController::ExclusionRule;
+ using Type = TextManipulationController::ExclusionRule::Type;
+
+ ExclusionRuleMatcher(const Vector<ExclusionRule>& rules)
+ : m_rules(rules)
+ { }
+
+ bool isExcluded(Node* node)
+ {
+ if (!node)
+ return false;
+
+ RefPtr<Element> startingElement = is<Element>(*node) ? downcast<Element>(node) : node->parentElement();
+ if (!startingElement)
+ return false;
+
+ Type type = Type::Include;
+ RefPtr<Element> matchingElement;
+ for (auto& element : elementLineage(startingElement.get())) {
+ if (auto typeOrNullopt = typeForElement(element)) {
+ type = *typeOrNullopt;
+ matchingElement = &element;
+ break;
+ }
+ }
+
+ for (auto& element : elementLineage(startingElement.get())) {
+ m_cache.set(element, type);
+ if (&element == matchingElement)
+ break;
+ }
+
+ return type == Type::Exclude;
+ }
+
+ Optional<Type> typeForElement(Element& element)
+ {
+ auto it = m_cache.find(element);
+ if (it != m_cache.end())
+ return it->value;
+
+ for (auto& rule : m_rules) {
+ if (rule.match(element))
+ return rule.type;
+ }
+
+ return WTF::nullopt;
+ }
+
+private:
+ const Vector<ExclusionRule>& m_rules;
+ HashMap<Ref<Element>, ExclusionRule::Type> m_cache;
+};
+
TextManipulationController::TextManipulationController(Document& document)
: m_document(makeWeakPtr(document))
{
}
-void TextManipulationController::startObservingParagraphs(ManipulationItemCallback&& callback)
+void TextManipulationController::startObservingParagraphs(ManipulationItemCallback&& callback, Vector<ExclusionRule>&& exclusionRules)
{
auto document = makeRefPtr(m_document.get());
if (!document)
@@ -45,6 +112,7 @@
return;
m_callback = WTFMove(callback);
+ m_exclusionRules = WTFMove(exclusionRules);
VisiblePosition start = firstPositionInNode(m_document.get());
VisiblePosition end = lastPositionInNode(m_document.get());
@@ -52,6 +120,7 @@
if (!document)
return; // VisiblePosition or TextIterator's constructor may have updated the layout and executed arbitrary scripts.
+ ExclusionRuleMatcher exclusionRuleMatcher(m_exclusionRules);
Vector<ManipulationToken> tokensInCurrentParagraph;
Position startOfCurrentParagraph = start.deepEquivalent();
while (!iterator.atEnd()) {
@@ -64,8 +133,8 @@
size_t offsetOfNextNewLine = 0;
while ((offsetOfNextNewLine = currentText.find('\n', endOfLastNewLine)) != notFound) {
if (endOfLastNewLine < offsetOfNextNewLine) {
- tokensInCurrentParagraph.append(ManipulationToken { m_tokenIdentifier.generate(),
- currentText.substring(endOfLastNewLine, offsetOfNextNewLine - endOfLastNewLine).toString() });
+ auto stringUntilEndOfLine = currentText.substring(endOfLastNewLine, offsetOfNextNewLine - endOfLastNewLine).toString();
+ tokensInCurrentParagraph.append(ManipulationToken { m_tokenIdentifier.generate(), stringUntilEndOfLine, exclusionRuleMatcher.isExcluded(iterator.node()) });
}
auto lastRange = iterator.range();
@@ -83,7 +152,7 @@
auto remainingText = currentText.substring(endOfLastNewLine);
if (remainingText.length())
- tokensInCurrentParagraph.append(ManipulationToken { m_tokenIdentifier.generate(), remainingText.toString() });
+ tokensInCurrentParagraph.append(ManipulationToken { m_tokenIdentifier.generate(), remainingText.toString(), exclusionRuleMatcher.isExcluded(iterator.node()) });
iterator.advance();
}
@@ -99,14 +168,14 @@
m_callback(*m_document, result.iterator->key, result.iterator->value.tokens);
}
-bool TextManipulationController::completeManipulation(ItemIdentifier itemIdentifier, const Vector<ManipulationToken>& replacementTokens)
+auto TextManipulationController::completeManipulation(ItemIdentifier itemIdentifier, const Vector<ManipulationToken>& replacementTokens) -> ManipulationResult
{
if (!itemIdentifier)
- return false;
+ return ManipulationResult::InvalidItem;
auto itemIterator = m_items.find(itemIdentifier);
if (itemIterator == m_items.end())
- return false;
+ return ManipulationResult::InvalidItem;
auto didReplace = replace(itemIterator->value, replacementTokens);
@@ -115,35 +184,48 @@
return didReplace;
}
-bool TextManipulationController::replace(const ManipulationItem& item, const Vector<ManipulationToken>& replacementTokens)
+struct DOMChange {
+ Ref<CharacterData> node;
+ String newData;
+};
+
+auto TextManipulationController::replace(const ManipulationItem& item, const Vector<ManipulationToken>& replacementTokens) -> ManipulationResult
{
TextIterator iterator { item.start, item.end };
size_t currentTokenIndex = 0;
- HashMap<TokenIdentifier, Ref<Node>> tokenToNode;
+ HashMap<TokenIdentifier, std::pair<RefPtr<Node>, const ManipulationToken*>> tokenToNodeTokenPair;
+
while (!iterator.atEnd()) {
auto string = iterator.text().toString();
if (currentTokenIndex >= item.tokens.size())
- return false;
+ return ManipulationResult::ContentChanged;
auto& currentToken = item.tokens[currentTokenIndex];
if (iterator.text() != currentToken.content)
- return false;
- tokenToNode.add(currentToken.identifier, *iterator.node());
+ return ManipulationResult::ContentChanged;
+ tokenToNodeTokenPair.set(currentToken.identifier, std::pair<RefPtr<Node>, const ManipulationToken*> { iterator.node(), ¤tToken });
iterator.advance();
++currentTokenIndex;
}
// FIXME: This doesn't preseve the order of the replacement at all.
- for (auto& token : replacementTokens) {
- auto* node = tokenToNode.get(token.identifier);
- if (!node)
- return false;
- if (!is<CharacterData>(node))
+ Vector<DOMChange> changes;
+ for (auto& newToken : replacementTokens) {
+ auto it = tokenToNodeTokenPair.find(newToken.identifier);
+ if (it == tokenToNodeTokenPair.end())
+ return ManipulationResult::InvalidToken;
+ auto& oldToken = *it->value.second;
+ if (oldToken.isExcluded)
+ return ManipulationResult::ExclusionViolation;
+ auto* node = it->value.first.get();
+ if (!node || !is<CharacterData>(*node))
continue;
- // FIXME: It's not safe to update DOM while iterating over the tokens.
- downcast<CharacterData>(node)->setData(token.content);
+ changes.append({ downcast<CharacterData>(*node), newToken.content });
}
- return true;
+ for (auto& change : changes)
+ change.node->setData(change.newData);
+
+ return ManipulationResult::Success;
}
} // namespace WebCore
Modified: trunk/Source/WebCore/editing/TextManipulationController.h (251599 => 251600)
--- trunk/Source/WebCore/editing/TextManipulationController.h 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebCore/editing/TextManipulationController.h 2019-10-25 20:41:15 UTC (rev 251600)
@@ -27,6 +27,7 @@
#include "Position.h"
#include <wtf/CompletionHandler.h>
+#include <wtf/EnumTraits.h>
#include <wtf/ObjectIdentifier.h>
#include <wtf/Optional.h>
#include <wtf/WeakPtr.h>
@@ -46,6 +47,7 @@
struct ManipulationToken {
TokenIdentifier identifier;
String content;
+ bool isExcluded { false };
template<class Encoder> void encode(Encoder&) const;
template<class Decoder> static Optional<ManipulationToken> decode(Decoder&);
@@ -54,10 +56,44 @@
enum ItemIdentifierType { };
using ItemIdentifier = ObjectIdentifier<ItemIdentifierType>;
+ struct ExclusionRule {
+ enum class Type : uint8_t { Exclude, Include };
+
+ struct ElementRule {
+ AtomString localName;
+
+ template<class Encoder> void encode(Encoder&) const;
+ template<class Decoder> static Optional<ElementRule> decode(Decoder&);
+ };
+
+ struct AttributeRule {
+ AtomString name;
+ String value;
+
+ template<class Encoder> void encode(Encoder&) const;
+ template<class Decoder> static Optional<AttributeRule> decode(Decoder&);
+ };
+
+ Type type;
+ WTF::Variant<ElementRule, AttributeRule> rule;
+
+ bool match(const Element&) const;
+
+ template<class Encoder> void encode(Encoder&) const;
+ template<class Decoder> static Optional<ExclusionRule> decode(Decoder&);
+ };
+
using ManipulationItemCallback = WTF::Function<void(Document&, ItemIdentifier, const Vector<ManipulationToken>&)>;
- WEBCORE_EXPORT void startObservingParagraphs(ManipulationItemCallback&&);
+ WEBCORE_EXPORT void startObservingParagraphs(ManipulationItemCallback&&, Vector<ExclusionRule>&& = { });
- WEBCORE_EXPORT bool completeManipulation(ItemIdentifier, const Vector<ManipulationToken>&);
+ enum class ManipulationResult : uint8_t {
+ Success,
+ ContentChanged,
+ InvalidItem,
+ InvalidToken,
+ ExclusionViolation,
+ };
+ WEBCORE_EXPORT ManipulationResult completeManipulation(ItemIdentifier, const Vector<ManipulationToken>&);
private:
struct ManipulationItem {
@@ -67,10 +103,11 @@
};
void addItem(const Position& startOfParagraph, const Position& endOfParagraph, Vector<ManipulationToken>&&);
- bool replace(const ManipulationItem&, const Vector<ManipulationToken>&);
+ ManipulationResult replace(const ManipulationItem&, const Vector<ManipulationToken>&);
WeakPtr<Document> m_document;
ManipulationItemCallback m_callback;
+ Vector<ExclusionRule> m_exclusionRules;
HashMap<ItemIdentifier, ManipulationItem> m_items;
ItemIdentifier m_itemIdentifier;
TokenIdentifier m_tokenIdentifier;
@@ -79,7 +116,7 @@
template<class Encoder>
void TextManipulationController::ManipulationToken::encode(Encoder& encoder) const
{
- encoder << identifier << content;
+ encoder << identifier << content << isExcluded;
}
template<class Decoder>
@@ -90,7 +127,83 @@
return WTF::nullopt;
if (!decoder.decode(result.content))
return WTF::nullopt;
+ if (!decoder.decode(result.isExcluded))
+ return WTF::nullopt;
return result;
}
+template<class Encoder>
+void TextManipulationController::ExclusionRule::encode(Encoder& encoder) const
+{
+ encoder << type << rule;
+}
+
+template<class Decoder>
+Optional<TextManipulationController::ExclusionRule> TextManipulationController::ExclusionRule::decode(Decoder& decoder)
+{
+ ExclusionRule result;
+ if (!decoder.decode(result.type))
+ return WTF::nullopt;
+ if (!decoder.decode(result.rule))
+ return WTF::nullopt;
+ return result;
+}
+
+template<class Encoder>
+void TextManipulationController::ExclusionRule::ElementRule::encode(Encoder& encoder) const
+{
+ encoder << localName;
+}
+
+template<class Decoder>
+Optional<TextManipulationController::ExclusionRule::ElementRule> TextManipulationController::ExclusionRule::ElementRule::decode(Decoder& decoder)
+{
+ ElementRule result;
+ if (!decoder.decode(result.localName))
+ return WTF::nullopt;
+ return result;
+}
+
+template<class Encoder>
+void TextManipulationController::ExclusionRule::AttributeRule::encode(Encoder& encoder) const
+{
+ encoder << name << value;
+}
+
+template<class Decoder>
+Optional<TextManipulationController::ExclusionRule::AttributeRule> TextManipulationController::ExclusionRule::AttributeRule::decode(Decoder& decoder)
+{
+ AttributeRule result;
+ if (!decoder.decode(result.name))
+ return WTF::nullopt;
+ if (!decoder.decode(result.value))
+ return WTF::nullopt;
+ return result;
+}
+
} // namespace WebCore
+
+namespace WTF {
+
+template<> struct EnumTraits<WebCore::TextManipulationController::ExclusionRule::Type> {
+ using ExclusionRule = WebCore::TextManipulationController::ExclusionRule;
+ using values = EnumValues<
+ ExclusionRule::Type,
+ ExclusionRule::Type::Include,
+ ExclusionRule::Type::Exclude
+ >;
+};
+
+template<> struct EnumTraits<WebCore::TextManipulationController::ManipulationResult> {
+ using ManipulationResult = WebCore::TextManipulationController::ManipulationResult;
+ using values = EnumValues<
+ ManipulationResult,
+ ManipulationResult::Success,
+ ManipulationResult::ContentChanged,
+ ManipulationResult::InvalidItem,
+ ManipulationResult::InvalidToken,
+ ManipulationResult::ExclusionViolation
+ >;
+};
+
+} // namespace WTF
Modified: trunk/Source/WebKit/ChangeLog (251599 => 251600)
--- trunk/Source/WebKit/ChangeLog 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebKit/ChangeLog 2019-10-25 20:41:15 UTC (rev 251600)
@@ -1,3 +1,45 @@
+2019-10-24 Ryosuke Niwa <rn...@webkit.org>
+
+ Add exclusion rules to text manipulation SPI
+ https://bugs.webkit.org/show_bug.cgi?id=203398
+ <rdar://problem/56567256>
+
+ Reviewed by Wenson Hsieh.
+
+ Added SPI to specify the configuration for the text manipulation (see r251574), in particular, the set of rules
+ governing which content should be excluded or included in text manipulations.
+
+ Test: TextManipulation.StartTextManipulationExitEarlyWithoutDelegate
+
+ * SourcesCocoa.txt:
+ * UIProcess/API/Cocoa/WKWebView.mm:
+ (-[WKWebView _startTextManipulationsWithConfiguration:completion:]): Takes _WKTextManipulationConfiguration
+ as an argument. Also fixed a bug that we weren't calling the completion handler when the delegate was not set.
+ (-[WKWebView _completeTextManipulation:completion:]):
+ (-[WKWebView _startTextManipulationsWithCompletionHandler:]): Deleted.
+ * UIProcess/API/Cocoa/WKWebViewPrivate.h:
+ * UIProcess/API/Cocoa/_WKTextManipulationConfiguration.h: Added.
+ * UIProcess/API/Cocoa/_WKTextManipulationConfiguration.mm: Added.
+ * UIProcess/API/Cocoa/_WKTextManipulationExclusionRule.h: Added.
+ * UIProcess/API/Cocoa/_WKTextManipulationExclusionRule.mm: Added.
+ (-[_WKTextManipulationExclusionRule initExclusion:forElement:]): Added.
+ (-[_WKTextManipulationExclusionRule initExclusion:forAttribute:value:]): Added.
+ (-[_WKTextManipulationExclusionRule elementName]): Added.
+ (-[_WKTextManipulationExclusionRule attributeName]): Added.
+ (-[_WKTextManipulationExclusionRule attributeValue]): Added.
+ * UIProcess/API/Cocoa/_WKTextManipulationToken.h: Added excluded boolean property.
+ * UIProcess/API/Cocoa/_WKTextManipulationToken.mm: Removed the superflous import of RetainPtr.h
+ * UIProcess/WebPageProxy.cpp:
+ (WebKit::WebPageProxy::startTextManipulations):
+ (WebKit::WebPageProxy::completeTextManipulation):
+ * UIProcess/WebPageProxy.h:
+ * WebKit.xcodeproj/project.pbxproj:
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::startTextManipulations):
+ (WebKit::WebPage::completeTextManipulation):
+ * WebProcess/WebPage/WebPage.h:
+ * WebProcess/WebPage/WebPage.messages.in:
+
2019-10-25 Chris Dumez <cdu...@apple.com>
[iOS][WK2] Use sendWithAsyncReply() to simplify the prepareToSuspend logic
Modified: trunk/Source/WebKit/SourcesCocoa.txt (251599 => 251600)
--- trunk/Source/WebKit/SourcesCocoa.txt 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebKit/SourcesCocoa.txt 2019-10-25 20:41:15 UTC (rev 251600)
@@ -260,6 +260,8 @@
UIProcess/API/Cocoa/_WKRemoteWebInspectorViewController.mm
UIProcess/API/Cocoa/_WKSessionState.mm
UIProcess/API/Cocoa/_WKTextInputContext.mm
+UIProcess/API/Cocoa/_WKTextManipulationConfiguration.mm
+UIProcess/API/Cocoa/_WKTextManipulationExclusionRule.mm
UIProcess/API/Cocoa/_WKTextManipulationItem.mm
UIProcess/API/Cocoa/_WKTextManipulationToken.mm
UIProcess/API/Cocoa/_WKThumbnailView.mm
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm (251599 => 251600)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebView.mm 2019-10-25 20:41:15 UTC (rev 251600)
@@ -99,7 +99,9 @@
#import "_WKRemoteObjectRegistryInternal.h"
#import "_WKSessionStateInternal.h"
#import "_WKTextInputContextInternal.h"
+#import "_WKTextManipulationConfiguration.h"
#import "_WKTextManipulationDelegate.h"
+#import "_WKTextManipulationExclusionRule.h"
#import "_WKTextManipulationItem.h"
#import "_WKTextManipulationToken.h"
#import "_WKVisitedLinkStoreInternal.h"
@@ -7477,13 +7479,27 @@
_textManipulationDelegate = delegate;
}
-- (void)_startTextManipulationsWithCompletionHandler:(void(^)())completionHandler
+- (void)_startTextManipulationsWithConfiguration:(_WKTextManipulationConfiguration *)configuration completion:(void(^)())completionHandler
{
- if (!_textManipulationDelegate)
+ using ExclusionRule = WebCore::TextManipulationController::ExclusionRule;
+
+ if (!_textManipulationDelegate || !_page) {
+ completionHandler();
return;
- if (!_page)
- return;
- _page->startTextManipulations([weakSelf = WeakObjCPtr<WKWebView>(self)] (WebCore::TextManipulationController::ItemIdentifier itemID,
+ }
+
+ Vector<WebCore::TextManipulationController::ExclusionRule> exclusionRules;
+ if (configuration) {
+ for (_WKTextManipulationExclusionRule *wkRule in configuration.exclusionRules) {
+ auto type = wkRule.isExclusion ? ExclusionRule::Type::Exclude : ExclusionRule::Type::Include;
+ if (wkRule.attributeName)
+ exclusionRules.append({type, ExclusionRule::AttributeRule { wkRule.attributeName, wkRule.attributeValue } });
+ else
+ exclusionRules.append({type, ExclusionRule::ElementRule { wkRule.elementName } });
+ }
+ }
+
+ _page->startTextManipulations(exclusionRules, [weakSelf = WeakObjCPtr<WKWebView>(self)] (WebCore::TextManipulationController::ItemIdentifier itemID,
const Vector<WebCore::TextManipulationController::ManipulationToken>& tokens) {
if (!weakSelf)
return;
@@ -7498,6 +7514,7 @@
auto wkToken = adoptNS([[_WKTextManipulationToken alloc] init]);
[wkToken setIdentifier:String::number(token.identifier.toUInt64())];
[wkToken setContent:token.content];
+ [wkToken setExcluded:token.isExcluded];
[wkTokens addObject:wkToken.get()];
}
@@ -7510,6 +7527,8 @@
- (void)_completeTextManipulation:(_WKTextManipulationItem *)item completion:(void(^)(BOOL success))completionHandler
{
+ using ManipulationResult = WebCore::TextManipulationController::ManipulationResult;
+
if (!_page)
return;
@@ -7521,8 +7540,8 @@
tokens.append(WebCore::TextManipulationController::ManipulationToken { tokenID, wkToken.content });
}
- _page->completeTextManipulation(itemID, tokens, [capturedCompletionBlock = makeBlockPtr(completionHandler)] (bool success) {
- capturedCompletionBlock(success);
+ _page->completeTextManipulation(itemID, tokens, [capturedCompletionBlock = makeBlockPtr(completionHandler)] (ManipulationResult result) {
+ capturedCompletionBlock(result == ManipulationResult::Success);
});
}
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h (251599 => 251600)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/WKWebViewPrivate.h 2019-10-25 20:41:15 UTC (rev 251600)
@@ -113,6 +113,7 @@
@class _WKSafeBrowsingWarning;
@class _WKSessionState;
@class _WKTextInputContext;
+@class _WKTextManipulationConfiguration;
@class _WKTextManipulationItem;
@class _WKThumbnailView;
@class _WKWebsitePolicies;
@@ -578,7 +579,7 @@
@property (nonatomic, readonly) _WKFrameHandle *_mainFrame WK_API_AVAILABLE(macos(10.14.4), ios(12.2));
@property (nonatomic, weak, setter=_setTextManipulationDelegate:) id <_WKTextManipulationDelegate> _textManipulationDelegate WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
-- (void)_startTextManipulationsWithCompletionHandler:(void(^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
+- (void)_startTextManipulationsWithConfiguration:(_WKTextManipulationConfiguration *)snapshotConfiguration completion:(void(^)(void))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
- (void)_completeTextManipulation:(_WKTextManipulationItem *)item completion:(void(^)(BOOL success))completionHandler WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
@property (nonatomic, setter=_setScrollingUpdatesDisabledForTesting:) BOOL _scrollingUpdatesDisabledForTesting WK_API_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA));
Added: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationConfiguration.h (0 => 251600)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationConfiguration.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationConfiguration.h 2019-10-25 20:41:15 UTC (rev 251600)
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#import <WebKit/WKFoundation.h>
+
+#import <Foundation/Foundation.h>
+
+@class _WKTextManipulationExclusionRule;
+
+WK_CLASS_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA))
+@interface _WKTextManipulationConfiguration : NSObject
+
+@property (nonatomic, copy) NSArray<_WKTextManipulationExclusionRule *> *exclusionRules;
+
+@end
Added: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationConfiguration.mm (0 => 251600)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationConfiguration.mm (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationConfiguration.mm 2019-10-25 20:41:15 UTC (rev 251600)
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#import "config.h"
+#import "_WKTextManipulationConfiguration.h"
+
+@implementation _WKTextManipulationConfiguration
+@end
+
Added: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationExclusionRule.h (0 => 251600)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationExclusionRule.h (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationExclusionRule.h 2019-10-25 20:41:15 UTC (rev 251600)
@@ -0,0 +1,42 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#import <WebKit/WKFoundation.h>
+
+#import <Foundation/Foundation.h>
+
+WK_CLASS_AVAILABLE(macos(WK_MAC_TBA), ios(WK_IOS_TBA))
+@interface _WKTextManipulationExclusionRule : NSObject
+
+- (instancetype)init NS_UNAVAILABLE;
+- (instancetype)initExclusion:(BOOL)exclusion forElement:(NSString *)localName;
+- (instancetype)initExclusion:(BOOL)exclusion forAttribute:(NSString *)name value:(NSString *)value;
+
+@property (nonatomic, readonly) BOOL isExclusion;
+@property (nonatomic, readonly) NSString *elementName;
+@property (nonatomic, readonly) NSString *attributeName;
+@property (nonatomic, readonly) NSString *attributeValue;
+
+@end
Added: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationExclusionRule.mm (0 => 251600)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationExclusionRule.mm (rev 0)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationExclusionRule.mm 2019-10-25 20:41:15 UTC (rev 251600)
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2019 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.
+ */
+
+#import "config.h"
+#import "_WKTextManipulationExclusionRule.h"
+
+#include <wtf/RetainPtr.h>
+
+@implementation _WKTextManipulationExclusionRule {
+ BOOL _isExclusion;
+ RetainPtr<NSString> _elementName;
+ RetainPtr<NSString> _attributeName;
+ RetainPtr<NSString> _attributeValue;
+}
+
+- (instancetype)initExclusion:(BOOL)exclusion forElement:(NSString *)localName
+{
+ if (!(self = [super init]))
+ return nil;
+
+ _isExclusion = exclusion;
+ _elementName = localName;
+
+ return self;
+}
+
+- (instancetype)initExclusion:(BOOL)exclusion forAttribute:(NSString *)name value:(NSString *)value
+{
+ if (!(self = [super init]))
+ return nil;
+
+ _isExclusion = exclusion;
+ _attributeName = name;
+ _attributeValue = value;
+
+ return self;
+}
+
+- (NSString *)elementName
+{
+ return _elementName.get();
+}
+
+- (NSString *)attributeName
+{
+ return _attributeName.get();
+}
+
+- (NSString *)attributeValue
+{
+ return _attributeValue.get();
+}
+
+@end
+
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.h (251599 => 251600)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.h 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.h 2019-10-25 20:41:15 UTC (rev 251600)
@@ -32,5 +32,6 @@
@property (nonatomic, copy) NSString *identifier;
@property (nonatomic, copy) NSString *content;
+@property (nonatomic, getter=isExcluded) BOOL excluded;
@end
Modified: trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.mm (251599 => 251600)
--- trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.mm 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebKit/UIProcess/API/Cocoa/_WKTextManipulationToken.mm 2019-10-25 20:41:15 UTC (rev 251600)
@@ -26,7 +26,5 @@
#import "config.h"
#import "_WKTextManipulationToken.h"
-#import <wtf/RetainPtr.h>
-
@implementation _WKTextManipulationToken
@end
Modified: trunk/Source/WebKit/UIProcess/Cocoa/SOAuthorization/RedirectSOAuthorizationSession.mm (251599 => 251600)
--- trunk/Source/WebKit/UIProcess/Cocoa/SOAuthorization/RedirectSOAuthorizationSession.mm 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebKit/UIProcess/Cocoa/SOAuthorization/RedirectSOAuthorizationSession.mm 2019-10-25 20:41:15 UTC (rev 251600)
@@ -28,7 +28,9 @@
#if HAVE(APP_SSO)
+#import "APINavigationAction.h"
#import "DataReference.h"
+#import "WebPageProxy.h"
#import <WebCore/ResourceResponse.h>
namespace WebKit {
Modified: trunk/Source/WebKit/UIProcess/Cocoa/SOAuthorization/SOAuthorizationCoordinator.mm (251599 => 251600)
--- trunk/Source/WebKit/UIProcess/Cocoa/SOAuthorization/SOAuthorizationCoordinator.mm 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebKit/UIProcess/Cocoa/SOAuthorization/SOAuthorizationCoordinator.mm 2019-10-25 20:41:15 UTC (rev 251600)
@@ -29,6 +29,7 @@
#if HAVE(APP_SSO)
#import "APIFrameHandle.h"
+#import "APINavigationAction.h"
#import "PopUpSOAuthorizationSession.h"
#import "RedirectSOAuthorizationSession.h"
#import "SubFrameSOAuthorizationSession.h"
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.cpp (251599 => 251600)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.cpp 2019-10-25 20:41:15 UTC (rev 251600)
@@ -9419,7 +9419,8 @@
}
#endif
-void WebPageProxy::startTextManipulations(TextManipulationItemCallback&& callback, WTF::CompletionHandler<void()>&& completionHandler)
+void WebPageProxy::startTextManipulations(const Vector<WebCore::TextManipulationController::ExclusionRule>& exclusionRules,
+ TextManipulationItemCallback&& callback, WTF::CompletionHandler<void()>&& completionHandler)
{
if (!hasRunningProcess()) {
completionHandler();
@@ -9426,7 +9427,7 @@
return;
}
m_textManipulationItemCallback = WTFMove(callback);
- m_process->connection()->sendWithAsyncReply(Messages::WebPage::StartTextManipulations(), WTFMove(completionHandler), m_webPageID);
+ m_process->connection()->sendWithAsyncReply(Messages::WebPage::StartTextManipulations(exclusionRules), WTFMove(completionHandler), m_webPageID);
}
void WebPageProxy::didFindTextManipulationItem(WebCore::TextManipulationController::ItemIdentifier itemID,
@@ -9438,10 +9439,10 @@
}
void WebPageProxy::completeTextManipulation(WebCore::TextManipulationController::ItemIdentifier itemID,
- const Vector<WebCore::TextManipulationController::ManipulationToken>& tokens, WTF::Function<void (bool success)>&& completionHandler)
+ const Vector<WebCore::TextManipulationController::ManipulationToken>& tokens, WTF::Function<void (WebCore::TextManipulationController::ManipulationResult result)>&& completionHandler)
{
if (!hasRunningProcess()) {
- completionHandler(false);
+ completionHandler(WebCore::TextManipulationController::ManipulationResult::InvalidItem);
return;
}
m_process->connection()->sendWithAsyncReply(Messages::WebPage::CompleteTextManipulation(itemID, tokens), WTFMove(completionHandler), m_webPageID);
Modified: trunk/Source/WebKit/UIProcess/WebPageProxy.h (251599 => 251600)
--- trunk/Source/WebKit/UIProcess/WebPageProxy.h 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebKit/UIProcess/WebPageProxy.h 2019-10-25 20:41:15 UTC (rev 251600)
@@ -1614,10 +1614,10 @@
#endif
using TextManipulationItemCallback = WTF::Function<void (WebCore::TextManipulationController::ItemIdentifier, const Vector<WebCore::TextManipulationController::ManipulationToken>&)>;
- void startTextManipulations(TextManipulationItemCallback&&, WTF::CompletionHandler<void()>&&);
+ void startTextManipulations(const Vector<WebCore::TextManipulationController::ExclusionRule>&, TextManipulationItemCallback&&, WTF::CompletionHandler<void()>&&);
void didFindTextManipulationItem(WebCore::TextManipulationController::ItemIdentifier, const Vector<WebCore::TextManipulationController::ManipulationToken>&);
- void completeTextManipulation(WebCore::TextManipulationController::ItemIdentifier,
- const Vector<WebCore::TextManipulationController::ManipulationToken>&, WTF::Function<void (bool success)>&&);
+ void completeTextManipulation(WebCore::TextManipulationController::ItemIdentifier, const Vector<WebCore::TextManipulationController::ManipulationToken>&,
+ WTF::Function<void (WebCore::TextManipulationController::ManipulationResult)>&&);
private:
WebPageProxy(PageClient&, WebProcessProxy&, Ref<API::PageConfiguration>&&);
Modified: trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj (251599 => 251600)
--- trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebKit/WebKit.xcodeproj/project.pbxproj 2019-10-25 20:41:15 UTC (rev 251600)
@@ -1337,6 +1337,8 @@
9B02E0CB235EB953004044B2 /* _WKTextManipulationDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B02E0C9235EB62D004044B2 /* _WKTextManipulationDelegate.h */; settings = {ATTRIBUTES = (Private, ); }; };
9B02E0CC235EB957004044B2 /* _WKTextManipulationItem.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B02E0CA235EB884004044B2 /* _WKTextManipulationItem.h */; settings = {ATTRIBUTES = (Private, ); }; };
9B02E0D7235FC94F004044B2 /* _WKTextManipulationToken.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B02E0CD235EB967004044B2 /* _WKTextManipulationToken.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 9B5499AD2362A6F900DF8BA5 /* _WKTextManipulationConfiguration.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B5499AC2362A6F600DF8BA5 /* _WKTextManipulationConfiguration.h */; settings = {ATTRIBUTES = (Private, ); }; };
+ 9B5499B22362A7EC00DF8BA5 /* _WKTextManipulationExclusionRule.h in Headers */ = {isa = PBXBuildFile; fileRef = 9B5499B02362A7EC00DF8BA5 /* _WKTextManipulationExclusionRule.h */; settings = {ATTRIBUTES = (Private, ); }; };
9FB5F395169E6A80002C25BF /* WKContextPrivateMac.h in Headers */ = {isa = PBXBuildFile; fileRef = 9FB5F393169E6A80002C25BF /* WKContextPrivateMac.h */; settings = {ATTRIBUTES = (Private, ); }; };
A102A7081EC0EEE900D81D82 /* com.macromedia.Flash Player ESR.plugin.sb in Copy Plug-in Sandbox Profiles */ = {isa = PBXBuildFile; fileRef = 7A5E39491D5BD8A700B4B7CE /* com.macromedia.Flash Player ESR.plugin.sb */; };
A1046EA12079263100F0C5D8 /* WKPDFView.h in Headers */ = {isa = PBXBuildFile; fileRef = A1046E9F2079263100F0C5D8 /* WKPDFView.h */; };
@@ -4057,6 +4059,10 @@
9B02E0CD235EB967004044B2 /* _WKTextManipulationToken.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _WKTextManipulationToken.h; sourceTree = "<group>"; };
9B02E0CE235EBB14004044B2 /* _WKTextManipulationToken.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKTextManipulationToken.mm; sourceTree = "<group>"; };
9B02E0D0235EBCCA004044B2 /* _WKTextManipulationItem.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKTextManipulationItem.mm; sourceTree = "<group>"; };
+ 9B5499AC2362A6F600DF8BA5 /* _WKTextManipulationConfiguration.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _WKTextManipulationConfiguration.h; sourceTree = "<group>"; };
+ 9B5499AE2362A7A700DF8BA5 /* _WKTextManipulationConfiguration.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKTextManipulationConfiguration.mm; sourceTree = "<group>"; };
+ 9B5499B02362A7EC00DF8BA5 /* _WKTextManipulationExclusionRule.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = _WKTextManipulationExclusionRule.h; sourceTree = "<group>"; };
+ 9B5499B12362A7EC00DF8BA5 /* _WKTextManipulationExclusionRule.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = _WKTextManipulationExclusionRule.mm; sourceTree = "<group>"; };
9BC59D6C1EFCCCB6001E8D09 /* CallbackID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CallbackID.h; sourceTree = "<group>"; };
9BC59D6D1EFCDC6D001E8D09 /* OptionalCallbackID.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OptionalCallbackID.h; sourceTree = "<group>"; };
9F54F88E16488E87007DF81A /* AuxiliaryProcessMac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = AuxiliaryProcessMac.mm; sourceTree = "<group>"; };
@@ -6356,7 +6362,11 @@
2DE9B1382231F61C005287B7 /* _WKTextInputContext.h */,
2DE9B1372231F61C005287B7 /* _WKTextInputContext.mm */,
2DE9B13B2231F77C005287B7 /* _WKTextInputContextInternal.h */,
+ 9B5499AC2362A6F600DF8BA5 /* _WKTextManipulationConfiguration.h */,
+ 9B5499AE2362A7A700DF8BA5 /* _WKTextManipulationConfiguration.mm */,
9B02E0C9235EB62D004044B2 /* _WKTextManipulationDelegate.h */,
+ 9B5499B02362A7EC00DF8BA5 /* _WKTextManipulationExclusionRule.h */,
+ 9B5499B12362A7EC00DF8BA5 /* _WKTextManipulationExclusionRule.mm */,
9B02E0CA235EB884004044B2 /* _WKTextManipulationItem.h */,
9B02E0D0235EBCCA004044B2 /* _WKTextManipulationItem.mm */,
9B02E0CD235EB967004044B2 /* _WKTextManipulationToken.h */,
@@ -9330,7 +9340,9 @@
1A002D43196B337000B9AD44 /* _WKSessionStateInternal.h in Headers */,
2DE9B13A2231F61C005287B7 /* _WKTextInputContext.h in Headers */,
2DE9B13C2231F77C005287B7 /* _WKTextInputContextInternal.h in Headers */,
+ 9B5499AD2362A6F900DF8BA5 /* _WKTextManipulationConfiguration.h in Headers */,
9B02E0CB235EB953004044B2 /* _WKTextManipulationDelegate.h in Headers */,
+ 9B5499B22362A7EC00DF8BA5 /* _WKTextManipulationExclusionRule.h in Headers */,
9B02E0CC235EB957004044B2 /* _WKTextManipulationItem.h in Headers */,
9B02E0D7235FC94F004044B2 /* _WKTextManipulationToken.h in Headers */,
2D6B371B18A967AD0042AE80 /* _WKThumbnailView.h in Headers */,
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp (251599 => 251600)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.cpp 2019-10-25 20:41:15 UTC (rev 251600)
@@ -6836,7 +6836,7 @@
return WebCore::ElementContext { elementRectInRootViewCoordinates(element, *frame), m_identifier, document.identifier(), document.identifierForElement(element) };
}
-void WebPage::startTextManipulations(CompletionHandler<void()>&& completionHandler)
+void WebPage::startTextManipulations(Vector<WebCore::TextManipulationController::ExclusionRule>&& exclusionRules, CompletionHandler<void()>&& completionHandler)
{
if (!m_page)
return;
@@ -6856,25 +6856,26 @@
return;
webPage->send(Messages::WebPageProxy::DidFindTextManipulationItem(itemIdentifier, tokens));
- });
+ }, WTFMove(exclusionRules));
// For now, we assume startObservingParagraphs find all paragraphs synchronously at once.
completionHandler();
}
void WebPage::completeTextManipulation(WebCore::TextManipulationController::ItemIdentifier itemID,
- const Vector<WebCore::TextManipulationController::ManipulationToken>& tokens, CompletionHandler<void(bool)>&& completionHandler)
+ const Vector<WebCore::TextManipulationController::ManipulationToken>& tokens, CompletionHandler<void(WebCore::TextManipulationController::ManipulationResult)>&& completionHandler)
{
+ using ManipulationResult = WebCore::TextManipulationController::ManipulationResult;
auto completeManipulation = [&] {
if (!m_page)
- return false;
+ return ManipulationResult::InvalidItem;
auto mainDocument = makeRefPtr(m_page->mainFrame().document());
if (!mainDocument)
- return false;
+ return ManipulationResult::InvalidItem;
auto* controller = mainDocument->textManipulationControllerIfExists();
if (!controller)
- return false;
+ return ManipulationResult::InvalidItem;
return controller->completeManipulation(itemID, tokens);
};
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.h (251599 => 251600)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.h 2019-10-25 20:41:15 UTC (rev 251600)
@@ -1197,9 +1197,10 @@
WebCore::Element* elementForContext(const WebCore::ElementContext&) const;
Optional<WebCore::ElementContext> contextForElement(WebCore::Element&) const;
- void startTextManipulations(CompletionHandler<void()>&&);
+ void startTextManipulations(Vector<WebCore::TextManipulationController::ExclusionRule>&&, CompletionHandler<void()>&&);
void completeTextManipulation(WebCore::TextManipulationController::ItemIdentifier,
- const Vector<WebCore::TextManipulationController::ManipulationToken>&, CompletionHandler<void(bool)>&&);
+ const Vector<WebCore::TextManipulationController::ManipulationToken>&,
+ CompletionHandler<void(WebCore::TextManipulationController::ManipulationResult)>&&);
#if ENABLE(APPLE_PAY)
WebPaymentCoordinator* paymentCoordinator();
Modified: trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in (251599 => 251600)
--- trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Source/WebKit/WebProcess/WebPage/WebPage.messages.in 2019-10-25 20:41:15 UTC (rev 251600)
@@ -583,6 +583,6 @@
SendMessageToWebExtensionWithReply(struct WebKit::UserMessage userMessage) -> (struct WebKit::UserMessage replyMessage) Async
#endif
- StartTextManipulations() -> () Async
- CompleteTextManipulation(WebCore::TextManipulationController::ItemIdentifier itemID, Vector<WebCore::TextManipulationController::ManipulationToken> tokens) -> (bool success) Async
+ StartTextManipulations(Vector<WebCore::TextManipulationController::ExclusionRule> exclusionRules) -> () Async
+ CompleteTextManipulation(WebCore::TextManipulationController::ItemIdentifier itemID, Vector<WebCore::TextManipulationController::ManipulationToken> tokens) -> (enum:uint8_t WebCore::TextManipulationController::ManipulationResult result) Async
}
Modified: trunk/Tools/ChangeLog (251599 => 251600)
--- trunk/Tools/ChangeLog 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Tools/ChangeLog 2019-10-25 20:41:15 UTC (rev 251600)
@@ -1,3 +1,18 @@
+2019-10-24 Ryosuke Niwa <rn...@webkit.org>
+
+ Add exclusion rules to text manipulation SPI
+ https://bugs.webkit.org/show_bug.cgi?id=203398
+ <rdar://problem/56567256>
+
+ Reviewed by Wenson Hsieh.
+
+ Added tests for including & excluding content based on element names and attribute values.
+
+ Also added a test to make sure _startTextManipulationsWithConfiguration calls the completion handler
+ even when the _WKTextManipulationDelegate isn't set.
+
+ * TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm:
+
2019-10-25 Jonathan Bedard <jbed...@apple.com>
results.webkit.org: Report the correct flavor for leaks
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm (251599 => 251600)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm 2019-10-25 19:25:29 UTC (rev 251599)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitCocoa/TextManipulation.mm 2019-10-25 20:41:15 UTC (rev 251600)
@@ -29,7 +29,9 @@
#import "Test.h"
#import "TestWKWebView.h"
#import <WebKit/WKWebViewPrivate.h>
+#import <WebKit/_WKTextManipulationConfiguration.h>
#import <WebKit/_WKTextManipulationDelegate.h>
+#import <WebKit/_WKTextManipulationExclusionRule.h>
#import <WebKit/_WKTextManipulationItem.h>
#import <WebKit/_WKTextManipulationToken.h>
#import <wtf/BlockPtr.h>
@@ -71,6 +73,23 @@
namespace TestWebKitAPI {
+TEST(TextManipulation, StartTextManipulationExitEarlyWithoutDelegate)
+{
+ auto delegate = adoptNS([[TextManipulationDelegate alloc] init]);
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+
+ [webView synchronouslyLoadHTMLString:@"<!DOCTYPE html>"
+ "<html><body>hello<br>world<div>WebKit</div></body></html>"];
+
+ done = false;
+ [webView _startTextManipulationsWithConfiguration:nil completion:^{
+ done = true;
+ }];
+ TestWebKitAPI::Util::run(&done);
+
+ EXPECT_EQ([delegate items].count, 0UL);
+}
+
TEST(TextManipulation, StartTextManipulationFindSimpleParagraphs)
{
auto delegate = adoptNS([[TextManipulationDelegate alloc] init]);
@@ -81,7 +100,7 @@
"<html><body>hello<br>world<div>WebKit</div></body></html>"];
done = false;
- [webView _startTextManipulationsWithCompletionHandler:^{
+ [webView _startTextManipulationsWithConfiguration:nil completion:^{
done = true;
}];
TestWebKitAPI::Util::run(&done);
@@ -108,7 +127,7 @@
"<html><body><pre>hello\nworld\nWebKit</pre></body></html>"];
done = false;
- [webView _startTextManipulationsWithCompletionHandler:^{
+ [webView _startTextManipulationsWithConfiguration:nil completion:^{
done = true;
}];
TestWebKitAPI::Util::run(&done);
@@ -135,7 +154,7 @@
"<html><body>hello, <b>world</b><br><div><em> <b>Web</b>Kit</em> </div></body></html>"];
done = false;
- [webView _startTextManipulationsWithCompletionHandler:^{
+ [webView _startTextManipulationsWithConfiguration:nil completion:^{
done = true;
}];
TestWebKitAPI::Util::run(&done);
@@ -151,6 +170,72 @@
EXPECT_STREQ("Kit", items[1].tokens[1].content.UTF8String);
}
+TEST(TextManipulation, StartTextManipulationApplySingleExcluionRuleForElement)
+{
+ auto delegate = adoptNS([[TextManipulationDelegate alloc] init]);
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ [webView _setTextManipulationDelegate:delegate.get()];
+
+ [webView synchronouslyLoadHTMLString:@"<!DOCTYPE html>"
+ "<html><body>Here's some code:<code>function <span>F</span>() { }</code>.</body></html>"];
+
+ RetainPtr<_WKTextManipulationConfiguration> configuration = adoptNS([[_WKTextManipulationConfiguration alloc] init]);
+ [configuration setExclusionRules:@[
+ [[[_WKTextManipulationExclusionRule alloc] initExclusion:(BOOL)YES forElement:@"code"] autorelease],
+ ]];
+
+ done = false;
+ [webView _startTextManipulationsWithConfiguration:configuration.get() completion:^{
+ done = true;
+ }];
+ TestWebKitAPI::Util::run(&done);
+
+ auto *items = [delegate items];
+ EXPECT_EQ(items.count, 1UL);
+ EXPECT_EQ(items[0].tokens.count, 5UL);
+ auto* tokens = items[0].tokens;
+ EXPECT_STREQ("Here's some code:", tokens[0].content.UTF8String);
+ EXPECT_FALSE(tokens[0].isExcluded);
+ EXPECT_STREQ("function ", tokens[1].content.UTF8String);
+ EXPECT_TRUE(tokens[1].isExcluded);
+ EXPECT_STREQ("F", tokens[2].content.UTF8String);
+ EXPECT_TRUE(tokens[2].isExcluded);
+ EXPECT_STREQ("() { }", tokens[3].content.UTF8String);
+ EXPECT_TRUE(tokens[3].isExcluded);
+ EXPECT_STREQ(".", tokens[4].content.UTF8String);
+ EXPECT_FALSE(tokens[4].isExcluded);
+}
+
+TEST(TextManipulation, StartTextManipulationApplyInclusionExclusionRulesForAttributes)
+{
+ auto delegate = adoptNS([[TextManipulationDelegate alloc] init]);
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ [webView _setTextManipulationDelegate:delegate.get()];
+
+ [webView synchronouslyLoadHTMLString:@"<!DOCTYPE html>"
+ "<html><body><span data-exclude=Yes><b>hello, </b><span data-exclude=NO>world</span></span></body></html>"];
+
+ RetainPtr<_WKTextManipulationConfiguration> configuration = adoptNS([[_WKTextManipulationConfiguration alloc] init]);
+ [configuration setExclusionRules:@[
+ [[[_WKTextManipulationExclusionRule alloc] initExclusion:(BOOL)YES forAttribute:@"data-exclude" value:@"yes"] autorelease],
+ [[[_WKTextManipulationExclusionRule alloc] initExclusion:(BOOL)NO forAttribute:@"data-exclude" value:@"no"] autorelease],
+ ]];
+
+ done = false;
+ [webView _startTextManipulationsWithConfiguration:configuration.get() completion:^{
+ done = true;
+ }];
+ TestWebKitAPI::Util::run(&done);
+
+ auto *items = [delegate items];
+ EXPECT_EQ(items.count, 1UL);
+ EXPECT_EQ(items[0].tokens.count, 2UL);
+ EXPECT_STREQ("hello, ", items[0].tokens[0].content.UTF8String);
+ EXPECT_TRUE(items[0].tokens[0].isExcluded);
+ EXPECT_STREQ("world", items[0].tokens[1].content.UTF8String);
+ EXPECT_FALSE(items[0].tokens[1].isExcluded);
+}
+
struct Token {
NSString *identifier;
NSString *content;
@@ -169,7 +254,7 @@
return adoptNS([[_WKTextManipulationItem alloc] initWithIdentifier:itemIdentifier tokens:wkTokens.get()]);
}
-TEST(TextManipulation, CompleteTextManipulationShouldReplaceSimpleParagraphContent)
+TEST(TextManipulation, CompleteTextManipulationReplaceSimpleParagraphContent)
{
auto delegate = adoptNS([[TextManipulationDelegate alloc] init]);
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
@@ -179,7 +264,7 @@
"<html><body><p>helllo, wooorld</p><p> hey, <b> Kits</b> is <em>cuuute</em></p></body></html>"];
done = false;
- [webView _startTextManipulationsWithCompletionHandler:^{
+ [webView _startTextManipulationsWithConfiguration:nil completion:^{
done = true;
}];
TestWebKitAPI::Util::run(&done);
@@ -221,7 +306,7 @@
[webView stringByEvaluatingJavaScript:@"document.body.innerHTML"]);
}
-TEST(TextManipulation, CompleteTextManipulationShouldFailWhenContentIsChanged)
+TEST(TextManipulation, CompleteTextManipulationFailWhenContentIsChanged)
{
auto delegate = adoptNS([[TextManipulationDelegate alloc] init]);
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
@@ -231,7 +316,7 @@
"<html><body><p> what <em>time</em> are they now?</p></body></html>"];
done = false;
- [webView _startTextManipulationsWithCompletionHandler:^{
+ [webView _startTextManipulationsWithConfiguration:nil completion:^{
done = true;
}];
TestWebKitAPI::Util::run(&done);
@@ -259,7 +344,7 @@
[webView stringByEvaluatingJavaScript:@"document.body.innerHTML"]);
}
-TEST(TextManipulation, CompleteTextManipulationShouldFailWhenDocumentHasBeenNavigatedAway)
+TEST(TextManipulation, CompleteTextManipulationFailWhenDocumentHasBeenNavigatedAway)
{
auto delegate = adoptNS([[TextManipulationDelegate alloc] init]);
auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
@@ -269,7 +354,7 @@
[webView stringByEvaluatingJavaScript:@"document.body.innerHTML = '<p>hey, <em>earth</em></p>'"];
done = false;
- [webView _startTextManipulationsWithCompletionHandler:^{
+ [webView _startTextManipulationsWithConfiguration:nil completion:^{
done = true;
}];
TestWebKitAPI::Util::run(&done);
@@ -284,7 +369,7 @@
[webView stringByEvaluatingJavaScript:@"document.body.innerHTML = '<p>hey, <em>earth</em></p>'"];
done = false;
- [webView _startTextManipulationsWithCompletionHandler:^{
+ [webView _startTextManipulationsWithConfiguration:nil completion:^{
done = true;
}];
TestWebKitAPI::Util::run(&done);
@@ -301,5 +386,43 @@
TestWebKitAPI::Util::run(&done);
}
+TEST(TextManipulation, CompleteTextManipulationFailWhenExclusionIsViolated)
+{
+ auto delegate = adoptNS([[TextManipulationDelegate alloc] init]);
+ auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]);
+ [webView _setTextManipulationDelegate:delegate.get()];
+
+ [webView synchronouslyLoadTestPageNamed:@"simple"];
+ [webView stringByEvaluatingJavaScript:@"document.body.innerHTML = '<p>hi, <em>WebKitten</em></p>'"];
+
+ RetainPtr<_WKTextManipulationConfiguration> configuration = adoptNS([[_WKTextManipulationConfiguration alloc] init]);
+ [configuration setExclusionRules:@[
+ [[[_WKTextManipulationExclusionRule alloc] initExclusion:(BOOL)YES forElement:@"p"] autorelease],
+ ]];
+
+ done = false;
+ [webView _startTextManipulationsWithConfiguration:configuration.get() completion:^{
+ done = true;
+ }];
+ TestWebKitAPI::Util::run(&done);
+
+ auto *items = [delegate items];
+ EXPECT_EQ(items.count, 1UL);
+ EXPECT_EQ(items[0].tokens.count, 2UL);
+ EXPECT_STREQ("hi, ", items[0].tokens[0].content.UTF8String);
+ EXPECT_STREQ("WebKitten", items[0].tokens[1].content.UTF8String);
+
+ done = false;
+ [webView _completeTextManipulation:(_WKTextManipulationItem *)createItem(items[0].identifier, {
+ { items[0].tokens[1].identifier, @"WebKit" },
+ }).get() completion:^(BOOL success) {
+ EXPECT_FALSE(success);
+ done = true;
+ }];
+
+ TestWebKitAPI::Util::run(&done);
+ EXPECT_WK_STREQ("<p>hi, <em>WebKitten</em></p>", [webView stringByEvaluatingJavaScript:@"document.body.innerHTML"]);
+}
+
} // namespace TestWebKitAPI