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 |