luca 0.9.8 → 0.9.9
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +49 -0
- data/Gemfile +8 -1
- data/Gemfile.lock +97 -53
- data/Guardfile +3 -25
- data/README.md +5 -16
- data/ROADMAP +15 -9
- data/Rakefile +24 -75
- data/app.rb +10 -42
- data/app/assets/javascripts/luca/basic.coffee +1 -1
- data/app/assets/javascripts/luca/components/application.coffee +187 -104
- data/app/assets/javascripts/luca/components/collection_view.coffee +115 -51
- data/app/assets/javascripts/luca/components/controller.coffee +87 -10
- data/app/assets/javascripts/luca/components/fields/base.coffee +74 -13
- data/app/assets/javascripts/luca/components/fields/button_field.coffee +60 -13
- data/app/assets/javascripts/luca/components/fields/checkbox_array.coffee +12 -7
- data/app/assets/javascripts/luca/components/fields/select_field.coffee +82 -23
- data/app/assets/javascripts/luca/components/fields/text_area_field.coffee +25 -10
- data/app/assets/javascripts/luca/components/fields/text_field.coffee +9 -3
- data/app/assets/javascripts/luca/components/form_view.coffee +105 -33
- data/app/assets/javascripts/luca/components/grid_layout_view.coffee +42 -0
- data/app/assets/javascripts/luca/components/index.coffee +6 -0
- data/app/assets/javascripts/luca/components/nav_bar.coffee +60 -6
- data/app/assets/javascripts/luca/components/page.coffee +70 -0
- data/app/assets/javascripts/luca/components/simple_collection_view.coffee +10 -0
- data/app/assets/javascripts/luca/components/table_view.coffee +7 -3
- data/app/assets/javascripts/luca/components/table_view_scrollable.coffee +23 -0
- data/app/assets/javascripts/luca/concerns/collection_event_bindings.coffee +4 -1
- data/app/assets/javascripts/luca/concerns/development_tool_helpers.coffee +23 -14
- data/app/assets/javascripts/luca/concerns/dom_helpers.coffee +2 -2
- data/app/assets/javascripts/luca/concerns/filterable.coffee +8 -11
- data/app/assets/javascripts/luca/concerns/form_model_bindings.coffee +20 -0
- data/app/assets/javascripts/luca/concerns/modal_view.coffee +40 -15
- data/app/assets/javascripts/luca/concerns/query_collection_bindings.coffee +7 -1
- data/app/assets/javascripts/luca/concerns/state_model.coffee +40 -26
- data/app/assets/javascripts/luca/concerns/templating.coffee +3 -1
- data/app/assets/javascripts/luca/config.coffee +5 -0
- data/app/assets/javascripts/luca/containers/card_view.coffee +87 -52
- data/app/assets/javascripts/luca/containers/container.coffee +305 -108
- data/app/assets/javascripts/luca/containers/modal_view.coffee +9 -9
- data/app/assets/javascripts/luca/containers/page_controller.coffee +25 -0
- data/app/assets/javascripts/luca/containers/panel_toolbar.coffee +5 -6
- data/app/assets/javascripts/luca/containers/tab_view.coffee +19 -10
- data/app/assets/javascripts/luca/containers/viewport.coffee +12 -16
- data/app/assets/javascripts/luca/core/collection.coffee +19 -5
- data/app/assets/javascripts/luca/core/events.coffee +5 -5
- data/app/assets/javascripts/luca/core/model.coffee +1 -1
- data/app/assets/javascripts/luca/core/panel.coffee +18 -6
- data/app/assets/javascripts/luca/core/registry/component_definition.coffee +2 -1
- data/app/assets/javascripts/luca/core/registry/meta_data.coffee +2 -0
- data/app/assets/javascripts/luca/core/registry/registry.coffee +14 -11
- data/app/assets/javascripts/luca/core/templates.coffee +5 -1
- data/app/assets/javascripts/luca/core/view.coffee +200 -47
- data/app/assets/javascripts/luca/dependencies.coffee +2 -0
- data/app/assets/javascripts/luca/development/code_sync_manager.coffee +173 -0
- data/app/assets/javascripts/luca/development/component.coffee +76 -0
- data/app/assets/javascripts/luca/development/components.coffee +57 -0
- data/app/assets/javascripts/luca/development/console.coffee +1 -1
- data/app/assets/javascripts/luca/development/index.coffee +4 -1
- data/app/assets/javascripts/luca/framework.coffee +7 -3
- data/app/assets/javascripts/luca/index.coffee +2 -1
- data/app/assets/javascripts/luca/managers/collection_manager.coffee +2 -3
- data/app/assets/javascripts/luca/managers/index.coffee +1 -1
- data/app/assets/javascripts/luca/managers/socket_manager.coffee +31 -8
- data/app/assets/javascripts/luca/templates/components/nav_bar.jst.ejs +16 -1
- data/app/assets/javascripts/luca/templates/containers/tab_view.jst.ejs +1 -1
- data/app/assets/javascripts/luca/util/index.coffee +1 -0
- data/app/assets/javascripts/luca/util/keybindings.coffee +24 -0
- data/app/assets/javascripts/luca/util/logging.coffee +15 -0
- data/app/assets/javascripts/luca/util/luca.coffee +9 -1
- data/app/assets/stylesheets/luca/components/table_view.scss +85 -0
- data/app/assets/stylesheets/luca/components/viewport.scss +0 -4
- data/app/assets/stylesheets/luca/containers/container.scss +8 -0
- data/app/assets/stylesheets/luca/index.css +2 -2
- data/bin/luca +14 -0
- data/config.ru +1 -2
- data/docs/framework.json +1 -0
- data/docs/luca-framework-documentation.js +1 -0
- data/docs/{application.md → old/application.md} +0 -0
- data/docs/{collection.md → old/collection.md} +0 -0
- data/docs/{collection_manager.md → old/collection_manager.md} +0 -0
- data/docs/{container_philosophy.md → old/container_philosophy.md} +0 -0
- data/docs/{event_binding_helpers.md → old/event_binding_helpers.md} +0 -0
- data/docs/{method_caching_and_computed_properties.md → old/method_caching_and_computed_properties.md} +0 -0
- data/docs/{view.md → old/view.md} +0 -0
- data/lib/generators/luca/application/templates/javascripts/dependencies.coffee +2 -5
- data/lib/guard/luca.rb +84 -0
- data/lib/luca.rb +25 -1
- data/lib/luca/asset_compiler.rb +117 -0
- data/lib/luca/cli.rb +68 -0
- data/lib/luca/cli/generate.rb +37 -0
- data/lib/luca/cli/server.rb +20 -0
- data/lib/luca/cli/sync.rb +40 -0
- data/lib/luca/cli/watch.rb +16 -0
- data/lib/luca/collection.rb +64 -0
- data/lib/luca/collection/endpoint.rb +38 -0
- data/lib/luca/collection/file_backend.rb +121 -0
- data/lib/luca/collection/redis_backend.rb +153 -0
- data/lib/luca/compiled_asset.rb +61 -0
- data/lib/luca/component_definition.rb +356 -0
- data/lib/luca/luca_application.rb +258 -0
- data/lib/luca/project.rb +73 -0
- data/lib/luca/project_harness.rb +96 -0
- data/lib/luca/rails.rb +5 -3
- data/lib/luca/rails/engine.rb +8 -0
- data/lib/luca/rails/version.rb +1 -2
- data/lib/luca/server.rb +7 -0
- data/lib/luca/stylesheet.rb +35 -0
- data/lib/luca/template.rb +2 -0
- data/lib/luca/template_asset.rb +64 -0
- data/lib/luca/version.rb +3 -0
- data/lib/luca/watcher.rb +72 -0
- data/lib/railties/luca/tasks.rake +7 -0
- data/site/.bundle/config +2 -0
- data/site/.gitignore +5 -0
- data/site/.rvmrc +1 -0
- data/site/CHANGELOG.md +41 -0
- data/site/DOCS.md +41 -0
- data/site/Gemfile +8 -0
- data/site/Gemfile.lock +134 -0
- data/site/LICENSE.md +19 -0
- data/site/config.rb +84 -0
- data/site/helpers/site_helpers.rb +20 -0
- data/site/html5bp-docs/README.md +38 -0
- data/site/html5bp-docs/contribute.md +104 -0
- data/site/html5bp-docs/crossdomain.md +21 -0
- data/site/html5bp-docs/css.md +135 -0
- data/site/html5bp-docs/extend.md +507 -0
- data/site/html5bp-docs/faq.md +77 -0
- data/site/html5bp-docs/htaccess.md +323 -0
- data/site/html5bp-docs/html.md +170 -0
- data/site/html5bp-docs/js.md +31 -0
- data/site/html5bp-docs/misc.md +25 -0
- data/site/html5bp-docs/usage.md +109 -0
- data/site/readme.md +47 -0
- data/site/source/.htaccess +540 -0
- data/site/source/404.html +157 -0
- data/site/source/app/assets/javascripts/dependencies.js.coffee +6 -0
- data/site/source/app/assets/javascripts/docs-docs.js +1 -0
- data/site/source/app/assets/javascripts/docs/application.coffee +64 -0
- data/site/source/app/assets/javascripts/docs/collections/docs_documentation.coffee +17 -0
- data/site/source/app/assets/javascripts/docs/collections/github_repositories.coffee +7 -0
- data/site/source/app/assets/javascripts/docs/collections/index.coffee +1 -0
- data/site/source/app/assets/javascripts/docs/collections/luca_documentation.coffee +17 -0
- data/site/source/app/assets/javascripts/docs/collections/public_gists.coffee +4 -0
- data/site/source/app/assets/javascripts/docs/config.coffee +5 -0
- data/site/source/app/assets/javascripts/docs/index.coffee +12 -0
- data/site/source/app/assets/javascripts/docs/lib/router.coffee +3 -0
- data/{spec/components/application_spec.coffee → site/source/app/assets/javascripts/docs/lib/util.coffee} +0 -0
- data/site/source/app/assets/javascripts/docs/models/component.coffee +99 -0
- data/site/source/app/assets/javascripts/docs/models/github_repository.coffee +3 -0
- data/site/source/app/assets/javascripts/docs/models/index.coffee +1 -0
- data/site/source/app/assets/javascripts/docs/templates/component_documentation.jst.ejs +55 -0
- data/site/source/app/assets/javascripts/docs/templates/examples_browser/overview.jst.ejs +4 -0
- data/site/source/app/assets/javascripts/docs/templates/examples_browser/selector.jst.ejs +11 -0
- data/site/source/app/assets/javascripts/docs/templates/github_repository.jst.ejs +4 -0
- data/site/source/app/assets/javascripts/docs/templates/layouts/main.jst.ejs +4 -0
- data/site/source/app/assets/javascripts/docs/templates/left_navigation.jst.ejs +5 -0
- data/site/source/app/assets/javascripts/docs/templates/pages/getting_started.jst.ejs +78 -0
- data/site/source/app/assets/javascripts/docs/templates/pages/home.jst.ejs +57 -0
- data/site/source/app/assets/javascripts/docs/views/components/code_editor.coffee +45 -0
- data/{spec/components/collection_loader_view_spec.coffee → site/source/app/assets/javascripts/docs/views/components/code_editor/index.coffee} +0 -0
- data/site/source/app/assets/javascripts/docs/views/components/component_documentation.coffee +72 -0
- data/site/source/app/assets/javascripts/docs/views/index.coffee +3 -0
- data/site/source/app/assets/javascripts/docs/views/pages/browse_source.coffee +46 -0
- data/site/source/app/assets/javascripts/docs/views/pages/browse_source/details.coffee +37 -0
- data/site/source/app/assets/javascripts/docs/views/pages/browse_source/list.coffee +31 -0
- data/site/source/app/assets/javascripts/docs/views/pages/component_editor.coffee +10 -0
- data/site/source/app/assets/javascripts/docs/views/pages/examples_browser.coffee +102 -0
- data/site/source/app/assets/javascripts/docs/views/pages/examples_browser/docs.coffee +12 -0
- data/site/source/app/assets/javascripts/docs/views/pages/examples_browser/source.coffee +13 -0
- data/site/source/app/assets/javascripts/docs/views/pages/home.coffee +10 -0
- data/site/source/app/assets/javascripts/docs/views/views/api_browser/index.coffee +43 -0
- data/site/source/app/assets/javascripts/docs/views/views/collection_view_examples/grid_layout_view_example.coffee +14 -0
- data/site/source/app/assets/javascripts/docs/views/views/collection_view_examples/table_view_example.coffee +39 -0
- data/site/source/app/assets/javascripts/docs/views/views/form_view_examples/basic_example.coffee +38 -0
- data/site/source/app/assets/javascripts/docs/views/views/form_view_examples/complex_layout.coffee +110 -0
- data/site/source/app/assets/javascripts/docs/views/views/top_navigation.coffee +6 -0
- data/site/source/app/assets/javascripts/luca-docs.js +1 -0
- data/site/source/app/assets/javascripts/luca-framework-documentation.js +1 -0
- data/site/source/app/assets/javascripts/site.js.coffee +4 -0
- data/site/source/app/assets/javascripts/vendor/codemirror.js +4786 -0
- data/site/source/app/assets/javascripts/vendor/coffeescript.js +346 -0
- data/site/source/app/assets/javascripts/vendor/css.js +465 -0
- data/site/source/app/assets/javascripts/vendor/htmlmixed.js +84 -0
- data/site/source/app/assets/javascripts/vendor/javascript.js +422 -0
- data/site/source/app/assets/javascripts/vendor/js-beautify.js +1353 -0
- data/site/source/app/assets/javascripts/vendor/modernizr-2.6.1.min.js +4 -0
- data/site/source/app/assets/javascripts/vendor/vim.js +2511 -0
- data/site/source/app/assets/stylesheets/docs/api-browser.css.scss +5 -0
- data/site/source/app/assets/stylesheets/docs/application.css.scss +35 -0
- data/site/source/app/assets/stylesheets/docs/browse-source.css.scss +5 -0
- data/site/source/app/assets/stylesheets/docs/scrollable-table.css.scss +5 -0
- data/site/source/app/assets/stylesheets/site.css.scss +2 -0
- data/site/source/app/assets/stylesheets/vendor/codemirror.css +240 -0
- data/site/source/app/assets/stylesheets/vendor/prettify-tomorrow-night-bright.css +160 -0
- data/site/source/app/assets/stylesheets/vendor/twilight.css +26 -0
- data/site/source/crossdomain.xml +15 -0
- data/site/source/documentation.html.haml +1 -0
- data/site/source/favicon_base.png +0 -0
- data/site/source/humans.txt +15 -0
- data/site/source/images/background.png +0 -0
- data/site/source/images/middleman.png +0 -0
- data/site/source/index.html.haml +1 -0
- data/site/source/layouts/layout.haml +55 -0
- data/site/source/readme.md +63 -0
- data/site/source/robots.txt +3 -0
- data/spec/{components/grid_view_spec.coffee → javascripts/components/application_spec.coffee} +0 -0
- data/spec/{components/pagination_control_spec.coffee → javascripts/components/collection_loader_view_spec.coffee} +0 -0
- data/spec/{components → javascripts/components}/collection_view_spec.coffee +1 -1
- data/spec/{components → javascripts/components}/controller_spec.coffee +0 -0
- data/spec/{components → javascripts/components}/fields/checkbox_array_spec.coffee +0 -0
- data/spec/javascripts/components/form_view_spec.coffee +162 -0
- data/spec/{components/record_manager_spec.coffee → javascripts/components/grid_view_spec.coffee} +0 -0
- data/spec/{components → javascripts/components}/multi_collection_view_spec.coffee +0 -0
- data/spec/{components/template_spec.coffee → javascripts/components/pagination_control_spec.coffee} +0 -0
- data/spec/{concerns/paginatable_spec.coffee → javascripts/components/record_manager_spec.coffee} +0 -0
- data/spec/{components → javascripts/components}/table_view_spec.coffee +0 -0
- data/spec/{containers/modal_view_spec.coffee → javascripts/components/template_spec.coffee} +0 -0
- data/spec/{concerns → javascripts/concerns}/collection_event_bindings_spec.coffee +0 -0
- data/spec/{concerns → javascripts/concerns}/dom_helpers_spec.coffee +0 -0
- data/spec/{concerns → javascripts/concerns}/filterable_spec.coffee +0 -0
- data/spec/{concerns → javascripts/concerns}/model_presenter_spec.coffee +0 -0
- data/spec/{containers/panel_view_spec.coffee → javascripts/concerns/paginatable_spec.coffee} +0 -0
- data/spec/{concerns → javascripts/concerns}/state_model_spec.coffee +5 -0
- data/spec/javascripts/containers/card_view_spec.coffee +108 -0
- data/spec/{containers/tab_view_spec.coffee → javascripts/containers/modal_view_spec.coffee} +0 -0
- data/spec/{containers/viewport_spec.coffee → javascripts/containers/panel_view_spec.coffee} +0 -0
- data/spec/{core/observer_spec.coffee → javascripts/containers/tab_view_spec.coffee} +0 -0
- data/spec/{managers/socket_manager_spec.coffee → javascripts/containers/viewport_spec.coffee} +0 -0
- data/spec/{core → javascripts/core}/collection_spec.coffee +1 -1
- data/spec/{core → javascripts/core}/concerns_spec.coffee +0 -0
- data/spec/{core → javascripts/core}/container_spec.coffee +0 -0
- data/spec/{core → javascripts/core}/define_spec.coffee +0 -0
- data/spec/{core → javascripts/core}/events_spec.coffee +0 -0
- data/spec/{core → javascripts/core}/field_spec.coffee +0 -0
- data/spec/{core → javascripts/core}/framework_spec.coffee +0 -0
- data/spec/{core → javascripts/core}/model_spec.coffee +0 -0
- data/spec/javascripts/core/observer_spec.coffee +0 -0
- data/spec/{core → javascripts/core}/util_spec.coffee +0 -0
- data/spec/{core → javascripts/core}/view_spec.coffee +51 -39
- data/spec/{dependencies → javascripts/dependencies}/index.coffee +0 -0
- data/spec/{dependencies → javascripts/dependencies}/jasmine-html.js +0 -0
- data/spec/{dependencies → javascripts/dependencies}/jasmine.js +0 -0
- data/spec/{dependencies → javascripts/dependencies}/sinon.js +0 -0
- data/spec/{helper.coffee → javascripts/helper.coffee} +0 -0
- data/spec/{managers → javascripts/managers}/collection_manager_spec.coffee +0 -0
- data/spec/javascripts/managers/socket_manager_spec.coffee +0 -0
- data/spec/lib/component_definition_spec.rb +63 -0
- data/spec/lib/input_compiler_spec.rb +9 -0
- data/spec/lib/luca_application_spec.rb +30 -0
- data/spec/support/fixtures/application.coffee +45 -0
- data/spec/support/fixtures/component.coffee +34 -0
- data/tutorials/component-definitions.md +0 -0
- data/tutorials/component-definitions/01_intro.md +0 -0
- data/tutorials/component-driven-design.md +140 -0
- data/tutorials/structure-of-a-project.md +63 -0
- data/vendor/assets/javascripts/backbone-min.js +37 -33
- data/vendor/assets/javascripts/backbone-query.min.js +1 -1
- data/vendor/assets/javascripts/hogan.js +707 -0
- data/vendor/assets/javascripts/jquery.js +5 -4
- data/vendor/assets/javascripts/keymaster.min.js +4 -0
- data/vendor/assets/javascripts/luca-dependencies.min.js +8 -0
- data/vendor/assets/javascripts/luca-development.min.js +1 -0
- data/vendor/assets/javascripts/luca-spec.js +6 -6
- data/vendor/assets/javascripts/luca-ui.js +7386 -0
- data/vendor/assets/javascripts/luca-ui.min.js +5 -0
- data/vendor/assets/javascripts/luca.full.min.js +12 -0
- data/vendor/assets/javascripts/luca.min.js +5 -0
- data/vendor/assets/javascripts/underscore-min.js +1 -5
- data/vendor/assets/javascripts/underscore-string.min.js +1 -1
- data/vendor/assets/stylesheets/luca-components.css +202 -0
- data/vendor/assets/stylesheets/luca-development.css +23 -0
- data/vendor/assets/stylesheets/luca-ui.css +198 -0
- metadata +324 -94
- data/app/assets/javascripts/luca/components/base_toolbar.coffee +0 -17
- data/app/assets/javascripts/luca/components/form_button_toolbar.coffee +0 -28
- data/app/assets/javascripts/luca/components/grid_view.coffee +0 -269
- data/app/assets/javascripts/luca/components/page_controller.coffee +0 -7
- data/app/assets/javascripts/luca/components/template.coffee +0 -5
- data/app/assets/javascripts/luca/components/toolbar_dialog.coffee +0 -25
- data/lib/luca/code_browser.rb +0 -55
- data/lib/luca/command_line.rb +0 -69
- data/lib/luca/component_documentation.rb +0 -72
- data/site/assets/bootstrap.min.js +0 -7
- data/site/assets/dependencies.js +0 -94
- data/site/assets/glyphicons-halflings-white.png +0 -0
- data/site/assets/glyphicons-halflings.png +0 -0
- data/site/assets/luca-ui-bootstrap.css +0 -1331
- data/site/assets/luca-ui-bootstrap.js +0 -9
- data/site/assets/luca-ui-development-tools.css +0 -234
- data/site/assets/luca-ui-development-tools.js +0 -18561
- data/site/assets/luca-ui-development-tools.min.js +0 -15
- data/site/assets/luca-ui-full.min.js +0 -8
- data/site/assets/luca-ui.min.js +0 -4
- data/site/assets/sandbox.css +0 -62
- data/site/assets/sandbox.js +0 -469
- data/site/docs/application.html +0 -41
- data/site/docs/caching.html +0 -43
- data/site/docs/collection.html +0 -75
- data/site/docs/collection_manager.html +0 -71
- data/site/docs/containers.html +0 -118
- data/site/docs/events.html +0 -153
- data/site/docs/view.html +0 -128
- data/site/img/glyphicons-halflings-white.png +0 -0
- data/site/img/glyphicons-halflings.png +0 -0
- data/site/index.html +0 -20
- data/site/source-map.js +0 -1
- data/spec/components/form_view_spec.coffee +0 -84
- data/spec/containers/card_view_spec.coffee +0 -50
- data/spec/luca-spec.coffee +0 -9
@@ -0,0 +1,63 @@
|
|
1
|
+
## The Structure Of A Project
|
2
|
+
|
3
|
+
Luca Applications can be generated with a rails generator `rails generate luca:application app`
|
4
|
+
|
5
|
+
This will create an application file structure for you, as well as some basic classes:
|
6
|
+
|
7
|
+
```
|
8
|
+
- app/assets/javascripts/app
|
9
|
+
- views/
|
10
|
+
- models/
|
11
|
+
- components/
|
12
|
+
- collections/
|
13
|
+
- templates/
|
14
|
+
- lib/
|
15
|
+
- config.coffee
|
16
|
+
- index.coffee
|
17
|
+
- application.coffee
|
18
|
+
```
|
19
|
+
|
20
|
+
### config.coffee
|
21
|
+
|
22
|
+
```
|
23
|
+
Luca.initialize "App",
|
24
|
+
modelBootstrap: "window.AppBootstrap"
|
25
|
+
customConfigValue: "overrides Luca.config.customConfigValue"
|
26
|
+
```
|
27
|
+
|
28
|
+
This will create the necessary namespaces to hold your components:
|
29
|
+
|
30
|
+
```
|
31
|
+
window.App =
|
32
|
+
views: {}
|
33
|
+
collections: {}
|
34
|
+
models: {}
|
35
|
+
components: {}
|
36
|
+
```
|
37
|
+
|
38
|
+
It will also create a helper function for you called `App()`
|
39
|
+
|
40
|
+
`App()` without any arguments can be used to access the singleton instance of the global `App.Application` class.
|
41
|
+
|
42
|
+
`App("my_view_name")` can be used to access an individual view instance by its `@name` or `@cid` property.
|
43
|
+
|
44
|
+
`App(".custom-dom-selector")` can be used to access an instance of a view by a member of its DOM structure.
|
45
|
+
|
46
|
+
|
47
|
+
### index.coffee
|
48
|
+
|
49
|
+
This will make the application available to the Rails asset Pipeline. You simply need to:
|
50
|
+
|
51
|
+
```
|
52
|
+
javascript_include_tag 'app'
|
53
|
+
```
|
54
|
+
|
55
|
+
This will load all of the assets defined in your folder, in the proper order they need to be included.
|
56
|
+
|
57
|
+
It will also handle booting your application for you:
|
58
|
+
|
59
|
+
```
|
60
|
+
App.onReady ()->
|
61
|
+
window.MyApp = new App.Application()
|
62
|
+
window.MyApp.boot()
|
63
|
+
```
|
@@ -1,38 +1,42 @@
|
|
1
|
-
// Backbone.js 0.9.
|
1
|
+
// Backbone.js 0.9.9
|
2
2
|
|
3
3
|
// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
|
4
4
|
// Backbone may be freely distributed under the MIT license.
|
5
5
|
// For all details and documentation:
|
6
6
|
// http://backbonejs.org
|
7
|
-
(function(){var
|
8
|
-
|
9
|
-
|
10
|
-
{
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
return this.isNew()?
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
a.slice():[a];
|
21
|
-
|
22
|
-
this.
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
this.
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
e.
|
38
|
-
b
|
7
|
+
(function(){var k=this,y=k.Backbone,h=[],z=h.push,r=h.slice,A=h.splice,g;g="undefined"!==typeof exports?exports:k.Backbone={};g.VERSION="0.9.9";var e=k._;!e&&"undefined"!==typeof require&&(e=require("underscore"));g.$=k.jQuery||k.Zepto||k.ender;g.noConflict=function(){k.Backbone=y;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var s=/\s+/,n=function(a,b,c,d){if(!c)return!0;if("object"===typeof c)for(var f in c)a[b].apply(a,[f,c[f]].concat(d));else if(s.test(c)){c=c.split(s);f=0;for(var e=c.length;f<
|
8
|
+
e;f++)a[b].apply(a,[c[f]].concat(d))}else return!0},t=function(a,b,c){var d,a=-1,f=b.length;switch(c.length){case 0:for(;++a<f;)(d=b[a]).callback.call(d.ctx);break;case 1:for(;++a<f;)(d=b[a]).callback.call(d.ctx,c[0]);break;case 2:for(;++a<f;)(d=b[a]).callback.call(d.ctx,c[0],c[1]);break;case 3:for(;++a<f;)(d=b[a]).callback.call(d.ctx,c[0],c[1],c[2]);break;default:for(;++a<f;)(d=b[a]).callback.apply(d.ctx,c)}},h=g.Events={on:function(a,b,c){if(!n(this,"on",a,[b,c])||!b)return this;this._events||(this._events=
|
9
|
+
{});(this._events[a]||(this._events[a]=[])).push({callback:b,context:c,ctx:c||this});return this},once:function(a,b,c){if(!n(this,"once",a,[b,c])||!b)return this;var d=this,f=e.once(function(){d.off(a,f);b.apply(this,arguments)});f._callback=b;this.on(a,f,c);return this},off:function(a,b,c){var d,f,l,g,i,m,h,j;if(!this._events||!n(this,"off",a,[b,c]))return this;if(!a&&!b&&!c)return this._events={},this;g=a?[a]:e.keys(this._events);i=0;for(m=g.length;i<m;i++)if(a=g[i],d=this._events[a]){l=[];if(b||
|
10
|
+
c){h=0;for(j=d.length;h<j;h++)f=d[h],(b&&b!==(f.callback._callback||f.callback)||c&&c!==f.context)&&l.push(f)}this._events[a]=l}return this},trigger:function(a){if(!this._events)return this;var b=r.call(arguments,1);if(!n(this,"trigger",a,b))return this;var c=this._events[a],d=this._events.all;c&&t(this,c,b);d&&t(this,d,arguments);return this},listenTo:function(a,b,c){var d=this._listeners||(this._listeners={}),f=a._listenerId||(a._listenerId=e.uniqueId("l"));d[f]=a;a.on(b,c||this,this);return this},
|
11
|
+
stopListening:function(a,b,c){var d=this._listeners;if(d){if(a)a.off(b,c,this),!b&&!c&&delete d[a._listenerId];else{for(var f in d)d[f].off(null,null,this);this._listeners={}}return this}}};h.bind=h.on;h.unbind=h.off;e.extend(g,h);var o=g.Model=function(a,b){var c,d=a||{};this.cid=e.uniqueId("c");this.changed={};this.attributes={};this._changes=[];b&&b.collection&&(this.collection=b.collection);b&&b.parse&&(d=this.parse(d));(c=e.result(this,"defaults"))&&e.defaults(d,c);this.set(d,{silent:!0});this._currentAttributes=
|
12
|
+
e.clone(this.attributes);this._previousAttributes=e.clone(this.attributes);this.initialize.apply(this,arguments)};e.extend(o.prototype,h,{changed:null,idAttribute:"id",initialize:function(){},toJSON:function(){return e.clone(this.attributes)},sync:function(){return g.sync.apply(this,arguments)},get:function(a){return this.attributes[a]},escape:function(a){return e.escape(this.get(a))},has:function(a){return null!=this.get(a)},set:function(a,b,c){var d,f;if(null==a)return this;e.isObject(a)?(f=a,c=
|
13
|
+
b):(f={})[a]=b;var a=c&&c.silent,l=c&&c.unset;if(!this._validate(f,c))return!1;this.idAttribute in f&&(this.id=f[this.idAttribute]);var g=this.attributes;for(d in f)b=f[d],l?delete g[d]:g[d]=b,this._changes.push(d,b);this._hasComputed=!1;a||this.change(c);return this},unset:function(a,b){return this.set(a,void 0,e.extend({},b,{unset:!0}))},clear:function(a){var b={},c;for(c in this.attributes)b[c]=void 0;return this.set(b,e.extend({},a,{unset:!0}))},fetch:function(a){a=a?e.clone(a):{};void 0===a.parse&&
|
14
|
+
(a.parse=!0);var b=this,c=a.success;a.success=function(d){if(!b.set(b.parse(d),a))return false;c&&c(b,d,a)};return this.sync("read",this,a)},save:function(a,b,c){var d,f,g;null==a||e.isObject(a)?(d=a,c=b):null!=a&&((d={})[a]=b);c=c?e.clone(c):{};if(c.wait){if(d&&!this._validate(d,c))return!1;f=e.clone(this.attributes)}a=e.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c)||!d&&!this._validate(null,c))return!1;var q=this,i=c.success;c.success=function(a){g=true;var b=q.parse(a);c.wait&&(b=e.extend(d||
|
15
|
+
{},b));if(!q.set(b,c))return false;i&&i(q,a,c)};b=this.isNew()?"create":c.patch?"patch":"update";"patch"==b&&(c.attrs=d);b=this.sync(b,this,c);!g&&c.wait&&(this.clear(a),this.set(f,a));return b},destroy:function(a){var a=a?e.clone(a):{},b=this,c=a.success,d=function(){b.trigger("destroy",b,b.collection,a)};a.success=function(f){(a.wait||b.isNew())&&d();c&&c(b,f,a)};if(this.isNew())return a.success(),!1;var f=this.sync("delete",this,a);a.wait||d();return f},url:function(){var a=e.result(this,"urlRoot")||
|
16
|
+
e.result(this.collection,"url")||u();return this.isNew()?a:a+("/"===a.charAt(a.length-1)?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return null==this.id},change:function(a){var b=this._changing;this._changing=!0;var c=this._computeChanges(!0);this._pending=!!c.length;for(var d=c.length-2;0<=d;d-=2)this.trigger("change:"+c[d],this,c[d+1],a);if(b)return this;for(;this._pending;)this._pending=!1,this.trigger("change",
|
17
|
+
this,a),this._previousAttributes=e.clone(this.attributes);this._changing=!1;return this},hasChanged:function(a){this._hasComputed||this._computeChanges();return null==a?!e.isEmpty(this.changed):e.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?e.clone(this.changed):!1;var b,c=!1,d=this._previousAttributes,f;for(f in a)if(!e.isEqual(d[f],b=a[f]))(c||(c={}))[f]=b;return c},_computeChanges:function(a){this.changed={};for(var b={},c=[],d=this._currentAttributes,f=this._changes,
|
18
|
+
e=f.length-2;0<=e;e-=2){var g=f[e],i=f[e+1];b[g]||(b[g]=!0,d[g]!==i&&(this.changed[g]=i,a&&(c.push(g,i),d[g]=i)))}a&&(this._changes=[]);this._hasComputed=!0;return c},previous:function(a){return null==a||!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return e.clone(this._previousAttributes)},_validate:function(a,b){if(!this.validate)return!0;var a=e.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error&&b.error(this,c,b);this.trigger("error",
|
19
|
+
this,c,b);return!1}});var p=g.Collection=function(a,b){b||(b={});b.model&&(this.model=b.model);void 0!==b.comparator&&(this.comparator=b.comparator);this._reset();this.initialize.apply(this,arguments);a&&this.reset(a,e.extend({silent:!0},b))};e.extend(p.prototype,h,{model:o,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},sync:function(){return g.sync.apply(this,arguments)},add:function(a,b){var c,d,f,g,h=b&&b.at,i=null==(b&&b.sort)?!0:b.sort,a=e.isArray(a)?
|
20
|
+
a.slice():[a];for(c=a.length-1;0<=c;c--)(d=this._prepareModel(a[c],b))?(a[c]=d,(f=null!=d.id&&this._byId[d.id])||this._byCid[d.cid]?(b&&(b.merge&&f)&&(f.set(d.attributes,b),g=i),a.splice(c,1)):(d.on("all",this._onModelEvent,this),this._byCid[d.cid]=d,null!=d.id&&(this._byId[d.id]=d))):(this.trigger("error",this,a[c],b),a.splice(c,1));a.length&&(g=i);this.length+=a.length;c=[null!=h?h:this.models.length,0];z.apply(c,a);A.apply(this.models,c);g&&(this.comparator&&null==h)&&this.sort({silent:!0});if(b&&
|
21
|
+
b.silent)return this;for(;d=a.shift();)d.trigger("add",d,this,b);return this},remove:function(a,b){var c,d,f,g;b||(b={});a=e.isArray(a)?a.slice():[a];c=0;for(d=a.length;c<d;c++)if(g=this.get(a[c]))delete this._byId[g.id],delete this._byCid[g.cid],f=this.indexOf(g),this.models.splice(f,1),this.length--,b.silent||(b.index=f,g.trigger("remove",g,this,b)),this._removeReference(g);return this},push:function(a,b){a=this._prepareModel(a,b);this.add(a,e.extend({at:this.length},b));return a},pop:function(a){var b=
|
22
|
+
this.at(this.length-1);this.remove(b,a);return b},unshift:function(a,b){a=this._prepareModel(a,b);this.add(a,e.extend({at:0},b));return a},shift:function(a){var b=this.at(0);this.remove(b,a);return b},slice:function(a,b){return this.models.slice(a,b)},get:function(a){return null==a?void 0:this._byId[null!=a.id?a.id:a]||this._byCid[a.cid||a]},at:function(a){return this.models[a]},where:function(a){return e.isEmpty(a)?[]:this.filter(function(b){for(var c in a)if(a[c]!==b.get(c))return!1;return!0})},
|
23
|
+
sort:function(a){if(!this.comparator)throw Error("Cannot sort a set without a comparator");e.isString(this.comparator)||1===this.comparator.length?this.models=this.sortBy(this.comparator,this):this.models.sort(e.bind(this.comparator,this));(!a||!a.silent)&&this.trigger("sort",this,a);return this},pluck:function(a){return e.invoke(this.models,"get",a)},update:function(a,b){var c,d,f,g,h=[],i=[],m={},j=this.model.prototype.idAttribute,b=e.extend({add:!0,merge:!0,remove:!0},b);b.parse&&(a=this.parse(a));
|
24
|
+
e.isArray(a)||(a=a?[a]:[]);if(b.add&&!b.remove)return this.add(a,b);d=0;for(f=a.length;d<f;d++)c=a[d],g=this.get(c.id||c.cid||c[j]),b.remove&&g&&(m[g.cid]=!0),(b.add&&!g||b.merge&&g)&&h.push(c);if(b.remove){d=0;for(f=this.models.length;d<f;d++)c=this.models[d],m[c.cid]||i.push(c)}i.length&&this.remove(i,b);h.length&&this.add(h,b);return this},reset:function(a,b){b||(b={});b.parse&&(a=this.parse(a));for(var c=0,d=this.models.length;c<d;c++)this._removeReference(this.models[c]);b.previousModels=this.models;
|
25
|
+
this._reset();a&&this.add(a,e.extend({silent:!0},b));b.silent||this.trigger("reset",this,b);return this},fetch:function(a){a=a?e.clone(a):{};void 0===a.parse&&(a.parse=!0);var b=this,c=a.success;a.success=function(d){b[a.update?"update":"reset"](d,a);c&&c(b,d,a)};return this.sync("read",this,a)},create:function(a,b){var c=this,b=b?e.clone(b):{},a=this._prepareModel(a,b);if(!a)return!1;b.wait||c.add(a,b);var d=b.success;b.success=function(a,b,e){e.wait&&c.add(a,e);d&&d(a,b,e)};a.save(null,b);return a},
|
26
|
+
parse:function(a){return a},clone:function(){return new this.constructor(this.models)},chain:function(){return e(this.models).chain()},_reset:function(){this.length=0;this.models=[];this._byId={};this._byCid={}},_prepareModel:function(a,b){if(a instanceof o)return a.collection||(a.collection=this),a;b||(b={});b.collection=this;var c=new this.model(a,b);return!c._validate(a,b)?!1:c},_removeReference:function(a){this===a.collection&&delete a.collection;a.off("all",this._onModelEvent,this)},_onModelEvent:function(a,
|
27
|
+
b,c,d){("add"===a||"remove"===a)&&c!==this||("destroy"===a&&this.remove(b,d),b&&a==="change:"+b.idAttribute&&(delete this._byId[b.previous(b.idAttribute)],null!=b.id&&(this._byId[b.id]=b)),this.trigger.apply(this,arguments))}});e.each("forEach each map collect reduce foldl inject reduceRight foldr find detect filter select reject every all some any include contains invoke max min sortedIndex toArray size first head take initial rest tail last without indexOf shuffle lastIndexOf isEmpty".split(" "),
|
28
|
+
function(a){p.prototype[a]=function(){var b=r.call(arguments);b.unshift(this.models);return e[a].apply(e,b)}});e.each(["groupBy","countBy","sortBy"],function(a){p.prototype[a]=function(b,c){var d=e.isFunction(b)?b:function(a){return a.get(b)};return e[a](this.models,d,c)}});var v=g.Router=function(a){a||(a={});a.routes&&(this.routes=a.routes);this._bindRoutes();this.initialize.apply(this,arguments)},B=/\((.*?)\)/g,C=/:\w+/g,D=/\*\w+/g,E=/[\-{}\[\]+?.,\\\^$|#\s]/g;e.extend(v.prototype,h,{initialize:function(){},
|
29
|
+
route:function(a,b,c){e.isRegExp(a)||(a=this._routeToRegExp(a));c||(c=this[b]);g.history.route(a,e.bind(function(d){d=this._extractParameters(a,d);c&&c.apply(this,d);this.trigger.apply(this,["route:"+b].concat(d));g.history.trigger("route",this,b,d)},this));return this},navigate:function(a,b){g.history.navigate(a,b);return this},_bindRoutes:function(){if(this.routes)for(var a,b=e.keys(this.routes);null!=(a=b.pop());)this.route(a,this.routes[a])},_routeToRegExp:function(a){a=a.replace(E,"\\$&").replace(B,
|
30
|
+
"(?:$1)?").replace(C,"([^/]+)").replace(D,"(.*?)");return RegExp("^"+a+"$")},_extractParameters:function(a,b){return a.exec(b).slice(1)}});var j=g.History=function(){this.handlers=[];e.bindAll(this,"checkUrl");"undefined"!==typeof window&&(this.location=window.location,this.history=window.history)},w=/^[#\/]|\s+$/g,F=/^\/+|\/+$/g,G=/msie [\w.]+/,H=/\/$/;j.started=!1;e.extend(j.prototype,h,{interval:50,getHash:function(a){return(a=(a||this).location.href.match(/#(.*)$/))?a[1]:""},getFragment:function(a,
|
31
|
+
b){if(null==a)if(this._hasPushState||!this._wantsHashChange||b){var a=this.location.pathname,c=this.root.replace(H,"");a.indexOf(c)||(a=a.substr(c.length))}else a=this.getHash();return a.replace(w,"")},start:function(a){if(j.started)throw Error("Backbone.history has already been started");j.started=!0;this.options=e.extend({},{root:"/"},this.options,a);this.root=this.options.root;this._wantsHashChange=!1!==this.options.hashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=!(!this.options.pushState||
|
32
|
+
!this.history||!this.history.pushState);var a=this.getFragment(),b=document.documentMode,b=G.exec(navigator.userAgent.toLowerCase())&&(!b||7>=b);this.root=("/"+this.root+"/").replace(F,"/");b&&this._wantsHashChange&&(this.iframe=g.$('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow,this.navigate(a));this._hasPushState?g.$(window).bind("popstate",this.checkUrl):this._wantsHashChange&&"onhashchange"in window&&!b?g.$(window).bind("hashchange",this.checkUrl):this._wantsHashChange&&
|
33
|
+
(this._checkUrlInterval=setInterval(this.checkUrl,this.interval));this.fragment=a;a=this.location;b=a.pathname.replace(/[^\/]$/,"$&/")===this.root;if(this._wantsHashChange&&this._wantsPushState&&!this._hasPushState&&!b)return this.fragment=this.getFragment(null,!0),this.location.replace(this.root+this.location.search+"#"+this.fragment),!0;this._wantsPushState&&(this._hasPushState&&b&&a.hash)&&(this.fragment=this.getHash().replace(w,""),this.history.replaceState({},document.title,this.root+this.fragment+
|
34
|
+
a.search));if(!this.options.silent)return this.loadUrl()},stop:function(){g.$(window).unbind("popstate",this.checkUrl).unbind("hashchange",this.checkUrl);clearInterval(this._checkUrlInterval);j.started=!1},route:function(a,b){this.handlers.unshift({route:a,callback:b})},checkUrl:function(){var a=this.getFragment();a===this.fragment&&this.iframe&&(a=this.getFragment(this.getHash(this.iframe)));if(a===this.fragment)return!1;this.iframe&&this.navigate(a);this.loadUrl()||this.loadUrl(this.getHash())},
|
35
|
+
loadUrl:function(a){var b=this.fragment=this.getFragment(a);return e.any(this.handlers,function(a){if(a.route.test(b))return a.callback(b),!0})},navigate:function(a,b){if(!j.started)return!1;if(!b||!0===b)b={trigger:b};a=this.getFragment(a||"");if(this.fragment!==a){this.fragment=a;var c=this.root+a;if(this._hasPushState)this.history[b.replace?"replaceState":"pushState"]({},document.title,c);else if(this._wantsHashChange)this._updateHash(this.location,a,b.replace),this.iframe&&a!==this.getFragment(this.getHash(this.iframe))&&
|
36
|
+
(b.replace||this.iframe.document.open().close(),this._updateHash(this.iframe.location,a,b.replace));else return this.location.assign(c);b.trigger&&this.loadUrl(a)}},_updateHash:function(a,b,c){c?(c=a.href.replace(/(javascript:|#).*$/,""),a.replace(c+"#"+b)):a.hash="#"+b}});g.history=new j;var x=g.View=function(a){this.cid=e.uniqueId("view");this._configure(a||{});this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()},I=/^(\S+)\s*(.*)$/,J="model collection el id attributes className tagName events".split(" ");
|
37
|
+
e.extend(x.prototype,h,{tagName:"div",$:function(a){return this.$el.find(a)},initialize:function(){},render:function(){return this},remove:function(){this.$el.remove();this.stopListening();return this},make:function(a,b,c){a=document.createElement(a);b&&g.$(a).attr(b);null!=c&&g.$(a).html(c);return a},setElement:function(a,b){this.$el&&this.undelegateEvents();this.$el=a instanceof g.$?a:g.$(a);this.el=this.$el[0];!1!==b&&this.delegateEvents();return this},delegateEvents:function(a){if(a||(a=e.result(this,
|
38
|
+
"events"))){this.undelegateEvents();for(var b in a){var c=a[b];e.isFunction(c)||(c=this[a[b]]);if(!c)throw Error('Method "'+a[b]+'" does not exist');var d=b.match(I),f=d[1],d=d[2],c=e.bind(c,this),f=f+(".delegateEvents"+this.cid);""===d?this.$el.bind(f,c):this.$el.delegate(d,f,c)}}},undelegateEvents:function(){this.$el.unbind(".delegateEvents"+this.cid)},_configure:function(a){this.options&&(a=e.extend({},e.result(this,"options"),a));e.extend(this,e.pick(a,J));this.options=a},_ensureElement:function(){if(this.el)this.setElement(e.result(this,
|
39
|
+
"el"),!1);else{var a=e.extend({},e.result(this,"attributes"));this.id&&(a.id=e.result(this,"id"));this.className&&(a["class"]=e.result(this,"className"));this.setElement(this.make(e.result(this,"tagName"),a),!1)}}});var K={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};g.sync=function(a,b,c){var d=K[a];e.defaults(c||(c={}),{emulateHTTP:g.emulateHTTP,emulateJSON:g.emulateJSON});var f={type:d,dataType:"json"};c.url||(f.url=e.result(b,"url")||u());if(null==c.data&&b&&("create"===
|
40
|
+
a||"update"===a||"patch"===a))f.contentType="application/json",f.data=JSON.stringify(c.attrs||b.toJSON(c));c.emulateJSON&&(f.contentType="application/x-www-form-urlencoded",f.data=f.data?{model:f.data}:{});if(c.emulateHTTP&&("PUT"===d||"DELETE"===d||"PATCH"===d)){f.type="POST";c.emulateJSON&&(f.data._method=d);var h=c.beforeSend;c.beforeSend=function(a){a.setRequestHeader("X-HTTP-Method-Override",d);if(h)return h.apply(this,arguments)}}"GET"!==f.type&&!c.emulateJSON&&(f.processData=!1);var j=c.success;
|
41
|
+
c.success=function(a,d,e){j&&j(a,d,e);b.trigger("sync",b,a,c)};var i=c.error;c.error=function(a){i&&i(b,a,c);b.trigger("error",b,a,c)};a=g.ajax(e.extend(f,c));b.trigger("request",b,a,c);return a};g.ajax=function(){return g.$.ajax.apply(g.$,arguments)};o.extend=p.extend=v.extend=x.extend=j.extend=function(a,b){var c=this,d;d=a&&e.has(a,"constructor")?a.constructor:function(){c.apply(this,arguments)};e.extend(d,c,b);var f=function(){this.constructor=d};f.prototype=c.prototype;d.prototype=new f;a&&e.extend(d.prototype,
|
42
|
+
a);d.__super__=c.prototype;return d};var u=function(){throw Error('A "url" property or function must be specified');}}).call(this);
|
@@ -1 +1 @@
|
|
1
|
-
((function(){
|
1
|
+
var __slice=[].slice,__hasProp={}.hasOwnProperty,__indexOf=[].indexOf||function(a){for(var b=0,c=this.length;b<c;b++)if(b in this&&this[b]===a)return b;return-1};((function(a){return a("backbone-query",function(a,b){var c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;return u=a("underscore"),c=a("backbone"),e=function(a,b){var c,d,e,f;f=[];for(d=0,e=a.length;d<e;d++)c=a[d],b(c)&&f.push(c);return f},p=function(a,b){var c,d,e,f;f=[];for(d=0,e=a.length;d<e;d++)c=a[d],b(c)||f.push(c);return f},d=function(a,b){var c,d,e;for(d=0,e=a.length;d<e;d++){c=a[d];if(b(c))return!0}return!1},j=function(){var a,b,c,d,e;a=1<=arguments.length?__slice.call(arguments,0):[],d={},b=d;while(a.length)c=a.shift(),e=a.length===1?a.shift():{},b=b[c]=e;return d},h=function(a){return u.isRegExp(a)?"$regex":u.isDate(a)?"$date":u.isObject(a)&&!u.isArray(a)?"object":u.isArray(a)?"array":u.isString(a)?"string":u.isNumber(a)?"number":u.isBoolean(a)?"boolean":u.isFunction(a)?"function":!1},m=function(a){var b,c,d,e,f,g,i,k,n,o,p,q,r;u.isArray(a)?g=a:g=function(){var c;c=[];for(b in a){if(!__hasProp.call(a,b))continue;n=a[b],c.push(j(b,n))}return c}(),r=[];for(p=0,q=g.length;p<q;p++){f=g[p];for(b in f){if(!__hasProp.call(f,b))continue;i=f[b],c={key:b},d=h(i);switch(d){case"$regex":case"$date":c.type=d,c.value=i;break;case"object":if(b==="$and"||b==="$or"||b==="$nor"||b==="$not")c.value=m(i),c.type=b,c.key=null;else for(k in i){o=i[k];if(t(k,o)){c.type=k;switch(k){case"$elemMatch":case"$relationMatch":c.value=l(o);break;case"$computed":e=j(b,o),c.value=m(e);break;default:c.value=o}}}break;default:c.type="$equal",c.value=i}c.type==="$equal"&&(d==="object"||d==="array")&&(c.type="$oEqual")}r.push(c)}return r},t=function(a,b){switch(a){case"$in":case"$nin":case"$all":case"$any":return u(b).isArray();case"$size":return u(b).isNumber();case"$regex":return u(b).isRegExp();case"$like":case"$likeI":return u(b).isString();case"$between":return u(b).isArray()&&b.length===2;case"$cb":return u(b).isFunction();default:return!0}},s=function(a,b){switch(a){case"$like":case"$likeI":case"$regex":return u(b).isString();case"$contains":case"$all":case"$any":case"$elemMatch":return u(b).isArray();case"$size":return u(b).isArray()||u(b).isString();case"$in":case"$nin":return b!=null;case"$relationMatch":return b!=null&&b.models;default:return!0}},n=function(a,b,c,e,f){switch(a){case"$equal":return u(c).isArray()?__indexOf.call(c,b)>=0:c===b;case"$oEqual":return u(c).isEqual(b);case"$contains":return __indexOf.call(c,b)>=0;case"$ne":return c!==b;case"$lt":return c<b;case"$gt":return c>b;case"$lte":return c<=b;case"$gte":return c>=b;case"$between":return b[0]<c&&c<b[1];case"$in":return __indexOf.call(b,c)>=0;case"$nin":return __indexOf.call(b,c)<0;case"$all":return u(b).all(function(a){return __indexOf.call(c,a)>=0});case"$any":return u(c).any(function(a){return __indexOf.call(b,a)>=0});case"$size":return c.length===b;case"$exists":case"$has":return c!=null===b;case"$like":return c.indexOf(b)!==-1;case"$likeI":return c.toLowerCase().indexOf(b.toLowerCase())!==-1;case"$regex":return b.test(c);case"$cb":return b.call(e,c);case"$elemMatch":return q(c,b,"elemMatch").length>0;case"$relationMatch":return q(c.models,b,"relationMatch").length>0;case"$computed":return i([e],b,!1,d,"computed");case"$and":case"$or":case"$nor":case"$not":return o[a]([e],b).length===1;default:return!1}},i=function(a,b,c,d,e){return e==null&&(e=!1),d(a,function(a){var d,f,g,h,i;for(h=0,i=b.length;h<i;h++){f=b[h],d=function(){switch(e){case"elemMatch":return a[f.key];case"computed":return a[f.key]();default:return a.get(f.key)}}(),g=s(f.type,d),g&&(g=n(f.type,f.value,d,a,f.key));if(c===g)return c}return!c})},o={$and:function(a,b,c){return i(a,b,!1,e,c)},$or:function(a,b,c){return i(a,b,!0,e,c)},$nor:function(a,b,c){return i(a,b,!0,p,c)},$not:function(a,b,c){return i(a,b,!1,p,c)}},l=function(a){var b,c,d,e,f,g;e=u(a).keys(),b=["$and","$not","$or","$nor"],c=u.intersection(b,e);if(c.length===0)return[{type:"$and",parsedQuery:m(a)}];if(c.length!==e.length){__indexOf.call(c,"$and")<0&&(a.$and={},c.unshift("$and"));for(d in a){if(!__hasProp.call(a,d))continue;g=a[d];if(__indexOf.call(b,d)<0)a.$and[d]=g,delete a[d];else continue}}return function(){var b,d,e;e=[];for(b=0,d=c.length;b<d;b++)f=c[b],e.push({type:f,parsedQuery:m(a[f])});return e}()},q=function(a,b,c){var d;return c||(b=l(b)),d=function(a,b){return o[b.type](a,b.parsedQuery,c)},u.reduce(b,d,a)},f=function(a,b,c){var d,e,f,h;return f=JSON.stringify(b),d=(h=a._queryCache)!=null?h:a._queryCache={},e=d[f],e||(e=g(a,b,c),d[f]=e),e},g=function(a,b,c){var d;return d=q(a.models,b),c.sortBy&&(d=r(d,c)),d},r=function(a,b){return u(b.sortBy).isString()?a=u(a).sortBy(function(a){return a.get(b.sortBy)}):u(b.sortBy).isFunction()&&(a=u(a).sortBy(b.sortBy)),b.order==="desc"&&(a=a.reverse()),a},k=function(a,b){var c,d,e,f;return b.offset?e=b.offset:b.page?e=(b.page-1)*b.limit:e=0,c=e+b.limit,d=a.slice(e,c),b.pager&&u.isFunction(b.pager)&&(f=Math.ceil(a.length/b.limit),b.pager(f,d)),d},c.QueryCollection=c.Collection.extend({query:function(a,b){var c;return b==null&&(b={}),b.cache?c=f(this,a,b):c=g(this,a,b),b.limit&&(c=k(c,b)),c},findOne:function(a){return this.query(a)[0]},whereBy:function(a,b){return b==null&&(b={}),new this.constructor(this.query(a,b))},resetQueryCache:function(){return this._queryCache={}}}),b.QueryCollection=c.QueryCollection})})).call(this,typeof define=="function"&&define.amd?define:function(a,b){typeof exports!="undefined"?b(function(a){return require(a)},exports):b(function(a){return this[a==="underscore"?"_":"Backbone"]},{})})
|
@@ -0,0 +1,707 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright 2011 Twitter, Inc.
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
4
|
+
* you may not use this file except in compliance with the License.
|
5
|
+
* You may obtain a copy of the License at
|
6
|
+
*
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
8
|
+
*
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
12
|
+
* See the License for the specific language governing permissions and
|
13
|
+
* limitations under the License.
|
14
|
+
*/
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
var Hogan = {};
|
19
|
+
|
20
|
+
(function (Hogan, useArrayBuffer) {
|
21
|
+
Hogan.Template = function (codeObj, text, compiler, options) {
|
22
|
+
codeObj = codeObj || {};
|
23
|
+
this.r = codeObj.code || this.r;
|
24
|
+
this.c = compiler;
|
25
|
+
this.options = options;
|
26
|
+
this.text = text || '';
|
27
|
+
this.partials = codeObj.partials || {};
|
28
|
+
this.subs = codeObj.subs || {};
|
29
|
+
this.ib();
|
30
|
+
}
|
31
|
+
|
32
|
+
Hogan.Template.prototype = {
|
33
|
+
// render: replaced by generated code.
|
34
|
+
r: function (context, partials, indent) { return ''; },
|
35
|
+
|
36
|
+
// variable escaping
|
37
|
+
v: hoganEscape,
|
38
|
+
|
39
|
+
// triple stache
|
40
|
+
t: coerceToString,
|
41
|
+
|
42
|
+
render: function render(context, partials, indent) {
|
43
|
+
return this.ri([context], partials || {}, indent);
|
44
|
+
},
|
45
|
+
|
46
|
+
// render internal -- a hook for overrides that catches partials too
|
47
|
+
ri: function (context, partials, indent) {
|
48
|
+
return this.r(context, partials, indent);
|
49
|
+
},
|
50
|
+
|
51
|
+
// ensurePartial
|
52
|
+
ep: function(symbol, partials) {
|
53
|
+
var partial = this.partials[symbol];
|
54
|
+
|
55
|
+
// check to see that if we've instantiated this partial before
|
56
|
+
var template = partials[partial.name];
|
57
|
+
if (partial.instance && partial.base == template) {
|
58
|
+
return partial.instance;
|
59
|
+
}
|
60
|
+
|
61
|
+
if (typeof template == 'string') {
|
62
|
+
if (!this.c) {
|
63
|
+
throw new Error("No compiler available.");
|
64
|
+
}
|
65
|
+
template = this.c.compile(template, this.options);
|
66
|
+
}
|
67
|
+
|
68
|
+
if (!template) {
|
69
|
+
return null;
|
70
|
+
}
|
71
|
+
|
72
|
+
// We use this to check whether the partials dictionary has changed
|
73
|
+
this.partials[symbol].base = template;
|
74
|
+
|
75
|
+
if (partial.subs) {
|
76
|
+
template = createSpecializedPartial(template, partial.subs, partial.partials);
|
77
|
+
}
|
78
|
+
|
79
|
+
this.partials[symbol].instance = template;
|
80
|
+
return template;
|
81
|
+
},
|
82
|
+
|
83
|
+
// tries to find a partial in the curent scope and render it
|
84
|
+
rp: function(symbol, context, partials, indent) {
|
85
|
+
var partial = this.ep(symbol, partials);
|
86
|
+
if (!partial) {
|
87
|
+
return '';
|
88
|
+
}
|
89
|
+
|
90
|
+
return partial.ri(context, partials, indent);
|
91
|
+
},
|
92
|
+
|
93
|
+
// render a section
|
94
|
+
rs: function(context, partials, section) {
|
95
|
+
var tail = context[context.length - 1];
|
96
|
+
|
97
|
+
if (!isArray(tail)) {
|
98
|
+
section(context, partials, this);
|
99
|
+
return;
|
100
|
+
}
|
101
|
+
|
102
|
+
for (var i = 0; i < tail.length; i++) {
|
103
|
+
context.push(tail[i]);
|
104
|
+
section(context, partials, this);
|
105
|
+
context.pop();
|
106
|
+
}
|
107
|
+
},
|
108
|
+
|
109
|
+
// maybe start a section
|
110
|
+
s: function(val, ctx, partials, inverted, start, end, tags) {
|
111
|
+
var pass;
|
112
|
+
|
113
|
+
if (isArray(val) && val.length === 0) {
|
114
|
+
return false;
|
115
|
+
}
|
116
|
+
|
117
|
+
if (typeof val == 'function') {
|
118
|
+
val = this.ms(val, ctx, partials, inverted, start, end, tags);
|
119
|
+
}
|
120
|
+
|
121
|
+
pass = (val === '') || !!val;
|
122
|
+
|
123
|
+
if (!inverted && pass && ctx) {
|
124
|
+
ctx.push((typeof val == 'object') ? val : ctx[ctx.length - 1]);
|
125
|
+
}
|
126
|
+
|
127
|
+
return pass;
|
128
|
+
},
|
129
|
+
|
130
|
+
// find values with dotted names
|
131
|
+
d: function(key, ctx, partials, returnFound) {
|
132
|
+
var names = key.split('.'),
|
133
|
+
val = this.f(names[0], ctx, partials, returnFound),
|
134
|
+
cx = null;
|
135
|
+
|
136
|
+
if (key === '.' && isArray(ctx[ctx.length - 2])) {
|
137
|
+
return ctx[ctx.length - 1];
|
138
|
+
}
|
139
|
+
|
140
|
+
for (var i = 1; i < names.length; i++) {
|
141
|
+
if (val && typeof val == 'object' && val[names[i]] != null) {
|
142
|
+
cx = val;
|
143
|
+
val = val[names[i]];
|
144
|
+
} else {
|
145
|
+
val = '';
|
146
|
+
}
|
147
|
+
}
|
148
|
+
|
149
|
+
if (returnFound && !val) {
|
150
|
+
return false;
|
151
|
+
}
|
152
|
+
|
153
|
+
if (!returnFound && typeof val == 'function') {
|
154
|
+
ctx.push(cx);
|
155
|
+
val = this.mv(val, ctx, partials);
|
156
|
+
ctx.pop();
|
157
|
+
}
|
158
|
+
|
159
|
+
return val;
|
160
|
+
},
|
161
|
+
|
162
|
+
// find values with normal names
|
163
|
+
f: function(key, ctx, partials, returnFound) {
|
164
|
+
var val = false,
|
165
|
+
v = null,
|
166
|
+
found = false;
|
167
|
+
|
168
|
+
for (var i = ctx.length - 1; i >= 0; i--) {
|
169
|
+
v = ctx[i];
|
170
|
+
if (v && typeof v == 'object' && v[key] != null) {
|
171
|
+
val = v[key];
|
172
|
+
found = true;
|
173
|
+
break;
|
174
|
+
}
|
175
|
+
}
|
176
|
+
|
177
|
+
if (!found) {
|
178
|
+
return (returnFound) ? false : "";
|
179
|
+
}
|
180
|
+
|
181
|
+
if (!returnFound && typeof val == 'function') {
|
182
|
+
val = this.mv(val, ctx, partials);
|
183
|
+
}
|
184
|
+
|
185
|
+
return val;
|
186
|
+
},
|
187
|
+
|
188
|
+
// higher order templates
|
189
|
+
ls: function(func, cx, partials, text, tags) {
|
190
|
+
var oldTags = this.options.delimiters;
|
191
|
+
|
192
|
+
this.options.delimiters = tags;
|
193
|
+
this.b(this.ct(coerceToString(func.call(cx, text)), cx, partials));
|
194
|
+
this.options.delimiters = oldTags;
|
195
|
+
|
196
|
+
return false;
|
197
|
+
},
|
198
|
+
|
199
|
+
// compile text
|
200
|
+
ct: function(text, cx, partials) {
|
201
|
+
if (this.options.disableLambda) {
|
202
|
+
throw new Error('Lambda features disabled.');
|
203
|
+
}
|
204
|
+
return this.c.compile(text, this.options).render(cx, partials);
|
205
|
+
},
|
206
|
+
|
207
|
+
// template result buffering
|
208
|
+
b: (useArrayBuffer) ? function(s) { this.buf.push(s); } :
|
209
|
+
function(s) { this.buf += s; },
|
210
|
+
|
211
|
+
fl: (useArrayBuffer) ? function() { var r = this.buf.join(''); this.buf = []; return r; } :
|
212
|
+
function() { var r = this.buf; this.buf = ''; return r; },
|
213
|
+
// init the buffer
|
214
|
+
ib: function () {
|
215
|
+
this.buf = (useArrayBuffer) ? [] : '';
|
216
|
+
},
|
217
|
+
|
218
|
+
// method replace section
|
219
|
+
ms: function(func, ctx, partials, inverted, start, end, tags) {
|
220
|
+
var cx = ctx[ctx.length - 1],
|
221
|
+
result = func.call(cx);
|
222
|
+
|
223
|
+
if (typeof result == 'function') {
|
224
|
+
if (inverted) {
|
225
|
+
return true;
|
226
|
+
} else {
|
227
|
+
return this.ls(result, cx, partials, this.text.substring(start, end), tags);
|
228
|
+
}
|
229
|
+
}
|
230
|
+
|
231
|
+
return result;
|
232
|
+
},
|
233
|
+
|
234
|
+
// method replace variable
|
235
|
+
mv: function(func, ctx, partials) {
|
236
|
+
var cx = ctx[ctx.length - 1];
|
237
|
+
var result = func.call(cx);
|
238
|
+
|
239
|
+
if (typeof result == 'function') {
|
240
|
+
return this.ct(coerceToString(result.call(cx)), cx, partials);
|
241
|
+
}
|
242
|
+
|
243
|
+
return result;
|
244
|
+
},
|
245
|
+
|
246
|
+
sub: function(name, context, partials, indent) {
|
247
|
+
var f = this.subs[name];
|
248
|
+
if (f) {
|
249
|
+
f(context, partials, this, indent);
|
250
|
+
}
|
251
|
+
}
|
252
|
+
|
253
|
+
};
|
254
|
+
|
255
|
+
function createSpecializedPartial(instance, subs, partials) {
|
256
|
+
function PartialTemplate() {};
|
257
|
+
PartialTemplate.prototype = instance;
|
258
|
+
function Substitutions() {};
|
259
|
+
Substitutions.prototype = instance.subs;
|
260
|
+
var key;
|
261
|
+
var partial = new PartialTemplate();
|
262
|
+
partial.subs = new Substitutions();
|
263
|
+
partial.ib();
|
264
|
+
|
265
|
+
for (key in subs) {
|
266
|
+
partial.subs[key] = subs[key];
|
267
|
+
}
|
268
|
+
|
269
|
+
for (key in partials) {
|
270
|
+
partial.partials[key] = partials[key];
|
271
|
+
}
|
272
|
+
|
273
|
+
return partial;
|
274
|
+
}
|
275
|
+
|
276
|
+
var rAmp = /&/g,
|
277
|
+
rLt = /</g,
|
278
|
+
rGt = />/g,
|
279
|
+
rApos =/\'/g,
|
280
|
+
rQuot = /\"/g,
|
281
|
+
hChars =/[&<>\"\']/;
|
282
|
+
|
283
|
+
function coerceToString(val) {
|
284
|
+
return String((val === null || val === undefined) ? '' : val);
|
285
|
+
}
|
286
|
+
|
287
|
+
function hoganEscape(str) {
|
288
|
+
str = coerceToString(str);
|
289
|
+
return hChars.test(str) ?
|
290
|
+
str
|
291
|
+
.replace(rAmp,'&')
|
292
|
+
.replace(rLt,'<')
|
293
|
+
.replace(rGt,'>')
|
294
|
+
.replace(rApos,''')
|
295
|
+
.replace(rQuot, '"') :
|
296
|
+
str;
|
297
|
+
}
|
298
|
+
|
299
|
+
var isArray = Array.isArray || function(a) {
|
300
|
+
return Object.prototype.toString.call(a) === '[object Array]';
|
301
|
+
};
|
302
|
+
|
303
|
+
})(typeof exports !== 'undefined' ? exports : Hogan);
|
304
|
+
|
305
|
+
|
306
|
+
|
307
|
+
(function (Hogan) {
|
308
|
+
// Setup regex assignments
|
309
|
+
// remove whitespace according to Mustache spec
|
310
|
+
var rIsWhitespace = /\S/,
|
311
|
+
rQuot = /\"/g,
|
312
|
+
rNewline = /\n/g,
|
313
|
+
rCr = /\r/g,
|
314
|
+
rSlash = /\\/g;
|
315
|
+
|
316
|
+
Hogan.tags = {
|
317
|
+
'#': 1, '^': 2, '<': 3, '$': 4,
|
318
|
+
'/': 5, '!': 6, '>': 7, '=': 8, '_v': 9,
|
319
|
+
'{': 10, '&': 11, '_t': 12
|
320
|
+
};
|
321
|
+
|
322
|
+
Hogan.scan = function scan(text, delimiters) {
|
323
|
+
var len = text.length,
|
324
|
+
IN_TEXT = 0,
|
325
|
+
IN_TAG_TYPE = 1,
|
326
|
+
IN_TAG = 2,
|
327
|
+
state = IN_TEXT,
|
328
|
+
tagType = null,
|
329
|
+
tag = null,
|
330
|
+
buf = '',
|
331
|
+
tokens = [],
|
332
|
+
seenTag = false,
|
333
|
+
i = 0,
|
334
|
+
lineStart = 0,
|
335
|
+
otag = '{{',
|
336
|
+
ctag = '}}';
|
337
|
+
|
338
|
+
function addBuf() {
|
339
|
+
if (buf.length > 0) {
|
340
|
+
tokens.push({tag: '_t', text: new String(buf)});
|
341
|
+
buf = '';
|
342
|
+
}
|
343
|
+
}
|
344
|
+
|
345
|
+
function lineIsWhitespace() {
|
346
|
+
var isAllWhitespace = true;
|
347
|
+
for (var j = lineStart; j < tokens.length; j++) {
|
348
|
+
isAllWhitespace =
|
349
|
+
(Hogan.tags[tokens[j].tag] < Hogan.tags['_v']) ||
|
350
|
+
(tokens[j].tag == '_t' && tokens[j].text.match(rIsWhitespace) === null);
|
351
|
+
if (!isAllWhitespace) {
|
352
|
+
return false;
|
353
|
+
}
|
354
|
+
}
|
355
|
+
|
356
|
+
return isAllWhitespace;
|
357
|
+
}
|
358
|
+
|
359
|
+
function filterLine(haveSeenTag, noNewLine) {
|
360
|
+
addBuf();
|
361
|
+
|
362
|
+
if (haveSeenTag && lineIsWhitespace()) {
|
363
|
+
for (var j = lineStart, next; j < tokens.length; j++) {
|
364
|
+
if (tokens[j].text) {
|
365
|
+
if ((next = tokens[j+1]) && next.tag == '>') {
|
366
|
+
// set indent to token value
|
367
|
+
next.indent = tokens[j].text.toString()
|
368
|
+
}
|
369
|
+
tokens.splice(j, 1);
|
370
|
+
}
|
371
|
+
}
|
372
|
+
} else if (!noNewLine) {
|
373
|
+
tokens.push({tag:'\n'});
|
374
|
+
}
|
375
|
+
|
376
|
+
seenTag = false;
|
377
|
+
lineStart = tokens.length;
|
378
|
+
}
|
379
|
+
|
380
|
+
function changeDelimiters(text, index) {
|
381
|
+
var close = '=' + ctag,
|
382
|
+
closeIndex = text.indexOf(close, index),
|
383
|
+
delimiters = trim(
|
384
|
+
text.substring(text.indexOf('=', index) + 1, closeIndex)
|
385
|
+
).split(' ');
|
386
|
+
|
387
|
+
otag = delimiters[0];
|
388
|
+
ctag = delimiters[1];
|
389
|
+
|
390
|
+
return closeIndex + close.length - 1;
|
391
|
+
}
|
392
|
+
|
393
|
+
if (delimiters) {
|
394
|
+
delimiters = delimiters.split(' ');
|
395
|
+
otag = delimiters[0];
|
396
|
+
ctag = delimiters[1];
|
397
|
+
}
|
398
|
+
|
399
|
+
for (i = 0; i < len; i++) {
|
400
|
+
if (state == IN_TEXT) {
|
401
|
+
if (tagChange(otag, text, i)) {
|
402
|
+
--i;
|
403
|
+
addBuf();
|
404
|
+
state = IN_TAG_TYPE;
|
405
|
+
} else {
|
406
|
+
if (text.charAt(i) == '\n') {
|
407
|
+
filterLine(seenTag);
|
408
|
+
} else {
|
409
|
+
buf += text.charAt(i);
|
410
|
+
}
|
411
|
+
}
|
412
|
+
} else if (state == IN_TAG_TYPE) {
|
413
|
+
i += otag.length - 1;
|
414
|
+
tag = Hogan.tags[text.charAt(i + 1)];
|
415
|
+
tagType = tag ? text.charAt(i + 1) : '_v';
|
416
|
+
if (tagType == '=') {
|
417
|
+
i = changeDelimiters(text, i);
|
418
|
+
state = IN_TEXT;
|
419
|
+
} else {
|
420
|
+
if (tag) {
|
421
|
+
i++;
|
422
|
+
}
|
423
|
+
state = IN_TAG;
|
424
|
+
}
|
425
|
+
seenTag = i;
|
426
|
+
} else {
|
427
|
+
if (tagChange(ctag, text, i)) {
|
428
|
+
tokens.push({tag: tagType, n: trim(buf), otag: otag, ctag: ctag,
|
429
|
+
i: (tagType == '/') ? seenTag - otag.length : i + ctag.length});
|
430
|
+
buf = '';
|
431
|
+
i += ctag.length - 1;
|
432
|
+
state = IN_TEXT;
|
433
|
+
if (tagType == '{') {
|
434
|
+
if (ctag == '}}') {
|
435
|
+
i++;
|
436
|
+
} else {
|
437
|
+
cleanTripleStache(tokens[tokens.length - 1]);
|
438
|
+
}
|
439
|
+
}
|
440
|
+
} else {
|
441
|
+
buf += text.charAt(i);
|
442
|
+
}
|
443
|
+
}
|
444
|
+
}
|
445
|
+
|
446
|
+
filterLine(seenTag, true);
|
447
|
+
|
448
|
+
return tokens;
|
449
|
+
}
|
450
|
+
|
451
|
+
function cleanTripleStache(token) {
|
452
|
+
if (token.n.substr(token.n.length - 1) === '}') {
|
453
|
+
token.n = token.n.substring(0, token.n.length - 1);
|
454
|
+
}
|
455
|
+
}
|
456
|
+
|
457
|
+
function trim(s) {
|
458
|
+
if (s.trim) {
|
459
|
+
return s.trim();
|
460
|
+
}
|
461
|
+
|
462
|
+
return s.replace(/^\s*|\s*$/g, '');
|
463
|
+
}
|
464
|
+
|
465
|
+
function tagChange(tag, text, index) {
|
466
|
+
if (text.charAt(index) != tag.charAt(0)) {
|
467
|
+
return false;
|
468
|
+
}
|
469
|
+
|
470
|
+
for (var i = 1, l = tag.length; i < l; i++) {
|
471
|
+
if (text.charAt(index + i) != tag.charAt(i)) {
|
472
|
+
return false;
|
473
|
+
}
|
474
|
+
}
|
475
|
+
|
476
|
+
return true;
|
477
|
+
}
|
478
|
+
|
479
|
+
// the tags allowed inside super templates
|
480
|
+
var allowedInSuper = {'_t': true, '\n': true, '$': true, '/': true};
|
481
|
+
|
482
|
+
function buildTree(tokens, kind, stack, customTags) {
|
483
|
+
var instructions = [],
|
484
|
+
opener = null,
|
485
|
+
tail = null,
|
486
|
+
token = null;
|
487
|
+
|
488
|
+
tail = stack[stack.length - 1];
|
489
|
+
|
490
|
+
while (tokens.length > 0) {
|
491
|
+
token = tokens.shift();
|
492
|
+
|
493
|
+
if (tail && tail.tag == '<' && !(token.tag in allowedInSuper)) {
|
494
|
+
throw new Error('Illegal content in < super tag.');
|
495
|
+
}
|
496
|
+
|
497
|
+
if (Hogan.tags[token.tag] <= Hogan.tags['$'] || isOpener(token, customTags)) {
|
498
|
+
stack.push(token);
|
499
|
+
token.nodes = buildTree(tokens, token.tag, stack, customTags);
|
500
|
+
} else if (token.tag == '/') {
|
501
|
+
if (stack.length === 0) {
|
502
|
+
throw new Error('Closing tag without opener: /' + token.n);
|
503
|
+
}
|
504
|
+
opener = stack.pop();
|
505
|
+
if (token.n != opener.n && !isCloser(token.n, opener.n, customTags)) {
|
506
|
+
throw new Error('Nesting error: ' + opener.n + ' vs. ' + token.n);
|
507
|
+
}
|
508
|
+
opener.end = token.i;
|
509
|
+
return instructions;
|
510
|
+
} else if (token.tag == '\n') {
|
511
|
+
token.last = (tokens.length == 0) || (tokens[0].tag == '\n');
|
512
|
+
}
|
513
|
+
|
514
|
+
instructions.push(token);
|
515
|
+
}
|
516
|
+
|
517
|
+
if (stack.length > 0) {
|
518
|
+
throw new Error('missing closing tag: ' + stack.pop().n);
|
519
|
+
}
|
520
|
+
|
521
|
+
return instructions;
|
522
|
+
}
|
523
|
+
|
524
|
+
function isOpener(token, tags) {
|
525
|
+
for (var i = 0, l = tags.length; i < l; i++) {
|
526
|
+
if (tags[i].o == token.n) {
|
527
|
+
token.tag = '#';
|
528
|
+
return true;
|
529
|
+
}
|
530
|
+
}
|
531
|
+
}
|
532
|
+
|
533
|
+
function isCloser(close, open, tags) {
|
534
|
+
for (var i = 0, l = tags.length; i < l; i++) {
|
535
|
+
if (tags[i].c == close && tags[i].o == open) {
|
536
|
+
return true;
|
537
|
+
}
|
538
|
+
}
|
539
|
+
}
|
540
|
+
|
541
|
+
function stringifySubstitutions(obj) {
|
542
|
+
var items = [];
|
543
|
+
for (var key in obj) {
|
544
|
+
items.push('"' + esc(key) + '": function(c,p,t,i) {' + obj[key] + '}');
|
545
|
+
}
|
546
|
+
return "{ " + items.join(",") + " }";
|
547
|
+
}
|
548
|
+
|
549
|
+
function stringifyPartials(codeObj) {
|
550
|
+
var partials = [];
|
551
|
+
for (var key in codeObj.partials) {
|
552
|
+
partials.push('"' + esc(key) + '":{name:"' + esc(codeObj.partials[key].name) + '", ' + stringifyPartials(codeObj.partials[key]) + "}");
|
553
|
+
}
|
554
|
+
return "partials: {" + partials.join(",") + "}, subs: " + stringifySubstitutions(codeObj.subs);
|
555
|
+
}
|
556
|
+
|
557
|
+
Hogan.stringify = function(codeObj, text, options) {
|
558
|
+
return "{code: function (c,p,i) { " + Hogan.wrapMain(codeObj.code) + " }," + stringifyPartials(codeObj) + "}";
|
559
|
+
}
|
560
|
+
|
561
|
+
var serialNo = 0;
|
562
|
+
Hogan.generate = function(tree, text, options) {
|
563
|
+
serialNo = 0;
|
564
|
+
var context = { code: '', subs: {}, partials: {} };
|
565
|
+
Hogan.walk(tree, context);
|
566
|
+
|
567
|
+
if (options.asString) {
|
568
|
+
return this.stringify(context, text, options);
|
569
|
+
}
|
570
|
+
|
571
|
+
return this.makeTemplate(context, text, options);
|
572
|
+
}
|
573
|
+
|
574
|
+
Hogan.wrapMain = function(code) {
|
575
|
+
return 'var t=this;t.b(i=i||"");' + code + 'return t.fl();';
|
576
|
+
}
|
577
|
+
|
578
|
+
Hogan.template = Hogan.Template;
|
579
|
+
|
580
|
+
Hogan.makeTemplate = function(codeObj, text, options) {
|
581
|
+
var template = this.makePartials(codeObj);
|
582
|
+
template.code = new Function('c', 'p', 'i', this.wrapMain(codeObj.code));
|
583
|
+
return new this.template(template, text, this, options);
|
584
|
+
}
|
585
|
+
|
586
|
+
Hogan.makePartials = function(codeObj) {
|
587
|
+
var key, template = {subs: {}, partials: codeObj.partials, name: codeObj.name};
|
588
|
+
for (key in template.partials) {
|
589
|
+
template.partials[key] = this.makePartials(template.partials[key]);
|
590
|
+
}
|
591
|
+
for (key in codeObj.subs) {
|
592
|
+
template.subs[key] = new Function('c', 'p', 't', 'i', codeObj.subs[key]);
|
593
|
+
}
|
594
|
+
return template;
|
595
|
+
}
|
596
|
+
|
597
|
+
function esc(s) {
|
598
|
+
return s.replace(rSlash, '\\\\')
|
599
|
+
.replace(rQuot, '\\\"')
|
600
|
+
.replace(rNewline, '\\n')
|
601
|
+
.replace(rCr, '\\r');
|
602
|
+
}
|
603
|
+
|
604
|
+
function chooseMethod(s) {
|
605
|
+
return (~s.indexOf('.')) ? 'd' : 'f';
|
606
|
+
}
|
607
|
+
|
608
|
+
function createPartial(node, context) {
|
609
|
+
var prefix = "<" + (context.prefix || "");
|
610
|
+
var sym = prefix + node.n + serialNo++;
|
611
|
+
context.partials[sym] = {name: node.n, partials: {}};
|
612
|
+
context.code += 't.b(t.rp("' + esc(sym) + '",c,p,"' + (node.indent || '') + '"));';
|
613
|
+
return sym;
|
614
|
+
}
|
615
|
+
|
616
|
+
Hogan.codegen = {
|
617
|
+
'#': function(node, context) {
|
618
|
+
context.code += 'if(t.s(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),' +
|
619
|
+
'c,p,0,' + node.i + ',' + node.end + ',"' + node.otag + " " + node.ctag + '")){' +
|
620
|
+
't.rs(c,p,' + 'function(c,p,t){';
|
621
|
+
Hogan.walk(node.nodes, context);
|
622
|
+
context.code += '});c.pop();}';
|
623
|
+
},
|
624
|
+
|
625
|
+
'^': function(node, context) {
|
626
|
+
context.code += 'if(!t.s(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,1),c,p,1,0,0,"")){';
|
627
|
+
Hogan.walk(node.nodes, context);
|
628
|
+
context.code += '};';
|
629
|
+
},
|
630
|
+
|
631
|
+
'>': createPartial,
|
632
|
+
'<': function(node, context) {
|
633
|
+
var ctx = {partials: {}, code: '', subs: {}, inPartial: true};
|
634
|
+
Hogan.walk(node.nodes, ctx);
|
635
|
+
var template = context.partials[createPartial(node, context)];
|
636
|
+
template.subs = ctx.subs;
|
637
|
+
template.partials = ctx.partials;
|
638
|
+
},
|
639
|
+
|
640
|
+
'$': function(node, context) {
|
641
|
+
var ctx = {subs: {}, code: '', partials: context.partials, prefix: node.n};
|
642
|
+
Hogan.walk(node.nodes, ctx);
|
643
|
+
context.subs[node.n] = ctx.code;
|
644
|
+
if (!context.inPartial) {
|
645
|
+
context.code += 't.sub("' + esc(node.n) + '",c,p,i);';
|
646
|
+
}
|
647
|
+
},
|
648
|
+
|
649
|
+
'\n': function(node, context) {
|
650
|
+
context.code += write('"\\n"' + (node.last ? '' : ' + i'));
|
651
|
+
},
|
652
|
+
|
653
|
+
'_v': function(node, context) {
|
654
|
+
context.code += 't.b(t.v(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));';
|
655
|
+
},
|
656
|
+
|
657
|
+
'_t': function(node, context) {
|
658
|
+
context.code += write('"' + esc(node.text) + '"');
|
659
|
+
},
|
660
|
+
|
661
|
+
'{': tripleStache,
|
662
|
+
|
663
|
+
'&': tripleStache
|
664
|
+
}
|
665
|
+
|
666
|
+
function tripleStache(node, context) {
|
667
|
+
context.code += 't.b(t.t(t.' + chooseMethod(node.n) + '("' + esc(node.n) + '",c,p,0)));';
|
668
|
+
}
|
669
|
+
|
670
|
+
function write(s) {
|
671
|
+
return 't.b(' + s + ');';
|
672
|
+
}
|
673
|
+
|
674
|
+
Hogan.walk = function (nodelist, context) {
|
675
|
+
var func;
|
676
|
+
for (var i = 0, l = nodelist.length; i < l; i++) {
|
677
|
+
func = Hogan.codegen[nodelist[i].tag];
|
678
|
+
func && func(nodelist[i], context);
|
679
|
+
}
|
680
|
+
return context;
|
681
|
+
}
|
682
|
+
|
683
|
+
Hogan.parse = function(tokens, text, options) {
|
684
|
+
options = options || {};
|
685
|
+
return buildTree(tokens, '', [], options.sectionTags || []);
|
686
|
+
},
|
687
|
+
|
688
|
+
Hogan.cache = {};
|
689
|
+
|
690
|
+
Hogan.cacheKey = function(text, options) {
|
691
|
+
return [text, !!options.asString, !!options.disableLambda].join('||');
|
692
|
+
},
|
693
|
+
|
694
|
+
Hogan.compile = function(text, options) {
|
695
|
+
options = options || {};
|
696
|
+
var key = Hogan.cacheKey(text, options);
|
697
|
+
var template = this.cache[key];
|
698
|
+
|
699
|
+
if (template) {
|
700
|
+
return template;
|
701
|
+
}
|
702
|
+
|
703
|
+
template = this.generate(this.parse(this.scan(text, options.delimiters), text, options), text, options);
|
704
|
+
return this.cache[key] = template;
|
705
|
+
};
|
706
|
+
})(typeof exports !== 'undefined' ? exports : Hogan);
|
707
|
+
|