erector-rails4 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +2 -0
  3. data/.gitignore +10 -0
  4. data/.rspec +1 -0
  5. data/.ruby-gemset +1 -0
  6. data/.ruby-version +1 -0
  7. data/.travis.yml +5 -0
  8. data/Gemfile +6 -0
  9. data/Gemfile.lock +143 -0
  10. data/README.md +4 -0
  11. data/Rakefile +24 -0
  12. data/erector-rails4.gemspec +36 -0
  13. data/erector-rails4.sublimeproject +20 -0
  14. data/lib/erector/abstract_widget.rb +231 -0
  15. data/lib/erector/after_initialize.rb +29 -0
  16. data/lib/erector/attributes.rb +29 -0
  17. data/lib/erector/cache.rb +37 -0
  18. data/lib/erector/caching.rb +65 -0
  19. data/lib/erector/convenience.rb +98 -0
  20. data/lib/erector/dependencies.rb +24 -0
  21. data/lib/erector/dependency.rb +31 -0
  22. data/lib/erector/element.rb +113 -0
  23. data/lib/erector/externals.rb +104 -0
  24. data/lib/erector/html.rb +12 -0
  25. data/lib/erector/html_widget.rb +220 -0
  26. data/lib/erector/inline.rb +37 -0
  27. data/lib/erector/jquery.rb +28 -0
  28. data/lib/erector/mixin.rb +12 -0
  29. data/lib/erector/needs.rb +95 -0
  30. data/lib/erector/output.rb +144 -0
  31. data/lib/erector/promise.rb +141 -0
  32. data/lib/erector/rails/form_builder.rb +44 -0
  33. data/lib/erector/rails/railtie.rb +13 -0
  34. data/lib/erector/rails/template_handler.rb +16 -0
  35. data/lib/erector/rails/widget_renderer.rb +6 -0
  36. data/lib/erector/rails.rb +221 -0
  37. data/lib/erector/raw_string.rb +12 -0
  38. data/lib/erector/sass.rb +32 -0
  39. data/lib/erector/tag.rb +66 -0
  40. data/lib/erector/text.rb +123 -0
  41. data/lib/erector/unicode.rb +18185 -0
  42. data/lib/erector/unicode_builder.rb +67 -0
  43. data/lib/erector/version.rb +5 -0
  44. data/lib/erector/widget.rb +94 -0
  45. data/lib/erector/widgets.rb +5 -0
  46. data/lib/erector/xml_widget.rb +131 -0
  47. data/lib/erector.rb +28 -0
  48. data/spec/dummy/Rakefile +7 -0
  49. data/spec/dummy/app/controllers/application.rb +6 -0
  50. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  51. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  52. data/spec/dummy/app/views/layouts/erb_as_layout.html.erb +2 -0
  53. data/spec/dummy/app/views/layouts/widget_as_layout.rb +8 -0
  54. data/spec/dummy/app/views/test/_erb.erb +1 -0
  55. data/spec/dummy/app/views/test/_erector.rb +5 -0
  56. data/spec/dummy/app/views/test/_partial_with_locals.rb +7 -0
  57. data/spec/dummy/app/views/test/bare.rb +5 -0
  58. data/spec/dummy/app/views/test/erb_from_erector.html.rb +5 -0
  59. data/spec/dummy/app/views/test/erector_from_erb.html.erb +1 -0
  60. data/spec/dummy/app/views/test/erector_with_locals_from_erb.html.erb +6 -0
  61. data/spec/dummy/app/views/test/implicit_assigns.html.rb +5 -0
  62. data/spec/dummy/app/views/test/needs.html.rb +7 -0
  63. data/spec/dummy/app/views/test/needs_subclass.html.rb +5 -0
  64. data/spec/dummy/app/views/test/protected_instance_variable.html.rb +5 -0
  65. data/spec/dummy/app/views/test/render_default.html.rb +5 -0
  66. data/spec/dummy/app/views/test/render_default_erb_with_layout.html.erb +1 -0
  67. data/spec/dummy/app/views/test/render_default_widget_with_layout.html.rb +5 -0
  68. data/spec/dummy/app/views/test/render_partial.html.rb +5 -0
  69. data/spec/dummy/app/views/test/render_with_widget_as_layout.rb +5 -0
  70. data/spec/dummy/app/views/test/render_with_widget_as_layout_using_content_for.rb +8 -0
  71. data/spec/dummy/config/application.rb +44 -0
  72. data/spec/dummy/config/boot.rb +10 -0
  73. data/spec/dummy/config/database.yml +22 -0
  74. data/spec/dummy/config/environment.rb +5 -0
  75. data/spec/dummy/config/environments/development.rb +22 -0
  76. data/spec/dummy/config/environments/production.rb +49 -0
  77. data/spec/dummy/config/environments/test.rb +36 -0
  78. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  79. data/spec/dummy/config/initializers/inflections.rb +10 -0
  80. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  81. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  82. data/spec/dummy/config/initializers/session_store.rb +8 -0
  83. data/spec/dummy/config/locales/en.yml +5 -0
  84. data/spec/dummy/config/routes.rb +3 -0
  85. data/spec/dummy/config.ru +4 -0
  86. data/spec/dummy/db/seeds.rb +7 -0
  87. data/spec/dummy/script/rails +6 -0
  88. data/spec/dummy/spec/form_builder_spec.rb +21 -0
  89. data/spec/dummy/spec/rails_helpers_spec.rb +236 -0
  90. data/spec/dummy/spec/rails_spec_helper.rb +10 -0
  91. data/spec/dummy/spec/rails_widget_spec.rb +83 -0
  92. data/spec/dummy/spec/render_spec.rb +369 -0
  93. data/spec/erector/after_initialize_spec.rb +45 -0
  94. data/spec/erector/cache_spec.rb +133 -0
  95. data/spec/erector/caching_spec.rb +184 -0
  96. data/spec/erector/convenience_spec.rb +250 -0
  97. data/spec/erector/dependency_spec.rb +67 -0
  98. data/spec/erector/hello_from_readme.rb +18 -0
  99. data/spec/erector/hello_from_readme_spec.rb +11 -0
  100. data/spec/erector/html_spec.rb +585 -0
  101. data/spec/erector/indentation_spec.rb +211 -0
  102. data/spec/erector/inline_spec.rb +94 -0
  103. data/spec/erector/jquery_spec.rb +35 -0
  104. data/spec/erector/mixin_spec.rb +65 -0
  105. data/spec/erector/needs_spec.rb +141 -0
  106. data/spec/erector/output_spec.rb +293 -0
  107. data/spec/erector/promise_spec.rb +173 -0
  108. data/spec/erector/sample-file.txt +1 -0
  109. data/spec/erector/sass_spec.rb +57 -0
  110. data/spec/erector/tag_spec.rb +67 -0
  111. data/spec/erector/unicode_builder_spec.rb +75 -0
  112. data/spec/erector/widget_spec.rb +310 -0
  113. data/spec/erector/xml_widget_spec.rb +73 -0
  114. data/spec/spec_helper.rb +31 -0
  115. metadata +368 -0
