unloosen 0.1.1 → 0.1.2

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 (49) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +3 -3
  3. data/Gemfile.lock +4 -4
  4. data/README.md +12 -20
  5. data/Rakefile +8 -1
  6. data/app.rb +57 -57
  7. data/bin/dl-util.rb +22 -22
  8. data/bin/minify.rb +7 -7
  9. data/examples/kitchensink/app.rb +17 -17
  10. data/examples/omikuji-popup/app.rb +20 -20
  11. data/examples/omikuji-popup/popup.html +12 -12
  12. data/examples/simple-content-script/app.rb +5 -5
  13. data/examples/simple-content-script/loader-content-script.esm.js +22 -22
  14. data/examples/simple-content-script/manifest.json +22 -22
  15. data/examples/simple-content-script/module-content-script.esm.js +73 -73
  16. data/lib/unloosen/compat/rubygems.rb +91 -91
  17. data/lib/unloosen/emit/emit_bg.rb +2 -2
  18. data/lib/unloosen/emit/emit_cs.rb +2 -2
  19. data/lib/unloosen/emit/emit_pu.rb +2 -2
  20. data/lib/unloosen/emit/emit_sb.rb +2 -2
  21. data/lib/unloosen/mode/background.rb +8 -8
  22. data/lib/unloosen/mode/content_script.rb +17 -17
  23. data/lib/unloosen/mode/mode.rb +12 -12
  24. data/lib/unloosen/mode/on_installed.rb +9 -9
  25. data/lib/unloosen/mode/popup.rb +8 -8
  26. data/lib/unloosen/mode/sandbox.rb +8 -8
  27. data/lib/unloosen/toplevel_alias.rb +49 -49
  28. data/lib/unloosen/utils/js.rb +208 -208
  29. data/lib/unloosen/utils/require_remote.rb +125 -125
  30. data/lib/unloosen/version.rb +1 -1
  31. data/lib/unloosen_simple.rb +8 -8
  32. data/packages/unloosen-ruby/dist/entry/loader-content-script.esm.js +23 -23
  33. data/packages/unloosen-ruby/dist/entry/module-background.esm.js +85 -85
  34. data/packages/unloosen-ruby/dist/entry/module-content-script.esm.js +74 -74
  35. data/packages/unloosen-ruby/dist/entry/module-popup.esm.js +74 -74
  36. data/packages/unloosen-ruby/dist/entry/module-sandbox.esm.js +59 -59
  37. data/packages/unloosen-ruby/dist/index.esm.js +1 -1
  38. data/packages/unloosen-ruby/dist/unloosen.esm.js +60 -60
  39. data/packages/unloosen-ruby/package-lock.json +12 -11
  40. data/packages/unloosen-ruby/package.json +3 -5
  41. data/packages/unloosen-ruby/src/entry/loader-content-script.js +24 -24
  42. data/packages/unloosen-ruby/src/entry/module-background.js +26 -26
  43. data/packages/unloosen-ruby/src/entry/module-content-script.js +15 -15
  44. data/packages/unloosen-ruby/src/entry/module-popup.js +14 -14
  45. data/packages/unloosen-ruby/src/entry/module-sandbox.js +14 -14
  46. data/packages/unloosen-ruby/src/unloosen.js +62 -62
  47. data/unloosen.config.json +8 -8
  48. data/unloosen.gemspec +1 -1
  49. metadata +4 -4
@@ -3472,77 +3472,77 @@ const initVM = async(wasmUrl) => {
3472
3472
  return vm;
3473
3473
  };
3474
3474
 
