motion-hybrid 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1166d97948ca1aab9c9d25fd3ad29a7246a9765c
4
- data.tar.gz: 1354f01d5146006199177ca31b5085dcb2c80a80
3
+ metadata.gz: ce0fa09ca4db9ca8ede81070958c19283aa176e4
4
+ data.tar.gz: 3e7355cc44d889739486a886afb825c9e9012ad3
5
5
  SHA512:
6
- metadata.gz: 6e023a1082b61452efc640041812eb0f6736e627b5df879153731f008e3275881239c54ee6440c9bc6480e4887c5f44bf07d011e6c2a21dc8e569f4c06aeb025
7
- data.tar.gz: 53cdaa93fe775e2c046405c44a0cb9016cbeac3a3775b59d232fbac0f393482d853763ed2fd25dd194829dda83f57f8d397a2c9f49e3b5b5bcfeafea4949976b
6
+ metadata.gz: b7d1d0c32961c63d908145a849a69a51dcec120ff4933c227a83cf879fdf2a803614562a81f931988b60e8eacf95c4f189fec5c3963827abfbe771375d6a88ed
7
+ data.tar.gz: 6e0b1e0dd7f1108c25966fd1256687e00c69399f88971625348c3e2cc9ba1cddd9481fba99206a5c512c5a79c3e9d0d10cbbc242b18f6d9f907818060961312c
data/README.md CHANGED
@@ -35,7 +35,7 @@ Instantiate a screen and set the initial path:
35
35
  # app/app_delegate.rb
36
36
  class AppDelegate < PM::Delegate
37
37
  def on_load(app, options)
