ProMotion 2.8.2 → 3.0.0

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
  SHA256:
3
- metadata.gz: ff88ba12cf5f2a7fed1cf73a74215e9c0e58423df7e906d8ae14e3f65cf10033
4
- data.tar.gz: 1d555e3974f3e502acaaa2a36ac54fab97e9b3c432ef6bedafec7d2fb1be66f1
3
+ metadata.gz: e8ab6f66bcfc437f402e9c8271b367626306a4d1a1cbe2e5cf7994abcf7570e4
4
+ data.tar.gz: 48619b0b60edff79951538f03a28a895c48a0b489c61d904f1f082c1d02faa6f
5
5
  SHA512:
6
- metadata.gz: 7367fe943641a5ec31e131bcb08eac656738cdcda01ee5122419822963a652864807e41f47fd93c2b5fa02d428a846632df75dd3178e1527cb982c58f084838f
7
- data.tar.gz: 247b1bee69acec4810af44199f90e2b8130ce2786cd18a7eb5ff969a4e5ba722ebd57b7b38be025f4a2de88d98908e6e1be39697bc9e6910347ae702f506be07
6
+ metadata.gz: 7dfe0a34fe391efdf62bc11873c2c6bb45bfb0697eb91716df58bb60aaec40d18480adba66eedb585ed68c4f85b8214f404eca85828237c5ddac014b076603c2
7
+ data.tar.gz: 84291ed23351a205df87ef74a39e71adb2d1c885902358ec132e3395cfb436b22bc32ed14f30bffceeab09bba1f2831f5a454ab1d7626ba16d1574c2a67f2802
data/README.md CHANGED
@@ -2,7 +2,6 @@
2
2
 