3475
- var VM;
3476
-
3477
- const UnloosenVersion = "0.1.0";
3478
- const printInitMessage = () => {
3479
- evalRubyCode(`
3480
- puts <<~"INF"
3481
- Unloosen Ruby Browser Extension by logiteca7/aaaa777
3482
- Ruby version: #{RUBY_DESCRIPTION}
3483
- Unloosen version: ${UnloosenVersion}
3484
- INF
3485
- `);
3486
- };
3487
-
3488
- const buildExtensionURL = (filepath) => {
3489
- return new URL(chrome.runtime.getURL(filepath));
3490
- };
3491
-
3492
- // eval ruby script
3493
- const evalRubyCode = (code) => {
3494
- VM.eval(code);
3495
- };
3496
-
3497
- const evalRubyCodeAsync = async (code) => {
3498
- await VM.evalAsync(code);
3499
- };
3500
-
3501
- const evalRubyFromURL = async (url) => {
3502
- await fetch(url)
3503
- .then((response) => response.text())
3504
- .then((text) => evalRubyCodeAsync(text));
3505
- };
3506
-
3507
- // build chrome-extension:// url and eval ruby script
3508
- const evalRubyFromExtension = async (filepath) => {
3509
- await evalRubyFromURL(buildExtensionURL(filepath));
3510
- };
3511
-
3512
- const loadConfig = async (configKey, defaultVal) => {
3513
- try {
3514
- return await fetch(chrome.runtime.getURL("unloosen.config.json"))
3515
- .then((response) => {
3516
- if(response.ok) {
3517
- return response.json().then((json) => json[configKey] == undefined ? defaultVal : json[configKey]);
3518
- } else {
3519
- return defaultVal;
3520
- }
3521
- });
3522
- } catch {
3523
- return defaultVal;
3524
- }
3525
- };
3526
-
3527
- const init = async () => {
3528
- return initVM(buildExtensionURL(await loadConfig("ruby.wasm", "ruby.wasm")))
3529
- .then(async (vm) => {
3530
- VM = vm;
3531
- return evalRubyCode('$:.unshift "/unloosen"');
3532
- })
3533
- .then(async (promise) => printInitMessage() || promise);
3534
- };
3535
-
3536
- const main = async () => {
3537
- await init();
3538
- await evalRubyCode("module Unloosen; CURRENT_EVENT = :content_script; end");
3539
-
3540
- await evalRubyCode("require 'require_remote'");
3541
- if(await loadConfig("remote-require", true)) {
3542
- await evalRubyCode("add_require_remote_uri('" + buildExtensionURL('lib') +"')");
3543
- await evalRubyCode("add_require_remote_uri('" + buildExtensionURL('') +"')");
3544
- }
3545
- await evalRubyFromExtension(await loadConfig("application", 'app.rb'));
3546
- };
3547
-
3475
+ var VM;
3476
+
3477
+ const UnloosenVersion = "0.1.0";
3478
+ const printInitMessage = () => {
3479
+ evalRubyCode(`
3480
+ puts <<~"INF"
3481
+ Unloosen Ruby Browser Extension by logiteca7/aaaa777
3482
+ Ruby version: #{RUBY_DESCRIPTION}
3483
+ Unloosen version: ${UnloosenVersion}
3484
+ INF
3485
+ `);
3486
+ };
3487
+
3488
+ const buildExtensionURL = (filepath) => {
3489
+ return new URL(chrome.runtime.getURL(filepath));
3490
+ };
3491
+
3492
+ // eval ruby script
3493
+ const evalRubyCode = (code) => {
3494
+ VM.eval(code);
3495
+ };
3496
+
3497
+ const evalRubyCodeAsync = async (code) => {
3498
+ await VM.evalAsync(code);
3499
+ };
3500
+
3501
+ const evalRubyFromURL = async (url) => {
3502
+ await fetch(url)
3503
+ .then((response) => response.text())
3504
+ .then((text) => evalRubyCodeAsync(text));
3505
+ };
3506
+
3507
+ // build chrome-extension:// url and eval ruby script
3508
+ const evalRubyFromExtension = async (filepath) => {
3509
+ await evalRubyFromURL(buildExtensionURL(filepath));
3510
+ };
3511
+
3512
+ const loadConfig = async (configKey, defaultVal) => {
3513
+ try {
3514
+ return await fetch(chrome.runtime.getURL("unloosen.config.json"))
3515
+ .then((response) => {
3516
+ if(response.ok) {
3517
+ return response.json().then((json) => json[configKey] == undefined ? defaultVal : json[configKey]);
3518
+ } else {
3519
+ return defaultVal;
3520
+ }
3521
+ });
3522
+ } catch {
3523
+ return defaultVal;
3524
+ }
3525
+ };
3526
+
3527
+ const init = async () => {
3528
+ return initVM(buildExtensionURL(await loadConfig("ruby.wasm", "ruby.wasm")))
3529
+ .then(async (vm) => {
3530
+ VM = vm;
3531
+ return evalRubyCode('$:.unshift "/unloosen"');
3532
+ })
3533
+ .then(async (promise) => printInitMessage() || promise);
3534
+ };
3535
+
3536
+ const main = async () => {
3537
+ await init();
3538
+ await evalRubyCode("module Unloosen; CURRENT_EVENT = :content_script; end");
3539
+
3540
+ await evalRubyCode("require 'require_remote'");
3541
+ if(await loadConfig("remote-require", true)) {
3542
+ await evalRubyCode("add_require_remote_uri('" + buildExtensionURL('lib') +"')");
3543
+ await evalRubyCode("add_require_remote_uri('" + buildExtensionURL('') +"')");
3544
+ }
3545
+ await evalRubyFromExtension(await loadConfig("application", 'app.rb'));
3546
+ };
3547
+
3548
3548
  main();