38
- open BaseScreen.new(nav_bar: true, path: '/balvig'
38
+ open BaseScreen.new(nav_bar: true, path: '/balvig')
39
39
  end
40
40
  end
41
41
  ```
@@ -75,7 +75,25 @@ Links with anchor `#self` will open the new url within the current view without
75
75
 
76
76
  ### Non-GET requests
77
77
 
78
- Any non-GET requests (form posts etc) will display the result within the current view and also automatically refresh all other views so that pages are up to date.
78
+ Any non-GET requests (form posts etc) will display the result within the current view and also automatically refresh all parent views so that pages are up to date.
79
+
80
+ ## Custom routes
81
+
82
+ Sometimes you will want to trigger native iOS functionality from the web views, this is done by intercepting URLs that you can handle using the routing api, so you can do things like:
83
+
84
+ ```ruby
85
+ class BaseScreen < MotionHybrid::Screen
86
+ # pops up in-app email composer when clicking mailto: links
87
+ route /^mailto:/ do
88
+ BW::Mail.compose(to: 'bob@example.com', subject: 'In app emailing', message: 'Hi!', animated: true)
89
+ end
90
+
91
+ # ask for push nofitication permisions when user hits '/setup' url
92
+ route '/setup' do
93
+ App.delegate.register_for_push_notifications :badge, :sound, :alert
94
+ end
95
+ end
96
+ ```
79
97
 
80
98
  ## The Bridge
81
99
 
@@ -106,22 +124,3 @@ All markup is contained within a div with id `motion-hybrid-bridge`
106
124
  ### Navbar items
107
125
 
108
126
  TBA
109
-
110
- ## Custom routes
111
-
112
- Sometimes you will want to trigger native iOS functionality from the web views, this is done by intercepting URLs that you can handle using the routing api, so you can do things like:
113
-
114
- ```ruby
115
- class BaseScreen < MotionHybrid::Screen
116
- # pops up in-app email composer when clicking mailto: links
117
- route /^mailto:/ do
118
- BW::Mail.compose(to: 'bob@example.com', subject: 'In app emailing', message: 'Hi!', animated: true)
119
- end
120
-
121
- # ask for push nofitication permisions when user hits '/setup' url
122
- route '/setup' do
123
- App.delegate.register_for_push_notifications :badge, :sound, :alert
124
- end
125
- end
126
- ```
127
-
data/Rakefile CHANGED
@@ -9,3 +9,12 @@ Motion::Project::App.setup do |app|
9
9
  app.name = 'motion-hybrid test'
10
10
  app.version = '1.0'
11
11
  end
12
+
13
+ namespace :spec do
14
+ task :unit do
15
+ App.config.spec_mode = true
16
+ spec_files = App.config.spec_files - Dir.glob('./spec/functional/**/*.rb')
17
+ App.config.instance_variable_set("@spec_files", spec_files)
18
+ Rake::Task["simulator"].invoke
19
+ end
20
+ end
@@ -11,7 +11,7 @@ Motion::Require.all(Dir.glob(File.expand_path('../motion-hybrid/**/*.rb', __FILE
11
11
  Motion::Project::App.setup do |app|
12
12
  app.resources_dirs << File.join(File.dirname(__FILE__), 'resources')
13
13
  app.pods do
14
- pod 'CRToast', '<0.0.6'
14
+ pod 'CRToast', git: 'git@github.com:cruffenach/CRToast.git'
15
15
  pod 'FontAwesomeKit'
16
16
  pod 'MBProgressHUD'
17
17
  pod 'SpinKit'
@@ -4,12 +4,6 @@ module MotionHybrid
4
4
 
5
5
  included do
6
6
 
7
- # Trigger dom-loaded events
8
- route 'motionhybrid://ready' do
9
- dom_loaded
10
- true
11
- end
12
-
13
7
  # All clicked GET-links are pushed
14
8
  route /.*/ do |request|
15
9
  push(request.url) if request.http_method == 'GET' && request.type == UIWebViewNavigationTypeLinkClicked
@@ -3,95 +3,99 @@ module MotionHybrid
3
3
 
4
4
  def on_appear
5
5
  super
6
- if title_blank? && bridge.present?
7
- set_titles
8
- else
9
- @transition_finished = true
10
- end
6
+ @appeared = true
7
+ set_titles if dom_loaded?
11
8
  refresher.endRefreshing if refresher #avoids stuck animation
12
9
  end
13
10
 
14
11
  private
15
12
 
16
- def title_blank?
17
- title.blank? && navigationItem.titleView.blank?
18
- end
13
+ def load_bridge
14
+ self.bridge = Bridge.new(self)
15
+ end
19
16
 
20
- def load_bridge
21
- self.bridge = Bridge.new(self)
22
- end
17
+ def dom_loaded
18
+ PM.logger.debug "#{self} dom_loaded"
19
+ set_titles if appeared?
20
+ set_buttons
21
+ set_refresher
22
+ render_flash
23
+ @dom_loaded = true
24
+ end
23
25
 
24
- def dom_loaded
25
- set_titles if transition_finished?
26
- set_buttons
27
- set_refresher
28
- render_flash
29
- end
26
+ def dom_loaded?
27
+ !!@dom_loaded
28
+ end
30
29
 
31
- def transition_finished?
32
- @transition_finished
33
- end
30
+ def appeared?
31
+ !!@appeared
32
+ end
34
33
 
35
- def set_titles
36
- if bridge.subtitle.present?
37
- self.navigationItem.titleView = MultiLineHeader.new(bridge.title, bridge.subtitle)
38
- else
39
- self.title = bridge.title
34
+ def set_titles
35
+ if bridge.subtitle.present?
36
+ self.navigationItem.titleView = MultiLineHeader.new(bridge.title, bridge.subtitle)
37
+ else
38
+ self.title = bridge.title
39
+ self.navigationItem.titleView = nil
40
+ end
40
41
  end
41
- end
42
42
 
43
- def set_buttons
44
- set_button :left, bridge.nav_bar_buttons.left
45
- set_button :right, bridge.nav_bar_buttons.right
46
- end
43
+ def set_buttons
44
+ if bridge.nav_bar_buttons
45
+ set_button :left, bridge.nav_bar_buttons.left
46
+ set_button :right, bridge.nav_bar_buttons.right
47
+ else
48
+ PM.logger.debug 'No buttons found'
49
+ end
50
+ end
47
51
 
48
- def set_button(side, button)
49
- return unless button
50
- icon = button.icon ? Icon.new(button.icon, 20) : nil
51
- send "set_nav_bar_#{side}_button", icon, action: "on_nav_bar_#{side}_button_click"
52
- end
52
+ def set_button(side, button)
53
+ return unless button
54
+ return if button.if && !send(button.if)
55
+ label = button.icon ? Icon.new(button.icon, 20) : button.label
56
+ send "set_nav_bar_#{side}_button", label, action: "on_nav_bar_#{side}_button_click"
57
+ end
53
58
 
54
- def on_nav_bar_button_click(side)
55
- button = bridge.nav_bar_buttons.send(side)
56
- if button.options.any?
57
- UIActionSheet.alert nil, buttons: button.options do |pressed, index|
58
- index = remap_index(index, button.options)
59
- bridge.click_child(button.id, index)
59
+ def on_nav_bar_button_click(side)
60
+ button = bridge.nav_bar_buttons.send(side)
61
+ if button.options.any?
62
+ UIActionSheet.alert nil, buttons: button.options do |pressed, index|
63
+ index = remap_index(index, button.options)
64
+ bridge.click_child(button.id, index)
65
+ end
66
+ else
67
+ bridge.click(button.id)
60
68
  end
61
- else
62
- bridge.click(button.id)
63
69
  end
64
- end
65
70
 
66
- # iOS button order and actual order of buttons on screen are not the same
67
- def remap_index(index, options)
68
- if index == options.length - 1
69
- 0
70
- else
71
- index + 1
71
+ # iOS button order and actual order of buttons on screen are not the same
72
+ def remap_index(index, options)
73
+ if index == options.length - 1
74
+ 0
75
+ else
76
+ index + 1
77
+ end
72
78
  end
73
- end
74
-
75
79
 
76
- def on_nav_bar_left_button_click
77
- on_nav_bar_button_click(:left)
78
- end
80
+ def on_nav_bar_left_button_click
81
+ on_nav_bar_button_click(:left)
82
+ end
79
83
 
80
- def on_nav_bar_right_button_click
81
- on_nav_bar_button_click(:right)
82
- end
84
+ def on_nav_bar_right_button_click
85
+ on_nav_bar_button_click(:right)
86
+ end
83
87
 
84
- def set_refresher
85
- if bridge.refreshable && !refresher
86
- self.refresher = UIRefreshControl.alloc.init
87
- refresher.addTarget(self, action: 'reload', forControlEvents: UIControlEventValueChanged)
88
- webview.scrollView.addSubview(refresher)
88
+ def set_refresher
89
+ if bridge.refreshable && !refresher
90
+ self.refresher = UIRefreshControl.alloc.init
91
+ refresher.addTarget(self, action: 'reload', forControlEvents: UIControlEventValueChanged)
92
+ webview.scrollView.addSubview(refresher)
93
+ end
89
94
  end
90
- end
91
95
 
92
- def render_flash
93
- Toast.new(bridge.flash.title, bridge.flash.subtitle) if bridge.flash
94
- end
96
+ def render_flash
97
+ Flash.new(bridge.flash.title, subtitle: bridge.flash.subtitle).show if bridge.flash
98
+ end
95
99
 
96
100
  end
97
101
  end
@@ -34,14 +34,15 @@ module MotionHybrid
34
34
  end
35
35
 
36
36
  def load_started
37
+ @dom_loaded = false
37
38
  start_transitions
38
39
  end
39
40
 
40
41
  def load_finished
41
42
  @url = current_url
42
- load_bridge
43
- reload_dependents if needs_reload?
44
43
  stop_transitions
44
+ load_bridge unless external_page?
45
+ reload_dependents if needs_reload?
45
46
  end
46
47
 
47
48
  def load_failed(error)
@@ -53,12 +54,13 @@ module MotionHybrid
53
54
  end
54
55
 
55
56
  def reset!
57
+ dismissModalViewControllerAnimated(false)
56
58
  return_to_root
57
59
  load_initial_url
58
60
  end
59
61
 
60
62
  def return_to_root
61
- close_nav_screen(animated: false) if nav_bar?
63
+ close to_screen: :root, animated: false if nav_bar?
62
64
  end
63
65
 
64
66
  def on_request(nsurlrequest, type)
@@ -66,6 +68,7 @@ module MotionHybrid
66
68
  end
67
69
 
68
70
  def navigate(new_path)
71
+ new_path = self.class.path_for(new_path)
69
72
  return if path == new_path
70
73
  process_request Request.new(self.class.request_for(new_path), UIWebViewNavigationTypeLinkClicked)
71
74
  end
@@ -79,57 +82,63 @@ module MotionHybrid
79
82
 
80
83
  private
81
84
 
82
- def process_request(request)
83
- @needs_reload = true if request.http_method != 'GET'
84
-
85
- if router.process(request)
86
- false
87
- else
88
- PM.logger.info("#{self} #{request.http_method} #{request.url}")
89
- true
85
+ def external_page?
86
+ !url.include?(self.class.root_url)
90
87
  end
91
- end
92
-
93
- def push(url, options = {})
94
- view_options = options.slice!(:hide_tab_bar)
95
- options[:modal] = view_options[:modal]
96
- view_options.reverse_merge!(url: url, modal: modal?, transition_style: transition_style)
97
- new_view = self.class.new(view_options)
98
- open(new_view, options)
99
- new_view
100
- end
101
88
 
102
- def load_initial_url
103
- self.path = self.class.path_for(@initial_url)
104
- end
89
+ def process_request(request)
90
+ return dom_loaded && false if request.url == 'motionhybrid://ready'
91
+ @needs_reload = true if request.http_method != 'GET'
105
92
 
106
- def transition_style
107
- modal? ? UIModalTransitionStyleFlipHorizontal : nil
108
- end
109
-
110
- def router
111
- @router ||= Router.new(self)
112
- end
93
+ if router.process(request)
94
+ PM.logger.info("#{self} #{request} <intercept>")
95
+ false
96
+ else
97
+ PM.logger.info("#{self} #{request} <load>")
98
+ true
99
+ end
100
+ end
113
101
 
114
- module ClassMethods
115
- def url_for(path)
116
- "#{root_url}#{path}"
102
+ def push(url, options = {})
103
+ screen = options.delete(:screen) || self.class
104
+ view_options = options.slice!(:hide_tab_bar)
105
+ options[:modal] = view_options[:modal]
106
+ view_options.reverse_merge!(url: url, modal: modal?)
107
+ new_view = screen.new(view_options)
108
+ open(new_view, options)
109
+ new_view
117
110
  end
118
111
 
119
- def request_for(path)
120
- NSURLRequest.requestWithURL NSURL.URLWithString(url_for(path))
112
+ def load_initial_url
113
+ self.path = self.class.path_for(@initial_url)
121
114
  end
122
115
 
123
- def path_for(url)
124
- return if url.blank?
125
- NSURL.URLWithString(url).path
116
+ def router
117
+ @router ||= Router.new(self)
126
118
  end
127
119
 
128
- def route(*patterns, &block)
129
- patterns.each do |pattern|
130
- self.routes = [Route.new(pattern, &block)] + routes
120
+ module ClassMethods
121
+ def url_for(path)
122
+ "#{root_url}#{path}"
123
+ end
124
+
125
+ def request_for(path)
126
+ NSURLRequest.requestWithURL NSURL.URLWithString(url_for(path))
127
+ end
128
+
129
+ def path_for(url)
130
+ return if url.blank?
131
+ nsurl = NSURL.URLWithString(url)
132
+ url = url.sub("#{nsurl.scheme}://#{nsurl.host}", '')
133
+ url = url.sub(":#{nsurl.port}", '') if nsurl.port
134
+ url
135
+ end
136
+
137
+ def route(*patterns, &block)
138
+ patterns.each do |pattern|
139
+ self.routes = [Route.new(pattern, &block)] + routes
140
+ end
131
141
  end
132
142
  end
133
- end
134
143
  end
135
144
  end
@@ -7,13 +7,13 @@ module MotionHybrid
7
7
 
8
8
  private
9
9
 
10
- def presenter_url
11
- presenter.url.sub(/\?.+/, '').sub(/#.+/, '')
12
- end
10
+ def presenter_url
11
+ presenter.url.sub(/\?.+/, '').sub(/#.+/, '')
12
+ end
13
13
 
14
- def presenter
15
- navigationController.viewControllers.first.parent_screen if navigationController
16
- end
14
+ def presenter
15
+ navigationController.viewControllers.first.parent_screen if navigationController
16
+ end
17
17
 
18
18
  end
19
19
  end
@@ -1,16 +1,21 @@
1
1
  module MotionHybrid
2
2
  module Releasable
3
3
 
4
- def view_will_disappear(animated)
5
- @should_release = !nav_bar? || !navigationController.viewControllers.include?(self)
4
+ def will_disappear
5
+ @should_release = nav_bar? && !navigationController.viewControllers.include?(self)
6
6
  end
7
7
 
8
- def view_did_disappear(animated)
9
- if @should_release
8
+ def on_disappear
9
+ release_from_memory if @should_release
10
+ end
11
+
12
+ private
13
+
14
+ def release_from_memory
15
+ PM.logger.debug "Releasing #{self}"
10
16
  webview.removeFromSuperview
11
17
  webview.release
12
18
  end
13
- end
14
19
 
15
20
  end
16
21
  end
@@ -1,38 +1,39 @@
1
1
  module MotionHybrid
2
2
  module Updatable
3
3
 
4
- private
4
+ def reload!
5
+ stop
6
+ stop_transitions
7
+ reload
8
+ end
5
9
 
6
10
  def reload_dependents
7
11
  @needs_reload = false
8
- dependents.map(&:stop)
9
- dependents.map(&:reload)
12
+ dependents.map(&:reload!)
10
13
  end
11
14
 
12
- # Inefficient, but will do for now
13
- def dependents
14
- #dependents = all_views - [self]
15
- #dependents = dependents | parent_screens
16
- #dependents
17
- parent_screens
18
- end
15
+ private
19
16
 
20
- def all_views
21
- app_delegate.window.rootViewController.viewControllers.map(&:viewControllers).flatten
22
- end
17
+ def dependents
18
+ parent_screens
19
+ end
23
20
 
24
- def needs_reload?
25
- @needs_reload
26
- end
21
+ def all_views
22
+ app_delegate.window.rootViewController.viewControllers.map(&:viewControllers).flatten
23
+ end
27
24
 
28
- def parent_screens
29
- parent_screens = []
30
- screen = self
31
- while screen = screen.parent_screen
32
- parent_screens << screen
25
+ def needs_reload?
26
+ @needs_reload
27
+ end
28
+
29
+ def parent_screens
30
+ parent_screens = []
31
+ screen = self
32
+ while screen = screen.parent_screen
33
+ parent_screens << screen
34
+ end
35
+ parent_screens
33
36
  end
34
- parent_screens
35
- end
36
37
 
37
38
  end
38
39
  end
@@ -18,21 +18,21 @@ module MotionHybrid
18
18
 
19
19
  private
20
20
 
21
- def bridge_hash
22
- @bridge_hash ||= Dish BW::JSON.parse(bridge_json)
23
- end
21
+ def bridge_hash
22
+ @bridge_hash ||= Dish BW::JSON.parse(bridge_json)
23
+ end
24
24
 
25
- def bridge_json
26
- js_api('getParams()').presence || '{}'
27
- end
25
+ def bridge_json
26
+ js_api('getParams()').presence || '{}'
27
+ end
28
28
 
29
- def method_missing(method)
30
- bridge_hash.send(method)
31
- end
29
+ def method_missing(method)
30
+ bridge_hash.send(method)
31
+ end
32
32
 
33
- def js_api(command)
34
- @screen.evaluate("MotionHybrid.#{command};").to_s
35
- end
33
+ def js_api(command)
34
+ @screen.evaluate("MotionHybrid.#{command};").to_s
35
+ end
36
36
 
37
37
  end
38
38
  end
@@ -25,5 +25,9 @@ module MotionHybrid
25
25
  @type
26
26
  end
27
27
 
28
+ def to_s
29
+ "#{http_method} #{url}"
30
+ end
31
+
28
32
  end
29
33
  end
@@ -7,15 +7,19 @@ module MotionHybrid
7
7
 
8
8
  def process(request)
9
9
  routes.find do |route|
10
- route.matches?(request) && @screen.instance_exec(request, &route.block)
10
+ route.matches?(request) && @screen.instance_exec(request, external?(request), &route.block)
11
11
  end
12
12
  end
13
13
 
14
14
  private
15
15
 
16
- def routes
17
- @screen.class.routes
18
- end
16
+ def external?(request)
17
+ !request.url.include?(@screen.root_url)
18
+ end
19
+
20
+ def routes
21
+ @screen.class.routes
22
+ end
19
23
 
20
24
  end
21
25
  end
@@ -1,3 +1,3 @@
1
1
  module MotionHybrid
2
- VERSION = "0.0.4"
2
+ VERSION = "0.0.5"
3
3
  end
@@ -1,24 +1,73 @@
1
1
  module MotionHybrid
2
+ CRToastManager.setDefaultOptions(
3
+ KCRToastAnimationOutDirectionKey => CRToastAnimationDirectionTop,
4
+ KCRToastTextAlignmentKey => NSTextAlignmentLeft,
5
+ KCRToastSubtitleTextAlignmentKey => NSTextAlignmentLeft,
6
+ KCRToastNotificationTypeKey => CRToastTypeNavigationBar,
7
+ KCRToastSubtitleFontKey => UIFont.systemFontOfSize(14)
8
+ )
9
+
2
10
  class Toast
3
- TEXT_COLOR = '#3c763d'.to_color
4
- BACKGROUND_COLOR = '#dff0d8'.to_color
5
- def initialize(title, subtitle = nil)
6
- options = {
7
- 'kCRToastTextKey' => title,
8
- 'kCRToastFontKey' => UIFont.systemFontOfSize(18),
9
- 'kCRToastTextColorKey' => TEXT_COLOR,
10
- 'kCRToastBackgroundColorKey' => BACKGROUND_COLOR,
11
- 'kCRToastSubtitleFontKey' => UIFont.systemFontOfSize(13),
12
- 'kCRToastSubtitleTextColorKey' => TEXT_COLOR,
13
- 'kCRToastTextAlignmentKey' => NSTextAlignmentLeft,
14
- 'kCRToastSubtitleTextAlignmentKey' => NSTextAlignmentLeft,
15
- 'kCRToastNotificationTypeKey' => CRToastTypeNavigationBar,
16
- 'kCRToastImageKey' => Icon.new(:check, 20, color: TEXT_COLOR)
17
- }
18
-
19
- options.merge!('kCRToastFontKey' => UIFont.boldSystemFontOfSize(17), 'kCRToastSubtitleTextKey' => subtitle, 'kCRToastTimeIntervalKey' => 5) if subtitle.present?
20
-
21
- CRToastManager.showNotificationWithOptions options, completionBlock: nil
11
+ attr_reader :title, :options, :responders
12
+
13
+ def initialize(title, options = {})
14
+ @title, @options = title, options
15
+ @responders = [CRToastInteractionResponder.interactionResponderWithInteractionType(CRToastInteractionTypeSwipeUp, automaticallyDismiss: true, block: nil)]
16
+ end
17
+
18
+ def show(&block)
19
+ responders << CRToastInteractionResponder.interactionResponderWithInteractionType(CRToastInteractionTypeTapOnce, automaticallyDismiss: true, block: -> (i) { block.call }) if block_given?
20
+ CRToastManager.showNotificationWithOptions(kcr_options, completionBlock: nil)
21
+ end
22
+
23
+ def text_color
24
+ '#333'.to_color
25
+ end
26
+
27
+ def background_color
28
+ '#ffffff'.to_color
29
+ end
30
+
31
+ def image
32
+ if options[:image_url]
33
+ image_data = NSData.dataWithContentsOfURL(NSURL.URLWithString(options[:image_url]))
34
+ retinafy UIImage.imageWithData(image_data)
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def retinafy(image)
41
+ UIImage.imageWithCGImage(image.CGImage, scale: 2, orientation: image.imageOrientation)
42
+ end
43
+
44
+ def kcr_options
45
+ {
46
+ KCRToastTextKey => title,
47
+ KCRToastSubtitleTextKey => options[:subtitle].presence,
48
+ KCRToastTextColorKey => text_color,
49
+ KCRToastBackgroundColorKey => background_color,
50
+ KCRToastSubtitleTextColorKey => text_color,
51
+ KCRToastImageKey => image,
52
+ KCRToastFontKey => options[:subtitle].present? ? UIFont.boldSystemFontOfSize(13) : UIFont.systemFontOfSize(18),
53
+ KCRToastTimeIntervalKey => options[:subtitle].present? ? 5 : nil,
54
+ KCRToastInteractionRespondersKey => responders
55
+ }
56
+ end
57
+ end
58
+
59
+ class Flash < Toast
60
+ def text_color
61
+ '#3c763d'.to_color
62
+ end
63
+
64
+ def background_color
65
+ '#dff0d8'.to_color
66
+ end
67
+
68
+ def image
69
+ Icon.new(:check, 20, color: text_color)
22
70
  end
23
71
  end
72
+
24
73
  end
@@ -17,14 +17,17 @@ class window.MotionHybrid
17
17
  { title: flash.find('h3').text() || flash.text().trim(), subtitle: flash.find('p').text() } if flash.length
18
18
 
19
19
  parseButton = (button) ->
20
- { id: button.attr('id'), options: button.children().map(-> this.innerText).get(), icon: button.data('icon') } if button.length
20
+ { id: button.attr('id'), options: button.children().map(-> this.innerText).get(), icon: button.data('icon'), if: button.data('if'), label: button.text().trim() } if button.length
21
21
 
22
22
  @clicked: (target, childIndex) ->
23
23
  target = $("##{target}")
24
- target = target.children() if childIndex
25
- target.get(childIndex || 0).click()
24
+ target = target.children().eq(childIndex) if childIndex
25
+ window.location = target.attr('href') # want to simulate real click but target.get(0).click() sometimes needs to be fired twice to work..?
26
26
 
27
- if document.readyState == 'complete'
28
- document.location.href = 'motionhybrid://ready'
29
- else
30
- jQuery -> document.location.href = 'motionhybrid://ready'
27
+ @waitForJqueryAndDom: ->
28
+ if window.$
29
+ jQuery -> document.location.href = 'motionhybrid://ready'
30
+ else
31
+ setTimeout MotionHybrid.waitForJqueryAndDom, 100
32
+
33
+ MotionHybrid.waitForJqueryAndDom()
@@ -32,11 +32,12 @@
32
32
  if (button.length) {
33
33
  return {
34
34
  id: button.attr('id'),
35
- link: button.attr('href'),
36
35
  options: button.children().map(function() {
37
36
  return this.innerText;
38
37
  }).get(),
39
- icon: button.data('icon')
38
+ icon: button.data('icon'),
39
+ "if": button.data('if'),
40
+ label: button.text().trim()
40
41
  };
41
42
  }
42
43
  };
@@ -44,21 +45,25 @@
44
45
  MotionHybrid.clicked = function(target, childIndex) {
45
46
  target = $("#" + target);
46
47
  if (childIndex) {
47
- target = target.children();
48
+ target = target.children().eq(childIndex);
49
+ }
50
+ return window.location = target.attr('href');
51
+ };
52
+
53
+ MotionHybrid.waitForJqueryAndDom = function() {
54
+ if (window.$) {
55
+ return jQuery(function() {
56
+ return document.location.href = 'motionhybrid://ready';
57
+ });
58
+ } else {
59
+ return setTimeout(MotionHybrid.waitForJqueryAndDom, 100);
48
60
  }
49
- return target.get(childIndex || 0).click();
50
61
  };
51
62
 
52
63
  return MotionHybrid;
53
64
 
54
65
  })();
55
66
 
56
- if (document.readyState === 'complete') {
57
- document.location.href = 'motionhybrid://ready';
58
- } else {
59
- jQuery(function() {
60
- return document.location.href = 'motionhybrid://ready';
61
- });
62
- }
67
+ MotionHybrid.waitForJqueryAndDom();
63
68
 
64
69
  }).call(this);
@@ -13,6 +13,7 @@
13
13
  <body>
14
14
  <div id="motion_hybrid_bridge">
15
15
  <h1>Page 2</h1>
16
+ <h2>Yes it is</h2>
16
17
  <div id="nav_bar_right_button" data-icon='trash-o'>
17
18
  <a href="#">Cancel</a>
18
19
  <a href="#">Delete</a>
@@ -22,6 +23,9 @@
22
23
 
23
24
  <div class="content-padded">
24
25
  This is page 2
26
+ <form action="index.html" method="post" accept-charset="utf-8">
27
+ <input type="submit" name="Post" />
28
+ </form>
25
29
  </div>
26
30
  </body>
27
31
  </html>
@@ -0,0 +1,30 @@
1
+ module MotionHybrid
2
+ describe Navigatable do
3
+ describe '.path_for' do
4
+ it "should parse path correctly for localhost" do
5
+ MotionHybrid::Screen.path_for('http://localhost:3000/chats').should == '/chats'
6
+ end
7
+ end
8
+
9
+ describe '.route' do
10
+ class MyScreen < Screen
11
+ attr_accessor :external
12
+ route /.*/ do |request, external|
13
+ self.external = external
14
+ end
15
+ end
16
+
17
+ it "determines whether request is external or not" do
18
+ MyScreen.root_url = 'http://mysite.com'
19
+ screen = MyScreen.new
20
+ internal_request = NSURLRequest.requestWithURL NSURL.URLWithString('http://mysite.com/users/')
21
+ external_request = NSURLRequest.requestWithURL NSURL.URLWithString('http://theirsite.com/users/')
22
+
23
+ screen.on_request(internal_request, UIWebViewNavigationTypeLinkClicked)
24
+ screen.external.should == false
25
+ screen.on_request(external_request, UIWebViewNavigationTypeLinkClicked)
26
+ screen.external.should == true
27
+ end
28
+ end
29
+ end
30
+ end
@@ -1,5 +1,5 @@
1
1
  PODS:
2
- - CRToast (0.0.5)
2
+ - CRToast (0.0.7)
3
3
  - FontAwesomeKit (2.1.5):
4
4
  - FontAwesomeKit/Core
5
5
  - FontAwesomeKit/FontAwesome
@@ -19,15 +19,19 @@ PODS:
19
19
  - SpinKit (1.0.1)
20
20
 
21
21
  DEPENDENCIES:
22
- - CRToast (< 0.0.6)
22
+ - CRToast (from `git@github.com:cruffenach/CRToast.git`)
23
23
  - FontAwesomeKit
24
24
  - MBProgressHUD
25
25
  - SpinKit
26
26
 
27
+ EXTERNAL SOURCES:
28
+ CRToast:
29
+ :git: git@github.com:cruffenach/CRToast.git
30
+
27
31
  SPEC CHECKSUMS:
28
- CRToast: 5be332fb9f4bcfd3023b6f10324ed9738c35cb96
29
- FontAwesomeKit: 7d935e100337d503bdaefde2ea16be740b81ed13
30
- MBProgressHUD: 2bbc6f470111daf7f3eaa4eb12b8cbf01c4c0622
31
- SpinKit: c7490233be81d8daf41da05dc463351423658aad
32
+ CRToast: da11d94a05b1351a87bb26cbf8f25e80ed2e7115
33
+ FontAwesomeKit: 2e37bec52edbb8f8044a487734ba63eb320a2665
34
+ MBProgressHUD: c356980b0cd097f19acec959b49dca5eb8ec31be
35
+ SpinKit: 563a00196a87d789b16e3592265f0dfa9c3fb9db
32
36
 
33
- COCOAPODS: 0.29.0
37
+ COCOAPODS: 0.33.1
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: motion-hybrid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jens Balvig
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-07-01 00:00:00.000000000 Z
11
+ date: 2014-08-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bubble-wrap
@@ -212,7 +212,8 @@ files:
212
212
  - resources/web/ratchet-theme-ios.css
213
213
  - resources/web/ratchet.css
214
214
  - resources/web/refreshable.html
215
- - spec/basic_routes_spec.rb
215
+ - spec/functional/basic_routes_spec.rb
216
+ - spec/unit/navigatable_spec.rb
216
217
  - vendor/Podfile.lock
217
218
  homepage: https://github.com/balvig/motion-hybrid
218
219
  licenses:
@@ -239,4 +240,5 @@ signing_key:
239
240
  specification_version: 4
240
241
  summary: RubyMotion framework for easily making hybrid webview-centric iOS apps
241
242
  test_files:
242
- - spec/basic_routes_spec.rb
243
+ - spec/functional/basic_routes_spec.rb
244
+ - spec/unit/navigatable_spec.rb