3
3
  [![Gem Version](https://img.shields.io/gem/v/ProMotion.svg?style=flat)](https://rubygems.org/gems/ProMotion)
4
4
  [![Build Status](https://img.shields.io/travis/infinitered/ProMotion.svg?style=flat)](https://travis-ci.org/infinitered/ProMotion)
5
- [![Code Climate](https://img.shields.io/codeclimate/github/infinitered/ProMotion.svg?style=flat)](https://codeclimate.com/github/infinitered/ProMotion)
6
5
 
7
6
  ProMotion was created by [Infinite Red](http://infinite.red), a web and mobile development company based in Portland, OR and San Francisco, CA. While you're welcome to use ProMotion, please note that we rely on the community to maintain it. We are happy to merge pull requests and release new versions but are no longer driving primary development.
8
7
 
@@ -76,8 +75,6 @@ end
76
75
  |---|---|---|
77
76
  |[![ProMotion SplitScreens](https://f.cloud.github.com/assets/1479215/1534507/0edb8dd4-4c96-11e3-9896-d4583d0ed161.png)](http://promotion.readthedocs.org/en/master/Reference/ProMotion%20SplitScreen/)|[![MapScreen](https://f.cloud.github.com/assets/1479215/1534628/f7dbf7e8-4c97-11e3-8817-4c2a58824771.png)](http://promotion.readthedocs.org/en/master/Reference/ProMotion%20MapScreen/)|[![ProMotion WebScreen](https://f.cloud.github.com/assets/1479215/1534631/ffe1b36a-4c97-11e3-8c8f-c7b14e26182d.png)](http://promotion.readthedocs.org/en/master/Reference/ProMotion%20WebScreen/)|
78
77
 
79
- **NEW** [Live reloading!](http://promotion.readthedocs.org/en/master/Guides/Live Screen Reloading/) Use `pm_live` to enable it, and `on_live_reload` in your screen to refresh things.
80
-
81
78
  #### ...and much more.
82
79
 
83
80
  ## Getting Started
@@ -12,63 +12,4 @@ Motion::Project::App.setup do |app|
12
12
  app.files.insert(insert_point, file)
13
13
  end
14
14
 
15
- app.development do
16
- app.info_plist["ProjectRootPath"] ||= File.absolute_path(app.project_dir)
17
- end
18
-
19
- # For compatibility with libraries that don't use detect_dependencies. :-(
20
- app.files_dependencies({
21
- "#{core_lib}/version.rb" => [ "#{core_lib}/pro_motion.rb" ],
22
- "#{core_lib}/cocoatouch/table_view_cell.rb" => [ "#{core_lib}/table/cell/table_view_cell_module.rb" ],
23
- "#{core_lib}/table/cell/table_view_cell_module.rb" => [ "#{core_lib}/styling/styling.rb" ],
24
- "#{core_lib}/cocoatouch/collection_view_cell.rb" => [ "#{core_lib}/collection/cell/collection_view_cell_module.rb" ],
25
- "#{core_lib}/collection/collection_screen.rb" => [
26
- "#{core_lib}/cocoatouch/collection_view_controller.rb",
27
- "#{core_lib}/screen/screen_module.rb",
28
- "#{core_lib}/collection/collection_builder.rb",
29
- "#{core_lib}/collection/collection.rb",
30
- "#{core_lib}/collection/cell/collection_view_cell_module.rb",
31
- ],
32
- "#{core_lib}/collection/cell/collection_view_cell_module.rb" => [ "#{core_lib}/styling/styling.rb" ],
33
- "#{core_lib}/delegate/delegate.rb" => [ "#{core_lib}/delegate/delegate_parent.rb" ],
34
- "#{core_lib}/delegate/delegate_parent.rb" => [ "#{core_lib}/delegate/delegate_module.rb" ],
35
- "#{core_lib}/delegate/delegate_module.rb" => [
36
- "#{core_lib}/support/support.rb",
37
- "#{core_lib}/tabs/tabs.rb",
38
- "#{core_lib}/ipad/split_screen.rb"
39
- ],
40
- "#{core_lib}/screen/screen.rb" => [ "#{core_lib}/screen/screen_module.rb" ],
41
- "#{core_lib}/screen/screen_navigation.rb" => [ "#{core_lib}/support/support.rb", ],
42
- "#{core_lib}/screen/screen_module.rb" => [
43
- "#{core_lib}/styling/styling.rb",
44
- "#{core_lib}/tabs/tabs.rb",
45
- "#{core_lib}/screen/nav_bar_module.rb",
46
- "#{core_lib}/screen/screen_navigation.rb",
47
- "#{core_lib}/ipad/split_screen.rb",
48
- ],
49
- "#{core_lib}/table/data/table_data.rb" => [
50
- "#{core_lib}/table/data/table_data_builder.rb",
51
- "#{core_lib}/table/table.rb"
52
- ],
53
- "#{core_lib}/collection/data/collection_data.rb" => [
54
- "#{core_lib}/collection/data/collection_data_builder.rb",
55
- "#{core_lib}/collection/collection.rb",
56
- "#{core_lib}/table/table_utils.rb"
57
- ],
58
- "#{core_lib}/table/table.rb" => [
59
- "#{core_lib}/table/table_class_methods.rb",
60
- "#{core_lib}/table/table_builder.rb",
61
- "#{core_lib}/table/table_utils.rb",
62
- "#{core_lib}/table/extensions/searchable.rb",
63
- "#{core_lib}/table/extensions/refreshable.rb",
64
- "#{core_lib}/table/extensions/indexable.rb",
65
- "#{core_lib}/table/extensions/longpressable.rb"
66
- ],
67
- "#{core_lib}/collection/collection.rb" => [
68
- "#{core_lib}/collection/collection_class_methods.rb",
69
- "#{core_lib}/collection/collection_builder.rb",
70
- "#{core_lib}/table/table_utils.rb"
71
- ],
72
- "#{core_lib}/web/web_screen.rb" => [ "#{core_lib}/web/web_screen_module.rb" ],
73
- })
74
15
  end
@@ -81,11 +81,6 @@ module ProMotion
81
81
  mp "Received memory warning in #{self.inspect}. You should implement on_memory_warning in your screen.", force_color: :red
82
82
  end
83
83
 
84
- def on_live_reload
85
- self.view.subviews.each(&:removeFromSuperview)
86
- on_load
87
- end
88
-
89
84
  def should_rotate(orientation)
90
85
  case orientation
91
86
  when UIInterfaceOrientationPortrait
@@ -23,10 +23,6 @@ module ProMotion
23
23
  set_up_row_height
24
24
  end
25
25
 
26
- def on_live_reload
27
- update_table_data
28
- end
29
-
30
26
  def check_table_data
31
27
  mp("Missing #table_data method in TableScreen #{self.class.to_s}.", force_color: :red) unless self.respond_to?(:table_data)
32
28
  end
@@ -125,7 +121,8 @@ module ProMotion
125
121
 
126
122
  def delete_row(index_paths, animation = nil)
127
123
  deletable_index_paths = []
128
- Array(index_paths).each do |index_path|
124
+ index_paths = [index_paths] if index_paths.kind_of?(NSIndexPath)
125
+ index_paths.each do |index_path|
129
126
  delete_cell = false
130
127
 
131
128
  delete_cell = trigger_action(:on_cell_deleted, cell_at(index_path: index_path), index_path) if respond_to?(:on_cell_deleted)
@@ -1,3 +1,3 @@
1
1
  module ProMotion
2
- VERSION = "2.8.2" unless defined?(ProMotion::VERSION)
2
+ VERSION = "3.0.0" unless defined?(ProMotion::VERSION)
3
3
  end
@@ -0,0 +1,78 @@
1
+ module ProMotion
2
+ module UIWebScreenModule
3
+ def web_view_setup
4
+ self.webview = add UIWebView.new, {
5
+ frame: CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height),
6
+ delegate: self,
7
+ data_detector_types: data_detector_types
8
+ }
9
+
10
+ self.webview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight
11
+ self.webview.scalesPageToFit = self.scale_to_fit
12
+ self.webview.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal
13
+ end
14
+
15
+ def evaluate(js)
16
+ self.webview.stringByEvaluatingJavaScriptFromString(js)
17
+ end
18
+
19
+ def evaluate_async(js, &block)
20
+ Dispatch::Queue.concurrent.async do
21
+ result = evaluate(js)
22
+ Dispatch::Queue.main.async do
23
+ block.call result
24
+ end
25
+ end
26
+ end
27
+
28
+ def go_to_item(item)
29
+ # self.webview.goToBackForwardListItem(item)
30
+ PM.logger.warn "`go_to_item` is not implemented with the older UIWebView, which doesn't support it."
31
+ false
32
+ end
33
+
34
+ def back_forward_list
35
+ # self.webview.backForwardList
36
+ PM.logger.warn "`back_forward_list` is not implemented with the older UIWebView, which doesn't support it."
37
+ false
38
+ end
39
+
40
+ def progress
41
+ # self.webview.estimatedProgress
42
+ PM.logger.warn "`progress` is not implemented with the older UIWebView, which doesn't support it."
43
+ false
44
+ end
45
+
46
+ # CocoaTouch methods
47
+
48
+ def webView(in_web, shouldStartLoadWithRequest:in_request, navigationType:in_type)
49
+ if %w(http https).include?(in_request.URL.scheme)
50
+ if self.external_links == true && in_type == UIWebViewNavigationTypeLinkClicked
51
+ if defined?(OpenInChromeController)
52
+ open_in_chrome in_request
53
+ else
54
+ open_in_safari in_request
55
+ end
56
+ return false # don't allow the web view to load the link.
57
+ end
58
+ end
59
+
60
+ load_request_enable = true #return true on default for local file loading.
61
+ load_request_enable = !!on_request(in_request, in_type) if self.respond_to?(:on_request)
62
+ load_request_enable
63
+ end
64
+
65
+ def webViewDidStartLoad(webView)
66
+ load_started if self.respond_to?(:load_started)
67
+ end
68
+
69
+ def webViewDidFinishLoad(webView)
70
+ load_finished if self.respond_to?(:load_finished)
71
+ end
72
+
73
+ def webView(webView, didFailLoadWithError:error)
74
+ load_failed(error) if self.respond_to?("load_failed:")
75
+ end
76
+
77
+ end
78
+ end
@@ -1,5 +1,7 @@
1
1
  module ProMotion
2
2
  module WebScreenModule
3
+ include WKWebScreenModule if defined?(WKWebView)
4
+ include UIWebScreenModule unless defined?(WKWebView)
3
5
 
4
6
  attr_accessor :webview, :external_links, :detector_types, :scale_to_fit
5
7
 
@@ -17,17 +19,6 @@ module ProMotion
17
19
  # TODO: Remove in 3.0
18
20
  end
19
21
 
20
- def web_view_setup
21
- self.webview ||= add UIWebView.new, {
22
- frame: CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height),
23
- delegate: self,
24
- data_detector_types: data_detector_types
25
- }
26
- self.webview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight
27
- self.webview.scalesPageToFit = self.scale_to_fit
28
- self.webview.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal
29
- end
30
-
31
22
  def web
32
23
  self.webview
33
24
  end
@@ -49,7 +40,6 @@ module ProMotion
49
40
  if File.exists? content_path
50
41
  content_string = File.read content_path
51
42
  content_base_url = NSURL.fileURLWithPath NSBundle.mainBundle.resourcePath
52
-
53
43
  self.web.loadHTMLString(convert_retina_images(content_string), baseURL:content_base_url)
54
44
  else
55
45
  # We assume the user wants to load an arbitrary string into the web view
@@ -58,10 +48,7 @@ module ProMotion
58
48
  end
59
49
 
60
50
  def open_url(url)
61
- request = NSURLRequest.requestWithURL(
62
- url.is_a?(NSURL) ? url : NSURL.URLWithString(url)
63
- )
64
- web.loadRequest request
51
+ web.loadRequest NSURLRequest.requestWithURL(url.to_url)
65
52
  end
66
53
 
67
54
  def convert_retina_images(content)
@@ -85,16 +72,12 @@ module ProMotion
85
72
  mp("Missing #content method in WebScreen #{self.class.to_s}.", force_color: :red) unless self.respond_to?(:content)
86
73
  end
87
74
 
88
- def html
89
- evaluate("document.documentElement.outerHTML")
90
- end
91
-
92
- def evaluate(js)
93
- self.webview.stringByEvaluatingJavaScriptFromString(js)
75
+ def html(&block)
76
+ evaluate('document.documentElement.outerHTML', &block)
94
77
  end
95
78
 
96
- def current_url
97
- evaluate('document.URL')
79
+ def current_url(&block)
80
+ evaluate('document.URL', &block)
98
81
  end
99
82
 
100
83
  # Navigation
@@ -119,36 +102,6 @@ module ProMotion
119
102
  UIApplication.sharedApplication.openURL(in_request.URL)
120
103
  end
121
104
 
122
- # UIWebViewDelegate Methods - Camelcase
123
- def webView(in_web, shouldStartLoadWithRequest:in_request, navigationType:in_type)
124
- if %w(http https).include?(in_request.URL.scheme)
125
- if self.external_links == true && in_type == UIWebViewNavigationTypeLinkClicked
126
- if defined?(OpenInChromeController)
127
- open_in_chrome in_request
128
- else
129
- open_in_safari in_request
130
- end
131
- return false # don't allow the web view to load the link.
132
- end
133
- end
134
-
135
- load_request_enable = true #return true on default for local file loading.
136
- load_request_enable = !!on_request(in_request, in_type) if self.respond_to?(:on_request)
137
- load_request_enable
138
- end
139
-
140
- def webViewDidStartLoad(webView)
141
- load_started if self.respond_to?(:load_started)
142
- end
143
-
144
- def webViewDidFinishLoad(webView)
145
- load_finished if self.respond_to?(:load_finished)
146
- end
147
-
148
- def webView(webView, didFailLoadWithError:error)
149
- load_failed(error) if self.respond_to?("load_failed:")
150
- end
151
-
152
105
  protected
153
106
 
154
107
  def data_detector_types
@@ -166,6 +119,5 @@ module ProMotion
166
119
  all: UIDataDetectorTypeAll
167
120
  }[symbol] || UIDataDetectorTypeNone
168
121
  end
169
-
170
122
  end
171
123
  end
@@ -0,0 +1,87 @@
1
+ module ProMotion
2
+ module WKWebScreenModule
3
+ def web_view_setup
4
+ configuration = WKWebViewConfiguration.alloc.init
5
+ configuration.dataDetectorTypes = data_detector_types
6
+ frame = CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)
7
+ # FIXME: get this working: wkwebview = WKWebView.alloc.initWithFrame(frame, configuration: configuration)
8
+ wkwebview = WKWebView.alloc.initWithFrame(frame)
9
+ self.webview = add(wkwebview)
10
+ self.webview.UIDelegate = self
11
+ self.webview.navigationDelegate = self
12
+ self.webview.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight
13
+ self.webview.scrollView.decelerationRate = UIScrollViewDecelerationRateNormal
14
+ end
15
+
16
+ def evaluate(js, &block)
17
+ if block
18
+ evaluate_async(js) do |result, error|
19
+ block.call(result) # ignore error
20
+ end
21
+ return
22
+ end
23
+ res = nil
24
+ semaphore = Dispatch::Semaphore.new(0)
25
+ # FIXME: this blocks and never returns
26
+ evaluate_async(js) do |result, error|
27
+ res = result
28
+ semaphore.signal
29
+ end
30
+ semaphore.wait(Dispatch::TIME_FOREVER)
31
+ return res
32
+ end
33
+
34
+ def evaluate_async(js, &block)
35
+ self.webview.evaluateJavaScript(js, completionHandler: -> (result, error) {
36
+ block.call(result, error)
37
+ })
38
+ end
39
+
40
+ def go_to_item(item)
41
+ self.webview.goToBackForwardListItem(item)
42
+ end
43
+
44
+ def back_forward_list
45
+ self.webview.backForwardList
46
+ end
47
+
48
+ def progress
49
+ self.webview.estimatedProgress
50
+ end
51
+
52
+ # CocoaTouch methods
53
+
54
+ def webView(view, decidePolicyForNavigationAction: navigationAction, decisionHandler: decisionHandler)
55
+ request = navigationAction.request
56
+ nav_type = navigationAction.navigationType
57
+
58
+ if %w(http https).include?(request.URL.scheme)
59
+ if self.external_links == true && nav_type == WKNavigationTypeLinkActivated
60
+ if defined?(OpenInChromeController)
61
+ open_in_chrome(request)
62
+ else
63
+ open_in_safari(request)
64
+ end
65
+ decisionHandler.call(WKNavigationActionPolicyCancel) # don't allow the web view to load the link
66
+ return
67
+ end
68
+ end
69
+
70
+ load_request_enable = true # return true by default for local file loading
71
+ load_request_enable = !!on_request(request, nav_type) if self.respond_to?(:on_request)
72
+ decisionHandler.call(load_request_enable ? WKNavigationActionPolicyAllow : WKNavigationActionPolicyCancel)
73
+ end
74
+
75
+ def webView(view, didCommitNavigation: navigation)
76
+ navigation_started(navigation) if self.respond_to?("navigation_started")
77
+ end
78
+
79
+ def webView(view, didFailNavigation: navigation, withError: error)
80
+ navigation_failed(navigation, error) if self.respond_to?("navigation_failed")
81
+ end
82
+
83
+ def webView(view, didFinishNavigation: navigation)
84
+ navigation_finished(navigation) if self.respond_to?("navigation_finished")
85
+ end
86
+ end
87
+ end
@@ -64,6 +64,7 @@ describe "ProMotion::TableScreen functionality" do
64
64
  table_screen.tableView.scrollToRowAtIndexPath(ip, atScrollPosition: UITableViewScrollPositionTop, animated: false)
65
65
 
66
66
  cell = views(TestCell).first
67
+ cell.prepare_for_reuse_time.should.not.be.nil
67
68
  cell.prepare_for_reuse_time.should < cell.on_reuse_time
68
69
  end
69
70
  end
@@ -1,11 +1,12 @@
1
1
  describe "ProMotion::TestWebScreen functionality" do
2
- extend WebStub::SpecHelpers
2
+ # NOTE: webstub doesn't support stubbing WKWebView requests
3
+ # extend WebStub::SpecHelpers
3
4
 
4
5
  before do
5
- disable_network_access!
6
+ # disable_network_access!
6
7
  UIView.setAnimationDuration 0.01
7
8
  end
8
- after { enable_network_access! }
9
+ # after { enable_network_access! }
9
10
 
10
11
  def controller
11
12
  @controller ||= TestWebScreen.new(nav_bar: true)
@@ -18,32 +19,41 @@ describe "ProMotion::TestWebScreen functionality" do
18
19
  it "should have the proper html content" do
19
20
  file_name = "WebScreen.html"
20
21
 
21
- controller.mock!(:load_finished) do
22
+ controller.mock!(:navigation_finished) do |nav|
22
23
  loaded_file = File.read(File.join(NSBundle.mainBundle.resourcePath, file_name))
23
- controller.html.delete("\n").should == loaded_file.delete("\n")
24
- resume
24
+ controller.html do |html|
25
+ html.should.not.be.nil
26
+ html.delete("\n").should == loaded_file.delete("\n")
27
+ resume
28
+ end
25
29
  end
26
30
  controller.set_content(file_name)
27
31
  wait_max 8 {}
28
32
  end
29
33
 
30
34
  it "should allow you to navigate to a website" do
31
- stub_request(:get, "https://www.google.com/").
32
- to_return(body: %q{Google! <form action="/search">%}, content_type: "text/html")
33
-
34
- controller.mock!(:load_finished) do
35
- controller.html.should.include('<form action="/search"')
36
- resume
35
+ # NOTE: webstub can't stub WKWebView requests
36
+ # stub_request(:get, "https://www.google.com/").
37
+ # to_return(body: %q{Google! <form action="/search">%}, content_type: "text/html")
38
+
39
+ controller.mock!(:navigation_finished) do |nav|
40
+ controller.html do |html|
41
+ html.should.include('<form action="/search"')
42
+ resume
43
+ end
37
44
  end
38
- controller.open_url(NSURL.URLWithString("https://www.google.com/"))
45
+ controller.open_url('https://www.google.com/') # LIVE request!
39
46
  wait_max 8 {}
40
47
  end
41
48
 
42
49
  it "should manipulate the webscreen contents with javascript" do
43
- controller.mock!(:load_finished) do
44
- controller.evaluate('document.getElementById("cool").innerHTML = "Changed"')
45
- controller.html.should =~ /<h1 id="cool">Changed<\/h1>/
46
- resume
50
+ controller.mock!(:navigation_finished) do |nav|
51
+ controller.evaluate_async('document.getElementById("cool").innerHTML = "Changed"') do |result, error|
52
+ controller.html do |html|
53
+ html.should =~ /<h1 id="cool">Changed<\/h1>/
54
+ resume
55
+ end
56
+ end
47
57
  end
48
58
  controller.set_content('<h1 id="cool">Something Cool</h1>')
49
59
  wait_max 8 {}
@@ -79,11 +79,11 @@ describe "PM::TableViewCellModule" do
79
79
  end
80
80
 
81
81
  it "should allow attributed title" do
82
- @attributed_subject.textLabel.attributedText.mutableString.should == "Attributed Title"
82
+ @attributed_subject.textLabel.attributedText.string.should == "Attributed Title"
83
83
  end
84
84
 
85
85
  it "should allow attributed subtitle" do
86
- @attributed_subject.detailTextLabel.attributedText.mutableString.should == "Attributed Subtitle"
86
+ @attributed_subject.detailTextLabel.attributedText.string.should == "Attributed Subtitle"
87
87
  end
88
88
 
89
89
  it "should have the right subtitle" do
@@ -1,63 +1,85 @@
1
1
  describe "web screen properties" do
2
- extend WebStub::SpecHelpers
3
-
4
- before { disable_network_access! }
5
- after { enable_network_access! }
2
+ # NOTE: webstub doesn't work with WKWebView
3
+ # extend WebStub::SpecHelpers
4
+ # before { disable_network_access! }
5
+ # after { enable_network_access! }
6
6
 
7
7
  it "should leave on_init available as a hook" do
8
- webscreen = TestWebScreen.new()
8
+ webscreen = TestWebScreen.new
9
9
  webscreen.on_init_available?.should == true
10
10
  end
11
11
 
12
- describe "when open web page with http request" do
12
+ it "can perform asynchronous javascript execution" do
13
+ webscreen = TestWebScreen.new
14
+ js = 'document.documentElement.innerHTML = "test"; document.documentElement.outerHTML'
15
+ webscreen.evaluate_async(js) do |result, error|
16
+ result.should == '<html><head></head><body>test</body></html>'
17
+ resume
18
+ end
19
+ wait_max 2 {}
20
+ end
21
+
22
+ it "can perform synchronous javascript execution" do
23
+ webscreen = TestWebScreen.new
24
+ js = 'document.documentElement.innerHTML = "test"; document.documentElement.outerHTML'
25
+ wait_max(2) do
26
+ result = webscreen.evaluate(js)
27
+ result.should == '<html><head></head><body>test</body></html>'
28
+ end
29
+ end
30
+
31
+ describe "opening a web page using an http request" do
13
32
  before do
14
33
  class TestWebScreenWithHTTPRequest < TestWebScreen
15
- attr_accessor :on_request, :on_request_args
34
+ attr_accessor :on_request_called, :on_request_args
35
+ # NOTE: this hook is for deciding whether or not the request should continue
16
36
  def on_request(request, type)
17
37
  self.on_request_args = [request, type]
18
- self.on_request = true
38
+ self.on_request_called = true
39
+ false # cancel request since we can't stub it
19
40
  end
20
41
  end
21
- stub_request(:get, "http://mixi.jp/").
22
- to_return(body: "<html><body>[mixi]</body></html>", content_type: "text/html")
42
+
43
+ # NOTE: webstub doesn't support stubbing WKWebView requests
44
+ #stub_request(:get, "https://mixi.jp/").
45
+ # to_return(body: "<html><body>[mixi]</body></html>", content_type: "text/html")
46
+
23
47
  # Simulate AppDelegate setup of web screen
24
48
  @webscreen = TestWebScreenWithHTTPRequest.new modal: true, nav_bar: true, external_links: false
25
49
  end
50
+
51
+ it "should call on_request hook" do
52
+ @webscreen.open_url('https://mixi.jp/')
26
53
 
27
- it "should get the current url" do
28
- @webscreen.open_url(NSURL.URLWithString('http://mixi.jp/'))
29
-
30
- wait_for_change @webscreen, 'is_load_finished' do
31
- @webscreen.current_url.should == 'http://mixi.jp/'
54
+ wait_for_change @webscreen, 'on_request_called' do
55
+ @webscreen.on_request_called.should == true
32
56
  end
33
57
  end
34
58
 
35
59
  it "should open web page via NSMutableURLRequest" do
36
- nsurl = NSURL.URLWithString('http://mixi.jp/')
60
+ nsurl = NSURL.URLWithString('https://mixi.jp/')
37
61
  @webscreen.web.loadRequest NSMutableURLRequest.requestWithURL(nsurl)
38
62
 
39
- wait_for_change @webscreen, 'is_load_finished' do
40
- @webscreen.current_url.should == 'http://mixi.jp/'
63
+ wait_for_change @webscreen, 'on_request_called' do
64
+ request = @webscreen.on_request_args.first
65
+ request.should.be.a.kind_of NSURLRequest
66
+ request.URL.absoluteString.should == 'https://mixi.jp/'
41
67
  end
42
68
  end
43
69
 
44
70
  it "should open web page by url string" do
45
- @webscreen.open_url('http://mixi.jp/')
46
- wait_for_change @webscreen, 'is_load_finished' do
47
- @webscreen.html.should =~ /mixi/
48
- end
49
- end
50
-
51
- it "should call on_request hook" do
52
- @webscreen.open_url(NSURL.URLWithString('http://mixi.jp/'))
71
+ @webscreen.open_url('https://mixi.jp/')
53
72
 
54
- wait_for_change @webscreen, 'on_request' do
55
- @webscreen.on_request_args[0].is_a?(NSURLRequest).should == true
56
- # on_request is called when @webscreen request for some iframe
57
- @webscreen.on_request_args[0].URL.absoluteString.should =~ %r|https?://.*|
73
+ wait_for_change @webscreen, 'on_request_called' do
74
+ request = @webscreen.on_request_args.first
75
+ request.should.be.a.kind_of NSURLRequest
76
+ request.URL.absoluteString.should == 'https://mixi.jp/'
58
77
  end
59
78
  end
60
79
 
80
+ # TODO: these features used to be supported prior to WKWebView migration
81
+ # it "can synchronously return the current page html"
82
+ # it "can synchronously return the current page url"
61
83
  end
62
84
 
63
85
  describe "when loading a static html file" do
@@ -68,16 +90,20 @@ describe "web screen properties" do
68
90
  end
69
91
 
70
92
  it "should get the url of content" do
71
- @webscreen.current_url.should == 'about:blank'
93
+ @webscreen.current_url do |url|
94
+ url.should == 'about:blank'
95
+ resume
96
+ end
97
+ wait_max 1 {}
72
98
  end
73
99
 
74
- it "should have a UIWebView as the primary view" do
75
- @webscreen.web.class.should == UIWebView
100
+ it "should have a WKWebView as the primary view" do
101
+ @webscreen.web.class.should == WKWebView
76
102
  end
77
103
 
78
104
  it "should load the about html page" do
79
- wait_for_change @webscreen, 'is_load_finished' do
80
- @webscreen.is_load_finished.should == true
105
+ wait_for_change @webscreen, 'is_nav_finished', 3 do
106
+ @webscreen.is_nav_finished.should == true
81
107
  end
82
108
  end
83
109
  end
@@ -85,29 +111,25 @@ describe "web screen properties" do
85
111
  describe "when setting attributes" do
86
112
  it "should have a default values" do
87
113
  webscreen = TestWebScreen.new()
88
- webscreen.web.dataDetectorTypes.should == UIDataDetectorTypeNone
89
- webscreen.web.scalesPageToFit.should == false
114
+ webscreen.web.configuration.dataDetectorTypes.should == UIDataDetectorTypeNone
90
115
  webscreen.external_links.should == false
91
116
  end
92
117
 
93
- it "should set a single data detector" do
94
- webscreen = TestWebScreen.new(detector_types: :phone)
95
- webscreen.web.dataDetectorTypes.should == UIDataDetectorTypePhoneNumber
96
- end
118
+ # FIXME: these should work after getting initWithFrame:configuration: to work.
119
+ # it "should set a single data detector" do
120
+ # webscreen = TestWebScreen.new(detector_types: :phone)
121
+ # webscreen.web.configuration.dataDetectorTypes.should == UIDataDetectorTypePhoneNumber
122
+ # end
97
123
 
98
- it "should set multiple data detectors" do
99
- webscreen = TestWebScreen.new(detector_types: [:phone, :link])
100
- webscreen.web.dataDetectorTypes.should == UIDataDetectorTypePhoneNumber | UIDataDetectorTypeLink
101
- end
102
-
103
- it "should set the scaling mode of the screen" do
104
- webscreen = TestWebScreen.new(scale_to_fit: true)
105
- webscreen.web.scalesPageToFit.should == true
106
- end
124
+ # it "should set multiple data detectors" do
125
+ # webscreen = TestWebScreen.new(detector_types: [:phone, :link])
126
+ # webscreen.web.configuration.dataDetectorTypes.should == UIDataDetectorTypePhoneNumber | UIDataDetectorTypeLink
127
+ # end
107
128
 
108
129
  it "should have the ability to open links externally" do
109
130
  webscreen = TestWebScreen.new(external_links: true)
110
131
  webscreen.external_links.should == true
132
+ # TODO: test that link click opens Safari
111
133
  end
112
134
  end
113
135
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ProMotion
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.8.2
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jamon Holmgren
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2018-10-25 00:00:00.000000000 Z
13
+ date: 2020-03-05 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: methadone
@@ -132,8 +132,6 @@ files:
132
132
  - lib/ProMotion/ipad/split_screen.rb
133
133
  - lib/ProMotion/logger/logger.rb
134
134
  - lib/ProMotion/pro_motion.rb
135
- - lib/ProMotion/repl/live_reloader.rb
136
- - lib/ProMotion/repl/repl.rb
137
135
  - lib/ProMotion/screen/nav_bar_module.rb
138
136
  - lib/ProMotion/screen/screen.rb
139
137
  - lib/ProMotion/screen/screen_module.rb
@@ -159,8 +157,10 @@ files:
159
157
  - lib/ProMotion/table/table_utils.rb
160
158
  - lib/ProMotion/tabs/tabs.rb
161
159
  - lib/ProMotion/version.rb
160
+ - lib/ProMotion/web/ui_web_screen_module.rb
162
161
  - lib/ProMotion/web/web_screen.rb
163
162
  - lib/ProMotion/web/web_screen_module.rb
163
+ - lib/ProMotion/web/wk_web_screen_module.rb
164
164
  - spec/functional/func_screen_spec.rb
165
165
  - spec/functional/func_split_screen_spec.rb
166
166
  - spec/functional/func_table_screen_cell_spec.rb
@@ -213,8 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
213
213
  - !ruby/object:Gem::Version
214
214
  version: '0'
215
215
  requirements: []
216
- rubyforge_project:
217
- rubygems_version: 2.7.6
216
+ rubygems_version: 3.0.6
218
217
  signing_key:
219
218
  specification_version: 4
220
219
  summary: ProMotion is a fast way to get started building RubyMotion apps. Instead
@@ -1,76 +0,0 @@
1
- class LiveReloader
2
- attr_reader :path_query, :opts
3
-
4
- def initialize(path, opts={})
5
- @path_query = path
6
- @opts = opts
7
- end
8
-
9
- def watch(&callback)
10
- log path_query
11
- log live_file_paths
12
-
13
- @live_reload_timer = every(opts[:interval] || 0.5) do
14
- live_files.each do |live_file, modified_date|
15
- if File.exist?(live_file) && File.mtime(live_file) > modified_date
16
- new_code = File.read(live_file)
17
- eval(new_code)
18
- callback.call *[live_file, new_code, parse_class_names(new_code)].first(callback.arity)
19
- reload_live_files
20
- end
21
- end
22
- end
23
-
24
- log "Watching #{path_query}."
25
- self
26
- end
27
-
28
- def stop
29
- @live_reload_timer.invalidate if @live_reload_timer
30
- @live_reload_timer = nil
31
- log "Stopped."
32
- self
33
- end
34
-
35
- def debug?
36
- @opts[:debug]
37
- end
38
-
39
- private
40
-
41
- def every(interval, &callback)
42
- NSTimer.scheduledTimerWithTimeInterval(interval, target: callback, selector: 'call:', userInfo: nil, repeats: true)
43
- end
44
-
45
- def live_files
46
- @live_files ||= live_file_paths.inject({}) do |out, live_file_path_file|
47
- out[live_file_path_file] = File.mtime(live_file_path_file)
48
- out
49
- end
50
- end
51
-
52
- def reload_live_files
53
- @live_files = nil
54
- live_files
55
- end
56
-
57
- def log(s)
58
- puts s.inspect if debug?
59
- s
60
- end
61
-
62
- def project_root_path
63
- NSBundle.mainBundle.infoDictionary["ProjectRootPath"]
64
- end
65
-
66
- def live_file_paths
67
- log Dir.glob("#{project_root_path}/#{path_query}").to_a
68
- end
69
-
70
- def parse_class_names(code)
71
- log code.split("\n").map do |code_line|
72
- matched = code_line.match(/^\s*class\s+(\S+)\s+</)
73
- matched[1] if matched
74
- end.to_a.compact.to_a
75
- end
76
- end
@@ -1,95 +0,0 @@
1
- if RUBYMOTION_ENV == "development"
2
- puts "Type `pm_live` to enable ProMotion's live reload system."
3
- module Kernel
4
-
5
- @live_reloaders ||= []
6
-
7
- def register_live_reloader watcher
8
- @live_reloaders << watcher
9
- end
10
-
11
- def pm_live(opts={})
12
-
13
- @watchers.each {|watcher| watcher.stop} if @watchers
14
-
15
- if opts == false || opts.to_s.downcase == "off"
16
- @watchers = nil
17
- "Live reloading of PM screens is now off."
18
- else
19
- @watchers = live_reloaders.collect {|reloader| reloader.(opts)}
20
- mp @watchers if opts[:debug]
21
-
22
- watching = @watchers.collect {|watcher| watcher.path_query}
23
- "Live reloading of #{watching.join(", ")} is now on."
24
- end
25
- end
26
-
27
- alias_method :pm_live_screens, :pm_live
28
-
29
-
30
- private
31
-
32
- def live_reloaders
33
- Kernel.instance_variable_get(:@live_reloaders)
34
- end
35
-
36
- def screen_watcher
37
- lambda do | opts |
38
- LiveReloader.new("app/screens/**/*.rb", opts).watch do |reloaded_file, new_code, class_names|
39
- vcs = pm_all_view_controllers(UIApplication.sharedApplication.delegate.window.rootViewController)
40
- vcs.each do |vc|
41
- if pm_is_in_ancestry?(vc, class_names)
42
- puts "Sending :on_live_reload to #{vc.inspect}." if opts[:debug]
43
- vc.send(:on_live_reload) if vc.respond_to?(:on_live_reload)
44
- end
45
- end
46
- end
47
- end
48
- end
49
-
50
- register_live_reloader screen_watcher
51
-
52
- def view_watcher
53
- lambda do | opts |
54
- LiveReloader.new("app/views/**/*.rb", opts).watch do |reloaded_file, new_code, class_names|
55
- views = pm_all_views(UIApplication.sharedApplication.delegate.window)
56
- views.each do |view|
57
- if pm_is_in_ancestry?(view, class_names)
58
- puts "Sending :on_live_reload to #{view.inspect}." if opts[:debug]
59
- view.send(:on_live_reload) if view.respond_to?(:on_live_reload)
60
- end
61
- end
62
- end
63
- end
64
- end
65
-
66
- register_live_reloader view_watcher
67
-
68
- # Very permissive. Might get unnecessary reloads. That's okay.
69
- def pm_is_in_ancestry?(vc, screen_names)
70
- screen_names.any? do |screen_name|
71
- vc.class.to_s.include?(screen_name) ||
72
- vc.class.ancestors.any? do |ancestor|
73
- screen_name.include?(ancestor.to_s)
74
- end
75
- end
76
- end
77
-
78
- def pm_all_view_controllers(root_view_controller)
79
- vcs = [ root_view_controller ]
80
- if root_view_controller.respond_to?(:viewControllers)
81
- vcs = vcs + root_view_controller.viewControllers.map{|vc| pm_all_view_controllers(vc) }
82
- end
83
- if root_view_controller.respond_to?(:childViewControllers)
84
- vcs = vcs + root_view_controller.childViewControllers.map{|vc| pm_all_view_controllers(vc) }
85
- end
86
- vcs.flatten.uniq
87
- end
88
-
89
- def pm_all_views(root_view)
90
- views = [ root_view ]
91
- views = views + views.map{|v| v.subviews.map{|sv| pm_all_views(sv) } }
92
- views.flatten.uniq
93
- end
94
- end
95
- end