├── .github └── workflows │ └── build.yml ├── .gitignore ├── CHANGELOG.md ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── angular-rails-templates.gemspec ├── gemfiles ├── rails_5.0.gemfile ├── rails_5.0_sprockets4.gemfile ├── rails_5.2.gemfile ├── rails_5.2_sprockets4.gemfile ├── rails_6.0.gemfile ├── rails_6.1.gemfile ├── rails_7.0.gemfile ├── rails_7.1.gemfile ├── rails_7.2.gemfile ├── rails_8.0.gemfile ├── rails_head.gemfile └── rails_head_sprockets4.gemfile ├── lib ├── angular-rails-templates.rb └── angular-rails-templates │ ├── compact_javascript_escape.rb │ ├── engine.rb │ ├── javascript_template.js.erb │ ├── processor.rb │ ├── transformer.rb │ └── version.rb ├── test ├── compact_javascript_escape_test.rb ├── dummy │ ├── README.rdoc │ ├── Rakefile │ ├── app │ │ ├── assets │ │ │ ├── config │ │ │ │ └── manifest.js │ │ │ ├── images │ │ │ │ └── .keep │ │ │ ├── javascripts │ │ │ │ ├── application.js │ │ │ │ ├── erb_template.html.erb │ │ │ │ ├── haml_template.html.haml │ │ │ │ ├── ignored_namespace │ │ │ │ │ └── hello-world.html │ │ │ │ ├── markdown.html.md │ │ │ │ ├── plain.html │ │ │ │ ├── slim_template.html.slim │ │ │ │ ├── subfolder │ │ │ │ │ ├── haml_template.html.haml │ │ │ │ │ ├── slim_template.html.slim │ │ │ │ │ └── template.html │ │ │ │ └── subfolder2 │ │ │ │ │ └── template.html │ │ │ └── templates │ │ │ │ ├── sub │ │ │ │ ├── sub.html.str │ │ │ │ └── sub2.html.haml │ │ │ │ └── test.html │ │ ├── controllers │ │ │ ├── application_controller.rb │ │ │ ├── concerns │ │ │ │ └── .keep │ │ │ └── welcome_controller.rb │ │ ├── helpers │ │ │ └── application_helper.rb │ │ ├── mailers │ │ │ └── .keep │ │ ├── models │ │ │ ├── .keep │ │ │ └── concerns │ │ │ │ └── .keep │ │ └── views │ │ │ ├── layouts │ │ │ └── application.html.erb │ │ │ └── welcome │ │ │ └── index.html.haml │ ├── bin │ │ ├── bundle │ │ ├── rails │ │ └── rake │ ├── config.ru │ ├── config │ │ ├── application.rb │ │ ├── boot.rb │ │ ├── database.yml │ │ ├── environment.rb │ │ ├── environments │ │ │ ├── development.rb │ │ │ ├── production.rb │ │ │ └── test.rb │ │ ├── initializers │ │ │ ├── backtrace_silencers.rb │ │ │ ├── filter_parameter_logging.rb │ │ │ ├── inflections.rb │ │ │ ├── mime_types.rb │ │ │ ├── secret_token.rb │ │ │ ├── session_store.rb │ │ │ └── wrap_parameters.rb │ │ ├── locales │ │ │ └── en.yml │ │ └── routes.rb │ ├── lib │ │ └── assets │ │ │ └── .keep │ ├── log │ │ └── .keep │ └── public │ │ ├── 404.html │ │ ├── 422.html │ │ ├── 500.html │ │ ├── angular.min.js │ │ └── favicon.ico ├── integration │ ├── static_assets_integration_test.rb │ └── user_assets_integration_test.rb ├── precompile_test.rb └── test_helper.rb └── vendor └── assets └── javascripts └── angular-rails-templates.js.erb /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | # This workflow uses actions that are not certified by GitHub. 2 | # They are provided by a third-party and are governed by 3 | # separate terms of service, privacy policy, and support 4 | # documentation. 5 | # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake 6 | # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby 7 | 8 | name: build 9 | 10 | on: [push, pull_request] 11 | 12 | jobs: 13 | test: 14 | runs-on: ubuntu-20.04 15 | strategy: 16 | fail-fast: false 17 | matrix: 18 | ruby: 19 | - '3.1' 20 | - '3.2' 21 | - '3.3' 22 | gemfile: 23 | - rails_6.0 24 | - rails_6.1 25 | - rails_7.0 26 | - rails_7.1 27 | - rails_7.2 28 | - rails_8.0 29 | exclude: 30 | - gemfile: rails_8.0 31 | ruby: '3.1' 32 | include: 33 | - gemfile: rails_5.0 34 | ruby: '2.6' 35 | - gemfile: rails_5.0_sprockets4 36 | ruby: '2.6' 37 | - gemfile: rails_5.2 38 | ruby: '2.7' 39 | - gemfile: rails_5.2_sprockets4 40 | ruby: '2.7' 41 | 42 | env: 43 | BUNDLE_GEMFILE: ${{ github.workspace }}/gemfiles/${{ matrix.gemfile }}.gemfile 44 | AWS_REGION: us-east1 45 | steps: 46 | - uses: actions/checkout@v2 47 | - uses: ruby/setup-ruby@v1 48 | with: 49 | ruby-version: ${{ matrix.ruby }} 50 | bundler-cache: true 51 | - run: bundle exec rake test 52 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | test/dummy/tmp/* 3 | test/dummy/log/* 4 | test/dummy/public/assets/* 5 | *.lock 6 | .DS_Store 7 | vendor/ruby 8 | .bundle 9 | coverage 10 | .ruby-version 11 | /.idea 12 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Changelog 2 | 3 | ### [Unreleased] 4 | 5 | ### 1.3.1 6 | 7 | - Fix broken tests due to missing Logger (#174) (Eric Helms) 8 | - Rely on the digest class defined by Rails (#173) (Eric Helms) 9 | 10 | ### 1.3.0 11 | 12 | - Support Rails 8 (#172) (Eric Pugh) 13 | 14 | ### 1.2.2 15 | 16 | - Support Rails 7.2 (#170) (Mansoor Khan) 17 | 18 | ### 1.2.1 19 | 20 | - Support Rails 7.1 (#169) (Mathieu Jobin) 21 | 22 | ### 1.2.0 23 | 24 | - Support Rails 7 25 | 26 | ### 1.1.0 27 | 28 | - Support Rails 6 29 | - Use global Rails namespace [merqlove, #148] 30 | 31 | ### 1.0.2 32 | 33 | - Silence deprecation warning on sprockets 3.7 [kressh, #145] 34 | 35 | ### 1.0.1 36 | 37 | - Better support for Rails 5 and Sprockets 4 [merqlove/sandrew, #142] 38 | 39 | ### 1.0.0 40 | 41 | - Add support for Rails 5.0 [pitr, #131] 42 | 43 | ### 1.0.0.beta2 44 | 45 | - Loading tilt gem before using 46 | - Configurable extension `.html` [speranskydanil, #99] 47 | - Default inside_paths is a relative path [redterror, #108] 48 | - Do not process files outside inside_paths path [keenahn, #113] 49 | 50 | ### 1.0.0.beta1 51 | 52 | - Add support for Rails 4.2 [superchris/pitr, #126] 53 | - Remove support for Rails 4.1 and less 54 | 55 | ### 0.2.0 56 | 57 | - Add config.angular_templates.inside_paths [sars, #90] 58 | 59 | ### 0.1.5 60 | 61 | - Lock Sprocket support to version 2 [davetron5000, #96] 62 | 63 | ### 0.1.4 64 | 65 | - Run when `initialize_on_precompile = false` [squirly, #84] 66 | 67 | ### 0.1.3 68 | 69 | - Add array support to config.angular_templates.ignore_prefix [AaronV, #54] 70 | - Compatibility with slim-rails 2.1.5 [blackxored, #57] 71 | 72 | ### 0.1.2 73 | 74 | - Automatic Sprockets Cache busting (+ tilt warning silence) [whitehat101, #48] 75 | 76 | ### 0.1.1 77 | 78 | - Add vendor folder to gemspec [whitehat101, #41] 79 | - Add Tilt as dependency [pitr, #43] 80 | 81 | ### 0.1.0 82 | 83 | - **BREAKING** Bring back a separate JS file for module declaration [whitehat101, #35] 84 | - Fix Rails 4 support [brianewing, #39] 85 | - Add Tilt support [whitehat101, #38] 86 | - Add Template Chaining e.g. `example.html.haml.erb` [whitehat101, #38] 87 | - Add HtmlCompressor [whitehat101, #38] 88 | 89 | ### 0.0.7 90 | 91 | - Add support for HAML and SLIM templates [oivoodoo, #26] 92 | 93 | ### 0.0.6 94 | 95 | - Fix for Rails 4 [pitr, #20] 96 | 97 | ### 0.0.5 (yanked) 98 | 99 | - Support Rails 3.2+ (in addition to Rails 4) [pitr, #14] 100 | 101 | ### 0.0.4 102 | 103 | - Deprecate need for angular-rails-templates.js (pitr, #9) 104 | - Add ignore_prefix (pitr, #7) 105 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rails", "~> 6.0" 4 | gem "haml" 5 | gem "slim-rails" 6 | gem "kramdown" 7 | 8 | gem 'coveralls', require: false 9 | 10 | gemspec 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013 Damien MATHIEU 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Angular Rails Templates 2 | 3 | [![Gem Version](https://badge.fury.io/rb/angular-rails-templates.png)](http://badge.fury.io/rb/angular-rails-templates) 4 | [![Coverage Status](https://coveralls.io/repos/github/pitr/angular-rails-templates/badge.svg?branch=master)](https://coveralls.io/github/pitr/angular-rails-templates?branch=master) 5 | [![Code Climate](https://codeclimate.com/github/pitr/angular-rails-templates/badges/gpa.svg)](https://codeclimate.com/github/pitr/angular-rails-templates) 6 | [![Issue Stats](http://issuestats.com/github/pitr/angular-rails-templates/badge/pr)](http://issuestats.com/github/pitr/angular-rails-templates) 7 | [![Issue Stats](http://issuestats.com/github/pitr/angular-rails-templates/badge/issue)](http://issuestats.com/github/pitr/angular-rails-templates) 8 | [![Stories in Ready](https://badge.waffle.io/pitr/angular-rails-templates.png?label=ready&title=Ready)](https://waffle.io/pitr/angular-rails-templates) 9 | 10 | Adds your HTML templates into Angular's `$templateCache` using Rails asset pipeline. 11 | 12 | **IMPORTANT**: for Rails 4.2+ use version 1.0+ of this gem. For Rails 3 - 4.1 use version 0.x 13 | 14 | Branch | Build Status 15 | ------------|--------- 16 | master | [![Build Status](https://github.com/pitr/angular-rails-templates/workflows/build/badge.svg)](https://github.com/pitr/angular-rails-templates) 17 | 0-x-stable | [![Build Status](https://travis-ci.org/pitr/angular-rails-templates.png?branch=0-x-stable)](https://travis-ci.org/pitr/angular-rails-templates) 18 | 19 | It removes the need for AJAX calls to retrieve the templates (or for you to manually set them into the DOM). 20 | 21 | ## Usage 22 | 23 | ### 1. Add the Gem 24 | 25 | In Gemfile 26 | 27 | ```ruby 28 | gem 'angular-rails-templates' 29 | ``` 30 | 31 | ### 2. Include Templates in Rails Asset Pipeline 32 | 33 | Then, in your `application.js` file, require `angular-rails-templates` and your templates: 34 | 35 | ```javascript 36 | //= require angularjs 37 | // ... 38 | //= require angular-rails-templates 39 | // 40 | // Templates in app/assets/javascript/templates 41 | //= require_tree ./templates 42 | // OR 43 | // Templates in app/assets/templates (but see step 5) 44 | //= require_tree ../templates 45 | ``` 46 | 47 | Make sure to `require angular-rails-templates` **before** you require your templates. 48 | 49 | Name your templates like you would name any other Rails view. **The `.html` part is required.** If it is not present your views will not be added to angular's template cache. 50 | 51 | ``` 52 | foo.html 53 | foo.html.erb 54 | foo.html.haml 55 | foo.html.slim 56 | ``` 57 | 58 | Angular Rails Templates will try to load support for the following markups if their gems are present: 59 | 60 | | Extension | Required gem | 61 | |---------- |----------------------------------------------------------| 62 | | .erb | - | 63 | | .str | - | 64 | | .haml | haml | 65 | | .slim | slim | 66 | | .md | liquid, rdiscount, redcarpet, bluecloth, kramdown, maruku | 67 | 68 | See [Advanced](#advanced-configuration) if you would like to use other markup languages. 69 | 70 | ### 3. Add a Dependency in your Angular Application Module 71 | 72 | Your Angular module needs to depend on the `templates` module. (configurable, see [Advanced Configuration](#configuration-option-module_name)) 73 | 74 | ```javascript 75 | angular.module('myApplication', ['templates']); 76 | ``` 77 | 78 | ### 4. Use your Templates 79 | 80 | No matter what the source file extension is, your template's url will be `#{base_name}.html` 81 | 82 | For example: 83 | ```ruby 84 | main.html => main.html 85 | widget.html.haml => widget.html 86 | modals/confirm.html.slim => modals/confirm.html 87 | modals/dialog.html.slim.erb.str => modals/dialog.html # don't do this 88 | ``` 89 | 90 | The templates can then be accessed via `templateUrl` as expected: 91 | 92 | ```javascript 93 | // Template: app/assets/templates/yourTemplate.html.haml 94 | { 95 | templateUrl: 'yourTemplate.html' 96 | } 97 | ``` 98 | 99 | Or anything else that uses `$templateCache` or `$templateRequest` 100 | 101 | ```html 102 |
103 | ``` 104 | 105 | ### 5. Avoid name collisions 106 | 107 | If you have `app/assets/javascript/user.js` and `app/assets/templates/user.html`, the former one will actually hide the latter. This is due to how Rails asset pipeline sees asset files, both are served under `/assets/user.js`. Please use namespacing to combat this issue. 108 | 109 | ## Advanced Configuration 110 | 111 | Angular Rails Templates has some configuration options that can be set inside `config/application.rb` 112 | 113 | Here are their default values: 114 | ```ruby 115 | # config/application.rb 116 | config.angular_templates.module_name = 'templates' 117 | config.angular_templates.ignore_prefix = %w(templates/) 118 | config.angular_templates.inside_paths = ['app/assets'] 119 | config.angular_templates.markups = %w(erb str haml slim md) 120 | config.angular_templates.extension = 'html' 121 | ``` 122 | 123 | ### Configuration Option: `module_name` 124 | 125 | This configures the module name that your templates will be placed into. 126 | It is used to generate javascript like: 127 | 128 | ```javascipt 129 | angular.module("<%= module_name %>")... 130 | ``` 131 | 132 | Although it is not recommended, you can set `module_name` to the name of your main application module and remove `require angular-rails-templates` from your javascript manifest to have your templates directly injected into your app. 133 | 134 | ### Configuration Option: `ignore_prefix` 135 | 136 | *If you place your templates in `app/assets/templates` this option is mostly useless.* 137 | 138 | `ignore_prefix` will be stripped from the beginning of the `templateUrl` it reports to angularjs. 139 | 140 | Since the default ignore_prefix is [`templates/`], any templates placed under `app/assets/javascripts/templates` will automatically have short names. If your templates are not in this location, you will need to use the full path to the template. 141 | 142 | You can set `config.angular_templates.ignore_prefix` to change the default ignore prefix. Default is [`templates/`]. 143 | 144 | 145 | ``` javascript 146 | // Templates in: app/assets/javascripts/templates (default) 147 | // ignore_prefix: templates/ (default) 148 | { 149 | templateUrl: 'yourTemplate.html' 150 | } 151 | // This won't work: 152 | { 153 | templateUrl: 'templates/yourTemplate.html' 154 | } 155 | ``` 156 | 157 | ``` javascript 158 | // Templates in: app/assets/javascripts/my_app/templates (custom) 159 | // ignore_prefix: templates/ (default) 160 | { 161 | templateUrl: 'my_app/templates/yourTemplate.html' 162 | } 163 | 164 | // ignore_prefix: my_app/templates/ (custom) 165 | { 166 | templateUrl: 'yourTemplate.html' 167 | } 168 | ``` 169 | 170 | 171 | ### Configuration Option: `inside_paths` 172 | 173 | Templates only from paths matched by `inside_paths` will be used. By default anything under app/assets can be templates. This option is useful if you are using this gem inside an engine. Also useful if you DON'T want some files to be processed by this gem (see issue #88) 174 | 175 | 176 | ### Configuration Option: `markups` 177 | 178 | Any markup that Tilt supports can be used, but you may need to add a gem to your Gemfile. See [Tilt](https://github.com/rtomayko/tilt) for a list of the supported markups and required libraries. 179 | 180 | ```ruby 181 | # Gemfile 182 | gem "asciidoctor" 183 | gem "radius" 184 | gem "creole" 185 | gem "tilt-handlebars" 186 | 187 | # config/application.rb 188 | config.angular_templates.markups.push 'asciidoc', 'radius', 'wiki', 'hbs' 189 | ``` 190 | If you would like to use a non-standard extension or you would like to use a custom template, you just need to tell Tilt about it. 191 | 192 | ```ruby 193 | # config/initializers/angular_rails_templates.rb 194 | Tilt.register Tilt::HamlTemplate, 'nghaml' 195 | 196 | # config/application.rb 197 | config.angular_templates.markups.push 'nghaml' 198 | ``` 199 | Note: You would still need to use `foo`**`.html`**`.nghaml` 200 | 201 | ### Configuration Option: `extension` 202 | 203 | By default this gem looks only at templates with `.html` suffix, eg. `foo.html` or `foo.html.haml`. This extension allows you to change that to another extension 204 | 205 | ## License 206 | 207 | MIT License. Copyright 2017 pitr 208 | 209 | ## Authors & contributors 210 | 211 | * Damien Mathieu <42@dmathieu.com> 212 | * pitr 213 | * Jeremy Ebler 214 | * Chris Nelson 215 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | begin 2 | require 'bundler/setup' 3 | rescue LoadError 4 | puts 'You must `gem install bundler` and `bundle install` to run rake tasks' 5 | end 6 | 7 | APP_RAKEFILE = File.expand_path("../test/dummy/Rakefile", __FILE__) 8 | load 'rails/tasks/engine.rake' 9 | 10 | Bundler::GemHelper.install_tasks 11 | 12 | require 'rake/testtask' 13 | 14 | Rake::TestTask.new(:test) do |t| 15 | t.libs << 'lib' 16 | t.libs << 'test' 17 | t.pattern = 'test/**/*_test.rb' 18 | t.verbose = false 19 | end 20 | 21 | 22 | task default: :test 23 | -------------------------------------------------------------------------------- /angular-rails-templates.gemspec: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | $:.push File.expand_path("../lib", __FILE__) 3 | require "angular-rails-templates/version" 4 | 5 | Gem::Specification.new do |s| 6 | s.name = "angular-rails-templates" 7 | s.version = AngularRailsTemplates::VERSION 8 | s.platform = Gem::Platform::RUBY 9 | s.authors = ["Damien Mathieu", 'pitr', 'whitehat101'] 10 | s.email = ["pitr.vern@gmail.com"] 11 | s.homepage = "https://github.com/pitr/angular-rails-templates" 12 | s.summary = "Use your angular templates with rails' asset pipeline" 13 | 14 | s.files = %w(README.md LICENSE) + Dir["lib/**/*", "vendor/**/*"] 15 | s.license = 'MIT' 16 | 17 | s.require_paths = ["lib"] 18 | 19 | s.add_dependency "railties", ">= 5.0", "< 8.1" 20 | s.add_dependency "sprockets", ">= 3.0", '< 5' 21 | s.add_dependency "sprockets-rails" 22 | s.add_dependency "tilt" 23 | 24 | # There is a deprecation warning indicating the build will fail with Minitest 6 25 | s.add_development_dependency "minitest", '< 6' 26 | s.add_development_dependency "capybara" 27 | s.add_development_dependency "uglifier" 28 | end 29 | -------------------------------------------------------------------------------- /gemfiles/rails_5.0.gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rails", ">= 5.0.0.beta2", "< 5.1" 4 | gem "slim-rails" 5 | gem "haml" 6 | gem "kramdown" 7 | 8 | gem 'coveralls', require: false 9 | 10 | gemspec :path => ".././" 11 | -------------------------------------------------------------------------------- /gemfiles/rails_5.0_sprockets4.gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rails", ">= 5.0.0.beta2", "< 5.1" 4 | gem "sprockets", "~> 4.0.0.beta2" 5 | gem "slim-rails" 6 | gem "haml" 7 | gem "kramdown" 8 | 9 | gem 'coveralls', require: false 10 | 11 | gemspec :path => ".././" 12 | -------------------------------------------------------------------------------- /gemfiles/rails_5.2.gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rails", "~> 5.2.7" 4 | gem "slim-rails" 5 | gem "haml" 6 | gem "kramdown" 7 | 8 | gem 'coveralls', require: false 9 | 10 | gemspec :path => ".././" 11 | -------------------------------------------------------------------------------- /gemfiles/rails_5.2_sprockets4.gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rails", "~> 5.2.7" 4 | gem "sprockets", "~> 4.0.0.beta2" 5 | gem "slim-rails" 6 | gem "haml" 7 | gem "kramdown" 8 | 9 | gem 'coveralls', require: false 10 | 11 | gemspec :path => ".././" 12 | -------------------------------------------------------------------------------- /gemfiles/rails_6.0.gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rails", "~> 6.0.4" 4 | gem "slim-rails" 5 | gem "haml" 6 | gem "kramdown" 7 | 8 | gem 'coveralls', require: false 9 | 10 | gemspec :path => ".././" 11 | -------------------------------------------------------------------------------- /gemfiles/rails_6.1.gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rails", ">= 6.1.0", "< 7" 4 | gem "slim-rails" 5 | gem "haml" 6 | gem "kramdown" 7 | 8 | gem 'coveralls', require: false 9 | 10 | gemspec :path => ".././" 11 | -------------------------------------------------------------------------------- /gemfiles/rails_7.0.gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rails", "~> 7.0.2" 4 | gem "slim-rails" 5 | gem "haml" 6 | gem "kramdown" 7 | 8 | gem 'coveralls', require: false 9 | 10 | gemspec :path => ".././" 11 | -------------------------------------------------------------------------------- /gemfiles/rails_7.1.gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rails", "~> 7.1.1" 4 | gem "slim-rails" 5 | gem "haml" 6 | gem "kramdown" 7 | 8 | gem 'coveralls', require: false 9 | 10 | gemspec :path => ".././" 11 | -------------------------------------------------------------------------------- /gemfiles/rails_7.2.gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rails", "~> 7.2.0" 4 | gem "slim-rails" 5 | gem "haml" 6 | gem "kramdown" 7 | 8 | gem 'coveralls', require: false 9 | 10 | gemspec :path => ".././" 11 | -------------------------------------------------------------------------------- /gemfiles/rails_8.0.gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rails", "~> 8.0.0" 4 | gem "slim-rails" 5 | gem "haml" 6 | gem "kramdown" 7 | 8 | gem 'coveralls', require: false 9 | 10 | gemspec :path => ".././" 11 | -------------------------------------------------------------------------------- /gemfiles/rails_head.gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rails", github: "rails/rails" 4 | gem "slim-rails" 5 | gem "haml" 6 | gem "kramdown" 7 | 8 | gem 'coveralls', require: false 9 | 10 | gemspec :path => ".././" 11 | -------------------------------------------------------------------------------- /gemfiles/rails_head_sprockets4.gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | gem "rails", github: "rails/rails" 4 | gem "sprockets", "~> 4.0.0.beta2" 5 | gem "slim-rails" 6 | gem "haml" 7 | gem "kramdown" 8 | 9 | gem 'coveralls', require: false 10 | 11 | gemspec :path => ".././" 12 | -------------------------------------------------------------------------------- /lib/angular-rails-templates.rb: -------------------------------------------------------------------------------- 1 | require 'tilt' 2 | 3 | require 'angular-rails-templates/compact_javascript_escape' 4 | require 'angular-rails-templates/processor' 5 | require 'angular-rails-templates/transformer' 6 | require 'angular-rails-templates/engine' 7 | 8 | module AngularRailsTemplates 9 | autoload :VERSION, 'angular-rails-templates/version' 10 | end 11 | -------------------------------------------------------------------------------- /lib/angular-rails-templates/compact_javascript_escape.rb: -------------------------------------------------------------------------------- 1 | module AngularRailsTemplates 2 | module CompactJavaScriptEscape 3 | # inspired by Rails' action_view/helpers/javascript_helper.rb 4 | JS_ESCAPE_MAP = { 5 | '\\' => '\\\\', 6 | "\r\n" => '\n', 7 | "\n" => '\n', 8 | "\r" => '\n', 9 | '"' => '\\"', 10 | "'" => "\\'" 11 | } 12 | 13 | # We want to deliver the shortist valid javascript escaped string 14 | # Count the number of " vs ' 15 | # If more ', escape " 16 | # If more ", escape ' 17 | # If equal, prefer to escape " 18 | 19 | def escape_javascript(raw) 20 | if raw 21 | quote = raw.count(%{'}) >= raw.count(%{"}) ? %{"} : %{'} 22 | escaped = raw.gsub(/(\\|\r\n|[\n\r#{quote}])/u) {|match| JS_ESCAPE_MAP[match] } 23 | "#{quote}#{escaped}#{quote}" 24 | else 25 | '""' 26 | end 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/angular-rails-templates/engine.rb: -------------------------------------------------------------------------------- 1 | module AngularRailsTemplates 2 | class Engine < ::Rails::Engine 3 | config.angular_templates = ActiveSupport::OrderedOptions.new 4 | config.angular_templates.module_name = 'templates' 5 | config.angular_templates.ignore_prefix = ['templates/'] 6 | config.angular_templates.inside_paths = ['app/assets'] 7 | config.angular_templates.markups = [] 8 | config.angular_templates.extension = 'html' 9 | 10 | config.before_configuration do |app| 11 | # try loading common markups 12 | %w(erb haml liquid md radius slim str textile wiki). 13 | each do |ext| 14 | begin 15 | silence_warnings do 16 | config.angular_templates.markups << ext if Tilt[ext] 17 | end 18 | rescue LoadError 19 | # They don't have the required library required. Oh well. 20 | end 21 | end 22 | end 23 | 24 | 25 | initializer 'angular-rails-templates', group: :all do |app| 26 | if defined?(Sprockets::Railtie) 27 | config.assets.configure do |env| 28 | env.register_mime_type 'text/ng-html', extensions: [".#{app.config.angular_templates.extension}"] 29 | env.register_transformer 'text/ng-html', 'application/javascript', AngularRailsTemplates::Processor 30 | 31 | # These engines render markup as HTML 32 | app.config.angular_templates.markups.each do |ext| 33 | AngularRailsTemplates::Transformer.register(env, ext) 34 | end 35 | end 36 | end 37 | 38 | # Sprockets Cache Busting 39 | # If ART's version or settings change, expire and recompile all assets 40 | hash_digest = if defined?(ActiveSupport::Digest) 41 | app.config.active_support.hash_digest_class || ActiveSupport::Digest.hash_digest_class 42 | else 43 | Digest::MD5 44 | end 45 | 46 | app.config.assets.version = [ 47 | app.config.assets.version, 48 | 'ART', 49 | hash_digest.hexdigest("#{VERSION}-#{app.config.angular_templates}") 50 | ].join '-' 51 | end 52 | 53 | 54 | config.after_initialize do |app| 55 | # Ensure ignore_prefix can be passed as a String or Array 56 | if app.config.angular_templates.ignore_prefix.is_a? String 57 | app.config.angular_templates.ignore_prefix = Array(app.config.angular_templates.ignore_prefix) 58 | end 59 | end 60 | end 61 | end 62 | -------------------------------------------------------------------------------- /lib/angular-rails-templates/javascript_template.js.erb: -------------------------------------------------------------------------------- 1 | // Angular Rails Template 2 | // source: <%= source_file %> 3 | 4 | angular.module("<%= angular_module %>").run(["$templateCache", function($templateCache) { 5 | $templateCache.put("<%= angular_template_name %>", <%= html %>) 6 | }]); 7 | 8 | -------------------------------------------------------------------------------- /lib/angular-rails-templates/processor.rb: -------------------------------------------------------------------------------- 1 | require 'angular-rails-templates/compact_javascript_escape' 2 | 3 | module AngularRailsTemplates 4 | class Processor 5 | 6 | AngularJsTemplateWrapper = ::Tilt::ERBTemplate.new "#{File.dirname __FILE__}/javascript_template.js.erb" 7 | 8 | include CompactJavaScriptEscape 9 | 10 | def self.instance 11 | @instance ||= new 12 | end 13 | 14 | def self.call(input) 15 | instance.call(input) 16 | end 17 | 18 | def self.cache_key 19 | instance.cache_key 20 | end 21 | 22 | attr_reader :cache_key 23 | 24 | def config 25 | Rails.configuration.angular_templates 26 | end 27 | 28 | def initialize(options = {}) 29 | @cache_key = [self.class.name, VERSION, options].freeze 30 | end 31 | 32 | def template_name(name) 33 | path = name.sub(/^#{config.ignore_prefix.join('|')}/, '') 34 | "#{path}.#{config.extension}" 35 | end 36 | 37 | def call(input) 38 | file_path = Pathname.new(input[:filename]).relative_path_from(Rails.root).to_s 39 | 40 | unless config.inside_paths.any? { |folder| file_path.match(folder.to_s) } 41 | return input[:data] 42 | end 43 | 44 | locals = {} 45 | locals[:angular_template_name] = template_name(input[:name]) 46 | locals[:angular_module] = config.module_name 47 | locals[:source_file] = "#{input[:filename]}".sub(/^#{Rails.root}\//,'') 48 | 49 | locals[:html] = escape_javascript(input[:data].chomp) 50 | 51 | AngularJsTemplateWrapper.render(nil, locals) 52 | end 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /lib/angular-rails-templates/transformer.rb: -------------------------------------------------------------------------------- 1 | module AngularRailsTemplates 2 | # 3 | # Temporary wrapper, old one is deprecated by Sprockets 4. 4 | # 5 | class Transformer 6 | attr_reader :cache_key 7 | 8 | def initialize(options = {}) 9 | @cache_key = [self.class.name, VERSION, options].freeze 10 | end 11 | 12 | def add_template(ext, template) 13 | templates[ext] ||= template 14 | end 15 | 16 | def call(input) 17 | filename = input[:filename] 18 | ext = File.extname(filename).split('.').last 19 | 20 | return input unless has?(ext) 21 | 22 | data = input[:data] 23 | context = input[:environment].context_class.new(input) 24 | 25 | process(filename, data, context, ext) 26 | end 27 | 28 | private 29 | 30 | def templates 31 | @templates ||= Hash.new 32 | end 33 | 34 | def has?(ext) 35 | templates.has_key?(ext) 36 | end 37 | 38 | def process(filename, data, context, ext) 39 | data = templates[ext].new(filename) { data }.render(context, {}) 40 | context.metadata.merge(data: data.to_str) 41 | end 42 | 43 | class << self 44 | def instance 45 | @instance ||= new 46 | end 47 | 48 | def cache_key 49 | instance.cache_key 50 | end 51 | 52 | def call(input) 53 | instance.call(input) 54 | end 55 | 56 | def config 57 | Rails.configuration.angular_templates 58 | end 59 | 60 | def register(env, ext) 61 | if ::Sprockets::VERSION.to_i < 4 # Legacy Sprockets 62 | args = [".#{ext}", ::Tilt[ext]] 63 | if ::Sprockets::VERSION.to_i == 3 64 | args << { mime_type: "text/ng-#{ext}", silence_deprecation: true } 65 | end 66 | env.register_engine(*args) 67 | else 68 | instance.add_template(ext, ::Tilt[ext]) 69 | 70 | env.register_mime_type "text/ng-#{ext}", extensions: [".#{config.extension}.#{ext}"] 71 | env.register_transformer "text/ng-#{ext}", 'text/ng-html', AngularRailsTemplates::Transformer 72 | end 73 | end 74 | end 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /lib/angular-rails-templates/version.rb: -------------------------------------------------------------------------------- 1 | module AngularRailsTemplates 2 | VERSION = '1.3.1' 3 | end 4 | -------------------------------------------------------------------------------- /test/compact_javascript_escape_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | require 'angular-rails-templates/compact_javascript_escape' 3 | 4 | describe AngularRailsTemplates::CompactJavaScriptEscape do 5 | let(:instance) do 6 | Class.new { include AngularRailsTemplates::CompactJavaScriptEscape }.new 7 | end 8 | 9 | it "responds to :escape_javascript" do 10 | instance.must_respond_to :escape_javascript 11 | end 12 | 13 | describe "#escape_javascript" do 14 | 15 | it "returns strings" do 16 | instance.escape_javascript("hello").must_be_kind_of String 17 | instance.escape_javascript(""). must_be_kind_of String 18 | instance.escape_javascript(nil). must_be_kind_of String 19 | end 20 | 21 | it "uses double quotes to wrap strings without quotes" do 22 | str = instance.escape_javascript("hello") 23 | str[0].must_equal str[-1] 24 | str[0].must_equal %(") 25 | end 26 | 27 | it "uses double quotes to wrap strings with many single quotes" do 28 | str = instance.escape_javascript(%{'hello'}) 29 | str[0].must_equal str[-1] 30 | str[0].must_equal %(") 31 | end 32 | 33 | it "uses single quotes to wrap strings with many double quotes" do 34 | str = instance.escape_javascript(%{"hello"}) 35 | str[0].must_equal str[-1] 36 | str[0].must_equal %(') 37 | end 38 | 39 | it "escapes single quotes when double quotes are used to wrap strings" do 40 | str = instance.escape_javascript(%{'h'e"l'lo'}) 41 | str[0].must_equal %(") 42 | str.must_match %{\\"} 43 | str.wont_match %{\\'} 44 | end 45 | 46 | it "escapes double quotes when single quotes are used to wrap strings" do 47 | str = instance.escape_javascript(%{"h"e'l"lo"}) 48 | str[0].must_equal %(') 49 | str.must_match %{\\'} 50 | str.wont_match %{\\"} 51 | end 52 | 53 | it "escapes backslashes" do 54 | str = instance.escape_javascript(%{a\\z}) 55 | str.must_match %{a\\\\z} 56 | end 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /test/dummy/README.rdoc: -------------------------------------------------------------------------------- 1 | == README 2 | 3 | This README would normally document whatever steps are necessary to get the 4 | application up and running. 5 | 6 | Things you may want to cover: 7 | 8 | * Ruby version 9 | 10 | * System dependencies 11 | 12 | * Configuration 13 | 14 | * Database creation 15 | 16 | * Database initialization 17 | 18 | * How to run the test suite 19 | 20 | * Services (job queues, cache servers, search engines, etc.) 21 | 22 | * Deployment instructions 23 | 24 | * ... 25 | 26 | 27 | Please feel free to use a different markup language if you do not plan to run 28 | rake doc:app. 29 | -------------------------------------------------------------------------------- /test/dummy/Rakefile: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env rake 2 | # Add your own tasks in files placed in lib/tasks ending in .rake, 3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 4 | 5 | require File.expand_path('../config/application', __FILE__) 6 | 7 | Dummy::Application.load_tasks 8 | -------------------------------------------------------------------------------- /test/dummy/app/assets/config/manifest.js: -------------------------------------------------------------------------------- 1 | // app/assets/config/manifest.js 2 | 3 | //= link angular-rails-templates 4 | //= link application.js 5 | -------------------------------------------------------------------------------- /test/dummy/app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pitr/angular-rails-templates/70db6af0f9ee760ffee44b9f814c179f23cfbf61/test/dummy/app/assets/images/.keep -------------------------------------------------------------------------------- /test/dummy/app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | //= require angular-rails-templates 2 | //= require_tree . 3 | //= require_tree ../templates 4 | -------------------------------------------------------------------------------- /test/dummy/app/assets/javascripts/erb_template.html.erb: -------------------------------------------------------------------------------- 1 |
<%= 6*7 %>
2 | -------------------------------------------------------------------------------- /test/dummy/app/assets/javascripts/haml_template.html.haml: -------------------------------------------------------------------------------- 1 | %h1 html-haml 2 | -------------------------------------------------------------------------------- /test/dummy/app/assets/javascripts/ignored_namespace/hello-world.html: -------------------------------------------------------------------------------- 1 |
Subfolder
2 | -------------------------------------------------------------------------------- /test/dummy/app/assets/javascripts/markdown.html.md: -------------------------------------------------------------------------------- 1 | ### Markdown! 2 | -------------------------------------------------------------------------------- /test/dummy/app/assets/javascripts/plain.html: -------------------------------------------------------------------------------- 1 |
plain text
2 | -------------------------------------------------------------------------------- /test/dummy/app/assets/javascripts/slim_template.html.slim: -------------------------------------------------------------------------------- 1 | h1 slim template 2 | -------------------------------------------------------------------------------- /test/dummy/app/assets/javascripts/subfolder/haml_template.html.haml: -------------------------------------------------------------------------------- 1 | .hello-world Subfolder-HAML 2 | -------------------------------------------------------------------------------- /test/dummy/app/assets/javascripts/subfolder/slim_template.html.slim: -------------------------------------------------------------------------------- 1 | .hello-world Subfolder-SLIM 2 | -------------------------------------------------------------------------------- /test/dummy/app/assets/javascripts/subfolder/template.html: -------------------------------------------------------------------------------- 1 |
Subfolder
2 | -------------------------------------------------------------------------------- /test/dummy/app/assets/javascripts/subfolder2/template.html: -------------------------------------------------------------------------------- 1 |
Subfolder2
2 | -------------------------------------------------------------------------------- /test/dummy/app/assets/templates/sub/sub.html.str: -------------------------------------------------------------------------------- 1 | outside-javascript #{6*7} 2 | -------------------------------------------------------------------------------- /test/dummy/app/assets/templates/sub/sub2.html.haml: -------------------------------------------------------------------------------- 1 | %p P.S. I love you 2 | -------------------------------------------------------------------------------- /test/dummy/app/assets/templates/test.html: -------------------------------------------------------------------------------- 1 | outside-javascript 2 | -------------------------------------------------------------------------------- /test/dummy/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | end 6 | -------------------------------------------------------------------------------- /test/dummy/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pitr/angular-rails-templates/70db6af0f9ee760ffee44b9f814c179f23cfbf61/test/dummy/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /test/dummy/app/controllers/welcome_controller.rb: -------------------------------------------------------------------------------- 1 | class WelcomeController < ApplicationController 2 | 3 | def index; end 4 | end 5 | -------------------------------------------------------------------------------- /test/dummy/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /test/dummy/app/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pitr/angular-rails-templates/70db6af0f9ee760ffee44b9f814c179f23cfbf61/test/dummy/app/mailers/.keep -------------------------------------------------------------------------------- /test/dummy/app/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pitr/angular-rails-templates/70db6af0f9ee760ffee44b9f814c179f23cfbf61/test/dummy/app/models/.keep -------------------------------------------------------------------------------- /test/dummy/app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pitr/angular-rails-templates/70db6af0f9ee760ffee44b9f814c179f23cfbf61/test/dummy/app/models/concerns/.keep -------------------------------------------------------------------------------- /test/dummy/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dummy 5 | <%= javascript_include_tag "/angular.min.js" %> 6 | <%= javascript_include_tag "application" %> 7 | 13 | 14 | 15 |

