00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 @import "CPView.j"
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 CPWebViewProgressStartedNotification = "CPWebViewProgressStartedNotification";
00036 CPWebViewProgressFinishedNotification = "CPWebViewProgressFinishedNotification";
00037
00038
00039
00040 @implementation CPWebView : CPView
00041 {
00042 IFrame _iframe;
00043 CPString _mainFrameURL;
00044 CPArray _backwardStack;
00045 CPArray _forwardStack;
00046
00047 BOOL _ignoreLoadEvent;
00048
00049 id _downloadDelegate;
00050 id _frameLoadDelegate;
00051 id _policyDelegate;
00052 id _resourceLoadDelegate;
00053 id _UIDelegate;
00054
00055 CPWebScriptObject _wso;
00056 }
00057
00058 - (id)initWithFrame:(CPRect)frameRect frameName:(CPString)frameName groupName:(CPString)groupName
00059 {
00060 if (self = [self initWithFrame:frameRect])
00061 {
00062 _iframe.name = frameName;
00063 }
00064 return self
00065 }
00066
00067 - (id)initWithFrame:(CPRect)aFrame
00068 {
00069 if (self = [super initWithFrame:aFrame])
00070 {
00071 _mainFrameURL = nil;
00072 _backwardStack = [];
00073 _forwardStack = [];
00074 [self _initDOMWithFrame:aFrame];
00075 }
00076
00077 return self;
00078 }
00079
00080 - (id)_initDOMWithFrame:(CPRect)aFrame
00081 {
00082 _ignoreLoadEvent = NO;
00083
00084 _iframe = document.createElement("iframe");
00085 _iframe.name = "iframe_" + Math.floor(Math.random()*10000);
00086 _iframe.style.width = "100%";
00087 _iframe.style.height = "100%";
00088 _iframe.style.borderWidth = "0px";
00089 [self setDrawsBackground:YES];
00090
00091 var loadCallback = function() {
00092
00093 if (!_ignoreLoadEvent)
00094 {
00095
00096 [self _startedLoading];
00097
00098 if (_mainFrameURL)
00099 [_backwardStack addObject:_mainFrameURL];
00100
00101
00102 _mainFrameURL = _iframe.src;
00103
00104 [_forwardStack removeAllObjects];
00105 }
00106 _ignoreLoadEvent = NO;
00107
00108 [self _finishedLoading]
00109 }
00110
00111 if (_iframe.addEventListener)
00112 _iframe.addEventListener("load", loadCallback, false);
00113 else if (_iframe.attachEvent)
00114 _iframe.attachEvent("onload", loadCallback);
00115
00116 _DOMElement.appendChild(_iframe);
00117 }
00118
00119
00120
00121 - (IBAction)takeStringURLFrom:(id)sender
00122 {
00123 [self setMainFrameURL:[sender stringValue]];
00124 }
00125
00126 - (IBAction)goBack:(id)sender
00127 {
00128 [self goBack];
00129 }
00130
00131 - (IBAction)goForward:(id)sender
00132 {
00133 [self goForward];
00134 }
00135
00136 - (IBAction)stopLoading:(id)sender
00137 {
00138
00139 }
00140
00141 - (IBAction)reload:(id)sender
00142 {
00143 [self _loadMainFrameURL];
00144 }
00145
00146 - (IBAction)print:(id)sender
00147 {
00148 try
00149 {
00150 [self window].print();
00151 }
00152 catch (e)
00153 {
00154 alert('Please click the webpage and select "Print" from the "File" menu');
00155 }
00156 }
00157
00158
00159 - (BOOL)drawsBackground
00160 {
00161 return _iframe.style.backgroundColor != "";
00162 }
00163
00164 - (void)setDrawsBackground:(BOOL)drawsBackround
00165 {
00166 _iframe.style.backgroundColor = drawsBackround ? "white" : "";
00167 }
00168
00169 - (void)_loadMainFrameURL
00170 {
00171 [self _startedLoading];
00172
00173 _ignoreLoadEvent = YES;
00174 _iframe.src = _mainFrameURL;
00175 }
00176
00177 - (void)_startedLoading
00178 {
00179 [[CPNotificationCenter defaultCenter] postNotificationName:CPWebViewProgressStartedNotification object:self];
00180
00181 if ([_frameLoadDelegate respondsToSelector:@selector(webView:didStartProvisionalLoadForFrame:)])
00182 [_frameLoadDelegate webView:self didStartProvisionalLoadForFrame:nil];
00183 }
00184
00185 - (void)_finishedLoading
00186 {
00187 [[CPNotificationCenter defaultCenter] postNotificationName:CPWebViewProgressFinishedNotification object:self];
00188
00189 if ([_frameLoadDelegate respondsToSelector:@selector(webView:didFinishLoadForFrame:)])
00190 [_frameLoadDelegate webView:self didFinishLoadForFrame:nil];
00191 }
00192
00193 - (CPString)mainFrameURL
00194 {
00195 return _mainFrameURL;
00196 }
00197
00198 - (void)setMainFrameURL:(CPString)URLString
00199 {
00200 if (_mainFrameURL)
00201 [_backwardStack addObject:_mainFrameURL];
00202 _mainFrameURL = URLString;
00203 [_forwardStack removeAllObjects];
00204
00205 [self _loadMainFrameURL];
00206 }
00207
00208 - (BOOL)goBack
00209 {
00210 if (_backwardStack.length > 0)
00211 {
00212 if (_mainFrameURL)
00213 [_forwardStack addObject:_mainFrameURL];
00214 _mainFrameURL = [_backwardStack lastObject];
00215 [_backwardStack removeLastObject];
00216
00217 [self _loadMainFrameURL];
00218
00219 return YES;
00220 }
00221 return NO;
00222 }
00223
00224 - (BOOL)goForward
00225 {
00226 if (_forwardStack.length > 0)
00227 {
00228 if (_mainFrameURL)
00229 [_backwardStack addObject:_mainFrameURL];
00230 _mainFrameURL = [_forwardStack lastObject];
00231 [_forwardStack removeLastObject];
00232
00233 [self _loadMainFrameURL];
00234
00235 return YES;
00236 }
00237 return NO;
00238 }
00239
00240 - (BOOL)canGoBack
00241 {
00242 return (_backwardStack.length > 0);
00243 }
00244
00245 - (BOOL)canGoForward
00246 {
00247 return (_forwardStack.length > 0);
00248 }
00249
00250 - (WebBackForwardList)backForwardList
00251 {
00252
00253 return { back: _backwardStack, forward: _forwardStack };
00254 }
00255
00256 - (void)close
00257 {
00258 _DOMElement.removeChild(_iframe);
00259 }
00260
00261 - (Window)window
00262 {
00263 return (_iframe.contentDocument && _iframe.contentDocument.defaultView) || _iframe.contentWindow;
00264 }
00265
00266 - (CPWebScriptObject)windowScriptObject
00267 {
00268 var win = [self window];
00269 if (!_wso || win != [_wso window])
00270 {
00271 if (win)
00272 _wso = [[CPWebScriptObject alloc] initWithWindow:win];
00273 else
00274 _wso = nil;
00275 }
00276 return _wso;
00277 }
00278
00279 - (CPString)stringByEvaluatingJavaScriptFromString:(CPString)script
00280 {
00281 var result = [self objectByEvaluatingJavaScriptFromString:script];
00282 return result ? String(result) : nil;
00283 }
00284
00285 - (JSObject)objectByEvaluatingJavaScriptFromString:(CPString)script
00286 {
00287 return [[self windowScriptObject] evaluateWebScript:script];
00288 }
00289
00290 - (DOMCSSStyleDeclaration)computedStyleForElement:(DOMElement)element pseudoElement:(CPString)pseudoElement
00291 {
00292 var win = [[self windowScriptObject] window];
00293 if (win)
00294 {
00295
00296 return win.document.defaultView.getComputedStyle(element, pseudoElement);
00297 }
00298 return nil;
00299 }
00300
00301
00302
00303
00304
00305 - (id)downloadDelegate
00306 {
00307 return _downloadDelegate;
00308 }
00309 - (void)setDownloadDelegate:(id)anObject
00310 {
00311 _downloadDelegate = anObject;
00312 }
00313 - (id)frameLoadDelegate
00314 {
00315 return _frameLoadDelegate;
00316 }
00317 - (void)setFrameLoadDelegate:(id)anObject
00318 {
00319 _frameLoadDelegate = anObject;
00320 }
00321 - (id)policyDelegate
00322 {
00323 return _policyDelegate;
00324 }
00325 - (void)setPolicyDelegate:(id)anObject
00326 {
00327 _policyDelegate = anObject;
00328 }
00329 - (id)resourceLoadDelegate
00330 {
00331 return _resourceLoadDelegate;
00332 }
00333 - (void)setResourceLoadDelegate:(id)anObject
00334 {
00335 _resourceLoadDelegate = anObject;
00336 }
00337 - (id)UIDelegate
00338 {
00339 return _UIDelegate;
00340 }
00341 - (void)setUIDelegate:(id)anObject
00342 {
00343 _UIDelegate = anObject;
00344 }
00345
00346
00347 - (void)loadHTMLString:(CPString)aString
00348 {
00349 [self loadHTMLString:aString baseURL:nil];
00350 }
00351
00352 - (void)loadHTMLString:(CPString)aString baseURL:(CPURL)URL
00353 {
00354
00355
00356
00357 _iframe.src = "";
00358
00359
00360 window.setTimeout(function() {
00361 var win = [self window];
00362 win.document.write(aString);
00363 }, 0);
00364 }
00365
00366 @end
00367
00368
00369 @implementation CPWebScriptObject : CPObject
00370 {
00371 Window _window;
00372 }
00373
00374 - (id)initWithWindow:(Window)aWindow
00375 {
00376 if (self = [super init])
00377 {
00378 _window = aWindow
00379 }
00380 return self;
00381 }
00382
00383 - (id)callWebScriptMethod:(CPString)methodName withArguments:(CPArray)args
00384 {
00385
00386 if (typeof _window[methodName] == "function")
00387 {
00388 try {
00389 return _window[methodName].apply(args);
00390 } catch (e) {
00391 }
00392 }
00393 return undefined;
00394 }
00395
00396 - (id)evaluateWebScript:(CPString)script
00397 {
00398 try {
00399 return _window.eval(script);
00400 } catch (e) {
00401 }
00402 return undefined;
00403 }
00404
00405 - (Window)window
00406 {
00407 return _window;
00408 }
00409
00410 @end
00411
00412
00413 @implementation CPWebView (CPCoding)
00414
00420 - (id)initWithCoder:(CPCoder)aCoder
00421 {
00422 self = [super initWithCoder:aCoder];
00423
00424 if (self)
00425 {
00426
00427 _mainFrameURL = nil;
00428 _backwardStack = [];
00429 _forwardStack = [];
00430
00431 [self _initDOMWithFrame:[self frame]];
00432 }
00433
00434 return self;
00435 }
00436
00441 - (void)encodeWithCoder:(CPCoder)aCoder
00442 {
00443 [super encodeWithCoder:aCoder];
00444 }
00445
00446 @end