@@ -1,92 +1,92 @@
1
- # MIT License
2
-
3
- # Copyright (c) 2022 Yuta Saito
4
-
5
- # Permission is hereby granted, free of charge, to any person obtaining a copy
6
- # of this software and associated documentation files (the "Software"), to deal
7
- # in the Software without restriction, including without limitation the rights
8
- # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- # copies of the Software, and to permit persons to whom the Software is
10
- # furnished to do so, subject to the following conditions:
11
-
12
- # The above copyright notice and this permission notice shall be included in all
13
- # copies or substantial portions of the Software.
14
-
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- # SOFTWARE.
22
-
23
- # source url: https://github.com/kateinoigakukun/irb.wasm
24
-
25
- require "rubygems/commands/install_command"
26
-
27
- class JS::Object
28
- def to_a
29
- ary = []
30
- self[:length].to_i.times do |i|
31
- ary << self.call(:at, i).to_i
32
- end
33
- ary
34
- end
35
- end
36
-
37
- class Gem::Request
38
- def self.request(uri, request)
39
- if uri.hostname == "rubygems.org" or uri.hostname == "index.rubygems.org"
40
- uri.hostname = "irb-wasm-proxy.edgecompute.app"
41
- end
42
- options = JS.eval("return {}")
43
- options[:method] = request.method.to_s
44
- options[:headers] = JS.eval("return {}")
45
- request.each_capitalized do |k, v|
46
- options[:headers][k] = v
47
- end
48
- response = JS.global.fetch(uri.to_s, options).await
49
- content_type = response[:headers].get("Content-Type").to_s
50
- is_octet_stream = content_type.start_with?("application/octet-stream")
51
- if uri.path.end_with?(".gem") or uri.path.end_with?(".rz") or is_octet_stream
52
- # FIXME: support class constructor and direct function call
53
- factory = JS.eval("return { make: (data) => new Uint8Array(data) }")
54
- body = factory.make response.arrayBuffer.await
55
- else
56
- body = response.text.await
57
- end
58
- if JS.is_a?(body, JS.global[:Uint8Array])
59
- body_str = body.to_a.pack("C*")
60
- else
61
- body_str = body.inspect
62
- end
63
- body_str = Net::BufferedIO.new(StringIO.new(body_str))
64
-
65
- status = response["status"].inspect
66
- response_class = Net::HTTPResponse::CODE_TO_OBJ[status]
67
- response = response_class.new("2.0", status.to_i, nil)
68
-
69
- response.reading_body(body_str, true) {}
70
- p response
71
- response
72
- end
73
-
74
- def perform_request(request) = Gem::Request.request(@uri, request)
75
- end
76
-
77
- class Gem::Installer
78
- def build_extensions
79
- # HACK: skip ext build for now...
80
- end
81
- end
82
-
83
- class Gem::Specification
84
- # HACK: supress missing extension warning, which prevents "require" to work
85
- def missing_extensions? = false
86
- end
87
-
88
- def Gem.user_home = Dir.home
89
- # HACK: Install gems under writable directory by default
90
- def Gem.dir = Gem.user_dir
91
-
1
+ # MIT License
2
+
3
+ # Copyright (c) 2022 Yuta Saito
4
+
5
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ # of this software and associated documentation files (the "Software"), to deal
7
+ # in the Software without restriction, including without limitation the rights
8
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ # copies of the Software, and to permit persons to whom the Software is
10
+ # furnished to do so, subject to the following conditions:
11
+
12
+ # The above copyright notice and this permission notice shall be included in all
13
+ # copies or substantial portions of the Software.
14
+
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ # SOFTWARE.
22
+
23
+ # source url: https://github.com/kateinoigakukun/irb.wasm
24
+
25
+ require "rubygems/commands/install_command"
26
+
27
+ class JS::Object
28
+ def to_a
29
+ ary = []
30
+ self[:length].to_i.times do |i|
31
+ ary << self.call(:at, i).to_i
32
+ end
33
+ ary
34
+ end
35
+ end
36
+
37
+ class Gem::Request
38
+ def self.request(uri, request)
39
+ if uri.hostname == "rubygems.org" or uri.hostname == "index.rubygems.org"
40
+ uri.hostname = "irb-wasm-proxy.edgecompute.app"
41
+ end
42
+ options = JS.eval("return {}")
43
+ options[:method] = request.method.to_s
44
+ options[:headers] = JS.eval("return {}")
45
+ request.each_capitalized do |k, v|
46
+ options[:headers][k] = v
47
+ end
48
+ response = JS.global.fetch(uri.to_s, options).await
49
+ content_type = response[:headers].get("Content-Type").to_s
50
+ is_octet_stream = content_type.start_with?("application/octet-stream")
51
+ if uri.path.end_with?(".gem") or uri.path.end_with?(".rz") or is_octet_stream
52
+ # FIXME: support class constructor and direct function call
53
+ factory = JS.eval("return { make: (data) => new Uint8Array(data) }")
54
+ body = factory.make response.arrayBuffer.await
55
+ else
56
+ body = response.text.await
57
+ end
58
+ if JS.is_a?(body, JS.global[:Uint8Array])
59
+ body_str = body.to_a.pack("C*")
60
+ else
61
+ body_str = body.inspect
62
+ end
63
+ body_str = Net::BufferedIO.new(StringIO.new(body_str))
64
+
65
+ status = response["status"].inspect
66
+ response_class = Net::HTTPResponse::CODE_TO_OBJ[status]
67
+ response = response_class.new("2.0", status.to_i, nil)
68
+
69
+ response.reading_body(body_str, true) {}
70
+ p response
71
+ response
72
+ end
73
+
74
+ def perform_request(request) = Gem::Request.request(@uri, request)
75
+ end
76
+
77
+ class Gem::Installer
78
+ def build_extensions
79
+ # HACK: skip ext build for now...
80
+ end
81
+ end
82
+
83
+ class Gem::Specification
84
+ # HACK: supress missing extension warning, which prevents "require" to work
85
+ def missing_extensions? = false
86
+ end
87
+
88
+ def Gem.user_home = Dir.home
89
+ # HACK: Install gems under writable directory by default
90
+ def Gem.dir = Gem.user_dir
91
+
92
92
  Gem.configuration.concurrent_downloads = 1
