rhack 1.2.1 → 1.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +13 -5
  2. data/README.md +21 -9
  3. data/ext/curb/curb.c +977 -977
  4. data/ext/curb/curb.h +52 -52
  5. data/ext/curb/curb_config.h +270 -270
  6. data/ext/curb/curb_easy.c +3437 -3434
  7. data/ext/curb/curb_easy.h +94 -94
  8. data/ext/curb/curb_errors.c +647 -647
  9. data/ext/curb/curb_errors.h +129 -129
  10. data/ext/curb/curb_macros.h +162 -162
  11. data/ext/curb/curb_multi.c +704 -702
  12. data/ext/curb/curb_multi.h +26 -26
  13. data/ext/curb/curb_postfield.c +523 -523
  14. data/ext/curb/curb_postfield.h +40 -40
  15. data/ext/curb/curb_upload.c +80 -80
  16. data/ext/curb/curb_upload.h +30 -30
  17. data/ext/curb-original/curb.c +977 -977
  18. data/ext/curb-original/curb.h +52 -52
  19. data/ext/curb-original/curb_config.h +238 -238
  20. data/ext/curb-original/curb_easy.c +3404 -3404
  21. data/ext/curb-original/curb_easy.h +90 -90
  22. data/ext/curb-original/curb_errors.c +647 -647
  23. data/ext/curb-original/curb_errors.h +129 -129
  24. data/ext/curb-original/curb_macros.h +159 -159
  25. data/ext/curb-original/curb_multi.c +633 -633
  26. data/ext/curb-original/curb_multi.h +26 -26
  27. data/ext/curb-original/curb_postfield.c +523 -523
  28. data/ext/curb-original/curb_postfield.h +40 -40
  29. data/ext/curb-original/curb_upload.c +80 -80
  30. data/ext/curb-original/curb_upload.h +30 -30
  31. data/lib/rhack/clients/base.rb +61 -10
  32. data/lib/rhack/clients/oauth.rb +4 -4
  33. data/lib/rhack/curl/easy.rb +1 -0
  34. data/lib/rhack/curl/global.rb +2 -0
  35. data/lib/rhack/curl/response.rb +4 -2
  36. data/lib/rhack/frame.rb +70 -32
  37. data/lib/rhack/js/browser/env.js +697 -697
  38. data/lib/rhack/js/browser/jquery.js +7180 -7180
  39. data/lib/rhack/js/browser/xmlsax.js +1564 -1564
  40. data/lib/rhack/js/browser/xmlw3cdom_1.js +1443 -1443
  41. data/lib/rhack/js/browser/xmlw3cdom_2.js +2744 -2744
  42. data/lib/rhack/page.rb +227 -68
  43. data/lib/rhack/scout.rb +52 -26
  44. data/lib/rhack/scout_squad.rb +10 -2
  45. data/lib/rhack/version.rb +1 -1
  46. data/rhack.gemspec +1 -1
  47. metadata +17 -17
