browserio 0.0.4 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,44 +0,0 @@
1
- module Nokogiri
2
- module XML
3
- class NodeSet
4
- # fix: this is really shity
5
- # alias_method :original_to_html, :to_html
6
- # def to_html *args
7
- # original_to_html(*args).gsub('%7B', "{").gsub('%7D', "}")
8
- # end
9
- end
10
- class Node
11
- # fix: this is really shity
12
- # alias_method :original_to_html, :to_html
13
- # def to_html *args
14
- # original_to_html(*args).gsub('%7B', "{").gsub('%7D', "}")
15
- # end
16
-
17
- private
18
-
19
- def coerce data # :nodoc:
20
- if data.class.to_s == 'BrowserIO::DOM'
21
- data = data.dom
22
- end
23
-
24
- case data
25
- when XML::NodeSet
26
- return data
27
- when XML::DocumentFragment
28
- return data.children
29
- when String
30
- return fragment(data).children
31
- when Document, XML::Attr
32
- # unacceptable
33
- when XML::Node
34
- return data
35
- end
36
-
37
- raise ArgumentError, <<-EOERR
38
- Requires a Node, NodeSet or String argument, and cannot accept a #{data.class}.
39
- (You probably want to select a node from the Document with at() or search(), or create a new Node via Node.new().)
40
- EOERR
41
- end
42
- end
43
- end
44
- end
@@ -1,97 +0,0 @@
1
- # -*- coding: utf-8 -*-
2
- # Adds String#titleize for creating properly capitalized titles.
3
- # It can be called as Titleize.titleize or "a string".titleize.
4
- #
5
- # titlecase is included as an alias for titleize.
6
- #
7
- # If loaded in a Rails environment, it modifies Inflector.titleize.
8
- module Titleize
9
- SMALL_WORDS = %w{a an and as at but by en for if in of on or the to v v. via vs vs.}
10
-
11
- extend self
12
-
13
- # Capitalizes most words to create a nicer looking title string.
14
- #
15
- # The list of "small words" which are not capped comes from
16
- # the New York Times Manual of Style, plus 'vs' and 'v'.
17
- #
18
- # "notes on a scandal" # => "Notes on a Scandal"
19
- # "the good german" # => "The Good German"
20
- def titleize(title)
21
- title = title.dup
22
- title.downcase! unless title[/[[:lower:]]/] # assume all-caps need fixing
23
-
24
- phrases(title).map do |phrase|
25
- words = phrase.split
26
- words.map do |word|
27
- def word.capitalize
28
- # like String#capitalize, but it starts with the first letter
29
- self.sub(/[[:alpha:]].*/) {|subword| subword.capitalize}
30
- end
31
-
32
- case word
33
- when /[[:alpha:]]\.[[:alpha:]]/ # words with dots in, like "example.com"
34
- word
35
- when /[-‑]/ # hyphenated word (regular and non-breaking)
36
- word.split(/([-‑])/).map do |part|
37
- SMALL_WORDS.include?(part) ? part : part.capitalize
38
- end.join
39
- when /^[[:alpha:]].*[[:upper:]]/ # non-first letter capitalized already
40
- word
41
- when /^[[:digit:]]/ # first character is a number
42
- word
43
- when words.first, words.last
44
- word.capitalize
45
- when *(SMALL_WORDS + SMALL_WORDS.map {|small| small.capitalize })
46
- word.downcase
47
- else
48
- word.capitalize
49
- end
50
- end.join(" ")
51
- end.join(" ")
52
- end
53
-
54
- # Splits a title into an array based on punctuation.
55
- #
56
- # "simple title" # => ["simple title"]
57
- # "more complicated: titling" # => ["more complicated:", "titling"]
58
- def phrases(title)
59
- phrases = title.scan(/.+?(?:[:.;?!] |$)/).map {|phrase| phrase.strip }
60
-
61
- # rejoin phrases that were split on the '.' from a small word
62
- if phrases.size > 1
63
- phrases[0..-2].each_with_index do |phrase, index|
64
- if SMALL_WORDS.include?(phrase.split.last.downcase)
65
- phrases[index] << " " + phrases.slice!(index + 1)
66
- end
67
- end
68
- end
69
-
70
- phrases
71
- end
72
- end
73
-
74
- class String
75
- # Capitalizes most words to create a nicer looking title string.
76
- #
77
- # The list of "small words" which are not capped comes from
78
- # the New York Times Manual of Style, plus 'vs' and 'v'.
79
- #
80
- # titleize is also aliased as titlecase.
81
- #
82
- # "notes on a scandal" # => "Notes on a Scandal"
83
- # "the good german" # => "The Good German"
84
- def titleize(opts={})
85
- # if defined? ActiveSupport
86
- # ActiveSupport::Inflector.titleize(self, opts)
87
- # else
88
- Titleize.titleize(self)
89
- # end
90
- end
91
- alias_method :titlecase, :titleize
92
-
93
- def titleize!
94
- replace(titleize)
95
- end
96
- alias_method :titlecase!, :titleize!
97
- end
@@ -1,106 +0,0 @@
1
- class Object
2
- # Invokes the public method whose name goes as first argument just like
3
- # +public_send+ does, except that if the receiver does not respond to it the
4
- # call returns +nil+ rather than raising an exception.
5
- #
6
- # This method is defined to be able to write
7
- #
8
- # @person.try(:name)
9
- #
10
- # instead of
11
- #
12
- # @person.name if @person
13
- #
14
- # +try+ calls can be chained:
15
- #
16
- # @person.try(:spouse).try(:name)
17
- #
18
- # instead of
19
- #
20
- # @person.spouse.name if @person && @person.spouse
21
- #
22
- # +try+ will also return +nil+ if the receiver does not respond to the method:
23
- #
24
- # @person.try(:non_existing_method) # => nil
25
- #
26
- # instead of
27
- #
28
- # @person.non_existing_method if @person.respond_to?(:non_existing_method) # => nil
29
- #
30
- # +try+ returns +nil+ when called on +nil+ regardless of whether it responds
31
- # to the method:
32
- #
33
- # nil.try(:to_i) # => nil, rather than 0
34
- #
35
- # Arguments and blocks are forwarded to the method if invoked:
36
- #
37
- # @posts.try(:each_slice, 2) do |a, b|
38
- # ...
39
- # end
40
- #
41
- # The number of arguments in the signature must match. If the object responds
42
- # to the method the call is attempted and +ArgumentError+ is still raised
43
- # in case of argument mismatch.
44
- #
45
- # If +try+ is called without arguments it yields the receiver to a given
46
- # block unless it is +nil+:
47
- #
48
- # @person.try do |p|
49
- # ...
50
- # end
51
- #
52
- # You can also call try with a block without accepting an argument, and the block
53
- # will be instance_eval'ed instead:
54
- #
55
- # @person.try { upcase.truncate(50) }
56
- #
57
- # Please also note that +try+ is defined on +Object+. Therefore, it won't work
58
- # with instances of classes that do not have +Object+ among their ancestors,
59
- # like direct subclasses of +BasicObject+. For example, using +try+ with
60
- # +SimpleDelegator+ will delegate +try+ to the target instead of calling it on
61
- # the delegator itself.
62
- def try(*a, &b)
63
- try!(*a, &b) if a.empty? || respond_to?(a.first)
64
- end
65
-
66
- # Same as #try, but raises a NoMethodError exception if the receiver is
67
- # not +nil+ and does not implement the tried method.
68
- #
69
- # "a".try!(:upcase) # => "A"
70
- # nil.try!(:upcase) # => nil
71
- # 123.try!(:upcase) # => NoMethodError: undefined method `upcase' for 123:Fixnum
72
- def try!(*a, &b)
73
- if a.empty? && block_given?
74
- if b.arity.zero?
75
- instance_eval(&b)
76
- else
77
- yield self
78
- end
79
- else
80
- public_send(*a, &b)
81
- end
82
- end
83
- end
84
-
85
- class NilClass
86
- # Calling +try+ on +nil+ always returns +nil+.
87
- # It becomes especially helpful when navigating through associations that may return +nil+.
88
- #
89
- # nil.try(:name) # => nil
90
- #
91
- # Without +try+
92
- # @person && @person.children.any? && @person.children.first.name
93
- #
94
- # With +try+
95
- # @person.try(:children).try(:first).try(:name)
96
- def try(*args)
97
- nil
98
- end
99
-
100
- # Calling +try!+ on +nil+ always returns +nil+.
101
- #
102
- # nil.try!(:name) # => nil
103
- def try!(*args)
104
- nil
105
- end
106
- end
@@ -1,88 +0,0 @@
1
- class Roda
2
- module RodaPlugins
3
- module BrowserIO
4
- def self.configure(app, opts = {})
5
- if app.opts[:browserio]
6
- app.opts[:browserio].merge!(opts)
7
- else
8
- app.opts[:browserio] = opts.dup
9
- end
10
-
11
- opts = app.opts[:browserio]
12
-
13
- opts.each do |k, v|
14
- case k.to_s
15
- when 'plugins'
16
- v.each { |p| ::BrowserIO.config.plugin p }
17
- when 'scope'
18
- ::BrowserIO.config.scope v.new
19
- else
20
- ::BrowserIO.config.send(k, v)
21
- end
22
- end
23
- end
24
-
25
- module InstanceMethods
26
- def bio(*args)
27
- args << { scope: self }
28
- ::BrowserIO[*args]
29
- end
30
- end
31
-
32
- module RequestClassMethods
33
- def bio_route_regex
34
- %r{#{roda_class.opts[:browserio][:assets_url]}/(.*)\.(.*)$}
35
- end
36
- end
37
-
38
- module RequestMethods
39
- def browserio
40
- on self.class.bio_route_regex do |component, ext|
41
- case ext
42
- when 'map'
43
- ::BrowserIO.source_map component
44
- when 'rb'
45
- if component =~ /^browserio/
46
- path = ::BrowserIO.opts.file_path.gsub(/\/browserio.rb$/, '')
47
- File.read("#{path}/#{component}.rb")
48
- else
49
- File.read("#{ROOT_PATH}/#{component}.rb")
50
- end
51
- when 'call'
52
- body = scope.request.body.read
53
- data = scope.request.params
54
-
55
- begin
56
- data.merge!(body ? JSON.parse(body) : {})
57
- rescue
58
- # can't be parsed by json
59
- end
60
-
61
- data = data.indifferent
62
- name = data.delete(:name)
63
- method_called = data.delete(:method_called)
64
- method_args = data.delete(:method_args)
65
-
66
- res = scope.bio(name, data).send(method_called, *method_args)
67
-
68
- scope.response.headers["BIO-CSRF-TOKEN"] = scope.csrf_token if scope.methods.include? :csrf_token
69
-
70
- if res.is_a? Hash
71
- scope.response.headers["Content-Type"] = 'application/json; charset=UTF-8'
72
- res = res.to_json
73
- else
74
- res = res.to_s
75
- end
76
-
77
- res
78
- else
79
- "#{::BrowserIO.javascript(component)}\n//# sourceMappingURL=/assets/bio/#{component}.map"
80
- end
81
- end
82
- end
83
- end
84
- end
85
-
86
- register_plugin(:browserio, BrowserIO)
87
- end
88
- end
@@ -1,34 +0,0 @@
1
- require 'browserio'
2
- require 'roda'
3
-
4
- require 'pry'
5
- require 'awesome_print'
6
-
7
- ROOT_PATH = File.dirname(__FILE__)
8
-
9
- class DummyApp < Roda
10
- plugin :assets, {
11
- group_subdirs: false,
12
- path: ROOT_PATH,
13
- css_dir: '',
14
- js_dir: '',
15
- js: [ 'bio/browserio.js' ]
16
- }
17
-
18
- plugin :browserio, {
19
- scope: self,
20
- assets_url: 'assets/bio',
21
- plugins: [:form]
22
- }
23
-
24
- route do |r|
25
- r.browserio
26
-
27
- r.root do
28
- bio(:root, :js).display
29
- end
30
- end
31
- end
32
-
33
- Dir["#{ROOT_PATH}/forms/*.rb"].sort.each { |file| require file }
34
- Dir["#{ROOT_PATH}/components/*.rb"].sort.each { |file| require file }
@@ -1,16 +0,0 @@
1
- require_relative 'root' unless RUBY_ENGINE == 'opal'
2
-
3
- class DummyApp
4
- class BarComponent < BrowserIO::Component
5
- config.name :bar
6
- config.requires :root
7
-
8
- def moo
9
- 'cow'
10
- end
11
-
12
- on :clicked_foo, for: :root do
13
- dom.find('body').append moo
14
- end
15
- end
16
- end
@@ -1,39 +0,0 @@
1
- class DummyApp
2
- class RootComponent < BrowserIO::Component
3
- config.name :root
4
- config.html <<-HTML
5
- <!DOCTYPE html>
6
- <html>
7
- <head>
8
- <script src="//code.jquery.com/jquery-1.11.2.js"></script>
9
- </head>
10
- <body>
11
- <div id='foo'>bar</div>
12
- </body>
13
- </html>
14
- HTML
15
- config.dom do
16
- dom.find('body') << assets(:js)
17
- end
18
- config.requires :bar, :foo_form
19
-
20
- def display
21
- if server?
22
- dom
23
- else
24
- el = Element['<div>']
25
- el.html 'foo'
26
- dom.find('#foo').before el
27
- end
28
- end
29
-
30
- on :ready do
31
- puts 'dom ready'
32
- end
33
-
34
- on :click, '#foo' do |el|
35
- el.after '<div>bar</div>'
36
- trigger :clicked_foo
37
- end
38
- end
39
- end
@@ -1,6 +0,0 @@
1
- require 'bundler'
2
- Bundler.setup :default, ENV.fetch('RACK_ENV') { 'development' }
3
-
4
- require_relative 'app'
5
-
6
- run DummyApp
@@ -1,6 +0,0 @@
1
- class DummyApp
2
- class FooForm < BrowserIO::Form
3
- config.name :foo_form
4
- config.requires :pjax_plugin
5
- end
6
- end