Skip to content

Commit bdb18be

Browse files
author
Maciej Adamczak
committed
can-stache-loader
0 parents  commit bdb18be

File tree

11 files changed

+498
-0
lines changed

11 files changed

+498
-0
lines changed

.editorconfig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# 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

.gitignore

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# Created by .ignore support plugin (hsz.mobi)
2+
### Node template
3+
# Logs
4+
logs
5+
*.log
6+
npm-debug.log*
7+
yarn-debug.log*
8+
yarn-error.log*
9+
10+
# Runtime data
11+
pids
12+
*.pid
13+
*.seed
14+
*.pid.lock
15+
16+
# Directory for instrumented libs generated by jscoverage/JSCover
17+
lib-cov
18+
19+
# Coverage directory used by tools like istanbul
20+
coverage
21+
22+
# nyc test coverage
23+
.nyc_output
24+
25+
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
26+
.grunt
27+
28+
# Bower dependency directory (https://bower.io/)
29+
bower_components
30+
31+
# node-waf configuration
32+
.lock-wscript
33+
34+
# Compiled binary addons (http://nodejs.org/api/addons.html)
35+
build/Release
36+
37+
# Dependency directories
38+
node_modules/
39+
jspm_packages/
40+
41+
# Typescript v1 declaration files
42+
typings/
43+
44+
# Optional npm cache directory
45+
.npm
46+
47+
# Optional eslint cache
48+
.eslintcache
49+
50+
# Optional REPL history
51+
.node_repl_history
52+
53+
# Output of 'npm pack'
54+
*.tgz
55+
56+
# Yarn Integrity file
57+
.yarn-integrity
58+
59+
# dotenv environment variables file
60+
.env
61+
62+
# Webstorm
63+
/.idea
64+
65+
# Build
66+
/lib
67+
68+
# OSX
69+
.DS_Store

.npmignore

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.editorconfig
2+
.gitignore
3+
.nvmrc
4+
node_modules
5+
.idea
6+
.npmignore

.nvmrc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
6.5

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License
2+
3+
Copyright (c) 2010-2017 Google, Inc. http://angularjs.org
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.

