├── .gitignore ├── .travis.yml ├── LICENSE.md ├── README.md ├── index.js ├── package.json └── tests ├── dummy.css ├── dummy.html ├── dummy.js ├── test-runner.js └── tests.js /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | node_modules 3 | .DS_Store 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | 3 | node_js: 4 | - "0.10" 5 | 6 | notifications: 7 | email: false -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | ### The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Bustle Labs. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all 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, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ember-cli-inline-content 2 | [![Build Status](https://travis-ci.org/gdub22/ember-cli-inline-content.svg?branch=master)](https://travis-ci.org/gdub22/ember-cli-inline-content) 3 | [![Ember Observer Score](https://emberobserver.com/badges/ember-cli-inline-content.svg)](https://emberobserver.com/addons/ember-cli-inline-content) 4 | 5 | An ember-cli add-on to render inline scripts, styles, or any content directly into your index.html file. 6 | 7 | ## Install 8 | ``` 9 | npm install --save-dev ember-cli-inline-content 10 | ``` 11 | 12 | ## Usage 13 | 14 | In your app's **ember-cli-build.js**, define inlineContent options on your app instance 15 | 16 | ```js 17 | var app = new EmberApp(defaults, { 18 | inlineContent: { 19 | 'key1' : 'filepath1.js', 20 | 'key2' : 'filepath2.css', 21 | 'key3' : { 22 | file: 'filepath3.js', 23 | attrs: { 'data-foo' : 'bar' } 24 | }, 25 | 'key4' : { 26 | content: 'foo' 27 | } 28 | } 29 | }); 30 | ``` 31 | 32 | Then in your **index.html** file, use the `content-for` helper with a references to the keys in your options: 33 | 34 | ```hbs 35 | {{content-for 'key1'}} 36 | {{content-for 'key2'}} 37 | {{content-for 'key3'}} 38 | {{content-for 'key4'}} 39 | ``` 40 | 41 | During the build process, this will render the contents of those files directly inline with ` 106 | ``` 107 | 108 | #### Post processing: 109 | ember-cli-build.js: 110 | ```js 111 | var env = process.env.EMBER_ENV; 112 | var config = require('./config/environment')(env); 113 | 114 | var app = new EmberApp(defaults, { 115 | inlineContent: { 116 | 'google-analytics' : { 117 | file: './ga.js', 118 | postProcess: function(content) { 119 | return content.replace(/\{\{GOOGLE_ANALYTICS_ID\}\}/g, config.googleAnalyticsId); 120 | } 121 | } 122 | } 123 | }); 124 | ``` 125 | 126 | environment.js 127 | ```js 128 | ENV.googleAnalyticsId = environment === 'production' ? 'UA-XXXXXXXX-1' : 'UA-XXXXXXXX-2'; 129 | ``` 130 | 131 | ga.js: 132 | ```js 133 | (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){ 134 | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o), 135 | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m) 136 | })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); 137 | 138 | ga('create', '{{GOOGLE_ANALYTICS_ID}}', 'auto'); 139 | ``` 140 | 141 | index.html: 142 | ```hbs 143 | {{content-for 'google-analytics'}} 144 | ``` 145 | 146 | Output: 147 | ```html 148 | 155 | ``` 156 | 157 | #### Explicitly enable/disable: 158 | ember-cli-build.js: 159 | ```js 160 | var app = new EmberApp(defaults, { 161 | inlineContent: { 162 | 'analytics' : { 163 | file: './analytics.js', 164 | enabled: process.env.EMBER_ENV === 'production' 165 | } 166 | } 167 | }); 168 | ``` 169 | 170 | 171 | ## Why? 172 | - You want some code to start executing before your whole app downloads 173 | - You don't want that code to require a separate request 174 | - `' ); 34 | }); 35 | 36 | test('can renderer css file', function() { 37 | var renderer = new InlineContentRenderer(defaultProject); 38 | var app = Object.create(defaultApp); 39 | app.options.inlineContent = { 40 | dummyCss: './tests/dummy.css' 41 | }; 42 | 43 | renderer.included(app); 44 | var content = renderer.contentFor('dummyCss'); 45 | var file = fs.readFileSync(path.join(renderer.project.root, app.options.inlineContent.dummyCss), 'utf8'); 46 | 47 | equal( content, '' ); 48 | }); 49 | 50 | test('can renderer other utf8 files', function() { 51 | var renderer = new InlineContentRenderer(defaultProject); 52 | var app = Object.create(defaultApp); 53 | app.options.inlineContent = { 54 | dummyHtml: './tests/dummy.html' 55 | }; 56 | 57 | renderer.included(app); 58 | var content = renderer.contentFor('dummyHtml'); 59 | var file = fs.readFileSync(path.join(renderer.project.root, app.options.inlineContent.dummyHtml), 'utf8'); 60 | 61 | equal( content, file ); 62 | }); 63 | 64 | test('can renderer content directly', function() { 65 | var renderer = new InlineContentRenderer(defaultProject); 66 | var app = Object.create(defaultApp); 67 | app.options.inlineContent = { 68 | dummyContent: { 69 | content: 'foo' 70 | } 71 | }; 72 | 73 | renderer.included(app); 74 | var content = renderer.contentFor('dummyContent'); 75 | 76 | equal( content, 'foo' ); 77 | }); 78 | 79 | test('can renderer empty string', function() { 80 | var renderer = new InlineContentRenderer(defaultProject); 81 | var app = Object.create(defaultApp); 82 | app.options.inlineContent = { 83 | dummyContent: { 84 | content: '' 85 | } 86 | }; 87 | 88 | renderer.included(app); 89 | var content = renderer.contentFor('dummyContent'); 90 | 91 | equal( content, '' ); 92 | }); 93 | 94 | test('content supersedes file', function() { 95 | var renderer = new InlineContentRenderer(defaultProject); 96 | var app = Object.create(defaultApp); 97 | app.options.inlineContent = { 98 | dummyContent: { 99 | content: 'foo', 100 | file: './tests/dummy.js' 101 | } 102 | }; 103 | 104 | renderer.included(app); 105 | var content = renderer.contentFor('dummyContent'); 106 | 107 | equal( content, 'foo' ); 108 | }); 109 | 110 | test('can render attributes', function() { 111 | var renderer = new InlineContentRenderer(defaultProject); 112 | var app = Object.create(defaultApp); 113 | app.options.inlineContent = { 114 | dummyJs: { 115 | file: './tests/dummy.js', 116 | attrs: { 'data-foo' : 'bar', 'data-baz' : false } 117 | } 118 | }; 119 | 120 | renderer.included(app); 121 | var content = renderer.contentFor('dummyJs'); 122 | var file = fs.readFileSync(path.join(renderer.project.root, app.options.inlineContent.dummyJs.file), 'utf8'); 123 | 124 | equal( content, '' ); 125 | }); 126 | 127 | test('postProcess hook', function() { 128 | var renderer = new InlineContentRenderer(defaultProject); 129 | var app = Object.create(defaultApp); 130 | app.options.inlineContent = { 131 | dummyJs: { 132 | file: './tests/dummy.js', 133 | postProcess: function(content) { 134 | return content + 'console.log(1);'; 135 | } 136 | } 137 | }; 138 | 139 | renderer.included(app); 140 | var content = renderer.contentFor('dummyJs'); 141 | var file = fs.readFileSync(path.join(renderer.project.root, app.options.inlineContent.dummyJs.file), 'utf8'); 142 | 143 | equal( content, '' ); 144 | }); 145 | 146 | test('can explictly enable/disable via option', function() { 147 | var renderer = new InlineContentRenderer(defaultProject); 148 | var app = Object.create(defaultApp); 149 | app.options.inlineContent = { 150 | dummyJs: { 151 | enabled: false, 152 | file: './tests/dummy.js' 153 | } 154 | }; 155 | 156 | renderer.included(app); 157 | var content = renderer.contentFor('dummyJs'); 158 | equal( content, undefined ); 159 | 160 | app.options.inlineContent.dummyJs.enabled = true; 161 | renderer.included(app); 162 | var content = renderer.contentFor('dummyJs'); 163 | var file = fs.readFileSync(path.join(renderer.project.root, app.options.inlineContent.dummyJs.file), 'utf8'); 164 | equal( content, '' ); 165 | }); 166 | --------------------------------------------------------------------------------