bowline 0.5.3 → 0.5.4

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 (47) hide show
  1. data/.gitignore +1 -0
  2. data/README.txt +62 -62
  3. data/Rakefile +10 -0
  4. data/TODO +3 -1
  5. data/VERSION +1 -1
  6. data/assets/bowline.js +118 -3
  7. data/bowline.gemspec +6 -6
  8. data/examples/example.js +2 -15
  9. data/examples/tweet.rb +35 -0
  10. data/examples/tweets_binder.rb +6 -0
  11. data/examples/twitter.html +6 -8
  12. data/examples/users.rb +8 -14
  13. data/lib/bowline/binders.rb +130 -42
  14. data/lib/bowline/dependencies/lib/dependencies.rb +2 -1
  15. data/lib/bowline/dependencies/lib/ext/rubygems.rb +4 -4
  16. data/lib/bowline/desktop.rb +11 -2
  17. data/lib/bowline/desktop/app.rb +7 -3
  18. data/lib/bowline/desktop/bridge.rb +8 -9
  19. data/lib/bowline/desktop/clipboard.rb +11 -2
  20. data/lib/bowline/desktop/dialog.rb +19 -0
  21. data/lib/bowline/desktop/dock.rb +14 -3
  22. data/lib/bowline/desktop/host.rb +13 -4
  23. data/lib/bowline/desktop/js.rb +2 -2
  24. data/lib/bowline/desktop/misc.rb +7 -3
  25. data/lib/bowline/desktop/network.rb +1 -1
  26. data/lib/bowline/desktop/proxy.rb +28 -30
  27. data/lib/bowline/desktop/sound.rb +3 -2
  28. data/lib/bowline/desktop/window.rb +147 -21
  29. data/lib/bowline/desktop/window_manager.rb +53 -5
  30. data/lib/bowline/desktop/window_methods.rb +2 -2
  31. data/lib/bowline/ext/object.rb +1 -1
  32. data/lib/bowline/generators.rb +1 -1
  33. data/lib/bowline/generators/binder.rb +1 -1
  34. data/lib/bowline/helpers.rb +1 -1
  35. data/lib/bowline/initializer.rb +37 -4
  36. data/lib/bowline/library.rb +11 -0
  37. data/lib/bowline/local_model.rb +45 -19
  38. data/lib/bowline/logging.rb +1 -1
  39. data/lib/bowline/platform.rb +8 -6
  40. data/lib/bowline/tasks/app.rake +4 -3
  41. data/lib/bowline/version.rb +1 -1
  42. data/lib/bowline/watcher.rb +18 -8
  43. data/templates/binder.rb +1 -1
  44. data/vendor/pathname.rb +0 -4
  45. metadata +6 -6
  46. data/examples/account.rb +0 -31
  47. data/examples/tweets.rb +0 -28
@@ -1,5 +1,24 @@
1
1
  module Bowline
2
2
  module Desktop
3
+ # This class provides a useful abstraction on the Window class.
4
+ # It's the usual way of interfacing with your application's windows,
5
+ # and all of Bowline's windows normally inherit from it.
6
+ #
7
+ # You'll need to call the setup method, before calling using this class.
8
+ # If the window is deallocated (i.e. closed), you'll need to call it again.
9
+ # It's worth not calling the setup method before you need it, since it'll
10
+ # increase the amount of CPU your application uses.
11
+ #
12
+ # By default, windows are hidden. You'll need to show your custom windows explicitly
13
+ # before any user interaction using the show method. You can still load HTML/JavaScript
14
+ # while the window is hidden.
15
+ #
16
+ # If you don't want to show the window until it's properly loaded, you can use this pattern:
17
+ # MyWindow.on_load { MyWindow.show }
18
+ # MyWindow.file = :test
19
+ #
20
+ # Any undefined methods are delegated to the Window class.
21
+ # See that class for the full windowing API.
3
22
  class WindowManager
4
23
  extend Bridge::ClassMethods
5
24
  js_expose
@@ -8,21 +27,24 @@ module Bowline
8
27
  watch :on_load
9
28
 
10
29
  class << self
30
+ # An array of all the application's windows
11
31
  def windows
12
- subclasses.map(&:constantize)
32
+ Bowline::Desktop::WindowManager.subclasses.map(&:constantize)
13
33
  end
14
34
 
35
+ # An array of all the application's windows that are currently shown
15
36
  def shown_windows
16
37
  windows.select(&:shown?)
17
38
  end
18
39
 
40
+ # An array of all the application's allocated windows
19
41
  def allocated_windows
20
42
  windows.select(&:allocated?)
21
43
  end
22
44
 
23
45
  # Methods for subclasses:
24
46
 
25
- def window
47
+ def window #:nodoc:
26
48
  @window
27
49
  end
28
50
 
