mattpuchlerz-jspec 2.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. data/History.rdoc +513 -0
  2. data/Manifest +57 -0
  3. data/README.rdoc +825 -0
  4. data/Rakefile +75 -0
  5. data/bin/jspec +305 -0
  6. data/jspec.gemspec +44 -0
  7. data/lib/images/bg.png +0 -0
  8. data/lib/images/hr.png +0 -0
  9. data/lib/images/loading.gif +0 -0
  10. data/lib/images/sprites.bg.png +0 -0
  11. data/lib/images/sprites.png +0 -0
  12. data/lib/images/vr.png +0 -0
  13. data/lib/jspec.css +145 -0
  14. data/lib/jspec.jquery.js +71 -0
  15. data/lib/jspec.js +1771 -0
  16. data/lib/jspec.shell.js +36 -0
  17. data/lib/jspec.timers.js +84 -0
  18. data/lib/jspec.xhr.js +183 -0
  19. data/server/browsers.rb +228 -0
  20. data/server/helpers.rb +82 -0
  21. data/server/routes.rb +57 -0
  22. data/server/server.rb +88 -0
  23. data/spec/async +1 -0
  24. data/spec/env.js +695 -0
  25. data/spec/fixtures/test.html +1 -0
  26. data/spec/fixtures/test.json +1 -0
  27. data/spec/fixtures/test.xml +5 -0
  28. data/spec/helpers.js +66 -0
  29. data/spec/server.rb +2 -0
  30. data/spec/spec.dom.html +34 -0
  31. data/spec/spec.fixtures.js +18 -0
  32. data/spec/spec.grammar-less.js +34 -0
  33. data/spec/spec.grammar.js +226 -0
  34. data/spec/spec.jquery.js +176 -0
  35. data/spec/spec.jquery.xhr.js +35 -0
  36. data/spec/spec.js +166 -0
  37. data/spec/spec.matchers.js +493 -0
  38. data/spec/spec.modules.js +67 -0
  39. data/spec/spec.node.js +46 -0
  40. data/spec/spec.rhino.js +17 -0
  41. data/spec/spec.server.html +29 -0
  42. data/spec/spec.shared-behaviors.js +80 -0
  43. data/spec/spec.utils.js +279 -0
  44. data/spec/spec.xhr.js +156 -0
  45. data/templates/default/History.md +4 -0
  46. data/templates/default/README.md +30 -0
  47. data/templates/default/lib/yourlib.js +2 -0
  48. data/templates/default/spec/server.rb +4 -0
  49. data/templates/default/spec/spec.dom.html +20 -0
  50. data/templates/default/spec/spec.rhino.js +9 -0
  51. data/templates/default/spec/spec.server.html +16 -0
  52. data/templates/default/spec/yourlib_spec.js +11 -0
  53. data/templates/rails/server.rb +4 -0
  54. data/templates/rails/spec.application.js +8 -0
  55. data/templates/rails/spec.dom.html +20 -0
  56. data/templates/rails/spec.rhino.js +8 -0
  57. data/templates/rails/spec.server.html +16 -0
  58. metadata +166 -0
