` tag with a given code snippet: 128 | 129 | ```hbs 130 | {{#let (get-code-snippet "static.hbs") as |snippet|}} 131 |{{snippet.source}}132 | {{/let}} 133 | ``` 134 | 135 | ### Syntax Highlighting 136 | 137 | This addon does not provide any syntax highlighting capabilities itself, but instead it is designed with composability 138 | in mind, so you can add highlighting capabilities with any highlighting library on top of the snippet extraction 139 | primitives of this addon. The following is an example of rendering a code snippet using code highlighting provided by the 140 | [ember-prism](https://github.com/shipshapecode/ember-prism) addon: 141 | 142 | ```hbs 143 | {{#let (get-code-snippet "demo.hbs") as |snippet|}} 144 |145 | {{snippet.source}} 146 | 147 | {{/let}} 148 | ``` 149 | 150 | If you want to show multiple snippets, it makes sense to extract that template code into a reusable component. In fact 151 | previous versions of `ember-code-snippet` shipped a `code-snippet` component, that you can replace now with the new 152 | helper and your highlighting library of choice. The following template-only component could replace the previously 153 | available component ``, again using `ember-prism` in this case: 154 | 155 | ```hbs 156 | {{!-- templates/components/code-snippet.hbs --}} 157 | {{#let (get-code-snippet @name) as |snippet|}} 158 | 159 | {{snippet.source}} 160 | 161 | {{/let}} 162 | ``` 163 | 164 | ### JavaScript usage 165 | 166 | When you want to use the code snippet functionality from JavaScript, you can import the `getCodeSnippet` function like 167 | this: 168 | 169 | ```js 170 | import { getCodeSnippet } from 'ember-code-snippet'; 171 | ``` 172 | 173 | Its call signature is similar to the helper invocation: `getCodeSnippet(name, unindent = true)`, and it returns the same 174 | POJO as described above. 175 | 176 | 177 | Contributing 178 | ------------------------------------------------------------------------------ 179 | 180 | See the [Contributing](CONTRIBUTING.md) guide for details. 181 | 182 | 183 | License 184 | ------------------------------------------------------------------------------ 185 | 186 | This project is licensed under the [MIT License](LICENSE.md). 187 | -------------------------------------------------------------------------------- /addon/-private/extension.js: -------------------------------------------------------------------------------- 1 | export default function getExtension(name) { 2 | let m = /\.(\w+)$/i.exec(name); 3 | return m ? m[1].toLowerCase() : undefined; 4 | } 5 | -------------------------------------------------------------------------------- /addon/-private/get-snippet.js: -------------------------------------------------------------------------------- 1 | import snippets from 'ember-code-snippet/snippets'; 2 | import getLanguage from './language'; 3 | import getExtension from './extension'; 4 | import unindentSource from '../-private/unindent'; 5 | import { assert } from '@ember/debug'; 6 | 7 | export default function getSnippet(name, unindent = true) { 8 | let source = name 9 | .split('/') 10 | .reduce((dir, name) => dir && dir[name], snippets); 11 | assert(`Code snippet with name "${name}" not found.`, source); 12 | 13 | source = source 14 | .replace(/^(\s*\n)*/, '') 15 | .replace(/\s*$/, ''); 16 | 17 | if (unindent) { 18 | source = unindentSource(source); 19 | } 20 | 21 | let language = getLanguage(name); 22 | let extension = getExtension(name); 23 | 24 | return { 25 | source, 26 | language, 27 | extension 28 | }; 29 | } -------------------------------------------------------------------------------- /addon/-private/language.js: -------------------------------------------------------------------------------- 1 | import getExtension from './extension'; 2 | 3 | export default function getLanguage(name) { 4 | let ext = getExtension(name); 5 | if (ext) { 6 | switch (ext) { 7 | case 'js': 8 | return 'javascript'; 9 | case 'coffee': 10 | return 'coffeescript'; 11 | case 'hbs': 12 | return 'handlebars'; 13 | case 'css': 14 | return 'css'; 15 | case 'scss': 16 | return 'scss'; 17 | case 'less': 18 | return 'less'; 19 | case 'emblem': 20 | return 'emblem'; 21 | case 'ts': 22 | return 'typescript'; 23 | default: 24 | return ext; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /addon/-private/unindent.js: -------------------------------------------------------------------------------- 1 | export default function unindent(src) { 2 | let match, min, lines = src.split("\n").filter(l => l !== ''); 3 | for (let i = 0; i < lines.length; i++) { 4 | match = /^[ \t]*/.exec(lines[i]); 5 | if (match && (typeof min === 'undefined' || min > match[0].length)) { 6 | min = match[0].length; 7 | } 8 | } 9 | if (typeof min !== 'undefined' && min > 0) { 10 | src = src.replace(new RegExp("^[ \t]{" + min + "}", 'gm'), ""); 11 | } 12 | return src; 13 | } 14 | -------------------------------------------------------------------------------- /addon/helpers/get-code-snippet.js: -------------------------------------------------------------------------------- 1 | import { helper } from '@ember/component/helper'; 2 | import { getCodeSnippet } from 'ember-code-snippet'; 3 | 4 | export default helper(function([name], { unindent = true }) { 5 | return getCodeSnippet(name, unindent); 6 | }); 7 | -------------------------------------------------------------------------------- /addon/index.js: -------------------------------------------------------------------------------- 1 | import getCodeSnippet from './-private/get-snippet'; 2 | 3 | export { 4 | getCodeSnippet 5 | }; 6 | -------------------------------------------------------------------------------- /app/helpers/get-code-snippet.js: -------------------------------------------------------------------------------- 1 | export { default } from 'ember-code-snippet/helpers/get-code-snippet'; 2 | -------------------------------------------------------------------------------- /config/ember-try.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const getChannelURL = require('ember-source-channel-url'); 4 | 5 | module.exports = function() { 6 | return Promise.all([ 7 | getChannelURL('release'), 8 | getChannelURL('beta'), 9 | getChannelURL('canary') 10 | ]).then((urls) => { 11 | return { 12 | useYarn: true, 13 | scenarios: [ 14 | { 15 | name: 'ember-lts-2.18', 16 | env: { 17 | EMBER_OPTIONAL_FEATURES: JSON.stringify({ 'jquery-integration': true }) 18 | }, 19 | npm: { 20 | devDependencies: { 21 | '@ember/jquery': '^0.5.1', 22 | 'ember-source': '~2.18.0' 23 | } 24 | } 25 | }, 26 | { 27 | name: 'ember-lts-3.4', 28 | npm: { 29 | devDependencies: { 30 | 'ember-source': '~3.4.0' 31 | } 32 | } 33 | }, 34 | { 35 | name: 'ember-release', 36 | npm: { 37 | devDependencies: { 38 | 'ember-source': urls[0] 39 | } 40 | } 41 | }, 42 | { 43 | name: 'ember-beta', 44 | npm: { 45 | devDependencies: { 46 | 'ember-source': urls[1] 47 | } 48 | } 49 | }, 50 | { 51 | name: 'ember-canary', 52 | npm: { 53 | devDependencies: { 54 | 'ember-source': urls[2] 55 | } 56 | } 57 | }, 58 | // The default `.travis.yml` runs this scenario via `yarn test`, 59 | // not via `ember try`. It's still included here so that running 60 | // `ember try:each` manually or from a customized CI config will run it 61 | // along with all the other scenarios. 62 | { 63 | name: 'ember-default', 64 | npm: { 65 | devDependencies: {} 66 | } 67 | }, 68 | { 69 | name: 'ember-default-with-jquery', 70 | env: { 71 | EMBER_OPTIONAL_FEATURES: JSON.stringify({ 72 | 'jquery-integration': true 73 | }) 74 | }, 75 | npm: { 76 | devDependencies: { 77 | '@ember/jquery': '^0.5.1' 78 | } 79 | } 80 | } 81 | ] 82 | }; 83 | }); 84 | }; 85 | -------------------------------------------------------------------------------- /config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(/* environment, appConfig */) { 4 | return { }; 5 | }; 6 | -------------------------------------------------------------------------------- /ember-cli-build.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const EmberAddon = require('ember-cli/lib/broccoli/ember-addon'); 4 | 5 | module.exports = function(defaults) { 6 | let app = new EmberAddon(defaults, { 7 | snippetSearchPaths: ['tests/integration', 'tests/dummy'], 8 | 'ember-prism': { 9 | 'components': ['markup-templating', 'handlebars', 'javascript'], 10 | 'plugins': ['line-highlight'] 11 | } 12 | }); 13 | 14 | /* 15 | This build file specifies the options for the dummy test app of this 16 | addon, located in `/tests/dummy` 17 | This build file does *not* influence how the addon or the app using it 18 | behave. You most likely want to be modifying `./index.js` or app's build file 19 | */ 20 | 21 | return app.toTree(); 22 | }; 23 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const fs = require('fs'); 4 | const mergeTrees = require('broccoli-merge-trees'); 5 | const flatiron = require('broccoli-flatiron'); 6 | const snippetFinder = require('./snippet-finder'); 7 | const findHost = require('./utils/findHost'); 8 | 9 | module.exports = { 10 | name: require('./package').name, 11 | 12 | snippetPaths() { 13 | let app = findHost(this); 14 | return app.options.snippetPaths || ['snippets']; 15 | }, 16 | 17 | snippetSearchPaths(){ 18 | let app = findHost(this); 19 | return app.options.snippetSearchPaths || ['app']; 20 | }, 21 | 22 | snippetRegexes() { 23 | let app = findHost(this); 24 | return [{ 25 | begin: /\bBEGIN-SNIPPET\s+(\S+)\b/, 26 | end: /\bEND-SNIPPET\b/ 27 | }].concat(app.options.snippetRegexes || []); 28 | }, 29 | 30 | snippetExtensions() { 31 | let app = findHost(this); 32 | return app.options.snippetExtensions || ['js','ts','gjs','gts','coffee','html','hbs','md','css','sass','scss','less','emblem','yaml']; 33 | }, 34 | 35 | includeExtensions() { 36 | let app = findHost(this); 37 | return app.options.includeFileExtensionInSnippetNames !== false; 38 | }, 39 | 40 | treeForAddon(tree) { 41 | let snippets = mergeTrees(this.snippetPaths().filter(function(path){ 42 | return fs.existsSync(path); 43 | })); 44 | 45 | let snippetOptions = { 46 | snippetRegexes: this.snippetRegexes(), 47 | includeExtensions: this.includeExtensions(), 48 | snippetExtensions: this.snippetExtensions() 49 | }; 50 | 51 | snippets = mergeTrees(this.snippetSearchPaths().map(function(path){ 52 | return snippetFinder(path, snippetOptions); 53 | }).concat(snippets)); 54 | 55 | snippets = flatiron(snippets, { 56 | outputFile: 'snippets.js' 57 | }); 58 | 59 | return this._super.treeForAddon.call(this, mergeTrees([tree, snippets])); 60 | } 61 | }; 62 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ember-code-snippet", 3 | "version": "3.0.0", 4 | "description": "Ember component for embedding syntax-highlighted code samples.", 5 | "main": "index.js", 6 | "author": "Edward Faulkner", 7 | "license": "MIT", 8 | "repository": "https://github.com/ef4/ember-code-snippet", 9 | "keywords": [ 10 | "ember-addon" 11 | ], 12 | "directories": { 13 | "doc": "doc", 14 | "test": "tests" 15 | }, 16 | "scripts": { 17 | "build": "ember build", 18 | "lint:hbs": "ember-template-lint .", 19 | "lint:js": "eslint .", 20 | "start": "ember serve", 21 | "test": "ember test", 22 | "test:all": "ember try:each" 23 | }, 24 | "dependencies": { 25 | "broccoli-flatiron": "^0.1.3", 26 | "broccoli-merge-trees": "^1.0.0", 27 | "broccoli-plugin": "^1.3.1", 28 | "ember-cli-babel": "^7.7.3", 29 | "ember-cli-htmlbars": "^3.0.1", 30 | "es6-promise": "^1.0.0", 31 | "glob": "^7.1.3" 32 | }, 33 | "devDependencies": { 34 | "@ember/optional-features": "^0.7.0", 35 | "broccoli-asset-rev": "^3.0.0", 36 | "ember-cli": "~3.10.0", 37 | "ember-cli-dependency-checker": "^3.1.0", 38 | "ember-cli-eslint": "^5.1.0", 39 | "ember-cli-htmlbars-inline-precompile": "^2.1.0", 40 | "ember-cli-inject-live-reload": "^1.8.2", 41 | "ember-cli-sri": "^2.1.1", 42 | "ember-cli-template-lint": "^1.0.0-beta.1", 43 | "ember-cli-uglify": "^2.1.0", 44 | "ember-disable-prototype-extensions": "^1.1.3", 45 | "ember-export-application-global": "^2.0.0", 46 | "ember-load-initializers": "^2.0.0", 47 | "ember-maybe-import-regenerator": "^0.1.6", 48 | "ember-prism": "^0.4.0", 49 | "ember-qunit": "^4.4.1", 50 | "ember-resolver": "^5.0.1", 51 | "ember-source": "~3.10.0", 52 | "ember-source-channel-url": "^1.1.0", 53 | "ember-try": "^1.0.0", 54 | "eslint-plugin-ember": "^6.2.0", 55 | "eslint-plugin-node": "^8.0.1", 56 | "loader.js": "^4.7.0", 57 | "qunit-dom": "^0.8.4" 58 | }, 59 | "engines": { 60 | "node": "8.* || >= 10.*" 61 | }, 62 | "ember-addon": { 63 | "configPath": "tests/dummy/config" 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /snippet-finder.js: -------------------------------------------------------------------------------- 1 | /* use strict */ 2 | 3 | const Plugin = require('broccoli-plugin'); 4 | const glob = require('glob'); 5 | const _Promise = require('es6-promise').Promise; 6 | const fs = require('fs'); 7 | const path = require('path'); 8 | 9 | 10 | function findFiles(srcDir, options) { 11 | let fileNamePattern = `**/*.+(${options.snippetExtensions.join('|')})`; 12 | return new _Promise(function(resolve, reject) { 13 | glob(path.join(srcDir, fileNamePattern), function (err, files) { 14 | if (err) { 15 | reject(err); 16 | } else { 17 | resolve(files); 18 | } 19 | }); 20 | }); 21 | } 22 | 23 | function extractSnippets(fileContent, regexes) { 24 | let stack = []; 25 | let output = {}; 26 | fileContent.split("\n").forEach(function(line){ 27 | let top = stack[stack.length - 1]; 28 | if (top && top.regex.end.test(line)) { 29 | output[top.name] = top.content.join("\n"); 30 | stack.pop(); 31 | } 32 | 33 | stack.forEach(function(snippet) { 34 | snippet.content.push(line); 35 | }); 36 | 37 | let match; 38 | let regex = regexes.find(function(regex) { 39 | return match = regex.begin.exec(line); 40 | }); 41 | 42 | if (match) { 43 | stack.push({ 44 | regex: regex, 45 | name: match[1], 46 | content: [] 47 | }); 48 | } 49 | }); 50 | return output; 51 | } 52 | 53 | function writeSnippets(files, outputPath, options) { 54 | files.forEach((filename) => { 55 | let regexes = options.snippetRegexes; 56 | let snippets = extractSnippets(fs.readFileSync(filename, 'utf-8'), regexes); 57 | for (let name in snippets) { 58 | let destFile = path.join(outputPath, name); 59 | let includeExtensions = options.includeExtensions; 60 | if (includeExtensions) { 61 | destFile += path.extname(filename); 62 | } 63 | fs.writeFileSync(destFile, snippets[name]); 64 | } 65 | }); 66 | } 67 | 68 | function SnippetFinder(inputNode, options) { 69 | if (!(this instanceof SnippetFinder)) { 70 | return new SnippetFinder(inputNode, options); 71 | } 72 | 73 | Plugin.call(this, [inputNode], { 74 | name: 'SnippetFinder', 75 | annotation: `SnippetFinder output: ${options.outputFile}`, 76 | persistentOutput: options.persistentOutput, 77 | needCache: options.needCache, 78 | }); 79 | 80 | this.options = options; 81 | } 82 | 83 | SnippetFinder.prototype = Object.create(Plugin.prototype); 84 | SnippetFinder.prototype.constructor = SnippetFinder; 85 | 86 | SnippetFinder.prototype.build = function() { 87 | return findFiles(this.inputPaths[0], this.options).then((files) => { 88 | writeSnippets(files, this.outputPath, this.options); 89 | }); 90 | }; 91 | 92 | module.exports = SnippetFinder; 93 | -------------------------------------------------------------------------------- /testem.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | test_page: 'tests/index.html?hidepassed', 3 | disable_watching: true, 4 | launch_in_ci: [ 5 | 'Chrome' 6 | ], 7 | launch_in_dev: [ 8 | 'Chrome' 9 | ], 10 | browser_args: { 11 | Chrome: { 12 | ci: [ 13 | // --no-sandbox is needed when running Chrome inside a container 14 | process.env.CI ? '--no-sandbox' : null, 15 | '--headless', 16 | '--disable-gpu', 17 | '--disable-dev-shm-usage', 18 | '--disable-software-rasterizer', 19 | '--mute-audio', 20 | '--remote-debugging-port=0', 21 | '--window-size=1440,900' 22 | ].filter(Boolean) 23 | } 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /tests/dummy/app/app.js: -------------------------------------------------------------------------------- 1 | import Application from '@ember/application'; 2 | import Resolver from './resolver'; 3 | import loadInitializers from 'ember-load-initializers'; 4 | import config from './config/environment'; 5 | 6 | const App = Application.extend({ 7 | modulePrefix: config.modulePrefix, 8 | podModulePrefix: config.podModulePrefix, 9 | Resolver 10 | }); 11 | 12 | loadInitializers(App, config.modulePrefix); 13 | 14 | export default App; 15 | -------------------------------------------------------------------------------- /tests/dummy/app/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ef4/ember-code-snippet/f4a52132d91563bb6e85d659ad0bfba384733535/tests/dummy/app/components/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/controllers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ef4/ember-code-snippet/f4a52132d91563bb6e85d659ad0bfba384733535/tests/dummy/app/controllers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/controllers/application.js: -------------------------------------------------------------------------------- 1 | import Controller from '@ember/controller'; 2 | 3 | export default Controller.extend({ 4 | inputType: 'text' 5 | }); 6 | -------------------------------------------------------------------------------- /tests/dummy/app/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ef4/ember-code-snippet/f4a52132d91563bb6e85d659ad0bfba384733535/tests/dummy/app/helpers/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Dummy 7 | 8 | 9 | 10 | {{content-for "head"}} 11 | 12 | 13 | 14 | 15 | {{content-for "head-footer"}} 16 | 17 | 18 | {{content-for "body"}} 19 | 20 | 21 | 22 | 23 | {{content-for "body-footer"}} 24 | 25 | 26 | -------------------------------------------------------------------------------- /tests/dummy/app/models/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ef4/ember-code-snippet/f4a52132d91563bb6e85d659ad0bfba384733535/tests/dummy/app/models/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/resolver.js: -------------------------------------------------------------------------------- 1 | import Resolver from 'ember-resolver'; 2 | 3 | export default Resolver; 4 | -------------------------------------------------------------------------------- /tests/dummy/app/router.js: -------------------------------------------------------------------------------- 1 | import EmberRouter from '@ember/routing/router'; 2 | import config from './config/environment'; 3 | 4 | const Router = EmberRouter.extend({ 5 | location: config.locationType, 6 | rootURL: config.rootURL 7 | }); 8 | 9 | Router.map(function() { 10 | }); 11 | 12 | export default Router; 13 | -------------------------------------------------------------------------------- /tests/dummy/app/routes/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ef4/ember-code-snippet/f4a52132d91563bb6e85d659ad0bfba384733535/tests/dummy/app/routes/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/app/styles/app.css: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ef4/ember-code-snippet/f4a52132d91563bb6e85d659ad0bfba384733535/tests/dummy/app/styles/app.css -------------------------------------------------------------------------------- /tests/dummy/app/templates/application.hbs: -------------------------------------------------------------------------------- 1 |Welcome to ember-code-snippet
2 | 3 |Static snippet
4 | 5 | 6 |I am a handlebars template!
7 |The value is: {{val}}
8 |9 | {{input value=val}} 10 |11 | 12 | 13 |Plain:
14 | 15 | {{#let (get-code-snippet "static.hbs") as |snippet|}} 16 |{{snippet.source}}17 | {{/let}} 18 | 19 |Prism.js
20 | 21 | {{#code-block language="handlebars"}}{{get (get-code-snippet "static.hbs") "source"}}{{/code-block}} 22 | -------------------------------------------------------------------------------- /tests/dummy/app/templates/components/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ef4/ember-code-snippet/f4a52132d91563bb6e85d659ad0bfba384733535/tests/dummy/app/templates/components/.gitkeep -------------------------------------------------------------------------------- /tests/dummy/config/environment.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | module.exports = function(environment) { 4 | let ENV = { 5 | modulePrefix: 'dummy', 6 | environment, 7 | rootURL: '/', 8 | locationType: 'auto', 9 | EmberENV: { 10 | FEATURES: { 11 | // Here you can enable experimental features on an ember canary build 12 | // e.g. EMBER_NATIVE_DECORATOR_SUPPORT: true 13 | }, 14 | EXTEND_PROTOTYPES: { 15 | // Prevent Ember Data from overriding Date.parse. 16 | Date: false 17 | } 18 | }, 19 | 20 | APP: { 21 | // Here you can pass flags/options to your application instance 22 | // when it is created 23 | } 24 | }; 25 | 26 | if (environment === 'development') { 27 | // ENV.APP.LOG_RESOLVER = true; 28 | // ENV.APP.LOG_ACTIVE_GENERATION = true; 29 | // ENV.APP.LOG_TRANSITIONS = true; 30 | // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; 31 | // ENV.APP.LOG_VIEW_LOOKUPS = true; 32 | } 33 | 34 | if (environment === 'test') { 35 | // Testem prefers this... 36 | ENV.locationType = 'none'; 37 | 38 | // keep test console output quieter 39 | ENV.APP.LOG_ACTIVE_GENERATION = false; 40 | ENV.APP.LOG_VIEW_LOOKUPS = false; 41 | 42 | ENV.APP.rootElement = '#ember-testing'; 43 | ENV.APP.autoboot = false; 44 | } 45 | 46 | if (environment === 'production') { 47 | // here you can enable a production-specific feature 48 | } 49 | 50 | return ENV; 51 | }; 52 | -------------------------------------------------------------------------------- /tests/dummy/config/optional-features.json: -------------------------------------------------------------------------------- 1 | { 2 | "jquery-integration": false 3 | } 4 | -------------------------------------------------------------------------------- /tests/dummy/config/targets.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const browsers = [ 4 | 'last 1 Chrome versions', 5 | 'last 1 Firefox versions', 6 | 'last 1 Safari versions' 7 | ]; 8 | 9 | const isCI = !!process.env.CI; 10 | const isProduction = process.env.EMBER_ENV === 'production'; 11 | 12 | if (isCI || isProduction) { 13 | browsers.push('ie 11'); 14 | } 15 | 16 | module.exports = { 17 | browsers 18 | }; 19 | -------------------------------------------------------------------------------- /tests/dummy/public/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /tests/helpers/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ef4/ember-code-snippet/f4a52132d91563bb6e85d659ad0bfba384733535/tests/helpers/.gitkeep -------------------------------------------------------------------------------- /tests/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |Dummy Tests 7 | 8 | 9 | 10 | {{content-for "head"}} 11 | {{content-for "test-head"}} 12 | 13 | 14 | 15 | 16 | 17 | {{content-for "head-footer"}} 18 | {{content-for "test-head-footer"}} 19 | 20 | 21 | {{content-for "body"}} 22 | {{content-for "test-body"}} 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | {{content-for "body-footer"}} 31 | {{content-for "test-body-footer"}} 32 | 33 | 34 | -------------------------------------------------------------------------------- /tests/integration/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ef4/ember-code-snippet/f4a52132d91563bb6e85d659ad0bfba384733535/tests/integration/.gitkeep -------------------------------------------------------------------------------- /tests/integration/helpers/get-code-snippet-test.js: -------------------------------------------------------------------------------- 1 | import { module, test } from 'qunit'; 2 | import { setupRenderingTest } from 'ember-qunit'; 3 | import { render } from '@ember/test-helpers'; 4 | import hbs from 'htmlbars-inline-precompile'; 5 | 6 | module('Integration | Helper | get-code-snippet', function(hooks) { 7 | setupRenderingTest(hooks); 8 | 9 | test('it returns snippet', async function(assert) { 10 | await render(hbs` 11 | // BEGIN-SNIPPET render-test 12 | function sample(){ 13 | return 42; 14 | }; 15 | // END-SNIPPET 16 | 17 | {{#with (get-code-snippet "render-test.js") as |snippet|}} 18 |19 |{{snippet.source}}
{{snippet.language}}20 |{{snippet.extension}}21 | {{/with}} 22 | `); 23 | 24 | assert.strictEqual( 25 | this.element.querySelector('#source').textContent, 26 | 'function sample(){\n return 42;\n};' 27 | ); 28 | assert.dom('#language').hasText('javascript'); // language is determined by file extension, so JS in this case 29 | assert.dom('#extension').hasText('js'); 30 | }); 31 | 32 | test('it returns snippet w/ indented source', async function(assert) { 33 | await render(hbs` 34 | // BEGIN-SNIPPET render-test 35 | function sample(){ 36 | return 42; 37 | }; 38 | // END-SNIPPET 39 | 40 | {{#with (get-code-snippet "render-test.js" unindent=false) as |snippet|}} 41 |42 |{{snippet.source}}
{{snippet.language}}43 |{{snippet.extension}}44 | {{/with}} 45 | `); 46 | 47 | assert.strictEqual( 48 | this.element.querySelector('#source').textContent, 49 | ' function sample(){\n return 42;\n };' 50 | ); 51 | assert.dom('#language').hasText('javascript'); // language is determined by file extension, so JS in this case 52 | assert.dom('#extension').hasText('js'); 53 | }); 54 | }); 55 | -------------------------------------------------------------------------------- /tests/test-helper.js: -------------------------------------------------------------------------------- 1 | import Application from '../app'; 2 | import config from '../config/environment'; 3 | import { setApplication } from '@ember/test-helpers'; 4 | import { start } from 'ember-qunit'; 5 | 6 | setApplication(Application.create(config.APP)); 7 | 8 | start(); 9 | -------------------------------------------------------------------------------- /tests/unit/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ef4/ember-code-snippet/f4a52132d91563bb6e85d659ad0bfba384733535/tests/unit/.gitkeep -------------------------------------------------------------------------------- /tests/unit/get-code-snippet-test.js: -------------------------------------------------------------------------------- 1 | import { module, test } from 'qunit'; 2 | import { getCodeSnippet } from 'ember-code-snippet'; 3 | 4 | module('Unit | getCodeSnippet', function() { 5 | 6 | test('it returns snippet', async function(assert) { 7 | let snippet = getCodeSnippet('render-test.js'); 8 | 9 | assert.strictEqual(snippet.source, 'function sample(){\n return 42;\n};'); 10 | assert.strictEqual(snippet.language, 'javascript'); 11 | assert.strictEqual(snippet.extension, 'js'); 12 | }); 13 | 14 | test('it returns snippet w/ indented source', async function(assert) { 15 | let snippet = getCodeSnippet('render-test.js', false); 16 | 17 | assert.strictEqual(snippet.source, ' function sample(){\n return 42;\n };'); 18 | assert.strictEqual(snippet.language, 'javascript'); 19 | assert.strictEqual(snippet.extension, 'js'); 20 | }); 21 | 22 | test('it returns handlebars snippet', async function(assert) { 23 | let snippet = getCodeSnippet('static.hbs'); 24 | 25 | assert.ok(snippet.source.includes('I am a handlebars template!
')); 26 | assert.strictEqual(snippet.language, 'handlebars'); 27 | assert.strictEqual(snippet.extension, 'hbs'); 28 | }); 29 | }); 30 | -------------------------------------------------------------------------------- /utils/findHost.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Finds the host given an addon's context by climbing 3 | * up the parent/app hierarchy. 4 | * See: https://github.com/ember-engines/ember-asset-loader/blob/master/lib/utils/find-host.js 5 | * 6 | * @param {EmberAddon|EmberApp} context 7 | * @return {EmberApp} app 8 | */ 9 | module.exports = function findHost(context) { 10 | var current = context; 11 | var app; 12 | 13 | // Keep iterating upward until we don't have a grandparent. 14 | // Has to do this grandparent check because at some point we hit the project. 15 | do { 16 | app = current.app || app; 17 | } while (current.parent && current.parent.parent && (current = current.parent)); 18 | 19 | return app; 20 | }; --------------------------------------------------------------------------------