Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Unified Diff: components/autofill/ios/browser/js_suggestion_manager.mm

Issue 1007813002: [iOS] Upstream autofill component code (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Added dconnelly to OWNERS Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: components/autofill/ios/browser/js_suggestion_manager.mm
diff --git a/components/autofill/ios/browser/js_suggestion_manager.mm b/components/autofill/ios/browser/js_suggestion_manager.mm
new file mode 100644
index 0000000000000000000000000000000000000000..51d2a62aacb8e221a33bed90037c7f6d1d47d3b8
--- /dev/null
+++ b/components/autofill/ios/browser/js_suggestion_manager.mm
@@ -0,0 +1,115 @@
+// Copyright 2013 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#import "components/autofill/ios/browser/js_suggestion_manager.h"
+
+#include "base/format_macros.h"
+#include "base/json/string_escape.h"
+#include "base/logging.h"
+#include "base/strings/sys_string_conversions.h"
+#import "ios/web/public/web_state/js/crw_js_early_script_manager.h"
+
+namespace {
+// Santizies |str| and wraps it in quotes so it can be injected safely in
+// JavaScript.
+NSString* JSONEscape(NSString* str) {
+ return base::SysUTF8ToNSString(
+ base::GetQuotedJSONString(base::SysNSStringToUTF8(str)));
+}
+} // namespace
+
+@implementation JsSuggestionManager
+
+#pragma mark -
+#pragma mark ProtectedMethods
+
+- (NSString*)scriptPath {
+ return @"suggestion_controller";
+}
+
+- (NSString*)presenceBeacon {
+ return @"__gCrWeb.suggestion";
+}
+
+- (NSArray*)directDependencies {
+ return @[ [CRWJSEarlyScriptManager class] ];
+}
+
+- (void)selectNextElement {
+ [self selectElementAfterForm:@"" field:@""];
+}
+
+- (void)selectElementAfterForm:(NSString*)formName field:(NSString*)fieldName {
+ NSString* selectNextElementJS = [NSString
+ stringWithFormat:@"__gCrWeb.suggestion.selectNextElement(%@, %@)",
+ JSONEscape(formName), JSONEscape(fieldName)];
+ [self evaluate:selectNextElementJS stringResultHandler:nil];
+}
+
+- (void)selectPreviousElement {
+ [self selectElementBeforeForm:@"" field:@""];
+}
+
+- (void)selectElementBeforeForm:(NSString*)formName field:(NSString*)fieldName {
+ NSString* selectPreviousElementJS = [NSString
+ stringWithFormat:@"__gCrWeb.suggestion.selectPreviousElement(%@, %@)",
+ JSONEscape(formName), JSONEscape(fieldName)];
+ [self evaluate:selectPreviousElementJS stringResultHandler:nil];
+}
+
+- (void)fetchPreviousAndNextElementsPresenceWithCompletionHandler:
+ (void (^)(BOOL, BOOL))completionHandler {
+ [self fetchPreviousAndNextElementsPresenceForForm:@""
+ field:@""
+ completionHandler:completionHandler];
+}
+
+- (void)fetchPreviousAndNextElementsPresenceForForm:(NSString*)formName
+ field:(NSString*)fieldName
+ completionHandler:
+ (void (^)(BOOL, BOOL))completionHandler {
+ DCHECK(completionHandler);
+ DCHECK([self hasBeenInjected]);
+ id stringResultHandler = ^(NSString* result, NSError* error) {
+ // The result maybe an empty string here due to 2 reasons:
+ // 1) When there is an exception running the JS
+ // 2) There is a race when the page is changing due to which
+ // JSSuggestionManager has not yet injected __gCrWeb.suggestion object
+ // Handle this case gracefully.
+ // TODO(shreyasv): Figure out / narrow down further why this occurs.
+ // crbug.com/432217.
+ // If a page has overridden Array.toString, the string returned may not
+ // contain a ",", hence this is a defensive measure to early return.
+ NSArray* components = [result componentsSeparatedByString:@","];
+ if (components.count != 2) {
+ completionHandler(NO, NO);
+ return;
+ }
+
+ DCHECK([components[0] isEqualToString:@"true"] ||
+ [components[0] isEqualToString:@"false"]);
+ BOOL hasPreviousElement = [components[0] isEqualToString:@"true"];
+ DCHECK([components[1] isEqualToString:@"true"] ||
+ [components[1] isEqualToString:@"false"]);
+ BOOL hasNextElement = [components[1] isEqualToString:@"true"];
+ completionHandler(hasPreviousElement, hasNextElement);
+ };
+ NSString* escapedFormName = JSONEscape(formName);
+ NSString* escapedFieldName = JSONEscape(fieldName);
+ NSString* js = [NSString
+ stringWithFormat:@"[__gCrWeb.suggestion.hasPreviousElement(%@, %@),"
+ @"__gCrWeb.suggestion.hasNextElement(%@, %@)]"
+ @".toString()",
+ escapedFormName, escapedFieldName, escapedFormName,
+ escapedFieldName];
+ [self evaluate:js stringResultHandler:stringResultHandler];
+}
+
+- (void)closeKeyboard {
+ // Deferred execution used because of a risk of crwebinvoke:// triggered
+ // immediately by the loss of focus.
+ [self deferredEvaluate:@"document.activeElement.blur()"];
+}
+
+@end

Powered by Google App Engine
This is Rietveld 408576698