Angular

16 | {{version}} 17 |

Template Cache

18 | {{info}} 19 |
20 | <%= yield %> 21 |
22 | 23 | 24 | -------------------------------------------------------------------------------- /test/dummy/app/views/welcome/index.html.haml: -------------------------------------------------------------------------------- 1 | %h1 Welcome 2 | -------------------------------------------------------------------------------- /test/dummy/bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /test/dummy/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../../config/application', __FILE__) 3 | require_relative '../config/boot' 4 | require 'rails/commands' 5 | -------------------------------------------------------------------------------- /test/dummy/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative '../config/boot' 3 | require 'rake' 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /test/dummy/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /test/dummy/config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require "action_controller/railtie" 4 | require "rails/test_unit/railtie" 5 | require "sprockets/rails" 6 | require "sprockets/railtie" 7 | 8 | Bundler.require(*Rails.groups) 9 | 10 | module Dummy 11 | class Application < Rails::Application 12 | # Settings in config/environments/* take precedence over those specified here. 13 | # Application configuration should go into files in config/initializers 14 | # -- all .rb files in that directory are automatically loaded. 15 | 16 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 17 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 18 | # config.time_zone = 'Central Time (US & Canada)' 19 | 20 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 21 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 22 | # config.i18n.default_locale = :de 23 | 24 | config.assets.enabled = true 25 | config.assets.version = "#{Time.now}" # always expire cached assets on Rails Boot 26 | 27 | config.assets.precompile = ["manifest.js"] unless ::Sprockets::VERSION.to_i < 4 28 | config.angular_templates.ignore_prefix = 'ignored_namespace/' 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /test/dummy/config/boot.rb: -------------------------------------------------------------------------------- 1 | # Set up gems listed in the Gemfile. 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__) 3 | 4 | require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) 5 | require "logger" # Fix concurrent-ruby removing logger dependency which Rails itself does not have 6 | $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__) 7 | -------------------------------------------------------------------------------- /test/dummy/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | development: 7 | adapter: sqlite3 8 | database: db/development.sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | # Warning: The database defined as "test" will be erased and 13 | # re-generated from your development database when you run "rake". 14 | # Do not set this db to the same as development or production. 15 | test: 16 | adapter: sqlite3 17 | database: db/test.sqlite3 18 | pool: 5 19 | timeout: 5000 20 | 21 | production: 22 | adapter: sqlite3 23 | database: db/production.sqlite3 24 | pool: 5 25 | timeout: 5000 26 | -------------------------------------------------------------------------------- /test/dummy/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | Dummy::Application.initialize! 6 | -------------------------------------------------------------------------------- /test/dummy/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports and disable caching. 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send. 17 | #config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger. 20 | config.active_support.deprecation = :log 21 | 22 | # Raise an error on page load if there are pending migrations 23 | #config.active_record.migration_error = :page_load 24 | 25 | # Debug mode disables concatenation and preprocessing of assets. 26 | # This option may cause significant delays in view rendering with a large 27 | # number of complex assets. 28 | config.assets.debug = true 29 | end 30 | -------------------------------------------------------------------------------- /test/dummy/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both thread web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application 18 | # Add `rack-cache` to your Gemfile before enabling this. 19 | # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid. 20 | # config.action_dispatch.rack_cache = true 21 | 22 | # Disable Rails's static asset server (Apache or nginx will already do this). 23 | config.serve_static_files = false 24 | 25 | # Compress JavaScripts and CSS. 26 | config.assets.js_compressor = :uglifier 27 | # config.assets.css_compressor = :sass 28 | 29 | # Do not fallback to assets pipeline if a precompiled asset is missed. 30 | config.assets.compile = false 31 | 32 | # Generate digests for assets URLs. 33 | config.assets.digest = false 34 | 35 | # Specifies the header that your server uses for sending files. 36 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache 37 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx 38 | 39 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 40 | # config.force_ssl = true 41 | 42 | # Set to :debug to see everything in the log. 43 | config.log_level = :info 44 | 45 | # Prepend all log lines with the following tags. 46 | # config.log_tags = [ :subdomain, :uuid ] 47 | 48 | # Use a different logger for distributed setups. 49 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 50 | 51 | # Use a different cache store in production. 52 | # config.cache_store = :mem_cache_store 53 | 54 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 55 | # config.action_controller.asset_host = "http://assets.example.com" 56 | 57 | # Precompile additional assets. 58 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 59 | # config.assets.precompile += %w( search.js ) 60 | 61 | # Ignore bad email addresses and do not raise email delivery errors. 62 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 63 | # config.action_mailer.raise_delivery_errors = false 64 | 65 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 66 | # the I18n.default_locale when a translation can not be found). 67 | config.i18n.fallbacks = true 68 | 69 | # Send deprecation notices to registered listeners. 70 | config.active_support.deprecation = :notify 71 | 72 | # Disable automatic flushing of the log to improve performance. 73 | # config.autoflush_log = false 74 | 75 | # Use default logging formatter so that PID and timestamp are not suppressed. 76 | config.log_formatter = ::Logger::Formatter.new 77 | end 78 | -------------------------------------------------------------------------------- /test/dummy/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Dummy::Application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Show full error reports and disable caching. 16 | config.consider_all_requests_local = true 17 | config.action_controller.perform_caching = false 18 | 19 | # Raise exceptions instead of rendering exception templates. 20 | config.action_dispatch.show_exceptions = false 21 | 22 | # Disable request forgery protection in test environment. 23 | config.action_controller.allow_forgery_protection = false 24 | 25 | # Tell Action Mailer not to deliver emails to the real world. 26 | # The :test delivery method accumulates sent emails in the 27 | # ActionMailer::Base.deliveries array. 28 | #config.action_mailer.delivery_method = :test 29 | 30 | # Print deprecation notices to the stderr. 31 | config.active_support.deprecation = :stderr 32 | end 33 | -------------------------------------------------------------------------------- /test/dummy/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /test/dummy/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /test/dummy/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /test/dummy/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | # Mime::Type.register_alias "text/html", :iphone 6 | -------------------------------------------------------------------------------- /test/dummy/config/initializers/secret_token.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure your secret_key_base is kept private 11 | # if you're sharing your code publicly. 12 | Dummy::Application.config.secret_key_base = '0b3d1b507efa0e9e51c65df5367806e1850572049361654461f74ee96e2244fd42f458b12d73acb8d9dd534e3f492c5845d67da933978a6ceb354514f1afe8e7' 13 | Dummy::Application.config.secret_token = '0b3d1b507efa0e9e51c65df5367806e1850572049361654461f74ee96e2244fd42f458b12d73acb8d9dd534e3f492c5845d67da933978a6ceb354514f1afe8e7' 14 | -------------------------------------------------------------------------------- /test/dummy/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Dummy::Application.config.session_store :cookie_store, key: '_dummy_session' 4 | -------------------------------------------------------------------------------- /test/dummy/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /test/dummy/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /test/dummy/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | 3 | root to: 'welcome#index' 4 | end 5 | -------------------------------------------------------------------------------- /test/dummy/lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pitr/angular-rails-templates/70db6af0f9ee760ffee44b9f814c179f23cfbf61/test/dummy/lib/assets/.keep -------------------------------------------------------------------------------- /test/dummy/log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pitr/angular-rails-templates/70db6af0f9ee760ffee44b9f814c179f23cfbf61/test/dummy/log/.keep -------------------------------------------------------------------------------- /test/dummy/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 48 | 49 | 50 | 51 | 52 |
53 |