@@ -0,0 +1,82 @@
1
+
2
+ helpers do
3
+
4
+ ##
5
+ # Return dotted assertion graph for _assertions_.
6
+
7
+ def assertion_graph_for assertions
8
+ return if assertions.empty?
9
+ assertions.map do |assertion|
10
+ assertion['passed'] ? green('.') : red('.')
11
+ end.join
12
+ end
13
+
14
+ ##
15
+ # Override Sinatra's #send_file to prevent caching.
16
+
17
+ def send_file path, opts = {}
18
+ stat = File.stat(path)
19
+ response['Cache-Control'] = 'no-cache'
20
+ content_type media_type(opts[:type]) ||
21
+ media_type(File.extname(path)) ||
22
+ response['Content-Type'] ||
23
+ 'application/octet-stream'
24
+ response['Content-Length'] ||= (opts[:length] || stat.size).to_s
25
+
26
+ if opts[:disposition] == 'attachment' || opts[:filename]
27
+ attachment opts[:filename] || path
28
+ elsif opts[:disposition] == 'inline'
29
+ response['Content-Disposition'] = 'inline'
30
+ end
31
+
32
+ halt ::Sinatra::Application::StaticFile.open(path, 'rb')
33
+ rescue Errno::ENOENT
34
+ not_found
35
+ end
36
+
37
+ ##
38
+ # Find the browser name for the current user agent.
39
+
40
+ def browser_name
41
+ Browser.subclasses.find do |browser|
42
+ browser.matches_agent? env['HTTP_USER_AGENT']
43
+ end.new
44
+ rescue
45
+ 'Unknown'
46
+ end
47
+
48
+ ##
49
+ # Wrap _string_ with ansi escape sequence using _code_.
50
+
51
+ def color string, code
52
+ "\e[#{code}m#{string}\e[0m"
53
+ end
54
+
55
+ ##
56
+ # Bold _string_.
57
+
58
+ def bold string
59
+ color string, 1
60
+ end
61
+
62
+ ##
63
+ # Color _string_ red.
64
+
65
+ def red string
66
+ color string, 31
67
+ end
68
+
69
+ ##
70
+ # Color _string_ green.
71
+
72
+ def green string
73
+ color string, 32
74
+ end
75
+
76
+ ##
77
+ # Color _string_ blue.
78
+
79
+ def blue string
80
+ color string, 34
81
+ end
82
+ end
@@ -0,0 +1,57 @@
1
+
2
+ get '/jspec/*' do |path|
3
+ send_file JSPEC_ROOT + '/lib/' + path
4
+ end
5
+
6
+ post '/results' do
7
+ require 'json'
8
+ data = JSON.parse request.body.read
9
+ if data['options'].include?('verbose') && data['options']['verbose'] ||
10
+ data['options'].include?('failuresOnly') && data['options']['failuresOnly']
11
+ puts "\n\n %s Passes: %s Failures: %s\n\n" % [
12
+ bold(browser_name),
13
+ green(data['stats']['passes']),
14
+ red(data['stats']['failures'])]
15
+ data['results'].compact.each do |suite|
16
+ specs = suite['specs'].compact.map do |spec|
17
+ case spec['status'].to_sym
18
+ when :pass
19
+ next if data['options'].include?('failuresOnly') && data['options']['failuresOnly']
20
+ ' ' + green(spec['description']) + assertion_graph_for(spec['assertions']).to_s + "\n"
21
+ when :fail
22
+ " #{red(spec['description'])}\n #{spec['message']}\n\n"
23
+ else
24
+ " #{blue(spec['description'])}\n"
25
+ end
26
+ end.join
27
+ unless specs.strip.empty?
28
+ puts "\n " + bold(suite['description'])
29
+ puts specs
30
+ end
31
+ end
32
+ else
33
+ puts "%20s Passes: %s Failures: %s" % [
34
+ bold(browser_name),
35
+ green(data['stats']['passes']),
36
+ red(data['stats']['failures'])]
37
+ end
38
+ halt 200
39
+ end
40
+
41
+ get '/*' do |path|
42
+ pass unless File.exists?(path)
43
+ send_file path
44
+ end
45
+
46
+ #--
47
+ # Simulation Routes
48
+ #++
49
+
50
+ get '/slow/*' do |seconds|
51
+ sleep seconds.to_i
52
+ halt 200
53
+ end
54
+
55
+ get '/status/*' do |code|
56
+ halt code.to_i
57
+ end
@@ -0,0 +1,88 @@
1
+
2
+ $:.unshift File.dirname(__FILE__)
3
+
4
+ require 'sinatra'
5
+ require 'thread'
6
+ require 'browsers'
7
+ require 'helpers'
8
+ require 'routes'
9
+
10
+ module JSpec
11
+ class Server
12
+
13
+ ##
14
+ # Suite HTML.
15
+
16
+ attr_accessor :suite
17
+
18
+ ##
19
+ # Host string.
20
+
21
+ attr_reader :host
22
+
23
+ ##
24
+ # Port number.
25
+
26
+ attr_reader :port
27
+
28
+ ##
29
+ # Server instance.
30
+
31
+ attr_reader :server
32
+
33
+ ##
34
+ # Initialize.
35
+
36
+ def initialize suite, port
37
+ @suite, @port, @host = suite, port, :localhost
38
+ end
39
+
40
+ ##
41
+ # URI formed by the given host and port.
42
+
43
+ def uri
44
+ 'http://%s:%d' % [host, port]
45
+ end
46
+
47
+ ##
48
+ # Start the server with _browsers_ which defaults to all supported browsers.
49
+
50
+ def start browsers = nil
51
+ browsers ||= Browser.subclasses.map { |browser| browser.new }
52
+ browsers.map do |browser|
53
+ Thread.new {
54
+ sleep 1
55
+ if browser.supported?
56
+ browser.setup
57
+ browser.visit uri + '/' + suite
58
+ browser.teardown
59
+ end
60
+ }
61
+ end.push(Thread.new {
62
+ start!
63
+ }).reverse.each { |thread| thread.join }
64
+ end
65
+
66
+ private
67
+
68
+ #:nodoc:
69
+
70
+ def start!
71
+ Sinatra::Application.class_eval do
72
+ begin
73
+ $stderr.puts 'Started JSpec server at http://%s:%d' % [host, port.to_i]
74
+ detect_rack_handler.run self, :Host => host, :Port => port do |server|
75
+ trap 'INT' do
76
+ server.respond_to?(:stop!) ? server.stop! : server.stop
77
+ end
78
+ end
79
+ rescue Errno::EADDRINUSE
80
+ raise "Port #{port} already in use"
81
+ rescue Errno::EACCES
82
+ raise "Permission Denied on port #{port}"
83
+ end
84
+ end
85
+ end
86
+
87
+ end
88
+ end
@@ -0,0 +1 @@
1
+ cookies!
@@ -0,0 +1,695 @@
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
+ (function(){
11
+
12
+ // Browser Navigator
13
+
14
+ window.navigator = {
15
+ get userAgent(){
16
+ return "Mozilla/5.0 (Macintosh; U; Intel Mac OS X; en-US; rv:1.8.1.3) Gecko/20070309 Firefox/2.0.0.3";
17
+ }
18
+ };
19
+
20
+ var curLocation = (new java.io.File("./")).toURL();
21
+
22
+ window.__defineSetter__("location", function(url){
23
+ var xhr = new XMLHttpRequest();
24
+ xhr.open("GET", url);
25
+ xhr.onreadystatechange = function(){
26
+ curLocation = new java.net.URL( curLocation, url );
27
+ window.document = xhr.responseXML;
28
+
29
+ var event = document.createEvent();
30
+ event.initEvent("load");
31
+ window.dispatchEvent( event );
32
+ };
33
+ xhr.send();
34
+ });
35
+
36
+ window.__defineGetter__("location", function(url){
37
+ return {
38
+ get protocol(){
39
+ return curLocation.getProtocol() + ":";
40
+ },
41
+ get href(){
42
+ return curLocation.toString();
43
+ },
44
+ toString: function(){
45
+ return this.href;
46
+ }
47
+ };
48
+ });
49
+
50
+ // Timers
51
+
52
+ var timers = [];
53
+
54
+ window.setTimeout = function(fn, time){
55
+ var num;
56
+ return num = setInterval(function(){
57
+ fn();
58
+ clearInterval(num);
59
+ }, time);
60
+ };
61
+
62
+ window.setInterval = function(fn, time){
63
+ var num = timers.length;
64
+
65
+ timers[num] = new java.lang.Thread(new java.lang.Runnable({
66
+ run: function(){
67
+ while (true){
68
+ java.lang.Thread.currentThread().sleep(time);
69
+ fn();
70
+ }
71
+ }
72
+ }));
73
+
74
+ timers[num].start();
75
+
76
+ return num;
77
+ };
78
+
79
+ window.clearInterval = function(num){
80
+ if ( timers[num] ) {
81
+ timers[num].stop();
82
+ delete timers[num];
83
+ }
84
+ };
85
+
86
+ // Window Events
87
+
88
+ var events = [{}];
89
+
90
+ window.addEventListener = function(type, fn){
91
+ if ( !this.uuid || this == window ) {
92
+ this.uuid = events.length;
93
+ events[this.uuid] = {};
94
+ }
95
+
96
+ if ( !events[this.uuid][type] )
97
+ events[this.uuid][type] = [];
98
+
99
+ if ( events[this.uuid][type].indexOf( fn ) < 0 )
100
+ events[this.uuid][type].push( fn );
101
+ };
102
+
103
+ window.removeEventListener = function(type, fn){
104
+ if ( !this.uuid || this == window ) {
105
+ this.uuid = events.length;
106
+ events[this.uuid] = {};
107
+ }
108
+
109
+ if ( !events[this.uuid][type] )
110
+ events[this.uuid][type] = [];
111
+
112
+ events[this.uuid][type] =
113
+ events[this.uuid][type].filter(function(f){
114
+ return f != fn;
115
+ });
116
+ };
117
+
118
+ window.dispatchEvent = function(event){
119
+ if ( event.type ) {
120
+ if ( this.uuid && events[this.uuid][event.type] ) {
121
+ var self = this;
122
+
123
+ events[this.uuid][event.type].forEach(function(fn){
124
+ fn.call( self, event );
125
+ });
126
+ }
127
+
128
+ if ( this["on" + event.type] )
129
+ this["on" + event.type].call( self, event );
130
+ }
131
+ };
132
+
133
+ // DOM Document
134
+
135
+ window.DOMDocument = function(file){
136
+ this._file = file;
137
+ this._dom = Packages.javax.xml.parsers.
138
+ DocumentBuilderFactory.newInstance()
139
+ .newDocumentBuilder().parse(file);
140
+
141
+ if ( !obj_nodes.containsKey( this._dom ) )
142
+ obj_nodes.put( this._dom, this );
143
+ };
144
+
145
+ DOMDocument.prototype = {
146
+ createTextNode: function(text){
147
+ return makeNode( this._dom.createTextNode(
148
+ text.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;")) );
149
+ },
150
+ createElement: function(name){
151
+ return makeNode( this._dom.createElement(name.toLowerCase()) );
152
+ },
153
+ getElementsByTagName: function(name){
154
+ return new DOMNodeList( this._dom.getElementsByTagName(
155
+ name.toLowerCase()) );
156
+ },
157
+ getElementById: function(id){
158
+ var elems = this._dom.getElementsByTagName("*");
159
+
160
+ for ( var i = 0; i < elems.length; i++ ) {
161
+ var elem = elems.item(i);
162
+ if ( elem.getAttribute("id") == id )
163
+ return makeNode(elem);
164
+ }
165
+
166
+ return null;
167
+ },
168
+ get body(){
169
+ return this.getElementsByTagName("body")[0];
170
+ },
171
+ get documentElement(){
172
+ return makeNode( this._dom.getDocumentElement() );
173
+ },
174
+ get ownerDocument(){
175
+ return null;
176
+ },
177
+ addEventListener: window.addEventListener,
178
+ removeEventListener: window.removeEventListener,
179
+ dispatchEvent: window.dispatchEvent,
180
+ get nodeName() {
181
+ return "#document";
182
+ },
183
+ importNode: function(node, deep){
184
+ return makeNode( this._dom.importNode(node._dom, deep) );
185
+ },
186
+ toString: function(){
187
+ return "Document" + (typeof this._file == "string" ?
188
+ ": " + this._file : "");
189
+ },
190
+ get innerHTML(){
191
+ return this.documentElement.outerHTML;
192
+ },
193
+
194
+ get defaultView(){
195
+ return {
196
+ getComputedStyle: function(elem){
197
+ return {
198
+ getPropertyValue: function(prop){
199
+ prop = prop.replace(/\-(\w)/g,function(m,c){
200
+ return c.toUpperCase();
201
+ });
202
+ var val = elem.style[prop];
203
+
204
+ if ( prop == "opacity" && val == "" )
205
+ val = "1";
206
+
207
+ return val;
208
+ }
209
+ };
210
+ }
211
+ };
212
+ },
213
+
214
+ createEvent: function(){
215
+ return {
216
+ type: "",
217
+ initEvent: function(type){
218
+ this.type = type;
219
+ }
220
+ };
221
+ }
222
+ };
223
+
224
+ function getDocument(node){
225
+ return obj_nodes.get(node);
226
+ }
227
+
228
+ // DOM NodeList
229
+
230
+ window.DOMNodeList = function(list){
231
+ this._dom = list;
232
+ this.length = list.getLength();
233
+
234
+ for ( var i = 0; i < this.length; i++ ) {
235
+ var node = list.item(i);
236
+ this[i] = makeNode( node );
237
+ }
238
+ };
239
+
240
+ DOMNodeList.prototype = {
241
+ toString: function(){
242
+ return "[ " +
243
+ Array.prototype.join.call( this, ", " ) + " ]";
244
+ },
245
+ get outerHTML(){
246
+ return Array.prototype.map.call(
247
+ this, function(node){return node.outerHTML;}).join('');
248
+ }
249
+ };
250
+
251
+ // DOM Node
252
+
253
+ window.DOMNode = function(node){
254
+ this._dom = node;
255
+ };
256
+
257
+ DOMNode.prototype = {
258
+ get nodeType(){
259
+ return this._dom.getNodeType();
260
+ },
261
+ get nodeValue(){
262
+ return this._dom.getNodeValue();
263
+ },
264
+ get nodeName() {
265
+ return this._dom.getNodeName();
266
+ },
267
+ cloneNode: function(deep){
268
+ return makeNode( this._dom.cloneNode(deep) );
269
+ },
270
+ get ownerDocument(){
271
+ return getDocument( this._dom.ownerDocument );
272
+ },
273
+ get documentElement(){
274
+ return makeNode( this._dom.documentElement );
275
+ },
276
+ get parentNode() {
277
+ return makeNode( this._dom.getParentNode() );
278
+ },
279
+ get nextSibling() {
280
+ return makeNode( this._dom.getNextSibling() );
281
+ },
282
+ get previousSibling() {
283
+ return makeNode( this._dom.getPreviousSibling() );
284
+ },
285
+ toString: function(){
286
+ return '"' + this.nodeValue + '"';
287
+ },
288
+ get outerHTML(){
289
+ return this.nodeValue;
290
+ }
291
+ };
292
+
293
+ // DOM Element
294
+
295
+ window.DOMElement = function(elem){
296
+ this._dom = elem;
297
+ this.style = {
298
+ get opacity(){ return this._opacity; },
299
+ set opacity(val){ this._opacity = val + ""; }
300
+ };
301
+
302
+ // Load CSS info
303
+ var styles = (this.getAttribute("style") || "").split(/\s*;\s*/);
304
+
305
+ for ( var i = 0; i < styles.length; i++ ) {
306
+ var style = styles[i].split(/\s*:\s*/);
307
+ if ( style.length == 2 )
308
+ this.style[ style[0] ] = style[1];
309
+ }
310
+ };
311
+
312
+ DOMElement.prototype = extend( new DOMNode(), {
313
+ get nodeName(){
314
+ return this.tagName.toUpperCase();
315
+ },
316
+ get tagName(){
317
+ return this._dom.getTagName();
318
+ },
319
+ toString: function(){
320
+ return "<" + this.tagName + (this.id ? "#" + this.id : "" ) + ">";
321
+ },
322
+ get outerHTML(){
323
+ var ret = "<" + this.tagName, attr = this.attributes;
324
+
325
+ for ( var i in attr )
326
+ ret += " " + i + "='" + attr[i] + "'";
327
+
328
+ if ( this.childNodes.length || this.nodeName == "SCRIPT" )
329
+ ret += ">" + this.childNodes.outerHTML +
330
+ "</" + this.tagName + ">";
331
+ else
332
+ ret += "/>";
333
+
334
+ return ret;
335
+ },
336
+
337
+ get attributes(){
338
+ var attr = {}, attrs = this._dom.getAttributes();
339
+
340
+ for ( var i = 0; i < attrs.getLength(); i++ )
341
+ attr[ attrs.item(i).nodeName ] = attrs.item(i).nodeValue;
342
+
343
+ return attr;
344
+ },
345
+
346
+ get innerHTML(){
347
+ return this.childNodes.outerHTML;
348
+ },
349
+ set innerHTML(html){
350
+ html = html.replace(/<\/?([A-Z]+)/g, function(m){
351
+ return m.toLowerCase();
352
+ });
353
+
354
+ var nodes = this.ownerDocument.importNode(
355
+ new DOMDocument( new java.io.ByteArrayInputStream(
356
+ (new java.lang.String("<wrap>" + html + "</wrap>"))
357
+ .getBytes("UTF8"))).documentElement, true).childNodes;
358
+
359
+ while (this.firstChild)
360
+ this.removeChild( this.firstChild );
361
+
362
+ for ( var i = 0; i < nodes.length; i++ )
363
+ this.appendChild( nodes[i] );
364
+ },
365
+
366
+ get textContent(){
367
+ return nav(this.childNodes);
368
+
369
+ function nav(nodes){
370
+ var str = "";
371
+ for ( var i = 0; i < nodes.length; i++ )
372
+ if ( nodes[i].nodeType == 3 )
373
+ str += nodes[i].nodeValue;
374
+ else if ( nodes[i].nodeType == 1 )
375
+ str += nav(nodes[i].childNodes);
376
+ return str;
377
+ }
378
+ },
379
+ set textContent(text){
380
+ while (this.firstChild)
381
+ this.removeChild( this.firstChild );
382
+ this.appendChild( this.ownerDocument.createTextNode(text));
383
+ },
384
+
385
+ style: {},
386
+ clientHeight: 0,
387
+ clientWidth: 0,
388
+ offsetHeight: 0,
389
+ offsetWidth: 0,
390
+
391
+ get disabled() {
392
+ var val = this.getAttribute("disabled");
393
+ return val != "false" && !!val;
394
+ },
395
+ set disabled(val) { return this.setAttribute("disabled",val); },
396
+
397
+ get checked() {
398
+ var val = this.getAttribute("checked");
399
+ return val != "false" && !!val;
400
+ },
401
+ set checked(val) { return this.setAttribute("checked",val); },
402
+
403
+ get selected() {
404
+ if ( !this._selectDone ) {
405
+ this._selectDone = true;
406
+
407
+ if ( this.nodeName == "OPTION" && !this.parentNode.getAttribute("multiple") ) {
408
+ var opt = this.parentNode.getElementsByTagName("option");
409
+
410
+ if ( this == opt[0] ) {
411
+ var select = true;
412
+
413
+ for ( var i = 1; i < opt.length; i++ )
414
+ if ( opt[i].selected ) {
415
+ select = false;
416
+ break;
417
+ }
418
+
419
+ if ( select )
420
+ this.selected = true;
421
+ }
422
+ }
423
+ }
424
+
425
+ var val = this.getAttribute("selected");
426
+ return val != "false" && !!val;
427
+ },
428
+ set selected(val) { return this.setAttribute("selected",val); },
429
+
430
+ get className() { return this.getAttribute("class") || ""; },
431
+ set className(val) {
432
+ return this.setAttribute("class",
433
+ val.replace(/(^\s*|\s*$)/g,""));
434
+ },
435
+
436
+ get type() { return this.getAttribute("type") || ""; },
437
+ set type(val) { return this.setAttribute("type",val); },
438
+
439
+ get value() { return this.getAttribute("value") || ""; },
440
+ set value(val) { return this.setAttribute("value",val); },
441
+
442
+ get src() { return this.getAttribute("src") || ""; },
443
+ set src(val) { return this.setAttribute("src",val); },
444
+
445
+ get id() { return this.getAttribute("id") || ""; },
446
+ set id(val) { return this.setAttribute("id",val); },
447
+
448
+ getAttribute: function(name){
449
+ return this._dom.hasAttribute(name) ?
450
+ new String( this._dom.getAttribute(name) ) :
451
+ null;
452
+ },
453
+ setAttribute: function(name,value){
454
+ this._dom.setAttribute(name,value);
455
+ },
456
+ removeAttribute: function(name){
457
+ this._dom.removeAttribute(name);
458
+ },
459
+
460
+ get childNodes(){
461
+ return new DOMNodeList( this._dom.getChildNodes() );
462
+ },
463
+ get firstChild(){
464
+ return makeNode( this._dom.getFirstChild() );
465
+ },
466
+ get lastChild(){
467
+ return makeNode( this._dom.getLastChild() );
468
+ },
469
+ appendChild: function(node){
470
+ this._dom.appendChild( node._dom );
471
+ },
472
+ insertBefore: function(node,before){
473
+ this._dom.insertBefore( node._dom, before ? before._dom : before );
474
+ },
475
+ removeChild: function(node){
476
+ this._dom.removeChild( node._dom );
477
+ },
478
+
479
+ getElementsByTagName: DOMDocument.prototype.getElementsByTagName,
480
+
481
+ addEventListener: window.addEventListener,
482
+ removeEventListener: window.removeEventListener,
483
+ dispatchEvent: window.dispatchEvent,
484
+
485
+ click: function(){
486
+ var event = document.createEvent();
487
+ event.initEvent("click");
488
+ this.dispatchEvent(event);
489
+ },
490
+ submit: function(){
491
+ var event = document.createEvent();
492
+ event.initEvent("submit");
493
+ this.dispatchEvent(event);
494
+ },
495
+ focus: function(){
496
+ var event = document.createEvent();
497
+ event.initEvent("focus");
498
+ this.dispatchEvent(event);
499
+ },
500
+ blur: function(){
501
+ var event = document.createEvent();
502
+ event.initEvent("blur");
503
+ this.dispatchEvent(event);
504
+ },
505
+ get elements(){
506
+ return this.getElementsByTagName("*");
507
+ },
508
+ get contentWindow(){
509
+ return this.nodeName == "IFRAME" ? {
510
+ document: this.contentDocument
511
+ } : null;
512
+ },
513
+ get contentDocument(){
514
+ if ( this.nodeName == "IFRAME" ) {
515
+ if ( !this._doc )
516
+ this._doc = new DOMDocument(
517
+ new java.io.ByteArrayInputStream((new java.lang.String(
518
+ "<html><head><title></title></head><body></body></html>"))
519
+ .getBytes("UTF8")));
520
+ return this._doc;
521
+ } else
522
+ return null;
523
+ }
524
+ });
525
+
526
+ // Helper method for extending one object with another
527
+
528
+ function extend(a,b) {
529
+ for ( var i in b ) {
530
+ var g = b.__lookupGetter__(i), s = b.__lookupSetter__(i);
531
+
532
+ if ( g || s ) {
533
+ if ( g )
534
+ a.__defineGetter__(i, g);
535
+ if ( s )
536
+ a.__defineSetter__(i, s);
537
+ } else
538
+ a[i] = b[i];
539
+ }
540
+ return a;
541
+ }
542
+
543
+ // Helper method for generating the right
544
+ // DOM objects based upon the type
545
+
546
+ var obj_nodes = new java.util.HashMap();
547
+
548
+ function makeNode(node){
549
+ if ( node ) {
550
+ if ( !obj_nodes.containsKey( node ) )
551
+ obj_nodes.put( node, node.getNodeType() ==
552
+ Packages.org.w3c.dom.Node.ELEMENT_NODE ?
553
+ new DOMElement( node ) : new DOMNode( node ) );
554
+
555
+ return obj_nodes.get(node);
556
+ } else
557
+ return null;
558
+ }
559
+
560
+ // XMLHttpRequest
561
+ // Originally implemented by Yehuda Katz
562
+
563
+ window.XMLHttpRequest = function(){
564
+ this.headers = {};
565
+ this.responseHeaders = {};
566
+ };
567
+
568
+ XMLHttpRequest.prototype = {
569
+ open: function(method, url, async, user, password){
570
+ this.readyState = 1;
571
+ if (async)
572
+ this.async = true;
573
+ this.method = method || "GET";
574
+ this.url = url;
575
+ this.onreadystatechange();
576
+ },
577
+ setRequestHeader: function(header, value){
578
+ this.headers[header] = value;
579
+ },
580
+ getResponseHeader: function(header){ },
581
+ send: function(data){
582
+ var self = this;
583
+
584
+ function makeRequest(){
585
+ var url = new java.net.URL(curLocation, self.url);
586
+
587
+ if ( url.getProtocol() == "file" ) {
588
+ if ( self.method == "PUT" ) {
589
+ var out = new java.io.FileWriter(
590
+ new java.io.File( new java.net.URI( url.toString() ) ) ),
591
+ text = new java.lang.String( data || "" );
592
+
593
+ out.write( text, 0, text.length() );
594
+ out.flush();
595
+ out.close();
596
+ } else if ( self.method == "DELETE" ) {
597
+ var file = new java.io.File( new java.net.URI( url.toString() ) );
598
+ file["delete"]();
599
+ } else {
600
+ var connection = url.openConnection();
601
+ connection.connect();
602
+ handleResponse();
603
+ }
604
+ } else {
605
+ var connection = url.openConnection();
606
+
607
+ connection.setRequestMethod( self.method );
608
+
609
+ // Add headers to Java connection
610
+ for (var header in self.headers)
611
+ connection.addRequestProperty(header, self.headers[header]);
612
+
613
+ connection.connect();
614
+
615
+ // Stick the response headers into responseHeaders
616
+ for (var i = 0; ; i++) {
617
+ var headerName = connection.getHeaderFieldKey(i);
618
+ var headerValue = connection.getHeaderField(i);
619
+ if (!headerName && !headerValue) break;
620
+ if (headerName)
621
+ self.responseHeaders[headerName] = headerValue;
622
+ }
623
+
624
+ handleResponse();
625
+ }
626
+
627
+ function handleResponse(){
628
+ self.readyState = 4;
629
+ self.status = parseInt(connection.responseCode) || undefined;
630
+ self.statusText = connection.responseMessage || "";
631
+
632
+ var stream = new java.io.InputStreamReader(connection.getInputStream()),
633
+ buffer = new java.io.BufferedReader(stream), line;
634
+
635
+ while ((line = buffer.readLine()) != null)
636
+ self.responseText += line;
637
+
638
+ self.responseXML = null;
639
+
640
+ if ( self.responseText.match(/^\s*</) ) {
641
+ try {
642
+ self.responseXML = new DOMDocument(
643
+ new java.io.ByteArrayInputStream(
644
+ (new java.lang.String(
645
+ self.responseText)).getBytes("UTF8")));
646
+ } catch(e) {}
647
+ }
648
+ }
649
+
650
+ self.onreadystatechange();
651
+ }
652
+
653
+ if (this.async)
654
+ (new java.lang.Thread(new java.lang.Runnable({
655
+ run: makeRequest
656
+ }))).start();
657
+ else
658
+ makeRequest();
659
+ },
660
+ abort: function(){},
661
+ onreadystatechange: function(){},
662
+ getResponseHeader: function(header){
663
+ if (this.readyState < 3)
664
+ throw new Error("INVALID_STATE_ERR");
665
+ else {
666
+ var returnedHeaders = [];
667
+ for (var rHeader in this.responseHeaders) {
668
+ if (rHeader.match(new Regexp(header, "i")))
669
+ returnedHeaders.push(this.responseHeaders[rHeader]);
670
+ }
671
+
672
+ if (returnedHeaders.length)
673
+ return returnedHeaders.join(", ");
674
+ }
675
+
676
+ return null;
677
+ },
678
+ getAllResponseHeaders: function(header){
679
+ if (this.readyState < 3)
680
+ throw new Error("INVALID_STATE_ERR");
681
+ else {
682
+ var returnedHeaders = [];
683
+
684
+ for (var header in this.responseHeaders)
685
+ returnedHeaders.push( header + ": " + this.responseHeaders[header] );
686
+
687
+ return returnedHeaders.join("\r\n");
688
+ }
689
+ },
690
+ async: true,
691
+ readyState: 0,
692
+ responseText: "",
693
+ status: 0
694
+ };
695
+ })();