├── demo
├── app
│ ├── views
│ │ ├── admin
│ │ │ ├── entity1.html
│ │ │ ├── entity2.html
│ │ │ └── entity3.html
│ │ └── main.html
│ ├── scripts
│ │ ├── components
│ │ │ ├── my-component1.html
│ │ │ ├── my-component2.html
│ │ │ ├── my-component3.html
│ │ │ ├── my-component1.js
│ │ │ ├── my-component2.js
│ │ │ └── my-component3.js
│ │ ├── directives
│ │ │ ├── my-directive1.html
│ │ │ ├── my-directive2.html
│ │ │ ├── my-directive3.html
│ │ │ ├── my-directive1.js
│ │ │ ├── my-directive2.js
│ │ │ └── my-directive3.js
│ │ ├── controllers
│ │ │ ├── main.js
│ │ │ └── admin
│ │ │ │ ├── entity1.js
│ │ │ │ ├── entity2.js
│ │ │ │ └── entity3.js
│ │ ├── app.js
│ │ └── app-routes.js
│ ├── styles
│ │ └── main.css
│ ├── test-directives.html
│ ├── index.html
│ ├── test-components.html
│ ├── test-angular-1.3.html
│ ├── test-angular-1.4.html
│ ├── test-angular-1.5.html
│ └── test-angular-1.2.html
├── package.json
├── README.txt
└── Gruntfile.js
├── src
├── angular-combine-app.js
├── angular-combine-config.js
└── angular-combine-decorator.js
├── .gitignore
├── .travis.yml
├── .jshintrc
├── bower.json
├── .jsbeautifier
├── dist
├── angular-combine-without-console.min.js
├── angular-combine.min.js
├── angular-combine-without-console.js
└── angular-combine.js
├── LICENSE-MIT
├── package.json
├── .jscsrc
├── test
└── spec
│ ├── nativeBehaviorSpec.js
│ └── basicCombineSpec.js
├── Gruntfile.js
└── README.md
/demo/app/views/admin/entity1.html:
--------------------------------------------------------------------------------
1 |
This is the admin/entity1 view.
2 |
--------------------------------------------------------------------------------
/demo/app/views/admin/entity2.html:
--------------------------------------------------------------------------------
1 | This is the admin/entity2 view.
2 |
--------------------------------------------------------------------------------
/demo/app/views/admin/entity3.html:
--------------------------------------------------------------------------------
1 | This is the admin/entity3 view.
2 |
--------------------------------------------------------------------------------
/src/angular-combine-app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularCombine', []);
4 |
--------------------------------------------------------------------------------
/demo/app/scripts/components/my-component1.html:
--------------------------------------------------------------------------------
1 |
2 |
My component
3 | This is an example of component 1 ...
4 |
5 |
--------------------------------------------------------------------------------
/demo/app/scripts/components/my-component2.html:
--------------------------------------------------------------------------------
1 |
2 |
My component
3 | This is an example of component 2 ...
4 |
5 |
--------------------------------------------------------------------------------
/demo/app/scripts/components/my-component3.html:
--------------------------------------------------------------------------------
1 |
2 |
My component
3 | This is an example of component 3 ...
4 |
5 |
--------------------------------------------------------------------------------
/demo/app/scripts/directives/my-directive1.html:
--------------------------------------------------------------------------------
1 |
2 |
My directive
3 | This is an example of directive 1 ...
4 |
5 |
--------------------------------------------------------------------------------
/demo/app/scripts/directives/my-directive2.html:
--------------------------------------------------------------------------------
1 |
2 |
My directive
3 | This is an example of directive 2 ...
4 |
5 |
--------------------------------------------------------------------------------
/demo/app/scripts/directives/my-directive3.html:
--------------------------------------------------------------------------------
1 |
2 |
My directive
3 | This is an example of directive 3 ...
4 |
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | npm-debug.log
3 | tmp
4 | .project
5 | .tmp
6 | bower_components
7 | .grunt
8 | _SpecRunner.html
9 | .DS_Store
10 |
--------------------------------------------------------------------------------
/demo/app/scripts/components/my-component1.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularCombineViewApp').component('myComponent1', {
4 | templateUrl : 'scripts/components/my-component1.html'
5 | });
6 |
--------------------------------------------------------------------------------
/demo/app/scripts/components/my-component2.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularCombineViewApp').component('myComponent2', {
4 | templateUrl : 'scripts/components/my-component2.html'
5 | });
6 |
--------------------------------------------------------------------------------
/demo/app/scripts/components/my-component3.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularCombineViewApp').component('myComponent3', {
4 | templateUrl : 'scripts/components/my-component3.html'
5 | });
6 |
--------------------------------------------------------------------------------
/demo/app/scripts/directives/my-directive1.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularCombineViewApp').directive('myDirective1', function() {
4 | return {
5 | restrict : 'E',
6 | templateUrl : 'scripts/directives/my-directive1.html'
7 | };
8 | });
9 |
--------------------------------------------------------------------------------
/demo/app/scripts/directives/my-directive2.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularCombineViewApp').directive('myDirective2', function() {
4 | return {
5 | restrict : 'E',
6 | templateUrl : 'scripts/directives/my-directive2.html'
7 | };
8 | });
9 |
--------------------------------------------------------------------------------
/demo/app/views/main.html:
--------------------------------------------------------------------------------
1 |
2 |
'Allo, 'Allo!
3 |
You now have
4 |
7 |
installed.
8 |
Enjoy coding! - Yeoman
9 |
10 |
--------------------------------------------------------------------------------
/demo/app/scripts/controllers/main.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularCombineViewApp')
4 | .controller('MainCtrl', function ($scope) {
5 | $scope.awesomeThings = [
6 | 'HTML5 Boilerplate',
7 | 'AngularJS',
8 | 'Karma'
9 | ];
10 | });
11 |
--------------------------------------------------------------------------------
/demo/app/scripts/controllers/admin/entity1.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularCombineViewApp')
4 | .controller('AdminEntity1Ctrl', function ($scope) {
5 | $scope.awesomeThings = [
6 | 'HTML5 Boilerplate',
7 | 'AngularJS',
8 | 'Karma'
9 | ];
10 | });
11 |
--------------------------------------------------------------------------------
/demo/app/scripts/controllers/admin/entity2.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularCombineViewApp')
4 | .controller('AdminEntity2Ctrl', function ($scope) {
5 | $scope.awesomeThings = [
6 | 'HTML5 Boilerplate',
7 | 'AngularJS',
8 | 'Karma'
9 | ];
10 | });
11 |
--------------------------------------------------------------------------------
/demo/app/scripts/controllers/admin/entity3.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularCombineViewApp')
4 | .controller('AdminEntity3Ctrl', function ($scope) {
5 | $scope.awesomeThings = [
6 | 'HTML5 Boilerplate',
7 | 'AngularJS',
8 | 'Karma'
9 | ];
10 | });
11 |
--------------------------------------------------------------------------------
/demo/app/scripts/directives/my-directive3.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularCombineViewApp').directive('myDirective3', function() {
4 | return {
5 | restrict : 'E',
6 | templateUrl : function() {
7 | return 'scripts/directives/my-directive3.html'
8 | }
9 | };
10 | });
11 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 5
4 | before_install:
5 | - npm prune
6 | - npm install -g grunt-cli bower
7 | install:
8 | - npm install
9 | - bower install
10 | script:
11 | - grunt jasmine
12 | cache:
13 | directories:
14 | - node_modules
15 | - bower_components
16 |
--------------------------------------------------------------------------------
/.jshintrc:
--------------------------------------------------------------------------------
1 | {
2 | "curly": true,
3 | "eqeqeq": true,
4 | "immed": true,
5 | "latedef": true,
6 | "newcap": true,
7 | "noarg": true,
8 | "sub": true,
9 | "undef": true,
10 | "boss": true,
11 | "eqnull": true,
12 | "node": true,
13 | "-W088": false, // Creating global 'for' variable. Should be 'for (var k ...'. = https://github.com/jshint/jshint/issues/1016
14 | "globals": {
15 | "angular": false
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/angular-combine-config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularCombine').provider('angularCombineConfig', function() {
4 | var config = [];
5 |
6 | this.addConf = function(regexp, combinedUrl) {
7 | console.log('Add conf to angularCombine', regexp, combinedUrl);
8 | config.push({
9 | regexp: regexp,
10 | combinedUrl: combinedUrl
11 | });
12 | };
13 | this.$get = function() {
14 | return config;
15 | };
16 | });
17 |
--------------------------------------------------------------------------------
/demo/app/scripts/app.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularCombineViewApp', [ 'ngRoute', 'angularCombine' ]);
4 |
5 | angular.module('angularCombineViewApp').config(function (angularCombineConfigProvider) {
6 | angularCombineConfigProvider.addConf(/^views\/admin\//, 'views/admin.html');
7 | angularCombineConfigProvider.addConf(/^scripts\/components\//, 'views/components.html');
8 | angularCombineConfigProvider.addConf(/^scripts\/directives\//, 'views/directives.html');
9 | });
10 |
--------------------------------------------------------------------------------
/demo/app/styles/main.css:
--------------------------------------------------------------------------------
1 | body {
2 | background: #fafafa;
3 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
4 | color: #333;
5 | }
6 |
7 | .hero-unit {
8 | margin: 50px auto 0 auto;
9 | width: 300px;
10 | font-size: 18px;
11 | font-weight: 200;
12 | line-height: 30px;
13 | background-color: #eee;
14 | border-radius: 6px;
15 | padding: 60px;
16 | }
17 |
18 | .hero-unit h1 {
19 | font-size: 60px;
20 | line-height: 1;
21 | letter-spacing: -1px;
22 | }
23 |
--------------------------------------------------------------------------------
/demo/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angularcombineview",
3 | "version": "0.0.0",
4 | "devDependencies": {
5 | "grunt": "1.0.1",
6 | "grunt-contrib-concat": "1.0.1",
7 | "grunt-contrib-jshint": "1.1.0",
8 | "grunt-contrib-connect": "1.0.2",
9 | "grunt-contrib-clean": "1.0.0",
10 | "grunt-contrib-watch": "1.0.0",
11 | "grunt-autoprefixer": "3.0.4",
12 | "load-grunt-tasks": "3.5.2",
13 | "serve-static": "1.11.1",
14 | "time-grunt": "1.4.0",
15 | "grunt-angular-combine": "0.1.8"
16 | },
17 | "engines": {
18 | "node": ">=0.8.0"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-combine",
3 | "version": "0.1.5",
4 | "main": "./dist/angular-combine.js",
5 | "description": "Allow loading of merge templates into a single HTML file.",
6 | "keywords": [
7 | "angular",
8 | "combine",
9 | "performance",
10 | "partials",
11 | "$templateCache"
12 | ],
13 | "dependencies": {
14 | "angular": "^1.2"
15 | },
16 | "devDependencies": {
17 | "angular-mocks": "^1.2"
18 | },
19 | "ignore": [
20 | "demo",
21 | "src",
22 | "test",
23 | ".*",
24 | "Gruntfile.js"
25 | ],
26 | "license": "MIT"
27 | }
28 |
--------------------------------------------------------------------------------
/demo/app/scripts/app-routes.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularCombineViewApp').config(function ($routeProvider) {
4 | $routeProvider.when('/', {
5 | templateUrl : 'views/main.html',
6 | controller : 'MainCtrl'
7 | }).when('/admin/entity1', {
8 | templateUrl : 'views/admin/entity1.html',
9 | controller : 'AdminEntity1Ctrl'
10 | }).when('/admin/entity2', {
11 | templateUrl : 'views/admin/entity2.html',
12 | controller : 'AdminEntity2Ctrl'
13 | }).when('/admin/entity3', {
14 | templateUrl : 'views/admin/entity3.html',
15 | controller : 'AdminEntity3Ctrl'
16 | }).otherwise({
17 | redirectTo : '/'
18 | });
19 | });
20 |
--------------------------------------------------------------------------------
/.jsbeautifier:
--------------------------------------------------------------------------------
1 | {
2 | "eol": "\n",
3 | "indent_level": 0,
4 | "indent_with_tabs": true,
5 | "preserve_newlines": true,
6 | "max_preserve_newlines": 10,
7 | "jslint_happy": false,
8 | "space_after_anon_function": false,
9 | "brace_style": "collapse",
10 | "keep_array_indentation": false,
11 | "keep_function_indentation": false,
12 | "space_before_conditional": true,
13 | "break_chained_methods": false,
14 | "eval_code": false,
15 | "unescape_strings": false,
16 | "wrap_line_length": 0,
17 | "wrap_attributes": "auto",
18 | "wrap_attributes_indent_size": 4,
19 | "end_with_newline": true
20 | }
21 |
--------------------------------------------------------------------------------
/demo/README.txt:
--------------------------------------------------------------------------------
1 | To run this example :
2 | npm install
3 | grunt server
4 |
5 | Check the console :
6 |
7 | Add conf to angularCombine RegExp /^views\/admin\// views/admin.html
8 | --> This is our specific configuration (see into scripts/app.js)
9 | GET http://127.0.0.1:9000/views/main.html
10 | --> Classic loading of a single partials into a single HTML file (this is usual Angular mechanism)
11 |
12 | Click on a link "Enity 1" :
13 |
14 | fetching all templates combined into views/admin.html
15 | GET http://127.0.0.1:9000/views/admin.html
16 | --> The ajax call for the combine files is made
17 |
18 | Click on another link : "Enity 2" or "Enity 3" :
19 | --> No additional HTTP call
20 |
--------------------------------------------------------------------------------
/dist/angular-combine-without-console.min.js:
--------------------------------------------------------------------------------
1 | /*! angular-combine - 2015-09-26 */
2 | !function(a){"use strict";a.module("angularCombine",[]),a.module("angularCombine").provider("angularCombineConfig",function(){var a=[];this.addConf=function(b,c){a.push({regexp:b,combinedUrl:c})},this.$get=function(){return a}}),a.module("angularCombine").config(["$provide",function(a){a.decorator("$templateCache",["$delegate","$http","$injector",function(a,b,c){var d,e,f=a.get,g=c.get("angularCombineConfig"),h=function(a){var d;return function(e){return d||(d=b.get(a).then(function(a){return c.get("$compile")(a.data),a})),d.then(function(a){return{status:a.status,data:f(e),headers:a.headers}})}};for(d in g)e=g[d],e.load=h(e.combinedUrl);return a.get=function(a){for(d in g)if(e=g[d],e.regexp&&e.regexp.test(a))return e.load(a);return f(a)},a}])}])}(angular);
--------------------------------------------------------------------------------
/dist/angular-combine.min.js:
--------------------------------------------------------------------------------
1 | /*! angular-combine - 2015-09-26 */
2 | !function(a){"use strict";a.module("angularCombine",[]),a.module("angularCombine").provider("angularCombineConfig",function(){var a=[];this.addConf=function(b,c){console.log("Add conf to angularCombine",b,c),a.push({regexp:b,combinedUrl:c})},this.$get=function(){return a}}),a.module("angularCombine").config(["$provide",function(a){a.decorator("$templateCache",["$delegate","$http","$injector",function(a,b,c){var d,e,f=a.get,g=c.get("angularCombineConfig"),h=function(a){var d;return function(e){return d||(console.log("fetching all templates combined into ",a),d=b.get(a).then(function(a){return c.get("$compile")(a.data),a})),d.then(function(a){return{status:a.status,data:f(e),headers:a.headers}})}};for(d in g)e=g[d],e.load=h(e.combinedUrl);return a.get=function(a){for(d in g)if(e=g[d],e.regexp&&e.regexp.test(a))return e.load(a);return f(a)},a}])}])}(angular);
--------------------------------------------------------------------------------
/LICENSE-MIT:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013 Romain Gonord
2 |
3 | Permission is hereby granted, free of charge, to any person
4 | obtaining a copy of this software and associated documentation
5 | files (the "Software"), to deal in the Software without
6 | restriction, including without limitation the rights to use,
7 | copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | copies of the Software, and to permit persons to whom the
9 | Software is furnished to do so, subject to the following
10 | conditions:
11 |
12 | The above copyright notice and this permission notice shall be
13 | included in all copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
22 | OTHER DEALINGS IN THE SOFTWARE.
23 |
--------------------------------------------------------------------------------
/demo/app/test-directives.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
--------------------------------------------------------------------------------
/src/angular-combine-decorator.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | angular.module('angularCombine').config(function($provide) {
4 | $provide.decorator('$templateCache', function($delegate, $http, $injector) {
5 | var origGetMethod = $delegate.get;
6 | var idx, conf;
7 | var angularCombineConfig = $injector.get('angularCombineConfig');
8 |
9 | var loadCombinedTemplates = function(combinedUrl) {
10 | var combinedTplPromise;
11 | return function(url) {
12 | if (!combinedTplPromise) {
13 | console.log('fetching all templates combined into ', combinedUrl);
14 | combinedTplPromise = $http.get(combinedUrl).then(function(response) {
15 | $injector.get('$compile')(response.data);
16 | return response;
17 | });
18 | }
19 | return combinedTplPromise.then(function(response) {
20 | return {
21 | status: response.status,
22 | data: origGetMethod(url),
23 | headers: response.headers
24 | };
25 | });
26 | };
27 | };
28 |
29 | for (idx in angularCombineConfig) {
30 | conf = angularCombineConfig[idx];
31 | conf.load = loadCombinedTemplates(conf.combinedUrl);
32 | }
33 |
34 | $delegate.get = function(url) {
35 | for (idx in angularCombineConfig) {
36 | conf = angularCombineConfig[idx];
37 | if (conf.regexp && conf.regexp.test(url)) {
38 | return conf.load(url);
39 | }
40 | }
41 | return origGetMethod(url);
42 | };
43 |
44 | return $delegate;
45 | });
46 | });
47 |
--------------------------------------------------------------------------------
/demo/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
39 |
40 |
41 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "angular-combine",
3 | "description": "Allow loading of merge templates into a single HTML file.",
4 | "version": "0.1.5",
5 | "homepage": "https://github.com/astik/angular-combine",
6 | "author": {
7 | "name": "Romain Gonord",
8 | "email": "romain.gonord.opensource@neteyes.org"
9 | },
10 | "repository": {
11 | "type": "git",
12 | "url": "git://github.com/astik/angular-combine.git"
13 | },
14 | "bugs": {
15 | "url": "https://github.com/astik/angular-combine/issues"
16 | },
17 | "license": "MIT",
18 | "main": "./dist/angular-combine.js",
19 | "engines": {
20 | "node": ">= 0.8.0"
21 | },
22 | "scripts": {
23 | "test": "grunt test"
24 | },
25 | "devDependencies": {
26 | "grunt": "1.0.1",
27 | "grunt-banner": "0.6.0",
28 | "grunt-release": "0.14.0",
29 | "grunt-contrib-clean": "1.0.0",
30 | "grunt-contrib-concat": "1.0.1",
31 | "grunt-contrib-jasmine": "1.0.3",
32 | "grunt-contrib-jshint": "1.1.0",
33 | "grunt-contrib-uglify": "2.0.0",
34 | "grunt-contrib-watch": "1.0.0",
35 | "grunt-jsbeautifier": "0.2.13",
36 | "grunt-jscs": "3.0.1",
37 | "grunt-ng-annotate": "3.0.0",
38 | "grunt-remove-logging": "0.2.0",
39 | "load-grunt-tasks": "3.5.2",
40 | "time-grunt": "1.4.0"
41 | },
42 | "peerDependencies": {
43 | "grunt": "1.0.1"
44 | },
45 | "keywords": [
46 | "angular",
47 | "combine",
48 | "performance",
49 | "partials",
50 | "$templateCache"
51 | ]
52 | }
53 |
--------------------------------------------------------------------------------
/.jscsrc:
--------------------------------------------------------------------------------
1 | {
2 | "disallowEmptyBlocks": true,
3 | "disallowFunctionDeclarations": true,
4 | "disallowKeywordsOnNewLine": ["else"],
5 | "disallowMixedSpacesAndTabs": "smart",
6 | "disallowMultipleLineBreaks": true,
7 | "disallowMultipleLineStrings": true,
8 | "disallowMultipleSpaces": true,
9 | "disallowMultipleVarDecl": "exceptUndefined",
10 | "disallowNewlineBeforeBlockStatements": true,
11 | // "disallowSpacesInFunctionDeclaration": {
12 | // "beforeOpeningRoundBrace": true,
13 | // "beforeOpeningCurlyBrace": true
14 | // },
15 | // "disallowSpacesInFunctionExpression": {
16 | // "beforeOpeningRoundBrace": true,
17 | // "beforeOpeningCurlyBrace": true
18 | // },
19 | "disallowTrailingComma": true,
20 | // "disallowTrailingWhitespace": true,
21 | "maximumLineLength": 209,
22 | "requireBlocksOnNewline": true,
23 | "requireCamelCaseOrUpperCaseIdentifiers": true,
24 | "requireCommaBeforeLineBreak": true,
25 | "requireCurlyBraces": [
26 | "if",
27 | "else",
28 | "for",
29 | "while",
30 | "do",
31 | "try",
32 | "catch"
33 | // "case",
34 | // "default"
35 | ],
36 | "requireDotNotation": "except_snake_case",
37 | "requireLineBreakAfterVariableAssignment": true,
38 | "requireLineFeedAtFileEnd": true,
39 | "requireParenthesesAroundIIFE": true,
40 | "requireSemicolons": true,
41 | "requireSpaceAfterBinaryOperators": [
42 | "=",
43 | ",",
44 | "+",
45 | "-",
46 | "/",
47 | "*",
48 | "==",
49 | "===",
50 | "!=",
51 | "!=="
52 | ],
53 | "requireSpaceAfterLineComment": true,
54 | "validateIndentation": "\t",
55 | "validateLineBreaks": "LF",
56 | "validateQuoteMarks": {
57 | "mark": "'",
58 | "escape": true
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/demo/app/test-components.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/demo/app/test-angular-1.3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | -
17 | Root
18 |
19 | -
20 | Admin
21 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/demo/app/test-angular-1.4.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | -
17 | Root
18 |
19 | -
20 | Admin
21 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/demo/app/test-angular-1.5.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 | -
17 | Root
18 |
19 | -
20 | Admin
21 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
--------------------------------------------------------------------------------
/demo/app/test-angular-1.2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | -
18 | Root
19 |
20 | -
21 | Admin
22 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/dist/angular-combine-without-console.js:
--------------------------------------------------------------------------------
1 | /*! angular-combine - 2015-09-26 */
2 | (function(angular){
3 | 'use strict';
4 |
5 | angular.module('angularCombine', []);
6 | ;
7 | 'use strict';
8 |
9 | angular.module('angularCombine').provider('angularCombineConfig', function() {
10 | var config = [];
11 |
12 | this.addConf = function(regexp, combinedUrl) {
13 |
14 | config.push({
15 | regexp: regexp,
16 | combinedUrl: combinedUrl
17 | });
18 | };
19 | this.$get = function() {
20 | return config;
21 | };
22 | });
23 | ;
24 | 'use strict';
25 |
26 | angular.module('angularCombine').config(["$provide", function($provide) {
27 | $provide.decorator('$templateCache', ["$delegate", "$http", "$injector", function($delegate, $http, $injector) {
28 | var origGetMethod = $delegate.get;
29 | var idx, conf;
30 | var angularCombineConfig = $injector.get('angularCombineConfig');
31 |
32 | var loadCombinedTemplates = function(combinedUrl) {
33 | var combinedTplPromise;
34 | return function(url) {
35 | if (!combinedTplPromise) {
36 |
37 | combinedTplPromise = $http.get(combinedUrl).then(function(response) {
38 | $injector.get('$compile')(response.data);
39 | return response;
40 | });
41 | }
42 | return combinedTplPromise.then(function(response) {
43 | return {
44 | status: response.status,
45 | data: origGetMethod(url),
46 | headers: response.headers
47 | };
48 | });
49 | };
50 | };
51 |
52 | for (idx in angularCombineConfig) {
53 | conf = angularCombineConfig[idx];
54 | conf.load = loadCombinedTemplates(conf.combinedUrl);
55 | }
56 |
57 | $delegate.get = function(url) {
58 | for (idx in angularCombineConfig) {
59 | conf = angularCombineConfig[idx];
60 | if (conf.regexp && conf.regexp.test(url)) {
61 | return conf.load(url);
62 | }
63 | }
64 | return origGetMethod(url);
65 | };
66 |
67 | return $delegate;
68 | }]);
69 | }]);
70 |
71 | }(angular));
--------------------------------------------------------------------------------
/dist/angular-combine.js:
--------------------------------------------------------------------------------
1 | /*! angular-combine - 2015-09-26 */
2 | (function(angular){
3 | 'use strict';
4 |
5 | angular.module('angularCombine', []);
6 | ;
7 | 'use strict';
8 |
9 | angular.module('angularCombine').provider('angularCombineConfig', function() {
10 | var config = [];
11 |
12 | this.addConf = function(regexp, combinedUrl) {
13 | console.log('Add conf to angularCombine', regexp, combinedUrl);
14 | config.push({
15 | regexp: regexp,
16 | combinedUrl: combinedUrl
17 | });
18 | };
19 | this.$get = function() {
20 | return config;
21 | };
22 | });
23 | ;
24 | 'use strict';
25 |
26 | angular.module('angularCombine').config(["$provide", function($provide) {
27 | $provide.decorator('$templateCache', ["$delegate", "$http", "$injector", function($delegate, $http, $injector) {
28 | var origGetMethod = $delegate.get;
29 | var idx, conf;
30 | var angularCombineConfig = $injector.get('angularCombineConfig');
31 |
32 | var loadCombinedTemplates = function(combinedUrl) {
33 | var combinedTplPromise;
34 | return function(url) {
35 | if (!combinedTplPromise) {
36 | console.log('fetching all templates combined into ', combinedUrl);
37 | combinedTplPromise = $http.get(combinedUrl).then(function(response) {
38 | $injector.get('$compile')(response.data);
39 | return response;
40 | });
41 | }
42 | return combinedTplPromise.then(function(response) {
43 | return {
44 | status: response.status,
45 | data: origGetMethod(url),
46 | headers: response.headers
47 | };
48 | });
49 | };
50 | };
51 |
52 | for (idx in angularCombineConfig) {
53 | conf = angularCombineConfig[idx];
54 | conf.load = loadCombinedTemplates(conf.combinedUrl);
55 | }
56 |
57 | $delegate.get = function(url) {
58 | for (idx in angularCombineConfig) {
59 | conf = angularCombineConfig[idx];
60 | if (conf.regexp && conf.regexp.test(url)) {
61 | return conf.load(url);
62 | }
63 | }
64 | return origGetMethod(url);
65 | };
66 |
67 | return $delegate;
68 | }]);
69 | }]);
70 |
71 | }(angular));
--------------------------------------------------------------------------------
/test/spec/nativeBehaviorSpec.js:
--------------------------------------------------------------------------------
1 | // this test checks that without doing anything, except loading the module, we don't break basic Angular behavior.
2 | describe('native behavior', function() {
3 |
4 | var $templateCache, $httpBackend, $templateRequest;
5 | var template = 'test
';
6 |
7 | beforeEach(function() {
8 | module('angularCombine');
9 | inject(function(_$httpBackend_, _$templateCache_, _$templateRequest_, _$http_) {
10 | $httpBackend = _$httpBackend_;
11 | $templateCache = _$templateCache_;
12 | $templateRequest = _$templateRequest_;
13 | $http = _$http_;
14 | });
15 | });
16 |
17 | afterEach(function() {
18 | $httpBackend.verifyNoOutstandingExpectation();
19 | $httpBackend.verifyNoOutstandingRequest();
20 | });
21 |
22 | it('should cache the given value at the given key', function() {
23 | var templateUrl = 'simpleTest.html';
24 | $templateCache.put(templateUrl, template);
25 | expect($templateCache.get(templateUrl)).toBe(template);
26 | });
27 |
28 | it('should not make a web request if put template found', function() {
29 | var templateUrl = 'testRightIntoTheCache.html';
30 | $templateCache.put(templateUrl, template);
31 | $templateRequest(templateUrl);
32 | $httpBackend.verifyNoOutstandingRequest();
33 | expect($templateCache.get(templateUrl)).toBe(template);
34 | });
35 |
36 | it('should make a web request if template is not found', function() {
37 | var templateUrl = 'testNotInTheCacheAtFirst.html';
38 | $httpBackend.expectGET(templateUrl).respond(template);
39 | $templateRequest(templateUrl).then(function(retrievedTemplate) {
40 | expect(retrievedTemplate).toBe(template);
41 | });
42 | $httpBackend.flush();
43 | });
44 |
45 | it('should not make an additional web request if template already loaded in cache', function() {
46 | var templateUrl = 'testRightIntoTheCache.html';
47 | $httpBackend.expectGET(templateUrl).respond(template);
48 | $templateRequest(templateUrl);
49 | $templateRequest(templateUrl).then(function(retrievedTemplate) {
50 | expect(retrievedTemplate).toBe(template);
51 | });
52 | $httpBackend.flush();
53 | $httpBackend.verifyNoOutstandingRequest();
54 | });
55 | });
56 |
--------------------------------------------------------------------------------
/demo/Gruntfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function(grunt) {
4 | require('load-grunt-tasks')(grunt);
5 | require('time-grunt')(grunt);
6 |
7 | var config = {
8 | app : 'app',
9 | dist : 'dist',
10 | tmp : '.tmp'
11 | };
12 | grunt.initConfig({
13 | yeoman : config,
14 | watch : {
15 | styles : {
16 | files : [ '<%= yeoman.app %>/styles/*.css' ],
17 | tasks : [ 'autoprefixer' ]
18 | },
19 | html : {
20 | files : [ '<%= yeoman.app %>/views/**/*.html' ],
21 | tasks : [ 'angularCombine:server' ]
22 | },
23 | livereload : {
24 | options : {
25 | livereload : '<%= connect.options.livereload %>'
26 | },
27 | files : [ '<%= yeoman.app %>/*.html', '<%= yeoman.tmp %>/views/*.html', '<%= yeoman.tmp %>/styles/*.css', '<%= yeoman.app %>/scripts/**/*.js',
28 | '<%= yeoman.app %>/images/{,*/}*.{png,jpg,jpeg,gif,webp,svg}' ]
29 | }
30 | },
31 | autoprefixer : {
32 | options : [ 'last 1 version' ],
33 | dist : {
34 | files : [ {
35 | expand : true,
36 | cwd : '<%= yeoman.app %>/styles/',
37 | src : '*.css',
38 | dest : '<%= yeoman.tmp %>/styles/'
39 | } ]
40 | }
41 | },
42 | connect : {
43 | options : {
44 | port : 9000,
45 | // Change this to '0.0.0.0' to access the server from outside.
46 | hostname : '0.0.0.0',
47 | livereload : 35729
48 | },
49 | livereload : {
50 | options : {
51 | open : true,
52 | middleware : function(connect, options) {
53 | var middlewares = [];
54 | var serveStatic = require('serve-static');
55 | middlewares.push(connect().use('/angular-combine/dist', serveStatic('../dist')));
56 | middlewares.push(serveStatic(config.tmp));
57 | middlewares.push(serveStatic(config.app));
58 | return middlewares;
59 | }
60 | }
61 | },
62 | },
63 | clean : {
64 | server : '<%= yeoman.tmp %>'
65 | },
66 | jshint : {
67 | options : {
68 | jshintrc : '.jshintrc'
69 | },
70 | all : [ 'Gruntfile.js', '<%= yeoman.app %>/scripts/{,*/}*.js' ]
71 | },
72 | angularCombine : {
73 | server : {
74 | files : [ {
75 | expand : true,
76 | cwd : '<%= yeoman.app %>',
77 | src : 'views/*',
78 | dest : '<%= yeoman.tmp %>/',
79 | filter : 'isDirectory'
80 | },{
81 | cwd : '<%= yeoman.app %>',
82 | src : 'scripts/components/*.html',
83 | dest : '<%= yeoman.tmp %>/views/components.html'
84 | },{
85 | cwd : '<%= yeoman.app %>',
86 | src : 'scripts/directives/*.html',
87 | dest : '<%= yeoman.tmp %>/views/directives.html'
88 | } ]
89 | }
90 | }
91 | });
92 |
93 | grunt.registerTask('server', function() {
94 | grunt.task.run([ 'clean', 'angularCombine', 'autoprefixer', 'connect', 'watch' ]);
95 | });
96 | };
97 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | /*
2 | * grunt-angular-combine
3 | * https://github.com/astik/grunt-angular-combine
4 | *
5 | * Copyright (c) 2013 Romain Gonord
6 | * Licensed under the MIT license.
7 | */
8 |
9 | 'use strict';
10 |
11 | module.exports = function(grunt) {
12 |
13 | require('load-grunt-tasks')(grunt);
14 | require('time-grunt')(grunt);
15 | var banner = '/*! <%= pkg.name %> - <%= grunt.template.today("yyyy-mm-dd") %> */\n';
16 |
17 | // Project configuration.
18 | grunt.initConfig({
19 | pkg : require('./bower.json'),
20 |
21 | jshint : {
22 | options : {
23 | jshintrc : '.jshintrc',
24 | },
25 | all : [ 'Gruntfile.js', 'src/*.js' ]
26 | },
27 |
28 | jscs: {
29 | options: {
30 | config: ".jscsrc"
31 | },
32 | all: {
33 | src: [ 'src/*.js' ]
34 | }
35 | },
36 |
37 | jsbeautifier: {
38 | options: {
39 | config: '.jsbeautifier'
40 | },
41 | all: [ 'src/*.js' ]
42 | },
43 |
44 | // Before generating any new files, remove any previously-created files.
45 | clean : {
46 | tests : [ 'tmp', 'dist' ],
47 | },
48 |
49 | ngAnnotate : {
50 | dist : {
51 | files : [ {
52 | expand : true,
53 | cwd : 'src',
54 | src : '*.js',
55 | dest : '.tmp'
56 | } ]
57 | }
58 | },
59 |
60 | concat : {
61 | options: {
62 | separator: ';\n',
63 | banner: '(function(angular){\n',
64 | footer: '\n}(angular));'
65 | },
66 | dist : {
67 | files : {
68 | 'dist/angular-combine.js' : [ '.tmp/angular-combine-app.js', '.tmp/angular-combine-config.js', '.tmp/angular-combine-decorator.js' ]
69 | }
70 | }
71 | },
72 |
73 | uglify : {
74 | min : {
75 | options : {
76 | mangle : true
77 | },
78 | expand : true,
79 | cwd : 'dist',
80 | src : '*.js',
81 | dest : 'dist',
82 | ext : '.min.js'
83 | }
84 | },
85 |
86 | release : {
87 | options : {
88 | tagName : 'v<%= version %>',
89 | additionalFiles: ['bower.json']
90 | }
91 | },
92 |
93 | removelogging : {
94 | dist : {
95 | src : 'dist/angular-combine.js',
96 | dest : 'dist/angular-combine-without-console.js'
97 | }
98 | },
99 |
100 | usebanner : {
101 | dist : {
102 | options : {
103 | position : 'top',
104 | banner : banner,
105 | linebreak : false
106 | },
107 | expand : true,
108 | cwd : 'dist',
109 | src : '*.js',
110 | dest : 'dist'
111 | }
112 | },
113 |
114 | jasmine : {
115 | test : {
116 | src : 'src/*.js',
117 | options : {
118 | specs : 'test/spec/*Spec.js',
119 | vendor : [ //
120 | "bower_components/angular/angular.js",//
121 | "bower_components/angular-mocks/angular-mocks.js" //
122 | ]
123 | }
124 | }
125 | },
126 |
127 | watch : {
128 | test : {
129 | files : [ 'src/*.js' ],
130 | tasks : [ 'jasmine' ]
131 | }
132 | },
133 | });
134 |
135 | grunt.registerTask('default', [ 'jasmine', 'clean', 'jsbeautifier', 'jshint', 'jscs', 'ngAnnotate', 'concat', 'removelogging', 'uglify', 'usebanner' ]);
136 | grunt.registerTask('test', [ 'jasmine', 'watch:test' ]);
137 | };
138 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # angular-combine
2 |
3 | [](https://travis-ci.org/astik/angular-combine)
4 |
5 | > Allow loading of merge templates into a single HTML file.
6 |
7 |
8 |
9 | ## Getting Started
10 |
11 | This plugin requires Bower
12 |
13 | If you haven't used [Bower](http://bower.io/) before, be sure to check out the [Getting Started](http://bower.io/#installing-bower) guide.
14 | Once you're familiar with that process, you may install this plugin with this command:
15 |
16 | ```shell
17 | bower install angular-combine --save
18 | ```
19 |
20 | Once the plugin has been installed, it may be enabled inside your application by adding the correpsonding module:
21 |
22 | ```js
23 | angular.module('myApp', ['angularCombine']);
24 | ```
25 |
26 | Then you need to configure a specific service to help Angular in finding the merged templates. When the templateCache is asked for a template it will use the regex in the first argument to determine if there is a combined file that can be loaded to gather that template. The second argument is the url/path to the combined template to load. Example Below:
27 |
28 | ```js
29 | angular.module('myApp').config(function (angularCombineConfigProvider) {
30 | angularCombineConfigProvider.addConf(/^views\/admin\//, 'views/admin.html');
31 | angularCombineConfigProvider.addConf(/^views\/otherSubFolder\//, 'views/otherSubFolderMergedTemplates.html');
32 | });
33 | ```
34 |
35 | You can add as many conf as you need.
36 |
37 |
38 | ## The "angularCombine" concept
39 |
40 |
41 |
42 | ### Theory
43 |
44 | Angular can load templates within an HTML by parsing script attribute with *text/ng-template* as type :
45 |
46 | ```html
47 |
50 |
53 | ```
54 |
55 | It allows us to use one.html or two.html as partials without having an extra HTTP call.
56 |
57 | So, it may be interesting to have a way to merge partials into a single HTML file that would be load once and give access to a bunch of partials.
58 |
59 | The difficult part then is to produce the merged filed.
60 |
61 | For the record, this plugin follows a Gist Vojta started a while ago : https://gist.github.com/vojtajina/3354046.
62 |
63 |
64 |
65 | ### Grunt to the rescue
66 |
67 | Chech this [Grunt](http://gruntjs.com/) task : [grunt-angular-combine](https://github.com/astik/grunt-angular-combine).
68 | This plugin was made especially for this need : producing the merged HTML file.
69 |
70 | You'll find all the documention to use it on the [grunt-angular-combine getting started](https://github.com/astik/grunt-angular-combine#getting-started) page.
71 |
72 |
73 |
74 | ## Release History
75 |
76 | - 0.1.0 : initial version
77 | - 0.1.1 : clean release process (no new feature)
78 | - v0.1.3 : release process is operational with good semserv versioning (no new feature)
79 | - v0.1.4 : distribution available without console (smaller files) + compatibility for Angular > 1.3.6
80 |
81 |
82 |
83 | ## Development
84 |
85 |
86 |
87 | ### How to release
88 |
89 | Before release, don't forget to do a full build !
90 |
91 | The project use [grunt-release](https://github.com/geddski/grunt-release) for its versionning an tag process.
92 |
93 |
94 | ### How to test
95 |
96 | Tests in realtime into CLI :
97 |
98 | ```
99 | grunt test
100 | ```
101 |
102 | Tests into your browser :
103 |
104 | ```
105 | grunt jasmine:test:build
106 | ```
107 |
108 | Then, open the newly create file _SpecRunner.html into your browser.
109 |
--------------------------------------------------------------------------------
/test/spec/basicCombineSpec.js:
--------------------------------------------------------------------------------
1 | describe('angularCombine behavior', function() {
2 |
3 | var $httpBackend, $templateRequest;
4 |
5 | var dependenciesInjection = function(_$httpBackend_, _$templateRequest_) {
6 | $httpBackend = _$httpBackend_;
7 | $templateRequest = _$templateRequest_;
8 | };
9 |
10 | var templates = [//
11 | 'content for template 1
', //
12 | 'content for template 2
', //
13 | 'content for template 3
', //
14 | ];
15 |
16 | afterEach(function() {
17 | $httpBackend.verifyNoOutstandingExpectation();
18 | $httpBackend.verifyNoOutstandingRequest();
19 | });
20 |
21 | describe('angularCombine behavior : without angularCombine configured', function() {
22 | beforeEach(function() {
23 | module('angularCombine');
24 | inject(dependenciesInjection);
25 | });
26 |
27 | it('should make as many requests as template needed', function() {
28 | // 3 template urls
29 | var template0Url = '/woot/dummy0.html';
30 | var template1Url = '/woot/dummy1.html';
31 | var template2Url = '/woot/dummy2.html';
32 | // 3 HTTP calls are expected
33 | $httpBackend.expectGET(template0Url).respond(templates[0]);
34 | $httpBackend.expectGET(template1Url).respond(templates[1]);
35 | $httpBackend.expectGET(template2Url).respond(templates[2]);
36 | // each http calls should deliver its own content
37 | $templateRequest(template0Url).then(function(retrievedTemplate) {
38 | expect(retrievedTemplate).toBe(templates[0]);
39 | });
40 | $templateRequest(template1Url).then(function(retrievedTemplate) {
41 | expect(retrievedTemplate).toBe(templates[1]);
42 | });
43 | $templateRequest(template2Url).then(function(retrievedTemplate) {
44 | expect(retrievedTemplate).toBe(templates[2]);
45 | });
46 | // trigger http calls
47 | $httpBackend.flush();
48 | // no more http calls are pending
49 | });
50 | });
51 |
52 | describe('angularCombine behavior : with angularCombine configured', function() {
53 | // let's build a dummy combined templates file
54 | var getDummmyTemplate = function(i) {
55 | return '';
56 | };
57 | var combinedTemplates = getDummmyTemplate(0) + getDummmyTemplate(1) + getDummmyTemplate(2);
58 | var combinedTemplatesUrl = '/combined/combinedTemplates.html';
59 |
60 | beforeEach(function() {
61 | // create a new module that will use angularCombine in order to be able to configure it
62 | var angularCombineModule = angular.module('testAngularCombine', ['angularCombine']);
63 | module('testAngularCombine');
64 | // provider configuration
65 | angularCombineModule.config(function(angularCombineConfigProvider) {
66 | angularCombineConfigProvider.addConf(/^\/woot\//, combinedTemplatesUrl);
67 | });
68 | inject(dependenciesInjection);
69 | });
70 |
71 | it('should load the combine template only once', function() {
72 | // 3 template urls
73 | var template0Url = '/woot/dummy0.html';
74 | var template1Url = '/woot/dummy1.html';
75 | var template2Url = '/woot/dummy2.html';
76 | // only 1 HTTP call is expected
77 | $httpBackend.expectGET(combinedTemplatesUrl).respond(combinedTemplates);
78 | // the one and only HTTP call should deliver content for the 3 templates
79 | $templateRequest(template0Url).then(function(retrievedTemplate) {
80 | expect(retrievedTemplate).toBe(templates[0]);
81 | });
82 | $templateRequest(template1Url).then(function(retrievedTemplate) {
83 | expect(retrievedTemplate).toBe(templates[1]);
84 | });
85 | $templateRequest(template2Url).then(function(retrievedTemplate) {
86 | expect(retrievedTemplate).toBe(templates[2]);
87 | });
88 | // trigger http calls
89 | $httpBackend.flush();
90 | // no more http calls are pending
91 | });
92 |
93 | it('should return undefined for missing templates into the combine template', function() {
94 | var template3Url = '/woot/dummy3.html';
95 | $httpBackend.expectGET(combinedTemplatesUrl).respond(combinedTemplates);
96 | $templateRequest(template3Url).then(function(retrievedTemplate) {
97 | expect(retrievedTemplate).toBe(undefined);
98 | });
99 | $httpBackend.flush();
100 | });
101 | });
102 | });
103 |
--------------------------------------------------------------------------------