@@ -1,3 +1,3 @@
1
- module Unloosen
2
- CURRENT_EVENT = :background
1
+ module Unloosen
2
+ CURRENT_EVENT = :background
3
3
  end
@@ -1,3 +1,3 @@
1
- module Unloosen
2
- CURRENT_EVENT = :content_script
1
+ module Unloosen
2
+ CURRENT_EVENT = :content_script
3
3
  end
@@ -1,3 +1,3 @@
1
- module Unloosen
2
- CURRENT_EVENT = :popup
1
+ module Unloosen
2
+ CURRENT_EVENT = :popup
3
3
  end
@@ -1,3 +1,3 @@
1
- module Unloosen
2
- CURRENT_EVENT = :sandbox
1
+ module Unloosen
2
+ CURRENT_EVENT = :sandbox
3
3
  end
@@ -1,9 +1,9 @@
1
- require_relative "./mode"
2
-
3
- module Unloosen::Mode
4
- class Background < BaseMode
5
- def should_load?
6
- ::Unloosen::CURRENT_EVENT == :background && super
7
- end
8
- end
1
+ require_relative "./mode"
2
+
3
+ module Unloosen::Mode
4
+ class Background < BaseMode
5
+ def should_load?
6
+ ::Unloosen::CURRENT_EVENT == :background && super
7
+ end
8
+ end
9
9
  end