@@ -0,0 +1,67 @@
1
+ # Note that this class is only used in building erector itself
2
+ # (and even then, only needs to be run when there is a new
3
+ # UnicodeData.txt file from unicode.org).
4
+ class Erector::UnicodeBuilder
5
+
6
+ def initialize(input, output)
7
+ @input = input
8
+ @output = output
9
+ @first = true
10
+ end
11
+
12
+ def generate()
13
+ @output.puts "Erector::CHARACTERS = {"
14
+ process_file
15
+ @output.puts "}"
16
+ end
17
+
18
+ def process_file()
19
+ while !@input.eof
20
+ line = @input.gets.strip
21
+ if (line == "")
22
+ next;
23
+ end
24
+
25
+ process_line(line)
26
+ end
27
+ if (!@first)
28
+ @output.puts
29
+ end
30
+ end
31
+
32
+ def output_line(line)
33
+ if (!@first)
34
+ @output.puts(',')
35
+ end
36
+
37
+ @output.print(line)
38
+
39
+ @first = false
40
+ end
41
+
42
+ def process_line(line)
43
+ fields = line.split(';')
44
+ code_point = fields[0]
45
+ name = fields[1]
46
+ alternate_name = fields[10]
47
+
48
+ if /^</.match(name)
49
+ return ""
50
+ end
51
+
52
+ output name, code_point
53
+ if (!alternate_name.nil? && alternate_name != "")
54
+ output alternate_name, code_point
55
+ end
56
+ end
57
+
58
+ def output(name, code_point)
59
+ output_line " :#{namify(name)} => 0x#{code_point.downcase}"
60
+ end
61
+
62
+ def namify(name)
63
+ name.downcase.gsub(/[- ]/, '_')
64
+ end
65
+
66
+ end
67
+
@@ -0,0 +1,5 @@
1
+ # Erector view framework
2
+ module Erector
3
+ VERSION = "0.0.1"
4
+ end
5
+
@@ -0,0 +1,94 @@
1
+ require "erector/element"
2
+ require "erector/attributes"
3
+ require "erector/promise"
4
+ require "erector/text"
5
+ require "erector/tag"
6
+ require "erector/html_widget"
7
+ require "erector/needs"
8
+
9
+ module Erector
10
+
11
+ # A Widget is the center of the Erector universe.
12
+ #
13
+ # To create a widget, extend Erector::Widget and implement the +content+
14
+ # method. Inside this method you may call any of the tag methods like +span+
15
+ # or +p+ to emit HTML/XML tags.
16
+ #
17
+ # You can also define a widget on the fly by passing a block to +new+. This
18
+ # block will get executed when the widget's +content+ method is called. See
19
+ # the userguide for important details about the scope of this block when run --
20
+ # http://erector.rubyforge.org/userguide.html#blocks
21
+ #
22
+ # To render a widget from the outside, instantiate it and call its +to_html+
23
+ # method.
24
+ #
25
+ # A widget's +new+ method optionally accepts an options hash. Entries in
26
+ # this hash are converted to instance variables.
27
+ #
28
+ # You can add runtime input checking via the +needs+ macro. See #needs.
29
+ # This mechanism is meant to ameliorate development-time confusion about
30
+ # exactly what parameters are supported by a given widget, avoiding
31
+ # confusing runtime NilClass errors.
32
+ #
33
+ # To call one widget from another, inside the parent widget's +content+
34
+ # method, instantiate the child widget and call the +widget+ method. This
35
+ # assures that the same output stream is used, which gives better
36
+ # performance than using +capture+ or +to_html+. It also preserves the
37
+ # indentation and helpers of the enclosing class.
38
+ #
39
+ # In this documentation we've tried to keep the distinction clear between
40
+ # methods that *emit* text and those that *return* text. "Emit" means that
41
+ # it writes to the output stream; "return" means that it returns a string
42
+ # like a normal method and leaves it up to the caller to emit that string if
43
+ # it wants.
44
+ #
45
+ # This class extends AbstractWidget and includes several modules,
46
+ # so be sure to check all of those places for API documentation for the
47
+ # various methods of Widget:
48
+ #
49
+ # * AbstractWidget
50
+ # * Element
51
+ # * Attributes
52
+ # * Text
53
+ # * Needs
54
+ # * Caching
55
+ # * Externals
56
+ # * AfterInitialize
57
+ #
58
+ # * HTML
59
+ # * Convenience
60
+ # * JQuery
61
+ # * Sass
62
+ #
63
+ # Also read the API Cheatsheet in the user guide
64
+ # at http://erector.rubyforge.org/userguide#apicheatsheet
65
+ class Widget < HTMLWidget
66
+
67
+ # for some reason these need to be included in Widget and not AbstractWidget
68
+ include Needs
69
+ include Caching
70
+ include Externals
71
+
72
+ include HTML
73
+ include Convenience
74
+ include Erector::JQuery
75
+ include Erector::Sass if Object.const_defined?(:Sass)
76
+
77
+ # alias for AbstractWidget#render
78
+ def to_html(options = {})
79
+ raise "Erector::Widget#to_html takes an options hash, not a symbol. Try calling \"to_html(:content_method_name=> :#{options})\"" if options.is_a? Symbol
80
+ _emit(options).to_s
81
+ end
82
+
83
+ # alias for #to_html
84
+ # @deprecated Please use {#to_html} instead
85
+ def to_s(*args)
86
+ unless defined? @@already_warned_to_s
87
+ $stderr.puts "Erector::Widget#to_s is deprecated. Please use #to_html instead. Called from #{caller.first}"
88
+ @@already_warned_to_s = true
89
+ end
90
+ to_html(*args)
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,5 @@
1
+ require "erector/widgets/environment_badge"
2
+ require "erector/widgets/field_table"
3
+ require "erector/widgets/external_renderer"
4
+ require "erector/widgets/page"
5
+ require "erector/widgets/table"
@@ -0,0 +1,131 @@
1
+ require 'erector/abstract_widget'
2
+ require 'erector/tag'
3
+ require 'erector/needs'
4
+
5
+ module Erector
6
+
7
+ # Abstract base class for XML Widgets and HTMLWidget.
8
+ # Declares "tags" which define methods that emit tags.
9
+ class XMLWidget < AbstractWidget
10
+ include Needs
11
+
12
+ def self.tag_named tag_name, checked = []
13
+ @tags ||= {}
14
+ @tags[tag_name] || begin
15
+ tag = nil
16
+ checked << self
17
+ taggy_ancestors = (ancestors - checked).select{|k| k.respond_to? :tag_named}
18
+ taggy_ancestors.each do |k|
19
+ tag = k.tag_named(tag_name, checked)
20
+ if tag
21
+ @tags[tag_name] = tag
22
+ break
23
+ end
24
+ end
25
+ tag
26
+ end
27
+ end
28
+
29
+ def self.tag *args
30
+ tag = Tag.new(*args)
31
+ @tags ||= {}
32
+ @tags[tag.name] = tag
33
+
34
+ if instance_methods.include?(tag.method_name.to_sym)
35
+ warn "method '#{tag.method_name}' is already defined; skipping #{caller[1]}"
36
+ return
37
+ end
38
+
39
+ if tag.self_closing?
40
+ self.class_eval(<<-SRC, __FILE__, __LINE__ + 1)
41
+ def #{tag.method_name}(*args, &block)
42
+ _empty_element('#{tag.name}', *args, &block)
43
+ end
44
+ SRC
45
+ else
46
+ self.class_eval(<<-SRC, __FILE__, __LINE__ + 1)
47
+ def #{tag.method_name}(*args, &block)
48
+ _element('#{tag.name}', *args, &block)
49
+ end
50
+
51
+ def #{tag.method_name}!(*args, &block)
52
+ _element('#{tag.name}', *(args.map{|a|raw(a)}), &block)
53
+ end
54
+ SRC
55
+ end
56
+ end
57
+
58
+ # Tags which are always self-closing
59
+ def self.self_closing_tags
60
+ @tags.values.select{|tag| tag.self_closing?}.map{|tag| tag.name}
61
+ end
62
+
63
+ # Tags which can contain other stuff
64
+ def self.full_tags
65
+ @tags.values.select{|tag| !tag.self_closing?}.map{|tag| tag.name}
66
+ end
67
+
68
+ def newliney?(tag_name)
69
+ tag = self.class.tag_named tag_name
70
+ if tag
71
+ tag.newliney?
72
+ else
73
+ true
74
+ end
75
+ end
76
+
77
+ # Emits an XML instruction, which looks like this: <?xml version=\"1.0\" encoding=\"UTF-8\" ?>
78
+ def instruct(attributes={:version => "1.0", :encoding => "UTF-8"})
79
+ output << raw("<?xml#{format_attributes(sort_for_xml_declaration(attributes))}?>")
80
+ end
81
+
82
+ # Emits an XML/HTML comment (&lt;!-- ... --&gt;) surrounding +text+ and/or
83
+ # the output of +block+. see
84
+ # http://www.w3.org/TR/html4/intro/sgmltut.html#h-3.2.4
85
+ #
86
+ # If +text+ is an Internet Explorer conditional comment condition such as
87
+ # "[if IE]", the output includes the opening condition and closing
88
+ # "[endif]". See http://www.quirksmode.org/css/condcom.html
89
+ #
90
+ # Since "Authors should avoid putting two or more adjacent hyphens inside
91
+ # comments," we emit a warning if you do that.
92
+ def comment(text = '')
93
+ puts "Warning: Authors should avoid putting two or more adjacent hyphens inside comments." if text =~ /--/
94
+
95
+ conditional = text =~ /\[if .*\]/
96
+
97
+ rawtext "<!--"
98
+ rawtext text
99
+ rawtext ">" if conditional
100
+
101
+ if block_given?
102
+ rawtext "\n"
103
+ yield
104
+ rawtext "\n"
105
+ end
106
+
107
+ rawtext "<![endif]" if conditional
108
+ rawtext "-->\n"
109
+ end
110
+
111
+ alias_method :to_xml, :emit
112
+
113
+ protected
114
+
115
+ def sort_for_xml_declaration(attributes)
116
+ # correct order is "version, encoding, standalone" (XML 1.0 section 2.8).
117
+ # But we only try to put version before encoding for now.
118
+ stringized = []
119
+ attributes.each do |key, value|
120
+ stringized << [key.to_s, value]
121
+ end
122
+ stringized.sort{|a, b| b <=> a}
123
+ end
124
+
125
+ end
126
+
127
+ public
128
+
129
+ XmlWidget = XMLWidget
130
+
131
+ end
data/lib/erector.rb ADDED
@@ -0,0 +1,28 @@
1
+ module Erector
2
+ end
3
+
4
+ require "cgi"
5
+
6
+ require "erector/raw_string"
7
+ require "erector/dependencies"
8
+ require "erector/dependency"
9
+ require "erector/externals"
10
+ require "erector/output"
11
+ require "erector/cache"
12
+ require "erector/caching"
13
+ require "erector/after_initialize"
14
+ require "erector/needs"
15
+ require "erector/html"
16
+ require "erector/convenience"
17
+ require "erector/jquery"
18
+ require "erector/sass"
19
+
20
+ require "erector/abstract_widget"
21
+ require "erector/html_widget"
22
+ require "erector/widget"
23
+
24
+ require "erector/inline"
25
+ require "erector/version"
26
+ require "erector/mixin"
27
+
28
+ require "erector/rails" if defined?(Rails)
@@ -0,0 +1,7 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+ require 'rake'
6
+
7
+ Dummy::Application.load_tasks
@@ -0,0 +1,6 @@
1
+ # Filters added to this controller apply to all controllers in the application.
2
+ # Likewise, all the methods added will be available for all controllers.
3
+
4
+ class ApplicationController < ActionController::Base
5
+ helper :all # include all helpers, all the time
6
+ end
@@ -0,0 +1,3 @@
1
+ class ApplicationController < ActionController::Base
2
+ protect_from_forgery
3
+ end
@@ -0,0 +1,2 @@
1
+ module ApplicationHelper
2
+ end
@@ -0,0 +1,2 @@
1
+ <%= @layout_content %>
2
+ <%= content_for :layout %>
@@ -0,0 +1,8 @@
1
+ class Views::Layouts::WidgetAsLayout < Erector::Widget
2
+ def content
3
+ content_for(:top) if content_for?(:top)
4
+ text @before || "BEFORE"
5
+ content_for(:layout)
6
+ text @after || "AFTER"
7
+ end
8
+ end
@@ -0,0 +1 @@
1
+ <%= "Partial #{@foobar}" %>
@@ -0,0 +1,5 @@
1
+ class Views::Test::Erector < Erector::Widget
2
+ def content
3
+ text "Partial #{@foobar}"
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ class Views::Test::PartialWithLocals < Erector::Widget
2
+ needs :foo, :bar => 12345
3
+
4
+ def content
5
+ text "Partial, foo #{@foo}, bar #{@bar}"
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ class Views::Test::Bare < Erector::Widget
2
+ def content
3
+ text "Bare"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class Views::Test::ErbFromErector < Erector::Widget
2
+ def content
3
+ text! parent.render(:partial => 'erb')
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ <%= render :partial => 'erector' %>
@@ -0,0 +1,6 @@
1
+ <%
2
+ passed_locals = { }
3
+ passed_locals[:foo] = @local_foo if @local_foo
4
+ passed_locals[:bar] = @local_bar if @local_bar
5
+ passed_locals[:baz] = @local_baz if @local_baz
6
+ %><%= render :partial => 'partial_with_locals', :locals => passed_locals %>
@@ -0,0 +1,5 @@
1
+ class Views::Test::ImplicitAssigns < Erector::Widget
2
+ def content
3
+ text @foobar
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ class Views::Test::Needs < Erector::Widget
2
+ needs :foobar
3
+
4
+ def content
5
+ text "Needs #{@foobar}"
6
+ end
7
+ end
@@ -0,0 +1,5 @@
1
+ class Views::Test::NeedsSubclass < Views::Test::Needs
2
+ def content
3
+ text "NeedsSubclass #{@foobar}"
4
+ end
5
+ end