]>
Commit | Line | Data |
---|---|---|
36228fbc | 1 | /* Cydget - open-source AwayView plugin multiplexer |
bea621e6 | 2 | * Copyright (C) 2009-2015 Jay Freeman (saurik) |
a1075171 JF |
3 | */ |
4 | ||
5bc15b17 | 5 | /* GNU General Public License, Version 3 {{{ */ |
a1075171 | 6 | /* |
bea621e6 | 7 | * Cydget is free software: you can redistribute it and/or modify |
5bc15b17 JF |
8 | * it under the terms of the GNU General Public License as published |
9 | * by the Free Software Foundation, either version 3 of the License, | |
10 | * or (at your option) any later version. | |
a1075171 | 11 | * |
bea621e6 | 12 | * Cydget is distributed in the hope that it will be useful, but |
5bc15b17 JF |
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of |
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 | * GNU General Public License for more details. | |
a1075171 | 16 | * |
5bc15b17 | 17 | * You should have received a copy of the GNU General Public License |
bea621e6 | 18 | * along with Cydget. If not, see <http://www.gnu.org/licenses/>. |
5bc15b17 JF |
19 | **/ |
20 | /* }}} */ | |
342b0866 | 21 | |
5bc15b17 JF |
22 | #include <CydiaSubstrate/CydiaSubstrate.h> |
23 | #include <UIKit/UIKit.h> | |
a1075171 | 24 | |
5bc15b17 | 25 | #include <pthread.h> |
342b0866 | 26 | |
5bc15b17 | 27 | #include <SpringBoardUI/SBAwayViewPluginController.h> |
342b0866 JF |
28 | |
29 | #include <WebKit/WebFrame.h> | |
5bc15b17 | 30 | #include <WebKit/WebView.h> |
342b0866 JF |
31 | #include <WebKit/WebPreferences-WebPrivate.h> |
32 | ||
8ce30b96 | 33 | #include <WebCycript.h> |
99c17c09 | 34 | |
5bc15b17 JF |
35 | #ifdef USE_ICU_REGEX |
36 | #include <unicode/uregex.h> | |
37 | #else | |
91fd6fae | 38 | #include <pcre.h> |
5bc15b17 | 39 | #endif |
a75dc45a | 40 | |
a1075171 JF |
41 | _disused static unsigned trace_; |
42 | ||
43 | #define _trace() do { \ | |
1c9ba76e JF |
44 | NSLog(@"_trace(%u)@%s:%u[%s](%p)\n", \ |
45 | trace_++, __FILE__, __LINE__, __FUNCTION__, pthread_self() \ | |
a1075171 JF |
46 | ); \ |
47 | } while (false) | |
48 | ||
5bc15b17 JF |
49 | typedef uint16_t UChar; |
50 | ||
51 | @interface TPBottomLockBar | |
52 | - (CGFloat) defaultHeight; | |
53 | @end | |
54 | ||
5bc15b17 | 55 | @interface UIScroller : UIView |
5bc15b17 | 56 | - (void) setDirectionalScrolling:(BOOL)directional; |
5bc15b17 JF |
57 | - (void) setScrollDecelerationFactor:(CGFloat)factor; |
58 | - (void) setScrollHysteresis:(CGFloat)hysteresis; | |
59 | - (void) setThumbDetectionEnabled:(BOOL)enabled; | |
60 | @end | |
61 | ||
62 | @interface UIWebDocumentView : UIView | |
63 | - (CGRect) documentBounds; | |
64 | - (void) enableReachability; | |
65 | - (void) loadRequest:(NSURLRequest *)request; | |
66 | - (void) redrawScaledDocument; | |
67 | - (void) setAllowsImageSheet:(BOOL)allows; | |
68 | - (void) setAllowsMessaging:(BOOL)allows; | |
69 | - (void) setAutoresizes:(BOOL)autoresizes; | |
70 | - (void) setContentsPosition:(NSInteger)position; | |
71 | - (void) setDrawsBackground:(BOOL)draws; | |
72 | - (void) _setDocumentType:(NSInteger)type; | |
73 | - (void) setDrawsGrid:(BOOL)draws; | |
74 | - (void) setInitialScale:(float)scale forDocumentTypes:(NSInteger)types; | |
75 | - (void) setLogsTilingChanges:(BOOL)logs; | |
76 | - (void) setMinimumScale:(float)scale forDocumentTypes:(NSInteger)types; | |
77 | - (void) setMinimumSize:(CGSize)size; | |
78 | - (void) setMaximumScale:(float)scale forDocumentTypes:(NSInteger)tpyes; | |
79 | - (void) setSmoothsFonts:(BOOL)smooths; | |
80 | - (void) setTileMinificationFilter:(NSString *)filter; | |
81 | - (void) setTileSize:(CGSize)size; | |
82 | - (void) setTilingEnabled:(BOOL)enabled; | |
83 | - (void) setViewportSize:(CGSize)size forDocumentTypes:(NSInteger)types; | |
84 | - (void) setZoomsFocusedFormControl:(BOOL)zooms; | |
85 | - (void) useSelectionAssistantWithMode:(NSInteger)mode; | |
86 | - (WebView *) webView; | |
87 | @end | |
88 | ||
89 | @interface UIView (Apple) | |
90 | - (UIScroller *) _scroller; | |
91 | - (void) setClipsSubviews:(BOOL)clips; | |
92 | - (void) setEnabledGestures:(NSInteger)gestures; | |
93 | - (void) setFixedBackgroundPattern:(BOOL)fixed; | |
94 | - (void) setGestureDelegate:(id)delegate; | |
95 | - (void) setNeedsDisplayOnBoundsChange:(BOOL)needs; | |
96 | - (void) setValue:(NSValue *)value forGestureAttribute:(NSInteger)attribute; | |
97 | - (void) setZoomScale:(float)scale duration:(double)duration; | |
98 | - (void) _setZoomScale:(float)scale duration:(double)duration; | |
99 | @end | |
100 | ||
0e06627b JF |
101 | @interface SBLockScreenView : UIView |
102 | - (BOOL) mediaControlsHidden; | |
103 | @end | |
104 | ||
5f249c0b JF |
105 | @interface SBLockScreenNotificationListController : NSObject |
106 | - (BOOL) hasAnyContent; | |
107 | @end | |
108 | ||
c6daf1f5 | 109 | @interface SBLockScreenViewController : UIViewController |
0e06627b | 110 | - (SBLockScreenView *) lockScreenView; |
c6daf1f5 JF |
111 | - (BOOL) isShowingMediaControls; |
112 | - (void) _setMediaControlsVisible:(BOOL)visible; | |
5f249c0b | 113 | - (SBLockScreenNotificationListController *) _notificationController; |
c6daf1f5 JF |
114 | @end |
115 | ||
116 | @interface SBLockScreenManager : NSObject | |
117 | + (SBLockScreenManager *) sharedInstance; | |
118 | - (SBLockScreenViewController *) lockScreenViewController; | |
119 | @end | |
120 | ||
342b0866 JF |
121 | @protocol CydgetController |
122 | - (NSDictionary *) currentConfiguration; | |
3215ed85 | 123 | - (NSString *) currentPath; |
342b0866 JF |
124 | @end |
125 | ||
126 | static Class $CydgetController(objc_getClass("CydgetController")); | |
127 | ||
8ce30b96 | 128 | MSClassHook(SBLockScreenManager) |
342b0866 | 129 | |
5bc15b17 JF |
130 | #ifdef USE_ICU_REGEX |
131 | /* ICU Regular Expression {{{ */ | |
132 | class RegEx { | |
133 | private: | |
134 | URegularExpression *regex_; | |
135 | ||
136 | public: | |
137 | RegEx(const char *regex) { | |
138 | UParseError error; | |
139 | UErrorCode status(U_ZERO_ERROR); | |
140 | regex_ = uregex_openC(regex, 0, &error, &status); | |
141 | if (U_FAILURE(status)) | |
142 | @throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"*** RegEx(): [%u] %s", error.offset, u_errorName(status)] userInfo:nil]; | |
143 | } | |
144 | ||
145 | ~RegEx() { | |
146 | uregex_close(regex_); | |
147 | } | |
148 | ||
149 | bool operator ()(NSString *string) { | |
150 | return operator ()(reinterpret_cast<const uint16_t *>([string cStringUsingEncoding:NSUTF16StringEncoding]), [string length]); | |
151 | } | |
152 | ||
153 | bool operator ()(const UChar *data, size_t size) { | |
154 | UErrorCode status(U_ZERO_ERROR); | |
155 | uregex_setText(regex_, data, size, &status); | |
8ce30b96 JF |
156 | if (!U_SUCCESS(status)) |
157 | return false; | |
5bc15b17 | 158 | bool matches(uregex_matches(regex_, 0, &status)); |
8ce30b96 JF |
159 | if (!U_SUCCESS(status)) |
160 | return false; | |
5bc15b17 JF |
161 | return matches; |
162 | } | |
163 | }; | |
164 | /* }}} */ | |
165 | #else | |
91fd6fae | 166 | /* Perl-Compatible RegEx {{{ */ |
5bc15b17 | 167 | class RegEx { |
91fd6fae JF |
168 | private: |
169 | pcre *code_; | |
170 | pcre_extra *study_; | |
171 | int capture_; | |
172 | int *matches_; | |
173 | const char *data_; | |
174 | ||
175 | public: | |
5bc15b17 | 176 | RegEx(const char *regex) : |
91fd6fae JF |
177 | study_(NULL) |
178 | { | |
179 | const char *error; | |
180 | int offset; | |
5bc15b17 | 181 | code_ = pcre_compile(regex, 0, &error, &offset, NULL); |
91fd6fae JF |
182 | |
183 | if (code_ == NULL) | |
5bc15b17 | 184 | @throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"*** RegEx(): [%u] %s", offset, error] userInfo:nil]; |
91fd6fae JF |
185 | |
186 | pcre_fullinfo(code_, study_, PCRE_INFO_CAPTURECOUNT, &capture_); | |
187 | matches_ = new int[(capture_ + 1) * 3]; | |
188 | } | |
189 | ||
5bc15b17 | 190 | ~RegEx() { |
91fd6fae JF |
191 | pcre_free(code_); |
192 | delete matches_; | |
193 | } | |
194 | ||
91fd6fae JF |
195 | bool operator ()(NSString *data) { |
196 | // XXX: length is for characters, not for bytes | |
197 | return operator ()([data UTF8String], [data length]); | |
198 | } | |
199 | ||
200 | bool operator ()(const char *data, size_t size) { | |
201 | data_ = data; | |
202 | return pcre_exec(code_, study_, data, size, 0, 0, matches_, (capture_ + 1) * 3) >= 0; | |
203 | } | |
204 | }; | |
205 | /* }}} */ | |
5bc15b17 | 206 | #endif |
342b0866 | 207 | |
42936531 | 208 | static float CYScrollViewDecelerationRateNormal; |
342b0866 | 209 | |
42936531 | 210 | @interface UIScrollView (Apple) |
5bc15b17 | 211 | - (void) setDecelerationRate:(CGFloat)value; |
42936531 | 212 | - (void) setScrollingEnabled:(BOOL)enabled; |
5bc15b17 | 213 | - (void) setShowBackgroundShadow:(BOOL)show; |
42936531 | 214 | @end |
342b0866 | 215 | |
42936531 | 216 | @interface UIWebView (Apple) |
5bc15b17 JF |
217 | - (UIWebDocumentView *) _documentView; |
218 | - (void) setDataDetectorTypes:(NSInteger)types; | |
03ff08c7 | 219 | - (void) _setDrawInWebThread:(BOOL)draw; |
42936531 JF |
220 | - (UIScrollView *) _scrollView; |
221 | - (UIScroller *) _scroller; | |
2430aa55 | 222 | - (void) webView:(WebView *)view addMessageToConsole:(NSDictionary *)message; |
42936531 JF |
223 | - (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame; |
224 | @end | |
342b0866 | 225 | |
42936531 JF |
226 | @interface WebView (Apple) |
227 | - (void) _setLayoutInterval:(float)interval; | |
228 | - (void) _setAllowsMessaging:(BOOL)allows; | |
229 | - (void) setShouldUpdateWhileOffscreen:(BOOL)update; | |
230 | @end | |
342b0866 | 231 | |
5bc15b17 | 232 | @protocol CydgetWebViewDelegate <UIWebViewDelegate> |
42936531 JF |
233 | - (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame; |
234 | @end | |
342b0866 | 235 | |
42936531 | 236 | @class UIWebViewWebViewDelegate; |
342b0866 | 237 | |
8ce30b96 | 238 | @interface UIWebView (WebCycript) |
f9869e67 | 239 | - (void) updateStyles; |
42936531 | 240 | @end |
342b0866 | 241 | |
8ce30b96 | 242 | @interface CydgetWebView : UIWebView { |
99c17c09 JF |
243 | } |
244 | ||
245 | @end | |
246 | ||
99c17c09 JF |
247 | @implementation CydgetWebView |
248 | ||
42936531 | 249 | - (void) webView:(WebView *)view didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { |
5bc15b17 | 250 | NSObject<CydgetWebViewDelegate> *delegate((NSObject<CydgetWebViewDelegate> *) [self delegate]); |
42936531 JF |
251 | if ([delegate respondsToSelector:@selector(webView:didClearWindowObject:forFrame:)]) |
252 | [delegate webView:view didClearWindowObject:window forFrame:frame]; | |
253 | if ([UIWebView instancesRespondToSelector:@selector(webView:didClearWindowObject:forFrame:)]) | |
254 | [super webView:view didClearWindowObject:window forFrame:frame]; | |
342b0866 JF |
255 | } |
256 | ||
2430aa55 JF |
257 | - (void) webView:(WebView *)view addMessageToConsole:(NSDictionary *)message { |
258 | NSLog(@"addMessageToConsole:%@", message); | |
ced0d2bd JF |
259 | |
260 | if ([UIWebView instancesRespondToSelector:@selector(webView:addMessageToConsole:)]) | |
261 | [super webView:view addMessageToConsole:message]; | |
2430aa55 JF |
262 | } |
263 | ||
342b0866 | 264 | @end |
342b0866 | 265 | |
5bc15b17 | 266 | @interface WebCydgetLockScreenView : UIView <UIWebViewDelegate> { |
42936531 JF |
267 | CydgetWebView *webview_; |
268 | UIScrollView *scroller_; | |
91fd6fae | 269 | NSString *cycript_; |
a1075171 JF |
270 | } |
271 | ||
f9869e67 JF |
272 | - (void) updateStyles; |
273 | ||
a1075171 JF |
274 | @end |
275 | ||
276 | @implementation WebCydgetLockScreenView | |
342b0866 JF |
277 | |
278 | //#include "UICaboodle/UCInternal.h" | |
279 | ||
280 | - (void) dealloc { | |
ef2f1af2 | 281 | [[NSNotificationCenter defaultCenter] removeObserver:self]; |
42936531 JF |
282 | [webview_ setDelegate:nil]; |
283 | [webview_ release]; | |
342b0866 JF |
284 | [super dealloc]; |
285 | } | |
286 | ||
342b0866 | 287 | - (void) loadRequest:(NSURLRequest *)request { |
42936531 | 288 | [webview_ loadRequest:request]; |
342b0866 JF |
289 | } |
290 | ||
291 | - (void) loadURL:(NSURL *)url cachePolicy:(NSURLRequestCachePolicy)policy { | |
292 | [self loadRequest:[NSURLRequest | |
293 | requestWithURL:url | |
294 | cachePolicy:policy | |
295 | timeoutInterval:30.0 | |
296 | ]]; | |
297 | } | |
298 | ||
299 | - (void) loadURL:(NSURL *)url { | |
300 | [self loadURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy]; | |
301 | } | |
302 | ||
32591608 | 303 | - (id) initWithURL:(NSURL *)url { |
5bc15b17 JF |
304 | CGRect frame = [[UIScreen mainScreen] bounds]; |
305 | if (kCFCoreFoundationVersionNumber < 800) | |
306 | frame.size.height -= 20; //[[[$SBStatusBarController sharedStatusBarController] statusBarView] frame].size.height; | |
342b0866 JF |
307 | |
308 | if ((self = [super initWithFrame:frame]) != nil) { | |
42936531 | 309 | CGRect bounds([self bounds]); |
5bc15b17 | 310 | if (kCFCoreFoundationVersionNumber < 800) |
33b26747 | 311 | bounds.size.height -= [objc_getClass("TPBottomLockBar") defaultHeight]; |
4e8fa43b | 312 | |
42936531 JF |
313 | webview_ = [[CydgetWebView alloc] initWithFrame:bounds]; |
314 | [webview_ setDelegate:self]; | |
315 | [self addSubview:webview_]; | |
2140e557 | 316 | |
42936531 JF |
317 | if ([webview_ respondsToSelector:@selector(setDataDetectorTypes:)]) |
318 | [webview_ setDataDetectorTypes:0x80000000]; | |
342b0866 | 319 | else |
42936531 | 320 | [webview_ setDetectsPhoneNumbers:NO]; |
342b0866 | 321 | |
42936531 | 322 | [webview_ setScalesPageToFit:YES]; |
342b0866 | 323 | |
7c019f4a JF |
324 | if (kCFCoreFoundationVersionNumber < 478.61) |
325 | if ([webview_ respondsToSelector:@selector(_setDrawInWebThread:)]) | |
326 | [webview_ _setDrawInWebThread:NO]; | |
03ff08c7 | 327 | |
42936531 JF |
328 | UIWebDocumentView *document([webview_ _documentView]); |
329 | WebView *webview([document webView]); | |
330 | WebPreferences *preferences([webview preferences]); | |
342b0866 | 331 | |
42936531 | 332 | [document setTileSize:CGSizeMake(bounds.size.width, 500)]; |
342b0866 | 333 | |
5bc15b17 | 334 | [document setBackgroundColor:[UIColor clearColor]]; |
42936531 | 335 | [document setDrawsBackground:NO]; |
342b0866 | 336 | |
42936531 | 337 | [webview setPreferencesIdentifier:@"WebCycript"]; |
342b0866 JF |
338 | |
339 | if ([webview respondsToSelector:@selector(_setLayoutInterval:)]) | |
340 | [webview _setLayoutInterval:0]; | |
341 | else | |
342 | [preferences _setLayoutInterval:0]; | |
343 | ||
42936531 JF |
344 | [preferences setCacheModel:WebCacheModelDocumentViewer]; |
345 | [preferences setJavaScriptCanOpenWindowsAutomatically:YES]; | |
346 | [preferences setOfflineWebApplicationCacheEnabled:YES]; | |
342b0866 | 347 | |
42936531 JF |
348 | if ([webview respondsToSelector:@selector(setShouldUpdateWhileOffscreen:)]) |
349 | [webview setShouldUpdateWhileOffscreen:NO]; | |
d826762d | 350 | |
42936531 JF |
351 | if ([document respondsToSelector:@selector(setAllowsMessaging:)]) |
352 | [document setAllowsMessaging:YES]; | |
353 | if ([webview respondsToSelector:@selector(_setAllowsMessaging:)]) | |
354 | [webview _setAllowsMessaging:YES]; | |
342b0866 | 355 | |
42936531 JF |
356 | if ([webview_ respondsToSelector:@selector(_scrollView)]) { |
357 | scroller_ = [webview_ _scrollView]; | |
342b0866 | 358 | |
42936531 JF |
359 | [scroller_ setDirectionalLockEnabled:YES]; |
360 | [scroller_ setDecelerationRate:CYScrollViewDecelerationRateNormal]; | |
361 | [scroller_ setDelaysContentTouches:NO]; | |
342b0866 | 362 | |
42936531 | 363 | [scroller_ setCanCancelContentTouches:YES]; |
fdadc3a3 JF |
364 | |
365 | [scroller_ setAlwaysBounceVertical:NO]; | |
42936531 JF |
366 | } else if ([webview_ respondsToSelector:@selector(_scroller)]) { |
367 | UIScroller *scroller([webview_ _scroller]); | |
368 | scroller_ = (UIScrollView *) scroller; | |
342b0866 | 369 | |
42936531 JF |
370 | [scroller setDirectionalScrolling:YES]; |
371 | [scroller setScrollDecelerationFactor:CYScrollViewDecelerationRateNormal]; /* 0.989324 */ | |
372 | [scroller setScrollHysteresis:0]; /* 8 */ | |
342b0866 | 373 | |
42936531 JF |
374 | [scroller setThumbDetectionEnabled:NO]; |
375 | } | |
342b0866 | 376 | |
5bc15b17 JF |
377 | [webview_ setOpaque:NO]; |
378 | [webview_ setBackgroundColor:[UIColor clearColor]]; | |
379 | ||
42936531 | 380 | [scroller_ setFixedBackgroundPattern:YES]; |
5bc15b17 | 381 | [scroller_ setBackgroundColor:[UIColor clearColor]]; |
42936531 | 382 | [scroller_ setClipsSubviews:NO]; |
342b0866 | 383 | |
42936531 JF |
384 | [scroller_ setBounces:YES]; |
385 | [scroller_ setShowBackgroundShadow:NO]; /* YES */ | |
342b0866 | 386 | |
42936531 JF |
387 | [self setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)]; |
388 | [webview_ setAutoresizingMask:(UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight)]; | |
342b0866 JF |
389 | |
390 | NSDictionary *configuration([$CydgetController currentConfiguration]); | |
17854c1a | 391 | cycript_ = [configuration objectForKey:@"CycriptURLs"]; |
545370d8 | 392 | |
42936531 | 393 | [scroller_ setScrollingEnabled:[[configuration objectForKey:@"Scrollable"] boolValue]]; |
545370d8 | 394 | |
32591608 | 395 | [self loadURL:url]; |
ef2f1af2 JF |
396 | |
397 | [[NSNotificationCenter defaultCenter] | |
398 | addObserver:self | |
399 | selector:@selector(mediaControlsDidSomething:) | |
400 | name:@"SBLockScreenViewControllerMediaControlsDidShow" | |
401 | object:nil | |
402 | ]; | |
403 | ||
404 | [[NSNotificationCenter defaultCenter] | |
405 | addObserver:self | |
406 | selector:@selector(mediaControlsDidSomething:) | |
407 | name:@"SBLockScreenViewControllerMediaControlsDidHide" | |
408 | object:nil | |
409 | ]; | |
342b0866 JF |
410 | } return self; |
411 | } | |
412 | ||
ef2f1af2 JF |
413 | - (void) mediaControlsDidSomething:(NSNotification *)notification { |
414 | [self updateStyles]; | |
415 | } | |
416 | ||
42936531 | 417 | - (void) webView:(WebView *)webview didClearWindowObject:(WebScriptObject *)window forFrame:(WebFrame *)frame { |
91fd6fae JF |
418 | if (cycript_ != nil) |
419 | if (NSString *href = [[[[frame dataSource] request] URL] absoluteString]) | |
5bc15b17 | 420 | if (RegEx([cycript_ UTF8String])(href)) |
8ce30b96 | 421 | WebCycriptSetupView(webview); |
342b0866 JF |
422 | } |
423 | ||
f9869e67 JF |
424 | - (void) updateStyles { |
425 | [webview_ updateStyles]; | |
426 | } | |
427 | ||
a1075171 JF |
428 | @end |
429 | ||
430 | @interface WebCycriptLockScreenController : SBAwayViewPluginController { | |
32591608 | 431 | NSDictionary *configuration_; |
cf677acc JF |
432 | bool legacy_; |
433 | bool media_; | |
434 | bool items_; | |
32591608 | 435 | WebCydgetLockScreenView *background_; |
0e06627b | 436 | WebCydgetLockScreenView *foreground_; |
a1075171 JF |
437 | } |
438 | ||
439 | @end | |
440 | ||
8ce30b96 | 441 | static BOOL CYHaveMediaControls() { |
a143e10b JF |
442 | SBLockScreenView *view([[[$SBLockScreenManager sharedInstance] lockScreenViewController] lockScreenView]); |
443 | return view != nil && ![view mediaControlsHidden]; | |
444 | //return [[[$SBLockScreenManager sharedInstance] lockScreenViewController] isShowingMediaControls]; | |
445 | } | |
446 | ||
8ce30b96 | 447 | static BOOL CYHaveNotificationList() { |
a143e10b JF |
448 | SBLockScreenNotificationListController *controller([[[$SBLockScreenManager sharedInstance] lockScreenViewController] _notificationController]); |
449 | return controller != nil && [controller hasAnyContent]; | |
450 | } | |
451 | ||
2430aa55 JF |
452 | static void $UIWebViewWebViewDelegate$webView$addMessageToConsole$(UIWebViewWebViewDelegate *self, SEL sel, WebView *view, NSDictionary *message) { |
453 | UIWebView *uiWebView(MSHookIvar<UIWebView *>(self, "uiWebView")); | |
454 | if ([uiWebView respondsToSelector:@selector(webView:addMessageToConsole:)]) | |
455 | [uiWebView webView:view addMessageToConsole:message]; | |
456 | } | |
457 | ||
42936531 JF |
458 | static void $UIWebViewWebViewDelegate$webView$didClearWindowObject$forFrame$(UIWebViewWebViewDelegate *self, SEL sel, WebView *view, WebScriptObject *window, WebFrame *frame) { |
459 | UIWebView *uiWebView(MSHookIvar<UIWebView *>(self, "uiWebView")); | |
460 | if ([uiWebView respondsToSelector:@selector(webView:didClearWindowObject:forFrame:)]) | |
461 | [uiWebView webView:view didClearWindowObject:window forFrame:frame]; | |
462 | } | |
463 | ||
8ce30b96 | 464 | MSInitialize { |
2430aa55 JF |
465 | if (Class $UIWebViewWebViewDelegate = objc_getClass("UIWebViewWebViewDelegate")) { |
466 | class_addMethod($UIWebViewWebViewDelegate, @selector(webView:addMessageToConsole:), (IMP) &$UIWebViewWebViewDelegate$webView$addMessageToConsole$, "v16@0:4@8@12"); | |
42936531 | 467 | class_addMethod($UIWebViewWebViewDelegate, @selector(webView:didClearWindowObject:forFrame:), (IMP) &$UIWebViewWebViewDelegate$webView$didClearWindowObject$forFrame$, "v20@0:4@8@12@16"); |
2430aa55 | 468 | } |
42936531 | 469 | |
5bc15b17 | 470 | if (CGFloat *_UIScrollViewDecelerationRateNormal = reinterpret_cast<CGFloat *>(dlsym(RTLD_DEFAULT, "UIScrollViewDecelerationRateNormal"))) |
42936531 JF |
471 | CYScrollViewDecelerationRateNormal = *_UIScrollViewDecelerationRateNormal; |
472 | else // XXX: this actually might be fast on some older systems: we should look into this | |
473 | CYScrollViewDecelerationRateNormal = 0.998; | |
474 | ||
8ce30b96 JF |
475 | if (kCFCoreFoundationVersionNumber >= 800) { |
476 | WebCycriptRegisterStyle("-cydget-media-controls", &CYHaveMediaControls); | |
477 | WebCycriptRegisterStyle("-cydget-notification-list", &CYHaveNotificationList); | |
89afbf46 | 478 | } |
a75dc45a JF |
479 | } |
480 | ||
8ce30b96 JF |
481 | @implementation WebCycriptLockScreenController |
482 | ||
a1075171 JF |
483 | + (id) rootViewController { |
484 | return [[[self alloc] init] autorelease]; | |
485 | } | |
486 | ||
32591608 JF |
487 | - (void) dealloc { |
488 | [configuration_ release]; | |
489 | [background_ release]; | |
a522309c | 490 | [foreground_ release]; |
32591608 JF |
491 | [super dealloc]; |
492 | } | |
493 | ||
494 | - (id) init { | |
495 | if ((self = [super init]) != nil) { | |
496 | configuration_ = [[$CydgetController currentConfiguration] retain]; | |
cf677acc JF |
497 | legacy_ = [configuration_ objectForKey:@"Background"] == nil; |
498 | media_ = [[configuration_ objectForKey:@"MediaControls"] boolValue]; | |
499 | items_ = [[configuration_ objectForKey:@"NotificationList"] boolValue]; | |
32591608 JF |
500 | } return self; |
501 | } | |
502 | ||
a1075171 | 503 | - (void) loadView { |
3215ed85 JF |
504 | NSURL *base([NSURL fileURLWithPath:[$CydgetController currentPath]]); |
505 | ||
32591608 | 506 | if (NSString *background = [configuration_ objectForKey:@"Background"]) |
3215ed85 | 507 | background_ = [[WebCydgetLockScreenView alloc] initWithURL:[NSURL URLWithString:background relativeToURL:base]]; |
7c87949d | 508 | |
0e06627b JF |
509 | if (NSString *homepage = [configuration_ objectForKey:@"Homepage"]) { |
510 | foreground_ = [[WebCydgetLockScreenView alloc] initWithURL:[NSURL URLWithString:homepage relativeToURL:base]]; | |
511 | [self setView:foreground_]; | |
7c87949d | 512 | } |
32591608 JF |
513 | } |
514 | ||
515 | - (void) purgeView { | |
516 | [background_ removeFromSuperview]; | |
517 | [background_ release]; | |
518 | background_ = nil; | |
0e06627b JF |
519 | [foreground_ removeFromSuperview]; |
520 | [foreground_ release]; | |
521 | foreground_ = nil; | |
32591608 JF |
522 | [super purgeView]; |
523 | } | |
524 | ||
f9869e67 JF |
525 | - (void) updateStyles { |
526 | [foreground_ updateStyles]; | |
527 | [background_ updateStyles]; | |
528 | } | |
529 | ||
32591608 JF |
530 | - (UIView *) backgroundView { |
531 | return background_; | |
a1075171 JF |
532 | } |
533 | ||
3a03af6c | 534 | - (BOOL) showAwayItems { |
d9265502 | 535 | return YES; |
3a03af6c JF |
536 | } |
537 | ||
0e06627b JF |
538 | - (BOOL) updateHidden { |
539 | if (foreground_ == nil) | |
540 | return true; | |
cf677acc | 541 | bool media(CYHaveMediaControls()); |
0e06627b JF |
542 | [foreground_ setHidden:media]; |
543 | return media; | |
544 | } | |
545 | ||
32591608 | 546 | - (BOOL) showDateView { |
0e06627b | 547 | if (kCFCoreFoundationVersionNumber < 800) |
cf677acc JF |
548 | return false; |
549 | [self updateStyles]; | |
550 | if (!legacy_ && foreground_ == nil) | |
551 | return true; | |
552 | if (!items_ && CYHaveNotificationList()) | |
0e06627b | 553 | return true; |
cf677acc | 554 | return false; |
0e06627b JF |
555 | } |
556 | ||
557 | - (BOOL) allowsLockScreenMediaControls { | |
558 | if (kCFCoreFoundationVersionNumber < 800) | |
559 | return true; | |
cf677acc | 560 | return media_; |
32591608 JF |
561 | } |
562 | ||
563 | /*- (BOOL) showHeaderView { | |
564 | return YES; | |
565 | }*/ | |
566 | ||
cf677acc JF |
567 | // 0: view is rendered above head |
568 | // 1: view moves as one with head | |
569 | // 2: view moves up and down only | |
570 | // 3: view simply never does move | |
32591608 JF |
571 | - (NSUInteger) presentationStyle { |
572 | return 1; | |
573 | } | |
574 | ||
cf677acc JF |
575 | // 1: light blur |
576 | // 2: heavy blur | |
577 | // 3: just black | |
578 | // 4: legibility | |
579 | // 5: no overlay | |
32591608 | 580 | - (NSUInteger) overlayStyle { |
cf677acc | 581 | return legacy_ ? 1 : 4; |
32591608 JF |
582 | } |
583 | ||
cf677acc JF |
584 | // 1: blur -> view -> list |
585 | // 2: view -> blur -> list | |
586 | // 3: view. unblur below?! | |
587 | // 4: blur -> list -> view | |
0e06627b | 588 | - (NSUInteger) notificationBehavior { |
cf677acc | 589 | return items_ ? 1 : 2; |
0e06627b JF |
590 | } |
591 | ||
5bc15b17 JF |
592 | - (BOOL) viewWantsFullscreenLayout { |
593 | return kCFCoreFoundationVersionNumber >= 800; | |
594 | } | |
595 | ||
32591608 JF |
596 | /*- (BOOL) viewWantsOverlayLayout { |
597 | return kCFCoreFoundationVersionNumber >= 800; | |
598 | }*/ | |
599 | ||
5bc15b17 JF |
600 | - (BOOL) shouldDisableOnUnlock { |
601 | return YES; | |
602 | } | |
603 | ||
604 | - (BOOL) canBeAlwaysFullscreen { | |
605 | return YES; | |
606 | } | |
607 | ||
32591608 JF |
608 | /*- (BOOL) wantsSwipeGestureRecognizer { |
609 | return YES; | |
610 | } | |
611 | ||
612 | - (BOOL) handleGesture:(int)arg1 fingerCount:(NSUInteger)fingers { | |
613 | return NO; | |
614 | return YES; | |
615 | }*/ | |
616 | ||
0e06627b JF |
617 | // - (void) lockScreenMediaControlsShown:(BOOL)shown; |
618 | ||
c6daf1f5 JF |
619 | - (BOOL) handleMenuButtonDoubleTap { |
620 | if (kCFCoreFoundationVersionNumber >= 800) { | |
621 | SBLockScreenViewController *controller([[$SBLockScreenManager sharedInstance] lockScreenViewController]); | |
622 | [controller _setMediaControlsVisible:![controller isShowingMediaControls]]; | |
623 | } | |
624 | ||
625 | return [super handleMenuButtonDoubleTap]; | |
626 | } | |
627 | ||
a1075171 | 628 | @end |