blacklight-spotlight 3.0.0.alpha.8 → 3.0.0.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (206) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +3 -3
  3. data/app/assets/images/blacklight/arrow-alt-circle-left.svg +1 -0
  4. data/app/assets/images/blacklight/arrow-alt-circle-right.svg +1 -0
  5. data/app/assets/javascripts/spotlight/admin/{add_new_page_button.js → add_new_button.js} +7 -0
  6. data/app/assets/javascripts/spotlight/admin/block_mixins/autocompleteable.js +4 -4
  7. data/app/assets/javascripts/spotlight/admin/blocks/browse_block.js +55 -1
  8. data/app/assets/javascripts/spotlight/admin/blocks/browse_group_categories_block.js +88 -0
  9. data/app/assets/javascripts/spotlight/admin/blocks/pages_block.js +1 -1
  10. data/app/assets/javascripts/spotlight/admin/blocks/solr_documents_base_block.js +1 -1
  11. data/app/assets/javascripts/spotlight/admin/blocks/uploaded_items_block.js +7 -2
  12. data/app/assets/javascripts/spotlight/admin/crop.es6 +11 -0
  13. data/app/assets/javascripts/spotlight/admin/croppable.js +1 -1
  14. data/app/assets/javascripts/spotlight/admin/index.js +0 -2
  15. data/app/assets/javascripts/spotlight/admin/search_typeahead.js +2 -2
  16. data/app/assets/javascripts/spotlight/admin/sir-trevor/block_controls.js +21 -12
  17. data/app/assets/javascripts/spotlight/admin/sir-trevor/locales.js +11 -3
  18. data/app/assets/javascripts/spotlight/user/browse_group_categories.js +59 -0
  19. data/app/assets/javascripts/spotlight/user/index.js +1 -0
  20. data/app/assets/stylesheets/spotlight/_accessibility.scss +1 -1
  21. data/app/assets/stylesheets/spotlight/_breadcrumbs.scss +8 -0
  22. data/app/assets/stylesheets/spotlight/_browse.scss +16 -0
  23. data/app/assets/stylesheets/spotlight/_catalog.scss +6 -6
  24. data/app/assets/stylesheets/spotlight/_curation.scss +6 -0
  25. data/app/assets/stylesheets/spotlight/_featured_browse_categories_block.scss +214 -83
  26. data/app/assets/stylesheets/spotlight/_header.scss +1 -1
  27. data/app/assets/stylesheets/spotlight/_item_text_block.scss +6 -0
  28. data/app/assets/stylesheets/spotlight/_pages.scss +10 -5
  29. data/app/assets/stylesheets/spotlight/_report_a_problem.scss +5 -2
  30. data/app/assets/stylesheets/spotlight/_spotlight.scss +2 -0
  31. data/app/assets/stylesheets/spotlight/_translations.scss +7 -0
  32. data/app/assets/stylesheets/spotlight/browse_group_categories_block.scss +69 -0
  33. data/app/builders/spotlight/bootstrap_breadcrumbs_builder.rb +1 -2
  34. data/app/controllers/concerns/spotlight/search_helper.rb +2 -8
  35. data/app/controllers/spotlight/appearances_controller.rb +0 -12
  36. data/app/controllers/spotlight/browse_controller.rb +7 -3
  37. data/app/controllers/spotlight/catalog_controller.rb +1 -1
  38. data/app/controllers/spotlight/concerns/application_controller.rb +13 -2
  39. data/app/controllers/spotlight/exhibits_controller.rb +2 -3
  40. data/app/controllers/spotlight/featured_images_controller.rb +1 -1
  41. data/app/controllers/spotlight/groups_controller.rb +80 -0
  42. data/app/controllers/spotlight/pages_controller.rb +6 -9
  43. data/app/controllers/spotlight/resources/csv_upload_controller.rb +1 -1
  44. data/app/controllers/spotlight/searches_controller.rb +7 -19
  45. data/app/controllers/spotlight/translations_controller.rb +46 -0
  46. data/app/helpers/spotlight/application_helper.rb +1 -1
  47. data/app/helpers/spotlight/crop_helper.rb +4 -1
  48. data/app/helpers/spotlight/crud_link_helpers.rb +1 -1
  49. data/app/helpers/spotlight/main_app_helpers.rb +1 -1
  50. data/app/jobs/spotlight/add_uploads_from_csv.rb +30 -5
  51. data/app/mailers/spotlight/indexing_complete_mailer.rb +3 -2
  52. data/app/models/concerns/spotlight/exhibit_defaults.rb +1 -1
  53. data/app/models/concerns/spotlight/translatables.rb +17 -1
  54. data/app/models/sir_trevor_rails/blocks/browse_group_categories_block.rb +25 -0
  55. data/app/models/spotlight/ability.rb +2 -0
  56. data/app/models/spotlight/about_page.rb +3 -1
  57. data/app/models/spotlight/blacklight_configuration.rb +2 -1
  58. data/app/models/spotlight/contact.rb +1 -1
  59. data/app/models/spotlight/custom_field.rb +3 -3
  60. data/app/models/spotlight/exhibit.rb +18 -4
  61. data/app/models/spotlight/feature_page.rb +3 -1
  62. data/app/models/spotlight/featured_image.rb +29 -12
  63. data/app/models/spotlight/group.rb +22 -0
  64. data/app/models/spotlight/group_member.rb +11 -0
  65. data/app/models/spotlight/home_page.rb +3 -1
  66. data/app/models/spotlight/main_navigation.rb +2 -2
  67. data/app/models/spotlight/masthead.rb +1 -1
  68. data/app/models/spotlight/page.rb +5 -1
  69. data/app/models/spotlight/page_configurations.rb +6 -0
  70. data/app/models/spotlight/page_content.rb +2 -0
  71. data/app/models/spotlight/resources/csv_upload.rb +2 -1
  72. data/app/models/spotlight/resources/iiif_manifest.rb +8 -6
  73. data/app/models/spotlight/resources/upload.rb +1 -1
  74. data/app/models/spotlight/search.rb +10 -1
  75. data/app/models/spotlight/solr_document_sidecar.rb +7 -5
  76. data/app/models/spotlight/temporary_image.rb +8 -0
  77. data/app/services/spotlight/exhibit_import_export_service.rb +482 -0
  78. data/app/services/spotlight/solr_document_builder.rb +1 -0
  79. data/app/values/custom_field_name.rb +1 -0
  80. data/app/views/catalog/_save_search.html.erb +1 -1
  81. data/app/views/spotlight/about_pages/_empty.html.erb +5 -5
  82. data/app/views/spotlight/browse/_search.html.erb +5 -3
  83. data/app/views/spotlight/browse/_search_title.html.erb +2 -1
  84. data/app/views/spotlight/browse/index.html.erb +13 -0
  85. data/app/views/spotlight/catalog/_document.html.erb +2 -4
  86. data/app/views/spotlight/catalog/index.iiif_json.jbuilder +22 -0
  87. data/app/views/spotlight/contacts/_form.html.erb +1 -1
  88. data/app/views/spotlight/feature_pages/_empty.html.erb +5 -5
  89. data/app/views/spotlight/featured_images/_form.html.erb +1 -1
  90. data/app/views/spotlight/featured_images/_upload_form.html.erb +1 -1
  91. data/app/views/spotlight/home_pages/_empty.html.erb +3 -3
  92. data/app/views/spotlight/indexing_complete_mailer/documents_indexed.html.erb +9 -0
  93. data/app/views/spotlight/pages/_form.html.erb +2 -2
  94. data/app/views/spotlight/searches/_form.html.erb +13 -0
  95. data/app/views/spotlight/searches/_group.html.erb +27 -0
  96. data/app/views/spotlight/searches/_search.html.erb +1 -0
  97. data/app/views/spotlight/searches/index.html.erb +58 -17
  98. data/app/views/spotlight/shared/_honeypot_field.html.erb +4 -0
  99. data/app/views/spotlight/shared/_report_a_problem.html.erb +7 -10
  100. data/app/views/spotlight/sir_trevor/blocks/_browse_block.html.erb +1 -0
  101. data/app/views/spotlight/sir_trevor/blocks/_browse_group_categories_block.html.erb +44 -0
  102. data/app/views/spotlight/sir_trevor/blocks/_uploaded_items_block.html.erb +7 -1
  103. data/app/views/spotlight/translations/_browse_categories.html.erb +29 -3
  104. data/app/views/spotlight/translations/_general.html.erb +7 -7
  105. data/app/views/spotlight/translations/_groups.html.erb +34 -0
  106. data/app/views/spotlight/translations/_import.html.erb +24 -0
  107. data/app/views/spotlight/translations/_metadata.html.erb +1 -1
  108. data/app/views/spotlight/translations/_page.html.erb +5 -5
  109. data/app/views/spotlight/translations/_pages.html.erb +4 -4
  110. data/app/views/spotlight/translations/_pages_table.html.erb +5 -5
  111. data/app/views/spotlight/translations/_search_fields.html.erb +3 -3
  112. data/app/views/spotlight/translations/edit.html.erb +14 -6
  113. data/app/views/spotlight/translations/show.yaml.yamlbuilder +81 -0
  114. data/config/i18n-tasks.yml +7 -0
  115. data/config/locales/spotlight.ar.yml +47 -24
  116. data/config/locales/spotlight.en.yml +182 -127
  117. data/config/routes.rb +16 -1
  118. data/db/migrate/20200403161512_add_subtitle_to_searches.rb +7 -0
  119. data/db/migrate/20210113092223_create_spotlight_groups.rb +23 -0
  120. data/lib/generators/spotlight/install_generator.rb +23 -2
  121. data/lib/generators/spotlight/templates/config/initializers/sir_trevor_rails.rb +10 -0
  122. data/lib/generators/spotlight/templates/config/initializers/spotlight_initializer.rb +3 -1
  123. data/lib/spotlight/engine.rb +27 -3
  124. data/lib/spotlight/upload_field_config.rb +1 -0
  125. data/lib/spotlight/version.rb +1 -1
  126. data/spec/controllers/spotlight/about_pages_controller_spec.rb +3 -3
  127. data/spec/controllers/spotlight/browse_controller_spec.rb +24 -1
  128. data/spec/controllers/spotlight/catalog_controller_spec.rb +1 -1
  129. data/spec/controllers/spotlight/contacts_controller_spec.rb +2 -2
  130. data/spec/controllers/spotlight/feature_pages_controller_spec.rb +11 -0
  131. data/spec/controllers/spotlight/groups_controller_spec.rb +103 -0
  132. data/spec/controllers/spotlight/home_pages_controller_spec.rb +2 -2
  133. data/spec/controllers/spotlight/resources/csv_upload_controller_spec.rb +4 -4
  134. data/spec/controllers/spotlight/resources/upload_controller_spec.rb +2 -2
  135. data/spec/controllers/spotlight/searches_controller_spec.rb +10 -3
  136. data/spec/controllers/spotlight/translations_controller_spec.rb +53 -2
  137. data/spec/controllers/spotlight/view_configurations_controller_spec.rb +1 -1
  138. data/spec/examples.txt +1437 -1389
  139. data/spec/factories/featured_images.rb +4 -0
  140. data/spec/factories/group.rb +17 -0
  141. data/spec/factories/searches.rb +11 -1
  142. data/spec/features/add_contacts_spec.rb +1 -1
  143. data/spec/features/browse_category_admin_spec.rb +39 -7
  144. data/spec/features/browse_category_navigation_spec.rb +44 -0
  145. data/spec/features/browse_category_spec.rb +2 -2
  146. data/spec/features/catalog_spec.rb +2 -2
  147. data/spec/features/create_exhibit_spec.rb +5 -4
  148. data/spec/features/dashboard_spec.rb +7 -7
  149. data/spec/features/edit_search_fields_spec.rb +2 -2
  150. data/spec/features/exhibits/administration_spec.rb +3 -3
  151. data/spec/features/exhibits/edit_metadata_fields_spec.rb +1 -1
  152. data/spec/features/exhibits/language_create_edit_spec.rb +3 -3
  153. data/spec/features/exhibits/translation_editing_spec.rb +57 -8
  154. data/spec/features/home_page_spec.rb +13 -4
  155. data/spec/features/item_admin_spec.rb +4 -4
  156. data/spec/features/javascript/about_page_admin_spec.rb +1 -1
  157. data/spec/features/javascript/block_controls_spec.rb +3 -1
  158. data/spec/features/javascript/blocks/browse_group_categories_block_spec.rb +64 -0
  159. data/spec/features/javascript/blocks/uploaded_items_block_spec.rb +4 -1
  160. data/spec/features/javascript/browse_group_admin_spec.rb +45 -0
  161. data/spec/features/javascript/edit_in_place_spec.rb +3 -3
  162. data/spec/features/javascript/feature_page_admin_spec.rb +1 -1
  163. data/spec/features/javascript/search_config_admin_spec.rb +1 -1
  164. data/spec/features/report_a_problem_spec.rb +6 -5
  165. data/spec/helpers/spotlight/crud_link_helpers_spec.rb +3 -3
  166. data/spec/helpers/spotlight/pages_helper_spec.rb +2 -2
  167. data/spec/i18n_spec.rb +0 -2
  168. data/spec/jobs/spotlight/add_uploads_from_csv_spec.rb +13 -1
  169. data/spec/mailers/spotlight/indexing_complete_mailer_spec.rb +11 -1
  170. data/spec/models/sir_trevor_rails/blocks/browse_group_categories_block_spec.rb +41 -0
  171. data/spec/models/solr_document_spec.rb +2 -3
  172. data/spec/models/spotlight/access_controls_enforcement_search_builder_spec.rb +1 -0
  173. data/spec/models/spotlight/exhibit_spec.rb +18 -2
  174. data/spec/models/spotlight/featured_image_spec.rb +27 -0
  175. data/spec/models/spotlight/group_spec.rb +19 -0
  176. data/spec/models/spotlight/main_navigation_spec.rb +1 -1
  177. data/spec/models/spotlight/page_spec.rb +6 -1
  178. data/spec/models/spotlight/resources/upload_spec.rb +43 -79
  179. data/spec/models/spotlight/role_spec.rb +3 -3
  180. data/spec/models/spotlight/search_spec.rb +30 -3
  181. data/spec/{serializers/spotlight/exhibit_export_serializer_spec.rb → services/spotlight/exhibit_import_export_service_spec.rb} +168 -23
  182. data/spec/services/spotlight/iiif_resource_resolver_spec.rb +1 -1
  183. data/spec/services/spotlight/solr_document_builder_spec.rb +1 -1
  184. data/spec/spec_helper.rb +1 -1
  185. data/spec/support/features/test_features_helpers.rb +15 -0
  186. data/spec/test_app_templates/Gemfile.extra +1 -3
  187. data/spec/test_app_templates/catalog_controller.rb +6 -3
  188. data/spec/test_app_templates/lib/generators/test_app_generator.rb +1 -1
  189. data/spec/views/shared/_exhibit_navbar.html.erb_spec.rb +1 -1
  190. data/spec/views/spotlight/browse/index.html.erb_spec.rb +2 -0
  191. data/spec/views/spotlight/dashboards/_analytics.html.erb_spec.rb +1 -1
  192. data/spec/views/spotlight/dashboards/_reindexing_activity.html.erb_spec.rb +6 -6
  193. data/spec/views/spotlight/metadata_configurations/_metadata_field.html.erb_spec.rb +3 -3
  194. data/spec/views/spotlight/pages/show.html.erb_spec.rb +1 -0
  195. data/spec/views/spotlight/search_configurations/_facets.html.erb_spec.rb +1 -1
  196. data/spec/views/spotlight/search_configurations/_sort.html.erb_spec.rb +7 -8
  197. data/spec/views/spotlight/translations/_import.html.erb_spec.rb +24 -0
  198. data/vendor/assets/javascripts/leaflet-iiif.js +46 -21
  199. data/vendor/assets/javascripts/tiny-slider.js +3218 -0
  200. data/vendor/assets/stylesheets/tiny-slider.css +1 -0
  201. metadata +399 -284
  202. data/app/serializers/spotlight/exhibit_export_serializer.rb +0 -205
  203. data/app/serializers/spotlight/featured_image_representer.rb +0 -29
  204. data/app/serializers/spotlight/main_navigation_representer.rb +0 -13
  205. data/app/serializers/spotlight/page_representer.rb +0 -33
  206. data/vendor/assets/javascripts/handlebars-v1.3.0.js +0 -2746