@@ -30,6 +52,9 @@ module Bowline
30
52
  !!@window
31
53
  end
32
54
 
55
+ # Call this method to allocate a new window.
56
+ # You'll need to do this before using it,
57
+ # or after it has been closed.
33
58
  def setup
34
59
  return unless Desktop.enabled?
35
60
  return if @window && !@window.dealocated?
@@ -39,19 +64,42 @@ module Bowline
39
64
  @window = Window.new
40
65
  end
41
66
  end
42
-
67
+
68
+ # Evaluate JavaScript in this window. Pass
69
+ # a block to capture the result.
70
+ # Example:
71
+ # eval("Bowline.msgs") {|res| puts res }
43
72
  def eval(*args, &block)
44
73
  JS.eval(window, *args, &block)
45
74
  end
46
75
 
76
+ # Window Proxy instance. Use this to evaluate JavaScript
77
+ # in this window, but in an object orientated way.
78
+ # Example:
79
+ # page.yourFunc.call
80
+ #
81
+ # See Bowline::Desktop::Proxy for full usage.
47
82
  def page
48
- Proxy.new(window)
83
+ Proxy.new(self)
84
+ end
85
+
86
+ def bowline
87
+ page.Bowline
49
88
  end
50
89
 
90
+ # Returns true if the both the HTML and JavaScript in
91
+ # this window have loaded. Use the on_load event to know
92
+ # when this window has loaded.
51
93
  def loaded?
52
94
  @loaded
53
95
  end
54
96
 
97
+ ##
98
+ # :singleton-method: on_load(method = nil, &block)
99
+ # A Watcher event method that gets called when this window loads.
100
+ # Example:
101
+ # on_load { puts "Window loaded!" }
102
+
55
103
  def loaded! # :nodoc:
56
104
  @loaded = true
57
105
  watcher.call(:on_load)
@@ -59,7 +107,7 @@ module Bowline
59
107
  end
60
108
 
61
109
  # Delegate most methods to Window
62
- def method_missing(sym, *args)
110
+ def method_missing(sym, *args) #:nodoc:
63
111
  if window && window.respond_to?(sym)
64
112
  return window.send(sym, *args)
65
113
  end
@@ -1,6 +1,6 @@
1
1
  module Bowline
2
2
  module Desktop
3
- module WindowMethods
3
+ module WindowMethods #:nodoc:
4
4
  def center(direction = nil)
5
5
  direction =
6
6
  case direction
@@ -63,7 +63,7 @@ module Bowline
63
63
  # The methods won't exist on window
64
64
  # if Bowline::Desktop isn't enabled
65
65
  def method_missing(sym, *args)
66
- Bowline::Desktop.enabled? ? raise : nil
66
+ Bowline::Desktop.enabled? ? super : nil
67
67
  end
68
68
  end
69
69
  end
@@ -1,5 +1,5 @@
1
1
  class Object
2
- # Aim is to convert the object in:
2
+ # Aim is to convert the object into:
3
3
  # * A hash or
4
4
  # * An array of hashes
5
5
  def to_js
@@ -2,7 +2,7 @@ gem 'templater', '>= 0.3.2'
2
2
  require 'templater'
3
3
 
4
4
  module Bowline
5
- module Generators
5
+ module Generators #:nodoc: all
6
6
  extend Templater::Manifold
7
7
 
8
8
  desc <<-DESC
@@ -9,7 +9,7 @@ module Bowline::Generators
9
9
  super + "Binder < Bowline::Binders::Base"
10
10
  end
11
11
 
12
- def expose_name
12
+ def bind_name
13
13
  plain_class_name.singularize
14
14
  end
15
15
 
@@ -1,4 +1,4 @@
1
1
  module Bowline
2
- module Helpers
2
+ module Helpers #:nodoc:
3
3
  end
4
4
  end
@@ -7,7 +7,7 @@ module Bowline
7
7
  @@configuration
8
8
  end
9
9
 
10
- def configuration=(configuration)
10
+ def configuration=(configuration) #:nodoc:
11
11
  @@configuration = configuration
12
12
  end
13
13
 
@@ -15,10 +15,12 @@ module Bowline
15
15
  @initialized || false
16
16
  end
17
17
 
18
- def initialized=(initialized)
18
+ def initialized=(initialized) #:nodoc:
19
19
  @initialized ||= initialized
20
20
  end
21
21
 
22
+ # The default Bowline logger.
23
+ # Also see the Bowline::Logging class.
22
24
  def logger
23
25
  if defined?(BOWLINE_LOGGER)
24
26
  BOWLINE_LOGGER
@@ -27,12 +29,13 @@ module Bowline
27
29
  end
28
30
  end
29
31
 
32
+ # The application's root
30
33
  def root
31
34
  Pathname.new(APP_ROOT) if defined?(APP_ROOT)
32
35
  end
