1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
|
//
// webman.m
// webkitexplorer
//
// Created by mark williamson on 09/09/2008.
// Copyright 2008 hanzo archives. All rights reserved.
//
#import "webman.h"
@implementation webman
-(void) awakeFromNib {
// we don't need a page history and it uses resources
//[wv setMaintainsBackForwardList:NO];
// this is just me being lazy - got bored of typing in a
// test url
[urlin setStringValue:@"http://www.dronten.nl/"];
[clicks setEnabled:NO];
}
// clear the text area
- (void) clearText {
NSAttributedString *s = [[NSAttributedString alloc] initWithString: @""];
[[otext textStorage] setAttributedString: s ];
}
// simple util to shove a string at the end of my output text
- (void) appendString: (NSString *) str {
NSRange endRange;
endRange.location =[[otext textStorage] length];
endRange.length = 0;
[otext replaceCharactersInRange:endRange withString: str ];
}
// shove a red string in
- (void) appendRedString: (NSString *) str {
NSRange endRange;
endRange.location =[[otext textStorage] length];
endRange.length = 0;
[otext replaceCharactersInRange:endRange withString: str ];
endRange.length = [str length];
[otext setTextColor:[NSColor redColor] range: endRange];
}
// the only way to load a page. Clicking is disabled the second we have
// the page loaded
- (IBAction) doGo: (id) sender {
NSURL *urltogo = [NSURL URLWithString:[urlin stringValue]];
[self clearText];
[self appendRedString:@"requesting...\n"];
[clicks setEnabled:NO];
loaded=FALSE;
partcount=0;
[[wv mainFrame] loadRequest:[NSURLRequest requestWithURL:urltogo]];
}
// these are the page assets. It picks up all the stuff for XML as well and javascript
// requests etc. so these are all valuable
- (id)webView:(WebView *)sender
identifierForInitialRequest:(NSURLRequest *)request fromDataSource:(WebDataSource
*)dataSource
{
NSString *urls = [NSString stringWithFormat: @" %@ \n" , [[request URL] absoluteString]];
[self appendString:urls];
return [NSNumber numberWithInt:resourceCount++];
}
// not getting the error message for some reason
- (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame {
NSString *es = [NSString stringWithFormat: @"Unable to load\n%@\n" , [error localizedDescription] ];
[self appendRedString:es];
}
- (void)webView:(WebView *)sender didReceiveServerRedirectForProvisionalLoadForFrame:(WebFrame *)frame {
// not sure if this is relevant but keeping an eye out for it
[self appendRedString: @"redirecting....\n" ];
redirect = TRUE;
}
- (void)webView:(WebView *)sender
willPerformClientRedirectToURL:(NSURL *)URL
delay:(NSTimeInterval)seconds
fireDate:(NSDate *)date
forFrame:(WebFrame *)frame {
// not sure if this is relevant but keeping an eye out for it
[self appendRedString: @"redirecting....\n" ];
redirect = TRUE;
}
// pages can be made up of parts (frames) - count them in
- (void)webView:(WebView *)sender didStartProvisionalLoadForFrame:(WebFrame *)frame {
[self appendRedString: @"start page load\n" ];
partcount += 1;
}
// and count them out. When they are all done we are loaded
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame {
[self appendRedString: @"page loaded\n" ];
partcount -= 1;
if ( partcount == 0 && !redirect) {
loaded=TRUE;
[clicks setEnabled:YES];
}
if (partcount == 0 && redirect ) {
redirect=FALSE;
}
}
// once we are loaded we don't want to let clicks work - all we are interested in
// is the url of the request
- (void) webView:(WebView *)sender
decidePolicyForNavigationAction:(NSDictionary *)actionInformation
request:(NSURLRequest *)request
frame:(WebFrame *)frame
decisionListener:(id)listener {
NSString *reqs = [NSString stringWithFormat: @"%@ \n" , [[request URL] absoluteString]];
[self appendString:reqs];
if (!loaded) {
[listener use];
} else {
[listener ignore];
}
}
// we need to traverse the document
// the DOMNodeIterator gets us a flattened representation of the DOM tree
// which is all we need for now
// Frames are nested documents though so we detect these and recurisvely all this function
//
// We make a new mouse click event for each node - the event has a life time and a result as far as I can tell
// so it is not reusable
//
// note as well that I rely on the OS X 1.5 garbage collector rather than doing any object managment
//
- (void) traverse: (DOMDocument*) doc {
DOMNodeIterator *iter = [doc createNodeIterator:[doc firstChild] whatToShow:DOM_SHOW_ALL filter:nil expandEntityReferences:NO];
DOMNode* node;
while ((node = [iter nextNode]) != nil) {
DOMMouseEvent *evt = (DOMMouseEvent*)[doc createEvent:@"MouseEvent"];
[evt initMouseEvent:@"click"canBubble:TRUE cancelable:TRUE view:[doc defaultView] detail:0 screenX:0 screenY:0 clientX:0 clientY:0 ctrlKey:FALSE altKey:FALSE shiftKey:FALSE metaKey:FALSE button:0 relatedTarget:nil];
[node dispatchEvent: evt];
if ( [[node localName] isEqualToString: @"frame"] ) {
DOMHTMLFrameElement *frame = (DOMHTMLFrameElement*)node;
[self traverse:[frame contentDocument]];
}
}
}
// this is the function called by the 'clicks' button
// we dig our DOMDocument reference out of the webkit and traverse it
// displaying a little bit of progress information before and afterwards
//
// Note that the DOM we are playing with here is the same as the one available inside the browser in javascript
// the big difference in this app is that we are able to constrain and listen to the embeded browser using the policies and
// the delegates
- (IBAction) doClicks: (id) sender {
[self appendRedString:@"clicks...\n"];
DOMDocument *doc = [[wv mainFrame] DOMDocument];
[self traverse:doc ];
[self appendRedString:@"done\n"];
}
@end |
Partager