| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "ios/chrome/browser/find_in_page/js_findinpage_manager.h" | 5 #import "ios/chrome/browser/find_in_page/js_findinpage_manager.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #import "base/ios/weak_nsobject.h" | |
| 11 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| 12 #include "base/json/string_escape.h" | 11 #include "base/json/string_escape.h" |
| 13 #include "base/logging.h" | 12 #include "base/logging.h" |
| 14 #include "base/mac/foundation_util.h" | 13 #include "base/mac/foundation_util.h" |
| 15 #include "base/strings/sys_string_conversions.h" | 14 #include "base/strings/sys_string_conversions.h" |
| 16 #include "base/values.h" | 15 #include "base/values.h" |
| 17 #import "ios/chrome/browser/find_in_page/find_in_page_model.h" | 16 #import "ios/chrome/browser/find_in_page/find_in_page_model.h" |
| 18 | 17 |
| 18 #if !defined(__has_feature) || !__has_feature(objc_arc) |
| 19 #error "This file requires ARC support." |
| 20 #endif |
| 21 |
| 19 namespace { | 22 namespace { |
| 20 | 23 |
| 21 // Initializes Find In Page JavaScript with the width and height of the window. | 24 // Initializes Find In Page JavaScript with the width and height of the window. |
| 22 NSString* const kFindInPageInit = @"window.__gCrWeb.findInPage && " | 25 NSString* const kFindInPageInit = @"window.__gCrWeb.findInPage && " |
| 23 "window.__gCrWeb.findInPage.init(%.f, %.f);"; | 26 "window.__gCrWeb.findInPage.init(%.f, %.f);"; |
| 24 | 27 |
| 25 // This will only do verbatim matches. | 28 // This will only do verbatim matches. |
| 26 // The timeout of 100ms is hardcoded into this string so we don't have | 29 // The timeout of 100ms is hardcoded into this string so we don't have |
| 27 // to spend any time at runtime to format this constant into another constant. | 30 // to spend any time at runtime to format this constant into another constant. |
| 28 NSString* const kFindInPageVerbatim = | 31 NSString* const kFindInPageVerbatim = |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 68 // previous element in the page and executes |completionHandler| after moving | 71 // previous element in the page and executes |completionHandler| after moving |
| 69 // with the new scroll position passed in. | 72 // with the new scroll position passed in. |
| 70 - (void)moveHighlightByEvaluatingJavaScript:(NSString*)script | 73 - (void)moveHighlightByEvaluatingJavaScript:(NSString*)script |
| 71 completionHandler: | 74 completionHandler: |
| 72 (void (^)(CGPoint))completionHandler; | 75 (void (^)(CGPoint))completionHandler; |
| 73 // Updates the current match index and its found position in the model. | 76 // Updates the current match index and its found position in the model. |
| 74 - (void)updateIndex:(NSInteger)index atPoint:(CGPoint)point; | 77 - (void)updateIndex:(NSInteger)index atPoint:(CGPoint)point; |
| 75 @end | 78 @end |
| 76 | 79 |
| 77 @implementation JsFindinpageManager | 80 @implementation JsFindinpageManager |
| 81 @synthesize findInPageModel = _findInPageModel; |
| 78 | 82 |
| 79 - (FindInPageModel*)findInPageModel { | 83 - (FindInPageModel*)findInPageModel { |
| 80 if (!findInPageModel_) | 84 if (!_findInPageModel) |
| 81 findInPageModel_.reset([[FindInPageModel alloc] init]); | 85 _findInPageModel = [[FindInPageModel alloc] init]; |
| 82 return findInPageModel_.get(); | 86 return _findInPageModel; |
| 83 } | 87 } |
| 84 | 88 |
| 85 - (void)setWidth:(CGFloat)width height:(CGFloat)height { | 89 - (void)setWidth:(CGFloat)width height:(CGFloat)height { |
| 86 NSString* javaScript = | 90 NSString* javaScript = |
| 87 [NSString stringWithFormat:kFindInPageInit, width, height]; | 91 [NSString stringWithFormat:kFindInPageInit, width, height]; |
| 88 [self executeJavaScript:javaScript completionHandler:nil]; | 92 [self executeJavaScript:javaScript completionHandler:nil]; |
| 89 } | 93 } |
| 90 | 94 |
| 91 - (void)findString:(NSString*)query | 95 - (void)findString:(NSString*)query |
| 92 completionHandler:(void (^)(BOOL, CGPoint))completionHandler { | 96 completionHandler:(void (^)(BOOL, CGPoint))completionHandler { |
| 93 DCHECK(completionHandler); | 97 DCHECK(completionHandler); |
| 94 // Save the query in the model before searching. | 98 // Save the query in the model before searching. |
| 95 [findInPageModel_ updateQuery:query matches:0]; | 99 [self.findInPageModel updateQuery:query matches:0]; |
| 96 | 100 |
| 97 // Escape |query| before passing to js. | 101 // Escape |query| before passing to js. |
| 98 std::string escapedJSON; | 102 std::string escapedJSON; |
| 99 base::EscapeJSONString(base::SysNSStringToUTF16(query), true, &escapedJSON); | 103 base::EscapeJSONString(base::SysNSStringToUTF16(query), true, &escapedJSON); |
| 100 NSString* JSONQuery = | 104 NSString* JSONQuery = |
| 101 [NSString stringWithFormat:kFindInPageVerbatim, | 105 [NSString stringWithFormat:kFindInPageVerbatim, |
| 102 base::SysUTF8ToNSString(escapedJSON.c_str())]; | 106 base::SysUTF8ToNSString(escapedJSON.c_str())]; |
| 103 base::WeakNSObject<JsFindinpageManager> weakSelf(self); | 107 __weak JsFindinpageManager* weakSelf = self; |
| 104 [self executeJavaScript:JSONQuery | 108 [self executeJavaScript:JSONQuery |
| 105 completionHandler:^(id result, NSError* error) { | 109 completionHandler:^(id result, NSError* error) { |
| 106 [weakSelf processFindInPagePumpResult:result | 110 [weakSelf processFindInPagePumpResult:result |
| 107 completionHandler:completionHandler]; | 111 completionHandler:completionHandler]; |
| 108 }]; | 112 }]; |
| 109 } | 113 } |
| 110 | 114 |
| 111 - (void)pumpWithCompletionHandler:(void (^)(BOOL, CGPoint))completionHandler { | 115 - (void)pumpWithCompletionHandler:(void (^)(BOOL, CGPoint))completionHandler { |
| 112 DCHECK(completionHandler); | 116 DCHECK(completionHandler); |
| 113 base::WeakNSObject<JsFindinpageManager> weakSelf(self); | 117 __weak JsFindinpageManager* weakSelf = self; |
| 114 [self executeJavaScript:kFindInPagePump | 118 [self executeJavaScript:kFindInPagePump |
| 115 completionHandler:^(id result, NSError* error) { | 119 completionHandler:^(id result, NSError* error) { |
| 116 // TODO(shreyasv): What to do here if this returns an NSError in the | 120 // TODO(shreyasv): What to do here if this returns an NSError in the |
| 117 // WKWebView version. | 121 // WKWebView version. |
| 118 [weakSelf processFindInPagePumpResult:result | 122 [weakSelf processFindInPagePumpResult:result |
| 119 completionHandler:completionHandler]; | 123 completionHandler:completionHandler]; |
| 120 }]; | 124 }]; |
| 121 } | 125 } |
| 122 | 126 |
| 123 - (void)nextMatchWithCompletionHandler:(void (^)(CGPoint))completionHandler { | 127 - (void)nextMatchWithCompletionHandler:(void (^)(CGPoint))completionHandler { |
| 124 [self moveHighlightByEvaluatingJavaScript:kFindInPageNext | 128 [self moveHighlightByEvaluatingJavaScript:kFindInPageNext |
| 125 completionHandler:completionHandler]; | 129 completionHandler:completionHandler]; |
| 126 } | 130 } |
| 127 | 131 |
| 128 - (void)previousMatchWithCompletionHandler: | 132 - (void)previousMatchWithCompletionHandler: |
| 129 (void (^)(CGPoint))completionHandler { | 133 (void (^)(CGPoint))completionHandler { |
| 130 [self moveHighlightByEvaluatingJavaScript:kFindInPagePrev | 134 [self moveHighlightByEvaluatingJavaScript:kFindInPagePrev |
| 131 completionHandler:completionHandler]; | 135 completionHandler:completionHandler]; |
| 132 } | 136 } |
| 133 | 137 |
| 134 - (void)moveHighlightByEvaluatingJavaScript:(NSString*)script | 138 - (void)moveHighlightByEvaluatingJavaScript:(NSString*)script |
| 135 completionHandler: | 139 completionHandler: |
| 136 (void (^)(CGPoint))completionHandler { | 140 (void (^)(CGPoint))completionHandler { |
| 137 base::WeakNSObject<JsFindinpageManager> weakSelf(self); | 141 __weak JsFindinpageManager* weakSelf = self; |
| 138 [self executeJavaScript:script | 142 [self executeJavaScript:script |
| 139 completionHandler:^(id result, NSError* error) { | 143 completionHandler:^(id result, NSError* error) { |
| 140 base::WeakNSObject<JsFindinpageManager> strongSelf([weakSelf retain]); | 144 JsFindinpageManager* strongSelf = weakSelf; |
| 141 if (!strongSelf) | 145 if (!strongSelf) |
| 142 return; | 146 return; |
| 143 DCHECK(!error); | 147 DCHECK(!error); |
| 144 FindInPageEntry entry = kFindInPageEntryZero; | 148 FindInPageEntry entry = kFindInPageEntryZero; |
| 145 if (![result isEqual:kFindInPagePending]) { | 149 if (![result isEqual:kFindInPagePending]) { |
| 146 NSString* stringResult = | 150 NSString* stringResult = |
| 147 base::mac::ObjCCastStrict<NSString>(result); | 151 base::mac::ObjCCastStrict<NSString>(result); |
| 148 entry = [strongSelf findInPageEntryForJson:stringResult]; | 152 entry = [strongSelf findInPageEntryForJson:stringResult]; |
| 149 } | 153 } |
| 150 CGPoint newPoint = entry.point; | 154 CGPoint newPoint = entry.point; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 178 | 182 |
| 179 base::ListValue* resultList = static_cast<base::ListValue*>(root.get()); | 183 base::ListValue* resultList = static_cast<base::ListValue*>(root.get()); |
| 180 DCHECK(resultList); | 184 DCHECK(resultList); |
| 181 if (resultList) { | 185 if (resultList) { |
| 182 if (resultList->GetSize() == 2) { | 186 if (resultList->GetSize() == 2) { |
| 183 int numHighlighted = 0; | 187 int numHighlighted = 0; |
| 184 if (resultList->GetInteger(0, &numHighlighted)) { | 188 if (resultList->GetInteger(0, &numHighlighted)) { |
| 185 if (numHighlighted > 0) { | 189 if (numHighlighted > 0) { |
| 186 base::ListValue* position; | 190 base::ListValue* position; |
| 187 if (resultList->GetList(1, &position)) { | 191 if (resultList->GetList(1, &position)) { |
| 188 [findInPageModel_ updateQuery:nil matches:numHighlighted]; | 192 [self.findInPageModel updateQuery:nil matches:numHighlighted]; |
| 189 // Scroll to first match. | 193 // Scroll to first match. |
| 190 FindInPageEntry entry = [self entryForListValue:position]; | 194 FindInPageEntry entry = [self entryForListValue:position]; |
| 191 [findInPageModel_ updateIndex:entry.index atPoint:entry.point]; | 195 [self.findInPageModel updateIndex:entry.index atPoint:entry.point]; |
| 192 if (point) | 196 if (point) |
| 193 *point = entry.point; | 197 *point = entry.point; |
| 194 } | 198 } |
| 195 } | 199 } |
| 196 } | 200 } |
| 197 } | 201 } |
| 198 } | 202 } |
| 199 return YES; | 203 return YES; |
| 200 } | 204 } |
| 201 | 205 |
| 202 - (void)processFindInPagePumpResult:(id)result | 206 - (void)processFindInPagePumpResult:(id)result |
| 203 completionHandler:(void (^)(BOOL, CGPoint))completionHandler { | 207 completionHandler:(void (^)(BOOL, CGPoint))completionHandler { |
| 204 CGPoint point = CGPointZero; | 208 CGPoint point = CGPointZero; |
| 205 if ([result isEqual:kFindInPagePending]) { | 209 if ([result isEqual:kFindInPagePending]) { |
| 206 completionHandler(NO, point); | 210 completionHandler(NO, point); |
| 207 } | 211 } |
| 208 // TODO(shreyasv): Inline this call from the logic from the above function | 212 // TODO(shreyasv): Inline this call from the logic from the above function |
| 209 // and remove the above function. | 213 // and remove the above function. |
| 210 BOOL processFIPResult = | 214 BOOL processFIPResult = |
| 211 [self processFindInPageResult:result scrollPosition:&point]; | 215 [self processFindInPageResult:result scrollPosition:&point]; |
| 212 completionHandler(processFIPResult, point); | 216 completionHandler(processFIPResult, point); |
| 213 } | 217 } |
| 214 | 218 |
| 215 - (void)updateIndex:(NSInteger)index atPoint:(CGPoint)point { | 219 - (void)updateIndex:(NSInteger)index atPoint:(CGPoint)point { |
| 216 [findInPageModel_ updateIndex:index atPoint:point]; | 220 [self.findInPageModel updateIndex:index atPoint:point]; |
| 217 } | 221 } |
| 218 | 222 |
| 219 - (FindInPageEntry)findInPageEntryForJson:(NSString*)jsonStr { | 223 - (FindInPageEntry)findInPageEntryForJson:(NSString*)jsonStr { |
| 220 std::string json([jsonStr UTF8String]); | 224 std::string json([jsonStr UTF8String]); |
| 221 std::unique_ptr<base::Value> root(base::JSONReader::Read(json, false)); | 225 std::unique_ptr<base::Value> root(base::JSONReader::Read(json, false)); |
| 222 if (!root.get()) | 226 if (!root.get()) |
| 223 return kFindInPageEntryZero; | 227 return kFindInPageEntryZero; |
| 224 | 228 |
| 225 if (!root->IsType(base::Value::TYPE_LIST)) | 229 if (!root->IsType(base::Value::TYPE_LIST)) |
| 226 return kFindInPageEntryZero; | 230 return kFindInPageEntryZero; |
| (...skipping 28 matching lines...) Expand all Loading... |
| 255 } | 259 } |
| 256 | 260 |
| 257 #pragma mark - | 261 #pragma mark - |
| 258 #pragma mark ProtectedMethods | 262 #pragma mark ProtectedMethods |
| 259 | 263 |
| 260 - (NSString*)scriptPath { | 264 - (NSString*)scriptPath { |
| 261 return @"find_in_page"; | 265 return @"find_in_page"; |
| 262 } | 266 } |
| 263 | 267 |
| 264 @end | 268 @end |
| OLD | NEW |