hobo 0.7.5 → 0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/{hobo_files/plugin/CHANGES.txt → CHANGES.txt} +391 -0
- data/Manifest +146 -0
- data/{hobo_files/plugin/README → README} +0 -0
- data/bin/hobo +13 -26
- data/dryml_generators/rapid/cards.dryml.erb +55 -0
- data/dryml_generators/rapid/forms.dryml.erb +43 -0
- data/dryml_generators/rapid/pages.dryml.erb +284 -0
- data/hobo.gemspec +168 -0
- data/init.rb +9 -0
- data/lib/action_view_extensions/helpers/tag_helper.rb +7 -0
- data/lib/active_record/association_collection.rb +54 -0
- data/{hobo_files/plugin/lib → lib}/active_record/association_proxy.rb +12 -4
- data/{hobo_files/plugin/lib → lib}/active_record/association_reflection.rb +7 -1
- data/{hobo_files/plugin/lib → lib}/extensions/test_case.rb +17 -17
- data/{hobo_files/plugin/lib → lib}/hobo.rb +193 -100
- data/{hobo_files/plugin/lib → lib}/hobo/authentication_support.rb +8 -8
- data/{hobo_files/plugin/lib → lib}/hobo/bundle.rb +90 -89
- data/{hobo_files/plugin/lib → lib}/hobo/composite_model.rb +21 -21
- data/{hobo_files/plugin/lib → lib}/hobo/controller.rb +38 -25
- data/{hobo_files/plugin/lib → lib}/hobo/dev_controller.rb +10 -6
- data/lib/hobo/dryml.rb +167 -0
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/dryml_builder.rb +28 -25
- data/lib/hobo/dryml/dryml_generator.rb +210 -0
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/dryml_support_controller.rb +1 -1
- data/lib/hobo/dryml/parser.rb +3 -0
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/parser/attribute.rb +6 -6
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/parser/base_parser.rb +16 -16
- data/lib/hobo/dryml/parser/document.rb +57 -0
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/parser/element.rb +7 -7
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/parser/elements.rb +9 -9
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/parser/source.rb +3 -3
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/parser/text.rb +3 -3
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/parser/tree_parser.rb +3 -3
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/part_context.rb +26 -26
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/scoped_variables.rb +15 -15
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/tag_parameters.rb +10 -10
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/taglib.rb +43 -37
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/template.rb +290 -208
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/template_environment.rb +173 -115
- data/{hobo_files/plugin/lib → lib}/hobo/dryml/template_handler.rb +19 -24
- data/lib/hobo/find_for.rb +95 -0
- data/{hobo_files/plugin/lib → lib}/hobo/generator.rb +2 -1
- data/{hobo_files/plugin/lib → lib}/hobo/guest.rb +12 -4
- data/{hobo_files/plugin/lib → lib}/hobo/hobo_helper.rb +146 -117
- data/lib/hobo/include_in_save.rb +43 -0
- data/lib/hobo/lifecycles.rb +94 -0
- data/lib/hobo/lifecycles/actions.rb +73 -0
- data/lib/hobo/lifecycles/creator.rb +76 -0
- data/lib/hobo/lifecycles/lifecycle.rb +205 -0
- data/lib/hobo/lifecycles/state.rb +23 -0
- data/lib/hobo/lifecycles/transition.rb +66 -0
- data/{hobo_files/plugin/lib → lib}/hobo/model.rb +306 -217
- data/{hobo_files/plugin/lib → lib}/hobo/model_controller.rb +342 -213
- data/{hobo_files/plugin/lib → lib}/hobo/model_router.rb +151 -120
- data/{hobo_files/plugin/lib → lib}/hobo/model_support.rb +9 -9
- data/{hobo_files/plugin/lib → lib}/hobo/rapid_helper.rb +30 -23
- data/{hobo_files/plugin/lib → lib}/hobo/scopes.rb +22 -68
- data/{hobo_files/plugin/lib → lib}/hobo/scopes/apply_scopes.rb +5 -5
- data/lib/hobo/scopes/association_proxy_extensions.rb +47 -0
- data/{hobo_files/plugin/lib → lib}/hobo/scopes/automatic_scopes.rb +104 -79
- data/lib/hobo/scopes/named_scope_extensions.rb +27 -0
- data/{hobo_files/plugin/lib → lib}/hobo/static_tags +1 -11
- data/{hobo_files/plugin/lib → lib}/hobo/undefined.rb +1 -1
- data/{hobo_files/plugin/lib → lib}/hobo/undefined_access_error.rb +0 -0
- data/{hobo_files/plugin/lib → lib}/hobo/user.rb +27 -25
- data/{hobo_files/plugin/lib → lib}/hobo/user_controller.rb +80 -34
- data/{hobo_files/plugin/generators → rails_generators}/hobo/hobo_generator.rb +7 -7
- data/rails_generators/hobo/templates/application.css +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo/templates/application.dryml +0 -2
- data/{hobo_files/plugin/generators → rails_generators}/hobo/templates/dryml-support.js +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo/templates/guest.rb +0 -0
- data/rails_generators/hobo/templates/initializer.rb +9 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_front_controller/USAGE +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_front_controller/hobo_front_controller_generator.rb +1 -3
- data/{hobo_files/plugin/generators → rails_generators}/hobo_front_controller/templates/controller.rb +1 -1
- data/{hobo_files/plugin/generators → rails_generators}/hobo_front_controller/templates/functional_test.rb +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_front_controller/templates/helper.rb +0 -0
- data/rails_generators/hobo_front_controller/templates/index.dryml +25 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_model/USAGE +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_model/hobo_model_generator.rb +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_model/templates/fixtures.yml +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_model/templates/model.rb +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_model/templates/unit_test.rb +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_model_controller/USAGE +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_model_controller/hobo_model_controller_generator.rb +0 -7
- data/{hobo_files/plugin/generators → rails_generators}/hobo_model_controller/templates/controller.rb +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_model_controller/templates/functional_test.rb +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_model_controller/templates/helper.rb +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_model_resource/hobo_model_resource_generator.rb +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_model_resource/templates/controller.rb +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_model_resource/templates/functional_test.rb +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_model_resource/templates/helper.rb +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_rapid/hobo_rapid_generator.rb +21 -11
- data/{hobo_files/plugin/generators → rails_generators}/hobo_rapid/templates/IE7.js +1 -1
- data/rails_generators/hobo_rapid/templates/blank.gif +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_rapid/templates/hobo-rapid.css +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_rapid/templates/hobo-rapid.js +175 -104
- data/{hobo_files/plugin/generators → rails_generators}/hobo_rapid/templates/lowpro.js +0 -0
- data/rails_generators/hobo_rapid/templates/nicEditorIcons.gif +0 -0
- data/rails_generators/hobo_rapid/templates/nicedit.js +91 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_rapid/templates/reset.css +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_rapid/templates/themes/clean/public/images/fieldbg.gif +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_rapid/templates/themes/clean/public/images/pencil.png +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_rapid/templates/themes/clean/public/images/small_close.png +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_rapid/templates/themes/clean/public/images/spinner.gif +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_rapid/templates/themes/clean/public/stylesheets/clean.css +80 -71
- data/{hobo_files/plugin/generators → rails_generators}/hobo_rapid/templates/themes/clean/public/stylesheets/rapid-ui.css +6 -1
- data/{hobo_files/plugin/generators → rails_generators}/hobo_rapid/templates/themes/clean/views/clean.dryml +4 -4
- data/rails_generators/hobo_subsite/hobo_subsite_generator.rb +73 -0
- data/rails_generators/hobo_subsite/templates/application.dryml +1 -0
- data/rails_generators/hobo_subsite/templates/controller.rb +5 -0
- data/rails_generators/hobo_subsite/templates/site_taglib.dryml +13 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_user_controller/USAGE +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_user_controller/hobo_user_controller_generator.rb +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_user_controller/templates/controller.rb +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_user_controller/templates/functional_test.rb +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_user_controller/templates/helper.rb +0 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_user_model/USAGE +0 -0
- data/rails_generators/hobo_user_model/hobo_user_model_generator.rb +30 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_user_model/templates/fixtures.yml +0 -0
- data/rails_generators/hobo_user_model/templates/forgot_password.erb +10 -0
- data/rails_generators/hobo_user_model/templates/mailer.rb +14 -0
- data/rails_generators/hobo_user_model/templates/model.rb +55 -0
- data/{hobo_files/plugin/generators → rails_generators}/hobo_user_model/templates/unit_test.rb +0 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/{hobo_files/plugin/taglibs → taglibs}/core.dryml +6 -7
- data/{hobo_files/plugin/taglibs → taglibs}/rapid.dryml +36 -67
- data/{hobo_files/plugin/taglibs → taglibs}/rapid_document_tags.dryml +7 -24
- data/{hobo_files/plugin/taglibs → taglibs}/rapid_editing.dryml +51 -50
- data/{hobo_files/plugin/taglibs → taglibs}/rapid_forms.dryml +62 -56
- data/taglibs/rapid_generics.dryml +33 -0
- data/taglibs/rapid_lifecycles.dryml +43 -0
- data/{hobo_files/plugin/taglibs → taglibs}/rapid_navigation.dryml +23 -23
- data/taglibs/rapid_pages.dryml +183 -0
- data/{hobo_files/plugin/taglibs → taglibs}/rapid_plus.dryml +30 -5
- data/{hobo_files/plugin/taglibs → taglibs}/rapid_support.dryml +3 -4
- data/taglibs/rapid_user_pages.dryml +179 -0
- data/{hobo_files/plugin/tasks → tasks}/environments.rake +0 -0
- data/{hobo_files/plugin/tasks → tasks}/fix_dryml.rake +0 -0
- data/{hobo_files/plugin/tasks → tasks}/generate_tag_reference.rb +21 -22
- data/tasks/hobo_tasks.rake +32 -0
- data/test/test_generator_helper.rb +29 -0
- data/test/test_helper.rb +1 -0
- data/test/test_hobo_model_controller_generator.rb +56 -0
- data/{hobo_files/plugin/uninstall.rb → uninstall.rb} +0 -0
- metadata +240 -225
- data/README.txt +0 -18
- data/hobo_files/plugin/LICENSE.txt +0 -22
- data/hobo_files/plugin/Rakefile +0 -96
- data/hobo_files/plugin/generators/hobo_front_controller/templates/index.dryml +0 -24
- data/hobo_files/plugin/generators/hobo_front_controller/templates/search.dryml +0 -19
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/banner.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg-bodytop.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg-corner-01.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg-corner-02.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg-corner-03.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg-corner-04.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg-shadow-bottom.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg-shadow-left.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg-shadow-right.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/bkg-shadow-top.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/header-blue.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/header-dblue.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/header-green.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/header-purple.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/header-red.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/logo.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/plus.png +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/spinner.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/txt-list-img-dblue.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/txt-list-img-green.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/txt-list-img-purple.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/txt-list-img-red.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window-corner-01.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window-corner-02.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window-corner-03.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window-corner-04.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window-shadow-bottom.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window-shadow-left.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window-shadow-right.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/images/window-shadow-top.gif +0 -0
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/public/stylesheets/application.css +0 -400
- data/hobo_files/plugin/generators/hobo_rapid/templates/themes/default/views/application.dryml +0 -96
- data/hobo_files/plugin/generators/hobo_user_model/hobo_user_model_generator.rb +0 -25
- data/hobo_files/plugin/generators/hobo_user_model/templates/model.rb +0 -56
- data/hobo_files/plugin/init.rb +0 -101
- data/hobo_files/plugin/lib/action_view_extensions/base.rb +0 -15
- data/hobo_files/plugin/lib/active_record/has_many_association.rb +0 -55
- data/hobo_files/plugin/lib/active_record/has_many_through_association.rb +0 -20
- data/hobo_files/plugin/lib/hobo/dryml.rb +0 -165
- data/hobo_files/plugin/lib/hobo/dryml/parser/document.rb +0 -53
- data/hobo_files/plugin/lib/hobo/scopes/association_proxy_extensions.rb +0 -33
- data/hobo_files/plugin/lib/hobo/scopes/defined_scope_proxy_extender.rb +0 -90
- data/hobo_files/plugin/lib/hobo/scopes/scope_reflection.rb +0 -18
- data/hobo_files/plugin/lib/hobo/scopes/scoped_proxy.rb +0 -55
- data/hobo_files/plugin/taglib-docs/core.markdown +0 -165
- data/hobo_files/plugin/taglib-docs/rapid.markdown +0 -677
- data/hobo_files/plugin/taglib-docs/rapid_document_tags.markdown +0 -240
- data/hobo_files/plugin/taglib-docs/rapid_editing.markdown +0 -418
- data/hobo_files/plugin/taglib-docs/rapid_forms.markdown +0 -562
- data/hobo_files/plugin/taglib-docs/rapid_generics.markdown +0 -187
- data/hobo_files/plugin/taglib-docs/rapid_navigation.markdown +0 -214
- data/hobo_files/plugin/taglib-docs/rapid_pages.markdown +0 -530
- data/hobo_files/plugin/taglib-docs/rapid_plus.markdown +0 -65
- data/hobo_files/plugin/taglib-docs/rapid_support.markdown +0 -50
- data/hobo_files/plugin/taglib-docs/rapid_user_pages.markdown +0 -129
- data/hobo_files/plugin/taglibs/rapid_generics.dryml +0 -117
- data/hobo_files/plugin/taglibs/rapid_pages.dryml +0 -359
- data/hobo_files/plugin/taglibs/rapid_user_pages.dryml +0 -104
- data/hobo_files/plugin/tasks/dump_fixtures.rake +0 -70
- data/hobo_files/plugin/tasks/hobo_tasks.rake +0 -17
@@ -1,8 +1,8 @@
|
|
1
1
|
module Hobo::Dryml::Parser
|
2
|
-
|
2
|
+
|
3
3
|
# A REXML source that keeps track of where in the buffer it is
|
4
4
|
class Source < REXML::Source
|
5
|
-
|
5
|
+
|
6
6
|
def initialize(src)
|
7
7
|
super(src)
|
8
8
|
@buffer_offset = 0
|
@@ -50,7 +50,7 @@ module Hobo::Dryml::Parser
|
|
50
50
|
|
51
51
|
def current_line
|
52
52
|
pos = last_match_offset || 0
|
53
|
-
[0, 0, @orig[0..pos].count("\n") + 1]
|
53
|
+
[0, 0, @orig[0..pos].count("\n") + 1]
|
54
54
|
end
|
55
55
|
|
56
56
|
end
|
@@ -6,7 +6,7 @@ module Hobo::Dryml::Parser
|
|
6
6
|
@parser = Hobo::Dryml::Parser::BaseParser.new(source)
|
7
7
|
end
|
8
8
|
|
9
|
-
|
9
|
+
|
10
10
|
def parse
|
11
11
|
tag_stack = []
|
12
12
|
in_doctype = false
|
@@ -39,8 +39,8 @@ module Hobo::Dryml::Parser
|
|
39
39
|
if @build_context[-1].instance_of? Text
|
40
40
|
@build_context[-1] << event[1]
|
41
41
|
else
|
42
|
-
@build_context.add(
|
43
|
-
Hobo::Dryml::Parser::Text.new(event[1], @build_context.whitespace, nil, true)
|
42
|
+
@build_context.add(
|
43
|
+
Hobo::Dryml::Parser::Text.new(event[1], @build_context.whitespace, nil, true)
|
44
44
|
) unless (
|
45
45
|
@build_context.ignore_whitespace_nodes and
|
46
46
|
event[1].strip.size==0
|
@@ -1,20 +1,20 @@
|
|
1
1
|
module Hobo
|
2
|
-
|
2
|
+
|
3
3
|
module Dryml
|
4
|
-
|
4
|
+
|
5
5
|
# Raised when the part context fails its integrity check.
|
6
6
|
class PartContext
|
7
|
-
|
7
|
+
|
8
8
|
class TamperedWithPartContext < StandardError; end
|
9
|
-
|
9
|
+
|
10
10
|
class Id < String; end
|
11
|
-
|
11
|
+
|
12
12
|
class << self
|
13
13
|
attr_accessor :secret, :digest
|
14
14
|
end
|
15
15
|
self.digest = 'SHA1'
|
16
|
-
|
17
|
-
|
16
|
+
|
17
|
+
|
18
18
|
def self.client_side_storage(contexts, session)
|
19
19
|
return "" if contexts.empty?
|
20
20
|
|
@@ -23,15 +23,15 @@ module Hobo
|
|
23
23
|
"hoboParts['#{dom_id}'] = (#{code});\n"
|
24
24
|
end.join
|
25
25
|
end
|
26
|
-
|
27
|
-
|
26
|
+
|
27
|
+
|
28
28
|
def initialize(part_name, this_id, locals)
|
29
29
|
@part_name = part_name
|
30
30
|
@this_id = this_id
|
31
31
|
@locals = locals.map { |l| pre_marshal(l) }
|
32
32
|
end
|
33
|
-
|
34
|
-
|
33
|
+
|
34
|
+
|
35
35
|
def pre_marshal(x)
|
36
36
|
if x.is_a?(ActiveRecord::Base) && x.respond_to?(:typed_id)
|
37
37
|
Id.new(x.typed_id)
|
@@ -39,26 +39,26 @@ module Hobo
|
|
39
39
|
x
|
40
40
|
end
|
41
41
|
end
|
42
|
-
|
43
|
-
|
42
|
+
|
43
|
+
|
44
44
|
def marshal(session)
|
45
45
|
context = [@part_name, @this_id, @locals]
|
46
46
|
data = Base64.encode64(Marshal.dump(context)).strip
|
47
47
|
digest = self.class.generate_digest(data, session)
|
48
48
|
"#{data}--#{digest}"
|
49
49
|
end
|
50
|
-
|
50
|
+
|
51
51
|
|
52
52
|
class << self
|
53
|
-
|
53
|
+
|
54
54
|
# Generate the HMAC keyed message digest. Uses SHA1 by default.
|
55
55
|
def generate_digest(data, session)
|
56
56
|
secret = self.secret || ActionController::Base.cached_session_options.first[:secret]
|
57
57
|
key = secret.respond_to?(:call) ? secret.call(session) : secret
|
58
58
|
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(digest), key, data)
|
59
59
|
end
|
60
|
-
|
61
|
-
|
60
|
+
|
61
|
+
|
62
62
|
# Unmarshal part context to a hash and verify its integrity.
|
63
63
|
def unmarshal(client_store, this, session)
|
64
64
|
data, digest = CGI.unescape(client_store).strip.split('--')
|
@@ -70,7 +70,7 @@ module Hobo
|
|
70
70
|
|
71
71
|
[part_name, restore_part_this(this_id, this), restore_locals(locals)]
|
72
72
|
end
|
73
|
-
|
73
|
+
|
74
74
|
def restore_part_this(this_id, this)
|
75
75
|
if this_id == "this" or this_id.blank?
|
76
76
|
this
|
@@ -78,10 +78,10 @@ module Hobo
|
|
78
78
|
nil
|
79
79
|
else
|
80
80
|
Hobo.object_from_dom_id(this_id)
|
81
|
-
end
|
81
|
+
end
|
82
82
|
end
|
83
|
-
|
84
|
-
|
83
|
+
|
84
|
+
|
85
85
|
def restore_locals(locals)
|
86
86
|
locals.map do |l|
|
87
87
|
if l.is_a?(Id)
|
@@ -91,11 +91,11 @@ module Hobo
|
|
91
91
|
end
|
92
92
|
end
|
93
93
|
end
|
94
|
-
|
94
|
+
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
end
|
98
|
-
|
99
|
-
end
|
100
|
-
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
101
|
end
|
@@ -1,34 +1,34 @@
|
|
1
1
|
module Hobo::Dryml
|
2
|
-
|
2
|
+
|
3
3
|
class ScopedVariables
|
4
|
-
|
5
|
-
def initialize
|
6
|
-
@scopes = [
|
4
|
+
|
5
|
+
def initialize(variables=nil)
|
6
|
+
@scopes = variables ? [variables] : []
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
def [](key)
|
10
10
|
s = scope_with_key(key) and s[key]
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
def []=(key, val)
|
14
|
-
s = scope_with_key(key)
|
14
|
+
s = scope_with_key(key) or raise ArgumentError, "no such scoped variable: #{key}"
|
15
15
|
s[key] = val
|
16
16
|
end
|
17
|
-
|
18
|
-
def new_scope
|
19
|
-
@scopes <<
|
17
|
+
|
18
|
+
def new_scope(variables)
|
19
|
+
@scopes << variables.dup
|
20
20
|
res = yield
|
21
21
|
@scopes.pop
|
22
22
|
res
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
def scope_with_key(key)
|
26
26
|
@scopes.reverse_each do |s|
|
27
27
|
return s if s.has_key?(key)
|
28
|
-
end
|
28
|
+
end
|
29
29
|
nil
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
def method_missing(name, *args)
|
33
33
|
if name.to_s =~ /=$/
|
34
34
|
self[name.to_s[0..-2].to_sym] = args.first
|
@@ -36,7 +36,7 @@ module Hobo::Dryml
|
|
36
36
|
self[name]
|
37
37
|
end
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Hobo
|
2
|
-
|
2
|
+
|
3
3
|
module Dryml
|
4
|
-
|
4
|
+
|
5
5
|
class NoParameterError < RuntimeError; end
|
6
|
-
|
6
|
+
|
7
7
|
class TagParameters < Hash
|
8
|
-
|
8
|
+
|
9
9
|
def initialize(parameters, exclude_names=nil)
|
10
10
|
if exclude_names.blank?
|
11
11
|
update(parameters)
|
@@ -13,7 +13,7 @@ module Hobo
|
|
13
13
|
parameters.each_pair { |k, v| self[k] = v unless k.in?(exclude_names) }
|
14
14
|
end
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
17
|
def method_missing(name, default_content="")
|
18
18
|
if name.to_s =~ /\?$/
|
19
19
|
has_key?(name.to_s[0..-2].to_sym)
|
@@ -21,15 +21,15 @@ module Hobo
|
|
21
21
|
self[name]._?.call(default_content) || ""
|
22
22
|
end
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
undef_method :default
|
26
|
-
|
26
|
+
|
27
27
|
def [](param_name)
|
28
28
|
fetch(param_name, nil)
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
end
|
32
|
-
|
32
|
+
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
end
|
@@ -1,93 +1,99 @@
|
|
1
1
|
module Hobo
|
2
|
-
|
2
|
+
|
3
3
|
module Dryml
|
4
4
|
|
5
5
|
class Taglib
|
6
|
-
|
6
|
+
|
7
7
|
@cache = {}
|
8
|
-
|
8
|
+
|
9
9
|
class << self
|
10
|
-
|
10
|
+
|
11
11
|
def get(options)
|
12
|
-
|
12
|
+
cache_key = options.inspect
|
13
|
+
taglib = @cache[cache_key]
|
13
14
|
if taglib
|
14
15
|
taglib.reload
|
15
16
|
else
|
16
17
|
src_file = taglib_filename(options)
|
17
18
|
bundle = options[:bundle] && Bundle.bundles[options[:bundle]]
|
18
|
-
|
19
|
+
|
19
20
|
taglib = Taglib.new(src_file, bundle)
|
20
|
-
@cache[
|
21
|
+
@cache[cache_key] = taglib
|
21
22
|
end
|
22
23
|
taglib
|
23
24
|
end
|
24
|
-
|
25
|
+
|
25
26
|
def clear_cache
|
26
27
|
@cache = {}
|
27
28
|
end
|
28
|
-
|
29
|
+
|
29
30
|
private
|
30
|
-
|
31
|
+
|
31
32
|
def taglib_filename(options)
|
32
|
-
|
33
|
-
|
33
|
+
plugin = options[:plugin]
|
34
|
+
base = if plugin == "hobo"
|
35
|
+
"#{HOBO_ROOT}/taglibs"
|
36
|
+
elsif plugin
|
37
|
+
"#{RAILS_ROOT}/vendor/plugins/#{plugin}/taglibs"
|
34
38
|
elsif (bundle_name = options[:bundle])
|
35
|
-
bundle = Bundle.bundles[bundle_name]
|
36
|
-
"vendor/plugins/#{bundle.plugin}/taglibs"
|
39
|
+
bundle = Bundle.bundles[bundle_name] or raise ArgumentError, "No such bundle: #{options[:bundle]}"
|
40
|
+
"#{RAILS_ROOT}/vendor/plugins/#{bundle.plugin}/taglibs"
|
37
41
|
elsif options[:src] =~ /\//
|
38
|
-
"app/views"
|
42
|
+
"#{RAILS_ROOT}/app/views"
|
43
|
+
elsif options[:template_dir] =~ /^#{HOBO_ROOT}/
|
44
|
+
options[:template_dir]
|
39
45
|
else
|
40
|
-
options[:template_dir].gsub(/^\//, "
|
46
|
+
"#{RAILS_ROOT}/#{options[:template_dir].gsub(/^\//, '')}" # remove leading / if there is one
|
41
47
|
end
|
42
|
-
|
43
|
-
filename = "#{
|
44
|
-
raise DrymlException, "No such taglib: #{options.inspect} #{filename}" unless File.exists?(filename)
|
48
|
+
|
49
|
+
filename = "#{base}/#{options[:src]}.dryml"
|
50
|
+
raise DrymlException, "No such taglib: #{base} #{options.inspect} #{filename}" unless File.exists?(filename)
|
45
51
|
filename
|
46
52
|
end
|
47
|
-
|
53
|
+
|
48
54
|
end
|
49
|
-
|
55
|
+
|
50
56
|
def initialize(src_file, bundle)
|
51
57
|
@src_file = src_file
|
52
58
|
@bundle = bundle
|
53
59
|
load
|
54
60
|
end
|
55
|
-
|
61
|
+
|
56
62
|
def reload
|
57
63
|
load if File.mtime(@src_file) > @last_load_time
|
58
64
|
end
|
59
|
-
|
65
|
+
|
60
66
|
def load
|
61
67
|
@module = Module.new do
|
62
|
-
|
68
|
+
|
63
69
|
@tag_attrs = {}
|
64
70
|
@tag_aliases = {}
|
65
|
-
|
71
|
+
|
66
72
|
class << self
|
67
|
-
|
73
|
+
|
68
74
|
def included(base)
|
69
75
|
@tag_aliases.each do |tag, feature|
|
70
76
|
base.send(:alias_method_chain, tag, feature)
|
71
77
|
end
|
72
78
|
end
|
73
|
-
|
79
|
+
|
74
80
|
def _register_tag_attrs(tag, attrs)
|
75
81
|
@tag_attrs[tag] = attrs
|
76
82
|
end
|
77
83
|
attr_reader :tag_attrs
|
78
|
-
|
79
|
-
def
|
84
|
+
|
85
|
+
def alias_method_chain_on_include(tag, feature)
|
80
86
|
@tag_aliases[tag] = feature
|
81
87
|
end
|
82
|
-
|
88
|
+
|
83
89
|
end
|
84
|
-
|
90
|
+
|
85
91
|
end
|
86
92
|
template = Template.new(File.read(@src_file), @module, @src_file, @bundle)
|
87
93
|
template.compile([], [])
|
88
94
|
@last_load_time = File.mtime(@src_file)
|
89
95
|
end
|
90
|
-
|
96
|
+
|
91
97
|
def import_into(class_or_module, as)
|
92
98
|
if as
|
93
99
|
# Define a method on class_or_module named whatever 'as'
|
@@ -95,10 +101,10 @@ module Hobo
|
|
95
101
|
# returns an object that provides the taglib's tags as
|
96
102
|
# methods. On subsequent calls the object is cached in an
|
97
103
|
# instance variable "@_#{as}_taglib"
|
98
|
-
|
104
|
+
|
99
105
|
taglib_module = @module
|
100
106
|
ivar = "@_#{as}_taglib"
|
101
|
-
class_or_module.send(:define_method, as) do
|
107
|
+
class_or_module.send(:define_method, as) do
|
102
108
|
instance_variable_get(ivar) or begin
|
103
109
|
as_class = Class.new(TemplateEnvironment) { include taglib_module }
|
104
110
|
as_object = as_class.new
|
@@ -111,9 +117,9 @@ module Hobo
|
|
111
117
|
class_or_module.tag_attrs.update(@module.tag_attrs) if @module.respond_to?(:tag_attrs)
|
112
118
|
end
|
113
119
|
end
|
114
|
-
|
120
|
+
|
115
121
|
end
|
116
|
-
|
122
|
+
|
117
123
|
end
|
118
|
-
|
124
|
+
|
119
125
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'rexml/document'
|
2
|
+
require 'pathname'
|
2
3
|
|
3
4
|
module Hobo::Dryml
|
4
5
|
|
@@ -9,21 +10,21 @@ module Hobo::Dryml
|
|
9
10
|
|
10
11
|
RUBY_NAME = "[a-zA-Z_][a-zA-Z0-9_]*"
|
11
12
|
RUBY_NAME_RX = /^#{RUBY_NAME}$/
|
12
|
-
|
13
|
+
|
13
14
|
CODE_ATTRIBUTE_CHAR = "&"
|
14
|
-
|
15
|
+
|
15
16
|
NO_METADATA_TAGS = %w(doctype if else unless repeat do with name type-name)
|
16
|
-
|
17
|
-
SPECIAL_ATTRIBUTES = %w(param merge merge-params merge-attrs
|
18
|
-
for-type
|
19
|
-
if unless repeat
|
17
|
+
|
18
|
+
SPECIAL_ATTRIBUTES = %w(param merge merge-params merge-attrs
|
19
|
+
for-type
|
20
|
+
if unless repeat
|
20
21
|
part part-locals
|
21
22
|
restore)
|
22
|
-
|
23
|
+
|
23
24
|
VALID_PARAMETER_TAG_ATTRIBUTES = %w(param replace)
|
24
25
|
|
25
26
|
@build_cache = {}
|
26
|
-
|
27
|
+
|
27
28
|
class << self
|
28
29
|
attr_reader :build_cache
|
29
30
|
|
@@ -35,7 +36,7 @@ module Hobo::Dryml
|
|
35
36
|
def initialize(src, environment, template_path, bundle=nil)
|
36
37
|
@src = src
|
37
38
|
@environment = environment # a class or a module
|
38
|
-
@template_path = template_path.sub(
|
39
|
+
@template_path = template_path.sub(%r(^#{Regexp.escape(RAILS_ROOT)}/), "")
|
39
40
|
@bundle = bundle
|
40
41
|
|
41
42
|
@builder = Template.build_cache[@template_path] || DRYMLBuilder.new(self)
|
@@ -45,49 +46,49 @@ module Hobo::Dryml
|
|
45
46
|
end
|
46
47
|
|
47
48
|
attr_reader :tags, :template_path, :bundle
|
48
|
-
|
49
|
+
|
49
50
|
def compile(local_names=[], auto_taglibs=[])
|
50
51
|
now = Time.now
|
51
52
|
|
52
53
|
unless @template_path.ends_with?(EMPTY_PAGE)
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
54
|
+
p = Pathname.new template_path
|
55
|
+
p = Pathname.new(RAILS_ROOT) + p unless p.absolute?
|
56
|
+
mtime = p.mtime
|
57
|
+
|
58
|
+
if !@builder.ready?(mtime)
|
59
|
+
@builder.start
|
60
|
+
parsed = true
|
61
|
+
# parse the DRYML file creating a list of build instructions
|
62
|
+
if is_taglib?
|
63
|
+
process_src
|
64
|
+
else
|
65
|
+
create_render_page_method
|
66
|
+
end
|
66
67
|
|
67
|
-
|
68
|
-
|
68
|
+
# store build instructions in the cache
|
69
|
+
Template.build_cache[@template_path] = @builder
|
70
|
+
end
|
69
71
|
end
|
70
|
-
|
72
|
+
|
71
73
|
# compile the build instructions
|
72
74
|
@builder.build(local_names, auto_taglibs, mtime)
|
73
75
|
|
74
|
-
|
75
|
-
logger.info(" DRYML: Compiled#{from_cache} #{template_path} in %.2fs" % (Time.now - now))
|
76
|
+
logger.info(" DRYML: Compiled #{template_path} in %.2fs" % (Time.now - now)) if parsed
|
76
77
|
end
|
77
|
-
|
78
|
+
|
78
79
|
|
79
80
|
def create_render_page_method
|
80
81
|
erb_src = process_src
|
81
|
-
|
82
|
+
|
82
83
|
@builder.add_build_instruction(:render_page, :src => erb_src, :line_num => 1)
|
83
84
|
end
|
84
85
|
|
85
|
-
|
86
|
+
|
86
87
|
def is_taglib?
|
87
88
|
@environment.class == Module
|
88
89
|
end
|
89
90
|
|
90
|
-
|
91
|
+
|
91
92
|
def process_src
|
92
93
|
@doc = Hobo::Dryml::Parser::Document.new(@src, @template_path)
|
93
94
|
result = children_to_erb(@doc.root)
|
@@ -99,11 +100,11 @@ module Hobo::Dryml
|
|
99
100
|
@doc.restore_erb_scriptlets(src)
|
100
101
|
end
|
101
102
|
|
102
|
-
|
103
|
+
|
103
104
|
def children_to_erb(nodes)
|
104
105
|
nodes.map{|x| node_to_erb(x)}.join
|
105
106
|
end
|
106
|
-
|
107
|
+
|
107
108
|
|
108
109
|
def node_to_erb(node)
|
109
110
|
case node
|
@@ -111,7 +112,7 @@ module Hobo::Dryml
|
|
111
112
|
# v important this comes before REXML::Text, as REXML::CData < REXML::Text
|
112
113
|
when REXML::CData
|
113
114
|
REXML::CData::START + node.to_s + REXML::CData::STOP
|
114
|
-
|
115
|
+
|
115
116
|
when REXML::Comment
|
116
117
|
REXML::Comment::START + node.to_s + REXML::Comment::STOP
|
117
118
|
|
@@ -127,8 +128,8 @@ module Hobo::Dryml
|
|
127
128
|
def strip_suppressed_whiteaspace(s)
|
128
129
|
s # s.gsub(/ -(\s*\n\s*)/, '<% \1 %>')
|
129
130
|
end
|
130
|
-
|
131
|
-
|
131
|
+
|
132
|
+
|
132
133
|
def element_to_erb(el)
|
133
134
|
dryml_exception("old-style parameter tag (<#{el.name}>)", el) if el.name.starts_with?(":")
|
134
135
|
|
@@ -140,7 +141,7 @@ module Hobo::Dryml
|
|
140
141
|
# return just the newlines to keep line-number matching - the
|
141
142
|
# include has no presence in the erb source
|
142
143
|
tag_newlines(el)
|
143
|
-
|
144
|
+
|
144
145
|
when "set-theme"
|
145
146
|
require_attribute(el, "name", /^#{DRYML_NAME}$/)
|
146
147
|
@builder.add_build_instruction(:set_theme, :name => el.attributes['name'])
|
@@ -150,16 +151,19 @@ module Hobo::Dryml
|
|
150
151
|
|
151
152
|
when "def"
|
152
153
|
def_element(el)
|
153
|
-
|
154
|
+
|
155
|
+
when "extend"
|
156
|
+
extend_element(el)
|
157
|
+
|
154
158
|
when "set"
|
155
159
|
set_element(el)
|
156
|
-
|
160
|
+
|
157
161
|
when "set-scoped"
|
158
162
|
set_scoped_element(el)
|
159
|
-
|
163
|
+
|
160
164
|
when "param-content"
|
161
165
|
param_content_element(el)
|
162
|
-
|
166
|
+
|
163
167
|
else
|
164
168
|
if el.dryml_name.not_in?(Hobo.static_tags) || el.attributes['param'] || el.attributes['restore']
|
165
169
|
tag_call(el)
|
@@ -179,7 +183,7 @@ module Hobo::Dryml
|
|
179
183
|
end
|
180
184
|
@builder.add_build_instruction(:include, options)
|
181
185
|
end
|
182
|
-
|
186
|
+
|
183
187
|
|
184
188
|
def import_module(mod, as=nil)
|
185
189
|
@builder.import_module(mod, as)
|
@@ -188,23 +192,24 @@ module Hobo::Dryml
|
|
188
192
|
|
189
193
|
def set_element(el)
|
190
194
|
assigns = el.attributes.map do |name, value|
|
195
|
+
next if name.in?(SPECIAL_ATTRIBUTES)
|
191
196
|
dryml_exception("invalid name in <set>", el) unless name =~ /^#{DRYML_NAME}(\.#{DRYML_NAME})*$/
|
192
197
|
"#{ruby_name name} = #{attribute_to_ruby(value)}; "
|
193
198
|
end.join
|
194
199
|
code = apply_control_attributes("begin; #{assigns}; end", el)
|
195
|
-
"<% #{
|
200
|
+
"<% #{code}#{tag_newlines(el)} %>"
|
196
201
|
end
|
197
|
-
|
198
|
-
|
202
|
+
|
203
|
+
|
199
204
|
def set_scoped_element(el)
|
200
|
-
|
205
|
+
variables = el.attributes.map do |name, value|
|
201
206
|
dryml_exception("invalid name in <set-scoped>", el) unless name =~ DRYML_NAME_RX
|
202
|
-
"
|
203
|
-
end
|
204
|
-
"<% scope.new_scope { #{
|
207
|
+
":#{ruby_name name} => #{attribute_to_ruby(value)} "
|
208
|
+
end
|
209
|
+
"<% scope.new_scope(#{variables * ', '}) { #{tag_newlines(el)} %>#{children_to_erb(el)}<% } %>"
|
205
210
|
end
|
206
|
-
|
207
|
-
|
211
|
+
|
212
|
+
|
208
213
|
def declared_attributes(def_element)
|
209
214
|
attrspec = def_element.attributes["attrs"]
|
210
215
|
attr_names = attrspec ? attrspec.split(/\s*,\s*/).map{ |n| n.underscore.to_sym } : []
|
@@ -212,13 +217,13 @@ module Hobo::Dryml
|
|
212
217
|
dryml_exception("invalid attrs in def: #{invalids * ', '}", def_element) unless invalids.empty?
|
213
218
|
attr_names
|
214
219
|
end
|
215
|
-
|
216
|
-
|
220
|
+
|
221
|
+
|
217
222
|
def ruby_name(dryml_name)
|
218
223
|
dryml_name.gsub('-', '_')
|
219
224
|
end
|
220
|
-
|
221
|
-
|
225
|
+
|
226
|
+
|
222
227
|
def with_containing_tag_name(el)
|
223
228
|
old = @containing_tag_name
|
224
229
|
@containing_tag_name = el.dryml_name
|
@@ -227,57 +232,86 @@ module Hobo::Dryml
|
|
227
232
|
end
|
228
233
|
|
229
234
|
|
230
|
-
def
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
235
|
+
def define_polymorphic_dispatcher(el, name)
|
236
|
+
# FIXME: The new erb context ends up being set-up twice
|
237
|
+
src = %(
|
238
|
+
def #{name}(attributes={}, parameters={})
|
239
|
+
_tag_context(attributes) do
|
240
|
+
attributes.delete :with
|
241
|
+
attributes.delete :field
|
242
|
+
call_polymorphic_tag('#{name}', attributes, parameters) { #{name}__base(attributes.except, parameters) }
|
243
|
+
end
|
244
|
+
end
|
245
|
+
)
|
246
|
+
@builder.add_build_instruction(:eval, :src => src, :line_num => element_line_num(el))
|
247
|
+
end
|
248
|
+
|
249
|
+
|
250
|
+
def extend_element(el)
|
251
|
+
def_element(el, true)
|
252
|
+
end
|
253
|
+
|
254
|
+
|
255
|
+
def type_specific_suffix
|
256
|
+
el = @def_element
|
257
|
+
for_type = el.attributes['for']
|
258
|
+
if for_type
|
240
259
|
type_name = if defined?(HoboFields) && for_type =~ /^[a-z]/
|
241
260
|
# It's a symbolic type name - look up the Ruby type name
|
242
|
-
klass = HoboFields.to_class(for_type)
|
243
|
-
|
261
|
+
klass = HoboFields.to_class(for_type) or
|
262
|
+
dryml_exception("No such type in polymorphic tag definition: '#{for_type}'", el)
|
244
263
|
klass.name
|
245
264
|
elsif for_type =~ /^_.*_$/
|
246
265
|
rename_class(for_type)
|
247
266
|
else
|
248
267
|
for_type
|
249
268
|
end.underscore.gsub('/', '__')
|
250
|
-
|
269
|
+
"__for_#{type_name}"
|
270
|
+
end
|
271
|
+
end
|
272
|
+
|
273
|
+
|
274
|
+
def def_element(el, extend_tag=false)
|
275
|
+
require_toplevel(el)
|
276
|
+
require_attribute(el, "tag", DRYML_NAME_RX)
|
277
|
+
require_attribute(el, "attrs", /^\s*#{DRYML_NAME}(\s*,\s*#{DRYML_NAME})*\s*$/, true)
|
278
|
+
require_attribute(el, "alias-of", DRYML_NAME_RX, true)
|
279
|
+
|
280
|
+
@def_element = el
|
281
|
+
|
282
|
+
unsafe_name = el.attributes["tag"]
|
283
|
+
name = Hobo::Dryml.unreserve(unsafe_name)
|
284
|
+
suffix = type_specific_suffix
|
285
|
+
if suffix
|
251
286
|
name += suffix
|
252
287
|
unsafe_name += suffix
|
253
288
|
end
|
254
289
|
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
290
|
+
if el.attributes['polymorphic']
|
291
|
+
%w(for alias-of).each do |attr|
|
292
|
+
dryml_exception("def cannot have both 'polymorphic' and '#{attr}' attributes") if el.attributes[attr]
|
293
|
+
end
|
294
|
+
|
295
|
+
define_polymorphic_dispatcher(el, ruby_name(name))
|
296
|
+
name += "__base"
|
297
|
+
unsafe_name += "__base"
|
298
|
+
end
|
259
299
|
|
260
|
-
|
300
|
+
alias_of = el.attributes['alias-of']
|
261
301
|
dryml_exception("def with alias-of must be empty", el) if alias_of and el.size > 0
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
302
|
+
|
303
|
+
alias_of and @builder.add_build_instruction(:alias_method,
|
304
|
+
:new => ruby_name(name).to_sym,
|
305
|
+
:old => ruby_name(Hobo::Dryml.unreserve(alias_of)).to_sym)
|
306
|
+
|
268
307
|
res = if alias_of
|
269
308
|
"<% #{tag_newlines(el)} %>"
|
270
309
|
else
|
271
|
-
src =
|
272
|
-
if extend_with
|
273
|
-
src << "<% delayed_alias_method_chain :#{ruby_name name}, :#{ruby_name extend_with} %>"
|
274
|
-
name = "#{name}-with-#{extend_with}"
|
275
|
-
end
|
276
|
-
src << tag_method(name, el) +
|
310
|
+
src = tag_method(name, el, extend_tag) +
|
277
311
|
"<% _register_tag_attrs(:#{ruby_name name}, #{declared_attributes(el).inspect.underscore}) %>"
|
278
|
-
|
312
|
+
|
279
313
|
logger.debug(restore_erb_scriptlets(src)) if el.attributes["debug-source"]
|
280
|
-
|
314
|
+
|
281
315
|
@builder.add_build_instruction(:def,
|
282
316
|
:src => restore_erb_scriptlets(src),
|
283
317
|
:line_num => element_line_num(el))
|
@@ -287,47 +321,56 @@ module Hobo::Dryml
|
|
287
321
|
@def_element = nil
|
288
322
|
res
|
289
323
|
end
|
290
|
-
|
291
|
-
|
324
|
+
|
325
|
+
|
292
326
|
def param_names_in_definition(el)
|
293
327
|
REXML::XPath.match(el, ".//*[@param]").map do |e|
|
294
328
|
name = get_param_name(e)
|
295
|
-
dryml_exception("invalid param name: #{name.inspect}", e) unless
|
329
|
+
dryml_exception("invalid param name: #{name.inspect}", e) unless
|
296
330
|
is_code_attribute?(name) || name =~ RUBY_NAME_RX || name =~ /#\{/
|
297
331
|
name.to_sym unless is_code_attribute?(name)
|
298
332
|
end.compact
|
299
333
|
end
|
300
|
-
|
301
|
-
|
302
|
-
def tag_method(name, el)
|
334
|
+
|
335
|
+
|
336
|
+
def tag_method(name, el, extend_tag=false)
|
337
|
+
name = ruby_name name
|
303
338
|
param_names = param_names_in_definition(el)
|
304
339
|
|
305
|
-
|
340
|
+
if extend_tag
|
341
|
+
@extend_key = 'a' + Digest::SHA1.hexdigest(el.to_s)[0..10]
|
342
|
+
alias_statement = "; alias_method_chain_on_include :#{name}, :#{@extend_key}"
|
343
|
+
name = "#{name}_with_#{@extend_key}"
|
344
|
+
end
|
345
|
+
|
346
|
+
src = "<% def #{name}(all_attributes={}, all_parameters={}); " +
|
306
347
|
"parameters = Hobo::Dryml::TagParameters.new(all_parameters, #{param_names.inspect.underscore}); " +
|
307
348
|
"all_parameters = Hobo::Dryml::TagParameters.new(all_parameters); " +
|
308
349
|
tag_method_body(el) +
|
309
|
-
"; end %>"
|
350
|
+
"; end#{alias_statement} %>"
|
351
|
+
@extend_key = nil
|
352
|
+
src
|
310
353
|
end
|
311
|
-
|
312
|
-
|
354
|
+
|
355
|
+
|
313
356
|
def tag_method_body(el)
|
314
357
|
attrs = declared_attributes(el)
|
315
|
-
|
358
|
+
|
316
359
|
# A statement to assign values to local variables named after the tag's attrs
|
317
360
|
# The trailing comma on `attributes` is supposed to be there!
|
318
361
|
setup_locals = attrs.map{|a| "#{Hobo::Dryml.unreserve(a).underscore}, "}.join + "attributes, = " +
|
319
362
|
"_tag_locals(all_attributes, #{attrs.inspect})"
|
320
363
|
|
321
364
|
start = "_tag_context(all_attributes) do #{setup_locals}"
|
322
|
-
|
365
|
+
|
323
366
|
"#{start} " +
|
324
367
|
# reproduce any line breaks in the start-tag so that line numbers are preserved
|
325
368
|
tag_newlines(el) + "%>" +
|
326
369
|
wrap_tag_method_body_with_metadata(children_to_erb(el)) +
|
327
370
|
"<% _erbout; end"
|
328
371
|
end
|
329
|
-
|
330
|
-
|
372
|
+
|
373
|
+
|
331
374
|
def wrap_source_with_metadata(content, kind, name, *args)
|
332
375
|
if (!include_source_metadata) || name.in?(NO_METADATA_TAGS)
|
333
376
|
content
|
@@ -336,32 +379,35 @@ module Hobo::Dryml
|
|
336
379
|
"<!--[DRYML|#{metadata * '|'}[-->" + content + "<!--]DRYML]-->"
|
337
380
|
end
|
338
381
|
end
|
339
|
-
|
340
|
-
|
382
|
+
|
383
|
+
|
341
384
|
def wrap_tag_method_body_with_metadata(content)
|
342
385
|
name = @def_element.attributes['tag']
|
343
|
-
extend = @def_element.attributes['extend-with']
|
344
386
|
for_ = @def_element.attributes['for']
|
345
|
-
name = extend ? "#{name}-with-#{extend}" : name
|
346
387
|
name += " for #{for_}" if for_
|
347
388
|
wrap_source_with_metadata(content, "def", name, element_line_num(@def_element))
|
348
389
|
end
|
349
|
-
|
350
|
-
|
390
|
+
|
391
|
+
|
351
392
|
def wrap_tag_call_with_metadata(el, content)
|
352
393
|
name = el.expanded_name
|
353
394
|
param = el.attributes['param']
|
354
|
-
|
395
|
+
|
355
396
|
if param == "&true"
|
356
397
|
name += " param"
|
357
398
|
elsif param
|
358
|
-
name += " param='#{param}'"
|
399
|
+
name += " param='#{param}'"
|
359
400
|
end
|
360
|
-
|
401
|
+
|
361
402
|
wrap_source_with_metadata(content, "call", name, element_line_num(el))
|
362
403
|
end
|
363
|
-
|
364
|
-
|
404
|
+
|
405
|
+
|
406
|
+
def param_content_local_name(name)
|
407
|
+
"_#{ruby_name name}__default_content"
|
408
|
+
end
|
409
|
+
|
410
|
+
|
365
411
|
def param_content_element(name_or_el)
|
366
412
|
name = if name_or_el.is_a?(String)
|
367
413
|
name_or_el
|
@@ -376,7 +422,7 @@ module Hobo::Dryml
|
|
376
422
|
|
377
423
|
def part_element(el, content)
|
378
424
|
require_attribute(el, "part", DRYML_NAME_RX)
|
379
|
-
|
425
|
+
|
380
426
|
if contains_param?(el)
|
381
427
|
delegated_part_element(el, content)
|
382
428
|
else
|
@@ -384,13 +430,13 @@ module Hobo::Dryml
|
|
384
430
|
end
|
385
431
|
end
|
386
432
|
|
387
|
-
|
433
|
+
|
388
434
|
def simple_part_element(el, content)
|
389
435
|
part_name = el.attributes['part']
|
390
436
|
dom_id = el.attributes['id'] || part_name
|
391
437
|
part_name = ruby_name(part_name)
|
392
438
|
part_locals = el.attributes["part-locals"]
|
393
|
-
|
439
|
+
|
394
440
|
part_src = "<% def #{part_name}_part(#{part_locals._?.gsub('@', '')}) #{tag_newlines(el)}; new_context do %>" +
|
395
441
|
content +
|
396
442
|
"<% end; end %>"
|
@@ -400,31 +446,36 @@ module Hobo::Dryml
|
|
400
446
|
args = [attribute_to_ruby(dom_id), ":#{part_name}", "nil", part_locals].compact
|
401
447
|
"<%= call_part(#{args * ', '}) #{newlines} %>"
|
402
448
|
end
|
403
|
-
|
404
|
-
|
449
|
+
|
450
|
+
|
405
451
|
def delegated_part_element(el, content)
|
406
|
-
# TODO
|
452
|
+
# TODO
|
407
453
|
end
|
408
|
-
|
409
|
-
|
454
|
+
|
455
|
+
|
410
456
|
def contains_param?(el)
|
411
457
|
# TODO
|
412
458
|
false
|
413
459
|
end
|
414
|
-
|
415
|
-
|
460
|
+
|
461
|
+
|
416
462
|
def part_delegate_tag_name(el)
|
417
463
|
"#{@def_name}_#{el.attributes['part']}__part_delegate"
|
418
464
|
end
|
419
465
|
|
420
466
|
|
467
|
+
def current_def_name
|
468
|
+
@def_element && @def_element.attributes['tag']
|
469
|
+
end
|
470
|
+
|
471
|
+
|
421
472
|
def get_param_name(el)
|
422
473
|
param_name = el.attributes["param"]
|
423
|
-
|
474
|
+
|
424
475
|
if param_name
|
425
|
-
def_tag = find_ancestor(el) {|e| e.name == "def"}
|
476
|
+
def_tag = find_ancestor(el) {|e| e.name == "def" || e.name == "extend" }
|
426
477
|
dryml_exception("param is not allowed outside of tag definitions", el) if def_tag.nil?
|
427
|
-
|
478
|
+
|
428
479
|
ruby_name(param_name == "&true" ? el.dryml_name : param_name)
|
429
480
|
else
|
430
481
|
nil
|
@@ -432,12 +483,37 @@ module Hobo::Dryml
|
|
432
483
|
end
|
433
484
|
|
434
485
|
|
486
|
+
def inside_def_for_type?
|
487
|
+
@def_element && @def_element.attributes['for']
|
488
|
+
end
|
489
|
+
|
490
|
+
|
435
491
|
def call_name(el)
|
436
492
|
dryml_exception("invalid tag name", el) unless el.dryml_name =~ /^#{DRYML_NAME}(\.#{DRYML_NAME})*$/
|
437
|
-
|
493
|
+
|
494
|
+
name = Hobo::Dryml.unreserve(ruby_name(el.dryml_name))
|
495
|
+
if call_to_self_from_type_specific_def?(el)
|
496
|
+
"#{name}__base"
|
497
|
+
elsif old_tag_call?(el)
|
498
|
+
name = name[4..-1] # remove 'old-' prefix
|
499
|
+
name += type_specific_suffix if inside_def_for_type?
|
500
|
+
"#{name}_without_#{@extend_key}"
|
501
|
+
else
|
502
|
+
name
|
503
|
+
end
|
504
|
+
end
|
505
|
+
|
506
|
+
|
507
|
+
def old_tag_call?(el)
|
508
|
+
@def_element && el.dryml_name == "old-#{current_def_name}"
|
509
|
+
end
|
510
|
+
|
511
|
+
|
512
|
+
def call_to_self_from_type_specific_def?(el)
|
513
|
+
inside_def_for_type? && el.dryml_name == current_def_name &&!el.attributes['for-type']
|
438
514
|
end
|
515
|
+
|
439
516
|
|
440
|
-
|
441
517
|
def polymorphic_call_type(el)
|
442
518
|
t = el.attributes['for-type']
|
443
519
|
if t.nil?
|
@@ -454,18 +530,18 @@ module Hobo::Dryml
|
|
454
530
|
dryml_exception("invalid for-type attribute", el)
|
455
531
|
end
|
456
532
|
end
|
457
|
-
|
458
|
-
|
533
|
+
|
534
|
+
|
459
535
|
def tag_call(el)
|
460
536
|
name = call_name(el)
|
461
537
|
param_name = get_param_name(el)
|
462
538
|
attributes = tag_attributes(el)
|
463
539
|
newlines = tag_newlines(el)
|
464
|
-
|
540
|
+
|
465
541
|
parameters = tag_newlines(el) + parameter_tags_hash(el)
|
466
|
-
|
542
|
+
|
467
543
|
is_param_restore = el.attributes['restore']
|
468
|
-
|
544
|
+
|
469
545
|
call = if param_name
|
470
546
|
param_name = attribute_to_ruby(param_name, :symbolize => true)
|
471
547
|
args = "#{attributes}, #{parameters}, all_parameters, #{param_name}"
|
@@ -502,18 +578,18 @@ module Hobo::Dryml
|
|
502
578
|
call = maybe_make_part_call(el, "<% _output(#{call}) %>")
|
503
579
|
wrap_tag_call_with_metadata(el, call)
|
504
580
|
end
|
505
|
-
|
506
|
-
|
581
|
+
|
582
|
+
|
507
583
|
def merge_attribute(el)
|
508
584
|
merge = el.attributes['merge']
|
509
585
|
dryml_exception("merge cannot have a RHS", el) if merge && merge != "&true"
|
510
586
|
merge
|
511
587
|
end
|
512
|
-
|
588
|
+
|
513
589
|
|
514
590
|
def parameter_tags_hash(el, containing_tag_name=nil)
|
515
591
|
call_type = nil
|
516
|
-
|
592
|
+
|
517
593
|
metadata_name = containing_tag_name || el.expanded_name
|
518
594
|
|
519
595
|
param_items = el.map do |node|
|
@@ -528,7 +604,7 @@ module Hobo::Dryml
|
|
528
604
|
when REXML::Element
|
529
605
|
e = node
|
530
606
|
is_parameter_tag = e.parameter_tag?
|
531
|
-
|
607
|
+
|
532
608
|
# Make sure there isn't a mix of parameter tags and normal content
|
533
609
|
case call_type
|
534
610
|
when nil
|
@@ -538,19 +614,21 @@ module Hobo::Dryml
|
|
538
614
|
when :default_param_only
|
539
615
|
dryml_exception("mixed parameter tags and non-parameter tags", el) if is_parameter_tag
|
540
616
|
end
|
541
|
-
|
617
|
+
|
542
618
|
if is_parameter_tag
|
543
619
|
parameter_tag_hash_item(e, metadata_name) + ", "
|
544
620
|
end
|
545
621
|
end
|
546
622
|
end.join
|
547
|
-
|
548
|
-
if call_type == :default_param_only || (el.children.empty? && el.has_end_tag?)
|
623
|
+
|
624
|
+
if call_type == :default_param_only || (call_type.nil? && param_items.length > 0) || (el.children.empty? && el.has_end_tag?)
|
549
625
|
with_containing_tag_name(el) do
|
550
626
|
param_items = " :default => #{default_param_proc(el, containing_tag_name)}, "
|
551
627
|
end
|
552
628
|
end
|
553
629
|
|
630
|
+
param_items.concat without_parameters(el)
|
631
|
+
|
554
632
|
merge_params = el.attributes['merge-params'] || merge_attribute(el)
|
555
633
|
if merge_params
|
556
634
|
extra_params = if merge_params == "&true"
|
@@ -567,6 +645,12 @@ module Hobo::Dryml
|
|
567
645
|
end
|
568
646
|
end
|
569
647
|
|
648
|
+
|
649
|
+
def without_parameters(el)
|
650
|
+
without_names = el.attributes.keys.map { |name| name =~ /^without-(.*)/ and $1 }.compact
|
651
|
+
without_names.map { |name| ":#{ruby_name name}_replacement => proc {|__discard__| '' }, " }.join
|
652
|
+
end
|
653
|
+
|
570
654
|
|
571
655
|
def parameter_tag_hash_item(el, metadata_name)
|
572
656
|
name = el.name.dup
|
@@ -588,8 +672,8 @@ module Hobo::Dryml
|
|
588
672
|
end
|
589
673
|
end
|
590
674
|
end
|
591
|
-
|
592
|
-
|
675
|
+
|
676
|
+
|
593
677
|
def before_parameter_tag_hash_item(name, el, metadata_name)
|
594
678
|
param_name = get_param_name(el)
|
595
679
|
dryml_exception("param declaration not allowed on 'before' parameters", el) if param_name
|
@@ -597,59 +681,63 @@ module Hobo::Dryml
|
|
597
681
|
":#{ruby_name name}_replacement => #{replace_parameter_proc(el, metadata_name, content)}"
|
598
682
|
end
|
599
683
|
|
600
|
-
|
684
|
+
|
601
685
|
def after_parameter_tag_hash_item(name, el, metadata_name)
|
602
686
|
param_name = get_param_name(el)
|
603
687
|
dryml_exception("param declaration not allowed on 'after' parameters", el) if param_name
|
604
|
-
content = "<% _output(#{param_restore_local_name(name)}.call({}, {})) %>" + children_to_erb(el)
|
688
|
+
content = "<% _output(#{param_restore_local_name(name)}.call({}, {})) %>" + children_to_erb(el)
|
605
689
|
":#{ruby_name name}_replacement => #{replace_parameter_proc(el, metadata_name, content)}"
|
606
690
|
end
|
607
|
-
|
608
|
-
|
691
|
+
|
692
|
+
|
609
693
|
def append_parameter_tag_hash_item(name, el, metadata_name)
|
610
|
-
":#{ruby_name name} => proc { [{}, { :default => proc { |#{param_content_local_name(name)}| new_context { %>" +
|
694
|
+
":#{ruby_name name} => proc { [{}, { :default => proc { |#{param_content_local_name(name)}| new_context { %>" +
|
611
695
|
param_content_element(name) + children_to_erb(el) +
|
612
696
|
"<% } } } ] }"
|
613
697
|
end
|
614
|
-
|
615
|
-
|
698
|
+
|
699
|
+
|
616
700
|
def prepend_parameter_tag_hash_item(name, el, metadata_name)
|
617
|
-
":#{ruby_name name} => proc { [{}, { :default => proc { |#{param_content_local_name(name)}| new_context { %>" +
|
701
|
+
":#{ruby_name name} => proc { [{}, { :default => proc { |#{param_content_local_name(name)}| new_context { %>" +
|
618
702
|
children_to_erb(el) + param_content_element(name) +
|
619
703
|
"<% } } } ] }"
|
620
704
|
end
|
621
705
|
|
622
|
-
|
706
|
+
|
623
707
|
def default_param_proc(el, containing_param_name=nil)
|
624
708
|
content = children_to_erb(el)
|
625
709
|
content = wrap_source_with_metadata(content, "param", containing_param_name,
|
626
710
|
element_line_num(el)) if containing_param_name
|
627
711
|
"proc { |#{param_content_local_name(el.dryml_name)}| new_context { %>#{content}<% } #{tag_newlines(el)}}"
|
628
712
|
end
|
629
|
-
|
630
|
-
|
713
|
+
|
714
|
+
|
631
715
|
def param_restore_local_name(name)
|
632
716
|
"_#{ruby_name name}_restore"
|
633
717
|
end
|
634
|
-
|
635
|
-
|
718
|
+
|
719
|
+
|
636
720
|
def wrap_replace_parameter(el, name)
|
637
721
|
wrap_source_with_metadata(children_to_erb(el), "replace", name, element_line_num(el))
|
638
722
|
end
|
639
|
-
|
640
|
-
|
723
|
+
|
724
|
+
|
641
725
|
def param_proc(el, metadata_name_prefix)
|
642
726
|
metadata_name = "#{metadata_name_prefix}><#{el.name}"
|
643
|
-
|
727
|
+
|
644
728
|
nl = tag_newlines(el)
|
645
|
-
|
729
|
+
|
646
730
|
if (repl = el.attribute("replace"))
|
647
731
|
dryml_exception("replace attribute must not have a value", el) if repl.has_rhs?
|
648
732
|
dryml_exception("replace parameters must not have attributes", el) if el.attributes.length > 1
|
649
|
-
|
733
|
+
|
650
734
|
replace_parameter_proc(el, metadata_name)
|
651
735
|
else
|
652
|
-
attributes = el.attributes.
|
736
|
+
attributes = el.attributes.dup
|
737
|
+
# Providing one of 'with' or 'field' but not the other should cancel out the other
|
738
|
+
attributes[:with] = "&nil" if attributes.key?(:field) && !attributes.key?(:with)
|
739
|
+
attributes[:field] = "&nil" if !attributes.key?(:field) && attributes.key?(:with)
|
740
|
+
attribute_items = attributes.map do |name, value|
|
653
741
|
if name.in?(VALID_PARAMETER_TAG_ATTRIBUTES)
|
654
742
|
# just ignore
|
655
743
|
elsif name.in?(SPECIAL_ATTRIBUTES)
|
@@ -658,56 +746,51 @@ module Hobo::Dryml
|
|
658
746
|
":#{ruby_name name} => #{attribute_to_ruby(value, el)}"
|
659
747
|
end
|
660
748
|
end.compact
|
661
|
-
|
749
|
+
|
662
750
|
nested_parameters_hash = parameter_tags_hash(el, metadata_name)
|
663
|
-
"proc { [{#{
|
751
|
+
"proc { [{#{attribute_items * ', '}}, #{nested_parameters_hash}] #{nl}}"
|
664
752
|
end
|
665
753
|
end
|
666
|
-
|
667
|
-
|
754
|
+
|
755
|
+
|
668
756
|
def replace_parameter_proc(el, metadata_name, content=nil)
|
669
757
|
content ||= wrap_replace_parameter(el, metadata_name)
|
670
758
|
param_name = el.dryml_name.sub(/^(before|after|append|prepend)-/, "")
|
671
759
|
"proc { |#{param_restore_local_name(param_name)}| new_context { %>#{content}<% } #{tag_newlines(el)}}"
|
672
760
|
end
|
673
|
-
|
674
|
-
|
675
|
-
def param_content_local_name(name)
|
676
|
-
"_#{ruby_name name}__default_content"
|
677
|
-
end
|
678
|
-
|
679
|
-
|
761
|
+
|
762
|
+
|
680
763
|
def maybe_make_part_call(el, call)
|
681
764
|
part_name = el.attributes['part']
|
682
765
|
if part_name
|
683
766
|
part_id = part_name && "<%= #{attribute_to_ruby(el.attributes['id'] || part_name)} %>"
|
684
|
-
"<
|
767
|
+
"<div class='part-wrapper' id='#{part_id}'>" + part_element(el, call) + "</div>"
|
685
768
|
else
|
686
769
|
call
|
687
770
|
end
|
688
771
|
end
|
689
|
-
|
690
|
-
|
772
|
+
|
773
|
+
|
691
774
|
def field_shorthand_element?(el)
|
692
775
|
el.expanded_name =~ /:./
|
693
776
|
end
|
694
|
-
|
695
|
-
|
777
|
+
|
778
|
+
|
696
779
|
def tag_attributes(el)
|
697
780
|
attributes = el.attributes
|
698
781
|
items = attributes.map do |n,v|
|
699
782
|
dryml_exception("invalid attribute name '#{n}'", el) unless n =~ DRYML_NAME_RX
|
700
|
-
|
701
|
-
unless n.in?(SPECIAL_ATTRIBUTES)
|
783
|
+
|
784
|
+
unless n.in?(SPECIAL_ATTRIBUTES) || n =~ /^without-/
|
702
785
|
":#{ruby_name n} => #{attribute_to_ruby(v)}"
|
703
786
|
end
|
704
787
|
end.compact
|
705
|
-
|
788
|
+
|
706
789
|
# if there's a ':' el.name is just the part after the ':'
|
707
790
|
items << ":field => \"#{ruby_name el.name}\"" if field_shorthand_element?(el)
|
708
|
-
|
791
|
+
|
709
792
|
items = items.join(", ")
|
710
|
-
|
793
|
+
|
711
794
|
merge_attrs = attributes['merge-attrs'] || merge_attribute(el)
|
712
795
|
if merge_attrs
|
713
796
|
extra_attributes = if merge_attrs == "&true"
|
@@ -730,46 +813,46 @@ module Hobo::Dryml
|
|
730
813
|
val = restore_erb_scriptlets(v).gsub('"', '\"').gsub(/<%=(.*?)%>/, '#{\1}')
|
731
814
|
%('#{n}' => "#{val}")
|
732
815
|
end.compact
|
733
|
-
|
816
|
+
|
734
817
|
# If there's a part but no id, the id defaults to the part name
|
735
818
|
if part && !el.attributes["id"]
|
736
819
|
attrs << ":id => '#{part}'"
|
737
820
|
end
|
738
|
-
|
821
|
+
|
739
822
|
# Convert the attributes hash to a call to merge_attrs if
|
740
823
|
# there's a merge-attrs attribute
|
741
824
|
attrs = if (merge_attrs = el.attributes['merge-attrs'])
|
742
825
|
dryml_exception("merge-attrs was given a string", el) unless is_code_attribute?(merge_attrs)
|
743
|
-
|
826
|
+
|
744
827
|
"merge_attrs({#{attrs * ', '}}, " +
|
745
828
|
"((__merge_attrs__ = (#{merge_attrs[1..-1]})) == true ? attributes : __merge_attrs__))"
|
746
829
|
else
|
747
830
|
"{" + attrs.join(', ') + "}"
|
748
831
|
end
|
749
|
-
|
832
|
+
|
750
833
|
if el.children.empty?
|
751
834
|
dryml_exception("part attribute on empty static tag", el) if part
|
752
835
|
|
753
|
-
"<%= " + apply_control_attributes("element(:#{el.name}, #{attrs} #{tag_newlines(el)})", el) + " %>"
|
836
|
+
"<%= " + apply_control_attributes("element(:#{el.name}, #{attrs}, nil, true, #{!el.has_end_tag?} #{tag_newlines(el)})", el) + " %>"
|
754
837
|
else
|
755
838
|
if part
|
756
839
|
body = part_element(el, children_to_erb(el))
|
757
840
|
else
|
758
|
-
body = children_to_erb(el)
|
841
|
+
body = children_to_erb(el)
|
759
842
|
end
|
760
843
|
|
761
844
|
output_tag = "element(:#{el.name}, #{attrs}, new_context { %>#{body}<% })"
|
762
845
|
"<% _output(" + apply_control_attributes(output_tag, el) + ") %>"
|
763
846
|
end
|
764
847
|
end
|
765
|
-
|
766
|
-
|
848
|
+
|
849
|
+
|
767
850
|
def static_element_to_erb(el)
|
768
851
|
if promote_static_tag_to_method_call?(el)
|
769
852
|
static_tag_to_method_call(el)
|
770
853
|
else
|
771
854
|
start_tag_src = el.start_tag_source.gsub(REXML::CData::START, "").gsub(REXML::CData::STOP, "")
|
772
|
-
|
855
|
+
|
773
856
|
# Allow #{...} as an alternate to <%= ... %>
|
774
857
|
start_tag_src.gsub!(/=\s*('.*?'|".*?")/) do |s|
|
775
858
|
s.gsub(/#\{(.*?)\}/, '<%= \1 %>')
|
@@ -782,19 +865,19 @@ module Hobo::Dryml
|
|
782
865
|
end
|
783
866
|
end
|
784
867
|
end
|
785
|
-
|
786
|
-
|
868
|
+
|
869
|
+
|
787
870
|
def promote_static_tag_to_method_call?(el)
|
788
871
|
%w(part merge-attrs if unless repeat).any? {|x| el.attributes[x]}
|
789
872
|
end
|
790
|
-
|
791
|
-
|
873
|
+
|
874
|
+
|
792
875
|
def apply_control_attributes(expression, el)
|
793
876
|
controls = %w(if unless repeat).map_hash { |x| el.attributes[x] }.compact
|
794
|
-
|
877
|
+
|
795
878
|
dryml_exception("You can't have multiple control attributes on the same element", el) if
|
796
879
|
controls.length > 1
|
797
|
-
|
880
|
+
|
798
881
|
attr = controls.keys.first
|
799
882
|
val = controls.values.first
|
800
883
|
if val.nil?
|
@@ -805,15 +888,15 @@ module Hobo::Dryml
|
|
805
888
|
elsif is_code_attribute?(val)
|
806
889
|
"#{val[1..-1]}"
|
807
890
|
else
|
808
|
-
"this.#{val}"
|
891
|
+
attr == "repeat" ? %("#{val}") : "this.#{val}"
|
809
892
|
end
|
810
|
-
|
893
|
+
|
811
894
|
x = gensym
|
812
895
|
case attr
|
813
896
|
when "if"
|
814
897
|
"(if !(#{control}).blank?; (#{x} = #{expression}; Hobo::Dryml.last_if = true; #{x}) " +
|
815
898
|
"else (Hobo::Dryml.last_if = false; ''); end)"
|
816
|
-
when "unless"
|
899
|
+
when "unless"
|
817
900
|
"(if (#{control}).blank?; (#{x} = #{expression}; Hobo::Dryml.last_if = true; #{x}) " +
|
818
901
|
"else (Hobo::Dryml.last_if = false; ''); end)"
|
819
902
|
when "repeat"
|
@@ -821,12 +904,12 @@ module Hobo::Dryml
|
|
821
904
|
end
|
822
905
|
end
|
823
906
|
end
|
824
|
-
|
907
|
+
|
825
908
|
|
826
909
|
def attribute_to_ruby(*args)
|
827
910
|
options = args.extract_options!
|
828
911
|
attr, el = args
|
829
|
-
|
912
|
+
|
830
913
|
dryml_exception('erb scriptlet not allowed in this attribute (use #{ ... } instead)', el) if
|
831
914
|
attr.is_a?(String) && attr.index("[![HOBO-ERB")
|
832
915
|
|
@@ -845,8 +928,7 @@ module Hobo::Dryml
|
|
845
928
|
else
|
846
929
|
dryml_exception("invalid quote(s) in attribute value")
|
847
930
|
end
|
848
|
-
|
849
|
-
end
|
931
|
+
end
|
850
932
|
options[:symbolize] ? (res + ".to_sym") : res
|
851
933
|
end
|
852
934
|
end
|
@@ -895,17 +977,17 @@ module Hobo::Dryml
|
|
895
977
|
def logger
|
896
978
|
ActionController::Base.logger rescue nil
|
897
979
|
end
|
898
|
-
|
980
|
+
|
899
981
|
def gensym(name="__tmp")
|
900
982
|
@gensym_counter ||= 0
|
901
983
|
@gensym_counter += 1
|
902
984
|
"#{name}_#{@gensym_counter}"
|
903
985
|
end
|
904
|
-
|
986
|
+
|
905
987
|
def rename_class(name)
|
906
988
|
@bundle && name.starts_with?("_") ? @bundle.send(name) : name
|
907
989
|
end
|
908
|
-
|
990
|
+
|
909
991
|
def include_source_metadata
|
910
992
|
# disabled for now -- we're still getting broken rendering with this feature on
|
911
993
|
return false
|