├── .editorconfig
├── .gitattributes
├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── .npmignore
├── .travis.yml
├── LICENSE
├── README.md
├── commitlint.config.js
├── index.js
├── package-lock.json
├── package.json
└── src
├── extname
└── index.js
├── inject
├── expected
│ ├── addPrefix.html
│ ├── addSuffix.html
│ ├── customName.html
│ ├── customTags.html
│ ├── customTagsWithExt.html
│ ├── customTagsWithPath.html
│ ├── customTransform.json
│ ├── defaults.haml
│ ├── defaults.html
│ ├── defaults.jade
│ ├── defaults.jsx
│ ├── defaults.less
│ ├── defaults.pug
│ ├── defaults.sass
│ ├── defaults.scss
│ ├── defaults.slim
│ ├── defaults.slm
│ ├── defaults2.html
│ ├── emptyTags.html
│ ├── emptyTags2.html
│ ├── emptyTags3.html
│ ├── existingData.html
│ ├── existingDataAndReplaced.html
│ ├── ignorePath.html
│ ├── issue107.html
│ ├── issue144.jade
│ ├── issue144.pug
│ ├── issue176.html
│ ├── issue177.html
│ ├── issue39.html
│ ├── issue56.html
│ ├── issue71.html
│ ├── issue74.html
│ ├── noRootSlash.html
│ ├── noRootSlashWithIgnorePath.html
│ ├── parallell.html
│ ├── relative.html
│ ├── removeAndEmptyTags.html
│ ├── removeTags.html
│ ├── selfClosingTag.html
│ └── templateWithExistingData2.html
├── fixtures
│ ├── issue107.html
│ ├── issue144.jade
│ ├── issue144.pug
│ ├── issue176.html
│ ├── issue39.html
│ ├── issue56.html
│ ├── issue71.html
│ ├── issue74.html
│ ├── partial.html
│ ├── template.haml
│ ├── template.html
│ ├── template.jade
│ ├── template.json
│ ├── template.jsx
│ ├── template.less
│ ├── template.pug
│ ├── template.sass
│ ├── template.scss
│ ├── template.slim
│ ├── template.slm
│ ├── template2.html
│ ├── templateCustomName.html
│ ├── templateCustomTags.html
│ ├── templateTagsWithExt.html
│ ├── templateTagsWithPath.html
│ ├── templateWithExistingData.html
│ ├── templateWithExistingData2.html
│ └── templateWithExistingData3.html
├── index.js
└── inject_test.js
├── path
├── index.js
└── path_test.js
├── tags
├── index.js
└── tags_test.js
└── transform
├── index.js
└── transform_test.js
/.editorconfig:
--------------------------------------------------------------------------------
1 | # http://editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
15 | [test/fixtures/*]
16 | insert_final_newline = false
17 | trim_trailing_whitespace = false
18 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | * text=auto
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: Check
2 | on: push
3 | jobs:
4 | check:
5 | name: Check
6 | runs-on: ubuntu-latest
7 | steps:
8 | - name: Checkout repo
9 | uses: actions/checkout@v3
10 |
11 | - name: Setup Node
12 | uses: actions/setup-node@v3
13 | with:
14 | node-version: 18
15 |
16 | - name: Install dependencies
17 | run: npm ci
18 |
19 | - name: Run test
20 | run: npm test
21 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | .idea/
3 | node_modules/
4 | temp/
5 | npm-debug.log
6 | yarn-error.log
7 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .*
2 | .idea
3 | src/inject/expected/
4 | src/inject/fixtures/
5 | src/inject/*_test.js
6 | src/tags/*_test.js
7 | src/transform/*_test.js
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | notifications:
3 | email: false
4 | node_js:
5 | - '12'
6 | - '10'
7 | - '8'
8 | env:
9 | - BUILD_LEADER_ID=4
10 | branches:
11 | except:
12 | - /^v\d+\.\d+\.\d+$/
13 | before_script:
14 | - npm prune
15 | jobs:
16 | include:
17 | - stage: release
18 | node_js: 8
19 | os: linux
20 | after_success:
21 | - test $TRAVIS_BRANCH = "master" && test $TRAVIS_PULL_REQUEST = "false"
22 | - echo "//registry.npmjs.org/:_authToken=${NPM_TOKEN}" > .npmrc
23 | - npm run semantic-release
24 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2014
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | "Software"), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # gulp-inject
2 |
3 | ---
4 | ## HELP WANTED
5 |
6 |
7 | ### Contributors are welcomed!
8 |
9 | **I don't have enough time to maintain this plugin as I would want to, so I'm looking for people who want to help out and be contributors/repository admins.**
10 |
11 |
12 | #### Interested?
13 | **Contact me! See `package.json` for contact information.**
14 |
15 | ---
16 |
17 | [![NPM version][npm-image]][npm-url] [](https://github.com/semantic-release/semantic-release) [![Build Status][travis-image]][travis-url] [![XO code style][codestyle-image]][codestyle-url] [![Dependency Status][depstat-image]][depstat-url]
18 |
19 | > A stylesheet, javascript and webcomponent reference injection plugin for [gulp](https://github.com/wearefractal/gulp). No more manual editing of your index.html!
20 |
21 | # Contents
22 |
23 |
24 |
25 | - [Introduction](#introduction)
26 | - [Installation](#installation)
27 | - [Basic usage](#basic-usage)
28 | - [More examples](#more-examples)
29 | - [Injecting files relative to target files](#injecting-files-relative-to-target-files)
30 | - [Injecting files from multiple source streams](#injecting-files-from-multiple-source-streams)
31 | - [Multiple sources when order is important](#multiple-sources-when-order-is-important)
32 | - [Injecting some files into `
` and some into ``](#injecting-some-files-into-head-and-some-into-body)
33 | - [Method 1: Use `gulp-inject`'s `starttag` option.](#method-1-use-gulp-injects-starttag-option)
34 | - [Method 2: Use `gulp-inject`'s `name` option.](#method-2-use-gulp-injects-name-option)
35 | - [Injecting all files for development](#injecting-all-files-for-development)
36 | - [Injecting AngularJS scripts for development](#injecting-angularjs-scripts-for-development)
37 | - [Injecting into a json-file](#injecting-into-a-json-file)
38 | - [Injecting with custom `transform` function with default fallback](#injecting-with-custom-transform-function-with-default-fallback)
39 | - [Injecting dist files into bower.json's main section](#injecting-dist-files-into-bowerjsons-main-section)
40 | - [Injecting all javascript files into a karma config file](#injecting-all-javascript-files-into-a-karma-config-file)
41 | - [Injecting files contents](#injecting-files-contents)
42 | - [Injecting files contents based on file path](#injecting-files-contents-based-on-file-path)
43 | - [API](#api)
44 | - [inject(sources, options)](#injectsources-options)
45 | - [Options](#options)
46 | - [options.ignorePath](#optionsignorepath)
47 | - [options.relative](#optionsrelative)
48 | - [options.addPrefix](#optionsaddprefix)
49 | - [options.addSuffix](#optionsaddsuffix)
50 | - [options.addRootSlash](#optionsaddrootslash)
51 | - [options.name](#optionsname)
52 | - [options.removeTags](#optionsremovetags)
53 | - [options.empty](#optionsempty)
54 | - [options.starttag](#optionsstarttag)
55 | - [options.endtag](#optionsendtag)
56 | - [options.transform](#optionstransform)
57 | - [options.selfClosingTag](#optionsselfclosingtag)
58 | - [~~options.templateString~~](#optionstemplatestring)
59 | - [~~options.sort~~](#optionssort)
60 | - [inject.transform](#injecttransform)
61 | - [License](#license)
62 |
63 |
64 |
65 | ## Introduction
66 |
67 | `gulp-inject` takes a stream of source files, transforms each file to a string and injects each transformed string into placeholders in the target stream files. See [Basic usage](#basic-usage) and [More examples](#more-examples) below.
68 |
69 | Default [transforms](#optionstransform) and [placeholders](#optionsstarttag) exists for injecting files into `html`, `jade`, `pug`, `jsx` , `less`, `slm`, `haml` and `sass` / `scss` files.
70 |
71 | ## Installation
72 |
73 | Install `gulp-inject` as a development dependency:
74 |
75 | ```shell
76 | npm install --save-dev gulp-inject
77 | ```
78 |
79 | ## Basic usage
80 |
81 | **The target file `src/index.html`:**
82 |
83 | Each pair of comments are the injection placeholders (aka. tags, see [`options.starttag`](#optionsstarttag) and [`options.endtag`](#optionsendtag)).
84 |
85 | ```html
86 |
87 |
88 |
89 | My index
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 | ```
100 |
101 | **The `gulpfile.js`:**
102 |
103 | ```javascript
104 | var gulp = require('gulp');
105 | var inject = require('gulp-inject');
106 |
107 | gulp.task('index', function () {
108 | var target = gulp.src('./src/index.html');
109 | // It's not necessary to read the files (will speed up things), we're only after their paths:
110 | var sources = gulp.src(['./src/**/*.js', './src/**/*.css'], {read: false});
111 |
112 | return target.pipe(inject(sources))
113 | .pipe(gulp.dest('./src'));
114 | });
115 | ```
116 |
117 | **`src/index.html` after running `gulp index`:**
118 |
119 | ```html
120 |
121 |
122 |
123 | My index
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 | ```
138 |
139 | ## More examples
140 |
141 | ### Injecting files relative to target files
142 |
143 | By default the injected file paths are relative to each source file's `cwd` (see [`options.ignorePath`](#optionsignorepath)). If `options.relative` is set to `true` each injected path will be relative to each target file's directory instead.
144 |
145 | **Project structure:**
146 |
147 | ```
148 | └── src
149 | ├── module
150 | │ ├── module.js
151 | │ └── module.html
152 | └── app
153 | ├── main.js
154 | └── index.html
155 | ```
156 |
157 | **`src/app/index.html`:**
158 |
159 | ```html
160 |
161 |
162 |
163 | My Index
164 |
165 |
166 | Home
167 |
168 |
169 |
170 |
171 | ```
172 |
173 | **`src/module/module.html`:**
174 |
175 | ```html
176 |
177 |
178 |
179 | Module
180 |
181 |
182 | Module
183 |
184 |
185 |
186 |
187 | ```
188 |
189 | **`gulpfile.js`:**
190 |
191 | ```javascript
192 | var inject = require('gulp-inject');
193 |
194 | gulp.src('./src/**/*.html')
195 | .pipe(inject(gulp.src('./src/**/*.js', {read: false}), {relative: true}))
196 | .pipe(gulp.dest('./src'));
197 | ```
198 |
199 | **Resulting `src/app/index.html`:**
200 |
201 | ```html
202 |
203 |
204 |
205 | My Index
206 |
207 |
208 | Home
209 |
210 |
211 |
212 |
213 |
214 |
215 | ```
216 |
217 | **Resulting `src/module/module.html`:**
218 |
219 | ```html
220 |
221 |
222 |
223 | Module
224 |
225 |
226 | Home
227 |
228 |
229 |
230 |
231 |
232 |
233 | ```
234 |
235 | ### Injecting files from multiple source streams
236 |
237 | This example demonstrates how to inject files from multiple different streams into the same injection placeholder.
238 |
239 | Install [`event-stream`](https://www.npmjs.org/package/event-stream) with: `npm install --save-dev event-stream` and use its [`merge`](https://github.com/dominictarr/event-stream#merge-stream1streamn) function.
240 |
241 | **Code:**
242 |
243 | ```javascript
244 | var es = require('event-stream'),
245 | inject = require('gulp-inject'),
246 | concat = require('gulp-concat'),
247 | uglify = require('gulp-uglify');
248 |
249 | // Concatenate vendor scripts
250 | var vendorStream = gulp.src(['./src/vendors/*.js'])
251 | .pipe(concat('vendors.js'))
252 | .pipe(gulp.dest('./dist'));
253 |
254 | // Concatenate AND minify app sources
255 | var appStream = gulp.src(['./src/app/*.js'])
256 | .pipe(concat('app.js'))
257 | .pipe(uglify())
258 | .pipe(gulp.dest('./dist'));
259 |
260 | gulp.src('./src/index.html')
261 | .pipe(inject(es.merge(vendorStream, appStream)))
262 | .pipe(gulp.dest('./dist'));
263 | ```
264 |
265 | #### Multiple sources when order is important
266 |
267 | Use [`stream-series`](https://github.com/rschmukler/stream-series).
268 |
269 | **Code:**
270 |
271 | ```javascript
272 | var series = require('stream-series'),
273 | inject = require('gulp-inject');
274 |
275 | var vendorStream = gulp.src(['./src/vendors/*.js'], {read: false});
276 |
277 | var appStream = gulp.src(['./src/app/*.js'], {read: false});
278 |
279 | gulp.src('./src/index.html')
280 | .pipe(inject(series(vendorStream, appStream))) // This will always inject vendor files before app files
281 | .pipe(gulp.dest('./dist'));
282 | ```
283 |
284 | ### Injecting some files into `` and some into ``
285 |
286 | #### Method 1: Use `gulp-inject`'s `starttag` option.
287 |
288 | **`gulpfile.js`:**
289 |
290 | ```javascript
291 | var inject = require('gulp-inject');
292 |
293 | gulp.src('./src/index.html')
294 | .pipe(inject(gulp.src('./src/importantFile.js', {read: false}), {starttag: ''}))
295 | .pipe(inject(gulp.src(['./src/*.js', '!./src/importantFile.js'], {read: false})))
296 | .pipe(gulp.dest('./dist'));
297 | ```
298 |
299 | **And in your `./src/index.html`:**
300 |
301 | ```html
302 |
303 |
304 |
305 | My index
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 | ```
318 |
319 | #### Method 2: Use `gulp-inject`'s `name` option.
320 |
321 | **`gulpfile.js`:**
322 |
323 | ```javascript
324 | var inject = require('gulp-inject');
325 |
326 | gulp.src('./src/index.html')
327 | .pipe(inject(gulp.src('./src/importantFile.js', {read: false}), {name: 'head'}))
328 | .pipe(inject(gulp.src(['./src/*.js', '!./src/importantFile.js'], {read: false})))
329 | .pipe(gulp.dest('./dist'));
330 | ```
331 |
332 | **And in your `./src/index.html`:**
333 |
334 | ```html
335 |
336 |
337 |
338 | My index
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 | ```
351 |
352 |
353 | ### Injecting all files for development
354 |
355 | If you use [Bower](http://bower.io/) for frontend dependencies I recommend using [`main-bower-files`](https://www.npmjs.org/package/main-bower-files) and injecting them as well.
356 |
357 | **`gulpfile.js`:**
358 |
359 | ```javascript
360 | var bowerFiles = require('main-bower-files'),
361 | inject = require('gulp-inject'),
362 | stylus = require('gulp-stylus'),
363 | es = require('event-stream');
364 |
365 | var cssFiles = gulp.src('./src/**/*.styl')
366 | .pipe(stylus())
367 | .pipe(gulp.dest('./build'));
368 |
369 | gulp.src('./src/index.html')
370 | .pipe(inject(gulp.src(bowerFiles(), {read: false}), {name: 'bower'}))
371 | .pipe(inject(es.merge(
372 | cssFiles,
373 | gulp.src('./src/app/**/*.js', {read: false})
374 | )))
375 | .pipe(gulp.dest('./build'));
376 | ```
377 |
378 | **`src/index.html`:**
379 |
380 | ```html
381 |
382 |
383 |
384 | My index
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 | ```
403 |
404 | **Note** remember to mount `./bower_components`, `./build` and `./src/app` as static resources in your server to make this work.
405 |
406 | ### Injecting AngularJS scripts for development
407 |
408 | If you're writing an AngularJS application and follow [Google's Angular APP Structure Recommendations](https://docs.google.com/document/d/1XXMvReO8-Awi1EZXAXS4PzDzdNvV6pGcuaF4Q9821Es/pub), which I think you should, it's important that the script files are injected in the correct order to avoid module instantiation problems like `Uncaught Error: [$injector:modulerr]`.
409 |
410 | To do this you can use [`gulp-angular-filesort`](https://www.npmjs.org/package/gulp-angular-filesort) together with `gulp-inject` like so:
411 |
412 | ```javascript
413 | var angularFilesort = require('gulp-angular-filesort'),
414 | inject = require('gulp-inject');
415 |
416 | gulp.src('./src/index.html')
417 | .pipe(inject(
418 | gulp.src('./src/app/**/*.js') // gulp-angular-filesort depends on file contents, so don't use {read: false} here
419 | .pipe(angularFilesort())
420 | ))
421 | .pipe(gulp.dest('./build'));
422 | ```
423 |
424 | ### Injecting into a json-file
425 |
426 | You can customize `gulp-inject` further by using the `transform` function option, e.g. by injecting files into a json-file.
427 |
428 | **Code:**
429 |
430 | ```javascript
431 | gulp.src('./files.json')
432 | .pipe(inject(gulp.src(['./src/*.js', './src/*.css', './src/*.html'], {read: false}), {
433 | starttag: '"{{ext}}": [',
434 | endtag: ']',
435 | transform: function (filepath, file, i, length) {
436 | return ' "' + filepath + '"' + (i + 1 < length ? ',' : '');
437 | }
438 | }))
439 | .pipe(gulp.dest('./'));
440 | ```
441 |
442 | Initial contents of `files.json`:
443 |
444 | ```json
445 | {
446 | "js": [
447 | ],
448 | "css": [
449 | ],
450 | "html": [
451 | ]
452 | }
453 | ```
454 |
455 | ### Injecting with custom `transform` function with default fallback
456 |
457 | The [default `transform`](#injecttransform) function is available to use e.g. as a default fallback.
458 |
459 | Used here to inject Word documents as `` tags below:
460 |
461 | **`index.html`:**
462 |
463 | ```html
464 |
465 |
466 |
467 | My documents
468 |
469 |
470 | Documents
471 |
475 |
476 |
477 |
478 |
479 | ```
480 |
481 | **`gulpfile.js`:**
482 |
483 | ```javascript
484 | var inject = require('gulp-inject');
485 |
486 | gulp.src('./index.html')
487 | .pipe(inject(
488 | gulp.src(['./*.js', './docs/*.docx'], {read: false}), {
489 | transform: function (filepath) {
490 | if (filepath.slice(-5) === '.docx') {
491 | return '' + filepath + '';
492 | }
493 | // Use the default transform as fallback:
494 | return inject.transform.apply(inject.transform, arguments);
495 | }
496 | }
497 | ))
498 | .pipe(gulp.dest('./'));
499 | ```
500 |
501 | **Resulting `index.html`:**
502 |
503 | ```html
504 |
505 |
506 |
507 | My documents
508 |
509 |
510 | Documents
511 |
512 |
513 |
514 |
515 |
516 |
517 |
518 |
519 |
520 |
521 |
522 |
523 | ```
524 |
525 | ### Injecting dist files into bower.json's main section
526 |
527 | **Code:**
528 |
529 | ```javascript
530 | gulp.src('./bower.json')
531 | .pipe(inject(gulp.src(['./dist/app.min.js', './dist/app.min.css'], {read: false}), {
532 | starttag: '"main": [',
533 | endtag: ']',
534 | transform: function (filepath, file, i, length) {
535 | return ' "' + filepath + '"' + (i + 1 < length ? ',' : '');
536 | }
537 | }))
538 | .pipe(gulp.dest('./'));
539 | ```
540 |
541 | ### Injecting all javascript files into a karma config file
542 |
543 | **Code:**
544 |
545 | ```javascript
546 | gulp.src('./karma.conf.js')
547 | .pipe(inject(gulp.src(['./src/**/*.js'], {read: false}), {
548 | starttag: 'files: [',
549 | endtag: ']',
550 | transform: function (filepath, file, i, length) {
551 | return ' "' + filepath + '"' + (i + 1 < length ? ',' : '');
552 | }
553 | }))
554 | .pipe(gulp.dest('./'));
555 | ```
556 |
557 | ### Injecting files contents
558 |
559 | In order to inject files contents you have to provide custom `transform` function, that will return file contents as string. You also have to omit `{read: false}` option of `gulp.src` in this case. Example below shows how to inject contents of html partials into head of `index.html`:
560 |
561 | ***Code:***
562 |
563 | ```javascript
564 | gulp.src('./src/index.html')
565 | .pipe(inject(gulp.src(['./src/partials/head/*.html']), {
566 | starttag: '',
567 | transform: function (filePath, file) {
568 | // return file contents as string
569 | return file.contents.toString('utf8')
570 | }
571 | }))
572 | .pipe(gulp.dest('./dest'));
573 | ```
574 |
575 | And in your `./src/index.html`:
576 |
577 | ```html
578 |
579 |
580 |
581 | My index
582 |
583 |
584 |
585 |
586 |
587 |
588 |
589 | ```
590 |
591 | ### Injecting files contents based on file path
592 |
593 | In order to inject files based on file path you have to provide custom `starttag` which includes `{{path}}`. Additionally, in order to inject file contents include `transform` function, that will return file contents as string. You also have to omit `{read: false}` option of `gulp.src` in this case. Path can be either absolute, or relative in which case you should set [`options.relative`] to true. Example below shows how to inject contents of html partials into `index.html`:
594 |
595 | ***Code:***
596 |
597 | ```javascript
598 | gulp.src('./src/index.html')
599 | .pipe(inject(gulp.src(['./src/partials/head/*.html']), {
600 | starttag: '',
601 | relative: true,
602 | transform: function (filePath, file) {
603 | // return file contents as string
604 | return file.contents.toString('utf8')
605 | }
606 | }))
607 | .pipe(gulp.dest('./dest'));
608 | ```
609 |
610 | And in your `./src/index.html`:
611 |
612 | ```html
613 |
614 |
615 |
616 | My index
617 |
618 |
619 |
620 |
621 |
622 |
623 |
624 | ```
625 |
626 | ## API
627 |
628 | ### inject(sources, options)
629 |
630 | Parameter: `sources`
631 | Type: `Stream`
632 |
633 | Provide a Vinyl File Stream as input to `inject`, see examples above.
634 |
635 |
636 | Parameter: `options`
637 | Type: `Object`
638 |
639 | For available options see [Options](#options)
640 |
641 | ### Options
642 |
643 | #### options.ignorePath
644 | Type: `String` or `Array`
645 |
646 | Default: `NULL`
647 |
648 |
649 | A path or paths that should be removed from each injected file path.
650 |
651 | This could also be solved by setting the `cwd` option for your `gulp.src` streams, each source file's `cwd` is automatically removed from its path before injection (if not [`options.relative`](#optionsrelative) is set to `true`, see below).
652 |
653 |
654 | #### options.relative
655 | Type: `Boolean`
656 |
657 | Default: `false`
658 |
659 |
660 | If set to `true` paths for the injected files will be relative to each target file, this also means that each source file's `cwd` is not necessary to remove from its path.
661 |
662 |
663 | #### options.addPrefix
664 | Type: `String`
665 |
666 | Default: `NULL`
667 |
668 |
669 | A path that should be prefixed to each injected file path.
670 |
671 | #### options.addSuffix
672 | Type: `String`
673 |
674 | Default: `NULL`
675 |
676 |
677 | A path that should be suffixed to each injected file path.
678 |
679 | #### options.addRootSlash
680 | Type: `Boolean`
681 |
682 | Default: [`!options.relative`](#optionsrelative)
683 |
684 |
685 | The root slash is automatically added at the beginning of the path ('/'), or removed if set to `false`.
686 |
687 | #### options.name
688 | Type: `String`
689 |
690 | Default: `"inject"`
691 |
692 |
693 | Used in the default [start](#optionsstarttag) and [end](#optionsendtag) tags below.
694 |
695 | #### options.removeTags
696 | Type: `Boolean`
697 |
698 | Default: `false`
699 |
700 |
701 | When `true` the start and end tags will be removed when injecting files.
702 |
703 | #### options.empty
704 | Type: `Boolean`
705 |
706 | Default: `false`
707 |
708 |
709 | When `true` all tags without corresponding files will be emptied.
710 |
711 | [**Warning** this has the potential issue of emptying more than expected.](https://github.com/klei/gulp-inject/issues/135)
712 |
713 |
714 | #### options.starttag
715 |
716 | **Type:** `String`|`Function(targetExt, sourceExt)`
717 |
718 | **Params (if function):**
719 | - `targetExt` - The file extension of the target file
720 | - `sourceExt` - The file extension of source file
721 |
722 | **Purpose:**
723 |
724 | Used to dynamically set starting placeholder tag depending on file extensions.
725 | In the provided string, or the string returned from the given function, the string `{{ext}}` is replaced with the source file extension name, e.g. "css", "js" or "html". `{{name}}` will be replaced by [`options.name`](#optionsname). `{{path}}` will be replaced by path to source file (when used together with [`options.relative`] it will allow relative path to source file.
726 |
727 | ##### Default:
728 |
729 | A function dependent on target file type and source file type that returns:
730 |
731 | * html as target: ``
732 | * haml as target: `-# {{name}}:{{ext}}`
733 | * jade as target: `//- {{name}}:{{ext}}`
734 | * pug as target: `//- {{name}}:{{ext}}`
735 | * jsx as target: `{/* {{name}}:{{ext}} */}`
736 | * slm as target: `/ {{name}}:{{ext}}`
737 | * less as target: `/* {{name}}:{{ext}} */`
738 | * sass, scss as target: `/* {{name}}:{{ext}} */`
739 |
740 | #### options.endtag
741 |
742 | **Type:** `String`|`Function(targetExt, sourceExt)`
743 |
744 | **Params (if function):**
745 | - `targetExt` - The file extension of the target file
746 | - `sourceExt` - The file extension of source file
747 |
748 | **Purpose:**
749 |
750 | Used to dynamically set ending placeholder tag depending on file extensions.
751 | In the provided string, or the string returned from the given function, the string `{{ext}}` is replaced with the source file extension name, e.g. "css", "js" or "html". `{{name}}` will be replaced by [`options.name`](#optionsname). `{{path}}` will be replaced by path to source file.
752 |
753 | ##### Default:
754 |
755 | A function dependent on target file type and source file type that returns:
756 |
757 | * html as target: ``
758 | * haml as target: `-# endinject`
759 | * jade as target: `//- endinject`
760 | * pug as target: `//- endinject`
761 | * jsx as target: `{/* endinject */}`
762 | * slm as target: `/ endinject`
763 | * less as target: `/* endinject */`
764 | * sass, scss as target: `/* endinject */`
765 |
766 | #### options.transform
767 |
768 | **Type**: `Function(filepath, file, index, length, targetFile)`
769 |
770 | **Params:**
771 | - `filepath` - The "unixified" path to the file with any `ignorePath`'s removed, `addPrefix` and `addSuffix` added
772 | - `file` - The [File object](https://github.com/wearefractal/vinyl) to inject given from `gulp.src`
773 | - `index` - 0-based file index
774 | - `length` - Total number of files to inject for the current file extension
775 | - `targetFile` - The target [file](https://github.com/wearefractal/vinyl) to inject into
776 |
777 | **Purpose:**
778 |
779 | Used to generate the content to inject for each file.
780 |
781 | ##### Default:
782 |
783 | [A function](#injecttransform) dependent on target file type and source file type that returns:
784 |
785 | **Injecting into `html`**
786 |
787 | * css files: ``
788 | * js files: ``
789 | * coffee files: ``
790 | * html files: ``
791 | * png files: `
`
792 | * gif files: `
`
793 | * jpg files: `
`
794 | * jpeg files: `
`
795 |
796 | If `options.selfClosingTag` is `true` the default transformer above will make the `` and `
` tags self close, i.e: `` and `
` respectively.
797 |
798 | **Injecting into `jsx`**
799 |
800 | The same as for injecting into `html` above with [`options.selfClosingTag`](#optionsselfclosingtag) set to `true`.
801 |
802 | **Injecting into `jade`**
803 |
804 | * css files: `link(rel="stylesheet", href=".css")`
805 | * js files: `script(src=".js")`
806 | * coffee files: `script(type="text/coffeescript", src=".coffee")`
807 | * html files: `link(rel="import", href=".html")`
808 | * png files: `img(src=".png")`
809 | * gif files: `img(src=".gif")`
810 | * jpg files: `img(src=".jpg")`
811 | * jpeg files: `img(src=".jpeg")`
812 |
813 | **Injecting into `pug`**
814 |
815 | * css files: `link(rel="stylesheet", href=".css")`
816 | * js files: `script(src=".js")`
817 | * coffee files: `script(type="text/coffeescript", src=".coffee")`
818 | * html files: `link(rel="import", href=".html")`
819 | * png files: `img(src=".png")`
820 | * gif files: `img(src=".gif")`
821 | * jpg files: `img(src=".jpg")`
822 | * jpeg files: `img(src=".jpeg")`
823 |
824 | **Injecting into `slm`**
825 |
826 | * css files: `link rel="stylesheet" href=".css"`
827 | * js files: `script src=".js"`
828 | * coffee files: `script type="text/coffeescript" src=".coffee"`
829 | * html files: `link rel="import" href=".html"`
830 | * png files: `img src=".png"`
831 | * gif files: `img src=".gif"`
832 | * jpg files: `img src=".jpg"`
833 | * jpeg files: `img src=".jpeg"`
834 |
835 | **Injecting into `haml`**
836 |
837 | * css files: `%link{rel:"stylesheet", href:".css"}`
838 | * js files: `%script{src:".js"}`
839 | * coffee files: `%script{type:"text/coffeescript", src:".coffee"}`
840 | * html files: `%link{rel:"import", href:".html"}`
841 | * png files: `%img{src:".png"}`
842 | * gif files: `%img{src:".gif"}`
843 | * jpg files: `%img{src:".jpg"}`
844 | * jpeg files: `%img{src:".jpeg"}`
845 |
846 | **Injecting into `less`**
847 |
848 | * css files: `@import ".css";`
849 | * less files: `@import ".less";`
850 |
851 | **Injecting into `scss`**
852 |
853 | * css files: `@import ".css";`
854 | * scss files: `@import ".scss";`
855 | * sass files: `@import ".sass";`
856 |
857 | **Injecting into `sass`**
858 |
859 | * css files: `@import ".css"`
860 | * sass files: `@import ".sass"`
861 | * scss files: `@import ".scss"`
862 |
863 | #### options.selfClosingTag
864 | Type: `Boolean`
865 |
866 | Default: `false`
867 |
868 | Affects the default `options.transform` function, see above.
869 |
870 |
871 | #### options.quiet
872 | Type: `Boolean`
873 |
874 | Default: `false`
875 |
876 | Lower the verbosity by setting this to true, suppressing the logging of successful injections.
877 |
878 |
879 | #### ~~options.templateString~~
880 |
881 | ***DEPRECATED!***
882 |
883 | *Deprecated since `v.1.0`. Use [`gulp-file`](https://www.npmjs.org/package/gulp-file) instead:*
884 |
885 | ```javascript
886 | var gulp = require('gulp');
887 | var file = require('gulp-file');
888 | var inject = require('gulp-inject');
889 |
890 | file('index.html', '')
891 | .pipe(inject(gulp.src(['./src/app/**/*.js']), {
892 | starttag: '',
893 | endtag: ''
894 | }))
895 | .pipe(gulp.dest('./dest'));
896 | ```
897 |
898 | #### ~~options.sort~~
899 |
900 | ***DEPRECATED!***
901 |
902 | *Deprecated since `v.1.0`. Use [`sort-stream`](https://www.npmjs.org/package/sort-stream) instead:*
903 |
904 | ```javascript
905 | var gulp = require('gulp');
906 | var sort = require('sort-stream');
907 | var inject = require('gulp-inject');
908 |
909 | gulp.src('index.html')
910 | .pipe(inject(
911 | gulp.src(['./src/app/**/*.js'])
912 | .pipe(sort(function (a, b) {
913 | // Sort condition here...
914 | }))
915 | ))
916 | .pipe(gulp.dest('./dest'));
917 | ```
918 |
919 | ### inject.transform
920 |
921 | The default transform function is exposed in the public API.
922 |
923 | For more details see [the code with tests](https://github.com/klei/gulp-inject/tree/master/src/transform).
924 |
925 | ##### inject.transform.html
926 |
927 | The default transform function for files into `html`, or other file types not `jade`, `pug`, `jsx`, `slm`, `less`, `scss`, `sass` or `haml`.
928 |
929 | ##### inject.transform.jade
930 |
931 | The default transform function for files into `jade`.
932 |
933 | ##### inject.transform.pug
934 |
935 | The default transform function for files into `pug`.
936 |
937 | ##### inject.transform.jsx
938 |
939 | The default transform function for files into `jsx`.
940 |
941 | ##### inject.transform.slm
942 |
943 | The default transform function for files into `slm`.
944 |
945 | ##### inject.transform.haml
946 |
947 | The default transform function for files into `haml`.
948 |
949 | ##### inject.transform.less
950 |
951 | The default transform function for files into `less`.
952 |
953 | ##### inject.transform.sass
954 |
955 | The default transform function for files into `sass`.
956 |
957 | ##### inject.transform.scss
958 |
959 | The default transform function for files into `scss`.
960 |
961 |
962 | ## License
963 |
964 | [MIT](http://en.wikipedia.org/wiki/MIT_License) © [Joakim Carlstein](http://joakim.beng.se)
965 |
966 | [npm-url]: https://npmjs.org/package/gulp-inject
967 | [npm-image]: https://badge.fury.io/js/gulp-inject.svg
968 |
969 | [travis-url]: http://travis-ci.org/klei/gulp-inject
970 | [travis-image]: https://secure.travis-ci.org/klei/gulp-inject.svg?branch=master
971 |
972 | [depstat-url]: https://david-dm.org/klei/gulp-inject
973 | [depstat-image]: https://david-dm.org/klei/gulp-inject.svg
974 |
975 | [codestyle-url]: https://github.com/sindresorhus/xo
976 | [codestyle-image]: https://img.shields.io/badge/code%20style-XO-5ed9c7.svg?style=flat
977 |
--------------------------------------------------------------------------------
/commitlint.config.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | module.exports = {
3 | extends: ['@commitlint/config-angular']
4 | };
5 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Export `gulp-inject`
3 | */
4 | module.exports = exports = require('./src/inject');
5 |
6 | /**
7 | * Export the default transform function(s)
8 | */
9 | exports.transform = require('./src/transform');
10 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gulp-inject",
3 | "version": "0.0.0-development",
4 | "description": "A javascript, stylesheet and webcomponent injection plugin for Gulp, i.e. inject file references into your index.html",
5 | "main": "index.js",
6 | "license": "MIT",
7 | "homepage": "https://github.com/klei/gulp-inject",
8 | "bugs": "https://github.com/klei/gulp-inject/issues",
9 | "author": {
10 | "name": "Joakim Carlstein",
11 | "email": "joakim@klei.se",
12 | "url": "http://joakim.beng.se"
13 | },
14 | "keywords": [
15 | "gulpplugin",
16 | "inject",
17 | "stylesheets",
18 | "webcomponents",
19 | "scripts",
20 | "index"
21 | ],
22 | "repository": {
23 | "type": "git",
24 | "url": "https://github.com/klei/gulp-inject.git"
25 | },
26 | "scripts": {
27 | "lint": "xo",
28 | "pretest": "npm run -s lint",
29 | "test": "mocha -R spec src/**/*_test.js",
30 | "semantic-release": "semantic-release"
31 | },
32 | "dependencies": {
33 | "ansi-colors": "^4.1.3",
34 | "arrify": "^2.0.1",
35 | "escape-string-regexp": "^2.0.0",
36 | "fancy-log": "^1.3.3",
37 | "group-array": "^1.0.0",
38 | "plugin-error": "^1.0.1",
39 | "stream-to-array": "^2.3.0",
40 | "through2": "^3.0.2"
41 | },
42 | "devDependencies": {
43 | "@commitlint/cli": "^8.3.6",
44 | "@commitlint/config-angular": "^8.3.6",
45 | "event-stream": "^4.0.1",
46 | "husky": "^3.1.0",
47 | "mocha": "^6.2.3",
48 | "semantic-release": "^15.14.0",
49 | "should": "^13.2.3",
50 | "strip-color": "^0.1.0",
51 | "vinyl": "^2.2.1",
52 | "xo": "^0.25.3"
53 | },
54 | "engines": {
55 | "node": ">=8"
56 | },
57 | "xo": {
58 | "space": true,
59 | "envs": [
60 | "node"
61 | ],
62 | "rules": {
63 | "func-names": 0,
64 | "func-name-matching": 0,
65 | "no-multi-assign": 0,
66 | "no-useless-escape": 0,
67 | "no-var": 0,
68 | "object-shorthand": [
69 | 2,
70 | "never"
71 | ],
72 | "padding-line-between-statements": 0,
73 | "prefer-arrow-callback": 0,
74 | "prefer-destructuring": 0,
75 | "prefer-rest-params": 0,
76 | "prefer-spread": 0,
77 | "unicorn/explicit-length-check": 0,
78 | "unicorn/filename-case": 0,
79 | "unicorn/import-index": 0,
80 | "valid-jsdoc": 0
81 | }
82 | },
83 | "husky": {
84 | "hooks": {
85 | "commit-msg": "commitlint -e"
86 | }
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/extname/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 |
4 | module.exports = exports = function extname(file) {
5 | file = file.split('?')[0];
6 | return path.extname(file).slice(1);
7 | };
8 |
--------------------------------------------------------------------------------
/src/inject/expected/addPrefix.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/inject/expected/addSuffix.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/inject/expected/customName.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/inject/expected/customTags.html:
--------------------------------------------------------------------------------
1 | Hello world
2 |
--------------------------------------------------------------------------------
/src/inject/expected/customTagsWithExt.html:
--------------------------------------------------------------------------------
1 | Hello world
2 |
--------------------------------------------------------------------------------
/src/inject/expected/customTagsWithPath.html:
--------------------------------------------------------------------------------
1 | Partial body
Hello world
2 |
--------------------------------------------------------------------------------
/src/inject/expected/customTransform.json:
--------------------------------------------------------------------------------
1 | {
2 | "js": [
3 | "/lib.js",
4 | "/lib2.js"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/src/inject/expected/defaults.haml:
--------------------------------------------------------------------------------
1 | !!!
2 | %html
3 | %head
4 | %title gulp-inject
5 | -# inject:html
6 | %link{rel:"import", href:"/fixtures/component.html"}
7 | -# endinject
8 | -# inject:css
9 | %link{rel:"stylesheet", href:"/fixtures/styles.css"}
10 | -# endinject
11 | %body
12 |
13 | -# inject:js
14 | %script{src:"/fixtures/lib.js"}
15 | -# endinject
16 |
--------------------------------------------------------------------------------
/src/inject/expected/defaults.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/inject/expected/defaults.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title gulp-inject
5 | //- inject:html
6 | link(rel="import", href="/fixtures/component.html")
7 | //- endinject
8 | //- inject:css
9 | link(rel="stylesheet", href="/fixtures/styles.css")
10 | //- endinject
11 | body
12 |
13 | //- inject:js
14 | script(src="/fixtures/lib.js")
15 | //- endinject
16 |
--------------------------------------------------------------------------------
/src/inject/expected/defaults.jsx:
--------------------------------------------------------------------------------
1 | /* eslint import/no-unresolved:0 */
2 | var React = require('react');
3 |
4 | var App = React.createClass({
5 |
6 | render: function () {
7 | return (
8 |
9 |
10 | gulp-inject
11 | {/* inject:html */}
12 |
13 | {/* endinject */}
14 | {/* inject:css */}
15 |
16 | {/* endinject */}
17 |
18 |
19 | {/* inject:js */}
20 |
21 | {/* endinject */}
22 |
23 |
24 | );
25 | }
26 |
27 | });
28 |
29 | module.exports = App;
30 |
--------------------------------------------------------------------------------
/src/inject/expected/defaults.less:
--------------------------------------------------------------------------------
1 | /* inject:css */
2 | @import "/fixtures/lib.css";
3 | /* endinject */
4 | /* inject:less */
5 | @import "/fixtures/component.less";
6 | @import "/fixtures/styles.less";
7 | /* endinject */
8 |
--------------------------------------------------------------------------------
/src/inject/expected/defaults.pug:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title gulp-inject
5 | //- inject:html
6 | link(rel="import", href="/fixtures/component.html")
7 | //- endinject
8 | //- inject:css
9 | link(rel="stylesheet", href="/fixtures/styles.css")
10 | //- endinject
11 | body
12 |
13 | //- inject:js
14 | script(src="/fixtures/lib.js")
15 | //- endinject
16 |
--------------------------------------------------------------------------------
/src/inject/expected/defaults.sass:
--------------------------------------------------------------------------------
1 | /* inject:css */
2 | @import "/fixtures/lib.css"
3 | /* endinject */
4 | /* inject:sass */
5 | @import "/fixtures/component.sass"
6 | @import "/fixtures/styles.sass"
7 | /* endinject */
8 | /* inject:scss */
9 | @import "/fixtures/component.scss"
10 | @import "/fixtures/styles.scss"
11 | /* endinject */
12 |
--------------------------------------------------------------------------------
/src/inject/expected/defaults.scss:
--------------------------------------------------------------------------------
1 | /* inject:css */
2 | @import "/fixtures/lib.css";
3 | /* endinject */
4 | /* inject:sass */
5 | @import "/fixtures/component.sass";
6 | @import "/fixtures/styles.sass";
7 | /* endinject */
8 | /* inject:scss */
9 | @import "/fixtures/component.scss";
10 | @import "/fixtures/styles.scss";
11 | /* endinject */
12 |
--------------------------------------------------------------------------------
/src/inject/expected/defaults.slim:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title gulp-inject
5 | / inject:html
6 | link rel="import" href="/fixtures/component.html"
7 | / endinject
8 | / inject:css
9 | link rel="stylesheet" href="/fixtures/styles.css"
10 | / endinject
11 | body
12 |
13 | / inject:js
14 | script src="/fixtures/lib.js"
15 | / endinject
16 |
--------------------------------------------------------------------------------
/src/inject/expected/defaults.slm:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title gulp-inject
5 | / inject:html
6 | link rel="import" href="/fixtures/component.html"
7 | / endinject
8 | / inject:css
9 | link rel="stylesheet" href="/fixtures/styles.css"
10 | / endinject
11 | body
12 |
13 | / inject:js
14 | script src="/fixtures/lib.js"
15 | / endinject
16 |
--------------------------------------------------------------------------------
/src/inject/expected/defaults2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject2
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/inject/expected/emptyTags.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/inject/expected/emptyTags2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/inject/expected/emptyTags3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/inject/expected/existingData.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Hello world
7 |
--------------------------------------------------------------------------------
/src/inject/expected/existingDataAndReplaced.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/inject/expected/ignorePath.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/inject/expected/issue107.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/inject/expected/issue144.jade:
--------------------------------------------------------------------------------
1 | //- inject:js
2 | script(src="/fixtures/lib.js")
3 | //- endinject
4 |
5 | //- inject:jsx
6 | script(type="text/jsx", src="/fixtures/component.jsx")
7 | //- endinject
8 |
--------------------------------------------------------------------------------
/src/inject/expected/issue144.pug:
--------------------------------------------------------------------------------
1 | //- inject:js
2 | script(src="/fixtures/lib.js")
3 | //- endinject
4 |
5 | //- inject:jsx
6 | script(type="text/jsx", src="/fixtures/component.jsx")
7 | //- endinject
8 |
--------------------------------------------------------------------------------
/src/inject/expected/issue176.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/inject/expected/issue177.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/src/inject/expected/issue39.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/inject/expected/issue56.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/inject/expected/issue71.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/src/inject/expected/issue74.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/inject/expected/noRootSlash.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/inject/expected/noRootSlashWithIgnorePath.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/inject/expected/parallell.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/inject/expected/relative.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/inject/expected/removeAndEmptyTags.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/inject/expected/removeTags.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/inject/expected/selfClosingTag.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/src/inject/expected/templateWithExistingData2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/inject/fixtures/issue107.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/inject/fixtures/issue144.jade:
--------------------------------------------------------------------------------
1 | //- inject:js
2 | //- endinject
3 |
4 | //- inject:jsx
5 | //- endinject
6 |
--------------------------------------------------------------------------------
/src/inject/fixtures/issue144.pug:
--------------------------------------------------------------------------------
1 | //- inject:js
2 | //- endinject
3 |
4 | //- inject:jsx
5 | //- endinject
6 |
--------------------------------------------------------------------------------
/src/inject/fixtures/issue176.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/src/inject/fixtures/issue39.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/inject/fixtures/issue56.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/inject/fixtures/issue71.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/inject/fixtures/issue74.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/inject/fixtures/partial.html:
--------------------------------------------------------------------------------
1 | Partial body
--------------------------------------------------------------------------------
/src/inject/fixtures/template.haml:
--------------------------------------------------------------------------------
1 | !!!
2 | %html
3 | %head
4 | %title gulp-inject
5 | -# inject:html
6 | -# endinject
7 | -# inject:css
8 | -# endinject
9 | %body
10 |
11 | -# inject:js
12 | -# endinject
13 |
--------------------------------------------------------------------------------
/src/inject/fixtures/template.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/inject/fixtures/template.jade:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title gulp-inject
5 | //- inject:html
6 | //- endinject
7 | //- inject:css
8 | //- endinject
9 | body
10 |
11 | //- inject:js
12 | //- endinject
13 |
--------------------------------------------------------------------------------
/src/inject/fixtures/template.json:
--------------------------------------------------------------------------------
1 | {
2 | "js": [
3 | ]
4 | }
5 |
--------------------------------------------------------------------------------
/src/inject/fixtures/template.jsx:
--------------------------------------------------------------------------------
1 | /* eslint import/no-unresolved:0 */
2 | var React = require('react');
3 |
4 | var App = React.createClass({
5 |
6 | render: function () {
7 | return (
8 |
9 |
10 | gulp-inject
11 | {/* inject:html */}
12 | {/* endinject */}
13 | {/* inject:css */}
14 | {/* endinject */}
15 |
16 |
17 | {/* inject:js */}
18 | {/* endinject */}
19 |
20 |
21 | );
22 | }
23 |
24 | });
25 |
26 | module.exports = App;
27 |
--------------------------------------------------------------------------------
/src/inject/fixtures/template.less:
--------------------------------------------------------------------------------
1 | /* inject:css */
2 | /* endinject */
3 | /* inject:less */
4 | /* endinject */
5 |
--------------------------------------------------------------------------------
/src/inject/fixtures/template.pug:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title gulp-inject
5 | //- inject:html
6 | //- endinject
7 | //- inject:css
8 | //- endinject
9 | body
10 |
11 | //- inject:js
12 | //- endinject
13 |
--------------------------------------------------------------------------------
/src/inject/fixtures/template.sass:
--------------------------------------------------------------------------------
1 | /* inject:css */
2 | /* endinject */
3 | /* inject:sass */
4 | /* endinject */
5 | /* inject:scss */
6 | /* endinject */
7 |
--------------------------------------------------------------------------------
/src/inject/fixtures/template.scss:
--------------------------------------------------------------------------------
1 | /* inject:css */
2 | /* endinject */
3 | /* inject:sass */
4 | /* endinject */
5 | /* inject:scss */
6 | /* endinject */
7 |
--------------------------------------------------------------------------------
/src/inject/fixtures/template.slim:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title gulp-inject
5 | / inject:html
6 | / endinject
7 | / inject:css
8 | / endinject
9 | body
10 |
11 | / inject:js
12 | / endinject
13 |
--------------------------------------------------------------------------------
/src/inject/fixtures/template.slm:
--------------------------------------------------------------------------------
1 | doctype html
2 | html
3 | head
4 | title gulp-inject
5 | / inject:html
6 | / endinject
7 | / inject:css
8 | / endinject
9 | body
10 |
11 | / inject:js
12 | / endinject
13 |
--------------------------------------------------------------------------------
/src/inject/fixtures/template2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject2
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/src/inject/fixtures/templateCustomName.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/src/inject/fixtures/templateCustomTags.html:
--------------------------------------------------------------------------------
1 | Hello world
2 |
--------------------------------------------------------------------------------
/src/inject/fixtures/templateTagsWithExt.html:
--------------------------------------------------------------------------------
1 | Hello world
2 |
--------------------------------------------------------------------------------
/src/inject/fixtures/templateTagsWithPath.html:
--------------------------------------------------------------------------------
1 | Hello world
2 |
--------------------------------------------------------------------------------
/src/inject/fixtures/templateWithExistingData.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Hello world
6 |
--------------------------------------------------------------------------------
/src/inject/fixtures/templateWithExistingData2.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/src/inject/fixtures/templateWithExistingData3.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | gulp-inject
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/src/inject/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var through2 = require('through2');
3 | var fancyLog = require('fancy-log');
4 | var PluginError = require('plugin-error');
5 | var colors = require('ansi-colors');
6 | var streamToArray = require('stream-to-array');
7 | var escapeStringRegexp = require('escape-string-regexp');
8 | var groupArray = require('group-array');
9 | var extname = require('../extname');
10 | var transform = require('../transform');
11 | var tags = require('../tags');
12 | var getFilepath = require('../path');
13 |
14 | var magenta = colors.magenta;
15 | var cyan = colors.cyan;
16 | var noop = function noop() {};
17 |
18 | /**
19 | * Constants
20 | */
21 | var PLUGIN_NAME = 'gulp-inject';
22 | var DEFAULT_NAME_FOR_TAGS = 'inject';
23 | var LEADING_WHITESPACE_REGEXP = /^\s*/;
24 |
25 | module.exports = exports = function (sources, opt) {
26 | if (!sources) {
27 | throw error('Missing sources stream!');
28 | }
29 | if (!opt) {
30 | opt = {};
31 | }
32 |
33 | if (opt.sort) {
34 | throw error('sort option is deprecated! Use `sort-stream` module instead!');
35 | }
36 | if (opt.templateString) {
37 | throw error('`templateString` option is deprecated! Create a virtual `vinyl` file instead!');
38 | }
39 | if (opt.transform && typeof opt.transform !== 'function') {
40 | throw error('transform option must be a function');
41 | }
42 | // Notify people of common mistakes...
43 | if (typeof opt.read !== 'undefined') {
44 | throw error('There is no `read` option. Did you mean to provide it for `gulp.src` perhaps?');
45 | }
46 |
47 | // Defaults:
48 | opt.quiet = bool(opt, 'quiet', false);
49 | opt.relative = bool(opt, 'relative', false);
50 | opt.addRootSlash = bool(opt, 'addRootSlash', !opt.relative);
51 | opt.transform = defaults(opt, 'transform', transform);
52 | opt.tags = tags();
53 | opt.name = defaults(opt, 'name', DEFAULT_NAME_FOR_TAGS);
54 | transform.selfClosingTag = bool(opt, 'selfClosingTag', false);
55 |
56 | // Is the first parameter a Vinyl File Stream:
57 | if (typeof sources.on === 'function' && typeof sources.pipe === 'function') {
58 | return handleVinylStream(sources, opt);
59 | }
60 |
61 | throw error('passing target file as a string is deprecated! Pass a vinyl file stream (i.e. use `gulp.src`)!');
62 | };
63 |
64 | function defaults(options, prop, defaultValue) {
65 | return options[prop] || defaultValue;
66 | }
67 |
68 | function bool(options, prop, defaultVal) {
69 | return typeof options[prop] === 'undefined' ? defaultVal : Boolean(options[prop]);
70 | }
71 |
72 | /**
73 | * Handle injection when files to
74 | * inject comes from a Vinyl File Stream
75 | *
76 | * @param {Stream} sources
77 | * @param {Object} opt
78 | * @returns {Stream}
79 | */
80 | function handleVinylStream(sources, opt) {
81 | var collected = streamToArray(sources);
82 |
83 | return through2.obj(function (target, enc, cb) {
84 | if (target.isStream()) {
85 | return cb(error('Streams not supported for target templates!'));
86 | }
87 | collected.then(function (collection) { // eslint-disable-line promise/prefer-await-to-then
88 | target.contents = getNewContent(target, collection, opt);
89 | this.push(target);
90 | cb();
91 | }.bind(this))
92 | .catch(function (error_) {
93 | cb(error_);
94 | });
95 | });
96 | }
97 |
98 | /**
99 | * Get new content for template
100 | * with all injections made
101 | *
102 | * @param {Object} target
103 | * @param {Array} collection
104 | * @param {Object} opt
105 | * @returns {Buffer}
106 | */
107 | function getNewContent(target, collection, opt) {
108 | var logger = opt.quiet ? noop : function (filesCount) {
109 | if (filesCount) {
110 | var pluralState = filesCount > 1 ? 's' : '';
111 | log(cyan(filesCount) + ' file' + pluralState + ' into ' + magenta(target.relative) + '.');
112 | } else {
113 | log('Nothing to inject into ' + magenta(target.relative) + '.');
114 | }
115 | };
116 | var content = String(target.contents);
117 | var targetExt = extname(target.path);
118 | var files = prepareFiles(collection, targetExt, opt, target);
119 | var filesPerTags = groupArray(files, 'tagKey');
120 | var startAndEndTags = Object.keys(filesPerTags);
121 | var matches = [];
122 | var injectedFilesCount = 0;
123 |
124 | startAndEndTags.forEach(function (tagKey) {
125 | var files = filesPerTags[tagKey];
126 | var startTag = files[0].startTag;
127 | var endTag = files[0].endTag;
128 | var tagsToInject = getTagsToInject(files, target, opt);
129 | content = inject(content, {
130 | startTag: startTag,
131 | endTag: endTag,
132 | tagsToInject: tagsToInject,
133 | removeTags: opt.removeTags,
134 | empty: opt.empty,
135 | willInject: function (filesToInject) {
136 | injectedFilesCount += filesToInject.length;
137 | },
138 | onMatch: function (match) {
139 | matches.push(match[0]);
140 | }
141 | });
142 | });
143 |
144 | logger(injectedFilesCount);
145 |
146 | if (opt.empty) {
147 | var ext = '{{ANY}}';
148 | var startTag = getTagRegExp(opt.tags.start(targetExt, ext, opt.starttag), ext, opt);
149 | var endTag = getTagRegExp(opt.tags.end(targetExt, ext, opt.endtag), ext, opt);
150 |
151 | content = inject(content, {
152 | startTag: startTag,
153 | endTag: endTag,
154 | tagsToInject: [],
155 | removeTags: opt.removeTags,
156 | empty: opt.empty,
157 | shouldAbort: function (match) {
158 | return matches.includes(match[0]);
159 | }
160 | });
161 | }
162 |
163 | return Buffer.from(content);
164 | }
165 |
166 | /**
167 | * Inject tags into content for given
168 | * start and end tags
169 | *
170 | * @param {String} content
171 | * @param {Object} opt
172 | * @returns {String}
173 | */
174 | function inject(content, opt) {
175 | var startTag = opt.startTag;
176 | var endTag = opt.endTag;
177 | var startMatch;
178 | var endMatch;
179 |
180 | /**
181 | * The content consists of:
182 | *
183 | *
184 | *
185 | *
186 | *
187 | *
188 | */
189 |
190 | while ((startMatch = startTag.exec(content)) !== null) {
191 | if (typeof opt.onMatch === 'function') {
192 | opt.onMatch(startMatch);
193 | }
194 | if (typeof opt.shouldAbort === 'function' && opt.shouldAbort(startMatch)) {
195 | continue;
196 | }
197 | // Take care of content length change:
198 | endTag.lastIndex = startTag.lastIndex;
199 | endMatch = endTag.exec(content);
200 | if (!endMatch) {
201 | throw error('Missing end tag for start tag: ' + startMatch[0]);
202 | }
203 | var toInject = opt.tagsToInject.slice();
204 |
205 | if (typeof opt.willInject === 'function') {
206 | opt.willInject(toInject);
207 | }
208 |
209 | // :
210 | var newContents = content.slice(0, startMatch.index);
211 |
212 | if (opt.removeTags) {
213 | if (opt.empty) {
214 | // Take care of content length change:
215 | startTag.lastIndex -= startMatch[0].length;
216 | }
217 | } else {
218 | // +
219 | toInject.unshift(startMatch[0]);
220 | toInject.push(endMatch[0]);
221 | }
222 | var previousInnerContent = content.slice(startTag.lastIndex, endMatch.index);
223 | var indent = getLeadingWhitespace(previousInnerContent);
224 | // :
225 | newContents += toInject.join(indent);
226 | // :
227 | newContents += content.slice(endTag.lastIndex);
228 | // Replace old content with new:
229 | content = newContents;
230 | }
231 |
232 | return content;
233 | }
234 |
235 | function getLeadingWhitespace(str) {
236 | return str.match(LEADING_WHITESPACE_REGEXP)[0];
237 | }
238 |
239 | function prepareFiles(files, targetExt, opt, target) {
240 | return files.map(function (file) {
241 | var ext = extname(file.path);
242 | var filePath = getFilepath(file, target, opt);
243 | var startTag = getTagRegExp(opt.tags.start(targetExt, ext, opt.starttag), ext, opt, filePath);
244 | var endTag = getTagRegExp(opt.tags.end(targetExt, ext, opt.endtag), ext, opt, filePath);
245 | var tagKey = String(startTag) + String(endTag);
246 | return {
247 | file: file,
248 | ext: ext,
249 | startTag: startTag,
250 | endTag: endTag,
251 | tagKey: tagKey
252 | };
253 | });
254 | }
255 |
256 | function getTagRegExp(tag, sourceExt, opt, sourcePath) {
257 | tag = makeWhiteSpaceOptional(escapeStringRegexp(tag));
258 | tag = replaceVariables(tag, {
259 | name: opt.name,
260 | path: sourcePath,
261 | ext: sourceExt === '{{ANY}}' ? '.+' : sourceExt
262 | });
263 | return new RegExp(tag, 'ig');
264 | }
265 |
266 | function replaceVariables(str, variables) {
267 | return Object.keys(variables).reduce(function (str, variable) {
268 | return str.replace(new RegExp(escapeStringRegexp(escapeStringRegexp('{{' + variable + '}}')), 'ig'), variables[variable] + '\\b');
269 | }, str);
270 | }
271 |
272 | function makeWhiteSpaceOptional(str) {
273 | return str.replace(/\s+/g, '\\s*');
274 | }
275 |
276 | function getTagsToInject(files, target, opt) {
277 | return files.reduce(function transformFile(lines, file, i, files) {
278 | var filepath = getFilepath(file.file, target, opt);
279 | var transformedContents = opt.transform(filepath, file.file, i, files.length, target);
280 | if (typeof transformedContents !== 'string') {
281 | return lines;
282 | }
283 | return lines.concat(transformedContents);
284 | }, []);
285 | }
286 |
287 | function log(message) {
288 | fancyLog.info(magenta(PLUGIN_NAME), message);
289 | }
290 |
291 | function error(message) {
292 | return new PluginError(PLUGIN_NAME, message);
293 | }
294 |
--------------------------------------------------------------------------------
/src/inject/inject_test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | 'use strict';
3 |
4 | var fs = require('fs');
5 | var path = require('path');
6 | var es = require('event-stream');
7 | var should = require('should');
8 | var fancyLog = require('fancy-log');
9 | var Vinyl = require('vinyl');
10 | var stripColor = require('strip-color');
11 | var inject = require('../../.');
12 |
13 | describe('gulp-inject', function () {
14 | var log;
15 |
16 | beforeEach(function () {
17 | log = fancyLog.info;
18 | });
19 |
20 | afterEach(function () {
21 | fancyLog.info = log;
22 | });
23 |
24 | it('should throw an error when the old api with target as string is used', function () {
25 | should(function () {
26 | inject('fixtures/template.html');
27 | }).throw();
28 | });
29 |
30 | it('should throw an error if sources stream is undefined', function () {
31 | should(function () {
32 | inject();
33 | }).throw();
34 | });
35 |
36 | it('should throw an error if `templateString` option is specified', function () {
37 | should(function () {
38 | src(['template.html'], {read: true})
39 | .pipe(inject(src(['file.js']), {templateString: ''}));
40 | }).throw();
41 | });
42 |
43 | it('should throw an error if `sort` option is specified', function () {
44 | should(function () {
45 | src(['template.html'], {read: true})
46 | .pipe(inject(src(['file.js']), {sort: function () {}}));
47 | }).throw();
48 | });
49 |
50 | it('should inject stylesheets, scripts, images, jsx and html components into desired file', function (done) {
51 | var target = src(['template.html'], {read: true});
52 | var sources = src([
53 | 'lib.js',
54 | 'component.html',
55 | 'styles.css',
56 | 'image.png',
57 | 'lib.jsx'
58 | ]);
59 |
60 | var stream = target.pipe(inject(sources));
61 |
62 | streamShouldContain(stream, ['defaults.html'], done);
63 | });
64 |
65 | it('should inject sources into multiple targets', function (done) {
66 | var target = src(['template.html', 'template2.html'], {read: true});
67 | var sources = src([
68 | 'lib.js',
69 | 'component.html',
70 | 'styles.css',
71 | 'image.png',
72 | 'lib.jsx'
73 | ]);
74 |
75 | var stream = target.pipe(inject(sources));
76 |
77 | streamShouldContain(stream, ['defaults.html', 'defaults2.html'], done);
78 | });
79 |
80 | it('should inject stylesheets, scripts and html components with `ignorePath` removed from file path', function (done) {
81 | var target = src(['template.html'], {read: true});
82 | var sources = src([
83 | 'lib.js',
84 | 'component.html',
85 | 'lib2.js',
86 | 'styles.css',
87 | 'lib.jsx'
88 | ]);
89 |
90 | var stream = target.pipe(inject(sources, {ignorePath: '/fixtures'}));
91 |
92 | streamShouldContain(stream, ['ignorePath.html'], done);
93 | });
94 |
95 | it('should inject stylesheets, scripts and html components with relative paths to target file if `relative` is truthy', function (done) {
96 | var target = src(['template.html'], {read: true});
97 | var sources = src([
98 | '../../folder/lib.js',
99 | '../../another/component.html',
100 | '../a-folder/lib2.js',
101 | '../../yet-another/styles.css',
102 | '../components/lib.jsx'
103 | ]);
104 |
105 | var stream = target.pipe(inject(sources, {relative: true}));
106 |
107 | streamShouldContain(stream, ['relative.html'], done);
108 | });
109 |
110 | it('should inject stylesheets, scripts and html components with `addPrefix` added to file path', function (done) {
111 | var target = src(['template.html'], {read: true});
112 | var sources = src([
113 | 'lib.js',
114 | 'component.html',
115 | 'lib2.js',
116 | 'styles.css',
117 | 'lib.jsx'
118 | ]);
119 |
120 | var stream = target.pipe(inject(sources, {addPrefix: 'my-test-dir'}));
121 |
122 | streamShouldContain(stream, ['addPrefix.html'], done);
123 | });
124 |
125 | it('should inject stylesheets, scripts and html components with `addSuffix` added to file path', function (done) {
126 | var target = src(['template.html'], {read: true});
127 | var sources = src([
128 | 'lib.js',
129 | 'component.html',
130 | 'lib2.js',
131 | 'styles.css',
132 | 'lib.jsx'
133 | ]);
134 |
135 | var stream = target.pipe(inject(sources, {addSuffix: '?my-test=suffix'}));
136 |
137 | streamShouldContain(stream, ['addSuffix.html'], done);
138 | });
139 |
140 | it('should inject stylesheets and html components with self closing tags if `selfClosingTag` is truthy', function (done) {
141 | var target = src(['template.html'], {read: true});
142 | var sources = src([
143 | 'component.html',
144 | 'styles.css'
145 | ]);
146 |
147 | var stream = target.pipe(inject(sources, {selfClosingTag: true}));
148 |
149 | streamShouldContain(stream, ['selfClosingTag.html'], done);
150 | });
151 |
152 | it('should inject stylesheets, scripts and html components without root slash if `addRootSlash` is `false`', function (done) {
153 | var target = src(['template.html'], {read: true});
154 | var sources = src([
155 | 'lib.js',
156 | 'component.html',
157 | 'styles.css',
158 | 'lib.jsx'
159 | ]);
160 |
161 | var stream = target.pipe(inject(sources, {addRootSlash: false}));
162 |
163 | streamShouldContain(stream, ['noRootSlash.html'], done);
164 | });
165 |
166 | it('should inject stylesheets, scripts and html components without root slash if `addRootSlash` is `false` and `ignorePath` is set', function (done) {
167 | var target = src(['template.html'], {read: true});
168 | var sources = src([
169 | 'a/folder/lib.js',
170 | 'a/folder/component.html',
171 | 'a/folder/styles.css',
172 | 'a/folder/lib.jsx'
173 | ]);
174 |
175 | var stream = target.pipe(inject(sources, {addRootSlash: false, ignorePath: 'fixtures'}));
176 |
177 | streamShouldContain(stream, ['noRootSlashWithIgnorePath.html'], done);
178 | });
179 |
180 | it('should use starttag and endtag if specified', function (done) {
181 | var target = src(['templateCustomTags.html'], {read: true});
182 | var sources = src([
183 | 'lib.js',
184 | 'lib2.js',
185 | 'style.css'
186 | ]);
187 |
188 | var stream = target.pipe(inject(sources, {
189 | ignorePath: 'fixtures',
190 | starttag: '',
191 | endtag: ''
192 | }));
193 |
194 | streamShouldContain(stream, ['customTags.html'], done);
195 | });
196 |
197 | it('should use starttag and endtag with specified name if specified', function (done) {
198 | var target = src(['templateCustomName.html'], {read: true});
199 | var sources = src([
200 | 'lib.js',
201 | 'lib2.js'
202 | ]);
203 |
204 | var stream = target.pipe(inject(sources, {name: 'head'}));
205 |
206 | streamShouldContain(stream, ['customName.html'], done);
207 | });
208 |
209 | it('should replace {{ext}} in starttag and endtag with current file extension if specified', function (done) {
210 | var target = src(['templateTagsWithExt.html'], {read: true});
211 | var sources = src([
212 | 'lib.js',
213 | 'component.html',
214 | 'lib2.js'
215 | ]);
216 |
217 | var stream = target.pipe(inject(sources, {
218 | ignorePath: 'fixtures',
219 | starttag: '',
220 | endtag: ''
221 | }));
222 |
223 | streamShouldContain(stream, ['customTagsWithExt.html'], done);
224 | });
225 |
226 | it('should replace {{path}} in starttag and endtag with current file path if specified', function (done) {
227 | var target = src(['templateTagsWithPath.html'], {read: true});
228 | var sources = src([
229 | 'template.html',
230 | 'partial.html',
231 | 'template2.html'
232 | ], {read: true});
233 |
234 | var stream = target.pipe(inject(sources, {
235 | starttag: '',
236 | endtag: '',
237 | transform: function (filePath, file) {
238 | return file.contents.toString('utf8');
239 | }
240 | }));
241 |
242 | streamShouldContain(stream, ['customTagsWithPath.html'], done);
243 | });
244 |
245 | it('should replace existing data within start and end tag', function (done) {
246 | var target = src(['templateWithExistingData.html'], {read: true});
247 | var sources = src([
248 | 'lib.js',
249 | 'component.html',
250 | 'lib2.js',
251 | 'styles.css'
252 | ]);
253 |
254 | var stream = target.pipe(inject(sources, {
255 | ignorePath: 'fixtures'
256 | }));
257 |
258 | streamShouldContain(stream, ['existingData.html'], done);
259 | });
260 |
261 | it('should use custom transform function for each file if specified', function (done) {
262 | var target = src(['template.json'], {read: true});
263 | var sources = src([
264 | 'lib.js',
265 | 'component.html',
266 | 'lib2.js',
267 | 'styles.css'
268 | ]);
269 |
270 | var stream = target.pipe(inject(sources, {
271 | ignorePath: 'fixtures',
272 | starttag: '"{{ext}}": [',
273 | endtag: ']',
274 | transform: function (srcPath, file, i, length) {
275 | return ' "' + srcPath + '"' + (i + 1 < length ? ',' : '');
276 | }
277 | }));
278 |
279 | streamShouldContain(stream, ['customTransform.json'], done);
280 | });
281 |
282 | it('should use special default tags when injecting into jsx files', function (done) {
283 | var target = src(['template.jsx'], {read: true});
284 | var sources = src([
285 | 'lib.js',
286 | 'component.html',
287 | 'styles.css'
288 | ]);
289 |
290 | var stream = target.pipe(inject(sources));
291 |
292 | streamShouldContain(stream, ['defaults.jsx'], done);
293 | });
294 |
295 | it('should use special default tags when injecting into jade files', function (done) {
296 | var target = src(['template.jade'], {read: true});
297 | var sources = src([
298 | 'lib.js',
299 | 'component.html',
300 | 'styles.css'
301 | ]);
302 |
303 | var stream = target.pipe(inject(sources));
304 |
305 | streamShouldContain(stream, ['defaults.jade'], done);
306 | });
307 |
308 | it('should use special default tags when injecting into pug files', function (done) {
309 | var target = src(['template.pug'], {read: true});
310 | var sources = src([
311 | 'lib.js',
312 | 'component.html',
313 | 'styles.css'
314 | ]);
315 |
316 | var stream = target.pipe(inject(sources));
317 |
318 | streamShouldContain(stream, ['defaults.pug'], done);
319 | });
320 |
321 | it('should be able to inject jsx into jade files (Issue #144)', function (done) {
322 | var target = src(['issue144.jade'], {read: true});
323 | var sources = src([
324 | 'lib.js',
325 | 'component.jsx'
326 | ]);
327 |
328 | var stream = target.pipe(inject(sources));
329 |
330 | streamShouldContain(stream, ['issue144.jade'], done);
331 | });
332 |
333 | it('should be able to inject jsx into pug files (Issue #144)', function (done) {
334 | var target = src(['issue144.pug'], {read: true});
335 | var sources = src([
336 | 'lib.js',
337 | 'component.jsx'
338 | ]);
339 |
340 | var stream = target.pipe(inject(sources));
341 |
342 | streamShouldContain(stream, ['issue144.pug'], done);
343 | });
344 |
345 | it('should use special default tags when injecting into slm files', function (done) {
346 | var target = src(['template.slm'], {read: true});
347 | var sources = src([
348 | 'lib.js',
349 | 'component.html',
350 | 'styles.css'
351 | ]);
352 |
353 | var stream = target.pipe(inject(sources));
354 |
355 | streamShouldContain(stream, ['defaults.slm'], done);
356 | });
357 |
358 | it('should use special default tags when injecting into slim files', function (done) {
359 | var target = src(['template.slim'], {read: true});
360 | var sources = src([
361 | 'lib.js',
362 | 'component.html',
363 | 'styles.css'
364 | ]);
365 |
366 | var stream = target.pipe(inject(sources));
367 |
368 | streamShouldContain(stream, ['defaults.slim'], done);
369 | });
370 |
371 | it('should use special default tags when injecting into haml files', function (done) {
372 | var target = src(['template.haml'], {read: true});
373 | var sources = src([
374 | 'lib.js',
375 | 'component.html',
376 | 'styles.css'
377 | ]);
378 |
379 | var stream = target.pipe(inject(sources));
380 |
381 | streamShouldContain(stream, ['defaults.haml'], done);
382 | });
383 |
384 | it('should use special default tags when injecting into less files', function (done) {
385 | var target = src(['template.less'], {read: true});
386 | var sources = src([
387 | 'lib.css',
388 | 'component.less',
389 | 'styles.less'
390 | ]);
391 |
392 | var stream = target.pipe(inject(sources));
393 |
394 | streamShouldContain(stream, ['defaults.less'], done);
395 | });
396 |
397 | it('should use special default tags when injecting into sass files', function (done) {
398 | var target = src(['template.sass'], {read: true});
399 | var sources = src([
400 | 'lib.css',
401 | 'component.sass',
402 | 'styles.sass',
403 | 'component.scss',
404 | 'styles.scss'
405 | ]);
406 |
407 | var stream = target.pipe(inject(sources));
408 |
409 | streamShouldContain(stream, ['defaults.sass'], done);
410 | });
411 |
412 | it('should use special default tags when injecting into scss files', function (done) {
413 | var target = src(['template.scss'], {read: true});
414 | var sources = src([
415 | 'lib.css',
416 | 'component.sass',
417 | 'styles.sass',
418 | 'component.scss',
419 | 'styles.scss'
420 | ]);
421 |
422 | var stream = target.pipe(inject(sources));
423 |
424 | streamShouldContain(stream, ['defaults.scss'], done);
425 | });
426 |
427 | it('should be able to chain inject calls with different names without overrides (Issue #39)', function (done) {
428 | var target = src(['issue39.html'], {read: true});
429 | var sources1 = src([
430 | 'lib1.js',
431 | 'lib3.js'
432 | ]);
433 | var sources2 = src([
434 | 'lib2.js',
435 | 'lib4.js'
436 | ]);
437 |
438 | var stream = target
439 | .pipe(inject(sources1, {name: 'head'}))
440 | .pipe(inject(sources2));
441 |
442 | streamShouldContain(stream, ['issue39.html'], done);
443 | });
444 |
445 | it('should be able to inject hashed files (Issue #71)', function (done) {
446 | var target = src(['issue71.html'], {read: true});
447 | var sources = src([
448 | 'lib.js?abcdef0123456789',
449 | 'styles.css?0123456789abcdef'
450 | ]);
451 |
452 | var stream = target.pipe(inject(sources));
453 |
454 | streamShouldContain(stream, ['issue71.html'], done);
455 | });
456 |
457 | it('should be able to inject when tags are missing whitespace (Issue #56)', function (done) {
458 | var target = src(['issue56.html'], {read: true});
459 | var sources = src([
460 | 'lib.js'
461 | ]);
462 |
463 | var stream = target.pipe(inject(sources));
464 |
465 | streamShouldContain(stream, ['issue56.html'], done);
466 | });
467 |
468 | it('should not crash when transform function returns undefined (Issue #74)', function (done) {
469 | var target = src(['issue74.html'], {read: true});
470 | var sources = src([
471 | 'lib.js'
472 | ]);
473 |
474 | var stream = target.pipe(inject(sources, {transform: function () {}}));
475 |
476 | streamShouldContain(stream, ['issue74.html'], done);
477 | });
478 |
479 | it('should be able to remove tags if removeTags option is set', function (done) {
480 | var target = src(['template.html'], {read: true});
481 | var sources = src([
482 | 'lib.js',
483 | 'component.html',
484 | 'styles.css',
485 | 'image.png',
486 | 'lib.jsx'
487 | ]);
488 |
489 | var stream = target.pipe(inject(sources, {removeTags: true}));
490 |
491 | streamShouldContain(stream, ['removeTags.html'], done);
492 | });
493 |
494 | it('should be able to remove tags without removing whitespace (issue #177)', function (done) {
495 | var target = src(['template.html'], {read: true});
496 | var sources = src([
497 | 'lib.js',
498 | 'component.html',
499 | 'styles.css',
500 | 'morestyles.css',
501 | 'andevenmore.css',
502 | 'image.png',
503 | 'lib.jsx'
504 | ]);
505 |
506 | var stream = target.pipe(inject(sources, {removeTags: true}));
507 |
508 | streamShouldContain(stream, ['issue177.html'], done);
509 | });
510 |
511 | it('should not produce log output if quiet option is set', function (done) {
512 | var logOutput = [];
513 | fancyLog.info = function () {
514 | logOutput.push(arguments);
515 | };
516 |
517 | var target = src(['template.html'], {read: true});
518 | var sources = src([
519 | 'lib.js',
520 | 'component.html',
521 | 'styles.css',
522 | 'image.png'
523 | ]);
524 |
525 | var stream = target.pipe(inject(sources, {quiet: true}));
526 |
527 | // Dummy data reader to make the `end` event be triggered
528 | stream.on('data', function () {
529 | });
530 |
531 | stream.on('end', function () {
532 | logOutput.should.have.length(0);
533 | done();
534 | });
535 | });
536 |
537 | it('should produce log output if quiet option is not set', function (done) {
538 | var logOutput = [];
539 | fancyLog.info = function () {
540 | logOutput.push(arguments);
541 | };
542 |
543 | var target = src(['template.html'], {read: true});
544 | var sources = src([
545 | 'lib.js',
546 | 'component.html',
547 | 'styles.css',
548 | 'image.png'
549 | ]);
550 |
551 | var stream = target.pipe(inject(sources));
552 |
553 | // Dummy data reader to make the `end` event be triggered
554 | stream.on('data', function () {
555 | });
556 |
557 | stream.on('end', function () {
558 | logOutput.should.have.length(1);
559 | done();
560 | });
561 | });
562 |
563 | it('should produce log output only for files actually injected (issue #184)', function (done) {
564 | var logOutput = [];
565 | fancyLog.info = function (a, b) {
566 | logOutput.push(a + ' ' + b);
567 | };
568 |
569 | var target = src(['template2.html'], {read: true});
570 | var sources = src([
571 | 'lib.js',
572 | 'component.html',
573 | 'styles.css',
574 | 'image.png'
575 | ]);
576 |
577 | var stream = target.pipe(inject(sources));
578 |
579 | // Dummy data reader to make the `end` event be triggered
580 | stream.on('data', function () {
581 | });
582 |
583 | stream.on('end', function () {
584 | logOutput.should.have.length(1);
585 | stripColor(logOutput[0]).should.equal('gulp-inject 1 file into template2.html.');
586 | done();
587 | });
588 | });
589 |
590 | it('should produce log output for multiple files actually injected (issue #192)', function (done) {
591 | var logOutput = [];
592 | fancyLog.info = function (a, b) {
593 | logOutput.push(a + ' ' + b);
594 | };
595 |
596 | var target = src(['template2.html'], {read: true});
597 | var sources = src([
598 | 'styles.css',
599 | 'app.css'
600 | ]);
601 |
602 | var stream = target.pipe(inject(sources));
603 |
604 | // Dummy data reader to make the `end` event be triggered
605 | stream.on('data', function () {
606 | });
607 |
608 | stream.on('end', function () {
609 | logOutput.should.have.length(1);
610 | stripColor(logOutput[0]).should.equal('gulp-inject 2 files into template2.html.');
611 | done();
612 | });
613 | });
614 |
615 | it('should be able to modify only the filepath (Issue #107)', function (done) {
616 | var version = '1.0.0';
617 |
618 | var target = src(['issue107.html'], {read: true});
619 | var sources = src([
620 | 'lib.js'
621 | ]);
622 |
623 | var stream = target.pipe(inject(sources, {
624 | transform: function (filepath) {
625 | arguments[0] = filepath + '?v=' + version;
626 | return inject.transform.apply(inject.transform, arguments);
627 | }
628 | }));
629 |
630 | streamShouldContain(stream, ['issue107.html'], done);
631 | });
632 |
633 | it('should be able to inject source maps (Issue #176)', function (done) {
634 | var target = src(['issue176.html'], {read: true});
635 | var sources = src([
636 | 'lib.js',
637 | 'lib.js.map'
638 | ]);
639 |
640 | var stream = target.pipe(inject(sources));
641 |
642 | streamShouldContain(stream, ['issue176.html'], done);
643 | });
644 |
645 | it('should be able to empty tags when there are no files for that tag and empty option is set', function (done) {
646 | var target = src(['templateWithExistingData2.html'], {read: true});
647 | var sources = src([
648 | 'lib.js'
649 | ]);
650 |
651 | var stream = target.pipe(inject(sources, {empty: true}));
652 |
653 | streamShouldContain(stream, ['emptyTags.html'], done);
654 | });
655 |
656 | it('should be able both leave and replace tag contents when there are no files for some tags and empty option is not set', function (done) {
657 | var target = src(['templateWithExistingData2.html'], {read: true});
658 | var sources = src([
659 | 'picture.png'
660 | ]);
661 |
662 | var stream = target.pipe(inject(sources));
663 |
664 | streamShouldContain(stream, ['existingDataAndReplaced.html'], done);
665 | });
666 |
667 | it('should be able to empty all tags when there are no files at all and empty option is set', function (done) {
668 | var target = src(['templateWithExistingData2.html'], {read: true});
669 | var sources = src([]);
670 |
671 | var stream = target.pipe(inject(sources, {empty: true}));
672 |
673 | streamShouldContain(stream, ['emptyTags2.html'], done);
674 | });
675 |
676 | it('should leave all tags when there are no files at all and empty option is not set', function (done) {
677 | var target = src(['templateWithExistingData2.html'], {read: true});
678 | var sources = src([]);
679 |
680 | var stream = target.pipe(inject(sources));
681 |
682 | streamShouldContain(stream, ['templateWithExistingData2.html'], done);
683 | });
684 |
685 | it('should be able to remove and empty tags when there are no files for that tag and empty and removeTags option is set', function (done) {
686 | var target = src(['templateWithExistingData2.html'], {read: true});
687 | var sources = src([
688 | 'lib.js'
689 | ]);
690 |
691 | var stream = target.pipe(inject(sources, {empty: true, removeTags: true}));
692 |
693 | streamShouldContain(stream, ['removeAndEmptyTags.html'], done);
694 | });
695 |
696 | it('should be able to empty custom tags when there are no files at all and empty option is set', function (done) {
697 | var target = src(['templateWithExistingData3.html'], {read: true});
698 | var sources = src([]);
699 |
700 | var stream = target.pipe(inject(sources, {empty: true, starttag: '', endtag: ''}));
701 |
702 | streamShouldContain(stream, ['emptyTags3.html'], done);
703 | });
704 | });
705 |
706 | function src(files, opt) {
707 | opt = opt || {};
708 | var stream = es.readArray(files.map(function (file) {
709 | return fixture(file, opt.read);
710 | }));
711 | return stream;
712 | }
713 |
714 | function streamShouldContain(stream, files, done) {
715 | var received = 0;
716 |
717 | stream.on('error', function (error) {
718 | should.exist(error);
719 | done(error);
720 | });
721 |
722 | var contents = files.map(function (file) {
723 | return String(expectedFile(file).contents);
724 | });
725 |
726 | stream.on('data', function (newFile) {
727 | should.exist(newFile);
728 | should.exist(newFile.contents);
729 |
730 | if (contents.length === 1) {
731 | String(newFile.contents).should.equal(contents[0]);
732 | } else {
733 | contents.should.containEql(String(newFile.contents));
734 | }
735 |
736 | if (++received === files.length) {
737 | done();
738 | }
739 | });
740 | }
741 |
742 | function expectedFile(file) {
743 | var filepath = path.resolve(__dirname, 'expected', file);
744 | return new Vinyl({
745 | path: filepath,
746 | cwd: __dirname,
747 | base: path.resolve(__dirname, 'expected', path.dirname(file)),
748 | contents: fs.readFileSync(filepath)
749 | });
750 | }
751 |
752 | function fixture(file, read) {
753 | var filepath = path.resolve(__dirname, 'fixtures', file);
754 | return new Vinyl({
755 | path: filepath,
756 | cwd: __dirname,
757 | base: path.resolve(__dirname, 'fixtures', path.dirname(file)),
758 | contents: read ? fs.readFileSync(filepath) : null
759 | });
760 | }
761 |
--------------------------------------------------------------------------------
/src/path/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 | var path = require('path');
3 | var arrify = require('arrify');
4 |
5 | module.exports = exports = function getFilepath(sourceFile, targetFile, opt) {
6 | opt = opt || {};
7 | var ignorePath = arrify(opt.ignorePath);
8 | var base = opt.relative ? path.dirname(addRootSlash(unixify(targetFile.path))) : addRootSlash(unixify(sourceFile.cwd));
9 |
10 | var filepath = unixify(path.relative(base, addRootSlash(unixify(sourceFile.path))));
11 |
12 | if (ignorePath.length) {
13 | filepath = removeBasePath(ignorePath, filepath);
14 | }
15 |
16 | if (opt.addPrefix) {
17 | filepath = addPrefix(filepath, opt.addPrefix);
18 | }
19 |
20 | if (opt.addRootSlash) {
21 | filepath = addRootSlash(filepath);
22 | } else if (!opt.addPrefix) {
23 | filepath = removeRootSlash(filepath);
24 | }
25 |
26 | if (opt.addSuffix) {
27 | filepath = addSuffix(filepath, opt.addSuffix);
28 | }
29 |
30 | return filepath;
31 | };
32 |
33 | function unixify(filepath) {
34 | return filepath.replace(/\\/g, '/');
35 | }
36 | function addRootSlash(filepath) {
37 | return filepath.replace(/^\/*([^\/])/, '/$1');
38 | }
39 | function removeRootSlash(filepath) {
40 | return filepath.replace(/^\/+/, '');
41 | }
42 | function addPrefix(filepath, prefix) {
43 | return prefix + addRootSlash(filepath);
44 | }
45 | function addSuffix(filepath, suffix) {
46 | return filepath + suffix;
47 | }
48 |
49 | function removeBasePath(basedirs, filepath) {
50 | return basedirs.map(unixify).reduce(function (path, remove) {
51 | if (path[0] === '/' && remove[0] !== '/') {
52 | remove = '/' + remove;
53 | }
54 | if (path[0] !== '/' && remove[0] === '/') {
55 | path = '/' + path;
56 | }
57 | if (remove && path.indexOf(remove) === 0) {
58 | return path.slice(remove.length);
59 | }
60 | return path;
61 | }, filepath);
62 | }
63 |
--------------------------------------------------------------------------------
/src/path/path_test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | 'use strict';
3 | var path = require('path');
4 | var Vinyl = require('vinyl');
5 | var getFilepath = require('./');
6 |
7 | describe('getFilepath', function () {
8 | describe('(relative=false)', function () {
9 | it('returns the path relative to the source file\'s cwd', function () {
10 | var source = new Vinyl({
11 | cwd: __dirname,
12 | path: path.join(__dirname, 'dir', 'file.js'),
13 | base: path.join(__dirname, 'dir')
14 | });
15 |
16 | var filepath = getFilepath(source);
17 | filepath.should.equal('dir/file.js');
18 | });
19 |
20 | it('returns the unixified path relative to the source file\'s cwd', function () {
21 | var source = new Vinyl({
22 | cwd: 'C:\\a\\folder',
23 | path: 'C:\\a\\folder\\dir\\file.js',
24 | base: 'C:\\a\\folder\\dir'
25 | });
26 |
27 | var filepath = getFilepath(source);
28 | filepath.should.equal('dir/file.js');
29 | });
30 | });
31 |
32 | describe('(relative=true)', function () {
33 | it('returns the path relative to the target file\'s directory', function () {
34 | var target = new Vinyl({
35 | cwd: __dirname,
36 | path: path.join(__dirname, 'dir1', 'index.html'),
37 | base: path.join(__dirname, 'dir1')
38 | });
39 | var source = new Vinyl({
40 | cwd: __dirname,
41 | path: path.join(__dirname, 'dir2', 'file.js'),
42 | base: path.join(__dirname, 'dir2')
43 | });
44 |
45 | var filepath = getFilepath(source, target, {relative: true});
46 | filepath.should.equal('../dir2/file.js');
47 | });
48 |
49 | it('returns the unixified path relative to the source file\'s cwd', function () {
50 | var target = new Vinyl({
51 | cwd: 'C:\\a\\folder',
52 | path: 'C:\\a\\folder\\dir1\\index.html',
53 | base: 'C:\\a\\folder\\dir1'
54 | });
55 | var source = new Vinyl({
56 | cwd: 'C:\\a\\folder',
57 | path: 'C:\\a\\folder\\dir2\\file.js',
58 | base: 'C:\\a\\folder\\dir2'
59 | });
60 |
61 | var filepath = getFilepath(source, target, {relative: true});
62 | filepath.should.equal('../dir2/file.js');
63 | });
64 | });
65 |
66 | describe('(ignorePath)', function () {
67 | it('removes the provided `ignorePath` from the beginning of the path', function () {
68 | var source = new Vinyl({
69 | cwd: __dirname,
70 | path: path.join(__dirname, 'dir', 'file.js'),
71 | base: path.join(__dirname, 'dir')
72 | });
73 |
74 | var filepath = getFilepath(source, null, {ignorePath: 'dir'});
75 | filepath.should.equal('file.js');
76 | });
77 |
78 | it('removes the provided `ignorePath` even if it both begins and ends in a `/` from the beginning of the path', function () {
79 | var source = new Vinyl({
80 | cwd: __dirname,
81 | path: path.join(__dirname, 'dir', 'file.js'),
82 | base: path.join(__dirname, 'dir')
83 | });
84 |
85 | var filepath = getFilepath(source, null, {ignorePath: '/dir/'});
86 | filepath.should.equal('file.js');
87 | });
88 |
89 | it('removes the provided `ignorePath`s from the beginning of the path', function () {
90 | var source = new Vinyl({
91 | cwd: __dirname,
92 | path: path.join(__dirname, 'dir', 'file.js'),
93 | base: path.join(__dirname, 'dir')
94 | });
95 |
96 | var filepath = getFilepath(source, null, {ignorePath: ['dir', 'dir2']});
97 | filepath.should.equal('file.js');
98 | });
99 |
100 | it('removes the provided `ignorePath` unixified from the beginning of the path', function () {
101 | var source = new Vinyl({
102 | cwd: __dirname,
103 | path: path.join(__dirname, 'dir', 'deep', 'file.js'),
104 | base: path.join(__dirname, 'dir', 'deep')
105 | });
106 |
107 | var filepath = getFilepath(source, null, {ignorePath: ['\\dir\\deep']});
108 | filepath.should.equal('file.js');
109 | });
110 |
111 | it('removes the provided `ignorePath` unixified from the beginning of a unixified path', function () {
112 | var source = new Vinyl({
113 | cwd: 'C:\\a\\folder',
114 | path: 'C:\\a\\folder\\dir\\deep\\file.js',
115 | base: 'C:\\a\\folder\\dir\\deep'
116 | });
117 |
118 | var filepath = getFilepath(source, null, {ignorePath: ['\\dir\\deep']});
119 | filepath.should.equal('file.js');
120 | });
121 |
122 | it('removes the provided `ignorePath` from the beginning of a unixified path', function () {
123 | var source = new Vinyl({
124 | cwd: 'C:\\a\\folder',
125 | path: 'C:\\a\\folder\\dir\\deep\\file.js',
126 | base: 'C:\\a\\folder\\dir\\deep'
127 | });
128 |
129 | var filepath = getFilepath(source, null, {ignorePath: ['dir/deep']});
130 | filepath.should.equal('file.js');
131 | });
132 | });
133 |
134 | describe('(addRootSlash=true)', function () {
135 | it('prepends the path with a `/`', function () {
136 | var source = new Vinyl({
137 | cwd: __dirname,
138 | path: path.join(__dirname, 'dir', 'file.js'),
139 | base: path.join(__dirname, 'dir')
140 | });
141 |
142 | var filepath = getFilepath(source, null, {addRootSlash: true});
143 | filepath.should.equal('/dir/file.js');
144 | });
145 | });
146 |
147 | describe('(addPrefix)', function () {
148 | it('prepends the prefix and a `/` to the path', function () {
149 | var source = new Vinyl({
150 | cwd: __dirname,
151 | path: path.join(__dirname, 'dir', 'file.js'),
152 | base: path.join(__dirname, 'dir')
153 | });
154 |
155 | var filepath = getFilepath(source, null, {addPrefix: 'hello'});
156 | filepath.should.equal('hello/dir/file.js');
157 | });
158 |
159 | it('keeps any leading `/` from the prefix', function () {
160 | var source = new Vinyl({
161 | cwd: __dirname,
162 | path: path.join(__dirname, 'dir', 'file.js'),
163 | base: path.join(__dirname, 'dir')
164 | });
165 |
166 | var filepath = getFilepath(source, null, {addPrefix: '/hello'});
167 | filepath.should.equal('/hello/dir/file.js');
168 | });
169 | });
170 |
171 | describe('(addSuffix)', function () {
172 | it('appends the suffix to the path', function () {
173 | var source = new Vinyl({
174 | cwd: __dirname,
175 | path: path.join(__dirname, 'dir', 'file.js'),
176 | base: path.join(__dirname, 'dir')
177 | });
178 |
179 | var filepath = getFilepath(source, null, {addSuffix: '?hello'});
180 | filepath.should.equal('dir/file.js?hello');
181 | });
182 | });
183 | });
184 |
--------------------------------------------------------------------------------
/src/tags/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Constants
3 | */
4 | var DEFAULT_TARGET = 'html';
5 | var DEFAULTS = {
6 | STARTS: {
7 | html: '',
8 | jsx: '{/* {{name}}:{{ext}} */}',
9 | jade: '//- {{name}}:{{ext}}',
10 | pug: '//- {{name}}:{{ext}}',
11 | slm: '/ {{name}}:{{ext}}',
12 | slim: '/ {{name}}:{{ext}}',
13 | haml: '-# {{name}}:{{ext}}',
14 | less: '/* {{name}}:{{ext}} */',
15 | sass: '/* {{name}}:{{ext}} */',
16 | scss: '/* {{name}}:{{ext}} */'
17 | },
18 | ENDS: {
19 | html: '',
20 | jsx: '{/* endinject */}',
21 | jade: '//- endinject',
22 | pug: '//- endinject',
23 | slm: '/ endinject',
24 | slim: '/ endinject',
25 | haml: '-# endinject',
26 | less: '/* endinject */',
27 | sass: '/* endinject */',
28 | scss: '/* endinject */'
29 | }
30 | };
31 |
32 | module.exports = function tags() {
33 | return {
34 | start: getTag.bind(null, DEFAULTS.STARTS),
35 | end: getTag.bind(null, DEFAULTS.ENDS)
36 | };
37 | };
38 |
39 | function getTag(defaults, targetExt, sourceExt, defaultValue) {
40 | var tag = defaultValue;
41 | if (!tag) {
42 | tag = defaults[targetExt] || defaults[DEFAULT_TARGET];
43 | } else if (typeof tag === 'function') {
44 | tag = tag(targetExt, sourceExt);
45 | }
46 | return tag;
47 | }
48 |
--------------------------------------------------------------------------------
/src/tags/tags_test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | /* eslint max-nested-callbacks:[1, 5] */
3 | 'use strict';
4 | var should = require('should');
5 |
6 | describe('tags', function () {
7 | var tags;
8 | var tagsModule;
9 |
10 | it('should not crash when required', function () {
11 | should(function () {
12 | tagsModule = require('./');
13 | }).not.throw();
14 | });
15 |
16 | beforeEach(function () {
17 | if (!tagsModule) {
18 | return;
19 | }
20 | tags = tagsModule();
21 | });
22 |
23 | describe('start()', function () {
24 | describe('with no default', function () {
25 | it('should return html comment tag for html target files', function () {
26 | tags.start('html').should.equal('');
27 | });
28 |
29 | it('should return jsx comments for jsx target files', function () {
30 | tags.start('jsx').should.equal('{/* {{name}}:{{ext}} */}');
31 | });
32 |
33 | it('should return jade comments for jade target files', function () {
34 | tags.start('jade', 'css').should.equal('//- {{name}}:{{ext}}');
35 | });
36 |
37 | it('should return pug comments for pug target files', function () {
38 | tags.start('pug', 'css').should.equal('//- {{name}}:{{ext}}');
39 | });
40 |
41 | it('should return slm comments for slm target files', function () {
42 | tags.start('slm').should.equal('/ {{name}}:{{ext}}');
43 | });
44 |
45 | it('should return haml comment tag for haml files', function () {
46 | tags.start('haml').should.equal('-# {{name}}:{{ext}}');
47 | });
48 |
49 | it('should return less comment tag for less files', function () {
50 | tags.start('less').should.equal('/* {{name}}:{{ext}} */');
51 | });
52 |
53 | it('should return sass comment tag for sass files', function () {
54 | tags.start('sass').should.equal('/* {{name}}:{{ext}} */');
55 | });
56 |
57 | it('should return sass comment tag for sass files', function () {
58 | tags.start('scss').should.equal('/* {{name}}:{{ext}} */');
59 | });
60 |
61 | it('should return html comment tag for other target files', function () {
62 | tags.start('txt').should.equal('');
63 | });
64 | });
65 |
66 | describe('given a string as default', function () {
67 | it('should return the string', function () {
68 | tags.start('json', 'css', '"{{ext}}": [').should.equal('"{{ext}}": [');
69 | });
70 | });
71 |
72 | describe('given a function as default', function () {
73 | it('should receive target file and source file extensions as parameters', function () {
74 | tags.start('html', 'css', function (targetExt, sourceExt) {
75 | targetExt.should.equal('html');
76 | sourceExt.should.equal('css');
77 | });
78 | });
79 |
80 | it('should return result of function untouched', function () {
81 | tags.start('json', 'css', function () {
82 | return '"{{ext}}": [';
83 | }).should.equal('"{{ext}}": [');
84 | });
85 | });
86 | });
87 |
88 | describe('end()', function () {
89 | describe('with no default', function () {
90 | it('should return html comment tag for html target files', function () {
91 | tags.end('html').should.equal('');
92 | });
93 |
94 | it('should return jsx comments for jsx target files', function () {
95 | tags.end('jsx').should.equal('{/* endinject */}');
96 | });
97 |
98 | it('should return jade comments for jade target files', function () {
99 | tags.end('jade').should.equal('//- endinject');
100 | });
101 |
102 | it('should return pug comments for pug target files', function () {
103 | tags.end('pug').should.equal('//- endinject');
104 | });
105 |
106 | it('should return slm comments for slm target files', function () {
107 | tags.end('slm').should.equal('/ endinject');
108 | });
109 |
110 | it('should return haml comments for haml target files', function () {
111 | tags.end('haml').should.equal('-# endinject');
112 | });
113 |
114 | it('should return haml comments for haml target files', function () {
115 | tags.end('less').should.equal('/* endinject */');
116 | });
117 |
118 | it('should return sass comments for sass target files', function () {
119 | tags.end('sass').should.equal('/* endinject */');
120 | });
121 |
122 | it('should return scss comments for scss target files', function () {
123 | tags.end('scss').should.equal('/* endinject */');
124 | });
125 |
126 | it('should return html comment tag for other target files', function () {
127 | tags.end('txt').should.equal('');
128 | });
129 | });
130 |
131 | describe('given a string as default', function () {
132 | it('should return the string', function () {
133 | tags.end('json', 'css', '] // {{ext}}').should.equal('] // {{ext}}');
134 | });
135 | });
136 |
137 | describe('given a function as default', function () {
138 | it('should receive target file and source file extensions as parameters', function () {
139 | tags.end('html', 'css', function (targetExt, sourceExt) {
140 | targetExt.should.equal('html');
141 | sourceExt.should.equal('css');
142 | });
143 | });
144 |
145 | it('should return result of function untouched', function () {
146 | tags.end('json', 'css', function () {
147 | return '] // {{ext}}';
148 | }).should.equal('] // {{ext}}');
149 | });
150 | });
151 | });
152 | });
153 |
--------------------------------------------------------------------------------
/src/transform/index.js:
--------------------------------------------------------------------------------
1 | /* eslint max-params:[1, 5] */
2 | 'use strict';
3 | var extname = require('../extname');
4 |
5 | /**
6 | * Constants
7 | */
8 | var TARGET_TYPES = ['html', 'jade', 'pug', 'slm', 'slim', 'jsx', 'haml', 'less', 'sass', 'scss', 'twig'];
9 | var IMAGES = ['jpeg', 'jpg', 'png', 'gif'];
10 | var DEFAULT_TARGET = TARGET_TYPES[0];
11 |
12 | /**
13 | * Transform module
14 | */
15 | var transform = module.exports = exports = function (filepath, i, length, sourceFile, targetFile) {
16 | var type;
17 | if (targetFile && targetFile.path) {
18 | var ext = extname(targetFile.path);
19 | type = typeFromExt(ext);
20 | }
21 | if (!isTargetType(type)) {
22 | type = DEFAULT_TARGET;
23 | }
24 | var func = transform[type];
25 | if (func) {
26 | return func.apply(transform, arguments);
27 | }
28 | };
29 |
30 | /**
31 | * Options
32 | */
33 |
34 | transform.selfClosingTag = false;
35 |
36 | /**
37 | * Transform functions
38 | */
39 | TARGET_TYPES.forEach(function (targetType) {
40 | transform[targetType] = function (filepath) {
41 | var ext = extname(filepath);
42 | var type = typeFromExt(ext);
43 | var func = transform[targetType][type];
44 | if (func) {
45 | return func.apply(transform[targetType], arguments);
46 | }
47 | };
48 | });
49 |
50 | transform.html.css = function (filepath) {
51 | return '';
56 | };
57 | transform.html.map = transform.html.js;
58 |
59 | transform.html.jsx = function (filepath) {
60 | return '';
61 | };
62 |
63 | transform.html.html = function (filepath) {
64 | return '';
69 | };
70 |
71 | transform.html.image = function (filepath) {
72 | return '
';
204 | };
205 |
206 | /**
207 | * Transformations for jsx is like html
208 | * but always with self closing tags, invalid jsx otherwise
209 | */
210 | Object.keys(transform.html).forEach(function (type) {
211 | transform.jsx[type] = function () {
212 | var originalOption = transform.selfClosingTag;
213 | transform.selfClosingTag = true;
214 | var result = transform.html[type].apply(transform.html, arguments);
215 | transform.selfClosingTag = originalOption;
216 | return result;
217 | };
218 | });
219 |
220 | function end() {
221 | return transform.selfClosingTag ? ' />' : '>';
222 | }
223 |
224 | function typeFromExt(ext) {
225 | ext = ext.toLowerCase();
226 | if (isImage(ext)) {
227 | return 'image';
228 | }
229 | return ext;
230 | }
231 |
232 | function isImage(ext) {
233 | return IMAGES.includes(ext);
234 | }
235 |
236 | function isTargetType(type) {
237 | if (!type) {
238 | return false;
239 | }
240 | return TARGET_TYPES.includes(type);
241 | }
242 |
--------------------------------------------------------------------------------
/src/transform/transform_test.js:
--------------------------------------------------------------------------------
1 | /* eslint-env mocha */
2 | 'use strict';
3 | var path = require('path');
4 | var fs = require('fs');
5 | var should = require('should');
6 | var Vinyl = require('vinyl');
7 |
8 | describe('transform', function () {
9 | var transform;
10 |
11 | it('should not crash when required', function () {
12 | should(function () {
13 | transform = require('./');
14 | }).not.throw();
15 | });
16 |
17 | it('should be a function', function () {
18 | transform.should.be.type('function');
19 | });
20 |
21 | describe('targets', function () {
22 | it('should have a transform function for html target files', function () {
23 | transform.html.should.be.type('function');
24 | });
25 |
26 | it('should have a transform function for react javascript (jsx) target files', function () {
27 | transform.jsx.should.be.type('function');
28 | });
29 |
30 | it('should have a transform function for jade target files', function () {
31 | transform.jade.should.be.type('function');
32 | });
33 |
34 | it('should have a transform function for pug target files', function () {
35 | transform.pug.should.be.type('function');
36 | });
37 |
38 | it('should have a transform function for slm target files', function () {
39 | transform.slm.should.be.type('function');
40 | });
41 |
42 | it('should have a transform function for haml target files', function () {
43 | transform.haml.should.be.type('function');
44 | });
45 |
46 | it('should have a transform function for less target files', function () {
47 | transform.less.should.be.type('function');
48 | });
49 |
50 | it('should have a transform function for sass target files', function () {
51 | transform.sass.should.be.type('function');
52 | });
53 |
54 | it('should have a transform function for scss target files', function () {
55 | transform.scss.should.be.type('function');
56 | });
57 | });
58 |
59 | describe('html as target', function () {
60 | it('should transform css to a link tag', function () {
61 | transform.html.css.should.be.type('function');
62 | transform.html.css('test-file.css').should.equal('');
63 | });
64 |
65 | it('should transform html to a link tag', function () {
66 | transform.html.html.should.be.type('function');
67 | transform.html.html('test-file.html').should.equal('');
68 | });
69 |
70 | it('should transform javascript to a script tag', function () {
71 | transform.html.js.should.be.type('function');
72 | transform.html.js('test-file.js').should.equal('');
73 | });
74 |
75 | it('should transform jsx to a script tag', function () {
76 | transform.html.jsx.should.be.type('function');
77 | transform.html.jsx('test-file.jsx').should.equal('');
78 | });
79 |
80 | it('should transform coffeescript to a script tag', function () {
81 | transform.html.coffee.should.be.type('function');
82 | transform.html.coffee('test-file.coffee').should.equal('');
83 | });
84 |
85 | it('should transform an image to an img tag', function () {
86 | transform.html.image.should.be.type('function');
87 | transform.html.image('test-file.png').should.equal('
');
88 | });
89 |
90 | describe('selfClosingTag option is true', function () {
91 | before(function () {
92 | transform.selfClosingTag = true;
93 | });
94 | after(function () {
95 | transform.selfClosingTag = false;
96 | });
97 |
98 | it('should make link tags self closing', function () {
99 | transform.html.css('test-file.css').should.equal('');
100 | transform.html.html('test-file.html').should.equal('');
101 | });
102 |
103 | it('should make img tags self closing', function () {
104 | transform.html.image('test-file.png').should.equal('
');
105 | });
106 | });
107 |
108 | it('should use the css transformer for css files automatically', function () {
109 | transform.html('test-file.css').should.equal(transform.html.css('test-file.css'));
110 | });
111 |
112 | it('should use the html transformer for html files automatically', function () {
113 | transform.html('test-file.html').should.equal(transform.html.html('test-file.html'));
114 | });
115 |
116 | it('should use the js transformer for js files automatically', function () {
117 | transform.html('test-file.js').should.equal(transform.html.js('test-file.js'));
118 | });
119 |
120 | it('should use the coffee transformer for coffee files automatically', function () {
121 | transform.html('test-file.coffee').should.equal(transform.html.coffee('test-file.coffee'));
122 | });
123 |
124 | it('should use the image transformer for png, gif, jpg and jpeg files automatically', function () {
125 | transform.html('test-file.png').should.equal(transform.html.image('test-file.png'));
126 | transform.html('test-file.gif').should.equal(transform.html.image('test-file.gif'));
127 | transform.html('test-file.jpg').should.equal(transform.html.image('test-file.jpg'));
128 | transform.html('test-file.jpeg').should.equal(transform.html.image('test-file.jpeg'));
129 | });
130 | });
131 |
132 | describe('jsx as target', function () {
133 | it('should transform css to a self closing link tag', function () {
134 | transform.jsx.css.should.be.type('function');
135 | transform.jsx.css('test-file.css').should.equal('');
136 | });
137 |
138 | it('should transform html to a self closing link tag', function () {
139 | transform.jsx.html.should.be.type('function');
140 | transform.jsx.html('test-file.html').should.equal('');
141 | });
142 |
143 | it('should transform javascript to a script tag', function () {
144 | transform.jsx.js.should.be.type('function');
145 | transform.jsx.js('test-file.js').should.equal('');
146 | });
147 |
148 | it('should transform coffeescript to a script tag', function () {
149 | transform.jsx.coffee.should.be.type('function');
150 | transform.jsx.coffee('test-file.coffee').should.equal('');
151 | });
152 |
153 | it('should transform an image to a self closing img tag', function () {
154 | transform.jsx.image.should.be.type('function');
155 | transform.jsx.image('test-file.png').should.equal('
');
156 | });
157 |
158 | it('should use the css transformer for css files automatically', function () {
159 | transform.jsx('test-file.css').should.equal(transform.jsx.css('test-file.css'));
160 | });
161 |
162 | it('should use the html transformer for html files automatically', function () {
163 | transform.jsx('test-file.html').should.equal(transform.jsx.html('test-file.html'));
164 | });
165 |
166 | it('should use the js transformer for js files automatically', function () {
167 | transform.jsx('test-file.js').should.equal(transform.jsx.js('test-file.js'));
168 | });
169 |
170 | it('should use the coffee transformer for coffee files automatically', function () {
171 | transform.jsx('test-file.coffee').should.equal(transform.jsx.coffee('test-file.coffee'));
172 | });
173 |
174 | it('should use the image transformer for png, gif, jpg and jpeg files automatically', function () {
175 | transform.jsx('test-file.png').should.equal(transform.jsx.image('test-file.png'));
176 | transform.jsx('test-file.gif').should.equal(transform.jsx.image('test-file.gif'));
177 | transform.jsx('test-file.jpg').should.equal(transform.jsx.image('test-file.jpg'));
178 | transform.jsx('test-file.jpeg').should.equal(transform.jsx.image('test-file.jpeg'));
179 | });
180 | });
181 |
182 | describe('jade as target', function () {
183 | it('should transform css to a jade link tag', function () {
184 | transform.jade.css.should.be.type('function');
185 | transform.jade.css('test-file.css').should.equal('link(rel="stylesheet", href="test-file.css")');
186 | });
187 |
188 | it('should transform jade to a jade include tag', function () {
189 | transform.jade.html.should.be.type('function');
190 | transform.jade.jade('test-file.jade').should.equal('include test-file.jade');
191 | });
192 |
193 | it('should transform html to a self closing link tag', function () {
194 | transform.jade.html.should.be.type('function');
195 | transform.jade.html('test-file.html').should.equal('link(rel="import", href="test-file.html")');
196 | });
197 |
198 | it('should transform javascript to a script tag', function () {
199 | transform.jade.js.should.be.type('function');
200 | transform.jade.js('test-file.js').should.equal('script(src="test-file.js")');
201 | });
202 |
203 | it('should transform coffeescript to a script tag', function () {
204 | transform.jade.coffee.should.be.type('function');
205 | transform.jade.coffee('test-file.coffee').should.equal('script(type="text/coffeescript", src="test-file.coffee")');
206 | });
207 |
208 | it('should transform an image to a self closing img tag', function () {
209 | transform.jade.image.should.be.type('function');
210 | transform.jade.image('test-file.png').should.equal('img(src="test-file.png")');
211 | });
212 |
213 | it('should use the css transformer for css files automatically', function () {
214 | transform.jade('test-file.css').should.equal(transform.jade.css('test-file.css'));
215 | });
216 |
217 | it('should use the jade transformer for jade files automatically', function () {
218 | transform.jade('test-file.jade').should.equal(transform.jade.jade('test-file.jade'));
219 | });
220 |
221 | it('should use the html transformer for html files automatically', function () {
222 | transform.jade('test-file.html').should.equal(transform.jade.html('test-file.html'));
223 | });
224 |
225 | it('should use the js transformer for js files automatically', function () {
226 | transform.jade('test-file.js').should.equal(transform.jade.js('test-file.js'));
227 | });
228 |
229 | it('should use the coffee transformer for coffee files automatically', function () {
230 | transform.jade('test-file.coffee').should.equal(transform.jade.coffee('test-file.coffee'));
231 | });
232 |
233 | it('should use the image transformer for png, gif, jpg and jpeg files automatically', function () {
234 | transform.jade('test-file.png').should.equal(transform.jade.image('test-file.png'));
235 | transform.jade('test-file.gif').should.equal(transform.jade.image('test-file.gif'));
236 | transform.jade('test-file.jpg').should.equal(transform.jade.image('test-file.jpg'));
237 | transform.jade('test-file.jpeg').should.equal(transform.jade.image('test-file.jpeg'));
238 | });
239 | });
240 |
241 | describe('pug as target', function () {
242 | it('should transform css to a pug link tag', function () {
243 | transform.pug.css.should.be.type('function');
244 | transform.pug.css('test-file.css').should.equal('link(rel="stylesheet", href="test-file.css")');
245 | });
246 |
247 | it('should transform pug to a pug include tag', function () {
248 | transform.pug.html.should.be.type('function');
249 | transform.pug.pug('test-file.pug').should.equal('include test-file.pug');
250 | });
251 |
252 | it('should transform html to a self closing link tag', function () {
253 | transform.pug.html.should.be.type('function');
254 | transform.pug.html('test-file.html').should.equal('link(rel="import", href="test-file.html")');
255 | });
256 |
257 | it('should transform javascript to a script tag', function () {
258 | transform.pug.js.should.be.type('function');
259 | transform.pug.js('test-file.js').should.equal('script(src="test-file.js")');
260 | });
261 |
262 | it('should transform coffeescript to a script tag', function () {
263 | transform.pug.coffee.should.be.type('function');
264 | transform.pug.coffee('test-file.coffee').should.equal('script(type="text/coffeescript", src="test-file.coffee")');
265 | });
266 |
267 | it('should transform an image to a self closing img tag', function () {
268 | transform.pug.image.should.be.type('function');
269 | transform.pug.image('test-file.png').should.equal('img(src="test-file.png")');
270 | });
271 |
272 | it('should use the css transformer for css files automatically', function () {
273 | transform.pug('test-file.css').should.equal(transform.pug.css('test-file.css'));
274 | });
275 |
276 | it('should use the pug transformer for pug files automatically', function () {
277 | transform.pug('test-file.pug').should.equal(transform.pug.pug('test-file.pug'));
278 | });
279 |
280 | it('should use the html transformer for html files automatically', function () {
281 | transform.pug('test-file.html').should.equal(transform.pug.html('test-file.html'));
282 | });
283 |
284 | it('should use the js transformer for js files automatically', function () {
285 | transform.pug('test-file.js').should.equal(transform.pug.js('test-file.js'));
286 | });
287 |
288 | it('should use the coffee transformer for coffee files automatically', function () {
289 | transform.pug('test-file.coffee').should.equal(transform.pug.coffee('test-file.coffee'));
290 | });
291 |
292 | it('should use the image transformer for png, gif, jpg and jpeg files automatically', function () {
293 | transform.pug('test-file.png').should.equal(transform.pug.image('test-file.png'));
294 | transform.pug('test-file.gif').should.equal(transform.pug.image('test-file.gif'));
295 | transform.pug('test-file.jpg').should.equal(transform.pug.image('test-file.jpg'));
296 | transform.pug('test-file.jpeg').should.equal(transform.pug.image('test-file.jpeg'));
297 | });
298 | });
299 |
300 | describe('slm as target', function () {
301 | it('should transform css to a slm link tag', function () {
302 | transform.slm.css.should.be.type('function');
303 | transform.slm.css('test-file.css').should.equal('link rel="stylesheet" href="test-file.css"');
304 | });
305 |
306 | it('should transform html to a self closing link tag', function () {
307 | transform.slm.html.should.be.type('function');
308 | transform.slm.html('test-file.html').should.equal('link rel="import" href="test-file.html"');
309 | });
310 |
311 | it('should transform javascript to a script tag', function () {
312 | transform.slm.js.should.be.type('function');
313 | transform.slm.js('test-file.js').should.equal('script src="test-file.js"');
314 | });
315 |
316 | it('should transform coffeescript to a script tag', function () {
317 | transform.slm.coffee.should.be.type('function');
318 | transform.slm.coffee('test-file.coffee').should.equal('script type="text/coffeescript" src="test-file.coffee"');
319 | });
320 |
321 | it('should transform an image to a self closing img tag', function () {
322 | transform.slm.image.should.be.type('function');
323 | transform.slm.image('test-file.png').should.equal('img src="test-file.png"');
324 | });
325 |
326 | it('should use the css transformer for css files automatically', function () {
327 | transform.slm('test-file.css').should.equal(transform.slm.css('test-file.css'));
328 | });
329 |
330 | it('should use the html transformer for html files automatically', function () {
331 | transform.slm('test-file.html').should.equal(transform.slm.html('test-file.html'));
332 | });
333 |
334 | it('should use the js transformer for js files automatically', function () {
335 | transform.slm('test-file.js').should.equal(transform.slm.js('test-file.js'));
336 | });
337 |
338 | it('should use the coffee transformer for coffee files automatically', function () {
339 | transform.slm('test-file.coffee').should.equal(transform.slm.coffee('test-file.coffee'));
340 | });
341 |
342 | it('should use the image transformer for png, gif, jpg and jpeg files automatically', function () {
343 | transform.slm('test-file.png').should.equal(transform.slm.image('test-file.png'));
344 | transform.slm('test-file.gif').should.equal(transform.slm.image('test-file.gif'));
345 | transform.slm('test-file.jpg').should.equal(transform.slm.image('test-file.jpg'));
346 | transform.slm('test-file.jpeg').should.equal(transform.slm.image('test-file.jpeg'));
347 | });
348 | });
349 |
350 | describe('haml as target', function () {
351 | it('should transform css to a haml link tag', function () {
352 | transform.haml.css.should.be.type('function');
353 | transform.haml.css('test-file.css').should.equal('%link{rel:"stylesheet", href:"test-file.css"}');
354 | });
355 |
356 | it('should transform html to a self closing link tag', function () {
357 | transform.haml.html.should.be.type('function');
358 | transform.haml.html('test-file.html').should.equal('%link{rel:"import", href:"test-file.html"}');
359 | });
360 |
361 | it('should transform javascript to a script tag', function () {
362 | transform.haml.js.should.be.type('function');
363 | transform.haml.js('test-file.js').should.equal('%script{src:"test-file.js"}');
364 | });
365 |
366 | it('should transform coffeescript to a script tag', function () {
367 | transform.haml.coffee.should.be.type('function');
368 | transform.haml.coffee('test-file.coffee').should.equal('%script{type:"text/coffeescript", src:"test-file.coffee"}');
369 | });
370 |
371 | it('should transform an image to a self closing img tag', function () {
372 | transform.haml.image.should.be.type('function');
373 | transform.haml.image('test-file.png').should.equal('%img{src:"test-file.png"}');
374 | });
375 |
376 | it('should use the css transformer for css files automatically', function () {
377 | transform.haml('test-file.css').should.equal(transform.haml.css('test-file.css'));
378 | });
379 |
380 | it('should use the html transformer for html files automatically', function () {
381 | transform.haml('test-file.html').should.equal(transform.haml.html('test-file.html'));
382 | });
383 |
384 | it('should use the js transformer for js files automatically', function () {
385 | transform.haml('test-file.js').should.equal(transform.haml.js('test-file.js'));
386 | });
387 |
388 | it('should use the coffee transformer for coffee files automatically', function () {
389 | transform.haml('test-file.coffee').should.equal(transform.haml.coffee('test-file.coffee'));
390 | });
391 |
392 | it('should use the image transformer for png, gif, jpg and jpeg files automatically', function () {
393 | transform.haml('test-file.png').should.equal(transform.haml.image('test-file.png'));
394 | transform.haml('test-file.gif').should.equal(transform.haml.image('test-file.gif'));
395 | transform.haml('test-file.jpg').should.equal(transform.haml.image('test-file.jpg'));
396 | transform.haml('test-file.jpeg').should.equal(transform.haml.image('test-file.jpeg'));
397 | });
398 | });
399 |
400 | describe('less as target', function () {
401 | it('should transform less to a import tag', function () {
402 | transform.less.css.should.be.type('function');
403 | transform.less.css('test-file.css').should.equal('@import "test-file.css";');
404 | });
405 |
406 | it('should transform css to a import tag', function () {
407 | transform.less.less.should.be.type('function');
408 | transform.less.less('test-file.less').should.equal('@import "test-file.less";');
409 | });
410 |
411 | it('should use the less transformer for less files automatically', function () {
412 | transform.less('test-file.less').should.equal(transform.less.less('test-file.less'));
413 | });
414 |
415 | it('should use the css transformer for css files automatically', function () {
416 | transform.less('test-file.css').should.equal(transform.less.css('test-file.css'));
417 | });
418 | });
419 |
420 | describe('sass as target', function () {
421 | it('should transform sass to a import tag', function () {
422 | transform.sass.sass.should.be.type('function');
423 | transform.sass.sass('test-file.sass').should.equal('@import "test-file.sass"');
424 | });
425 |
426 | it('should transform scss to a import tag', function () {
427 | transform.sass.scss.should.be.type('function');
428 | transform.sass.scss('test-file.scss').should.equal('@import "test-file.scss"');
429 | });
430 |
431 | it('should transform css to a import tag', function () {
432 | transform.sass.css.should.be.type('function');
433 | transform.sass.css('test-file.css').should.equal('@import "test-file.css"');
434 | });
435 |
436 | it('should use the sass transformer for sass files automatically', function () {
437 | transform.sass('test-file.sass').should.equal(transform.sass.sass('test-file.sass'));
438 | });
439 |
440 | it('should use the sass transformer for scss files automatically', function () {
441 | transform.sass('test-file.scss').should.equal(transform.sass.scss('test-file.scss'));
442 | });
443 |
444 | it('should use the sass transformer for css files automatically', function () {
445 | transform.sass('test-file.css').should.equal(transform.sass.css('test-file.css'));
446 | });
447 | });
448 |
449 | describe('scss as target', function () {
450 | it('should transform sass to a import tag', function () {
451 | transform.scss.sass.should.be.type('function');
452 | transform.scss.sass('test-file.sass').should.equal('@import "test-file.sass";');
453 | });
454 |
455 | it('should transform scss to a import tag', function () {
456 | transform.scss.scss.should.be.type('function');
457 | transform.scss.scss('test-file.scss').should.equal('@import "test-file.scss";');
458 | });
459 |
460 | it('should transform css to a import tag', function () {
461 | transform.scss.css.should.be.type('function');
462 | transform.scss.css('test-file.css').should.equal('@import "test-file.css";');
463 | });
464 |
465 | it('should use the scss transformer for sass files automatically', function () {
466 | transform.scss('test-file.sass').should.equal(transform.scss.sass('test-file.sass'));
467 | });
468 |
469 | it('should use the scss transformer for scss files automatically', function () {
470 | transform.scss('test-file.scss').should.equal(transform.scss.scss('test-file.scss'));
471 | });
472 |
473 | it('should use the scss transformer for css files automatically', function () {
474 | transform.scss('test-file.css').should.equal(transform.scss.css('test-file.css'));
475 | });
476 | });
477 |
478 | it('should pick the correct target transformer for html targets', function () {
479 | var targetFile = fixture('index.html');
480 | var sourceFile = fixture('style.css');
481 | transform(sourceFile.path, null, null, sourceFile, targetFile)
482 | .should.equal(transform.html.css(sourceFile.path));
483 | });
484 |
485 | it('should pick the correct target transformer for jsx targets', function () {
486 | var targetFile = fixture('app.jsx');
487 | var sourceFile = fixture('app.js');
488 | transform(sourceFile.path, null, null, sourceFile, targetFile)
489 | .should.equal(transform.jsx.js(sourceFile.path));
490 | });
491 |
492 | it('should pick the correct target transformer for jade targets', function () {
493 | var targetFile = fixture('index.jade');
494 | var sourceFile = fixture('image.gif');
495 | transform(sourceFile.path, null, null, sourceFile, targetFile)
496 | .should.equal(transform.jade.image(sourceFile.path));
497 | });
498 |
499 | it('should pick the correct target transformer for pug targets', function () {
500 | var targetFile = fixture('index.pug');
501 | var sourceFile = fixture('image.gif');
502 | transform(sourceFile.path, null, null, sourceFile, targetFile)
503 | .should.equal(transform.pug.image(sourceFile.path));
504 | });
505 |
506 | it('should pick the correct target transformer for slm targets', function () {
507 | var targetFile = fixture('index.slm');
508 | var sourceFile = fixture('image.gif');
509 | transform(sourceFile.path, null, null, sourceFile, targetFile)
510 | .should.equal(transform.slm.image(sourceFile.path));
511 | });
512 |
513 | it('should pick the correct target transformer for haml targets', function () {
514 | var targetFile = fixture('index.haml');
515 | var sourceFile = fixture('image.gif');
516 | transform(sourceFile.path, null, null, sourceFile, targetFile)
517 | .should.equal(transform.haml.image(sourceFile.path));
518 | });
519 |
520 | it('should pick the correct target transformer for less targets', function () {
521 | var targetFile = fixture('index.less');
522 | var sourceFile = fixture('test-file.less');
523 | transform(sourceFile.path, null, null, sourceFile, targetFile)
524 | .should.equal(transform.less.less(sourceFile.path));
525 | });
526 |
527 | it('should pick the correct target transformer for sass targets', function () {
528 | var targetFile = fixture('index.sass');
529 | var sourceFile = fixture('test-file.sass');
530 | transform(sourceFile.path, null, null, sourceFile, targetFile)
531 | .should.equal(transform.sass.sass(sourceFile.path));
532 | });
533 |
534 | it('should pick the correct target transformer for scss targets', function () {
535 | var targetFile = fixture('index.scss');
536 | var sourceFile = fixture('test-file.scss');
537 | transform(sourceFile.path, null, null, sourceFile, targetFile)
538 | .should.equal(transform.scss.scss(sourceFile.path));
539 | });
540 |
541 | it('should default to the html target transformer for other files', function () {
542 | var targetFile = fixture('plain.txt');
543 | var sourceFile = fixture('image.gif');
544 | transform(sourceFile.path, null, null, sourceFile, targetFile)
545 | .should.equal(transform.html.image(sourceFile.path));
546 | });
547 |
548 | it('should default to the html target transformer for unknown files', function () {
549 | var sourceFile = fixture('image.gif');
550 | transform(sourceFile.path, null, null, sourceFile)
551 | .should.equal(transform.html.image(sourceFile.path));
552 | });
553 | });
554 |
555 | function fixture(file, read) {
556 | var filepath = path.resolve(__dirname, 'fixtures', file);
557 | return new Vinyl({
558 | path: filepath,
559 | cwd: __dirname,
560 | base: path.resolve(__dirname, 'fixtures', path.dirname(file)),
561 | contents: read ? fs.readFileSync(filepath) : null
562 | });
563 | }
564 |
--------------------------------------------------------------------------------