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

Side by Side Diff: ios/web/web_state/js/crw_js_injection_manager.mm

Issue 790803002: Upstream JavaScript injection for iOS (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Review comments Created 6 years 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 unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #import "ios/web/public/web_state/js/crw_js_injection_manager.h"
6
7 #import <UIKit/UIKit.h>
8
9 #include "base/logging.h"
10 #include "base/mac/bundle_locations.h"
11 #import "base/mac/scoped_nsobject.h"
12 #include "base/strings/sys_string_conversions.h"
13 #import "ios/web/public/web_state/js/crw_js_injection_receiver.h"
14
15 namespace {
16 // Template with presence beacon check to prevent re-injection of JavaScript.
17 NSString* const kPresenceCheckTemplate = @"if (typeof %@ !== 'object') { %@ }";
18 }
19
20 @implementation CRWJSInjectionManager {
21 // JS to inject into the page for our own nefarious purposes. This may be
stuartmorgan 2014/12/11 23:59:38 Let's drop the "for our own nefarious purposes"
22 // nil if it has been purged due to low memory.
23 base::scoped_nsobject<NSString> _injectObject;
24 // An object the can receive JavaScript injection.
25 __weak CRWJSInjectionReceiver* _receiver;
sdefresne 2014/12/11 15:25:12 nity: __weak is useless here too.
26 }
27
28 - (id)initWithReceiver:(CRWJSInjectionReceiver*)receiver {
29 DCHECK(receiver);
30 self = [super init];
31 if (self) {
32 _receiver = receiver;
33 // Register for low-memory warnings.
34 [[NSNotificationCenter defaultCenter]
35 addObserver:self
36 selector:@selector(lowMemoryWarning:)
37 name:UIApplicationDidReceiveMemoryWarningNotification
38 object:nil];
39 }
40 return self;
41 }
42
43 - (void)dealloc {
44 [[NSNotificationCenter defaultCenter] removeObserver:self];
45 [super dealloc];
46 }
47
48 - (BOOL)hasBeenInjected {
49 DCHECK(self.presenceBeacon);
50 return [_receiver scriptHasBeenInjectedForClass:[self class]
51 presenceBeacon:self.presenceBeacon];
52 }
53
54 - (void)inject {
55 if ([self hasBeenInjected])
56 return;
57 [self injectDependenciesIfMissing];
58 [_receiver injectScript:[self injectionContent] forClass:[self class]];
59 DCHECK([self hasBeenInjected]);
60 }
61
62 - (NSString*)injectionContentIncludingDependencies {
63 NSArray* allDependencies = [self allDependencies];
64 NSMutableArray* scripts =
65 [NSMutableArray arrayWithCapacity:allDependencies.count];
66 for (CRWJSInjectionManager* dependency in allDependencies) {
67 [scripts addObject:[dependency injectionContent]];
68 }
69 NSString* script = [scripts componentsJoinedByString:@""];
70 NSString* beacon = [self presenceBeacon];
71 return [NSString stringWithFormat:kPresenceCheckTemplate, beacon, script];
72 }
73
74 - (void)lowMemoryWarning:(NSNotification*)notify {
75 _injectObject.reset();
76 }
77
78 - (void)deferredEvaluate:(NSString*)script {
79 NSString* deferredScript = [NSString
80 stringWithFormat:@"window.setTimeout(function() {%@}, 0)", script];
81 [self evaluate:deferredScript stringResultHandler:nil];
82 }
83
84 - (void)evaluate:(NSString*)script
85 stringResultHandler:(web::JavaScriptCompletion)completionHandler {
86 [_receiver evaluateJavaScript:script stringResultHandler:completionHandler];
87 }
88
89 - (NSArray*)directDependencies {
90 return @[];
91 }
92
93 - (NSArray*)allDependencies {
94 NSMutableArray* allDendencies = [NSMutableArray array];
95 for (Class dependencyClass in [self directDependencies]) {
96 CRWJSInjectionManager* dependency =
97 [_receiver instanceOfClass:dependencyClass];
98 NSArray* list = [dependency allDependencies];
99 for (CRWJSInjectionManager* manager in list) {
100 if (![allDendencies containsObject:manager])
101 [allDendencies addObject:manager];
102 }
103 }
104 [allDendencies addObject:self];
105 return allDendencies;
106 }
107
108 #pragma mark -
109 #pragma mark ProtectedMethods
110
111 - (CRWJSInjectionReceiver*)receiver {
112 return _receiver;
113 }
114
115 - (NSString*)scriptPath {
116 NOTREACHED();
117 return nil;
118 }
119
120 - (NSString*)presenceBeacon {
121 return nil;
122 }
123
124 - (NSString*)injectionContent {
125 if (!_injectObject)
126 _injectObject.reset([[self staticInjectionContent] copy]);
127 return _injectObject.get();
128 }
129
130 - (NSString*)staticInjectionContent {
131 DCHECK(self.scriptPath);
132 NSString* path = [base::mac::FrameworkBundle() pathForResource:self.scriptPath
133 ofType:@"js"];
134 DCHECK(path) << "Script file not found: "
135 << base::SysNSStringToUTF8(self.scriptPath) << ".js";
136 NSError* error = nil;
137 NSString* content = [NSString stringWithContentsOfFile:path
138 encoding:NSUTF8StringEncoding
139 error:&error];
140 DCHECK(!error) << "Error fetching script: " << [error.description UTF8String];
141 DCHECK(content);
142 return content;
143 }
144
145 - (void)injectDependenciesIfMissing {
146 for (Class dependencyClass in [self directDependencies]) {
147 CRWJSInjectionManager* dependency =
148 [_receiver instanceOfClass:dependencyClass];
149 [dependency inject];
150 }
151 }
152
153 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698