@@ -1,205 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'roar/decorator'
4
- require 'roar/json'
5
- require 'base64'
6
- require 'tempfile'
7
-
8
- module Spotlight
9
- ##
10
- # Serialize the Spotlight::BlacklightConfiguration
11
- class ConfigurationRepresenter < Roar::Decorator
12
- include Roar::JSON
13
-
14
- (Spotlight::BlacklightConfiguration.attribute_names - %w[id exhibit_id]).each do |prop|
15
- property prop
16
- end
17
-
18
- property :skip_default_configuration, exec_context: :decorator
19
-
20
- def skip_default_configuration
21
- true
22
- end
23
-
24
- delegate :skip_default_configuration=, to: :represented
25
- end
26
-
27
- ##
28
- # Serialize an exhibit with all the data needed to reconstruct it
29
- # in a different environment
30
- class ExhibitExportSerializer < Roar::Decorator
31
- def self.config?(config)
32
- lambda do |**_args|
33
- Spotlight::Engine.config.exports[config]
34
- end
35
- end
36
-
37
- include Roar::JSON
38
-
39
- (Spotlight::Exhibit.attribute_names - %w[id slug masthead_id thumbnail_id]).each do |prop|
40
- property prop, if: config?(:config)
41
- end
42
-
43
- property :theme, if: config?(:config), setter: lambda { |fragment:, represented:, **|
44
- represented.theme = fragment if Spotlight::Engine.config.exhibit_themes.include? fragment
45
- }
46
-
47
- collection :main_navigations, class: Spotlight::MainNavigation, decorator: MainNavigationRepresenter, if: config?(:config)
48
- collection :contact_emails, class: Spotlight::ContactEmail, if: config?(:config) do
49
- (Spotlight::ContactEmail.attribute_names - %w[id exhibit_id confirmation_token]).each do |prop|
50
- property prop
51
- end
52
- end
53
-
54
- collection :searches, populator: ->(fragment, options) { options[:represented].searches.find_or_initialize_by(slug: fragment['slug']) },
55
- if: config?(:pages),
56
- class: Spotlight::Search do
57
- (Spotlight::Search.attribute_names - %w[id scope exhibit_id masthead_id thumbnail_id]).each do |prop|
58
- property prop
59
- end
60
-
61
- property :masthead, class: Spotlight::Masthead,
62
- decorator: FeaturedImageRepresenter,
63
- if: Spotlight::ExhibitExportSerializer.config?(:attachments)
64
-
65
- property :thumbnail, class: Spotlight::FeaturedImage,
66
- decorator: FeaturedImageRepresenter,
67
- if: Spotlight::ExhibitExportSerializer.config?(:attachments)
68
- end
69
-
70
- collection :about_pages, populator: ->(fragment, options) { options[:represented].about_pages.find_or_initialize_by(slug: fragment['slug']) },
71
- if: config?(:pages),
72
- class: Spotlight::AboutPage,
73
- decorator: PageRepresenter
74
-
75
- collection :feature_pages, populator: ->(fragment, options) { options[:represented].feature_pages.find_or_initialize_by(slug: fragment['slug']) },
76
- getter: ->(_opts) { feature_pages.at_top_level },
77
- class: Spotlight::FeaturePage,
78
- decorator: NestedPageRepresenter,
79
- if: config?(:pages)
80
-
81
- property :home_page, populator: ->(_fragment, options) { options[:represented].home_page },
82
- class: Spotlight::HomePage,
83
- decorator: PageRepresenter,
84
- if: config?(:pages)
85
-
86
- collection :contacts, populator: ->(fragment, options) { options[:represented].contacts.find_or_initialize_by(slug: fragment['slug']) },
87
- class: Spotlight::Contact,
88
- if: config?(:pages) do
89
- (Spotlight::Contact.attribute_names - %w[id exhibit_id]).each do |prop|
90
- property prop
91
- end
92
-
93
- property :avatar, class: Spotlight::ContactImage, decorator: FeaturedImageRepresenter
94
- end
95
-
96
- property :masthead, class: Spotlight::Masthead, decorator: FeaturedImageRepresenter, if: config?(:attachments)
97
-
98
- property :thumbnail, class: Spotlight::ExhibitThumbnail, decorator: FeaturedImageRepresenter, if: config?(:attachments)
99
-
100
- property :blacklight_configuration, class: Spotlight::BlacklightConfiguration, decorator: ConfigurationRepresenter, if: config?(:blacklight_configuration)
101
-
102
- collection :custom_fields, populator: ->(fragment, options) { options[:represented].custom_fields.find_or_initialize_by(slug: fragment['slug']) },
103
- class: Spotlight::CustomField,
104
- if: config?(:blacklight_configuration) do
105
- (Spotlight::CustomField.attribute_names - %w[id exhibit_id]).each do |prop|
106
- property prop
107
- end
108
- end
109
-
110
- collection :solr_document_sidecars, class: Spotlight::SolrDocumentSidecar,
111
- if: config?(:resources) do
112
- (Spotlight::SolrDocumentSidecar.attribute_names - %w[id document_type exhibit_id]).each do |prop|
113
- property prop
114
- end
115
-
116
- property :document_type, exec_context: :decorator
117
-
118
- def document_type
119
- represented.document_type.to_s
120
- end
121
-
122
- delegate :document_type=, to: :represented
123
- end
124
-
125
- collection :owned_taggings, class: ActsAsTaggableOn::Tagging,
126
- if: config?(:resources) do
127
- property :taggable_id
128
- property :taggable_type
129
- property :context
130
- property :tag, exec_context: :decorator
131
-
132
- def tag
133
- represented.tag.name
134
- end
135
-
136
- def tag=(tag)
137
- represented.tag = ActsAsTaggableOn::Tag.find_or_create_by name: tag
138
- end
139
- end
140
-
141
- collection :attachments, class: Spotlight::Attachment, if: config?(:attachments) do
142
- (Spotlight::Attachment.attribute_names - %w[id exhibit_id file]).each do |prop|
143
- property prop
144
- end
145
-
146
- property :file, exec_context: :decorator
147
-
148
- def file
149
- file = represented.file.file
150
-
151
- { filename: file.filename, content_type: file.content_type, content: Base64.encode64(file.read) }
152
- end
153
-
154
- def file=(file)
155
- represented.file = CarrierWave::SanitizedFile.new tempfile: StringIO.new(Base64.decode64(file['content'])),
156
- filename: file['filename'],
157
- content_type: file['content_type']
158
- end
159
- end
160
-
161
- collection :resources, class: ->(options) { options[:fragment].key?('type') ? options[:fragment]['type'].constantize : Spotlight::Resource },
162
- if: config?(:resources) do
163
- (Spotlight::Resource.attribute_names - %w[id upload_id exhibit_id]).each do |prop|
164
- property prop
165
- end
166
-
167
- property :upload, exec_context: :decorator
168
-
169
- def upload
170
- return unless represented.is_a? Spotlight::Resources::Upload
171
-
172
- FeaturedImageRepresenter.new(represented.upload).to_json
173
- end
174
-
175
- def upload=(json)
176
- return unless represented.is_a? Spotlight::Resources::Upload
177
-
178
- FeaturedImageRepresenter.new(represented.build_upload).from_json(json)
179
- end
180
- end
181
-
182
- collection :languages, class: Spotlight::Language,
183
- populator: ->(fragment, options) { options[:represented].languages.find_or_initialize_by(locale: fragment['locale']) },
184
- if: config?(:config) do
185
- (Spotlight::Language.attribute_names - %w[id exhibit_id]).each do |prop|
186
- property prop
187
- end
188
- end
189
-
190
- collection :translations, getter: ->(represented:, **) { represented.translations.unscope(where: :locale) },
191
- populator: (lambda do |fragment, options|
192
- options[:represented].translations
193
- .unscope(where: :locale)
194
- .find_or_initialize_by(locale: fragment['locale'], key: fragment['key'])
195
- end),
196
- class: I18n::Backend::ActiveRecord::Translation,
197
- if: config?(:config) do
198
- property :locale
199
- property :key
200
- property :value
201
- property :interpolations
202
- property :is_proc
203
- end
204
- end
205
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'roar/decorator'
4
- require 'roar/json'
5
- module Spotlight
6
- ##
7
- # Serialize mastheads and thumbnails
8
- class FeaturedImageRepresenter < Roar::Decorator
9
- include Roar::JSON
10
- (Spotlight::FeaturedImage.attribute_names - %w[id image]).each do |prop|
11
- property prop
12
- end
13
-
14
- property :image, exec_context: :decorator
15
- def image
16
- file = represented.image.file
17
-
18
- return unless file
19
-
20
- { filename: file.filename, content_type: file.content_type, content: Base64.encode64(file.read) }
21
- end
22
-
23
- def image=(file)
24
- represented.image = CarrierWave::SanitizedFile.new tempfile: StringIO.new(Base64.decode64(file['content'])),
25
- filename: file['filename'],
26
- content_type: file['content_type']
27
- end
28
- end
29
- end
@@ -1,13 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Spotlight
4
- ##
5
- # Serialize the Spotlight::BlacklightConfiguration
6
- class MainNavigationRepresenter < Roar::Decorator
7
- include Roar::JSON
8
-
9
- (Spotlight::MainNavigation.attribute_names - %w[id exhibit_id]).each do |prop|
10
- property prop
11
- end
12
- end
13
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'roar/decorator'
4
- require 'roar/json'
5
- module Spotlight
6
- ##
7
- # Serialize an exhibit page
8
- class PageRepresenter < Roar::Decorator
9
- include Roar::JSON
10
- (Spotlight::Page.attribute_names - %w[id scope exhibit_id parent_page_id content thumbnail_id]).each do |prop|
11
- property prop
12
- end
13
-
14
- property :content, exec_context: :decorator
15
-
16
- def content
17
- # get the original data, bypassing any Sir-Trevor transformations
18
- represented.read_attribute(:content)
19
- end
20
-
21
- delegate :content=, to: :represented
22
- end
23
-
24
- ##
25
- # Serialize the page hierarchy (e.g. for Feature pages)
26
- class NestedPageRepresenter < PageRepresenter
27
- collection :child_pages, populator: ->(fragment, options) { options[:represented].child_pages.find_or_initialize_by(slug: fragment['slug']) },
28
- class: Spotlight::FeaturePage,
29
- extend: NestedPageRepresenter
30
-
31
- property :thumbnail, class: Spotlight::FeaturedImage, decorator: FeaturedImageRepresenter, if: Spotlight::ExhibitExportSerializer.config?(:attachments)
32
- end
33
- end
@@ -1,2746 +0,0 @@
1
- /*!
2
-
3
- handlebars v1.3.0
4
-
5
- Copyright (C) 2011 by Yehuda Katz
6
-
7
- Permission is hereby granted, free of charge, to any person obtaining a copy
8
- of this software and associated documentation files (the "Software"), to deal
9
- in the Software without restriction, including without limitation the rights
10
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
- copies of the Software, and to permit persons to whom the Software is
12
- furnished to do so, subject to the following conditions:
13
-
14
- The above copyright notice and this permission notice shall be included in
15
- all copies or substantial portions of the Software.
16
-
17
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
- THE SOFTWARE.
24
-
25
- @license
26
- */
27
- /* exported Handlebars */
28
- var Handlebars = (function() {
29
- // handlebars/safe-string.js
30
- var __module4__ = (function() {
31
- "use strict";
32
- var __exports__;
33
- // Build out our basic SafeString type
34
- function SafeString(string) {
35
- this.string = string;
36
- }
37
-
38
- SafeString.prototype.toString = function() {
39
- return "" + this.string;
40
- };
41
-
42
- __exports__ = SafeString;
43
- return __exports__;
44
- })();
45
-
46
- // handlebars/utils.js
47
- var __module3__ = (function(__dependency1__) {
48
- "use strict";
49
- var __exports__ = {};
50
- /*jshint -W004 */
51
- var SafeString = __dependency1__;
52
-
53
- var escape = {
54
- "&": "&amp;",
55
- "<": "&lt;",
56
- ">": "&gt;",
57
- '"': "&quot;",
58
- "'": "&#x27;",
59
- "`": "&#x60;"
60
- };
61
-
62
- var badChars = /[&<>"'`]/g;
63
- var possible = /[&<>"'`]/;
64
-
65
- function escapeChar(chr) {
66
- return escape[chr] || "&amp;";
67
- }
68
-
69
- function extend(obj, value) {
70
- for(var key in value) {
71
- if(Object.prototype.hasOwnProperty.call(value, key)) {
72
- obj[key] = value[key];
73
- }
74
- }
75
- }
76
-
77
- __exports__.extend = extend;var toString = Object.prototype.toString;
78
- __exports__.toString = toString;
79
- // Sourced from lodash
80
- // https://github.com/bestiejs/lodash/blob/master/LICENSE.txt
81
- var isFunction = function(value) {
82
- return typeof value === 'function';
83
- };
84
- // fallback for older versions of Chrome and Safari
85
- if (isFunction(/x/)) {
86
- isFunction = function(value) {
87
- return typeof value === 'function' && toString.call(value) === '[object Function]';
88
- };
89
- }
90
- var isFunction;
91
- __exports__.isFunction = isFunction;
92
- var isArray = Array.isArray || function(value) {
93
- return (value && typeof value === 'object') ? toString.call(value) === '[object Array]' : false;
94
- };
95
- __exports__.isArray = isArray;
96
-
97
- function escapeExpression(string) {
98
- // don't escape SafeStrings, since they're already safe
99
- if (string instanceof SafeString) {
100
- return string.toString();
101
- } else if (!string && string !== 0) {
102
- return "";
103
- }
104
-
105
- // Force a string conversion as this will be done by the append regardless and
106
- // the regex test will do this transparently behind the scenes, causing issues if
107
- // an object's to string has escaped characters in it.
108
- string = "" + string;
109
-
110
- if(!possible.test(string)) { return string; }
111
- return string.replace(badChars, escapeChar);
112
- }
113
-
114
- __exports__.escapeExpression = escapeExpression;function isEmpty(value) {
115
- if (!value && value !== 0) {
116
- return true;
117
- } else if (isArray(value) && value.length === 0) {
118
- return true;
119
- } else {
120
- return false;
121
- }
122
- }
123
-
124
- __exports__.isEmpty = isEmpty;
125
- return __exports__;
126
- })(__module4__);
127
-
128
- // handlebars/exception.js
129
- var __module5__ = (function() {
130
- "use strict";
131
- var __exports__;
132
-
133
- var errorProps = ['description', 'fileName', 'lineNumber', 'message', 'name', 'number', 'stack'];
134
-
135
- function Exception(message, node) {
136
- var line;
137
- if (node && node.firstLine) {
138
- line = node.firstLine;
139
-
140
- message += ' - ' + line + ':' + node.firstColumn;
141
- }
142
-
143
- var tmp = Error.prototype.constructor.call(this, message);
144
-
145
- // Unfortunately errors are not enumerable in Chrome (at least), so `for prop in tmp` doesn't work.
146
- for (var idx = 0; idx < errorProps.length; idx++) {
147
- this[errorProps[idx]] = tmp[errorProps[idx]];
148
- }
149
-
150
- if (line) {
151
- this.lineNumber = line;
152
- this.column = node.firstColumn;
153
- }
154
- }
155
-
156
- Exception.prototype = new Error();
157
-
158
- __exports__ = Exception;
159
- return __exports__;
160
- })();
161
-
162
- // handlebars/base.js
163
- var __module2__ = (function(__dependency1__, __dependency2__) {
164
- "use strict";
165
- var __exports__ = {};
166
- var Utils = __dependency1__;
167
- var Exception = __dependency2__;
168
-
169
- var VERSION = "1.3.0";
170
- __exports__.VERSION = VERSION;var COMPILER_REVISION = 4;
171
- __exports__.COMPILER_REVISION = COMPILER_REVISION;
172
- var REVISION_CHANGES = {
173
- 1: '<= 1.0.rc.2', // 1.0.rc.2 is actually rev2 but doesn't report it
174
- 2: '== 1.0.0-rc.3',
175
- 3: '== 1.0.0-rc.4',
176
- 4: '>= 1.0.0'
177
- };
178
- __exports__.REVISION_CHANGES = REVISION_CHANGES;
179
- var isArray = Utils.isArray,
180
- isFunction = Utils.isFunction,
181
- toString = Utils.toString,
182
- objectType = '[object Object]';
183
-
184
- function HandlebarsEnvironment(helpers, partials) {
185
- this.helpers = helpers || {};
186
- this.partials = partials || {};
187
-
188
- registerDefaultHelpers(this);
189
- }
190
-
191
- __exports__.HandlebarsEnvironment = HandlebarsEnvironment;HandlebarsEnvironment.prototype = {
192
- constructor: HandlebarsEnvironment,
193
-
194
- logger: logger,
195
- log: log,
196
-
197
- registerHelper: function(name, fn, inverse) {
198
- if (toString.call(name) === objectType) {
199
- if (inverse || fn) { throw new Exception('Arg not supported with multiple helpers'); }
200
- Utils.extend(this.helpers, name);
201
- } else {
202
- if (inverse) { fn.not = inverse; }
203
- this.helpers[name] = fn;
204
- }
205
- },
206
-
207
- registerPartial: function(name, str) {
208
- if (toString.call(name) === objectType) {
209
- Utils.extend(this.partials, name);
210
- } else {
211
- this.partials[name] = str;
212
- }
213
- }
214
- };
215
-
216
- function registerDefaultHelpers(instance) {
217
- instance.registerHelper('helperMissing', function(arg) {
218
- if(arguments.length === 2) {
219
- return undefined;
220
- } else {
221
- throw new Exception("Missing helper: '" + arg + "'");
222
- }
223
- });
224
-
225
- instance.registerHelper('blockHelperMissing', function(context, options) {
226
- var inverse = options.inverse || function() {}, fn = options.fn;
227
-
228
- if (isFunction(context)) { context = context.call(this); }
229
-
230
- if(context === true) {
231
- return fn(this);
232
- } else if(context === false || context == null) {
233
- return inverse(this);
234
- } else if (isArray(context)) {
235
- if(context.length > 0) {
236
- return instance.helpers.each(context, options);
237
- } else {
238
- return inverse(this);
239
- }
240
- } else {
241
- return fn(context);
242
- }
243
- });
244
-
245
- instance.registerHelper('each', function(context, options) {
246
- var fn = options.fn, inverse = options.inverse;
247
- var i = 0, ret = "", data;
248
-
249
- if (isFunction(context)) { context = context.call(this); }
250
-
251
- if (options.data) {
252
- data = createFrame(options.data);
253
- }
254
-
255
- if(context && typeof context === 'object') {
256
- if (isArray(context)) {
257
- for(var j = context.length; i<j; i++) {
258
- if (data) {
259
- data.index = i;
260
- data.first = (i === 0);
261
- data.last = (i === (context.length-1));
262
- }
263
- ret = ret + fn(context[i], { data: data });
264
- }
265
- } else {
266
- for(var key in context) {
267
- if(context.hasOwnProperty(key)) {
268
- if(data) {
269
- data.key = key;
270
- data.index = i;
271
- data.first = (i === 0);
272
- }
273
- ret = ret + fn(context[key], {data: data});
274
- i++;
275
- }
276
- }
277
- }
278
- }
279
-
280
- if(i === 0){
281
- ret = inverse(this);
282
- }
283
-
284
- return ret;
285
- });
286
-
287
- instance.registerHelper('if', function(conditional, options) {
288
- if (isFunction(conditional)) { conditional = conditional.call(this); }
289
-
290
- // Default behavior is to render the positive path if the value is truthy and not empty.
291
- // The `includeZero` option may be set to treat the condtional as purely not empty based on the
292
- // behavior of isEmpty. Effectively this determines if 0 is handled by the positive path or negative.
293
- if ((!options.hash.includeZero && !conditional) || Utils.isEmpty(conditional)) {
294
- return options.inverse(this);
295
- } else {
296
- return options.fn(this);
297
- }
298
- });
299
-
300
- instance.registerHelper('unless', function(conditional, options) {
301
- return instance.helpers['if'].call(this, conditional, {fn: options.inverse, inverse: options.fn, hash: options.hash});
302
- });
303
-
304
- instance.registerHelper('with', function(context, options) {
305
- if (isFunction(context)) { context = context.call(this); }
306
-
307
- if (!Utils.isEmpty(context)) return options.fn(context);
308
- });
309
-
310
- instance.registerHelper('log', function(context, options) {
311
- var level = options.data && options.data.level != null ? parseInt(options.data.level, 10) : 1;
312
- instance.log(level, context);
313
- });
314
- }
315
-
316
- var logger = {
317
- methodMap: { 0: 'debug', 1: 'info', 2: 'warn', 3: 'error' },
318
-
319
- // State enum
320
- DEBUG: 0,
321
- INFO: 1,
322
- WARN: 2,
323
- ERROR: 3,
324
- level: 3,
325
-
326
- // can be overridden in the host environment
327
- log: function(level, obj) {
328
- if (logger.level <= level) {
329
- var method = logger.methodMap[level];
330
- if (typeof console !== 'undefined' && console[method]) {
331
- console[method].call(console, obj);
332
- }
333
- }
334
- }
335
- };
336
- __exports__.logger = logger;
337
- function log(level, obj) { logger.log(level, obj); }
338
-
339
- __exports__.log = log;var createFrame = function(object) {
340
- var obj = {};
341
- Utils.extend(obj, object);
342
- return obj;
343
- };
344
- __exports__.createFrame = createFrame;
345
- return __exports__;
346
- })(__module3__, __module5__);
347
-
348
- // handlebars/runtime.js
349
- var __module6__ = (function(__dependency1__, __dependency2__, __dependency3__) {
350
- "use strict";
351
- var __exports__ = {};
352
- var Utils = __dependency1__;
353
- var Exception = __dependency2__;
354
- var COMPILER_REVISION = __dependency3__.COMPILER_REVISION;
355
- var REVISION_CHANGES = __dependency3__.REVISION_CHANGES;
356
-
357
- function checkRevision(compilerInfo) {
358
- var compilerRevision = compilerInfo && compilerInfo[0] || 1,
359
- currentRevision = COMPILER_REVISION;
360
-
361
- if (compilerRevision !== currentRevision) {
362
- if (compilerRevision < currentRevision) {
363
- var runtimeVersions = REVISION_CHANGES[currentRevision],
364
- compilerVersions = REVISION_CHANGES[compilerRevision];
365
- throw new Exception("Template was precompiled with an older version of Handlebars than the current runtime. "+
366
- "Please update your precompiler to a newer version ("+runtimeVersions+") or downgrade your runtime to an older version ("+compilerVersions+").");
367
- } else {
368
- // Use the embedded version info since the runtime doesn't know about this revision yet
369
- throw new Exception("Template was precompiled with a newer version of Handlebars than the current runtime. "+
370
- "Please update your runtime to a newer version ("+compilerInfo[1]+").");
371
- }
372
- }
373
- }
374
-
375
- __exports__.checkRevision = checkRevision;// TODO: Remove this line and break up compilePartial
376
-
377
- function template(templateSpec, env) {
378
- if (!env) {
379
- throw new Exception("No environment passed to template");
380
- }
381
-
382
- // Note: Using env.VM references rather than local var references throughout this section to allow
383
- // for external users to override these as psuedo-supported APIs.
384
- var invokePartialWrapper = function(partial, name, context, helpers, partials, data) {
385
- var result = env.VM.invokePartial.apply(this, arguments);
386
- if (result != null) { return result; }
387
-
388
- if (env.compile) {
389
- var options = { helpers: helpers, partials: partials, data: data };
390
- partials[name] = env.compile(partial, { data: data !== undefined }, env);
391
- return partials[name](context, options);
392
- } else {
393
- throw new Exception("The partial " + name + " could not be compiled when running in runtime-only mode");
394
- }
395
- };
396
-
397
- // Just add water
398
- var container = {
399
- escapeExpression: Utils.escapeExpression,
400
- invokePartial: invokePartialWrapper,
401
- programs: [],
402
- program: function(i, fn, data) {
403
- var programWrapper = this.programs[i];
404
- if(data) {
405
- programWrapper = program(i, fn, data);
406
- } else if (!programWrapper) {
407
- programWrapper = this.programs[i] = program(i, fn);
408
- }
409
- return programWrapper;
410
- },
411
- merge: function(param, common) {
412
- var ret = param || common;
413
-
414
- if (param && common && (param !== common)) {
415
- ret = {};
416
- Utils.extend(ret, common);
417
- Utils.extend(ret, param);
418
- }
419
- return ret;
420
- },
421
- programWithDepth: env.VM.programWithDepth,
422
- noop: env.VM.noop,
423
- compilerInfo: null
424
- };
425
-
426
- return function(context, options) {
427
- options = options || {};
428
- var namespace = options.partial ? options : env,
429
- helpers,
430
- partials;
431
-
432
- if (!options.partial) {
433
- helpers = options.helpers;
434
- partials = options.partials;
435
- }
436
- var result = templateSpec.call(
437
- container,
438
- namespace, context,
439
- helpers,
440
- partials,
441
- options.data);
442
-
443
- if (!options.partial) {
444
- env.VM.checkRevision(container.compilerInfo);
445
- }
446
-
447
- return result;
448
- };
449
- }
450
-
451
- __exports__.template = template;function programWithDepth(i, fn, data /*, $depth */) {
452
- var args = Array.prototype.slice.call(arguments, 3);
453
-
454
- var prog = function(context, options) {
455
- options = options || {};
456
-
457
- return fn.apply(this, [context, options.data || data].concat(args));
458
- };
459
- prog.program = i;
460
- prog.depth = args.length;
461
- return prog;
462
- }
463
-
464
- __exports__.programWithDepth = programWithDepth;function program(i, fn, data) {
465
- var prog = function(context, options) {
466
- options = options || {};
467
-
468
- return fn(context, options.data || data);
469
- };
470
- prog.program = i;
471
- prog.depth = 0;
472
- return prog;
473
- }
474
-
475
- __exports__.program = program;function invokePartial(partial, name, context, helpers, partials, data) {
476
- var options = { partial: true, helpers: helpers, partials: partials, data: data };
477
-
478
- if(partial === undefined) {
479
- throw new Exception("The partial " + name + " could not be found");
480
- } else if(partial instanceof Function) {
481
- return partial(context, options);
482
- }
483
- }
484
-
485
- __exports__.invokePartial = invokePartial;function noop() { return ""; }
486
-
487
- __exports__.noop = noop;
488
- return __exports__;
489
- })(__module3__, __module5__, __module2__);
490
-
491
- // handlebars.runtime.js
492
- var __module1__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
493
- "use strict";
494
- var __exports__;
495
- /*globals Handlebars: true */
496
- var base = __dependency1__;
497
-
498
- // Each of these augment the Handlebars object. No need to setup here.
499
- // (This is done to easily share code between commonjs and browse envs)
500
- var SafeString = __dependency2__;
501
- var Exception = __dependency3__;
502
- var Utils = __dependency4__;
503
- var runtime = __dependency5__;
504
-
505
- // For compatibility and usage outside of module systems, make the Handlebars object a namespace
506
- var create = function() {
507
- var hb = new base.HandlebarsEnvironment();
508
-
509
- Utils.extend(hb, base);
510
- hb.SafeString = SafeString;
511
- hb.Exception = Exception;
512
- hb.Utils = Utils;
513
-
514
- hb.VM = runtime;
515
- hb.template = function(spec) {
516
- return runtime.template(spec, hb);
517
- };
518
-
519
- return hb;
520
- };
521
-
522
- var Handlebars = create();
523
- Handlebars.create = create;
524
-
525
- __exports__ = Handlebars;
526
- return __exports__;
527
- })(__module2__, __module4__, __module5__, __module3__, __module6__);
528
-
529
- // handlebars/compiler/ast.js
530
- var __module7__ = (function(__dependency1__) {
531
- "use strict";
532
- var __exports__;
533
- var Exception = __dependency1__;
534
-
535
- function LocationInfo(locInfo){
536
- locInfo = locInfo || {};
537
- this.firstLine = locInfo.first_line;
538
- this.firstColumn = locInfo.first_column;
539
- this.lastColumn = locInfo.last_column;
540
- this.lastLine = locInfo.last_line;
541
- }
542
-
543
- var AST = {
544
- ProgramNode: function(statements, inverseStrip, inverse, locInfo) {
545
- var inverseLocationInfo, firstInverseNode;
546
- if (arguments.length === 3) {
547
- locInfo = inverse;
548
- inverse = null;
549
- } else if (arguments.length === 2) {
550
- locInfo = inverseStrip;
551
- inverseStrip = null;
552
- }
553
-
554
- LocationInfo.call(this, locInfo);
555
- this.type = "program";
556
- this.statements = statements;
557
- this.strip = {};
558
-
559
- if(inverse) {
560
- firstInverseNode = inverse[0];
561
- if (firstInverseNode) {
562
- inverseLocationInfo = {
563
- first_line: firstInverseNode.firstLine,
564
- last_line: firstInverseNode.lastLine,
565
- last_column: firstInverseNode.lastColumn,
566
- first_column: firstInverseNode.firstColumn
567
- };
568
- this.inverse = new AST.ProgramNode(inverse, inverseStrip, inverseLocationInfo);
569
- } else {
570
- this.inverse = new AST.ProgramNode(inverse, inverseStrip);
571
- }
572
- this.strip.right = inverseStrip.left;
573
- } else if (inverseStrip) {
574
- this.strip.left = inverseStrip.right;
575
- }
576
- },
577
-
578
- MustacheNode: function(rawParams, hash, open, strip, locInfo) {
579
- LocationInfo.call(this, locInfo);
580
- this.type = "mustache";
581
- this.strip = strip;
582
-
583
- // Open may be a string parsed from the parser or a passed boolean flag
584
- if (open != null && open.charAt) {
585
- // Must use charAt to support IE pre-10
586
- var escapeFlag = open.charAt(3) || open.charAt(2);
587
- this.escaped = escapeFlag !== '{' && escapeFlag !== '&';
588
- } else {
589
- this.escaped = !!open;
590
- }
591
-
592
- if (rawParams instanceof AST.SexprNode) {
593
- this.sexpr = rawParams;
594
- } else {
595
- // Support old AST API
596
- this.sexpr = new AST.SexprNode(rawParams, hash);
597
- }
598
-
599
- this.sexpr.isRoot = true;
600
-
601
- // Support old AST API that stored this info in MustacheNode
602
- this.id = this.sexpr.id;
603
- this.params = this.sexpr.params;
604
- this.hash = this.sexpr.hash;
605
- this.eligibleHelper = this.sexpr.eligibleHelper;
606
- this.isHelper = this.sexpr.isHelper;
607
- },
608
-
609
- SexprNode: function(rawParams, hash, locInfo) {
610
- LocationInfo.call(this, locInfo);
611
-
612
- this.type = "sexpr";
613
- this.hash = hash;
614
-
615
- var id = this.id = rawParams[0];
616
- var params = this.params = rawParams.slice(1);
617
-
618
- // a mustache is an eligible helper if:
619
- // * its id is simple (a single part, not `this` or `..`)
620
- var eligibleHelper = this.eligibleHelper = id.isSimple;
621
-
622
- // a mustache is definitely a helper if:
623
- // * it is an eligible helper, and
624
- // * it has at least one parameter or hash segment
625
- this.isHelper = eligibleHelper && (params.length || hash);
626
-
627
- // if a mustache is an eligible helper but not a definite
628
- // helper, it is ambiguous, and will be resolved in a later
629
- // pass or at runtime.
630
- },
631
-
632
- PartialNode: function(partialName, context, strip, locInfo) {
633
- LocationInfo.call(this, locInfo);
634
- this.type = "partial";
635
- this.partialName = partialName;
636
- this.context = context;
637
- this.strip = strip;
638
- },
639
-
640
- BlockNode: function(mustache, program, inverse, close, locInfo) {
641
- LocationInfo.call(this, locInfo);
642
-
643
- if(mustache.sexpr.id.original !== close.path.original) {
644
- throw new Exception(mustache.sexpr.id.original + " doesn't match " + close.path.original, this);
645
- }
646
-
647
- this.type = 'block';
648
- this.mustache = mustache;
649
- this.program = program;
650
- this.inverse = inverse;
651
-
652
- this.strip = {
653
- left: mustache.strip.left,
654
- right: close.strip.right
655
- };
656
-
657
- (program || inverse).strip.left = mustache.strip.right;
658
- (inverse || program).strip.right = close.strip.left;
659
-
660
- if (inverse && !program) {
661
- this.isInverse = true;
662
- }
663
- },
664
-
665
- ContentNode: function(string, locInfo) {
666
- LocationInfo.call(this, locInfo);
667
- this.type = "content";
668
- this.string = string;
669
- },
670
-
671
- HashNode: function(pairs, locInfo) {
672
- LocationInfo.call(this, locInfo);
673
- this.type = "hash";
674
- this.pairs = pairs;
675
- },
676
-
677
- IdNode: function(parts, locInfo) {
678
- LocationInfo.call(this, locInfo);
679
- this.type = "ID";
680
-
681
- var original = "",
682
- dig = [],
683
- depth = 0;
684
-
685
- for(var i=0,l=parts.length; i<l; i++) {
686
- var part = parts[i].part;
687
- original += (parts[i].separator || '') + part;
688
-
689
- if (part === ".." || part === "." || part === "this") {
690
- if (dig.length > 0) {
691
- throw new Exception("Invalid path: " + original, this);
692
- } else if (part === "..") {
693
- depth++;
694
- } else {
695
- this.isScoped = true;
696
- }
697
- } else {
698
- dig.push(part);
699
- }
700
- }
701
-
702
- this.original = original;
703
- this.parts = dig;
704
- this.string = dig.join('.');
705
- this.depth = depth;
706
-
707
- // an ID is simple if it only has one part, and that part is not
708
- // `..` or `this`.
709
- this.isSimple = parts.length === 1 && !this.isScoped && depth === 0;
710
-
711
- this.stringModeValue = this.string;
712
- },
713
-
714
- PartialNameNode: function(name, locInfo) {
715
- LocationInfo.call(this, locInfo);
716
- this.type = "PARTIAL_NAME";
717
- this.name = name.original;
718
- },
719
-
720
- DataNode: function(id, locInfo) {
721
- LocationInfo.call(this, locInfo);
722
- this.type = "DATA";
723
- this.id = id;
724
- },
725
-
726
- StringNode: function(string, locInfo) {
727
- LocationInfo.call(this, locInfo);
728
- this.type = "STRING";
729
- this.original =
730
- this.string =
731
- this.stringModeValue = string;
732
- },
733
-
734
- IntegerNode: function(integer, locInfo) {
735
- LocationInfo.call(this, locInfo);
736
- this.type = "INTEGER";
737
- this.original =
738
- this.integer = integer;
739
- this.stringModeValue = Number(integer);
740
- },
741
-
742
- BooleanNode: function(bool, locInfo) {
743
- LocationInfo.call(this, locInfo);
744
- this.type = "BOOLEAN";
745
- this.bool = bool;
746
- this.stringModeValue = bool === "true";
747
- },
748
-
749
- CommentNode: function(comment, locInfo) {
750
- LocationInfo.call(this, locInfo);
751
- this.type = "comment";
752
- this.comment = comment;
753
- }
754
- };
755
-
756
- // Must be exported as an object rather than the root of the module as the jison lexer
757
- // most modify the object to operate properly.
758
- __exports__ = AST;
759
- return __exports__;
760
- })(__module5__);
761
-
762
- // handlebars/compiler/parser.js
763
- var __module9__ = (function() {
764
- "use strict";
765
- var __exports__;
766
- /* jshint ignore:start */
767
- /* Jison generated parser */
768
- var handlebars = (function(){
769
- var parser = {trace: function trace() { },
770
- yy: {},
771
- symbols_: {"error":2,"root":3,"statements":4,"EOF":5,"program":6,"simpleInverse":7,"statement":8,"openInverse":9,"closeBlock":10,"openBlock":11,"mustache":12,"partial":13,"CONTENT":14,"COMMENT":15,"OPEN_BLOCK":16,"sexpr":17,"CLOSE":18,"OPEN_INVERSE":19,"OPEN_ENDBLOCK":20,"path":21,"OPEN":22,"OPEN_UNESCAPED":23,"CLOSE_UNESCAPED":24,"OPEN_PARTIAL":25,"partialName":26,"partial_option0":27,"sexpr_repetition0":28,"sexpr_option0":29,"dataName":30,"param":31,"STRING":32,"INTEGER":33,"BOOLEAN":34,"OPEN_SEXPR":35,"CLOSE_SEXPR":36,"hash":37,"hash_repetition_plus0":38,"hashSegment":39,"ID":40,"EQUALS":41,"DATA":42,"pathSegments":43,"SEP":44,"$accept":0,"$end":1},
772
- terminals_: {2:"error",5:"EOF",14:"CONTENT",15:"COMMENT",16:"OPEN_BLOCK",18:"CLOSE",19:"OPEN_INVERSE",20:"OPEN_ENDBLOCK",22:"OPEN",23:"OPEN_UNESCAPED",24:"CLOSE_UNESCAPED",25:"OPEN_PARTIAL",32:"STRING",33:"INTEGER",34:"BOOLEAN",35:"OPEN_SEXPR",36:"CLOSE_SEXPR",40:"ID",41:"EQUALS",42:"DATA",44:"SEP"},
773
- productions_: [0,[3,2],[3,1],[6,2],[6,3],[6,2],[6,1],[6,1],[6,0],[4,1],[4,2],[8,3],[8,3],[8,1],[8,1],[8,1],[8,1],[11,3],[9,3],[10,3],[12,3],[12,3],[13,4],[7,2],[17,3],[17,1],[31,1],[31,1],[31,1],[31,1],[31,1],[31,3],[37,1],[39,3],[26,1],[26,1],[26,1],[30,2],[21,1],[43,3],[43,1],[27,0],[27,1],[28,0],[28,2],[29,0],[29,1],[38,1],[38,2]],
774
- performAction: function anonymous(yytext,yyleng,yylineno,yy,yystate,$$,_$) {
775
-
776
- var $0 = $$.length - 1;
777
- switch (yystate) {
778
- case 1: return new yy.ProgramNode($$[$0-1], this._$);
779
- break;
780
- case 2: return new yy.ProgramNode([], this._$);
781
- break;
782
- case 3:this.$ = new yy.ProgramNode([], $$[$0-1], $$[$0], this._$);
783
- break;
784
- case 4:this.$ = new yy.ProgramNode($$[$0-2], $$[$0-1], $$[$0], this._$);
785
- break;
786
- case 5:this.$ = new yy.ProgramNode($$[$0-1], $$[$0], [], this._$);
787
- break;
788
- case 6:this.$ = new yy.ProgramNode($$[$0], this._$);
789
- break;
790
- case 7:this.$ = new yy.ProgramNode([], this._$);
791
- break;
792
- case 8:this.$ = new yy.ProgramNode([], this._$);
793
- break;
794
- case 9:this.$ = [$$[$0]];
795
- break;
796
- case 10: $$[$0-1].push($$[$0]); this.$ = $$[$0-1];
797
- break;
798
- case 11:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1].inverse, $$[$0-1], $$[$0], this._$);
799
- break;
800
- case 12:this.$ = new yy.BlockNode($$[$0-2], $$[$0-1], $$[$0-1].inverse, $$[$0], this._$);
801
- break;
802
- case 13:this.$ = $$[$0];
803
- break;
804
- case 14:this.$ = $$[$0];
805
- break;
806
- case 15:this.$ = new yy.ContentNode($$[$0], this._$);
807
- break;
808
- case 16:this.$ = new yy.CommentNode($$[$0], this._$);
809
- break;
810
- case 17:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
811
- break;
812
- case 18:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
813
- break;
814
- case 19:this.$ = {path: $$[$0-1], strip: stripFlags($$[$0-2], $$[$0])};
815
- break;
816
- case 20:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
817
- break;
818
- case 21:this.$ = new yy.MustacheNode($$[$0-1], null, $$[$0-2], stripFlags($$[$0-2], $$[$0]), this._$);
819
- break;
820
- case 22:this.$ = new yy.PartialNode($$[$0-2], $$[$0-1], stripFlags($$[$0-3], $$[$0]), this._$);
821
- break;
822
- case 23:this.$ = stripFlags($$[$0-1], $$[$0]);
823
- break;
824
- case 24:this.$ = new yy.SexprNode([$$[$0-2]].concat($$[$0-1]), $$[$0], this._$);
825
- break;
826
- case 25:this.$ = new yy.SexprNode([$$[$0]], null, this._$);
827
- break;
828
- case 26:this.$ = $$[$0];
829
- break;
830
- case 27:this.$ = new yy.StringNode($$[$0], this._$);
831
- break;
832
- case 28:this.$ = new yy.IntegerNode($$[$0], this._$);
833
- break;
834
- case 29:this.$ = new yy.BooleanNode($$[$0], this._$);
835
- break;
836
- case 30:this.$ = $$[$0];
837
- break;
838
- case 31:$$[$0-1].isHelper = true; this.$ = $$[$0-1];
839
- break;
840
- case 32:this.$ = new yy.HashNode($$[$0], this._$);
841
- break;
842
- case 33:this.$ = [$$[$0-2], $$[$0]];
843
- break;
844
- case 34:this.$ = new yy.PartialNameNode($$[$0], this._$);
845
- break;
846
- case 35:this.$ = new yy.PartialNameNode(new yy.StringNode($$[$0], this._$), this._$);
847
- break;
848
- case 36:this.$ = new yy.PartialNameNode(new yy.IntegerNode($$[$0], this._$));
849
- break;
850
- case 37:this.$ = new yy.DataNode($$[$0], this._$);
851
- break;
852
- case 38:this.$ = new yy.IdNode($$[$0], this._$);
853
- break;
854
- case 39: $$[$0-2].push({part: $$[$0], separator: $$[$0-1]}); this.$ = $$[$0-2];
855
- break;
856
- case 40:this.$ = [{part: $$[$0]}];
857
- break;
858
- case 43:this.$ = [];
859
- break;
860
- case 44:$$[$0-1].push($$[$0]);
861
- break;
862
- case 47:this.$ = [$$[$0]];
863
- break;
864
- case 48:$$[$0-1].push($$[$0]);
865
- break;
866
- }
867
- },
868
- table: [{3:1,4:2,5:[1,3],8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[3]},{5:[1,16],8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],22:[1,13],23:[1,14],25:[1,15]},{1:[2,2]},{5:[2,9],14:[2,9],15:[2,9],16:[2,9],19:[2,9],20:[2,9],22:[2,9],23:[2,9],25:[2,9]},{4:20,6:18,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{4:20,6:22,7:19,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,8],22:[1,13],23:[1,14],25:[1,15]},{5:[2,13],14:[2,13],15:[2,13],16:[2,13],19:[2,13],20:[2,13],22:[2,13],23:[2,13],25:[2,13]},{5:[2,14],14:[2,14],15:[2,14],16:[2,14],19:[2,14],20:[2,14],22:[2,14],23:[2,14],25:[2,14]},{5:[2,15],14:[2,15],15:[2,15],16:[2,15],19:[2,15],20:[2,15],22:[2,15],23:[2,15],25:[2,15]},{5:[2,16],14:[2,16],15:[2,16],16:[2,16],19:[2,16],20:[2,16],22:[2,16],23:[2,16],25:[2,16]},{17:23,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:29,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:30,21:24,30:25,40:[1,28],42:[1,27],43:26},{17:31,21:24,30:25,40:[1,28],42:[1,27],43:26},{21:33,26:32,32:[1,34],33:[1,35],40:[1,28],43:26},{1:[2,1]},{5:[2,10],14:[2,10],15:[2,10],16:[2,10],19:[2,10],20:[2,10],22:[2,10],23:[2,10],25:[2,10]},{10:36,20:[1,37]},{4:38,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,7],22:[1,13],23:[1,14],25:[1,15]},{7:39,8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,21],20:[2,6],22:[1,13],23:[1,14],25:[1,15]},{17:23,18:[1,40],21:24,30:25,40:[1,28],42:[1,27],43:26},{10:41,20:[1,37]},{18:[1,42]},{18:[2,43],24:[2,43],28:43,32:[2,43],33:[2,43],34:[2,43],35:[2,43],36:[2,43],40:[2,43],42:[2,43]},{18:[2,25],24:[2,25],36:[2,25]},{18:[2,38],24:[2,38],32:[2,38],33:[2,38],34:[2,38],35:[2,38],36:[2,38],40:[2,38],42:[2,38],44:[1,44]},{21:45,40:[1,28],43:26},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],42:[2,40],44:[2,40]},{18:[1,46]},{18:[1,47]},{24:[1,48]},{18:[2,41],21:50,27:49,40:[1,28],43:26},{18:[2,34],40:[2,34]},{18:[2,35],40:[2,35]},{18:[2,36],40:[2,36]},{5:[2,11],14:[2,11],15:[2,11],16:[2,11],19:[2,11],20:[2,11],22:[2,11],23:[2,11],25:[2,11]},{21:51,40:[1,28],43:26},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,3],22:[1,13],23:[1,14],25:[1,15]},{4:52,8:4,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,5],22:[1,13],23:[1,14],25:[1,15]},{14:[2,23],15:[2,23],16:[2,23],19:[2,23],20:[2,23],22:[2,23],23:[2,23],25:[2,23]},{5:[2,12],14:[2,12],15:[2,12],16:[2,12],19:[2,12],20:[2,12],22:[2,12],23:[2,12],25:[2,12]},{14:[2,18],15:[2,18],16:[2,18],19:[2,18],20:[2,18],22:[2,18],23:[2,18],25:[2,18]},{18:[2,45],21:56,24:[2,45],29:53,30:60,31:54,32:[1,57],33:[1,58],34:[1,59],35:[1,61],36:[2,45],37:55,38:62,39:63,40:[1,64],42:[1,27],43:26},{40:[1,65]},{18:[2,37],24:[2,37],32:[2,37],33:[2,37],34:[2,37],35:[2,37],36:[2,37],40:[2,37],42:[2,37]},{14:[2,17],15:[2,17],16:[2,17],19:[2,17],20:[2,17],22:[2,17],23:[2,17],25:[2,17]},{5:[2,20],14:[2,20],15:[2,20],16:[2,20],19:[2,20],20:[2,20],22:[2,20],23:[2,20],25:[2,20]},{5:[2,21],14:[2,21],15:[2,21],16:[2,21],19:[2,21],20:[2,21],22:[2,21],23:[2,21],25:[2,21]},{18:[1,66]},{18:[2,42]},{18:[1,67]},{8:17,9:5,11:6,12:7,13:8,14:[1,9],15:[1,10],16:[1,12],19:[1,11],20:[2,4],22:[1,13],23:[1,14],25:[1,15]},{18:[2,24],24:[2,24],36:[2,24]},{18:[2,44],24:[2,44],32:[2,44],33:[2,44],34:[2,44],35:[2,44],36:[2,44],40:[2,44],42:[2,44]},{18:[2,46],24:[2,46],36:[2,46]},{18:[2,26],24:[2,26],32:[2,26],33:[2,26],34:[2,26],35:[2,26],36:[2,26],40:[2,26],42:[2,26]},{18:[2,27],24:[2,27],32:[2,27],33:[2,27],34:[2,27],35:[2,27],36:[2,27],40:[2,27],42:[2,27]},{18:[2,28],24:[2,28],32:[2,28],33:[2,28],34:[2,28],35:[2,28],36:[2,28],40:[2,28],42:[2,28]},{18:[2,29],24:[2,29],32:[2,29],33:[2,29],34:[2,29],35:[2,29],36:[2,29],40:[2,29],42:[2,29]},{18:[2,30],24:[2,30],32:[2,30],33:[2,30],34:[2,30],35:[2,30],36:[2,30],40:[2,30],42:[2,30]},{17:68,21:24,30:25,40:[1,28],42:[1,27],43:26},{18:[2,32],24:[2,32],36:[2,32],39:69,40:[1,70]},{18:[2,47],24:[2,47],36:[2,47],40:[2,47]},{18:[2,40],24:[2,40],32:[2,40],33:[2,40],34:[2,40],35:[2,40],36:[2,40],40:[2,40],41:[1,71],42:[2,40],44:[2,40]},{18:[2,39],24:[2,39],32:[2,39],33:[2,39],34:[2,39],35:[2,39],36:[2,39],40:[2,39],42:[2,39],44:[2,39]},{5:[2,22],14:[2,22],15:[2,22],16:[2,22],19:[2,22],20:[2,22],22:[2,22],23:[2,22],25:[2,22]},{5:[2,19],14:[2,19],15:[2,19],16:[2,19],19:[2,19],20:[2,19],22:[2,19],23:[2,19],25:[2,19]},{36:[1,72]},{18:[2,48],24:[2,48],36:[2,48],40:[2,48]},{41:[1,71]},{21:56,30:60,31:73,32:[1,57],33:[1,58],34:[1,59],35:[1,61],40:[1,28],42:[1,27],43:26},{18:[2,31],24:[2,31],32:[2,31],33:[2,31],34:[2,31],35:[2,31],36:[2,31],40:[2,31],42:[2,31]},{18:[2,33],24:[2,33],36:[2,33],40:[2,33]}],
869
- defaultActions: {3:[2,2],16:[2,1],50:[2,42]},
870
- parseError: function parseError(str, hash) {
871
- throw new Error(str);
872
- },
873
- parse: function parse(input) {
874
- var self = this, stack = [0], vstack = [null], lstack = [], table = this.table, yytext = "", yylineno = 0, yyleng = 0, recovering = 0, TERROR = 2, EOF = 1;
875
- this.lexer.setInput(input);
876
- this.lexer.yy = this.yy;
877
- this.yy.lexer = this.lexer;
878
- this.yy.parser = this;
879
- if (typeof this.lexer.yylloc == "undefined")
880
- this.lexer.yylloc = {};
881
- var yyloc = this.lexer.yylloc;
882
- lstack.push(yyloc);
883
- var ranges = this.lexer.options && this.lexer.options.ranges;
884
- if (typeof this.yy.parseError === "function")
885
- this.parseError = this.yy.parseError;
886
- function popStack(n) {
887
- stack.length = stack.length - 2 * n;
888
- vstack.length = vstack.length - n;
889
- lstack.length = lstack.length - n;
890
- }
891
- function lex() {
892
- var token;
893
- token = self.lexer.lex() || 1;
894
- if (typeof token !== "number") {
895
- token = self.symbols_[token] || token;
896
- }
897
- return token;
898
- }
899
- var symbol, preErrorSymbol, state, action, a, r, yyval = {}, p, len, newState, expected;
900
- while (true) {
901
- state = stack[stack.length - 1];
902
- if (this.defaultActions[state]) {
903
- action = this.defaultActions[state];
904
- } else {
905
- if (symbol === null || typeof symbol == "undefined") {
906
- symbol = lex();
907
- }
908
- action = table[state] && table[state][symbol];
909
- }
910
- if (typeof action === "undefined" || !action.length || !action[0]) {
911
- var errStr = "";
912
- if (!recovering) {
913
- expected = [];
914
- for (p in table[state])
915
- if (this.terminals_[p] && p > 2) {
916
- expected.push("'" + this.terminals_[p] + "'");
917
- }
918
- if (this.lexer.showPosition) {
919
- errStr = "Parse error on line " + (yylineno + 1) + ":\n" + this.lexer.showPosition() + "\nExpecting " + expected.join(", ") + ", got '" + (this.terminals_[symbol] || symbol) + "'";
920
- } else {
921
- errStr = "Parse error on line " + (yylineno + 1) + ": Unexpected " + (symbol == 1?"end of input":"'" + (this.terminals_[symbol] || symbol) + "'");
922
- }
923
- this.parseError(errStr, {text: this.lexer.match, token: this.terminals_[symbol] || symbol, line: this.lexer.yylineno, loc: yyloc, expected: expected});
924
- }
925
- }
926
- if (action[0] instanceof Array && action.length > 1) {
927
- throw new Error("Parse Error: multiple actions possible at state: " + state + ", token: " + symbol);
928
- }
929
- switch (action[0]) {
930
- case 1:
931
- stack.push(symbol);
932
- vstack.push(this.lexer.yytext);
933
- lstack.push(this.lexer.yylloc);
934
- stack.push(action[1]);
935
- symbol = null;
936
- if (!preErrorSymbol) {
937
- yyleng = this.lexer.yyleng;
938
- yytext = this.lexer.yytext;
939
- yylineno = this.lexer.yylineno;
940
- yyloc = this.lexer.yylloc;
941
- if (recovering > 0)
942
- recovering--;
943
- } else {
944
- symbol = preErrorSymbol;
945
- preErrorSymbol = null;
946
- }
947
- break;
948
- case 2:
949
- len = this.productions_[action[1]][1];
950
- yyval.$ = vstack[vstack.length - len];
951
- yyval._$ = {first_line: lstack[lstack.length - (len || 1)].first_line, last_line: lstack[lstack.length - 1].last_line, first_column: lstack[lstack.length - (len || 1)].first_column, last_column: lstack[lstack.length - 1].last_column};
952
- if (ranges) {
953
- yyval._$.range = [lstack[lstack.length - (len || 1)].range[0], lstack[lstack.length - 1].range[1]];
954
- }
955
- r = this.performAction.call(yyval, yytext, yyleng, yylineno, this.yy, action[1], vstack, lstack);
956
- if (typeof r !== "undefined") {
957
- return r;
958
- }
959
- if (len) {
960
- stack = stack.slice(0, -1 * len * 2);
961
- vstack = vstack.slice(0, -1 * len);
962
- lstack = lstack.slice(0, -1 * len);
963
- }
964
- stack.push(this.productions_[action[1]][0]);
965
- vstack.push(yyval.$);
966
- lstack.push(yyval._$);
967
- newState = table[stack[stack.length - 2]][stack[stack.length - 1]];
968
- stack.push(newState);
969
- break;
970
- case 3:
971
- return true;
972
- }
973
- }
974
- return true;
975
- }
976
- };
977
-
978
-
979
- function stripFlags(open, close) {
980
- return {
981
- left: open.charAt(2) === '~',
982
- right: close.charAt(0) === '~' || close.charAt(1) === '~'
983
- };
984
- }
985
-
986
- /* Jison generated lexer */
987
- var lexer = (function(){
988
- var lexer = ({EOF:1,
989
- parseError:function parseError(str, hash) {
990
- if (this.yy.parser) {
991
- this.yy.parser.parseError(str, hash);
992
- } else {
993
- throw new Error(str);
994
- }
995
- },
996
- setInput:function (input) {
997
- this._input = input;
998
- this._more = this._less = this.done = false;
999
- this.yylineno = this.yyleng = 0;
1000
- this.yytext = this.matched = this.match = '';
1001
- this.conditionStack = ['INITIAL'];
1002
- this.yylloc = {first_line:1,first_column:0,last_line:1,last_column:0};
1003
- if (this.options.ranges) this.yylloc.range = [0,0];
1004
- this.offset = 0;
1005
- return this;
1006
- },
1007
- input:function () {
1008
- var ch = this._input[0];
1009
- this.yytext += ch;
1010
- this.yyleng++;
1011
- this.offset++;
1012
- this.match += ch;
1013
- this.matched += ch;
1014
- var lines = ch.match(/(?:\r\n?|\n).*/g);
1015
- if (lines) {
1016
- this.yylineno++;
1017
- this.yylloc.last_line++;
1018
- } else {
1019
- this.yylloc.last_column++;
1020
- }
1021
- if (this.options.ranges) this.yylloc.range[1]++;
1022
-
1023
- this._input = this._input.slice(1);
1024
- return ch;
1025
- },
1026
- unput:function (ch) {
1027
- var len = ch.length;
1028
- var lines = ch.split(/(?:\r\n?|\n)/g);
1029
-
1030
- this._input = ch + this._input;
1031
- this.yytext = this.yytext.substr(0, this.yytext.length-len-1);
1032
- //this.yyleng -= len;
1033
- this.offset -= len;
1034
- var oldLines = this.match.split(/(?:\r\n?|\n)/g);
1035
- this.match = this.match.substr(0, this.match.length-1);
1036
- this.matched = this.matched.substr(0, this.matched.length-1);
1037
-
1038
- if (lines.length-1) this.yylineno -= lines.length-1;
1039
- var r = this.yylloc.range;
1040
-
1041
- this.yylloc = {first_line: this.yylloc.first_line,
1042
- last_line: this.yylineno+1,
1043
- first_column: this.yylloc.first_column,
1044
- last_column: lines ?
1045
- (lines.length === oldLines.length ? this.yylloc.first_column : 0) + oldLines[oldLines.length - lines.length].length - lines[0].length:
1046
- this.yylloc.first_column - len
1047
- };
1048
-
1049
- if (this.options.ranges) {
1050
- this.yylloc.range = [r[0], r[0] + this.yyleng - len];
1051
- }
1052
- return this;
1053
- },
1054
- more:function () {
1055
- this._more = true;
1056
- return this;
1057
- },
1058
- less:function (n) {
1059
- this.unput(this.match.slice(n));
1060
- },
1061
- pastInput:function () {
1062
- var past = this.matched.substr(0, this.matched.length - this.match.length);
1063
- return (past.length > 20 ? '...':'') + past.substr(-20).replace(/\n/g, "");
1064
- },
1065
- upcomingInput:function () {
1066
- var next = this.match;
1067
- if (next.length < 20) {
1068
- next += this._input.substr(0, 20-next.length);
1069
- }
1070
- return (next.substr(0,20)+(next.length > 20 ? '...':'')).replace(/\n/g, "");
1071
- },
1072
- showPosition:function () {
1073
- var pre = this.pastInput();
1074
- var c = new Array(pre.length + 1).join("-");
1075
- return pre + this.upcomingInput() + "\n" + c+"^";
1076
- },
1077
- next:function () {
1078
- if (this.done) {
1079
- return this.EOF;
1080
- }
1081
- if (!this._input) this.done = true;
1082
-
1083
- var token,
1084
- match,
1085
- tempMatch,
1086
- index,
1087
- col,
1088
- lines;
1089
- if (!this._more) {
1090
- this.yytext = '';
1091
- this.match = '';
1092
- }
1093
- var rules = this._currentRules();
1094
- for (var i=0;i < rules.length; i++) {
1095
- tempMatch = this._input.match(this.rules[rules[i]]);
1096
- if (tempMatch && (!match || tempMatch[0].length > match[0].length)) {
1097
- match = tempMatch;
1098
- index = i;
1099
- if (!this.options.flex) break;
1100
- }
1101
- }
1102
- if (match) {
1103
- lines = match[0].match(/(?:\r\n?|\n).*/g);
1104
- if (lines) this.yylineno += lines.length;
1105
- this.yylloc = {first_line: this.yylloc.last_line,
1106
- last_line: this.yylineno+1,
1107
- first_column: this.yylloc.last_column,
1108
- last_column: lines ? lines[lines.length-1].length-lines[lines.length-1].match(/\r?\n?/)[0].length : this.yylloc.last_column + match[0].length};
1109
- this.yytext += match[0];
1110
- this.match += match[0];
1111
- this.matches = match;
1112
- this.yyleng = this.yytext.length;
1113
- if (this.options.ranges) {
1114
- this.yylloc.range = [this.offset, this.offset += this.yyleng];
1115
- }
1116
- this._more = false;
1117
- this._input = this._input.slice(match[0].length);
1118
- this.matched += match[0];
1119
- token = this.performAction.call(this, this.yy, this, rules[index],this.conditionStack[this.conditionStack.length-1]);
1120
- if (this.done && this._input) this.done = false;
1121
- if (token) return token;
1122
- else return;
1123
- }
1124
- if (this._input === "") {
1125
- return this.EOF;
1126
- } else {
1127
- return this.parseError('Lexical error on line '+(this.yylineno+1)+'. Unrecognized text.\n'+this.showPosition(),
1128
- {text: "", token: null, line: this.yylineno});
1129
- }
1130
- },
1131
- lex:function lex() {
1132
- var r = this.next();
1133
- if (typeof r !== 'undefined') {
1134
- return r;
1135
- } else {
1136
- return this.lex();
1137
- }
1138
- },
1139
- begin:function begin(condition) {
1140
- this.conditionStack.push(condition);
1141
- },
1142
- popState:function popState() {
1143
- return this.conditionStack.pop();
1144
- },
1145
- _currentRules:function _currentRules() {
1146
- return this.conditions[this.conditionStack[this.conditionStack.length-1]].rules;
1147
- },
1148
- topState:function () {
1149
- return this.conditionStack[this.conditionStack.length-2];
1150
- },
1151
- pushState:function begin(condition) {
1152
- this.begin(condition);
1153
- }});
1154
- lexer.options = {};
1155
- lexer.performAction = function anonymous(yy,yy_,$avoiding_name_collisions,YY_START) {
1156
-
1157
-
1158
- function strip(start, end) {
1159
- return yy_.yytext = yy_.yytext.substr(start, yy_.yyleng-end);
1160
- }
1161
-
1162
-
1163
- var YYSTATE=YY_START
1164
- switch($avoiding_name_collisions) {
1165
- case 0:
1166
- if(yy_.yytext.slice(-2) === "\\\\") {
1167
- strip(0,1);
1168
- this.begin("mu");
1169
- } else if(yy_.yytext.slice(-1) === "\\") {
1170
- strip(0,1);
1171
- this.begin("emu");
1172
- } else {
1173
- this.begin("mu");
1174
- }
1175
- if(yy_.yytext) return 14;
1176
-
1177
- break;
1178
- case 1:return 14;
1179
- break;
1180
- case 2:
1181
- this.popState();
1182
- return 14;
1183
-
1184
- break;
1185
- case 3:strip(0,4); this.popState(); return 15;
1186
- break;
1187
- case 4:return 35;
1188
- break;
1189
- case 5:return 36;
1190
- break;
1191
- case 6:return 25;
1192
- break;
1193
- case 7:return 16;
1194
- break;
1195
- case 8:return 20;
1196
- break;
1197
- case 9:return 19;
1198
- break;
1199
- case 10:return 19;
1200
- break;
1201
- case 11:return 23;
1202
- break;
1203
- case 12:return 22;
1204
- break;
1205
- case 13:this.popState(); this.begin('com');
1206
- break;
1207
- case 14:strip(3,5); this.popState(); return 15;
1208
- break;
1209
- case 15:return 22;
1210
- break;
1211
- case 16:return 41;
1212
- break;
1213
- case 17:return 40;
1214
- break;
1215
- case 18:return 40;
1216
- break;
1217
- case 19:return 44;
1218
- break;
1219
- case 20:// ignore whitespace
1220
- break;
1221
- case 21:this.popState(); return 24;
1222
- break;
1223
- case 22:this.popState(); return 18;
1224
- break;
1225
- case 23:yy_.yytext = strip(1,2).replace(/\\"/g,'"'); return 32;
1226
- break;
1227
- case 24:yy_.yytext = strip(1,2).replace(/\\'/g,"'"); return 32;
1228
- break;
1229
- case 25:return 42;
1230
- break;
1231
- case 26:return 34;
1232
- break;
1233
- case 27:return 34;
1234
- break;
1235
- case 28:return 33;
1236
- break;
1237
- case 29:return 40;
1238
- break;
1239
- case 30:yy_.yytext = strip(1,2); return 40;
1240
- break;
1241
- case 31:return 'INVALID';
1242
- break;
1243
- case 32:return 5;
1244
- break;
1245
- }
1246
- };
1247
- lexer.rules = [/^(?:[^\x00]*?(?=(\{\{)))/,/^(?:[^\x00]+)/,/^(?:[^\x00]{2,}?(?=(\{\{|\\\{\{|\\\\\{\{|$)))/,/^(?:[\s\S]*?--\}\})/,/^(?:\()/,/^(?:\))/,/^(?:\{\{(~)?>)/,/^(?:\{\{(~)?#)/,/^(?:\{\{(~)?\/)/,/^(?:\{\{(~)?\^)/,/^(?:\{\{(~)?\s*else\b)/,/^(?:\{\{(~)?\{)/,/^(?:\{\{(~)?&)/,/^(?:\{\{!--)/,/^(?:\{\{![\s\S]*?\}\})/,/^(?:\{\{(~)?)/,/^(?:=)/,/^(?:\.\.)/,/^(?:\.(?=([=~}\s\/.)])))/,/^(?:[\/.])/,/^(?:\s+)/,/^(?:\}(~)?\}\})/,/^(?:(~)?\}\})/,/^(?:"(\\["]|[^"])*")/,/^(?:'(\\[']|[^'])*')/,/^(?:@)/,/^(?:true(?=([~}\s)])))/,/^(?:false(?=([~}\s)])))/,/^(?:-?[0-9]+(?=([~}\s)])))/,/^(?:([^\s!"#%-,\.\/;->@\[-\^`\{-~]+(?=([=~}\s\/.)]))))/,/^(?:\[[^\]]*\])/,/^(?:.)/,/^(?:$)/];
1248
- lexer.conditions = {"mu":{"rules":[4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32],"inclusive":false},"emu":{"rules":[2],"inclusive":false},"com":{"rules":[3],"inclusive":false},"INITIAL":{"rules":[0,1,32],"inclusive":true}};
1249
- return lexer;})()
1250
- parser.lexer = lexer;
1251
- function Parser () { this.yy = {}; }Parser.prototype = parser;parser.Parser = Parser;
1252
- return new Parser;
1253
- })();__exports__ = handlebars;
1254
- /* jshint ignore:end */
1255
- return __exports__;
1256
- })();
1257
-
1258
- // handlebars/compiler/base.js
1259
- var __module8__ = (function(__dependency1__, __dependency2__) {
1260
- "use strict";
1261
- var __exports__ = {};
1262
- var parser = __dependency1__;
1263
- var AST = __dependency2__;
1264
-
1265
- __exports__.parser = parser;
1266
-
1267
- function parse(input) {
1268
- // Just return if an already-compile AST was passed in.
1269
- if(input.constructor === AST.ProgramNode) { return input; }
1270
-
1271
- parser.yy = AST;
1272
- return parser.parse(input);
1273
- }
1274
-
1275
- __exports__.parse = parse;
1276
- return __exports__;
1277
- })(__module9__, __module7__);
1278
-
1279
- // handlebars/compiler/compiler.js
1280
- var __module10__ = (function(__dependency1__) {
1281
- "use strict";
1282
- var __exports__ = {};
1283
- var Exception = __dependency1__;
1284
-
1285
- function Compiler() {}
1286
-
1287
- __exports__.Compiler = Compiler;// the foundHelper register will disambiguate helper lookup from finding a
1288
- // function in a context. This is necessary for mustache compatibility, which
1289
- // requires that context functions in blocks are evaluated by blockHelperMissing,
1290
- // and then proceed as if the resulting value was provided to blockHelperMissing.
1291
-
1292
- Compiler.prototype = {
1293
- compiler: Compiler,
1294
-
1295
- disassemble: function() {
1296
- var opcodes = this.opcodes, opcode, out = [], params, param;
1297
-
1298
- for (var i=0, l=opcodes.length; i<l; i++) {
1299
- opcode = opcodes[i];
1300
-
1301
- if (opcode.opcode === 'DECLARE') {
1302
- out.push("DECLARE " + opcode.name + "=" + opcode.value);
1303
- } else {
1304
- params = [];
1305
- for (var j=0; j<opcode.args.length; j++) {
1306
- param = opcode.args[j];
1307
- if (typeof param === "string") {
1308
- param = "\"" + param.replace("\n", "\\n") + "\"";
1309
- }
1310
- params.push(param);
1311
- }
1312
- out.push(opcode.opcode + " " + params.join(" "));
1313
- }
1314
- }
1315
-
1316
- return out.join("\n");
1317
- },
1318
-
1319
- equals: function(other) {
1320
- var len = this.opcodes.length;
1321
- if (other.opcodes.length !== len) {
1322
- return false;
1323
- }
1324
-
1325
- for (var i = 0; i < len; i++) {
1326
- var opcode = this.opcodes[i],
1327
- otherOpcode = other.opcodes[i];
1328
- if (opcode.opcode !== otherOpcode.opcode || opcode.args.length !== otherOpcode.args.length) {
1329
- return false;
1330
- }
1331
- for (var j = 0; j < opcode.args.length; j++) {
1332
- if (opcode.args[j] !== otherOpcode.args[j]) {
1333
- return false;
1334
- }
1335
- }
1336
- }
1337
-
1338
- len = this.children.length;
1339
- if (other.children.length !== len) {
1340
- return false;
1341
- }
1342
- for (i = 0; i < len; i++) {
1343
- if (!this.children[i].equals(other.children[i])) {
1344
- return false;
1345
- }
1346
- }
1347
-
1348
- return true;
1349
- },
1350
-
1351
- guid: 0,
1352
-
1353
- compile: function(program, options) {
1354
- this.opcodes = [];
1355
- this.children = [];
1356
- this.depths = {list: []};
1357
- this.options = options;
1358
-
1359
- // These changes will propagate to the other compiler components
1360
- var knownHelpers = this.options.knownHelpers;
1361
- this.options.knownHelpers = {
1362
- 'helperMissing': true,
1363
- 'blockHelperMissing': true,
1364
- 'each': true,
1365
- 'if': true,
1366
- 'unless': true,
1367
- 'with': true,
1368
- 'log': true
1369
- };
1370
- if (knownHelpers) {
1371
- for (var name in knownHelpers) {
1372
- this.options.knownHelpers[name] = knownHelpers[name];
1373
- }
1374
- }
1375
-
1376
- return this.accept(program);
1377
- },
1378
-
1379
- accept: function(node) {
1380
- var strip = node.strip || {},
1381
- ret;
1382
- if (strip.left) {
1383
- this.opcode('strip');
1384
- }
1385
-
1386
- ret = this[node.type](node);
1387
-
1388
- if (strip.right) {
1389
- this.opcode('strip');
1390
- }
1391
-
1392
- return ret;
1393
- },
1394
-
1395
- program: function(program) {
1396
- var statements = program.statements;
1397
-
1398
- for(var i=0, l=statements.length; i<l; i++) {
1399
- this.accept(statements[i]);
1400
- }
1401
- this.isSimple = l === 1;
1402
-
1403
- this.depths.list = this.depths.list.sort(function(a, b) {
1404
- return a - b;
1405
- });
1406
-
1407
- return this;
1408
- },
1409
-
1410
- compileProgram: function(program) {
1411
- var result = new this.compiler().compile(program, this.options);
1412
- var guid = this.guid++, depth;
1413
-
1414
- this.usePartial = this.usePartial || result.usePartial;
1415
-
1416
- this.children[guid] = result;
1417
-
1418
- for(var i=0, l=result.depths.list.length; i<l; i++) {
1419
- depth = result.depths.list[i];
1420
-
1421
- if(depth < 2) { continue; }
1422
- else { this.addDepth(depth - 1); }
1423
- }
1424
-
1425
- return guid;
1426
- },
1427
-
1428
- block: function(block) {
1429
- var mustache = block.mustache,
1430
- program = block.program,
1431
- inverse = block.inverse;
1432
-
1433
- if (program) {
1434
- program = this.compileProgram(program);
1435
- }
1436
-
1437
- if (inverse) {
1438
- inverse = this.compileProgram(inverse);
1439
- }
1440
-
1441
- var sexpr = mustache.sexpr;
1442
- var type = this.classifySexpr(sexpr);
1443
-
1444
- if (type === "helper") {
1445
- this.helperSexpr(sexpr, program, inverse);
1446
- } else if (type === "simple") {
1447
- this.simpleSexpr(sexpr);
1448
-
1449
- // now that the simple mustache is resolved, we need to
1450
- // evaluate it by executing `blockHelperMissing`
1451
- this.opcode('pushProgram', program);
1452
- this.opcode('pushProgram', inverse);
1453
- this.opcode('emptyHash');
1454
- this.opcode('blockValue');
1455
- } else {
1456
- this.ambiguousSexpr(sexpr, program, inverse);
1457
-
1458
- // now that the simple mustache is resolved, we need to
1459
- // evaluate it by executing `blockHelperMissing`
1460
- this.opcode('pushProgram', program);
1461
- this.opcode('pushProgram', inverse);
1462
- this.opcode('emptyHash');
1463
- this.opcode('ambiguousBlockValue');
1464
- }
1465
-
1466
- this.opcode('append');
1467
- },
1468
-
1469
- hash: function(hash) {
1470
- var pairs = hash.pairs, pair, val;
1471
-
1472
- this.opcode('pushHash');
1473
-
1474
- for(var i=0, l=pairs.length; i<l; i++) {
1475
- pair = pairs[i];
1476
- val = pair[1];
1477
-
1478
- if (this.options.stringParams) {
1479
- if(val.depth) {
1480
- this.addDepth(val.depth);
1481
- }
1482
- this.opcode('getContext', val.depth || 0);
1483
- this.opcode('pushStringParam', val.stringModeValue, val.type);
1484
-
1485
- if (val.type === 'sexpr') {
1486
- // Subexpressions get evaluated and passed in
1487
- // in string params mode.
1488
- this.sexpr(val);
1489
- }
1490
- } else {
1491
- this.accept(val);
1492
- }
1493
-
1494
- this.opcode('assignToHash', pair[0]);
1495
- }
1496
- this.opcode('popHash');
1497
- },
1498
-
1499
- partial: function(partial) {
1500
- var partialName = partial.partialName;
1501
- this.usePartial = true;
1502
-
1503
- if(partial.context) {
1504
- this.ID(partial.context);
1505
- } else {
1506
- this.opcode('push', 'depth0');
1507
- }
1508
-
1509
- this.opcode('invokePartial', partialName.name);
1510
- this.opcode('append');
1511
- },
1512
-
1513
- content: function(content) {
1514
- this.opcode('appendContent', content.string);
1515
- },
1516
-
1517
- mustache: function(mustache) {
1518
- this.sexpr(mustache.sexpr);
1519
-
1520
- if(mustache.escaped && !this.options.noEscape) {
1521
- this.opcode('appendEscaped');
1522
- } else {
1523
- this.opcode('append');
1524
- }
1525
- },
1526
-
1527
- ambiguousSexpr: function(sexpr, program, inverse) {
1528
- var id = sexpr.id,
1529
- name = id.parts[0],
1530
- isBlock = program != null || inverse != null;
1531
-
1532
- this.opcode('getContext', id.depth);
1533
-
1534
- this.opcode('pushProgram', program);
1535
- this.opcode('pushProgram', inverse);
1536
-
1537
- this.opcode('invokeAmbiguous', name, isBlock);
1538
- },
1539
-
1540
- simpleSexpr: function(sexpr) {
1541
- var id = sexpr.id;
1542
-
1543
- if (id.type === 'DATA') {
1544
- this.DATA(id);
1545
- } else if (id.parts.length) {
1546
- this.ID(id);
1547
- } else {
1548
- // Simplified ID for `this`
1549
- this.addDepth(id.depth);
1550
- this.opcode('getContext', id.depth);
1551
- this.opcode('pushContext');
1552
- }
1553
-
1554
- this.opcode('resolvePossibleLambda');
1555
- },
1556
-
1557
- helperSexpr: function(sexpr, program, inverse) {
1558
- var params = this.setupFullMustacheParams(sexpr, program, inverse),
1559
- name = sexpr.id.parts[0];
1560
-
1561
- if (this.options.knownHelpers[name]) {
1562
- this.opcode('invokeKnownHelper', params.length, name);
1563
- } else if (this.options.knownHelpersOnly) {
1564
- throw new Exception("You specified knownHelpersOnly, but used the unknown helper " + name, sexpr);
1565
- } else {
1566
- this.opcode('invokeHelper', params.length, name, sexpr.isRoot);
1567
- }
1568
- },
1569
-
1570
- sexpr: function(sexpr) {
1571
- var type = this.classifySexpr(sexpr);
1572
-
1573
- if (type === "simple") {
1574
- this.simpleSexpr(sexpr);
1575
- } else if (type === "helper") {
1576
- this.helperSexpr(sexpr);
1577
- } else {
1578
- this.ambiguousSexpr(sexpr);
1579
- }
1580
- },
1581
-
1582
- ID: function(id) {
1583
- this.addDepth(id.depth);
1584
- this.opcode('getContext', id.depth);
1585
-
1586
- var name = id.parts[0];
1587
- if (!name) {
1588
- this.opcode('pushContext');
1589
- } else {
1590
- this.opcode('lookupOnContext', id.parts[0]);
1591
- }
1592
-
1593
- for(var i=1, l=id.parts.length; i<l; i++) {
1594
- this.opcode('lookup', id.parts[i]);
1595
- }
1596
- },
1597
-
1598
- DATA: function(data) {
1599
- this.options.data = true;
1600
- if (data.id.isScoped || data.id.depth) {
1601
- throw new Exception('Scoped data references are not supported: ' + data.original, data);
1602
- }
1603
-
1604
- this.opcode('lookupData');
1605
- var parts = data.id.parts;
1606
- for(var i=0, l=parts.length; i<l; i++) {
1607
- this.opcode('lookup', parts[i]);
1608
- }
1609
- },
1610
-
1611
- STRING: function(string) {
1612
- this.opcode('pushString', string.string);
1613
- },
1614
-
1615
- INTEGER: function(integer) {
1616
- this.opcode('pushLiteral', integer.integer);
1617
- },
1618
-
1619
- BOOLEAN: function(bool) {
1620
- this.opcode('pushLiteral', bool.bool);
1621
- },
1622
-
1623
- comment: function() {},
1624
-
1625
- // HELPERS
1626
- opcode: function(name) {
1627
- this.opcodes.push({ opcode: name, args: [].slice.call(arguments, 1) });
1628
- },
1629
-
1630
- declare: function(name, value) {
1631
- this.opcodes.push({ opcode: 'DECLARE', name: name, value: value });
1632
- },
1633
-
1634
- addDepth: function(depth) {
1635
- if(depth === 0) { return; }
1636
-
1637
- if(!this.depths[depth]) {
1638
- this.depths[depth] = true;
1639
- this.depths.list.push(depth);
1640
- }
1641
- },
1642
-
1643
- classifySexpr: function(sexpr) {
1644
- var isHelper = sexpr.isHelper;
1645
- var isEligible = sexpr.eligibleHelper;
1646
- var options = this.options;
1647
-
1648
- // if ambiguous, we can possibly resolve the ambiguity now
1649
- if (isEligible && !isHelper) {
1650
- var name = sexpr.id.parts[0];
1651
-
1652
- if (options.knownHelpers[name]) {
1653
- isHelper = true;
1654
- } else if (options.knownHelpersOnly) {
1655
- isEligible = false;
1656
- }
1657
- }
1658
-
1659
- if (isHelper) { return "helper"; }
1660
- else if (isEligible) { return "ambiguous"; }
1661
- else { return "simple"; }
1662
- },
1663
-
1664
- pushParams: function(params) {
1665
- var i = params.length, param;
1666
-
1667
- while(i--) {
1668
- param = params[i];
1669
-
1670
- if(this.options.stringParams) {
1671
- if(param.depth) {
1672
- this.addDepth(param.depth);
1673
- }
1674
-
1675
- this.opcode('getContext', param.depth || 0);
1676
- this.opcode('pushStringParam', param.stringModeValue, param.type);
1677
-
1678
- if (param.type === 'sexpr') {
1679
- // Subexpressions get evaluated and passed in
1680
- // in string params mode.
1681
- this.sexpr(param);
1682
- }
1683
- } else {
1684
- this[param.type](param);
1685
- }
1686
- }
1687
- },
1688
-
1689
- setupFullMustacheParams: function(sexpr, program, inverse) {
1690
- var params = sexpr.params;
1691
- this.pushParams(params);
1692
-
1693
- this.opcode('pushProgram', program);
1694
- this.opcode('pushProgram', inverse);
1695
-
1696
- if (sexpr.hash) {
1697
- this.hash(sexpr.hash);
1698
- } else {
1699
- this.opcode('emptyHash');
1700
- }
1701
-
1702
- return params;
1703
- }
1704
- };
1705
-
1706
- function precompile(input, options, env) {
1707
- if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
1708
- throw new Exception("You must pass a string or Handlebars AST to Handlebars.precompile. You passed " + input);
1709
- }
1710
-
1711
- options = options || {};
1712
- if (!('data' in options)) {
1713
- options.data = true;
1714
- }
1715
-
1716
- var ast = env.parse(input);
1717
- var environment = new env.Compiler().compile(ast, options);
1718
- return new env.JavaScriptCompiler().compile(environment, options);
1719
- }
1720
-
1721
- __exports__.precompile = precompile;function compile(input, options, env) {
1722
- if (input == null || (typeof input !== 'string' && input.constructor !== env.AST.ProgramNode)) {
1723
- throw new Exception("You must pass a string or Handlebars AST to Handlebars.compile. You passed " + input);
1724
- }
1725
-
1726
- options = options || {};
1727
-
1728
- if (!('data' in options)) {
1729
- options.data = true;
1730
- }
1731
-
1732
- var compiled;
1733
-
1734
- function compileInput() {
1735
- var ast = env.parse(input);
1736
- var environment = new env.Compiler().compile(ast, options);
1737
- var templateSpec = new env.JavaScriptCompiler().compile(environment, options, undefined, true);
1738
- return env.template(templateSpec);
1739
- }
1740
-
1741
- // Template is only compiled on first use and cached after that point.
1742
- return function(context, options) {
1743
- if (!compiled) {
1744
- compiled = compileInput();
1745
- }
1746
- return compiled.call(this, context, options);
1747
- };
1748
- }
1749
-
1750
- __exports__.compile = compile;
1751
- return __exports__;
1752
- })(__module5__);
1753
-
1754
- // handlebars/compiler/javascript-compiler.js
1755
- var __module11__ = (function(__dependency1__, __dependency2__) {
1756
- "use strict";
1757
- var __exports__;
1758
- var COMPILER_REVISION = __dependency1__.COMPILER_REVISION;
1759
- var REVISION_CHANGES = __dependency1__.REVISION_CHANGES;
1760
- var log = __dependency1__.log;
1761
- var Exception = __dependency2__;
1762
-
1763
- function Literal(value) {
1764
- this.value = value;
1765
- }
1766
-
1767
- function JavaScriptCompiler() {}
1768
-
1769
- JavaScriptCompiler.prototype = {
1770
- // PUBLIC API: You can override these methods in a subclass to provide
1771
- // alternative compiled forms for name lookup and buffering semantics
1772
- nameLookup: function(parent, name /* , type*/) {
1773
- var wrap,
1774
- ret;
1775
- if (parent.indexOf('depth') === 0) {
1776
- wrap = true;
1777
- }
1778
-
1779
- if (/^[0-9]+$/.test(name)) {
1780
- ret = parent + "[" + name + "]";
1781
- } else if (JavaScriptCompiler.isValidJavaScriptVariableName(name)) {
1782
- ret = parent + "." + name;
1783
- }
1784
- else {
1785
- ret = parent + "['" + name + "']";
1786
- }
1787
-
1788
- if (wrap) {
1789
- return '(' + parent + ' && ' + ret + ')';
1790
- } else {
1791
- return ret;
1792
- }
1793
- },
1794
-
1795
- compilerInfo: function() {
1796
- var revision = COMPILER_REVISION,
1797
- versions = REVISION_CHANGES[revision];
1798
- return "this.compilerInfo = ["+revision+",'"+versions+"'];\n";
1799
- },
1800
-
1801
- appendToBuffer: function(string) {
1802
- if (this.environment.isSimple) {
1803
- return "return " + string + ";";
1804
- } else {
1805
- return {
1806
- appendToBuffer: true,
1807
- content: string,
1808
- toString: function() { return "buffer += " + string + ";"; }
1809
- };
1810
- }
1811
- },
1812
-
1813
- initializeBuffer: function() {
1814
- return this.quotedString("");
1815
- },
1816
-
1817
- namespace: "Handlebars",
1818
- // END PUBLIC API
1819
-
1820
- compile: function(environment, options, context, asObject) {
1821
- this.environment = environment;
1822
- this.options = options || {};
1823
-
1824
- log('debug', this.environment.disassemble() + "\n\n");
1825
-
1826
- this.name = this.environment.name;
1827
- this.isChild = !!context;
1828
- this.context = context || {
1829
- programs: [],
1830
- environments: [],
1831
- aliases: { }
1832
- };
1833
-
1834
- this.preamble();
1835
-
1836
- this.stackSlot = 0;
1837
- this.stackVars = [];
1838
- this.registers = { list: [] };
1839
- this.hashes = [];
1840
- this.compileStack = [];
1841
- this.inlineStack = [];
1842
-
1843
- this.compileChildren(environment, options);
1844
-
1845
- var opcodes = environment.opcodes, opcode;
1846
-
1847
- this.i = 0;
1848
-
1849
- for(var l=opcodes.length; this.i<l; this.i++) {
1850
- opcode = opcodes[this.i];
1851
-
1852
- if(opcode.opcode === 'DECLARE') {
1853
- this[opcode.name] = opcode.value;
1854
- } else {
1855
- this[opcode.opcode].apply(this, opcode.args);
1856
- }
1857
-
1858
- // Reset the stripNext flag if it was not set by this operation.
1859
- if (opcode.opcode !== this.stripNext) {
1860
- this.stripNext = false;
1861
- }
1862
- }
1863
-
1864
- // Flush any trailing content that might be pending.
1865
- this.pushSource('');
1866
-
1867
- if (this.stackSlot || this.inlineStack.length || this.compileStack.length) {
1868
- throw new Exception('Compile completed with content left on stack');
1869
- }
1870
-
1871
- return this.createFunctionContext(asObject);
1872
- },
1873
-
1874
- preamble: function() {
1875
- var out = [];
1876
-
1877
- if (!this.isChild) {
1878
- var namespace = this.namespace;
1879
-
1880
- var copies = "helpers = this.merge(helpers, " + namespace + ".helpers);";
1881
- if (this.environment.usePartial) { copies = copies + " partials = this.merge(partials, " + namespace + ".partials);"; }
1882
- if (this.options.data) { copies = copies + " data = data || {};"; }
1883
- out.push(copies);
1884
- } else {
1885
- out.push('');
1886
- }
1887
-
1888
- if (!this.environment.isSimple) {
1889
- out.push(", buffer = " + this.initializeBuffer());
1890
- } else {
1891
- out.push("");
1892
- }
1893
-
1894
- // track the last context pushed into place to allow skipping the
1895
- // getContext opcode when it would be a noop
1896
- this.lastContext = 0;
1897
- this.source = out;
1898
- },
1899
-
1900
- createFunctionContext: function(asObject) {
1901
- var locals = this.stackVars.concat(this.registers.list);
1902
-
1903
- if(locals.length > 0) {
1904
- this.source[1] = this.source[1] + ", " + locals.join(", ");
1905
- }
1906
-
1907
- // Generate minimizer alias mappings
1908
- if (!this.isChild) {
1909
- for (var alias in this.context.aliases) {
1910
- if (this.context.aliases.hasOwnProperty(alias)) {
1911
- this.source[1] = this.source[1] + ', ' + alias + '=' + this.context.aliases[alias];
1912
- }
1913
- }
1914
- }
1915
-
1916
- if (this.source[1]) {
1917
- this.source[1] = "var " + this.source[1].substring(2) + ";";
1918
- }
1919
-
1920
- // Merge children
1921
- if (!this.isChild) {
1922
- this.source[1] += '\n' + this.context.programs.join('\n') + '\n';
1923
- }
1924
-
1925
- if (!this.environment.isSimple) {
1926
- this.pushSource("return buffer;");
1927
- }
1928
-
1929
- var params = this.isChild ? ["depth0", "data"] : ["Handlebars", "depth0", "helpers", "partials", "data"];
1930
-
1931
- for(var i=0, l=this.environment.depths.list.length; i<l; i++) {
1932
- params.push("depth" + this.environment.depths.list[i]);
1933
- }
1934
-
1935
- // Perform a second pass over the output to merge content when possible
1936
- var source = this.mergeSource();
1937
-
1938
- if (!this.isChild) {
1939
- source = this.compilerInfo()+source;
1940
- }
1941
-
1942
- if (asObject) {
1943
- params.push(source);
1944
-
1945
- return Function.apply(this, params);
1946
- } else {
1947
- var functionSource = 'function ' + (this.name || '') + '(' + params.join(',') + ') {\n ' + source + '}';
1948
- log('debug', functionSource + "\n\n");
1949
- return functionSource;
1950
- }
1951
- },
1952
- mergeSource: function() {
1953
- // WARN: We are not handling the case where buffer is still populated as the source should
1954
- // not have buffer append operations as their final action.
1955
- var source = '',
1956
- buffer;
1957
- for (var i = 0, len = this.source.length; i < len; i++) {
1958
- var line = this.source[i];
1959
- if (line.appendToBuffer) {
1960
- if (buffer) {
1961
- buffer = buffer + '\n + ' + line.content;
1962
- } else {
1963
- buffer = line.content;
1964
- }
1965
- } else {
1966
- if (buffer) {
1967
- source += 'buffer += ' + buffer + ';\n ';
1968
- buffer = undefined;
1969
- }
1970
- source += line + '\n ';
1971
- }
1972
- }
1973
- return source;
1974
- },
1975
-
1976
- // [blockValue]
1977
- //
1978
- // On stack, before: hash, inverse, program, value
1979
- // On stack, after: return value of blockHelperMissing
1980
- //
1981
- // The purpose of this opcode is to take a block of the form
1982
- // `{{#foo}}...{{/foo}}`, resolve the value of `foo`, and
1983
- // replace it on the stack with the result of properly
1984
- // invoking blockHelperMissing.
1985
- blockValue: function() {
1986
- this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
1987
-
1988
- var params = ["depth0"];
1989
- this.setupParams(0, params);
1990
-
1991
- this.replaceStack(function(current) {
1992
- params.splice(1, 0, current);
1993
- return "blockHelperMissing.call(" + params.join(", ") + ")";
1994
- });
1995
- },
1996
-
1997
- // [ambiguousBlockValue]
1998
- //
1999
- // On stack, before: hash, inverse, program, value
2000
- // Compiler value, before: lastHelper=value of last found helper, if any
2001
- // On stack, after, if no lastHelper: same as [blockValue]
2002
- // On stack, after, if lastHelper: value
2003
- ambiguousBlockValue: function() {
2004
- this.context.aliases.blockHelperMissing = 'helpers.blockHelperMissing';
2005
-
2006
- var params = ["depth0"];
2007
- this.setupParams(0, params);
2008
-
2009
- var current = this.topStack();
2010
- params.splice(1, 0, current);
2011
-
2012
- this.pushSource("if (!" + this.lastHelper + ") { " + current + " = blockHelperMissing.call(" + params.join(", ") + "); }");
2013
- },
2014
-
2015
- // [appendContent]
2016
- //
2017
- // On stack, before: ...
2018
- // On stack, after: ...
2019
- //
2020
- // Appends the string value of `content` to the current buffer
2021
- appendContent: function(content) {
2022
- if (this.pendingContent) {
2023
- content = this.pendingContent + content;
2024
- }
2025
- if (this.stripNext) {
2026
- content = content.replace(/^\s+/, '');
2027
- }
2028
-
2029
- this.pendingContent = content;
2030
- },
2031
-
2032
- // [strip]
2033
- //
2034
- // On stack, before: ...
2035
- // On stack, after: ...
2036
- //
2037
- // Removes any trailing whitespace from the prior content node and flags
2038
- // the next operation for stripping if it is a content node.
2039
- strip: function() {
2040
- if (this.pendingContent) {
2041
- this.pendingContent = this.pendingContent.replace(/\s+$/, '');
2042
- }
2043
- this.stripNext = 'strip';
2044
- },
2045
-
2046
- // [append]
2047
- //
2048
- // On stack, before: value, ...
2049
- // On stack, after: ...
2050
- //
2051
- // Coerces `value` to a String and appends it to the current buffer.
2052
- //
2053
- // If `value` is truthy, or 0, it is coerced into a string and appended
2054
- // Otherwise, the empty string is appended
2055
- append: function() {
2056
- // Force anything that is inlined onto the stack so we don't have duplication
2057
- // when we examine local
2058
- this.flushInline();
2059
- var local = this.popStack();
2060
- this.pushSource("if(" + local + " || " + local + " === 0) { " + this.appendToBuffer(local) + " }");
2061
- if (this.environment.isSimple) {
2062
- this.pushSource("else { " + this.appendToBuffer("''") + " }");
2063
- }
2064
- },
2065
-
2066
- // [appendEscaped]
2067
- //
2068
- // On stack, before: value, ...
2069
- // On stack, after: ...
2070
- //
2071
- // Escape `value` and append it to the buffer
2072
- appendEscaped: function() {
2073
- this.context.aliases.escapeExpression = 'this.escapeExpression';
2074
-
2075
- this.pushSource(this.appendToBuffer("escapeExpression(" + this.popStack() + ")"));
2076
- },
2077
-
2078
- // [getContext]
2079
- //
2080
- // On stack, before: ...
2081
- // On stack, after: ...
2082
- // Compiler value, after: lastContext=depth
2083
- //
2084
- // Set the value of the `lastContext` compiler value to the depth
2085
- getContext: function(depth) {
2086
- if(this.lastContext !== depth) {
2087
- this.lastContext = depth;
2088
- }
2089
- },
2090
-
2091
- // [lookupOnContext]
2092
- //
2093
- // On stack, before: ...
2094
- // On stack, after: currentContext[name], ...
2095
- //
2096
- // Looks up the value of `name` on the current context and pushes
2097
- // it onto the stack.
2098
- lookupOnContext: function(name) {
2099
- this.push(this.nameLookup('depth' + this.lastContext, name, 'context'));
2100
- },
2101
-
2102
- // [pushContext]
2103
- //
2104
- // On stack, before: ...
2105
- // On stack, after: currentContext, ...
2106
- //
2107
- // Pushes the value of the current context onto the stack.
2108
- pushContext: function() {
2109
- this.pushStackLiteral('depth' + this.lastContext);
2110
- },
2111
-
2112
- // [resolvePossibleLambda]
2113
- //
2114
- // On stack, before: value, ...
2115
- // On stack, after: resolved value, ...
2116
- //
2117
- // If the `value` is a lambda, replace it on the stack by
2118
- // the return value of the lambda
2119
- resolvePossibleLambda: function() {
2120
- this.context.aliases.functionType = '"function"';
2121
-
2122
- this.replaceStack(function(current) {
2123
- return "typeof " + current + " === functionType ? " + current + ".apply(depth0) : " + current;
2124
- });
2125
- },
2126
-
2127
- // [lookup]
2128
- //
2129
- // On stack, before: value, ...
2130
- // On stack, after: value[name], ...
2131
- //
2132
- // Replace the value on the stack with the result of looking
2133
- // up `name` on `value`
2134
- lookup: function(name) {
2135
- this.replaceStack(function(current) {
2136
- return current + " == null || " + current + " === false ? " + current + " : " + this.nameLookup(current, name, 'context');
2137
- });
2138
- },
2139
-
2140
- // [lookupData]
2141
- //
2142
- // On stack, before: ...
2143
- // On stack, after: data, ...
2144
- //
2145
- // Push the data lookup operator
2146
- lookupData: function() {
2147
- this.pushStackLiteral('data');
2148
- },
2149
-
2150
- // [pushStringParam]
2151
- //
2152
- // On stack, before: ...
2153
- // On stack, after: string, currentContext, ...
2154
- //
2155
- // This opcode is designed for use in string mode, which
2156
- // provides the string value of a parameter along with its
2157
- // depth rather than resolving it immediately.
2158
- pushStringParam: function(string, type) {
2159
- this.pushStackLiteral('depth' + this.lastContext);
2160
-
2161
- this.pushString(type);
2162
-
2163
- // If it's a subexpression, the string result
2164
- // will be pushed after this opcode.
2165
- if (type !== 'sexpr') {
2166
- if (typeof string === 'string') {
2167
- this.pushString(string);
2168
- } else {
2169
- this.pushStackLiteral(string);
2170
- }
2171
- }
2172
- },
2173
-
2174
- emptyHash: function() {
2175
- this.pushStackLiteral('{}');
2176
-
2177
- if (this.options.stringParams) {
2178
- this.push('{}'); // hashContexts
2179
- this.push('{}'); // hashTypes
2180
- }
2181
- },
2182
- pushHash: function() {
2183
- if (this.hash) {
2184
- this.hashes.push(this.hash);
2185
- }
2186
- this.hash = {values: [], types: [], contexts: []};
2187
- },
2188
- popHash: function() {
2189
- var hash = this.hash;
2190
- this.hash = this.hashes.pop();
2191
-
2192
- if (this.options.stringParams) {
2193
- this.push('{' + hash.contexts.join(',') + '}');
2194
- this.push('{' + hash.types.join(',') + '}');
2195
- }
2196
-
2197
- this.push('{\n ' + hash.values.join(',\n ') + '\n }');
2198
- },
2199
-
2200
- // [pushString]
2201
- //
2202
- // On stack, before: ...
2203
- // On stack, after: quotedString(string), ...
2204
- //
2205
- // Push a quoted version of `string` onto the stack
2206
- pushString: function(string) {
2207
- this.pushStackLiteral(this.quotedString(string));
2208
- },
2209
-
2210
- // [push]
2211
- //
2212
- // On stack, before: ...
2213
- // On stack, after: expr, ...
2214
- //
2215
- // Push an expression onto the stack
2216
- push: function(expr) {
2217
- this.inlineStack.push(expr);
2218
- return expr;
2219
- },
2220
-
2221
- // [pushLiteral]
2222
- //
2223
- // On stack, before: ...
2224
- // On stack, after: value, ...
2225
- //
2226
- // Pushes a value onto the stack. This operation prevents
2227
- // the compiler from creating a temporary variable to hold
2228
- // it.
2229
- pushLiteral: function(value) {
2230
- this.pushStackLiteral(value);
2231
- },
2232
-
2233
- // [pushProgram]
2234
- //
2235
- // On stack, before: ...
2236
- // On stack, after: program(guid), ...
2237
- //
2238
- // Push a program expression onto the stack. This takes
2239
- // a compile-time guid and converts it into a runtime-accessible
2240
- // expression.
2241
- pushProgram: function(guid) {
2242
- if (guid != null) {
2243
- this.pushStackLiteral(this.programExpression(guid));
2244
- } else {
2245
- this.pushStackLiteral(null);
2246
- }
2247
- },
2248
-
2249
- // [invokeHelper]
2250
- //
2251
- // On stack, before: hash, inverse, program, params..., ...
2252
- // On stack, after: result of helper invocation
2253
- //
2254
- // Pops off the helper's parameters, invokes the helper,
2255
- // and pushes the helper's return value onto the stack.
2256
- //
2257
- // If the helper is not found, `helperMissing` is called.
2258
- invokeHelper: function(paramSize, name, isRoot) {
2259
- this.context.aliases.helperMissing = 'helpers.helperMissing';
2260
- this.useRegister('helper');
2261
-
2262
- var helper = this.lastHelper = this.setupHelper(paramSize, name, true);
2263
- var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
2264
-
2265
- var lookup = 'helper = ' + helper.name + ' || ' + nonHelper;
2266
- if (helper.paramsInit) {
2267
- lookup += ',' + helper.paramsInit;
2268
- }
2269
-
2270
- this.push(
2271
- '('
2272
- + lookup
2273
- + ',helper '
2274
- + '? helper.call(' + helper.callParams + ') '
2275
- + ': helperMissing.call(' + helper.helperMissingParams + '))');
2276
-
2277
- // Always flush subexpressions. This is both to prevent the compounding size issue that
2278
- // occurs when the code has to be duplicated for inlining and also to prevent errors
2279
- // due to the incorrect options object being passed due to the shared register.
2280
- if (!isRoot) {
2281
- this.flushInline();
2282
- }
2283
- },
2284
-
2285
- // [invokeKnownHelper]
2286
- //
2287
- // On stack, before: hash, inverse, program, params..., ...
2288
- // On stack, after: result of helper invocation
2289
- //
2290
- // This operation is used when the helper is known to exist,
2291
- // so a `helperMissing` fallback is not required.
2292
- invokeKnownHelper: function(paramSize, name) {
2293
- var helper = this.setupHelper(paramSize, name);
2294
- this.push(helper.name + ".call(" + helper.callParams + ")");
2295
- },
2296
-
2297
- // [invokeAmbiguous]
2298
- //
2299
- // On stack, before: hash, inverse, program, params..., ...
2300
- // On stack, after: result of disambiguation
2301
- //
2302
- // This operation is used when an expression like `{{foo}}`
2303
- // is provided, but we don't know at compile-time whether it
2304
- // is a helper or a path.
2305
- //
2306
- // This operation emits more code than the other options,
2307
- // and can be avoided by passing the `knownHelpers` and
2308
- // `knownHelpersOnly` flags at compile-time.
2309
- invokeAmbiguous: function(name, helperCall) {
2310
- this.context.aliases.functionType = '"function"';
2311
- this.useRegister('helper');
2312
-
2313
- this.emptyHash();
2314
- var helper = this.setupHelper(0, name, helperCall);
2315
-
2316
- var helperName = this.lastHelper = this.nameLookup('helpers', name, 'helper');
2317
-
2318
- var nonHelper = this.nameLookup('depth' + this.lastContext, name, 'context');
2319
- var nextStack = this.nextStack();
2320
-
2321
- if (helper.paramsInit) {
2322
- this.pushSource(helper.paramsInit);
2323
- }
2324
- this.pushSource('if (helper = ' + helperName + ') { ' + nextStack + ' = helper.call(' + helper.callParams + '); }');
2325
- this.pushSource('else { helper = ' + nonHelper + '; ' + nextStack + ' = typeof helper === functionType ? helper.call(' + helper.callParams + ') : helper; }');
2326
- },
2327
-
2328
- // [invokePartial]
2329
- //
2330
- // On stack, before: context, ...
2331
- // On stack after: result of partial invocation
2332
- //
2333
- // This operation pops off a context, invokes a partial with that context,
2334
- // and pushes the result of the invocation back.
2335
- invokePartial: function(name) {
2336
- var params = [this.nameLookup('partials', name, 'partial'), "'" + name + "'", this.popStack(), "helpers", "partials"];
2337
-
2338
- if (this.options.data) {
2339
- params.push("data");
2340
- }
2341
-
2342
- this.context.aliases.self = "this";
2343
- this.push("self.invokePartial(" + params.join(", ") + ")");
2344
- },
2345
-
2346
- // [assignToHash]
2347
- //
2348
- // On stack, before: value, hash, ...
2349
- // On stack, after: hash, ...
2350
- //
2351
- // Pops a value and hash off the stack, assigns `hash[key] = value`
2352
- // and pushes the hash back onto the stack.
2353
- assignToHash: function(key) {
2354
- var value = this.popStack(),
2355
- context,
2356
- type;
2357
-
2358
- if (this.options.stringParams) {
2359
- type = this.popStack();
2360
- context = this.popStack();
2361
- }
2362
-
2363
- var hash = this.hash;
2364
- if (context) {
2365
- hash.contexts.push("'" + key + "': " + context);
2366
- }
2367
- if (type) {
2368
- hash.types.push("'" + key + "': " + type);
2369
- }
2370
- hash.values.push("'" + key + "': (" + value + ")");
2371
- },
2372
-
2373
- // HELPERS
2374
-
2375
- compiler: JavaScriptCompiler,
2376
-
2377
- compileChildren: function(environment, options) {
2378
- var children = environment.children, child, compiler;
2379
-
2380
- for(var i=0, l=children.length; i<l; i++) {
2381
- child = children[i];
2382
- compiler = new this.compiler();
2383
-
2384
- var index = this.matchExistingProgram(child);
2385
-
2386
- if (index == null) {
2387
- this.context.programs.push(''); // Placeholder to prevent name conflicts for nested children
2388
- index = this.context.programs.length;
2389
- child.index = index;
2390
- child.name = 'program' + index;
2391
- this.context.programs[index] = compiler.compile(child, options, this.context);
2392
- this.context.environments[index] = child;
2393
- } else {
2394
- child.index = index;
2395
- child.name = 'program' + index;
2396
- }
2397
- }
2398
- },
2399
- matchExistingProgram: function(child) {
2400
- for (var i = 0, len = this.context.environments.length; i < len; i++) {
2401
- var environment = this.context.environments[i];
2402
- if (environment && environment.equals(child)) {
2403
- return i;
2404
- }
2405
- }
2406
- },
2407
-
2408
- programExpression: function(guid) {
2409
- this.context.aliases.self = "this";
2410
-
2411
- if(guid == null) {
2412
- return "self.noop";
2413
- }
2414
-
2415
- var child = this.environment.children[guid],
2416
- depths = child.depths.list, depth;
2417
-
2418
- var programParams = [child.index, child.name, "data"];
2419
-
2420
- for(var i=0, l = depths.length; i<l; i++) {
2421
- depth = depths[i];
2422
-
2423
- if(depth === 1) { programParams.push("depth0"); }
2424
- else { programParams.push("depth" + (depth - 1)); }
2425
- }
2426
-
2427
- return (depths.length === 0 ? "self.program(" : "self.programWithDepth(") + programParams.join(", ") + ")";
2428
- },
2429
-
2430
- register: function(name, val) {
2431
- this.useRegister(name);
2432
- this.pushSource(name + " = " + val + ";");
2433
- },
2434
-
2435
- useRegister: function(name) {
2436
- if(!this.registers[name]) {
2437
- this.registers[name] = true;
2438
- this.registers.list.push(name);
2439
- }
2440
- },
2441
-
2442
- pushStackLiteral: function(item) {
2443
- return this.push(new Literal(item));
2444
- },
2445
-
2446
- pushSource: function(source) {
2447
- if (this.pendingContent) {
2448
- this.source.push(this.appendToBuffer(this.quotedString(this.pendingContent)));
2449
- this.pendingContent = undefined;
2450
- }
2451
-
2452
- if (source) {
2453
- this.source.push(source);
2454
- }
2455
- },
2456
-
2457
- pushStack: function(item) {
2458
- this.flushInline();
2459
-
2460
- var stack = this.incrStack();
2461
- if (item) {
2462
- this.pushSource(stack + " = " + item + ";");
2463
- }
2464
- this.compileStack.push(stack);
2465
- return stack;
2466
- },
2467
-
2468
- replaceStack: function(callback) {
2469
- var prefix = '',
2470
- inline = this.isInline(),
2471
- stack,
2472
- createdStack,
2473
- usedLiteral;
2474
-
2475
- // If we are currently inline then we want to merge the inline statement into the
2476
- // replacement statement via ','
2477
- if (inline) {
2478
- var top = this.popStack(true);
2479
-
2480
- if (top instanceof Literal) {
2481
- // Literals do not need to be inlined
2482
- stack = top.value;
2483
- usedLiteral = true;
2484
- } else {
2485
- // Get or create the current stack name for use by the inline
2486
- createdStack = !this.stackSlot;
2487
- var name = !createdStack ? this.topStackName() : this.incrStack();
2488
-
2489
- prefix = '(' + this.push(name) + ' = ' + top + '),';
2490
- stack = this.topStack();
2491
- }
2492
- } else {
2493
- stack = this.topStack();
2494
- }
2495
-
2496
- var item = callback.call(this, stack);
2497
-
2498
- if (inline) {
2499
- if (!usedLiteral) {
2500
- this.popStack();
2501
- }
2502
- if (createdStack) {
2503
- this.stackSlot--;
2504
- }
2505
- this.push('(' + prefix + item + ')');
2506
- } else {
2507
- // Prevent modification of the context depth variable. Through replaceStack
2508
- if (!/^stack/.test(stack)) {
2509
- stack = this.nextStack();
2510
- }
2511
-
2512
- this.pushSource(stack + " = (" + prefix + item + ");");
2513
- }
2514
- return stack;
2515
- },
2516
-
2517
- nextStack: function() {
2518
- return this.pushStack();
2519
- },
2520
-
2521
- incrStack: function() {
2522
- this.stackSlot++;
2523
- if(this.stackSlot > this.stackVars.length) { this.stackVars.push("stack" + this.stackSlot); }
2524
- return this.topStackName();
2525
- },
2526
- topStackName: function() {
2527
- return "stack" + this.stackSlot;
2528
- },
2529
- flushInline: function() {
2530
- var inlineStack = this.inlineStack;
2531
- if (inlineStack.length) {
2532
- this.inlineStack = [];
2533
- for (var i = 0, len = inlineStack.length; i < len; i++) {
2534
- var entry = inlineStack[i];
2535
- if (entry instanceof Literal) {
2536
- this.compileStack.push(entry);
2537
- } else {
2538
- this.pushStack(entry);
2539
- }
2540
- }
2541
- }
2542
- },
2543
- isInline: function() {
2544
- return this.inlineStack.length;
2545
- },
2546
-
2547
- popStack: function(wrapped) {
2548
- var inline = this.isInline(),
2549
- item = (inline ? this.inlineStack : this.compileStack).pop();
2550
-
2551
- if (!wrapped && (item instanceof Literal)) {
2552
- return item.value;
2553
- } else {
2554
- if (!inline) {
2555
- if (!this.stackSlot) {
2556
- throw new Exception('Invalid stack pop');
2557
- }
2558
- this.stackSlot--;
2559
- }
2560
- return item;
2561
- }
2562
- },
2563
-
2564
- topStack: function(wrapped) {
2565
- var stack = (this.isInline() ? this.inlineStack : this.compileStack),
2566
- item = stack[stack.length - 1];
2567
-
2568
- if (!wrapped && (item instanceof Literal)) {
2569
- return item.value;
2570
- } else {
2571
- return item;
2572
- }
2573
- },
2574
-
2575
- quotedString: function(str) {
2576
- return '"' + str
2577
- .replace(/\\/g, '\\\\')
2578
- .replace(/"/g, '\\"')
2579
- .replace(/\n/g, '\\n')
2580
- .replace(/\r/g, '\\r')
2581
- .replace(/\u2028/g, '\\u2028') // Per Ecma-262 7.3 + 7.8.4
2582
- .replace(/\u2029/g, '\\u2029') + '"';
2583
- },
2584
-
2585
- setupHelper: function(paramSize, name, missingParams) {
2586
- var params = [],
2587
- paramsInit = this.setupParams(paramSize, params, missingParams);
2588
- var foundHelper = this.nameLookup('helpers', name, 'helper');
2589
-
2590
- return {
2591
- params: params,
2592
- paramsInit: paramsInit,
2593
- name: foundHelper,
2594
- callParams: ["depth0"].concat(params).join(", "),
2595
- helperMissingParams: missingParams && ["depth0", this.quotedString(name)].concat(params).join(", ")
2596
- };
2597
- },
2598
-
2599
- setupOptions: function(paramSize, params) {
2600
- var options = [], contexts = [], types = [], param, inverse, program;
2601
-
2602
- options.push("hash:" + this.popStack());
2603
-
2604
- if (this.options.stringParams) {
2605
- options.push("hashTypes:" + this.popStack());
2606
- options.push("hashContexts:" + this.popStack());
2607
- }
2608
-
2609
- inverse = this.popStack();
2610
- program = this.popStack();
2611
-
2612
- // Avoid setting fn and inverse if neither are set. This allows
2613
- // helpers to do a check for `if (options.fn)`
2614
- if (program || inverse) {
2615
- if (!program) {
2616
- this.context.aliases.self = "this";
2617
- program = "self.noop";
2618
- }
2619
-
2620
- if (!inverse) {
2621
- this.context.aliases.self = "this";
2622
- inverse = "self.noop";
2623
- }
2624
-
2625
- options.push("inverse:" + inverse);
2626
- options.push("fn:" + program);
2627
- }
2628
-
2629
- for(var i=0; i<paramSize; i++) {
2630
- param = this.popStack();
2631
- params.push(param);
2632
-
2633
- if(this.options.stringParams) {
2634
- types.push(this.popStack());
2635
- contexts.push(this.popStack());
2636
- }
2637
- }
2638
-
2639
- if (this.options.stringParams) {
2640
- options.push("contexts:[" + contexts.join(",") + "]");
2641
- options.push("types:[" + types.join(",") + "]");
2642
- }
2643
-
2644
- if(this.options.data) {
2645
- options.push("data:data");
2646
- }
2647
-
2648
- return options;
2649
- },
2650
-
2651
- // the params and contexts arguments are passed in arrays
2652
- // to fill in
2653
- setupParams: function(paramSize, params, useRegister) {
2654
- var options = '{' + this.setupOptions(paramSize, params).join(',') + '}';
2655
-
2656
- if (useRegister) {
2657
- this.useRegister('options');
2658
- params.push('options');
2659
- return 'options=' + options;
2660
- } else {
2661
- params.push(options);
2662
- return '';
2663
- }
2664
- }
2665
- };
2666
-
2667
- var reservedWords = (
2668
- "break else new var" +
2669
- " case finally return void" +
2670
- " catch for switch while" +
2671
- " continue function this with" +
2672
- " default if throw" +
2673
- " delete in try" +
2674
- " do instanceof typeof" +
2675
- " abstract enum int short" +
2676
- " boolean export interface static" +
2677
- " byte extends long super" +
2678
- " char final native synchronized" +
2679
- " class float package throws" +
2680
- " const goto private transient" +
2681
- " debugger implements protected volatile" +
2682
- " double import public let yield"
2683
- ).split(" ");
2684
-
2685
- var compilerWords = JavaScriptCompiler.RESERVED_WORDS = {};
2686
-
2687
- for(var i=0, l=reservedWords.length; i<l; i++) {
2688
- compilerWords[reservedWords[i]] = true;
2689
- }
2690
-
2691
- JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
2692
- if(!JavaScriptCompiler.RESERVED_WORDS[name] && /^[a-zA-Z_$][0-9a-zA-Z_$]*$/.test(name)) {
2693
- return true;
2694
- }
2695
- return false;
2696
- };
2697
-
2698
- __exports__ = JavaScriptCompiler;
2699
- return __exports__;
2700
- })(__module2__, __module5__);
2701
-
2702
- // handlebars.js
2703
- var __module0__ = (function(__dependency1__, __dependency2__, __dependency3__, __dependency4__, __dependency5__) {
2704
- "use strict";
2705
- var __exports__;
2706
- /*globals Handlebars: true */
2707
- var Handlebars = __dependency1__;
2708
-
2709
- // Compiler imports
2710
- var AST = __dependency2__;
2711
- var Parser = __dependency3__.parser;
2712
- var parse = __dependency3__.parse;
2713
- var Compiler = __dependency4__.Compiler;
2714
- var compile = __dependency4__.compile;
2715
- var precompile = __dependency4__.precompile;
2716
- var JavaScriptCompiler = __dependency5__;
2717
-
2718
- var _create = Handlebars.create;
2719
- var create = function() {
2720
- var hb = _create();
2721
-
2722
- hb.compile = function(input, options) {
2723
- return compile(input, options, hb);
2724
- };
2725
- hb.precompile = function (input, options) {
2726
- return precompile(input, options, hb);
2727
- };
2728
-
2729
- hb.AST = AST;
2730
- hb.Compiler = Compiler;
2731
- hb.JavaScriptCompiler = JavaScriptCompiler;
2732
- hb.Parser = Parser;
2733
- hb.parse = parse;
2734
-
2735
- return hb;
2736
- };
2737
-
2738
- Handlebars = create();
2739
- Handlebars.create = create;
2740
-
2741
- __exports__ = Handlebars;
2742
- return __exports__;
2743
- })(__module1__, __module7__, __module8__, __module10__, __module11__);
2744
-
2745
- return __module0__;
2746
- })();