@@ -1,18 +1,18 @@
1
- require_relative "./mode"
2
-
3
- module Unloosen::Mode
4
- class ContentScript < BaseMode
5
- def initialize(enable_all_site: false, site: nil, sites: [], **kwds, &blk)
6
- @enable_all_site = enable_all_site
7
- @site = site
8
- @sites = sites
9
- @page_url = JS.global.location.href.inspect[1...-1]
10
-
11
- super(**kwds, &blk)
12
- end
13
-
14
- def should_load?
15
- ::Unloosen::CURRENT_EVENT == :content_script && super && @sites.find { |s| s.match?(@page_url) } || (@site && @page_url&.match?(@site)) || @enable_all_site
16
- end
17
- end
1
+ require_relative "./mode"
2
+
3
+ module Unloosen::Mode
4
+ class ContentScript < BaseMode
5
+ def initialize(enable_all_site: false, site: nil, sites: [], **kwds, &blk)
6
+ @enable_all_site = enable_all_site
7
+ @site = site
8
+ @sites = sites
9
+ @page_url = JS.global.location.href.inspect[1...-1]
10
+
11
+ super(**kwds, &blk)
12
+ end
13
+
14
+ def should_load?
15
+ ::Unloosen::CURRENT_EVENT == :content_script && super && @sites.find { |s| s.match?(@page_url) } || (@site && @page_url&.match?(@site)) || @enable_all_site
16
+ end
17
+ end
18
18
  end
@@ -1,13 +1,13 @@
1
- module Unloosen; module Mode
2
- class BaseMode
3
- def initialize(enable: true)
4
- @enable = enable
5
-
6
- return yield if self.should_load?
7
- end
8
-
9
- def should_load?
10
- @enable
11
- end
12
- end
1
+ module Unloosen; module Mode
2
+ class BaseMode
3
+ def initialize(enable: true)
4
+ @enable = enable
5
+
6
+ return yield if self.should_load?
7
+ end
8
+
9
+ def should_load?
10
+ @enable
11
+ end
12
+ end
13
13
  end; end
@@ -1,10 +1,10 @@
1
- require_relative "./mode"
2
-
3
- # should be event?
4
- module Unloosen::Mode
5
- class OnInstalled < BaseMode
6
- def should_load?
7
- ::Unloosen.const_defined?("ON_INSTALLED") && super
8
- end
9
- end
1
+ require_relative "./mode"
2
+
3
+ # should be event?
4
+ module Unloosen::Mode
5
+ class OnInstalled < BaseMode
6
+ def should_load?
7
+ ::Unloosen.const_defined?("ON_INSTALLED") && super
8
+ end
9
+ end
10
10
  end
@@ -1,9 +1,9 @@
1
- require_relative "./mode"
2
-
3
- module Unloosen::Mode
4
- class Popup < BaseMode
5
- def should_load?
6
- ::Unloosen::CURRENT_EVENT == :popup && super
7
- end
8
- end
1
+ require_relative "./mode"
2
+
3
+ module Unloosen::Mode
4
+ class Popup < BaseMode
5
+ def should_load?
6
+ ::Unloosen::CURRENT_EVENT == :popup && super
7
+ end
8
+ end
9
9
  end
