browserio 0.0.4 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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