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.
5 #import "ios/web/public/web_state/js/crw_js_injection_manager.h"
7 #import <UIKit/UIKit.h>
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 #import "ios/web/web_state/js/page_script_util.h"
16 @implementation CRWJSInjectionManager {
17 // JS to inject into the page. This may be nil if it has been purged due to
19 base::scoped_nsobject<NSString> _injectObject;
20 // An object the can receive JavaScript injection.
21 CRWJSInjectionReceiver* _receiver; // Weak.
24 - (id)initWithReceiver:(CRWJSInjectionReceiver*)receiver {
29 // Register for low-memory warnings.
30 [[NSNotificationCenter defaultCenter]
32 selector:@selector(lowMemoryWarning:)
33 name:UIApplicationDidReceiveMemoryWarningNotification
40 [[NSNotificationCenter defaultCenter] removeObserver:self];
44 - (BOOL)hasBeenInjected {
45 DCHECK(self.presenceBeacon);
46 return [_receiver scriptHasBeenInjectedForClass:[self class]
47 presenceBeacon:self.presenceBeacon];
51 if ([self hasBeenInjected])
53 [self injectDependenciesIfMissing];
54 [_receiver injectScript:[self injectionContent] forClass:[self class]];
55 DCHECK([self hasBeenInjected]);
58 - (void)lowMemoryWarning:(NSNotification*)notify {
59 _injectObject.reset();
62 - (void)deferredEvaluate:(NSString*)script {
63 NSString* deferredScript = [NSString
64 stringWithFormat:@"window.setTimeout(function() {%@}, 0)", script];
65 [self evaluate:deferredScript stringResultHandler:nil];
68 - (void)evaluate:(NSString*)script
69 stringResultHandler:(web::JavaScriptCompletion)completionHandler {
70 [_receiver evaluateJavaScript:script stringResultHandler:completionHandler];
73 - (NSArray*)directDependencies {
77 - (NSArray*)allDependencies {
78 NSMutableArray* allDendencies = [NSMutableArray array];
79 for (Class dependencyClass in [self directDependencies]) {
80 CRWJSInjectionManager* dependency =
81 [_receiver instanceOfClass:dependencyClass];
82 NSArray* list = [dependency allDependencies];
83 for (CRWJSInjectionManager* manager in list) {
84 if (![allDendencies containsObject:manager])
85 [allDendencies addObject:manager];
88 [allDendencies addObject:self];
93 #pragma mark ProtectedMethods
95 - (CRWJSInjectionReceiver*)receiver {
99 - (NSString*)scriptPath {
104 - (NSString*)presenceBeacon {
108 - (NSString*)injectionContent {
110 _injectObject.reset([[self staticInjectionContent] copy]);
111 return _injectObject.get();
114 - (NSString*)staticInjectionContent {
115 return web::GetPageScript([self scriptPath]);
118 - (void)injectDependenciesIfMissing {
119 for (Class dependencyClass in [self directDependencies]) {
120 CRWJSInjectionManager* dependency =
121 [_receiver instanceOfClass:dependencyClass];