@@ -1,9 +1,9 @@
1
- require_relative "./mode"
2
-
3
- module Unloosen::Mode
4
- class Sandbox < BaseMode
5
- def should_load?
6
- ::Unloosen::CURRENT_EVENT == :sandbox && super
7
- end
8
- end
1
+ require_relative "./mode"
2
+
3
+ module Unloosen::Mode
4
+ class Sandbox < BaseMode
5
+ def should_load?
6
+ ::Unloosen::CURRENT_EVENT == :sandbox && super
7
+ end
8
+ end
9
9
  end
@@ -1,50 +1,50 @@
1
- require_relative "mode/content_script"
2
- require_relative "mode/background"
3
- require_relative "mode/popup"
4
- require_relative "mode/sandbox"
5
-
6
-
7
- module Unloosen::ToplevelAlias
8
- def content_script(*args, **kwds, &blk)
9
- Unloosen::Mode::ContentScript.new(*args, **kwds, &blk)
10
- end
11
-
12
- def background(*args, **kwds, &blk)
13
- Unloosen::Mode::Background.new(*args, **kwds, &blk)
14
- end
15
-
16
- def sandbox(*args, **kwds, &blk)
17
- Unloosen::Mode::Sandbox.new(*args, **kwds, &blk)
18
- end
19
-
20
- def popup(*args, **kwds, &blk)
21
- Unloosen::Mode::Popup.new(*args, **kwds, &blk)
22
- end
23
-
24
- def on_installed(*args, **kwds, &blk)
25
- Unloosen::Mode::OnInstalled.new(*args, **kwds, &blk)
26
- end
27
-
28
- def alert(message)
29
- JS.global.alert(message)
30
- end
31
-
32
- def fetch(url)
33
- JS.global.fetch(url)
34
- end
35
- end
36
-
37
- @window = JS.global
38
- @undefined = JS::Undefined
39
- @null = JS::Null
40
- # overwrite eql? method to be comparable JS object
41
- @document = @window.document if @window[:document] != @undefined
42
- @console = @window.console if @window[:console] != @undefined
43
- @chrome = @window.chrome if @window[:console] != @undefined
44
-
45
- class << self
46
- include Unloosen::ToplevelAlias
47
- attr_accessor :window, :document, :console
48
- attr_accessor :chrome
49
- attr_reader :undefined, :null
1
+ require_relative "mode/content_script"
2
+ require_relative "mode/background"
3
+ require_relative "mode/popup"
4
+ require_relative "mode/sandbox"
5
+
6
+
7
+ module Unloosen::ToplevelAlias
8
+ def content_script(*args, **kwds, &blk)
9
+ Unloosen::Mode::ContentScript.new(*args, **kwds, &blk)
10
+ end
11
+
12
+ def background(*args, **kwds, &blk)
13
+ Unloosen::Mode::Background.new(*args, **kwds, &blk)
14
+ end
15
+
16
+ def sandbox(*args, **kwds, &blk)
17
+ Unloosen::Mode::Sandbox.new(*args, **kwds, &blk)
18
+ end
19
+
20
+ def popup(*args, **kwds, &blk)
21
+ Unloosen::Mode::Popup.new(*args, **kwds, &blk)
22
+ end
23
+
24
+ def on_installed(*args, **kwds, &blk)
25
+ Unloosen::Mode::OnInstalled.new(*args, **kwds, &blk)
26
+ end
27
+
28
+ def alert(message)
29
+ JS.global.alert(message)
30
+ end
31
+
32
+ def fetch(url)
33
+ JS.global.fetch(url)
34
+ end
35
+ end
36
+
37
+ @window = JS.global
38
+ @undefined = JS::Undefined
39
+ @null = JS::Null
40
+ # overwrite eql? method to be comparable JS object
41
+ @document = @window.document if @window[:document] != @undefined
42
+ @console = @window.console if @window[:console] != @undefined
43
+ @chrome = @window.chrome if @window[:console] != @undefined
44
+
45
+ class << self
46
+ include Unloosen::ToplevelAlias
47
+ attr_accessor :window, :document, :console
48
+ attr_accessor :chrome
49
+ attr_reader :undefined, :null
50
50
  end