@@ -1,697 +1,697 @@
1
- /*
2
- * Simulated browser environment for Rhino
3
- * By John Resig <http://ejohn.org/>
4
- * Copyright 2007 John Resig, under the MIT License
5
- */
6
-
7
- // The window Object
8
- var window = this;
9
-
10
- //Ruby.require("uri");
11
-
12
- print = function(txt) { Ruby.puts(txt); };
13
-
14
- (function(){
15
-
16
- // Browser Navigator
17
-
18
- window.navigator = {
19
- get userAgent(){
20
- return "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3";
21
- }
22
- };
23
- /*
24
- var fileToUrl = function(file) {
25
- return Ruby.URI.parse("file://" + Ruby.File.expand_path(file));
26
- };
27
-
28
- var curLocation = fileToUrl(".");
29
- /*
30
- window.__defineSetter__("location", function(url){
31
- var xhr = new XMLHttpRequest();
32
- xhr.open("GET", url);
33
- xhr.onreadystatechange = function(){
34
- curLocation = curLocation.merge(url);
35
- window.document = xhr.responseXML;
36
-
37
- if(window.document) {
38
- var event = document.createEvent();
39
- event.initEvent("load");
40
- window.dispatchEvent( event );
41
- }
42
- };
43
- xhr.send();
44
- });
45
-
46
- window.__defineGetter__("location", function(url){
47
- return {
48
- get protocol(){
49
- return curLocation.scheme() + ":";
50
- },
51
- get href(){
52
- return curLocation.toString();
53
- },
54
- toString: function(){
55
- return this.href.toString();
56
- }
57
- };
58
- });
59
- */
60
-
61
- // Timers
62
-
63
- var timers = [];
64
-
65
- window.setTimeout = function(fn, time){
66
- var num;
67
- return num = setInterval(function(){
68
- fn();
69
- clearInterval(num);
70
- }, time);
71
- };
72
-
73
- window.setInterval = function(fn, time){
74
- var num = timers.length;
75
-
76
- timers[num] = new Ruby.Thread(function() {
77
- while(true) {
78
- Ruby.sleep(time);
79
- fn();
80
- }
81
- });
82
-
83
- return num;
84
- };
85
-
86
- window.clearInterval = function(num){
87
- if ( timers[num] ) {
88
- timers[num].kill();
89
- delete timers[num];
90
- }
91
- };
92
-
93
- // Window Events
94
-
95
- var events = [{}];
96
-
97
- window.addEventListener = function(type, fn){
98
- if ( !this.uuid || this == window ) {
99
- this.uuid = events.length;
100
- events[this.uuid] = {};
101
- }
102
-
103
- if ( !events[this.uuid][type] )
104
- events[this.uuid][type] = [];
105
-
106
- if ( events[this.uuid][type].indexOf( fn ) < 0 )
107
- events[this.uuid][type].push( fn );
108
- };
109
-
110
- window.removeEventListener = function(type, fn){
111
- if ( !this.uuid || this == window ) {
112
- this.uuid = events.length;
113
- events[this.uuid] = {};
114
- }
115
-
116
- if ( !events[this.uuid][type] )
117
- events[this.uuid][type] = [];
118
-
119
- events[this.uuid][type] =
120
- events[this.uuid][type].filter(function(f){
121
- return f != fn;
122
- });
123
- };
124
-
125
- window.dispatchEvent = function(event){
126
- if ( event.type ) {
127
- if ( this.uuid && events[this.uuid][event.type] ) {
128
- var self = this;
129
-
130
- events[this.uuid][event.type].forEach(function(fn){
131
- fn.call( self, event );
132
- });
133
- }
134
-
135
- if ( this["on" + event.type] )
136
- this["on" + event.type].call( self, event );
137
- }
138
- };
139
-
140
- // DOM Document
141
-
142
- window.DOMDocument = function(file){
143
- this._file = file;
144
- var parser = new W3CDOMImplementation();
145
- try {
146
- this._dom = parser.loadXML(file);
147
- } catch(e) {
148
- Ruby.puts("*** wycats to fix: " + parser.translateErrCode(e.code));
149
- throw parser.translateErrCode(e.code);
150
- }
151
-
152
- if ( !obj_nodes["key?"]( this._dom ) )
153
- obj_nodes[this._dom] = this;
154
- };
155
-
156
- DOMDocument.prototype = {
157
- nodeType: 1,
158
- write: function(str) {
159
- if (typeof(write_output) != 'undefined')
160
- write_output += str;
161
- },
162
- createTextNode: function(text){
163
- return makeNode( this._dom.createTextNode(
164
- text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")) );
165
- },
166
- createElement: function(name){
167
- return makeNode( this._dom.createElement(name.toLowerCase()) );
168
- },
169
- getElementsByTagName: function(name){
170
- return new DOMNodeList( this._dom.getElementsByTagName(
171
- name.toLowerCase()) );
172
- },
173
- getElementById: function(id){
174
- return makeNode( this._dom.getElementById(id) );
175
- },
176
- get body(){
177
- return this.getElementsByTagName("body")[0];
178
- },
179
- get documentElement(){
180
- return makeNode( this._dom.getDocumentElement() );
181
- },
182
- get ownerDocument(){
183
- return null;
184
- },
185
- addEventListener: window.addEventListener,
186
- removeEventListener: window.removeEventListener,
187
- dispatchEvent: window.dispatchEvent,
188
- get nodeName() {
189
- return "#document";
190
- },
191
- importNode: function(node, deep){
192
- return makeNode( this._dom.importNode(node._dom, deep) );
193
- },
194
- toString: function(){
195
- return "Document" + (typeof this._file == "string" ?
196
- ": " + this._file : "");
197
- },
198
- get innerHTML(){
199
- return this.documentElement.outerHTML;
200
- },
201
-
202
- get defaultView(){
203
- return {
204
- getComputedStyle: function(elem){
205
- return {
206
- getPropertyValue: function(prop){
207
- prop = prop.replace(/\-(\w)/g,function(m,c){
208
- return c.toUpperCase();
209
- });
210
- var val = elem.style[prop];
211
-
212
- if ( prop === "opacity" && val === "" )
213
- val = "1";
214
-
215
- return val;
216
- }
217
- };
218
- }
219
- };
220
- },
221
-
222
- createEvent: function(){
223
- return {
224
- type: "",
225
- initEvent: function(type){
226
- this.type = type;
227
- }
228
- };
229
- }
230
- };
231
-
232
- function getDocument(node){
233
- return obj_nodes[node];
234
- }
235
-
236
- // DOM NodeList
237
-
238
- window.DOMNodeList = function(list){
239
- this._dom = list;
240
- this.length = list.getLength();
241
-
242
- for ( var i = 0; i < this.length; i++ ) {
243
- var node = list.item(i);
244
- this[i] = makeNode( node );
245
- }
246
- };
247
-
248
- DOMNodeList.prototype = {
249
- toString: function(){
250
- return "[ " +
251
- Array.prototype.join.call( this, ", " ) + " ]";
252
- },
253
- get outerHTML(){
254
- return Array.prototype.map.call(
255
- this, function(node){return node.outerHTML;}).join('');
256
- }
257
- };
258
-
259
- // DOM Node
260
-
261
- window.DOMNode = function(node){
262
- this._dom = node;
263
- };
264
-
265
- DOMNode.prototype = {
266
- get nodeType(){
267
- return this._dom.getNodeType();
268
- },
269
- get nodeValue(){
270
- return this._dom.getNodeValue();
271
- },
272
- get nodeName() {
273
- return this._dom.getNodeName();
274
- },
275
- cloneNode: function(deep){
276
- return makeNode( this._dom.cloneNode(deep) );
277
- },
278
- get ownerDocument(){
279
- return getDocument( this._dom.getOwnerDocument() );
280
- },
281
- get documentElement(){
282
- return makeNode( this._dom.getDocumentElement() );
283
- },
284
- get parentNode() {
285
- return makeNode( this._dom.getParentNode() );
286
- },
287
- get nextSibling() {
288
- return makeNode( this._dom.getNextSibling() );
289
- },
290
- get previousSibling() {
291
- return makeNode( this._dom.getPreviousSibling() );
292
- },
293
- toString: function(){
294
- return '"' + this.nodeValue + '"';
295
- },
296
- get outerHTML(){
297
- return this.nodeValue;
298
- }
299
- };
300
-
301
- // DOM Element
302
-
303
- window.DOMElement = function(elem){
304
- this._dom = elem;
305
- this.style = {
306
- get opacity(){ return this._opacity; },
307
- set opacity(val){ this._opacity = val + ""; }
308
- };
309
-
310
- // Load CSS info
311
- var styles = (this.getAttribute("style") || "").split(/\s*;\s*/);
312
-
313
- for ( var i = 0; i < styles.length; i++ ) {
314
- var style = styles[i].split(/\s*:\s*/);
315
- if ( style.length == 2 )
316
- this.style[ style[0] ] = style[1];
317
- }
318
- };
319
-
320
- DOMElement.prototype = extend( new DOMNode(), {
321
- get nodeName(){
322
- return this.tagName.toUpperCase();
323
- },
324
- get tagName(){
325
- return this._dom.getTagName().toUpperCase();
326
- },
327
- toString: function(){
328
- return "<" + this.tagName + (this.id ? "#" + this.id : "" ) + ">";
329
- },
330
- get outerHTML(){
331
- var ret = "<" + this.tagName, attr = this.attributes;
332
-
333
- for ( var i in attr )
334
- ret += " " + i + "='" + attr[i] + "'";
335
-
336
- if ( this.childNodes.length || this.nodeName == "SCRIPT" )
337
- ret += ">" + this.childNodes.outerHTML +
338
- "</" + this.tagName + ">";
339
- else
340
- ret += "/>";
341
-
342
- return ret;
343
- },
344
-
345
- get attributes(){
346
- var attr = {}, attrs = this._dom.getAttributes();
347
-
348
- for ( var i = 0; i < attrs.getLength(); i++ )
349
- attr[ attrs.item(i).nodeName ] = attrs.item(i).nodeValue;
350
-
351
- return attr;
352
- },
353
-
354
- get innerHTML(){
355
- return this.childNodes.outerHTML;
356
- },
357
- set innerHTML(html){
358
- html = html.replace(/<\/?([A-Z]+)/g, function(m){
359
- return m.toLowerCase();
360
- });
361
-
362
- var nodes = this.ownerDocument.importNode(
363
- new DOMDocument( html ).documentElement, true
364
- ).childNodes;
365
-
366
- while (this.firstChild)
367
- this.removeChild( this.firstChild );
368
-
369
- for ( var i = 0; i < nodes.length; i++ )
370
- this.appendChild( nodes[i] );
371
- },
372
-
373
- get textContent(){
374
- function nav(nodes){
375
- var str = "";
376
- for ( var i = 0; i < nodes.length; i++ ) {
377
- if ( nodes[i].nodeType == 3 )
378
- str += nodes[i].nodeValue;
379
- else if ( nodes[i].nodeType == 1 )
380
- str += nav(nodes[i].childNodes);
381
- }
382
- return str;
383
- }
384
-
385
- return nav(this.childNodes);
386
- },
387
- set textContent(text){
388
- while (this.firstChild)
389
- this.removeChild( this.firstChild );
390
- this.appendChild( this.ownerDocument.createTextNode(text) );
391
- },
392
-
393
- style: {},
394
- clientHeight: 0,
395
- clientWidth: 0,
396
- offsetHeight: 0,
397
- offsetWidth: 0,
398
-
399
- get disabled() {
400
- var val = this.getAttribute("disabled");
401
- return val != "false" && !!val;
402
- },
403
- set disabled(val) { return this.setAttribute("disabled",val); },
404
-
405
- get checked() {
406
- var val = this.getAttribute("checked");
407
- return val != "false" && !!val;
408
- },
409
- set checked(val) { return this.setAttribute("checked",val); },
410
-
411
- get selected() {
412
- if ( !this._selectDone ) {
413
- this._selectDone = true;
414
-
415
- if ( this.nodeName == "OPTION" && !this.parentNode.getAttribute("multiple") ) {
416
- var opt = this.parentNode.getElementsByTagName("option");
417
-
418
- if ( this == opt[0] ) {
419
- var select = true;
420
-
421
- for ( var i = 1; i < opt.length; i++ ) {
422
- if ( opt[i].selected ) {
423
- select = false;
424
- break;
425
- }
426
- }
427
-
428
- if ( select )
429
- this.selected = true;
430
- }
431
- }
432
- }
433
-
434
- var val = this.getAttribute("selected");
435
- return val != "false" && !!val;
436
- },
437
- set selected(val) { return this.setAttribute("selected",val); },
438
-
439
- get className() { return this.getAttribute("class") || ""; },
440
- set className(val) {
441
- return this.setAttribute("class",
442
- val.replace(/(^\s*|\s*$)/g,""));
443
- },
444
-
445
- get type() { return this.getAttribute("type") || ""; },
446
- set type(val) { return this.setAttribute("type",val); },
447
-
448
- get value() { return this.getAttribute("value") || ""; },
449
- set value(val) { return this.setAttribute("value",val); },
450
-
451
- get src() { return this.getAttribute("src") || ""; },
452
- set src(val) { return this.setAttribute("src",val); },
453
-
454
- get id() { return this.getAttribute("id") || ""; },
455
- set id(val) { return this.setAttribute("id",val); },
456
-
457
- getAttribute: function(name){
458
- return this._dom.hasAttribute(name) ?
459
- new String( this._dom.getAttribute(name) ) :
460
- null;
461
- },
462
- setAttribute: function(name,value){
463
- this._dom.setAttribute(name,value);
464
- },
465
- removeAttribute: function(name){
466
- this._dom.removeAttribute(name);
467
- },
468
-
469
- get childNodes(){
470
- return new DOMNodeList( this._dom.getChildNodes() );
471
- },
472
- get firstChild(){
473
- return makeNode( this._dom.getFirstChild() );
474
- },
475
- get lastChild(){
476
- return makeNode( this._dom.getLastChild() );
477
- },
478
- appendChild: function(node){
479
- this._dom.appendChild( node._dom );
480
- },
481
- insertBefore: function(node,before){
482
- this._dom.insertBefore( node._dom, before ? before._dom : before );
483
- },
484
- removeChild: function(node){
485
- this._dom.removeChild( node._dom );
486
- },
487
-
488
- getElementsByTagName: DOMDocument.prototype.getElementsByTagName,
489
-
490
- addEventListener: window.addEventListener,
491
- removeEventListener: window.removeEventListener,
492
- dispatchEvent: window.dispatchEvent,
493
-
494
- click: function(){
495
- var event = document.createEvent();
496
- event.initEvent("click");
497
- this.dispatchEvent(event);
498
- },
499
- submit: function(){
500
- var event = document.createEvent();
501
- event.initEvent("submit");
502
- this.dispatchEvent(event);
503
- },
504
- focus: function(){
505
- var event = document.createEvent();
506
- event.initEvent("focus");
507
- this.dispatchEvent(event);
508
- },
509
- blur: function(){
510
- var event = document.createEvent();
511
- event.initEvent("blur");
512
- this.dispatchEvent(event);
513
- },
514
- get elements(){
515
- return this.getElementsByTagName("*");
516
- },
517
- get contentWindow(){
518
- return this.nodeName == "IFRAME" ? {
519
- document: this.contentDocument
520
- } : null;
521
- },
522
- get contentDocument(){
523
- if ( this.nodeName == "IFRAME" ) {
524
- if ( !this._doc )
525
- this._doc = new DOMDocument(
526
- "<html><head><title></title></head><body></body></html>"
527
- );
528
- return this._doc;
529
- } else
530
- return null;
531
- }
532
- });
533
-
534
- DOMElement.prototype.toString = function() {
535
- return "<" + this.tagName + (this.className !== "" ? " class='" + this.className + "'" : "") +
536
- (this.id !== "" ? " id='" + this.id + "'" : "") + ">";
537
- };
538
-
539
- // Helper method for extending one object with another
540
-
541
- function extend(a,b) {
542
- for ( var i in b ) {
543
- var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
544
-
545
- if ( g || s ) {
546
- if ( g )
547
- a.__defineGetter__(i, g);
548
- if ( s )
549
- a.__defineSetter__(i, s);
550
- } else
551
- a[i] = b[i];
552
- }
553
- return a;
554
- }
555
-
556
- // Helper method for generating the right
557
- // DOM objects based upon the type
558
-
559
- var obj_nodes = new Ruby.Hash;
560
-
561
- function makeNode(node){
562
- if ( node ) {
563
- if ( !obj_nodes['key?']( node ) )
564
- obj_nodes[node] = node.getNodeType() ==
565
- W3CDOMNode.ELEMENT_NODE ?
566
- new DOMElement( node ) : new DOMNode( node );
567
-
568
- return obj_nodes[node];
569
- } else
570
- return null;
571
- }
572
-
573
- // XMLHttpRequest
574
- // Originally implemented by Yehuda Katz
575
-
576
- window.XMLHttpRequest = function(){
577
- this.headers = {};
578
- this.responseHeaders = {};
579
- };
580
-
581
- XMLHttpRequest.prototype = {
582
- open: function(method, url, async, user, password){
583
- this.readyState = 1;
584
- if (async)
585
- this.async = true;
586
- this.method = method || "GET";
587
- this.url = url;
588
- this.onreadystatechange();
589
- },
590
- setRequestHeader: function(header, value){
591
- this.headers[header] = value;
592
- },
593
- getResponseHeader: function(header){ },
594
- send: function(data){
595
- var self = this;
596
-
597
- function makeRequest(){
598
- var url = curLocation.merge(self.url);
599
- var connection;
600
-
601
- if ( url.scheme == "file" ) {
602
- if ( self.method == "PUT" ) {
603
- var out = new Ruby.File(url.path);
604
- var text = data || "";
605
-
606
- out.puts( text );
607
- out.flush();
608
- out.close();
609
- } else if ( self.method == "DELETE" ) {
610
- var file = new Ruby.File(url.path());
611
- file["delete"]();
612
- } else if ( self.method == "GET" ) {
613
- var file = Ruby.File.read(url.path);
614
- connection = {
615
- code: "200",
616
- message: "Ok",
617
- body: file,
618
- }
619
- handleResponse();
620
- } else {
621
- connection = Ruby.Net.HTTP.start(url.host, url.port, function(http) {
622
- http.get(url.path);
623
- });
624
- handleResponse();
625
- }
626
- } else {
627
- var http = Ruby.Net.HTTP.new(url.host, url.port);
628
- var request = new Ruby.Net.HTTP.Get(url.path);
629
- for (var header in self.headers)
630
- request.add_field(header, self.headers[header]);
631
-
632
- var connection = http.request(request);
633
- connection.each_header(function(k,v) {
634
- self.responseHeaders[k] = v;
635
- });
636
-
637
- handleResponse();
638
- }
639
-
640
- function handleResponse(){
641
- self.readyState = 4;
642
- self.status = parseInt(connection.code) || undefined;
643
- self.statusText = connection.message || "";
644
-
645
- self.responseText = connection.body;
646
-
647
- self.responseXML = null;
648
-
649
- if ( self.responseText.match(/^\s*</) ) {
650
- self.responseXML = new DOMDocument( self.responseText );
651
- }
652
- }
653
-
654
- self.onreadystatechange();
655
- }
656
-
657
- if (this.async)
658
- new Ruby.Thread(function() { makeRequest(); });
659
- else
660
- makeRequest();
661
- },
662
- abort: function(){},
663
- onreadystatechange: function(){},
664
- getResponseHeader: function(header){
665
- if (this.readyState < 3)
666
- throw new Error("INVALID_STATE_ERR");
667
- else {
668
- var returnedHeaders = [];
669
- for (var rHeader in this.responseHeaders) {
670
- if (rHeader.match(new Regexp(header, "i")))
671
- returnedHeaders.push(this.responseHeaders[rHeader]);
672
- }
673
-
674
- if (returnedHeaders.length)
675
- return returnedHeaders.join(", ");
676
- }
677
-
678
- return null;
679
- },
680
- getAllResponseHeaders: function(header){
681
- if (this.readyState < 3)
682
- throw new Error("INVALID_STATE_ERR");
683
- else {
684
- var returnedHeaders = [];
685
-
686
- for (var aHeader in this.responseHeaders)
687
- returnedHeaders.push( aHeader + ": " + this.responseHeaders[aHeader] );
688
-
689
- return returnedHeaders.join("\r\n");
690
- }
691
- },
692
- async: true,
693
- readyState: 0,
694
- responseText: "",
695
- status: 0
696
- };
697
- })();
1
+ /*
2
+ * Simulated browser environment for Rhino
3
+ * By John Resig <http://ejohn.org/>
4
+ * Copyright 2007 John Resig, under the MIT License
5
+ */
6
+
7
+ // The window Object
8
+ var window = this;
9
+
10
+ //Ruby.require("uri");
11
+
12
+ print = function(txt) { Ruby.puts(txt); };
13
+
14
+ (function(){
15
+
16
+ // Browser Navigator
17
+
18
+ window.navigator = {
19
+ get userAgent(){
20
+ return "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3";
21
+ }
22
+ };
23
+ /*
24
+ var fileToUrl = function(file) {
25
+ return Ruby.URI.parse("file://" + Ruby.File.expand_path(file));
26
+ };
27
+
28
+ var curLocation = fileToUrl(".");
29
+ /*
30
+ window.__defineSetter__("location", function(url){
31
+ var xhr = new XMLHttpRequest();
32
+ xhr.open("GET", url);
33
+ xhr.onreadystatechange = function(){
34
+ curLocation = curLocation.merge(url);
35
+ window.document = xhr.responseXML;
36
+
37
+ if(window.document) {
38
+ var event = document.createEvent();
39
+ event.initEvent("load");
40
+ window.dispatchEvent( event );
41
+ }
42
+ };
43
+ xhr.send();
44
+ });
45
+
46
+ window.__defineGetter__("location", function(url){
47
+ return {
48
+ get protocol(){
49
+ return curLocation.scheme() + ":";
50
+ },
51
+ get href(){
52
+ return curLocation.toString();
53
+ },
54
+ toString: function(){
55
+ return this.href.toString();
56
+ }
57
+ };
58
+ });
59
+ */
60
+
61
+ // Timers
62
+
63
+ var timers = [];
64
+
65
+ window.setTimeout = function(fn, time){
66
+ var num;
67
+ return num = setInterval(function(){
68
+ fn();
69
+ clearInterval(num);
70
+ }, time);
71
+ };
72
+
73
+ window.setInterval = function(fn, time){
74
+ var num = timers.length;
75
+
76
+ timers[num] = new Ruby.Thread(function() {
77
+ while(true) {
78
+ Ruby.sleep(time);
79
+ fn();
80
+ }
81
+ });
82
+
83
+ return num;
84
+ };
85
+
86
+ window.clearInterval = function(num){
87
+ if ( timers[num] ) {
88
+ timers[num].kill();
89
+ delete timers[num];
90
+ }
91
+ };
92
+
93
+ // Window Events
94
+
95
+ var events = [{}];
96
+
97
+ window.addEventListener = function(type, fn){
98
+ if ( !this.uuid || this == window ) {
99
+ this.uuid = events.length;
100
+ events[this.uuid] = {};
101
+ }
102
+
103
+ if ( !events[this.uuid][type] )
104
+ events[this.uuid][type] = [];
105
+
106
+ if ( events[this.uuid][type].indexOf( fn ) < 0 )
107
+ events[this.uuid][type].push( fn );
108
+ };
109
+
110
+ window.removeEventListener = function(type, fn){
111
+ if ( !this.uuid || this == window ) {
112
+ this.uuid = events.length;
113
+ events[this.uuid] = {};
114
+ }
115
+
116
+ if ( !events[this.uuid][type] )
117
+ events[this.uuid][type] = [];
118
+
119
+ events[this.uuid][type] =
120
+ events[this.uuid][type].filter(function(f){
121
+ return f != fn;
122
+ });
123
+ };
124
+
125
+ window.dispatchEvent = function(event){
126
+ if ( event.type ) {
127
+ if ( this.uuid && events[this.uuid][event.type] ) {
128
+ var self = this;
129
+
130
+ events[this.uuid][event.type].forEach(function(fn){
131
+ fn.call( self, event );
132
+ });
133
+ }
134
+
135
+ if ( this["on" + event.type] )
136
+ this["on" + event.type].call( self, event );
137
+ }
138
+ };
139
+
140
+ // DOM Document
141
+
142
+ window.DOMDocument = function(file){
143
+ this._file = file;
144
+ var parser = new W3CDOMImplementation();
145
+ try {
146
+ this._dom = parser.loadXML(file);
147
+ } catch(e) {
148
+ Ruby.puts("*** wycats to fix: " + parser.translateErrCode(e.code));
149
+ throw parser.translateErrCode(e.code);
150
+ }
151
+
152
+ if ( !obj_nodes["key?"]( this._dom ) )
153
+ obj_nodes[this._dom] = this;
154
+ };
155
+
156
+ DOMDocument.prototype = {
157
+ nodeType: 1,
158
+ write: function(str) {
159
+ if (typeof(write_output) != 'undefined')
160
+ write_output += str;
161
+ },
162
+ createTextNode: function(text){
163
+ return makeNode( this._dom.createTextNode(
164
+ text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")) );
165
+ },
166
+ createElement: function(name){
167
+ return makeNode( this._dom.createElement(name.toLowerCase()) );
168
+ },
169
+ getElementsByTagName: function(name){
170
+ return new DOMNodeList( this._dom.getElementsByTagName(
171
+ name.toLowerCase()) );
172
+ },
173
+ getElementById: function(id){
174
+ return makeNode( this._dom.getElementById(id) );
175
+ },
176
+ get body(){
177
+ return this.getElementsByTagName("body")[0];
178
+ },
179
+ get documentElement(){
180
+ return makeNode( this._dom.getDocumentElement() );
181
+ },
182
+ get ownerDocument(){
183
+ return null;
184
+ },
185
+ addEventListener: window.addEventListener,
186
+ removeEventListener: window.removeEventListener,
187
+ dispatchEvent: window.dispatchEvent,
188
+ get nodeName() {
189
+ return "#document";
190
+ },
191
+ importNode: function(node, deep){
192
+ return makeNode( this._dom.importNode(node._dom, deep) );
193
+ },
194
+ toString: function(){
195
+ return "Document" + (typeof this._file == "string" ?
196
+ ": " + this._file : "");
197
+ },
198
+ get innerHTML(){
199
+ return this.documentElement.outerHTML;
200
+ },
201
+
202
+ get defaultView(){
203
+ return {
204
+ getComputedStyle: function(elem){
205
+ return {
206
+ getPropertyValue: function(prop){
207
+ prop = prop.replace(/\-(\w)/g,function(m,c){
208
+ return c.toUpperCase();
209
+ });
210
+ var val = elem.style[prop];
211
+
212
+ if ( prop === "opacity" && val === "" )
213
+ val = "1";
214
+
215
+ return val;
216
+ }
217
+ };
218
+ }
219
+ };
220
+ },
221
+
222
+ createEvent: function(){
223
+ return {
224
+ type: "",
225
+ initEvent: function(type){
226
+ this.type = type;
227
+ }
228
+ };
229
+ }
230
+ };
231
+
232
+ function getDocument(node){
233
+ return obj_nodes[node];
234
+ }
235
+
236
+ // DOM NodeList
237
+
238
+ window.DOMNodeList = function(list){
239
+ this._dom = list;
240
+ this.length = list.getLength();
241
+
242
+ for ( var i = 0; i < this.length; i++ ) {
243
+ var node = list.item(i);
244
+ this[i] = makeNode( node );
245
+ }
246
+ };
247
+
248
+ DOMNodeList.prototype = {
249
+ toString: function(){
250
+ return "[ " +
251
+ Array.prototype.join.call( this, ", " ) + " ]";
252
+ },
253
+ get outerHTML(){
254
+ return Array.prototype.map.call(
255
+ this, function(node){return node.outerHTML;}).join('');
256
+ }
257
+ };
258
+
259
+ // DOM Node
260
+
261
+ window.DOMNode = function(node){
262
+ this._dom = node;
263
+ };
264
+
265
+ DOMNode.prototype = {
266
+ get nodeType(){
267
+ return this._dom.getNodeType();
268
+ },
269
+ get nodeValue(){
270
+ return this._dom.getNodeValue();
271
+ },
272
+ get nodeName() {
273
+ return this._dom.getNodeName();
274
+ },
275
+ cloneNode: function(deep){
276
+ return makeNode( this._dom.cloneNode(deep) );
277
+ },
278
+ get ownerDocument(){
279
+ return getDocument( this._dom.getOwnerDocument() );
280
+ },
281
+ get documentElement(){
282
+ return makeNode( this._dom.getDocumentElement() );
283
+ },
284
+ get parentNode() {
285
+ return makeNode( this._dom.getParentNode() );
286
+ },
287
+ get nextSibling() {
288
+ return makeNode( this._dom.getNextSibling() );
289
+ },
290
+ get previousSibling() {
291
+ return makeNode( this._dom.getPreviousSibling() );
292
+ },
293
+ toString: function(){
294
+ return '"' + this.nodeValue + '"';
295
+ },
296
+ get outerHTML(){
297
+ return this.nodeValue;
298
+ }
299
+ };
300
+
301
+ // DOM Element
302
+
303
+ window.DOMElement = function(elem){
304
+ this._dom = elem;
305
+ this.style = {
306
+ get opacity(){ return this._opacity; },
307
+ set opacity(val){ this._opacity = val + ""; }
308
+ };
309
+
310
+ // Load CSS info
311
+ var styles = (this.getAttribute("style") || "").split(/\s*;\s*/);
312
+
313
+ for ( var i = 0; i < styles.length; i++ ) {
314
+ var style = styles[i].split(/\s*:\s*/);
315
+ if ( style.length == 2 )
316
+ this.style[ style[0] ] = style[1];
317
+ }
318
+ };
319
+
320
+ DOMElement.prototype = extend( new DOMNode(), {
321
+ get nodeName(){
322
+ return this.tagName.toUpperCase();
323
+ },
324
+ get tagName(){
325
+ return this._dom.getTagName().toUpperCase();
326
+ },
327
+ toString: function(){
328
+ return "<" + this.tagName + (this.id ? "#" + this.id : "" ) + ">";
329
+ },
330
+ get outerHTML(){
331
+ var ret = "<" + this.tagName, attr = this.attributes;
332
+
333
+ for ( var i in attr )
334
+ ret += " " + i + "='" + attr[i] + "'";
335
+
336
+ if ( this.childNodes.length || this.nodeName == "SCRIPT" )
337
+ ret += ">" + this.childNodes.outerHTML +
338
+ "</" + this.tagName + ">";
339
+ else
340
+ ret += "/>";
341
+
342
+ return ret;
343
+ },
344
+
345
+ get attributes(){
346
+ var attr = {}, attrs = this._dom.getAttributes();
347
+
348
+ for ( var i = 0; i < attrs.getLength(); i++ )
349
+ attr[ attrs.item(i).nodeName ] = attrs.item(i).nodeValue;
350
+
351
+ return attr;
352
+ },
353
+
354
+ get innerHTML(){
355
+ return this.childNodes.outerHTML;
356
+ },
357
+ set innerHTML(html){
358
+ html = html.replace(/<\/?([A-Z]+)/g, function(m){
359
+ return m.toLowerCase();
360
+ });
361
+
362
+ var nodes = this.ownerDocument.importNode(
363
+ new DOMDocument( html ).documentElement, true
364
+ ).childNodes;
365
+
366
+ while (this.firstChild)
367
+ this.removeChild( this.firstChild );
368
+
369
+ for ( var i = 0; i < nodes.length; i++ )
370
+ this.appendChild( nodes[i] );
371
+ },
372
+
373
+ get textContent(){
374
+ function nav(nodes){
375
+ var str = "";
376
+ for ( var i = 0; i < nodes.length; i++ ) {
377
+ if ( nodes[i].nodeType == 3 )
378
+ str += nodes[i].nodeValue;
379
+ else if ( nodes[i].nodeType == 1 )
380
+ str += nav(nodes[i].childNodes);
381
+ }
382
+ return str;
383
+ }
384
+
385
+ return nav(this.childNodes);
386
+ },
387
+ set textContent(text){
388
+ while (this.firstChild)
389
+ this.removeChild( this.firstChild );
390
+ this.appendChild( this.ownerDocument.createTextNode(text) );
391
+ },
392
+
393
+ style: {},
394
+ clientHeight: 0,
395
+ clientWidth: 0,
396
+ offsetHeight: 0,
397
+ offsetWidth: 0,
398
+
399
+ get disabled() {
400
+ var val = this.getAttribute("disabled");
401
+ return val != "false" && !!val;
402
+ },
403
+ set disabled(val) { return this.setAttribute("disabled",val); },
404
+
405
+ get checked() {
406
+ var val = this.getAttribute("checked");
407
+ return val != "false" && !!val;
408
+ },
409
+ set checked(val) { return this.setAttribute("checked",val); },
410
+
411
+ get selected() {
412
+ if ( !this._selectDone ) {
413
+ this._selectDone = true;
414
+
415
+ if ( this.nodeName == "OPTION" && !this.parentNode.getAttribute("multiple") ) {
416
+ var opt = this.parentNode.getElementsByTagName("option");
417
+
418
+ if ( this == opt[0] ) {
419
+ var select = true;
420
+
421
+ for ( var i = 1; i < opt.length; i++ ) {
422
+ if ( opt[i].selected ) {
423
+ select = false;
424
+ break;
425
+ }
426
+ }
427
+
428
+ if ( select )
429
+ this.selected = true;
430
+ }
431
+ }
432
+ }
433
+
434
+ var val = this.getAttribute("selected");
435
+ return val != "false" && !!val;
436
+ },
437
+ set selected(val) { return this.setAttribute("selected",val); },
438
+
439
+ get className() { return this.getAttribute("class") || ""; },
440
+ set className(val) {
441
+ return this.setAttribute("class",
442
+ val.replace(/(^\s*|\s*$)/g,""));
443
+ },
444
+
445
+ get type() { return this.getAttribute("type") || ""; },
446
+ set type(val) { return this.setAttribute("type",val); },
447
+
448
+ get value() { return this.getAttribute("value") || ""; },
449
+ set value(val) { return this.setAttribute("value",val); },
450
+
451
+ get src() { return this.getAttribute("src") || ""; },
452
+ set src(val) { return this.setAttribute("src",val); },
453
+
454
+ get id() { return this.getAttribute("id") || ""; },
455
+ set id(val) { return this.setAttribute("id",val); },
456
+
457
+ getAttribute: function(name){
458
+ return this._dom.hasAttribute(name) ?
459
+ new String( this._dom.getAttribute(name) ) :
460
+ null;
461
+ },
462
+ setAttribute: function(name,value){
463
+ this._dom.setAttribute(name,value);
464
+ },
465
+ removeAttribute: function(name){
466
+ this._dom.removeAttribute(name);
467
+ },
468
+
469
+ get childNodes(){
470
+ return new DOMNodeList( this._dom.getChildNodes() );
471
+ },
472
+ get firstChild(){
473
+ return makeNode( this._dom.getFirstChild() );
474
+ },
475
+ get lastChild(){
476
+ return makeNode( this._dom.getLastChild() );
477
+ },
478
+ appendChild: function(node){
479
+ this._dom.appendChild( node._dom );
480
+ },
481
+ insertBefore: function(node,before){
482
+ this._dom.insertBefore( node._dom, before ? before._dom : before );
483
+ },
484
+ removeChild: function(node){
485
+ this._dom.removeChild( node._dom );
486
+ },
487
+
488
+ getElementsByTagName: DOMDocument.prototype.getElementsByTagName,
489
+
490
+ addEventListener: window.addEventListener,
491
+ removeEventListener: window.removeEventListener,
492
+ dispatchEvent: window.dispatchEvent,
493
+
494
+ click: function(){
495
+ var event = document.createEvent();
496
+ event.initEvent("click");
497
+ this.dispatchEvent(event);
498
+ },
499
+ submit: function(){
500
+ var event = document.createEvent();
501
+ event.initEvent("submit");
502
+ this.dispatchEvent(event);
503
+ },
504
+ focus: function(){
505
+ var event = document.createEvent();
506
+ event.initEvent("focus");
507
+ this.dispatchEvent(event);
508
+ },
509
+ blur: function(){
510
+ var event = document.createEvent();
511
+ event.initEvent("blur");
512
+ this.dispatchEvent(event);
513
+ },
514
+ get elements(){
515
+ return this.getElementsByTagName("*");
516
+ },
517
+ get contentWindow(){
518
+ return this.nodeName == "IFRAME" ? {
519
+ document: this.contentDocument
520
+ } : null;
521
+ },
522
+ get contentDocument(){
523
+ if ( this.nodeName == "IFRAME" ) {
524
+ if ( !this._doc )
525
+ this._doc = new DOMDocument(
526
+ "<html><head><title></title></head><body></body></html>"
527
+ );
528
+ return this._doc;
529
+ } else
530
+ return null;
531
+ }
532
+ });
533
+
534
+ DOMElement.prototype.toString = function() {
535
+ return "<" + this.tagName + (this.className !== "" ? " class='" + this.className + "'" : "") +
536
+ (this.id !== "" ? " id='" + this.id + "'" : "") + ">";
537
+ };
538
+
539
+ // Helper method for extending one object with another
540
+
541
+ function extend(a,b) {
542
+ for ( var i in b ) {
543
+ var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
544
+
545
+ if ( g || s ) {
546
+ if ( g )
547
+ a.__defineGetter__(i, g);
548
+ if ( s )
549
+ a.__defineSetter__(i, s);
550
+ } else
551
+ a[i] = b[i];
552
+ }
553
+ return a;
554
+ }
555
+
556
+ // Helper method for generating the right
557
+ // DOM objects based upon the type
558
+
559
+ var obj_nodes = new Ruby.Hash;
560
+
561
+ function makeNode(node){
562
+ if ( node ) {
563
+ if ( !obj_nodes['key?']( node ) )
564
+ obj_nodes[node] = node.getNodeType() ==
565
+ W3CDOMNode.ELEMENT_NODE ?
566
+ new DOMElement( node ) : new DOMNode( node );
567
+
568
+ return obj_nodes[node];
569
+ } else
570
+ return null;
571
+ }
572
+
573
+ // XMLHttpRequest
574
+ // Originally implemented by Yehuda Katz
575
+
576
+ window.XMLHttpRequest = function(){
577
+ this.headers = {};
578
+ this.responseHeaders = {};
579
+ };
580
+
581
+ XMLHttpRequest.prototype = {
582
+ open: function(method, url, async, user, password){
583
+ this.readyState = 1;
584
+ if (async)
585
+ this.async = true;
586
+ this.method = method || "GET";
587
+ this.url = url;
588
+ this.onreadystatechange();
589
+ },
590
+ setRequestHeader: function(header, value){
591
+ this.headers[header] = value;
592
+ },
593
+ getResponseHeader: function(header){ },
594
+ send: function(data){
595
+ var self = this;
596
+
597
+ function makeRequest(){
598
+ var url = curLocation.merge(self.url);
599
+ var connection;
600
+
601
+ if ( url.scheme == "file" ) {
602
+ if ( self.method == "PUT" ) {
603
+ var out = new Ruby.File(url.path);
604
+ var text = data || "";
605
+
606
+ out.puts( text );
607
+ out.flush();
608
+ out.close();
609
+ } else if ( self.method == "DELETE" ) {
610
+ var file = new Ruby.File(url.path());
611
+ file["delete"]();
612
+ } else if ( self.method == "GET" ) {
613
+ var file = Ruby.File.read(url.path);
614
+ connection = {
615
+ code: "200",
616
+ message: "Ok",
617
+ body: file,
618
+ }
619
+ handleResponse();
620
+ } else {
621
+ connection = Ruby.Net.HTTP.start(url.host, url.port, function(http) {
622
+ http.get(url.path);
623
+ });
624
+ handleResponse();
625
+ }
626
+ } else {
627
+ var http = Ruby.Net.HTTP.new(url.host, url.port);
628
+ var request = new Ruby.Net.HTTP.Get(url.path);
629
+ for (var header in self.headers)
630
+ request.add_field(header, self.headers[header]);
631
+
632
+ var connection = http.request(request);
633
+ connection.each_header(function(k,v) {
634
+ self.responseHeaders[k] = v;
635
+ });
636
+
637
+ handleResponse();
638
+ }
639
+
640
+ function handleResponse(){
641
+ self.readyState = 4;
642
+ self.status = parseInt(connection.code) || undefined;
643
+ self.statusText = connection.message || "";
644
+
645
+ self.responseText = connection.body;
646
+
647
+ self.responseXML = null;
648
+
649
+ if ( self.responseText.match(/^\s*</) ) {
650
+ self.responseXML = new DOMDocument( self.responseText );
651
+ }
652
+ }
653
+
654
+ self.onreadystatechange();
655
+ }
656
+
657
+ if (this.async)
658
+ new Ruby.Thread(function() { makeRequest(); });
659
+ else
660
+ makeRequest();
661
+ },
662
+ abort: function(){},
663
+ onreadystatechange: function(){},
664
+ getResponseHeader: function(header){
665
+ if (this.readyState < 3)
666
+ throw new Error("INVALID_STATE_ERR");
667
+ else {
668
+ var returnedHeaders = [];
669
+ for (var rHeader in this.responseHeaders) {
670
+ if (rHeader.match(new Regexp(header, "i")))
671
+ returnedHeaders.push(this.responseHeaders[rHeader]);
672
+ }
673
+
674
+ if (returnedHeaders.length)
675
+ return returnedHeaders.join(", ");
676
+ }
677
+
678
+ return null;
679
+ },
680
+ getAllResponseHeaders: function(header){
681
+ if (this.readyState < 3)
682
+ throw new Error("INVALID_STATE_ERR");
683
+ else {
684
+ var returnedHeaders = [];
685
+
686
+ for (var aHeader in this.responseHeaders)
687
+ returnedHeaders.push( aHeader + ": " + this.responseHeaders[aHeader] );
688
+
689
+ return returnedHeaders.join("\r\n");
690
+ }
691
+ },
692
+ async: true,
693
+ readyState: 0,
694
+ responseText: "",
695
+ status: 0
696
+ };
697
+ })();