The page you were looking for doesn't exist.

54 |

You may have mistyped the address or the page may have moved.

55 |
56 |

If you are the application owner check the logs for more information.

57 | 58 | 59 | -------------------------------------------------------------------------------- /test/dummy/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 48 | 49 | 50 | 51 | 52 |
53 |

The change you wanted was rejected.

54 |

Maybe you tried to change something you didn't have access to.

55 |
56 |

If you are the application owner check the logs for more information.

57 | 58 | 59 | -------------------------------------------------------------------------------- /test/dummy/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 48 | 49 | 50 | 51 | 52 |
53 |

We're sorry, but something went wrong.

54 |
55 |

If you are the application owner check the logs for more information.

56 | 57 | 58 | -------------------------------------------------------------------------------- /test/dummy/public/angular.min.js: -------------------------------------------------------------------------------- 1 | /* 2 | AngularJS v1.2.16 3 | (c) 2010-2014 Google, Inc. http://angularjs.org 4 | License: MIT 5 | */ 6 | (function(O,U,s){'use strict';function t(b){return function(){var a=arguments[0],c,a="["+(b?b+":":"")+a+"] http://errors.angularjs.org/1.2.16/"+(b?b+"/":"")+a;for(c=1;c").append(b).html();try{return 3===b[0].nodeType?K(c):c.match(/^(<[^>]+>)/)[1].replace(/^<([\w\-]+)/, 15 | function(a,b){return"<"+K(b)})}catch(d){return K(c)}}function Xb(b){try{return decodeURIComponent(b)}catch(a){}}function Yb(b){var a={},c,d;q((b||"").split("&"),function(b){b&&(c=b.split("="),d=Xb(c[0]),B(d)&&(b=B(c[1])?Xb(c[1]):!0,a[d]?M(a[d])?a[d].push(b):a[d]=[a[d],b]:a[d]=b))});return a}function Zb(b){var a=[];q(b,function(b,d){M(b)?q(b,function(b){a.push(za(d,!0)+(!0===b?"":"="+za(b,!0)))}):a.push(za(d,!0)+(!0===b?"":"="+za(b,!0)))});return a.length?a.join("&"):""}function wb(b){return za(b, 16 | !0).replace(/%26/gi,"&").replace(/%3D/gi,"=").replace(/%2B/gi,"+")}function za(b,a){return encodeURIComponent(b).replace(/%40/gi,"@").replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,a?"%20":"+")}function Wc(b,a){function c(a){a&&d.push(a)}var d=[b],e,g,f=["ng:app","ng-app","x-ng-app","data-ng-app"],h=/\sng[:\-]app(:\s*([\w\d_]+);?)?\s/;q(f,function(a){f[a]=!0;c(U.getElementById(a));a=a.replace(":","\\:");b.querySelectorAll&&(q(b.querySelectorAll("."+a),c),q(b.querySelectorAll("."+ 17 | a+"\\:"),c),q(b.querySelectorAll("["+a+"]"),c))});q(d,function(a){if(!e){var b=h.exec(" "+a.className+" ");b?(e=a,g=(b[2]||"").replace(/\s+/g,",")):q(a.attributes,function(b){!e&&f[b.name]&&(e=a,g=b.value)})}});e&&a(e,g?[g]:[])}function $b(b,a){var c=function(){b=y(b);if(b.injector()){var c=b[0]===U?"document":ha(b);throw Pa("btstrpd",c);}a=a||[];a.unshift(["$provide",function(a){a.value("$rootElement",b)}]);a.unshift("ng");c=ac(a);c.invoke(["$rootScope","$rootElement","$compile","$injector","$animate", 18 | function(a,b,c,d,e){a.$apply(function(){b.data("$injector",d);c(b)(a)})}]);return c},d=/^NG_DEFER_BOOTSTRAP!/;if(O&&!d.test(O.name))return c();O.name=O.name.replace(d,"");Ea.resumeBootstrap=function(b){q(b,function(b){a.push(b)});c()}}function fb(b,a){a=a||"_";return b.replace(Xc,function(b,d){return(d?a:"")+b.toLowerCase()})}function xb(b,a,c){if(!b)throw Pa("areq",a||"?",c||"required");return b}function Ra(b,a,c){c&&M(b)&&(b=b[b.length-1]);xb(P(b),a,"not a function, got "+(b&&"object"==typeof b? 19 | b.constructor.name||"Object":typeof b));return b}function Aa(b,a){if("hasOwnProperty"===b)throw Pa("badname",a);}function bc(b,a,c){if(!a)return b;a=a.split(".");for(var d,e=b,g=a.length,f=0;f "+e[1]+a.replace(le,"<$1>")+e[2]; 26 | d.removeChild(d.firstChild);for(a=e[0];a--;)d=d.lastChild;a=0;for(e=d.childNodes.length;a=S?(c.preventDefault=null,c.stopPropagation=null,c.isDefaultPrevented=null):(delete c.preventDefault,delete c.stopPropagation,delete c.isDefaultPrevented)};c.elem=b;return c}function Ia(b){var a=typeof b,c;"object"==a&&null!==b?"function"==typeof(c=b.$$hashKey)?c=b.$$hashKey():c===s&&(c=b.$$hashKey=bb()):c=b;return a+":"+c}function Va(b){q(b,this.put,this)}function oc(b){var a,c;"function"==typeof b?(a=b.$inject)||(a=[],b.length&&(c=b.toString().replace(oe, 32 | ""),c=c.match(pe),q(c[1].split(qe),function(b){b.replace(re,function(b,c,d){a.push(d)})})),b.$inject=a):M(b)?(c=b.length-1,Ra(b[c],"fn"),a=b.slice(0,c)):Ra(b,"fn",!0);return a}function ac(b){function a(a){return function(b,c){if(X(b))q(b,Rb(a));else return a(b,c)}}function c(a,b){Aa(a,"service");if(P(b)||M(b))b=n.instantiate(b);if(!b.$get)throw Wa("pget",a);return m[a+h]=b}function d(a,b){return c(a,{$get:b})}function e(a){var b=[],c,d,g,h;q(a,function(a){if(!k.get(a)){k.put(a,!0);try{if(w(a))for(c= 33 | Sa(a),b=b.concat(e(c.requires)).concat(c._runBlocks),d=c._invokeQueue,g=0,h=d.length;g 4096 bytes)!"));else{if(l.cookie!==da)for(da=l.cookie,d=da.split("; "),Q={},g=0;gk&&this.remove(p.key),b},get:function(a){if(k").parent()[0])});var g=L(a,b,a,c,d,e);ma(a,"ng-scope");return function(b,c,d){xb(b,"scope");var e=c?Ja.clone.call(a):a;q(d,function(a,b){e.data("$"+b+"Controller",a)});d=0;for(var f=e.length;darguments.length&& 51 | (b=a,a=s);D&&(c=lb);return p(a,b,c)}var I,x,v,A,R,H,lb={},da;I=c===g?d:Ub(d,new Hb(y(g),d.$attr));x=I.$$element;if(Q){var T=/^\s*([@=&])(\??)\s*(\w*)\s*$/;f=y(g);H=e.$new(!0);ia&&ia===Q.$$originalDirective?f.data("$isolateScope",H):f.data("$isolateScopeNoTemplate",H);ma(f,"ng-isolate-scope");q(Q.scope,function(a,c){var d=a.match(T)||[],g=d[3]||c,f="?"==d[2],d=d[1],l,m,n,p;H.$$isolateBindings[c]=d+g;switch(d){case "@":I.$observe(g,function(a){H[c]=a});I.$$observers[g].$$scope=e;I[g]&&(H[c]=b(I[g])(e)); 52 | break;case "=":if(f&&!I[g])break;m=r(I[g]);p=m.literal?xa:function(a,b){return a===b};n=m.assign||function(){l=H[c]=m(e);throw ja("nonassign",I[g],Q.name);};l=H[c]=m(e);H.$watch(function(){var a=m(e);p(a,H[c])||(p(a,l)?n(e,a=H[c]):H[c]=a);return l=a},null,m.literal);break;case "&":m=r(I[g]);H[c]=function(a){return m(e,a)};break;default:throw ja("iscp",Q.name,c,a);}})}da=p&&u;L&&q(L,function(a){var b={$scope:a===Q||a.$$isolateScope?H:e,$element:x,$attrs:I,$transclude:da},c;R=a.controller;"@"==R&&(R= 53 | I[a.name]);c=z(R,b);lb[a.name]=c;D||x.data("$"+a.name+"Controller",c);a.controllerAs&&(b.$scope[a.controllerAs]=c)});f=0;for(v=l.length;fG.priority)break;if(V=G.scope)A=A||G,G.templateUrl||(K("new/isolated scope",Q,G,Z),X(V)&&(Q=G));t=G.name;!G.templateUrl&&G.controller&&(V=G.controller,L=L||{},K("'"+t+"' controller",L[t],G,Z),L[t]=G);if(V=G.transclude)E=!0,G.$$tlb||(K("transclusion",T,G,Z),T=G),"element"==V?(D=!0,v=G.priority, 55 | V=H(c,ra,W),Z=d.$$element=y(U.createComment(" "+t+": "+d[t]+" ")),c=Z[0],mb(g,y(ya.call(V,0)),c),Xa=x(V,e,v,f&&f.name,{nonTlbTranscludeDirective:T})):(V=y(Eb(c)).contents(),Z.empty(),Xa=x(V,e));if(G.template)if(K("template",ia,G,Z),ia=G,V=P(G.template)?G.template(Z,d):G.template,V=Y(V),G.replace){f=G;V=Cb.test(V)?y(V):[];c=V[0];if(1!=V.length||1!==c.nodeType)throw ja("tplrt",t,"");mb(g,Z,c);S={$attr:{}};V=da(c,[],S);var $=a.splice(N+1,a.length-(N+1));Q&&pc(V);a=a.concat(V).concat($);B(d,S);S=a.length}else Z.html(V); 56 | if(G.templateUrl)K("template",ia,G,Z),ia=G,G.replace&&(f=G),J=C(a.splice(N,a.length-N),Z,d,g,Xa,l,n,{controllerDirectives:L,newIsolateScopeDirective:Q,templateDirective:ia,nonTlbTranscludeDirective:T}),S=a.length;else if(G.compile)try{O=G.compile(Z,d,Xa),P(O)?u(null,O,ra,W):O&&u(O.pre,O.post,ra,W)}catch(aa){m(aa,ha(Z))}G.terminal&&(J.terminal=!0,v=Math.max(v,G.priority))}J.scope=A&&!0===A.scope;J.transclude=E&&Xa;p.hasElementTranscludeDirective=D;return J}function pc(a){for(var b=0,c=a.length;bp.priority)&&-1!=p.restrict.indexOf(g)&&(n&&(p=Tb(p,{$$start:n,$$end:r})),b.push(p),k=p)}catch(F){m(F)}}return k}function B(a,b){var c=b.$attr,d=a.$attr,e=a.$$element;q(a,function(d,e){"$"!=e.charAt(0)&&(b[e]&&(d+=("style"===e?";":" ")+b[e]),a.$set(e,d,!0,c[e]))});q(b,function(b,g){"class"==g?(ma(e,b),a["class"]=(a["class"]? 58 | a["class"]+" ":"")+b):"style"==g?(e.attr("style",e.attr("style")+";"+b),a.style=(a.style?a.style+";":"")+b):"$"==g.charAt(0)||a.hasOwnProperty(g)||(a[g]=b,d[g]=c[g])})}function C(a,b,c,d,e,g,f,l){var k=[],m,r,z=b[0],u=a.shift(),F=D({},u,{templateUrl:null,transclude:null,replace:null,$$originalDirective:u}),x=P(u.templateUrl)?u.templateUrl(b,c):u.templateUrl;b.empty();n.get(v.getTrustedResourceUrl(x),{cache:p}).success(function(n){var p,J;n=Y(n);if(u.replace){n=Cb.test(n)?y(n):[];p=n[0];if(1!=n.length|| 59 | 1!==p.nodeType)throw ja("tplrt",u.name,x);n={$attr:{}};mb(d,b,p);var v=da(p,[],n);X(u.scope)&&pc(v);a=v.concat(a);B(c,n)}else p=z,b.html(n);a.unshift(F);m=ia(a,p,c,e,b,u,g,f,l);q(d,function(a,c){a==p&&(d[c]=b[0])});for(r=L(b[0].childNodes,e);k.length;){n=k.shift();J=k.shift();var A=k.shift(),R=k.shift(),v=b[0];if(J!==z){var H=J.className;l.hasElementTranscludeDirective&&u.replace||(v=Eb(p));mb(A,y(J),v);ma(y(v),H)}J=m.transclude?Q(n,m.transclude):R;m(r,n,v,d,J)}k=null}).error(function(a,b,c,d){throw ja("tpload", 60 | d.url);});return function(a,b,c,d,e){k?(k.push(b),k.push(c),k.push(d),k.push(e)):m(r,b,c,d,e)}}function E(a,b){var c=b.priority-a.priority;return 0!==c?c:a.name!==b.name?a.namea.status? 69 | b:n.reject(b)}var d={method:"get",transformRequest:e.transformRequest,transformResponse:e.transformResponse},g=function(a){function b(a){var c;q(a,function(b,d){P(b)&&(c=b(),null!=c?a[d]=c:delete a[d])})}var c=e.headers,d=D({},a.headers),g,f,c=D({},c.common,c[K(a.method)]);b(c);b(d);a:for(g in c){a=K(g);for(f in d)if(K(f)===a)continue a;d[g]=c[g]}return d}(a);D(d,a);d.headers=g;d.method=Fa(d.method);(a=Ib(d.url)?b.cookies()[d.xsrfCookieName||e.xsrfCookieName]:s)&&(g[d.xsrfHeaderName||e.xsrfHeaderName]= 70 | a);var f=[function(a){g=a.headers;var b=uc(a.data,tc(g),a.transformRequest);E(a.data)&&q(g,function(a,b){"content-type"===K(b)&&delete g[b]});E(a.withCredentials)&&!E(e.withCredentials)&&(a.withCredentials=e.withCredentials);return z(a,b,g).then(c,c)},s],h=n.when(d);for(q(v,function(a){(a.request||a.requestError)&&f.unshift(a.request,a.requestError);(a.response||a.responseError)&&f.push(a.response,a.responseError)});f.length;){a=f.shift();var k=f.shift(),h=h.then(a,k)}h.success=function(a){h.then(function(b){a(b.data, 71 | b.status,b.headers,d)});return h};h.error=function(a){h.then(null,function(b){a(b.data,b.status,b.headers,d)});return h};return h}function z(b,c,g){function f(a,b,c,e){v&&(200<=a&&300>a?v.put(s,[a,b,sc(c),e]):v.remove(s));l(b,a,c,e);d.$$phase||d.$apply()}function l(a,c,d,e){c=Math.max(c,0);(200<=c&&300>c?p.resolve:p.reject)({data:a,status:c,headers:tc(d),config:b,statusText:e})}function k(){var a=db(r.pendingRequests,b);-1!==a&&r.pendingRequests.splice(a,1)}var p=n.defer(),z=p.promise,v,q,s=u(b.url, 72 | b.params);r.pendingRequests.push(b);z.then(k,k);(b.cache||e.cache)&&(!1!==b.cache&&"GET"==b.method)&&(v=X(b.cache)?b.cache:X(e.cache)?e.cache:F);if(v)if(q=v.get(s),B(q)){if(q.then)return q.then(k,k),q;M(q)?l(q[1],q[0],ba(q[2]),q[3]):l(q,200,{},"OK")}else v.put(s,z);E(q)&&a(b.method,s,c,f,g,b.timeout,b.withCredentials,b.responseType);return z}function u(a,b){if(!b)return a;var c=[];Sc(b,function(a,b){null===a||E(a)||(M(a)||(a=[a]),q(a,function(a){X(a)&&(a=qa(a));c.push(za(b)+"="+za(a))}))});0=S&&(!b.match(/^(get|post|head|put|delete|options)$/i)||!O.XMLHttpRequest))return new O.ActiveXObject("Microsoft.XMLHTTP");if(O.XMLHttpRequest)return new O.XMLHttpRequest;throw t("$httpBackend")("noxhr");}function Ud(){this.$get=["$browser","$window","$document",function(b,a,c){return ve(b,ue,b.defer,a.angular.callbacks,c[0])}]}function ve(b,a,c,d,e){function g(a,b){var c=e.createElement("script"),d=function(){c.onreadystatechange= 75 | c.onload=c.onerror=null;e.body.removeChild(c);b&&b()};c.type="text/javascript";c.src=a;S&&8>=S?c.onreadystatechange=function(){/loaded|complete/.test(c.readyState)&&d()}:c.onload=c.onerror=function(){d()};e.body.appendChild(c);return d}var f=-1;return function(e,l,k,m,n,p,r,z){function u(){v=f;A&&A();x&&x.abort()}function F(a,d,e,g,f){L&&c.cancel(L);A=x=null;0===d&&(d=e?200:"file"==sa(l).protocol?404:0);a(1223===d?204:d,e,g,f||"");b.$$completeOutstandingRequest(C)}var v;b.$$incOutstandingRequestCount(); 76 | l=l||b.url();if("jsonp"==K(e)){var J="_"+(d.counter++).toString(36);d[J]=function(a){d[J].data=a};var A=g(l.replace("JSON_CALLBACK","angular.callbacks."+J),function(){d[J].data?F(m,200,d[J].data):F(m,v||-2);d[J]=Ea.noop})}else{var x=a(e);x.open(e,l,!0);q(n,function(a,b){B(a)&&x.setRequestHeader(b,a)});x.onreadystatechange=function(){if(x&&4==x.readyState){var a=null,b=null;v!==f&&(a=x.getAllResponseHeaders(),b="response"in x?x.response:x.responseText);F(m,v||x.status,b,a,x.statusText||"")}};r&&(x.withCredentials= 77 | !0);if(z)try{x.responseType=z}catch(s){if("json"!==z)throw s;}x.send(k||null)}if(0=h&&(n.resolve(r),m(p.$$intervalId),delete e[p.$$intervalId]);z||b.$apply()},f);e[p.$$intervalId]=n;return p}var e={};d.cancel=function(a){return a&&a.$$intervalId in e?(e[a.$$intervalId].reject("canceled"),clearInterval(a.$$intervalId),delete e[a.$$intervalId], 80 | !0):!1};return d}]}function ad(){this.$get=function(){return{id:"en-us",NUMBER_FORMATS:{DECIMAL_SEP:".",GROUP_SEP:",",PATTERNS:[{minInt:1,minFrac:0,maxFrac:3,posPre:"",posSuf:"",negPre:"-",negSuf:"",gSize:3,lgSize:3},{minInt:1,minFrac:2,maxFrac:2,posPre:"\u00a4",posSuf:"",negPre:"(\u00a4",negSuf:")",gSize:3,lgSize:3}],CURRENCY_SYM:"$"},DATETIME_FORMATS:{MONTH:"January February March April May June July August September October November December".split(" "),SHORTMONTH:"Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec".split(" "), 81 | DAY:"Sunday Monday Tuesday Wednesday Thursday Friday Saturday".split(" "),SHORTDAY:"Sun Mon Tue Wed Thu Fri Sat".split(" "),AMPMS:["AM","PM"],medium:"MMM d, y h:mm:ss a","short":"M/d/yy h:mm a",fullDate:"EEEE, MMMM d, y",longDate:"MMMM d, y",mediumDate:"MMM d, y",shortDate:"M/d/yy",mediumTime:"h:mm:ss a",shortTime:"h:mm a"},pluralCat:function(b){return 1===b?"one":"other"}}}}function wc(b){b=b.split("/");for(var a=b.length;a--;)b[a]=wb(b[a]);return b.join("/")}function xc(b,a,c){b=sa(b,c);a.$$protocol= 82 | b.protocol;a.$$host=b.hostname;a.$$port=Y(b.port)||we[b.protocol]||null}function yc(b,a,c){var d="/"!==b.charAt(0);d&&(b="/"+b);b=sa(b,c);a.$$path=decodeURIComponent(d&&"/"===b.pathname.charAt(0)?b.pathname.substring(1):b.pathname);a.$$search=Yb(b.search);a.$$hash=decodeURIComponent(b.hash);a.$$path&&"/"!=a.$$path.charAt(0)&&(a.$$path="/"+a.$$path)}function oa(b,a){if(0===a.indexOf(b))return a.substr(b.length)}function Ya(b){var a=b.indexOf("#");return-1==a?b:b.substr(0,a)}function Jb(b){return b.substr(0, 83 | Ya(b).lastIndexOf("/")+1)}function zc(b,a){this.$$html5=!0;a=a||"";var c=Jb(b);xc(b,this,b);this.$$parse=function(a){var e=oa(c,a);if(!w(e))throw Kb("ipthprfx",a,c);yc(e,this,b);this.$$path||(this.$$path="/");this.$$compose()};this.$$compose=function(){var a=Zb(this.$$search),b=this.$$hash?"#"+wb(this.$$hash):"";this.$$url=wc(this.$$path)+(a?"?"+a:"")+b;this.$$absUrl=c+this.$$url.substr(1)};this.$$rewrite=function(d){var e;if((e=oa(b,d))!==s)return d=e,(e=oa(a,e))!==s?c+(oa("/",e)||e):b+d;if((e=oa(c, 84 | d))!==s)return c+e;if(c==d+"/")return c}}function Lb(b,a){var c=Jb(b);xc(b,this,b);this.$$parse=function(d){var e=oa(b,d)||oa(c,d),e="#"==e.charAt(0)?oa(a,e):this.$$html5?e:"";if(!w(e))throw Kb("ihshprfx",d,a);yc(e,this,b);d=this.$$path;var g=/^\/?.*?:(\/.*)/;0===e.indexOf(b)&&(e=e.replace(b,""));g.exec(e)||(d=(e=g.exec(d))?e[1]:d);this.$$path=d;this.$$compose()};this.$$compose=function(){var c=Zb(this.$$search),e=this.$$hash?"#"+wb(this.$$hash):"";this.$$url=wc(this.$$path)+(c?"?"+c:"")+e;this.$$absUrl= 85 | b+(this.$$url?a+this.$$url:"")};this.$$rewrite=function(a){if(Ya(b)==Ya(a))return a}}function Ac(b,a){this.$$html5=!0;Lb.apply(this,arguments);var c=Jb(b);this.$$rewrite=function(d){var e;if(b==Ya(d))return d;if(e=oa(c,d))return b+a+e;if(c===d+"/")return c}}function nb(b){return function(){return this[b]}}function Bc(b,a){return function(c){if(E(c))return this[b];this[b]=a(c);this.$$compose();return this}}function Vd(){var b="",a=!1;this.hashPrefix=function(a){return B(a)?(b=a,this):b};this.html5Mode= 86 | function(b){return B(b)?(a=b,this):a};this.$get=["$rootScope","$browser","$sniffer","$rootElement",function(c,d,e,g){function f(a){c.$broadcast("$locationChangeSuccess",h.absUrl(),a)}var h,l=d.baseHref(),k=d.url();a?(l=k.substring(0,k.indexOf("/",k.indexOf("//")+2))+(l||"/"),e=e.history?zc:Ac):(l=Ya(k),e=Lb);h=new e(l,"#"+b);h.$$parse(h.$$rewrite(k));g.on("click",function(a){if(!a.ctrlKey&&!a.metaKey&&2!=a.which){for(var b=y(a.target);"a"!==K(b[0].nodeName);)if(b[0]===g[0]||!(b=b.parent())[0])return; 87 | var e=b.prop("href");X(e)&&"[object SVGAnimatedString]"===e.toString()&&(e=sa(e.animVal).href);var f=h.$$rewrite(e);e&&(!b.attr("target")&&f&&!a.isDefaultPrevented())&&(a.preventDefault(),f!=d.url()&&(h.$$parse(f),c.$apply(),O.angular["ff-684208-preventDefault"]=!0))}});h.absUrl()!=k&&d.url(h.absUrl(),!0);d.onUrlChange(function(a){h.absUrl()!=a&&(c.$evalAsync(function(){var b=h.absUrl();h.$$parse(a);c.$broadcast("$locationChangeStart",a,b).defaultPrevented?(h.$$parse(b),d.url(b)):f(b)}),c.$$phase|| 88 | c.$digest())});var m=0;c.$watch(function(){var a=d.url(),b=h.$$replace;m&&a==h.absUrl()||(m++,c.$evalAsync(function(){c.$broadcast("$locationChangeStart",h.absUrl(),a).defaultPrevented?h.$$parse(a):(d.url(h.absUrl(),b),f(a))}));h.$$replace=!1;return m});return h}]}function Wd(){var b=!0,a=this;this.debugEnabled=function(a){return B(a)?(b=a,this):b};this.$get=["$window",function(c){function d(a){a instanceof Error&&(a.stack?a=a.message&&-1===a.stack.indexOf(a.message)?"Error: "+a.message+"\n"+a.stack: 89 | a.stack:a.sourceURL&&(a=a.message+"\n"+a.sourceURL+":"+a.line));return a}function e(a){var b=c.console||{},e=b[a]||b.log||C;a=!1;try{a=!!e.apply}catch(l){}return a?function(){var a=[];q(arguments,function(b){a.push(d(b))});return e.apply(b,a)}:function(a,b){e(a,null==b?"":b)}}return{log:e("log"),info:e("info"),warn:e("warn"),error:e("error"),debug:function(){var c=e("debug");return function(){b&&c.apply(a,arguments)}}()}}]}function fa(b,a){if("constructor"===b)throw Ba("isecfld",a);return b}function Za(b, 90 | a){if(b){if(b.constructor===b)throw Ba("isecfn",a);if(b.document&&b.location&&b.alert&&b.setInterval)throw Ba("isecwindow",a);if(b.children&&(b.nodeName||b.prop&&b.attr&&b.find))throw Ba("isecdom",a);}return b}function ob(b,a,c,d,e){e=e||{};a=a.split(".");for(var g,f=0;1e?Cc(d[0],d[1],d[2],d[3],d[4],c,a):function(b,g){var f=0,h;do h=Cc(d[f++],d[f++],d[f++],d[f++],d[f++],c,a)(b,g),g=s,b=h;while(fa)for(b in l++,e)e.hasOwnProperty(b)&&!d.hasOwnProperty(b)&&(q--,delete e[b])}else e!==d&&(e=d,l++);return l},function(){p?(p=!1,b(d,d,c)):b(d,f,c);if(h)if(X(d))if(ab(d)){f=Array(d.length);for(var a=0;as&&(y=4-s,Q[y]||(Q[y]=[]),H=P(d.exp)?"fn: "+(d.exp.name||d.exp.toString()):d.exp,H+="; newVal: "+qa(g)+"; oldVal: "+qa(f),Q[y].push(H));else if(d===c){x=!1;break a}}catch(w){p.$$phase= 107 | null,e(w)}if(!(h=L.$$childHead||L!==this&&L.$$nextSibling))for(;L!==this&&!(h=L.$$nextSibling);)L=L.$parent}while(L=h);if((x||k.length)&&!s--)throw p.$$phase=null,a("infdig",b,qa(Q));}while(x||k.length);for(p.$$phase=null;m.length;)try{m.shift()()}catch(T){e(T)}},$destroy:function(){if(!this.$$destroyed){var a=this.$parent;this.$broadcast("$destroy");this.$$destroyed=!0;this!==p&&(q(this.$$listenerCount,eb(null,m,this)),a.$$childHead==this&&(a.$$childHead=this.$$nextSibling),a.$$childTail==this&& 108 | (a.$$childTail=this.$$prevSibling),this.$$prevSibling&&(this.$$prevSibling.$$nextSibling=this.$$nextSibling),this.$$nextSibling&&(this.$$nextSibling.$$prevSibling=this.$$prevSibling),this.$parent=this.$$nextSibling=this.$$prevSibling=this.$$childHead=this.$$childTail=this.$root=null,this.$$listeners={},this.$$watchers=this.$$asyncQueue=this.$$postDigestQueue=[],this.$destroy=this.$digest=this.$apply=C,this.$on=this.$watch=function(){return C})}},$eval:function(a,b){return g(a)(this,b)},$evalAsync:function(a){p.$$phase|| 109 | p.$$asyncQueue.length||f.defer(function(){p.$$asyncQueue.length&&p.$digest()});this.$$asyncQueue.push({scope:this,expression:a})},$$postDigest:function(a){this.$$postDigestQueue.push(a)},$apply:function(a){try{return l("$apply"),this.$eval(a)}catch(b){e(b)}finally{p.$$phase=null;try{p.$digest()}catch(c){throw e(c),c;}}},$on:function(a,b){var c=this.$$listeners[a];c||(this.$$listeners[a]=c=[]);c.push(b);var d=this;do d.$$listenerCount[a]||(d.$$listenerCount[a]=0),d.$$listenerCount[a]++;while(d=d.$parent); 110 | var e=this;return function(){c[db(c,b)]=null;m(e,1,a)}},$emit:function(a,b){var c=[],d,g=this,f=!1,h={name:a,targetScope:g,stopPropagation:function(){f=!0},preventDefault:function(){h.defaultPrevented=!0},defaultPrevented:!1},l=[h].concat(ya.call(arguments,1)),k,m;do{d=g.$$listeners[a]||c;h.currentScope=g;k=0;for(m=d.length;kc.msieDocumentMode)throw ua("iequirks");var e=ba(ga);e.isEnabled=function(){return b};e.trustAs=d.trustAs;e.getTrusted=d.getTrusted;e.valueOf=d.valueOf;b||(e.trustAs=e.getTrusted=function(a,b){return b},e.valueOf=Da);e.parseAs=function(b,c){var d=a(c);return d.literal&&d.constant?d:function(a,c){return e.getTrusted(b, 117 | d(a,c))}};var g=e.parseAs,f=e.getTrusted,h=e.trustAs;q(ga,function(a,b){var c=K(b);e[Ta("parse_as_"+c)]=function(b){return g(a,b)};e[Ta("get_trusted_"+c)]=function(b){return f(a,b)};e[Ta("trust_as_"+c)]=function(b){return h(a,b)}});return e}]}function be(){this.$get=["$window","$document",function(b,a){var c={},d=Y((/android (\d+)/.exec(K((b.navigator||{}).userAgent))||[])[1]),e=/Boxee/i.test((b.navigator||{}).userAgent),g=a[0]||{},f=g.documentMode,h,l=/^(Moz|webkit|O|ms)(?=[A-Z])/,k=g.body&&g.body.style, 118 | m=!1,n=!1;if(k){for(var p in k)if(m=l.exec(p)){h=m[0];h=h.substr(0,1).toUpperCase()+h.substr(1);break}h||(h="WebkitOpacity"in k&&"webkit");m=!!("transition"in k||h+"Transition"in k);n=!!("animation"in k||h+"Animation"in k);!d||m&&n||(m=w(g.body.style.webkitTransition),n=w(g.body.style.webkitAnimation))}return{history:!(!b.history||!b.history.pushState||4>d||e),hashchange:"onhashchange"in b&&(!f||7b;b=Math.abs(b);var f=b+"",h="",l=[],k=!1;if(-1!==f.indexOf("e")){var m=f.match(/([\d\.]+)e(-?)(\d+)/);m&&"-"==m[2]&&m[3]>e+1?f="0":(h=f,k=!0)}if(k)0b)&&(h=b.toFixed(e)); 125 | else{f=(f.split(Nc)[1]||"").length;E(e)&&(e=Math.min(Math.max(a.minFrac,f),a.maxFrac));f=Math.pow(10,e);b=Math.round(b*f)/f;b=(""+b).split(Nc);f=b[0];b=b[1]||"";var m=0,n=a.lgSize,p=a.gSize;if(f.length>=n+p)for(m=f.length-n,k=0;kb&&(d="-",b=-b);for(b=""+b;b.length-c)e+=c;0===e&&-12==c&&(e=12);return Ob(e,a,d)}}function pb(b,a){return function(c,d){var e=c["get"+b](),g=Fa(a?"SHORT"+b:b);return d[g][e]}}function Jc(b){function a(a){var b;if(b=a.match(c)){a=new Date(0);var g=0,f=0,h=b[8]?a.setUTCFullYear:a.setFullYear,l=b[8]?a.setUTCHours:a.setHours;b[9]&&(g=Y(b[9]+b[10]),f=Y(b[9]+b[11])); 127 | h.call(a,Y(b[1]),Y(b[2])-1,Y(b[3]));g=Y(b[4]||0)-g;f=Y(b[5]||0)-f;h=Y(b[6]||0);b=Math.round(1E3*parseFloat("0."+(b[7]||0)));l.call(a,g,f,h,b)}return a}var c=/^(\d{4})-?(\d\d)-?(\d\d)(?:T(\d\d)(?::?(\d\d)(?::?(\d\d)(?:\.(\d+))?)?)?(Z|([+-])(\d\d):?(\d\d))?)?$/;return function(c,e){var g="",f=[],h,l;e=e||"mediumDate";e=b.DATETIME_FORMATS[e]||e;w(c)&&(c=Ge.test(c)?Y(c):a(c));vb(c)&&(c=new Date(c));if(!Na(c))return c;for(;e;)(l=He.exec(e))?(f=f.concat(ya.call(l,1)),e=f.pop()):(f.push(e),e=null);q(f,function(a){h= 128 | Ie[a];g+=h?h(c,b.DATETIME_FORMATS):a.replace(/(^'|'$)/g,"").replace(/''/g,"'")});return g}}function Ce(){return function(b){return qa(b,!0)}}function De(){return function(b,a){if(!M(b)&&!w(b))return b;a=Y(a);if(w(b))return a?0<=a?b.slice(0,a):b.slice(a,b.length):"";var c=[],d,e;a>b.length?a=b.length:a<-b.length&&(a=-b.length);0a||37<=a&&40>=a)||m()});if(e.hasEvent("paste"))a.on("paste cut",m)}a.on("change",l);d.$render=function(){a.val(d.$isEmpty(d.$viewValue)? 134 | "":d.$viewValue)};var n=c.ngPattern;n&&((e=n.match(/^\/(.*)\/([gim]*)$/))?(n=RegExp(e[1],e[2]),e=function(a){return pa(d,"pattern",d.$isEmpty(a)||n.test(a),a)}):e=function(c){var e=b.$eval(n);if(!e||!e.test)throw t("ngPattern")("noregexp",n,e,ha(a));return pa(d,"pattern",d.$isEmpty(c)||e.test(c),c)},d.$formatters.push(e),d.$parsers.push(e));if(c.ngMinlength){var p=Y(c.ngMinlength);e=function(a){return pa(d,"minlength",d.$isEmpty(a)||a.length>=p,a)};d.$parsers.push(e);d.$formatters.push(e)}if(c.ngMaxlength){var r= 135 | Y(c.ngMaxlength);e=function(a){return pa(d,"maxlength",d.$isEmpty(a)||a.length<=r,a)};d.$parsers.push(e);d.$formatters.push(e)}}function Pb(b,a){b="ngClass"+b;return["$animate",function(c){function d(a,b){var c=[],d=0;a:for(;dS?function(b){b=b.nodeName?b:b[0];return b.scopeName&&"HTML"!=b.scopeName?Fa(b.scopeName+":"+b.nodeName):b.nodeName}:function(b){return b.nodeName?b.nodeName:b[0].nodeName};var Xc=/[A-Z]/g,$c={full:"1.2.16",major:1,minor:2,dot:16,codeName:"badger-enumeration"},Ua=N.cache={},gb=N.expando="ng-"+(new Date).getTime(), 139 | me=1,Pc=O.document.addEventListener?function(b,a,c){b.addEventListener(a,c,!1)}:function(b,a,c){b.attachEvent("on"+a,c)},Fb=O.document.removeEventListener?function(b,a,c){b.removeEventListener(a,c,!1)}:function(b,a,c){b.detachEvent("on"+a,c)};N._data=function(b){return this.cache[b[this.expando]]||{}};var he=/([\:\-\_]+(.))/g,ie=/^moz([A-Z])/,Bb=t("jqLite"),je=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,Cb=/<|&#?\w+;/,ke=/<([\w:]+)/,le=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,ea= 140 | {option:[1,'"],thead:[1,"","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ea.optgroup=ea.option;ea.tbody=ea.tfoot=ea.colgroup=ea.caption=ea.thead;ea.th=ea.td;var Ja=N.prototype={ready:function(b){function a(){c||(c=!0,b())}var c=!1;"complete"===U.readyState?setTimeout(a):(this.on("DOMContentLoaded",a),N(O).on("load",a))},toString:function(){var b= 141 | [];q(this,function(a){b.push(""+a)});return"["+b.join(", ")+"]"},eq:function(b){return 0<=b?y(this[b]):y(this[this.length+b])},length:0,push:Ke,sort:[].sort,splice:[].splice},kb={};q("multiple selected checked disabled readOnly required open".split(" "),function(b){kb[K(b)]=b});var nc={};q("input select option textarea button form details".split(" "),function(b){nc[Fa(b)]=!0});q({data:jc,inheritedData:jb,scope:function(b){return y(b).data("$scope")||jb(b.parentNode||b,["$isolateScope","$scope"])}, 142 | isolateScope:function(b){return y(b).data("$isolateScope")||y(b).data("$isolateScopeNoTemplate")},controller:kc,injector:function(b){return jb(b,"$injector")},removeAttr:function(b,a){b.removeAttribute(a)},hasClass:Gb,css:function(b,a,c){a=Ta(a);if(B(c))b.style[a]=c;else{var d;8>=S&&(d=b.currentStyle&&b.currentStyle[a],""===d&&(d="auto"));d=d||b.style[a];8>=S&&(d=""===d?s:d);return d}},attr:function(b,a,c){var d=K(a);if(kb[d])if(B(c))c?(b[a]=!0,b.setAttribute(a,d)):(b[a]=!1,b.removeAttribute(d)); 143 | else return b[a]||(b.attributes.getNamedItem(a)||C).specified?d:s;else if(B(c))b.setAttribute(a,c);else if(b.getAttribute)return b=b.getAttribute(a,2),null===b?s:b},prop:function(b,a,c){if(B(c))b[a]=c;else return b[a]},text:function(){function b(b,d){var e=a[b.nodeType];if(E(d))return e?b[e]:"";b[e]=d}var a=[];9>S?(a[1]="innerText",a[3]="nodeValue"):a[1]=a[3]="textContent";b.$dv="";return b}(),val:function(b,a){if(E(a)){if("SELECT"===Ka(b)&&b.multiple){var c=[];q(b.options,function(a){a.selected&& 144 | c.push(a.value||a.text)});return 0===c.length?null:c}return b.value}b.value=a},html:function(b,a){if(E(a))return b.innerHTML;for(var c=0,d=b.childNodes;c":function(a,c,d,e){return d(a,c)>e(a,c)},"<=":function(a,c,d,e){return d(a,c)<=e(a,c)},">=":function(a,c,d,e){return d(a,c)>=e(a,c)},"&&":function(a,c,d,e){return d(a,c)&&e(a,c)},"||":function(a,c,d,e){return d(a,c)||e(a,c)},"&":function(a,c,d,e){return d(a,c)&e(a,c)},"|":function(a,c,d,e){return e(a,c)(a,c,d(a,c))},"!":function(a,c,d){return!d(a,c)}},Ne={n:"\n",f:"\f",r:"\r",t:"\t",v:"\v","'":"'",'"':'"'}, 156 | Nb=function(a){this.options=a};Nb.prototype={constructor:Nb,lex:function(a){this.text=a;this.index=0;this.ch=s;this.lastCh=":";this.tokens=[];var c;for(a=[];this.index=a},isWhitespace:function(a){return" "===a||"\r"===a||"\t"===a||"\n"===a||"\v"===a||"\u00a0"=== 159 | a},isIdent:function(a){return"a"<=a&&"z">=a||"A"<=a&&"Z">=a||"_"===a||"$"===a},isExpOperator:function(a){return"-"===a||"+"===a||this.isNumber(a)},throwError:function(a,c,d){d=d||this.index;c=B(c)?"s "+c+"-"+this.index+" ["+this.text.substring(c,d)+"]":" "+d;throw Ba("lexerr",a,c,this.text);},readNumber:function(){for(var a="",c=this.index;this.index","<=",">="))a=this.binaryFn(a,c.fn,this.relational());return a},additive:function(){for(var a=this.multiplicative(),c;c=this.expect("+","-");)a=this.binaryFn(a,c.fn,this.multiplicative());return a},multiplicative:function(){for(var a=this.unary(),c;c=this.expect("*","/","%");)a=this.binaryFn(a,c.fn,this.unary());return a},unary:function(){var a;return this.expect("+")?this.primary():(a=this.expect("-"))?this.binaryFn($a.ZERO,a.fn, 171 | this.unary()):(a=this.expect("!"))?this.unaryFn(a.fn,this.unary()):this.primary()},fieldAccess:function(a){var c=this,d=this.expect().text,e=Dc(d,this.options,this.text);return D(function(c,d,h){return e(h||a(c,d))},{assign:function(e,f,h){return ob(a(e,h),d,f,c.text,c.options)}})},objectIndex:function(a){var c=this,d=this.expression();this.consume("]");return D(function(e,g){var f=a(e,g),h=d(e,g),l;if(!f)return s;(f=Za(f[h],c.text))&&(f.then&&c.options.unwrapPromises)&&(l=f,"$$v"in f||(l.$$v=s,l.then(function(a){l.$$v= 172 | a})),f=f.$$v);return f},{assign:function(e,g,f){var h=d(e,f);return Za(a(e,f),c.text)[h]=g}})},functionCall:function(a,c){var d=[];if(")"!==this.peekToken().text){do d.push(this.expression());while(this.expect(","))}this.consume(")");var e=this;return function(g,f){for(var h=[],l=c?c(g,f):g,k=0;ka.getHours()?c.AMPMS[0]:c.AMPMS[1]},Z:function(a){a=-1*a.getTimezoneOffset();return a=(0<=a?"+":"")+(Ob(Math[0=S&&(c.href||c.name||c.$set("href",""),a.append(U.createComment("IE fix")));if(!c.href&&!c.xlinkHref&&!c.name)return function(a,c){var g="[object SVGAnimatedString]"===wa.call(c.prop("href"))?"xlink:href":"href";c.on("click",function(a){c.attr(g)||a.preventDefault()})}}}),zb={};q(kb,function(a,c){if("multiple"!=a){var d=na("ng-"+c);zb[d]=function(){return{priority:100,link:function(a,g,f){a.$watch(f[d],function(a){f.$set(c,!!a)})}}}}});q(["src", 177 | "srcset","href"],function(a){var c=na("ng-"+a);zb[c]=function(){return{priority:99,link:function(d,e,g){var f=a,h=a;"href"===a&&"[object SVGAnimatedString]"===wa.call(e.prop("href"))&&(h="xlinkHref",g.$attr[h]="xlink:href",f=null);g.$observe(c,function(a){a&&(g.$set(h,a),S&&f&&e.prop(f,g[h]))})}}}});var sb={$addControl:C,$removeControl:C,$setValidity:C,$setDirty:C,$setPristine:C};Oc.$inject=["$element","$attrs","$scope","$animate"];var Qc=function(a){return["$timeout",function(c){return{name:"form", 178 | restrict:a?"EAC":"E",controller:Oc,compile:function(){return{pre:function(a,e,g,f){if(!g.action){var h=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1};Pc(e[0],"submit",h);e.on("$destroy",function(){c(function(){Fb(e[0],"submit",h)},0,!1)})}var l=e.parent().controller("form"),k=g.name||g.ngForm;k&&ob(a,k,f,k);if(l)e.on("$destroy",function(){l.$removeControl(f);k&&ob(a,k,s,k);D(f,sb)})}}}}}]},dd=Qc(),qd=Qc(!0),Oe=/^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/, 179 | Pe=/^[a-z0-9!#$%&'*+/=?^_`{|}~.-]+@[a-z0-9-]+(\.[a-z0-9-]+)*$/i,Qe=/^\s*(\-|\+)?(\d+|(\d*(\.\d*)))\s*$/,Rc={text:ub,number:function(a,c,d,e,g,f){ub(a,c,d,e,g,f);e.$parsers.push(function(a){var c=e.$isEmpty(a);if(c||Qe.test(a))return e.$setValidity("number",!0),""===a?null:c?a:parseFloat(a);e.$setValidity("number",!1);return s});Je(e,"number",c);e.$formatters.push(function(a){return e.$isEmpty(a)?"":""+a});d.min&&(a=function(a){var c=parseFloat(d.min);return pa(e,"min",e.$isEmpty(a)||a>=c,a)},e.$parsers.push(a), 180 | e.$formatters.push(a));d.max&&(a=function(a){var c=parseFloat(d.max);return pa(e,"max",e.$isEmpty(a)||a<=c,a)},e.$parsers.push(a),e.$formatters.push(a));e.$formatters.push(function(a){return pa(e,"number",e.$isEmpty(a)||vb(a),a)})},url:function(a,c,d,e,g,f){ub(a,c,d,e,g,f);a=function(a){return pa(e,"url",e.$isEmpty(a)||Oe.test(a),a)};e.$formatters.push(a);e.$parsers.push(a)},email:function(a,c,d,e,g,f){ub(a,c,d,e,g,f);a=function(a){return pa(e,"email",e.$isEmpty(a)||Pe.test(a),a)};e.$formatters.push(a); 181 | e.$parsers.push(a)},radio:function(a,c,d,e){E(d.name)&&c.attr("name",bb());c.on("click",function(){c[0].checked&&a.$apply(function(){e.$setViewValue(d.value)})});e.$render=function(){c[0].checked=d.value==e.$viewValue};d.$observe("value",e.$render)},checkbox:function(a,c,d,e){var g=d.ngTrueValue,f=d.ngFalseValue;w(g)||(g=!0);w(f)||(f=!1);c.on("click",function(){a.$apply(function(){e.$setViewValue(c[0].checked)})});e.$render=function(){c[0].checked=e.$viewValue};e.$isEmpty=function(a){return a!==g}; 182 | e.$formatters.push(function(a){return a===g});e.$parsers.push(function(a){return a?g:f})},hidden:C,button:C,submit:C,reset:C,file:C},dc=["$browser","$sniffer",function(a,c){return{restrict:"E",require:"?ngModel",link:function(d,e,g,f){f&&(Rc[K(g.type)]||Rc.text)(d,e,g,f,c,a)}}}],rb="ng-valid",qb="ng-invalid",La="ng-pristine",tb="ng-dirty",Re=["$scope","$exceptionHandler","$attrs","$element","$parse","$animate",function(a,c,d,e,g,f){function h(a,c){c=c?"-"+fb(c,"-"):"";f.removeClass(e,(a?qb:rb)+c); 183 | f.addClass(e,(a?rb:qb)+c)}this.$modelValue=this.$viewValue=Number.NaN;this.$parsers=[];this.$formatters=[];this.$viewChangeListeners=[];this.$pristine=!0;this.$dirty=!1;this.$valid=!0;this.$invalid=!1;this.$name=d.name;var l=g(d.ngModel),k=l.assign;if(!k)throw t("ngModel")("nonassign",d.ngModel,ha(e));this.$render=C;this.$isEmpty=function(a){return E(a)||""===a||null===a||a!==a};var m=e.inheritedData("$formController")||sb,n=0,p=this.$error={};e.addClass(La);h(!0);this.$setValidity=function(a,c){p[a]!== 184 | !c&&(c?(p[a]&&n--,n||(h(!0),this.$valid=!0,this.$invalid=!1)):(h(!1),this.$invalid=!0,this.$valid=!1,n++),p[a]=!c,h(c,a),m.$setValidity(a,c,this))};this.$setPristine=function(){this.$dirty=!1;this.$pristine=!0;f.removeClass(e,tb);f.addClass(e,La)};this.$setViewValue=function(d){this.$viewValue=d;this.$pristine&&(this.$dirty=!0,this.$pristine=!1,f.removeClass(e,La),f.addClass(e,tb),m.$setDirty());q(this.$parsers,function(a){d=a(d)});this.$modelValue!==d&&(this.$modelValue=d,k(a,d),q(this.$viewChangeListeners, 185 | function(a){try{a()}catch(d){c(d)}}))};var r=this;a.$watch(function(){var c=l(a);if(r.$modelValue!==c){var d=r.$formatters,e=d.length;for(r.$modelValue=c;e--;)c=d[e](c);r.$viewValue!==c&&(r.$viewValue=c,r.$render())}return c})}],Fd=function(){return{require:["ngModel","^?form"],controller:Re,link:function(a,c,d,e){var g=e[0],f=e[1]||sb;f.$addControl(g);a.$on("$destroy",function(){f.$removeControl(g)})}}},Hd=aa({require:"ngModel",link:function(a,c,d,e){e.$viewChangeListeners.push(function(){a.$eval(d.ngChange)})}}), 186 | ec=function(){return{require:"?ngModel",link:function(a,c,d,e){if(e){d.required=!0;var g=function(a){if(d.required&&e.$isEmpty(a))e.$setValidity("required",!1);else return e.$setValidity("required",!0),a};e.$formatters.push(g);e.$parsers.unshift(g);d.$observe("required",function(){g(e.$viewValue)})}}}},Gd=function(){return{require:"ngModel",link:function(a,c,d,e){var g=(a=/\/(.*)\//.exec(d.ngList))&&RegExp(a[1])||d.ngList||",";e.$parsers.push(function(a){if(!E(a)){var c=[];a&&q(a.split(g),function(a){a&& 187 | c.push(ca(a))});return c}});e.$formatters.push(function(a){return M(a)?a.join(", "):s});e.$isEmpty=function(a){return!a||!a.length}}}},Se=/^(true|false|\d+)$/,Id=function(){return{priority:100,compile:function(a,c){return Se.test(c.ngValue)?function(a,c,g){g.$set("value",a.$eval(g.ngValue))}:function(a,c,g){a.$watch(g.ngValue,function(a){g.$set("value",a)})}}}},id=va(function(a,c,d){c.addClass("ng-binding").data("$binding",d.ngBind);a.$watch(d.ngBind,function(a){c.text(a==s?"":a)})}),kd=["$interpolate", 188 | function(a){return function(c,d,e){c=a(d.attr(e.$attr.ngBindTemplate));d.addClass("ng-binding").data("$binding",c);e.$observe("ngBindTemplate",function(a){d.text(a)})}}],jd=["$sce","$parse",function(a,c){return function(d,e,g){e.addClass("ng-binding").data("$binding",g.ngBindHtml);var f=c(g.ngBindHtml);d.$watch(function(){return(f(d)||"").toString()},function(c){e.html(a.getTrustedHtml(f(d))||"")})}}],ld=Pb("",!0),nd=Pb("Odd",0),md=Pb("Even",1),od=va({compile:function(a,c){c.$set("ngCloak",s);a.removeClass("ng-cloak")}}), 189 | pd=[function(){return{scope:!0,controller:"@",priority:500}}],fc={};q("click dblclick mousedown mouseup mouseover mouseout mousemove mouseenter mouseleave keydown keyup keypress submit focus blur copy cut paste".split(" "),function(a){var c=na("ng-"+a);fc[c]=["$parse",function(d){return{compile:function(e,g){var f=d(g[c]);return function(c,d,e){d.on(K(a),function(a){c.$apply(function(){f(c,{$event:a})})})}}}}]});var sd=["$animate",function(a){return{transclude:"element",priority:600,terminal:!0,restrict:"A", 190 | $$tlb:!0,link:function(c,d,e,g,f){var h,l,k;c.$watch(e.ngIf,function(g){Qa(g)?l||(l=c.$new(),f(l,function(c){c[c.length++]=U.createComment(" end ngIf: "+e.ngIf+" ");h={clone:c};a.enter(c,d.parent(),d)})):(k&&(k.remove(),k=null),l&&(l.$destroy(),l=null),h&&(k=yb(h.clone),a.leave(k,function(){k=null}),h=null))})}}}],td=["$http","$templateCache","$anchorScroll","$animate","$sce",function(a,c,d,e,g){return{restrict:"ECA",priority:400,terminal:!0,transclude:"element",controller:Ea.noop,compile:function(f, 191 | h){var l=h.ngInclude||h.src,k=h.onload||"",m=h.autoscroll;return function(f,h,q,s,u){var F=0,v,y,A,x=function(){y&&(y.remove(),y=null);v&&(v.$destroy(),v=null);A&&(e.leave(A,function(){y=null}),y=A,A=null)};f.$watch(g.parseAsResourceUrl(l),function(g){var l=function(){!B(m)||m&&!f.$eval(m)||d()},q=++F;g?(a.get(g,{cache:c}).success(function(a){if(q===F){var c=f.$new();s.template=a;a=u(c,function(a){x();e.enter(a,null,h,l)});v=c;A=a;v.$emit("$includeContentLoaded");f.$eval(k)}}).error(function(){q=== 192 | F&&x()}),f.$emit("$includeContentRequested")):(x(),s.template=null)})}}}}],Jd=["$compile",function(a){return{restrict:"ECA",priority:-400,require:"ngInclude",link:function(c,d,e,g){d.html(g.template);a(d.contents())(c)}}}],ud=va({priority:450,compile:function(){return{pre:function(a,c,d){a.$eval(d.ngInit)}}}}),vd=va({terminal:!0,priority:1E3}),wd=["$locale","$interpolate",function(a,c){var d=/{}/g;return{restrict:"EA",link:function(e,g,f){var h=f.count,l=f.$attr.when&&g.attr(f.$attr.when),k=f.offset|| 193 | 0,m=e.$eval(l)||{},n={},p=c.startSymbol(),r=c.endSymbol(),s=/^when(Minus)?(.+)$/;q(f,function(a,c){s.test(c)&&(m[K(c.replace("when","").replace("Minus","-"))]=g.attr(f.$attr[c]))});q(m,function(a,e){n[e]=c(a.replace(d,p+h+"-"+k+r))});e.$watch(function(){var c=parseFloat(e.$eval(h));if(isNaN(c))return"";c in m||(c=a.pluralCat(c-k));return n[c](e,g,!0)},function(a){g.text(a)})}}}],xd=["$parse","$animate",function(a,c){var d=t("ngRepeat");return{transclude:"element",priority:1E3,terminal:!0,$$tlb:!0, 194 | link:function(e,g,f,h,l){var k=f.ngRepeat,m=k.match(/^\s*([\s\S]+?)\s+in\s+([\s\S]+?)(?:\s+track\s+by\s+([\s\S]+?))?\s*$/),n,p,r,s,u,F,v={$id:Ia};if(!m)throw d("iexp",k);f=m[1];h=m[2];(m=m[3])?(n=a(m),p=function(a,c,d){F&&(v[F]=a);v[u]=c;v.$index=d;return n(e,v)}):(r=function(a,c){return Ia(c)},s=function(a){return a});m=f.match(/^(?:([\$\w]+)|\(([\$\w]+)\s*,\s*([\$\w]+)\))$/);if(!m)throw d("iidexp",f);u=m[3]||m[1];F=m[2];var B={};e.$watchCollection(h,function(a){var f,h,m=g[0],n,v={},H,R,w,C,T,t, 195 | E=[];if(ab(a))T=a,n=p||r;else{n=p||s;T=[];for(w in a)a.hasOwnProperty(w)&&"$"!=w.charAt(0)&&T.push(w);T.sort()}H=T.length;h=E.length=T.length;for(f=0;fA;)z.pop().element.remove()}for(;x.length>I;)x.pop()[0].element.remove()}var k;if(!(k=t.match(d)))throw Te("iexp",t,ha(f));var l=c(k[2]||k[1]),m=k[4]||k[6],n=k[5],p=c(k[3]||""),q= 206 | c(k[2]?k[1]:m),y=c(k[7]),w=k[8]?c(k[8]):null,x=[[{element:f,label:""}]];u&&(a(u)(e),u.removeClass("ng-scope"),u.remove());f.empty();f.on("change",function(){e.$apply(function(){var a,c=y(e)||[],d={},h,k,l,p,t,v,u;if(r)for(k=[],p=0,v=x.length;p@charset "UTF-8";[ng\\:cloak],[ng-cloak],[data-ng-cloak],[x-ng-cloak],.ng-cloak,.x-ng-cloak,.ng-hide{display:none !important;}ng\\:form{display:block;}.ng-animate-block-transitions{transition:0s all!important;-webkit-transition:0s all!important;}'); 210 | //# sourceMappingURL=angular.min.js.map 211 | -------------------------------------------------------------------------------- /test/dummy/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pitr/angular-rails-templates/70db6af0f9ee760ffee44b9f814c179f23cfbf61/test/dummy/public/favicon.ico -------------------------------------------------------------------------------- /test/integration/static_assets_integration_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | # Test the Asset the Gem Provides 4 | 5 | describe "angular-rails-templates.js integration" do 6 | let(:config) { Dummy::Application.config.angular_templates } 7 | 8 | it "serves angular-rails-templates.js on the pipeline" do 9 | visit '/assets/angular-rails-templates.js' 10 | page.source.must_include %Q{angular.module("#{config.module_name}", [])} 11 | end 12 | 13 | it "includes a comment with the gem name and version" do 14 | visit '/assets/angular-rails-templates.js' 15 | page.source.must_include %Q{// Angular Rails Templates #{AngularRailsTemplates::VERSION}} 16 | end 17 | 18 | it "includes a comment describing the ignore_prefix" do 19 | visit '/assets/angular-rails-templates.js' 20 | page.source.must_include %Q{// angular_templates.ignore_prefix: #{config.ignore_prefix}} 21 | end 22 | 23 | it "includes a comment describing the availible markups" do 24 | visit '/assets/angular-rails-templates.js' 25 | page.source.must_include %Q{// angular_templates.markups: #{config.markups}} 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /test/integration/user_assets_integration_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | # Test the "user" templates in the Dummy app 4 | 5 | describe "user assets integration" do 6 | let(:config) { Dummy::Application.config.angular_templates } 7 | 8 | describe "any rendered template" do 9 | 10 | before { visit '/assets/plain.js' } 11 | 12 | it "has a comment with the gem name" do 13 | page.source.must_match %r{// Angular Rails Template} 14 | end 15 | 16 | it "has a comment with the source file" do 17 | page.source.must_include %Q{// source:} 18 | end 19 | 20 | it "opens an existing angular module" do 21 | page.source.must_include %Q{angular.module("#{config.module_name}")} 22 | end 23 | 24 | it "puts something in the templateCache" do 25 | page.source.must_include %Q{$templateCache.put} 26 | end 27 | end 28 | 29 | describe "templates in assets/javascript" do 30 | 31 | it "compiles erb (erb_template.html.erb)" do 32 | visit '/assets/erb_template.js' 33 | page.source.must_include %Q{// source: app/assets/javascripts/erb_template.html.erb} 34 | page.source.must_include %Q{$templateCache.put("erb_template.html"} 35 | page.source.must_include %q{'
42
'} 36 | end 37 | 38 | # assuming the user loads haml 39 | it "compiles haml (haml_template.html.haml)" do 40 | visit '/assets/haml_template.js' 41 | page.source.must_include %Q{// source: app/assets/javascripts/haml_template.html.haml} 42 | page.source.must_include %Q{$templateCache.put("haml_template.html"} 43 | page.source.must_include %q{"

html-haml

"} 44 | end 45 | 46 | # assuming the user loads an approperate md library 47 | it "compiles markdown (markdown.html.md)" do 48 | visit '/assets/markdown.js' 49 | page.source.must_include %Q{// source: app/assets/javascripts/markdown.html.md} 50 | page.source.must_include %Q{$templateCache.put("markdown.html"} 51 | page.source.must_match %r{Markdown!} 52 | end 53 | 54 | it "compiles plain html (plain.html)" do 55 | visit '/assets/plain.js' 56 | page.source.must_include %Q{// source: app/assets/javascripts/plain.html} 57 | page.source.must_include %Q{$templateCache.put("plain.html"} 58 | page.source.must_include %q{'
plain text
'} 59 | end 60 | 61 | # assuming the user loads slim 62 | it "compiles slim (slim_template.html.slim)" do 63 | visit '/assets/slim_template.js' 64 | page.source.must_include %Q{// source: app/assets/javascripts/slim_template.html.slim} 65 | page.source.must_include %Q{$templateCache.put("slim_template.html"} 66 | page.source.must_include %q{"

slim template

"} 67 | end 68 | end 69 | 70 | describe "templates in assets/javascript/ignored_namespace" do 71 | 72 | it "is configured with a custom namespace" do 73 | assert_equal config.ignore_prefix.count, 1 74 | assert_match config.ignore_prefix[0], "ignored_namespace/" 75 | end 76 | 77 | it "compiles haml (slim_template.html.slim)" do 78 | visit '/assets/slim_template.js' 79 | page.source.must_include %Q{// source: app/assets/javascripts/slim_template.html} 80 | page.source.must_include %Q{$templateCache.put("slim_template.html"} 81 | page.source.must_include %q{"

slim template

"} 82 | end 83 | end 84 | 85 | describe "templates in assets/javascript/subfolder" do 86 | 87 | it "compiles html in a subfolder (template.html)" do 88 | visit '/assets/subfolder/template.js' 89 | page.source.must_include %Q{// source: app/assets/javascripts/subfolder/template.html} 90 | page.source.must_include %Q{$templateCache.put("subfolder/template.html"} 91 | page.source.must_include %q{'
Subfolder
'} 92 | end 93 | 94 | it "compiles slim in a subfolder (slim_template.html.slim)" do 95 | visit '/assets/subfolder/slim_template.js' 96 | page.source.must_include %Q{// source: app/assets/javascripts/subfolder/slim_template.html.slim} 97 | page.source.must_include %Q{$templateCache.put("subfolder/slim_template.html"} 98 | page.source.must_include %q{'
Subfolder-SLIM
'} 99 | end 100 | 101 | it "compiles haml in a subfolder (haml_template.html.haml)" do 102 | visit '/assets/subfolder/haml_template.js' 103 | page.source.must_include %Q{// source: app/assets/javascripts/subfolder/haml_template.html.haml} 104 | page.source.must_include %Q{$templateCache.put("subfolder/haml_template.html"} 105 | page.source.must_include %q{"
Subfolder-HAML
"} 106 | end 107 | end 108 | 109 | describe "templates in assets/javascript/subfolder2" do 110 | 111 | it "compiles html in a subfolder (template.html)" do 112 | visit '/assets/subfolder2/template.js' 113 | page.source.must_include %Q{// source: app/assets/javascripts/subfolder2/template.html} 114 | page.source.must_include %Q{$templateCache.put("subfolder2/template.html"} 115 | page.source.must_include %q{'
Subfolder2
'} 116 | end 117 | end 118 | 119 | # NOT in assets/javascript 120 | describe "templates in assets/templates" do 121 | 122 | it "compiles html (test.html)" do 123 | visit '/assets/test.js' 124 | page.source.must_include %Q{// source: app/assets/templates/test.html} 125 | page.source.must_include %Q{$templateCache.put("test.html"} 126 | page.source.must_include %q{"outside-javascript"} 127 | end 128 | 129 | it "compiles str (sub/sub.html.str)" do 130 | visit '/assets/sub/sub.js' 131 | page.source.must_include %Q{// source: app/assets/templates/sub/sub.html.str} 132 | page.source.must_include %Q{$templateCache.put("sub/sub.html"} 133 | page.source.must_include %q{"outside-javascript 42"} 134 | end 135 | 136 | it "compiles haml (sub2.html.haml)" do 137 | visit '/assets/sub/sub2.js' 138 | page.source.must_include %Q{// source: app/assets/templates/sub/sub2.html.haml} 139 | page.source.must_include %Q{$templateCache.put("sub/sub2.html"} 140 | page.source.must_include %q{"

P.S. I love you

"} 141 | end 142 | end 143 | 144 | end 145 | -------------------------------------------------------------------------------- /test/precompile_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | require 'fileutils' 4 | require 'pathname' 5 | 6 | class PrecompileTest < Minitest::Test 7 | def setup 8 | delete_assets! 9 | end 10 | 11 | def teardown 12 | delete_assets! 13 | end 14 | 15 | def delete_assets! 16 | FileUtils.rm_rf app_path.join('public', 'assets') 17 | FileUtils.rm_rf app_path.join('tmp', 'cache','assets') 18 | end 19 | 20 | def precompile!(rails_env) 21 | Dir.chdir(app_path) { `bundle exec rake assets:precompile RAILS_ENV=#{rails_env} 2> /dev/null` } 22 | 23 | appjs = Dir["#{app_path}/public/assets/application*.js"].first 24 | 25 | assert appjs, "the file #{app_path}/public/assets/application.js should exist" 26 | contents = File.read(appjs) 27 | 28 | # essential javascript things 29 | assert_match /angular\.module\("templates", ?\[\]\)[,;]/, contents 30 | assert_match 'angular.module("templates")', contents 31 | 32 | # Test the inclusion of the templates 33 | %w(erb_template haml_template hello-world markdown plain slim_template sub/sub sub/sub2 subfolder/haml_template subfolder/slim_template subfolder/template subfolder2/template test). 34 | each do |file| 35 | assert_match %Q{.put("#{file}.html"}, contents 36 | end 37 | 38 | # no templates starting with the ignored namespace are in the bundle 39 | refute_match '.put("ignored_namespace/', contents 40 | 41 | contents 42 | end 43 | 44 | def app_path 45 | Pathname.new("#{File.dirname(__FILE__)}/dummy") 46 | end 47 | 48 | def test_precompile_succeeds_in_development_environment 49 | contents = precompile! 'development' 50 | 51 | assert_match "angular_templates.ignore_prefix: [\"ignored_namespace/\"]", contents 52 | assert_match "angular_templates.markups:", contents 53 | assert_match /source: .+\/ignored_namespace\//, contents 54 | end 55 | 56 | def test_precompile_succeeds_in_production_environment 57 | precompile! 'production' 58 | end 59 | 60 | end 61 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | require 'coveralls' 2 | Coveralls.wear! 3 | 4 | # Configure Rails Environment 5 | ENV['RAILS_ENV'] = 'test' 6 | 7 | # Remove tmp dir of dummy app before it's booted. 8 | FileUtils.rm_rf "#{File.dirname(__FILE__)}/dummy/tmp" 9 | 10 | require File.expand_path('../dummy/config/environment.rb', __FILE__) 11 | require 'minitest/autorun' 12 | require 'capybara/rails' 13 | require 'active_support/core_ext/kernel/reporting' 14 | 15 | Rails.backtrace_cleaner.remove_silencers! 16 | 17 | # Support MiniTest 4/5 18 | Minitest::Test = Minitest::Unit::TestCase unless defined? Minitest::Test 19 | 20 | class IntegrationTest < Minitest::Spec 21 | include Capybara::DSL 22 | register_spec_type(/integration$/, self) 23 | end 24 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/angular-rails-templates.js.erb: -------------------------------------------------------------------------------- 1 | // Angular Rails Templates <%= AngularRailsTemplates::VERSION %> 2 | // 3 | // angular_templates.ignore_prefix: <%= ::Rails.configuration.angular_templates.ignore_prefix %> 4 | // angular_templates.markups: <%= ::Rails.configuration.angular_templates.markups %> 5 | // angular_templates.htmlcompressor: <%= ::Rails.configuration.angular_templates.htmlcompressor %> 6 | 7 | angular.module("<%= ::Rails.configuration.angular_templates.module_name %>", []); 8 | 9 | --------------------------------------------------------------------------------