33
36
  end
34
37
 
35
- class Initializer
38
+ class Initializer #:nodoc:
36
39
  # The Configuration instance used by this Initializer instance.
37
40
  attr_reader :configuration
38
41
 
@@ -58,6 +61,7 @@ module Bowline
58
61
  @loaded_plugins = []
59
62
  end
60
63
 
64
+ # Add all of Ruby's stdlib to the load path
61
65
  def initialize_ruby
62
66
  return unless Bowline::Desktop.enabled?
63
67
  ruby_path = Bowline::Library.local_rubylib_path
@@ -65,6 +69,10 @@ module Bowline
65
69
  ruby_path = Bowline::Library.rubylib_path
66
70
  return unless File.directory?(ruby_path)
67
71
  end
72
+ # Remove old stdlib load paths
73
+ $:.delete_if {|path| path =~ /^\/usr\// }
74
+
75
+ # Add new stdlib load paths
68
76
  version = Library::RUBY_LIB_VERSION
69
77
  platform = Library::RUBY_ARCHLIB_PLATFORM
70
78
  $: << File.join(ruby_path, version) # RUBY_LIB
@@ -75,9 +83,10 @@ module Bowline
75
83
  $: << File.join(ruby_path, "vendor_ruby") # RUBY_VENDOR_LIB
76
84
  $: << File.join(ruby_path, "vendor_ruby", version) # RUBY_VENDOR_LIB2
77
85
  $: << File.join(ruby_path, "vendor_ruby", version, platform) # RUBY_VENDOR_ARCHLIB
86
+
87
+ # These two need to be required to fully setup internationalization
78
88
  require File.join(*%w[enc encdb])
79
89
  require File.join(*%w[enc trans transdb])
80
- $:.uniq!
81
90
  end
82
91
 
83
92
  def require_frameworks
@@ -119,6 +128,7 @@ module Bowline
119
128
  $LOAD_PATH.uniq!
120
129
  end
121
130
 
131
+ # Initializes ActiveRecord databases
122
132
  def initialize_database
123
133
  if defined?(ActiveRecord)
124
134
  ActiveRecord::Base.establish_connection(configuration.database_configuration)
@@ -268,6 +278,8 @@ module Bowline
268
278
  silence_warnings { Object.const_set "APP_NAME", configuration.name }
269
279
  end
270
280
 
281
+ # Creates a class called AppConfig from configuration
282
+ # variables found in config/application.yml
271
283
  def load_app_config
272
284
  app_config = configuration.app_config
273
285
  return unless app_config
@@ -446,13 +458,34 @@ module Bowline
446
458
 
447
459
  attr_accessor :initializer_glob
448
460
 
461
+ # Set the path that MainWindow will load
462
+ # when the application starts.
449
463
  attr_accessor :index_path
450
464
 
465
+ # Set the application's name.
466
+ # This is required.
451
467
  attr_accessor :name
468
+
469
+ # Set the application's globally unique id.
470
+ # This is required.
471
+ # Example:
472
+ # config.id = "com.maccman.bowline"
452
473
  attr_accessor :id
474
+
475
+ # Set the application's version.
476
+ # Example:
477
+ # config.version = "0.1.2"
453
478
  attr_accessor :version
479
+
454
480
  attr_accessor :description
455
481
  attr_accessor :url
482
+
483
+ # Set the application's icon.
484
+ # Point this variable to the icons path.
485
+ #
486
+ # If this isn't specified, Bowline's default one will be used.
487
+ #
488
+ # Supported icon files are PNGs and JPGs, preferably 512px x 512px.
456
489
  attr_accessor :icon
457
490
 
458
491
  attr_accessor :publisher
@@ -1,4 +1,5 @@
1
1
  module Bowline
2
+ # Provides paths to Bowline's required libraries.
2
3
  module Library
3
4
  RUBY_LIB_VERSION = "1.9.1"
4
5
  RUBY_ARCHLIB_PLATFORM = "i386-darwin9.8.0"
@@ -6,6 +7,8 @@ module Bowline
6
7
  DESKTOP_URL = "#{PROJECT_URL}/bowline-desktop"
7
8
  RUBYLIB_URL = "#{PROJECT_URL}/rubylib.zip"
8
9
 
10
+ # Path to a folder stored under the users
11
+ # home directory containing the downloaded libraries.
9
12
  def path
10
13
  File.expand_path(
11
14
  File.join(home_path, ".bowline")
@@ -13,11 +16,13 @@ module Bowline
13
16
  end
14
17
  module_function :path
15
18
 
19
+ # Path to the bowline-desktop binary
16
20
  def desktop_path
17
21
  File.join(path, "bowline-desktop")
18
22
  end
19
23
  module_function :desktop_path
20
24
 
25
+ # Path to Ruby's stdlib
21
26
  def rubylib_path
22
27
  File.join(path, "rubylib")
23
28
  end
@@ -33,6 +38,12 @@ module Bowline
33
38
  end
34
39
  module_function :local_rubylib_path
35
40
 
41
+ def local_build_path
42
+ File.join(APP_ROOT, "build")
43
+ end
44
+ module_function :local_build_path
45
+
46
+ # Returns true if all required libraries exist.
36
47
  def ready?
37
48
  File.exist?(desktop_path) &&
38
49
  File.directory?(rubylib_path) &&
@@ -1,4 +1,12 @@
1
1
  module Bowline
2
+ # The LocalModel class mirrors ActiveRecord's api, and is used for
3
+ # models you want to hold in memory.
4
+ #
5
+ # You can also use this class in conjunction with Bowline's binders.
6
+ #
7
+ # All normal ActiveRecord callbacks are supported, such as before_save and after_save.
8
+ #
9
+ # Associations are not currently supported.
2
10
  class LocalModel
3
11
  extend Watcher::Base
4
12
 
@@ -6,47 +14,60 @@ module Bowline
6
14
  :before_create, :after_create,
7
15
  :before_update, :after_update,
8
16
  :before_destroy, :after_destroy
9
-
10
- @@records = []
11
-
17
+
12
18
  class << self
19
+ def records
20
+ @records ||= []
21
+ end
22
+
23
+ # Populate the model with the array argument.
24
+ # This doesn't replace the model's existing records.
25
+ # Create callbacks are still executed.
13
26
  def populate(array)
14
27
  array.each {|r| create(r) }
15
28
  end
16
-
29
+
30
+ # Find record by ID, or raise.
17
31
  def find(id)
18
- @@records.find {|r| r.id == id } || raise('Unknown Record')
32
+ records.find {|r| r.id == id } || raise('Unknown Record')
19
33
  end
20
34
  alias :[] :find
21
35
 
22
36
  def first
23
- @@records[0]
37
+ records[0]
24
38
  end
25
39
 
26
40
  def last
27
- @@records[-1]
41
+ records[-1]
28
42
  end
29
43
 
30
44
  def count
31
- @@records.length
45
+ records.length
32
46
  end
33
47
 
34
48
  def all
35
- @@records
49
+ records
36
50
  end
37
-
51
+
38
52
  def destroy(id)
39
53
  find(id).destroy
40
54
  end
41
55
 
56
+ # Removes all records and executes
57
+ # destory callbacks.
42
58
  def destroy_all
43
- @@records.dup.each {|r| r.destroy }
59
+ records.dup.each {|r| r.destroy }
44
60
  end
45
61
 
62
+ # Removes all records without executing
63
+ # destroy callbacks.
46
64
  def delete_all
47
- @@records.clear
65
+ records.clear
48
66
  end
49
-
67
+
68
+ # Create a new record.
69
+ # Example:
70
+ # create(:name => "foo", :id => 1)
50
71
  def create(atts = {})
51
72
  rec = self.new(atts)
52
73
  rec.save && rec
@@ -54,7 +75,11 @@ module Bowline
54
75
  end
55
76
 
56
77
  attr_reader :attributes
57
-
78
+
79
+ # Initialize the record with an optional
80
+ # hash of attributes. If a :id attribute
81
+ # isn't passed, the instance's object id
82
+ # is used instead.
58
83
  def initialize(atts = {})
59
84
  @attributes = {}.with_indifferent_access
60
85
  @attributes.replace(atts)
@@ -66,7 +91,8 @@ module Bowline
66
91
  def id
67
92
  @attributes[:id]
68
93
  end
69
-
94
+
95
+ # Update record with a hash of new attributes.
70
96
  def update(atts)
71
97
  run_callbacks(:before_save)
72
98
  run_callbacks(:before_update)
@@ -75,12 +101,12 @@ module Bowline
75
101
  run_callbacks(:after_update)
76
102
  true
77
103
  end
78
-
104
+
79
105
  def save
80
106
  run_callbacks(:before_save)
81
107
  if @new_record
82
108
  run_callbacks(:before_create)
83
- @@records << self
109
+ self.class.records << self
84
110
  run_callbacks(:after_create)
85
111
  @new_record = false
86
112
  end
@@ -90,7 +116,7 @@ module Bowline
90
116
 
91
117
  def destroy
92
118
  run_callbacks(:before_destroy)
93
- @@records.delete(self)
119
+ self.class.records.delete(self)
94
120
  run_callbacks(:after_destroy)
95
121
  true
96
122
  end
@@ -110,7 +136,7 @@ module Bowline
110
136
 
111
137
  private
112
138
  def run_callbacks(callback)
113
- self.class.watcher.call(callback)
139
+ self.class.watcher.call(callback, self)
114
140
  end
115
141
  end
116
142
  end