wedge 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,44 @@
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 == 'Wedge::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
@@ -0,0 +1,97 @@
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
@@ -0,0 +1,106 @@
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
@@ -0,0 +1,3 @@
1
+ module Wedge
2
+ VERSION = "0.0.1"
3
+ end
data/test.rb ADDED
@@ -0,0 +1,44 @@
1
+ require 'awesome_print'
2
+
3
+ requires = {
4
+ form_plugin: [],
5
+ list: [
6
+ {
7
+ name: 'claim',
8
+ requires: [
9
+ {name: 'filter_form', requires: [{ name: 'form_plugin', requires: [] }]},
10
+ {name: 'claim_form', requires: []}
11
+ ],
12
+ },
13
+ {
14
+ name: 'claim_form',
15
+ requires: [
16
+ {name: 'form_plugin', requires: []},
17
+ {name: 'address_form', requires: [{ name: 'form_plugin', requires: [] }]}
18
+ ],
19
+ }
20
+ ]
21
+ }
22
+
23
+ $loaded_requires = []
24
+
25
+ def get_requires reqs, requires_array = []
26
+ new_reqs = []
27
+
28
+ reqs.each do |r|
29
+ if r[:requires].any?
30
+ get_requires(r[:requires], requires_array)
31
+ end
32
+
33
+ unless $loaded_requires.include? r[:name]
34
+ $loaded_requires << r[:name]
35
+ new_reqs << r[:name]
36
+ end
37
+ end
38
+
39
+ requires_array << new_reqs if new_reqs.any?
40
+
41
+ requires_array
42
+ end
43
+
44
+ ap get_requires requires[:list]
data/test/dummy/app.rb ADDED
@@ -0,0 +1,34 @@
1
+ require 'wedge'
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 :wedge, {
11
+ scope: self,
12
+ plugins: [:form]
13
+ }
14
+
15
+ plugin :assets, {
16
+ group_subdirs: false,
17
+ path: ROOT_PATH,
18
+ css_dir: '',
19
+ js_dir: ''
20
+ }
21
+
22
+ route do |r|
23
+ r.wedge_assets
24
+
25
+ r.root do
26
+ wedge(:root, :js).display
27
+ end
28
+ end
29
+ end
30
+
31
+ Dir["#{ROOT_PATH}/forms/*.rb"].sort.each { |file| require file }
32
+ Dir["#{ROOT_PATH}/components/*.rb"].sort.each { |file| require file }
33
+
34
+ Wedge.cache # cache files on app load
@@ -0,0 +1,14 @@
1
+ class DummyApp
2
+ class BarComponent < Wedge::Component
3
+ config.name :bar
4
+ config.requires :root, :base
5
+
6
+ def moo
7
+ 'cow'
8
+ end
9
+
10
+ on :clicked_foo, for: :root do
11
+ dom.find('body').append moo
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,5 @@
1
+ class DummyApp
2
+ class BaseComponent < Wedge::Component
3
+ config.name :base
4
+ end
5
+ end
@@ -0,0 +1,42 @@
1
+ require_relative 'base' unless RUBY_ENGINE == 'opal'
2
+
3
+ class DummyApp
4
+ class RootComponent < BaseComponent
5
+ config.name :root
6
+ config.html <<-HTML
7
+ <!DOCTYPE html>
8
+ <html>
9
+ <head>
10
+ <script src="//code.jquery.com/jquery-1.11.2.js"></script>
11
+ #{Wedge.script_tag}
12
+ </head>
13
+ <body>
14
+ <div id='foo'>bar</div>
15
+ </body>
16
+ </html>
17
+ HTML
18
+ config.dom do
19
+ dom.find('body') << assets(:js)
20
+ end
21
+ config.requires :base, :bar, :foo_form, :pjax_plugin
22
+
23
+ def display
24
+ if server?
25
+ dom
26
+ else
27
+ el = Element['<div>']
28
+ el.html 'foo'
29
+ dom.find('#foo').before el
30
+ end
31
+ end
32
+
33
+ on :ready do
34
+ puts 'dom ready'
35
+ end
36
+
37
+ on :click, '#foo' do |el|
38
+ el.after '<div>bar</div>'
39
+ trigger :clicked_foo
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,6 @@
1
+ require 'bundler'
2
+ Bundler.setup :default, ENV.fetch('RACK_ENV') { 'development' }
3
+
4
+ require_relative 'app'
5
+
6
+ run DummyApp
@@ -0,0 +1,5 @@
1
+ class DummyApp
2
+ class BarForm < Wedge::Plugins::Form
3
+ config.name :bar_form
4
+ end
5
+ end
@@ -0,0 +1,6 @@
1
+ class DummyApp
2
+ class FooForm < Wedge::Plugins::Form
3
+ config.name :foo_form
4
+ config.requires :bar_form
5
+ end
6
+ end
data/test/test.js ADDED
@@ -0,0 +1,59 @@
1
+ var page = require('webpage').create();
2
+ page.settings.localToRemoteUrlAccessEnabled = true;
3
+ page.settings.resourceTimeout = 1000;
4
+ // page.content = "<!doctype html>\n<html>\n<head>\new<script type=\"text/javascript\" src=\"https://code.jquery.com/jquery-1.11.2.min.js\"></script>\n</head>\n<body>\n<div id=\"foo\">bar<div>\n</body>\n</html>";
5
+ var content = '<!doctype html>';
6
+ content += '<html><head>';
7
+ content += '<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.2.min.js"></script>';
8
+ content += '</head><body>';
9
+ content += '<h1 id="foo">bar</h1>';
10
+ content += '</body></html>';
11
+
12
+ // page.content = "<div id='foo'>bar</div>";
13
+
14
+ page.onConsoleMessage = function(msg) {
15
+ console.log(msg);
16
+ };
17
+
18
+ page.onResourceTimeout = function(a) {
19
+ phantom.exit(1);
20
+ };
21
+
22
+ page.onError = function(msg, trace) {
23
+
24
+ var msgStack = ['ERROR: ' + msg];
25
+
26
+ if (trace && trace.length) {
27
+ msgStack.push('TRACE:');
28
+ trace.forEach(function(t) {
29
+ msgStack.push(' -> ' + t.file + ': ' + t.line + (t.function ? ' (in function "' + t.function +'")' : ''));
30
+ });
31
+ }
32
+
33
+ console.log(msgStack.join('\n'));
34
+ phantom.exit();
35
+ };
36
+
37
+ phantom.onError = function(msg, trace) {
38
+ var msgStack = ['PHANTOM ERROR: ' + msg];
39
+ if (trace && trace.length) {
40
+ msgStack.push('TRACE:');
41
+ trace.forEach(function(t) {
42
+ msgStack.push(' -> ' + (t.file || t.sourceURL) + ': ' + t.line + (t.function ? ' (in function ' + t.function +')' : ''));
43
+ });
44
+ }
45
+ console.log(msgStack.join('\n'));
46
+ phantom.exit();
47
+ };
48
+
49
+ page.content = content
50
+
51
+ page.onLoadFinished = function() {
52
+ page.evaluate(function() {
53
+ console.log($('#foo').html());
54
+ });
55
+ phantom.exit();
56
+ };
57
+
58
+ // page.includeJs("http://code.jquery.com/jquery-1.11.2.min.js", function(){
59
+ // });