README.md

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
[![version](https://img.shields.io/npm/v/can-stache-loader.svg)](https://www.npmjs.com/package/can-stache-loader)
2+
[![dependencies](https://img.shields.io/david/macku/can-stache-loader.svg)](https://david-dm.org/macku/can-stache-loader)
3+
[![dev dependencies](https://img.shields.io/david/dev/macku/can-stache-loader.svg)](https://david-dm.org/macku/can-stache-loader?type=dev)
4+
5+
# CanJS Stache template loader for webpack
6+
7+
Compiles [CanJS Stache](https://github.com/canjs/can-stache) templates with [can-view-parser](https://github.com/canjs/can-view-parser) and allows to load them with [webpack](https://webpack.github.io/)
8+
9+
10+
## How to install
11+
12+
### NPM and Yarn
13+
14+
You can install the library using [**NPM**](https://www.npmjs.com):
15+
16+
```bash
17+
npm install can-stache-loader --save-dev
18+
```
19+
20+
or by [**Yarn**](https://yarnpkg.com/):
21+
22+
```bash
23+
yarn add can-stache-loader
24+
```
25+
26+
## How to use it
27+
28+
29+
### Configure webpack 2+
30+
31+
```js
32+
{
33+
module: {
34+
rules: [
35+
{
36+
test: /\.stache$/,
37+
use: {
38+
loader: 'can-stache-loader'
39+
}
40+
}
41+
]
42+
}
43+
}
44+
```
45+
46+
### Import stache templates in your [CanJS](https://canjs.com/) project
47+
48+
```js
49+
const tpl = require('./template.stache');
50+
const html = tpl({
51+
foo: 'bar'
52+
});
53+
```
54+
55+
## CanJS Compatibility
56+
57+
This library works fine with [CanJS](https://v2.canjs.com/) version **2.3.0+** and [webpack](https://webpack.github.io/) **2.0.0+**.
58+
59+
It was not (yet) tested with [CanJS](https://canjs.com/) version **3.0.0+**.
60+
61+
## License
62+
[MIT](https://opensource.org/licenses/MIT)

clean-line-endings.js

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
var mustacheLineBreakRegExp = /(?:(?:^|(\r?)\n)(\s*)(\{\{([^\}]*)\}\}\}?)([^\S\n\r]*)($|\r?\n))|(\{\{([^\}]*)\}\}\}?)/g;
2+
/**
3+
* @hide
4+
* Returns the mustache mode split from the rest of the expression.
5+
* @param {can.stache.Expression} expression
6+
* @param {Object} state The state of HTML where the expression was found.
7+
*/
8+
function splitModeFromExpression (expression, state){
9+
expression = expression.trim();
10+
var mode = expression.charAt(0);
11+
12+
if( "#/{&^>!".indexOf(mode) >= 0 ) {
13+
expression = expression.substr(1).trim();
14+
} else {
15+
mode = null;
16+
}
17+
// Triple braces do nothing within a tag.
18+
if(mode === "{" && state.node) {
19+
mode = null;
20+
}
21+
return {
22+
mode: mode,
23+
expression: expression
24+
};
25+
};
26+
27+
/**
28+
* @hide
29+
* Prunes line breaks accoding to the mustache specification.
30+
* @param {String} template
31+
* @return {String}
32+
*/
33+
module.exports = function cleanLineEndings(template) {
34+
return template.replace(mustacheLineBreakRegExp, function (whole, returnBefore, spaceBefore, special, expression, spaceAfter, returnAfter, spaceLessSpecial, spaceLessExpression, matchIndex) {
35+
spaceAfter = spaceAfter || '';
36+
returnBefore = returnBefore || '';
37+
spaceBefore = spaceBefore || '';
38+
var modeAndExpression = splitModeFromExpression(expression || spaceLessExpression, {});
39+
if (spaceLessSpecial || '>{'.indexOf(modeAndExpression.mode) >= 0) {
40+
return whole;
41+
} else if ('^#!/'.indexOf(modeAndExpression.mode) >= 0) {
42+
return special + (matchIndex !== 0 && returnAfter.length ? returnBefore + '\n' : '');
43+
} else {
44+
return spaceBefore + special + spaceAfter + (spaceBefore.length || matchIndex !== 0 ? returnBefore + '\n' : '');
45+
}
46+
});
47+
}

index.js

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
const getIntermediateAndImports = require('./intermediate_and_imports');
2+
// const getIntermediateAndImports = require('can-stache/src/intermediate_and_imports');
3+
// const getIntermediateAndImports = require('can/dist/cjs/view/stache/intermediate_and_imports');
4+
5+
6+
const getTemplate = (source, imports) => {
7+
const requires = imports.map(i => `require('${i}');`).join('\n');
8+
9+
return `var stache = require('can/dist/cjs/view/stache/stache');
10+
var mustacheCore = require('can/dist/cjs/view/stache/mustache_core');
11+
var getIntermediateAndImports = require('can/dist/cjs/view/stache/intermediate_and_imports');
12+
13+
${requires}
14+
15+
var source = ${source};
16+
var intermediateAndImports = getIntermediateAndImports(source);
17+
18+
var intermediate = intermediateAndImports.intermediate;
19+
var renderer = stache(intermediate);
20+
21+
module.exports = function (scope, options, nodeList) {
22+
var moduleOptions = { module: module };
23+
24+
if (!(options instanceof mustacheCore.Options)) {
25+
options = new mustacheCore.Options(options || {});
26+
}
27+
28+
return renderer(scope, options.add(moduleOptions), nodeList);
29+
};`;
30+
}
31+
32+
module.exports = function canStacheLoader(source) {
33+
const src = JSON.stringify(source);
34+
35+
const intermediateAndImports = getIntermediateAndImports(source);
36+
37+
return getTemplate(src, intermediateAndImports.imports);
38+
};

intermediate_and_imports.js

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
const parser = require('can-view-parser');
2+
const cleanLineEndings = require('./clean-line-endings');
3+
4+
module.exports = function(source){
5+
var template = cleanLineEndings(source);
6+
var imports = [], dynamicImports = [], ases = {}, inImport = false, inFrom = false, inAs = false, isUnary = false, currentAs = '', currentFrom = '';
7+
var intermediate = parser(template, {
8+
start: function (tagName, unary) {
9+
isUnary = unary;
10+
if (tagName === 'can-import') {
11+
inImport = true;
12+
} else if (inImport) {
13+
inImport = false;
14+
}
15+
},
16+
attrStart: function (attrName) {
17+
if (attrName === 'from') {
18+
inFrom = true;
19+
} else if (attrName === 'as' || attrName === 'export-as') {
20+
inAs = true;
21+
}
22+
},
23+
attrEnd: function (attrName) {
24+
if (attrName === 'from') {
25+
inFrom = false;
26+
} else if (attrName === 'as' || attrName === 'export-as') {
27+
inAs = false;
28+
}
29+
},
30+
attrValue: function (value) {
31+
if (inFrom && inImport) {
32+
imports.push(value);
33+
if (!isUnary) {
34+
dynamicImports.push(value);
35+
}
36+
currentFrom = value;
37+
} else if (inAs && inImport) {
38+
currentAs = value;
39+
}
40+
},
41+
end: function (tagName) {
42+
if (tagName === 'can-import') {
43+
if (currentAs) {
44+
ases[currentAs] = currentFrom;
45+
currentAs = '';
46+
}
47+
}
48+
},
49+
close: function (tagName) {
50+
if (tagName === 'can-import') {
51+
imports.pop();
52+
}
53+
}
54+
}, true);
55+
return {
56+
intermediate: intermediate,
57+
imports: imports,
58+
dynamicImports: dynamicImports,
59+
ases: ases,
60+
exports: ases
61+
};
62+
};

0 commit comments

Comments
 (0)