Compare commits

...

33 Commits

Author SHA1 Message Date
Jakob Linskeseder ca0d385a6c Coerce noEscape-statements to a string
Also removed `chai-diff`-dependency, since
it is unmaintained and not that useful.

Fixes #1838
2023-08-29 23:45:05 +02:00
Jakob Linskeseder 520e1d5f08 Fix links in README
This commit backports changes from `master`.
2023-08-02 23:37:05 +02:00
Jakob Linskeseder 02423780a9 Fix link to homepage
When visiting the www-variant, a `SSL_ERROR_INTERNAL_ERROR_ALERT`
error is displayed by the browser.
2023-08-02 23:35:42 +02:00
Jakob Linskeseder be92d2f254 Backport: publish latest and tags to AWS S3
In order to automate publishing 4.x releases to AWS S3,
we also need this workflow on the 4.x branch.

See #1972
2023-08-02 23:09:34 +02:00
Jakob Linskeseder 443a613b3a Add guideline for pushing to RubyGems 2023-08-02 22:56:15 +02:00
Nils Knappmeier 83ee5908f2 add links to publish requirements 2023-08-01 23:24:13 +02:00
Jakob Linskeseder 8dc3d2517b v4.7.8 2023-08-01 23:06:18 +02:00
Jakob Linskeseder 668c4fb878 Fix browser tests in CI pipeline 2023-07-23 20:46:46 +02:00
Jakob Linskeseder c65c6cce3f Test on Node 18
* Replaced outdated `grunt-bg-shell`-package to get rid of
  coffee-script warnings

Backports parts of 785a63e0a8.
2022-10-21 16:48:14 +02:00
Marnix Kok 3d3796c1e9 Make library compatible with workers
When using Handlebars in a Cloudflare Worker, an environment
in which the `window` and `global` objects both don't exist,
an error is thrown about `window` being undefined.

According to the ECMA specification, only `self` is available
in a worker. Since we support old runtimes in our 4.x branch,
we can't use `globalThis` but have to use a polyfill.
2022-10-16 22:17:50 +02:00
Jakob Linskeseder 075b354a3b Fix sync issue with npm lock-file
```
npm ERR! `npm ci` can only install packages when your package.json and package-lock.json or npm-shrinkwrap.json are in sync. Please update your lock file with `npm install` before continuing.
npm ERR!
npm ERR! Invalid: lock file's acorn@5.7.4 does not satisfy acorn@7.4.1
npm ERR! Missing: acorn@5.7.4 from lock file
```
2022-10-16 21:55:05 +02:00
arturmakaranka 30dbf04781 Fix compiling of each block params in strict mode
Fixes #1820
Closes #1821
2022-05-25 22:18:36 +02:00
Jakob Linskeseder e3a54485db Fix bundler issue with webpack 5
As explained in issue #1844 and in issue
https://github.com/webpack/webpack/issues/15007#issuecomment-996615250,
the way we used the `browser`-field was wrong.

The main reason for using the `browser`-field is the requirement of
`require('fs')` in the main-entry-file.
The workaround for this was using `require('handlebars/lib/handlebars')`,
but now it will also work via `require('handlebars')` for bundlers that
respect the `browser`-field.

The `"./runtime"`-config was removed, because it didn't have any effect.
In order to detect regressions, the webpack-integration test was
extended to test with different webpack versions.

Fixes #1174
Closes #1844
2022-05-17 21:19:48 +02:00
Jakob Linskeseder 8e23642ea2 Fix integration-tests issue with npm >= 7
Fixes the following error when running integration-tests:
```
npm ERR! code ERESOLVE
npm ERR! ERESOLVE unable to resolve dependency tree
npm ERR!
npm ERR! While resolving: webpack-test@1.0.0
npm ERR! Found: handlebars@5.0.0-alpha.1
npm ERR! node_modules/handlebars
npm ERR!   dev handlebars@"file:../../.." from the root project
npm ERR!
npm ERR! Could not resolve dependency:
npm ERR! peer handlebars@">= 1.3.0 < 5" from handlebars-loader@1.7.1
npm ERR! node_modules/handlebars-loader
npm ERR!   dev handlebars-loader@"^1.7.1" from the root project
npm ERR!
```
2022-05-17 21:19:48 +02:00
James Wilson 88ac06875f use https instead of git for mustache submodule 2022-03-19 19:19:27 +01:00
Jakob Linskeseder c68bc08a0d Fix typo 2022-01-08 00:39:29 +01:00
Nils Knappmeier 6cfbc2653a Use eslint-env "shared-node-browser" for shared handlebars code 2022-01-07 18:15:48 +01:00
Jakob Linskeseder b65135acef Replace shields.io with faster badgen.net
Badgen is a faster successor of shields.io:
https://github.com/badgen/badgen.net

Backport from `master`-branch.
2021-12-30 00:58:48 +01:00
Jakob Linskeseder e2f63da5c0 Don't create security alerts for dev-dependencies 2021-12-29 22:48:01 +01:00
Jakob Linskeseder 78e7e28ff9 Replace custom test-server with Grunt connect 2021-12-29 21:35:16 +01:00
Jakob Linskeseder 03d387bf8e Fix rollup warning when importing Handlebars as ESM
Closes #1696
2021-12-29 21:35:16 +01:00
Jakob Linskeseder e0f50b4eec Add integration-tests to CI workflow 2021-12-29 21:35:16 +01:00
Jakob Linskeseder 9ed9418488 Replace Saucelabs with Playwright
Also reorganized npm scripts.
2021-12-29 21:35:16 +01:00
Jakob Linskeseder ef0fc290b9 Move print-script.js-file in tests-folder
Also removed it from published files, since the script doesn't seem to be used.

Fourth part of reorganizing and cleaning up test-folders.
2021-12-29 21:35:16 +01:00
Jakob Linskeseder edc65b5c19 Move integration-testing-folder in tests-folder
Third part of reorganizing and cleaning up test-folders.
2021-12-29 21:35:16 +01:00
Jakob Linskeseder 715f4af179 Remove redundant task-part in task-tests-folder
Second part of reorganizing and cleaning up test-folders.
2021-12-29 21:35:16 +01:00
Jakob Linskeseder 3bd0fa8b32 Move bench-folder in tests-folder
First part of reorganizing and cleaning up test-folders.
2021-12-29 21:35:16 +01:00
Jakob Linskeseder c295ef085f Update repository URL 2021-12-03 23:12:20 +01:00
Jakob Linskeseder c1ad3c8057 Update contributing guidelines 2021-12-03 23:12:20 +01:00
Jakob Linskeseder af92e32822 Run CI tests on more versions 2021-12-03 23:12:20 +01:00
Jakob Linskeseder 2954e7ea66 Don't rely on Node.js global object
If `global` is used and handlebars is compiled for browser
usage without a Node.js `global` polyfill, handlebars
fails with a `global is undefined` error.

Fixes #1593
2021-12-03 21:57:55 +01:00
Jay Linski 8eefee56ff Replace Travis CI with GitHub action (#1772) 2021-12-03 19:04:01 +01:00
Shon Frazier fd93073146 Fix Mustache links
...to point to 'https://mustache.github.io/...'
2021-11-23 23:58:57 +01:00
124 changed files with 17676 additions and 719 deletions
+14
View File
@@ -0,0 +1,14 @@
root = true
[*.js]
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
[spec/expected/*.js]
insert_final_newline = false
[*.yml]
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true
+1 -2
View File
@@ -4,7 +4,6 @@
*.sublime-project
*.sublime-workspace
npm-debug.log
sauce_connect.log*
.idea
yarn-error.log
node_modules
@@ -15,7 +14,7 @@ node_modules
lib/handlebars/compiler/parser.js
/coverage/
/dist/
/integration-testing/*/dist/
/tests/integration/*/dist/
# Third-party or files that must remain unchanged
/spec/expected/
+9
View File
@@ -0,0 +1,9 @@
version: 2
updates:
- package-ecosystem: npm
directory: "/"
open-pull-requests-limit: 0
schedule:
interval: weekly
allow:
- dependency-type: production
+89
View File
@@ -0,0 +1,89 @@
name: CI
on:
push:
branches:
- master
pull_request: {}
jobs:
lint:
name: Lint
runs-on: 'ubuntu-latest'
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm ci
- name: Lint
run: npm run lint
test:
name: Test (Node)
runs-on: ${{ matrix.operating-system }}
strategy:
fail-fast: false
matrix:
operating-system: ['ubuntu-latest', 'windows-latest']
# https://nodejs.org/en/about/releases/
node-version: ['10', '12', '14', '16', '18', '20']
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: true
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node-version }}
- name: Install dependencies
run: npm ci
- name: Test
run: npm run test
- name: Test (Integration)
# https://github.com/webpack/webpack/issues/14532
if: ${{ matrix.node-version != '18' && matrix.node-version != '20' }}
run: |
cd ./tests/integration/rollup-test && ./test.sh && cd -
cd ./tests/integration/webpack-babel-test && ./test.sh && cd -
cd ./tests/integration/webpack-test && ./test.sh && cd -
browser:
name: Test (Browser)
runs-on: 'ubuntu-20.04'
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: true
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm ci
- name: Install Playwright
run: |
npx playwright install-deps
npx playwright install
- name: Build
run: npx grunt prepare
- name: Test
run: npm run test:browser
+38
View File
@@ -0,0 +1,38 @@
name: Release
on:
workflow_dispatch:
push:
branches:
- master
tags:
- '*'
jobs:
publish-aws-s3:
name: Publish to AWS S3
runs-on: 'ubuntu-latest'
environment: 'builds.handlebarsjs.com.s3.amazonaws.com'
steps:
- name: Checkout
uses: actions/checkout@v2
with:
submodules: true
- name: Setup Node.js
uses: actions/setup-node@v2
with:
node-version: '16'
- name: Install dependencies
run: npm ci
- name: Publish
run: |
git config --global user.email "release@handlebarsjs.com"
git config --global user.name "handlebars-lang"
npm run publish:aws
env:
S3_BUCKET_NAME: "builds.handlebarsjs.com"
S3_ACCESS_KEY_ID: ${{ secrets.S3_ACCESS_KEY_ID }}
S3_SECRET_ACCESS_KEY: ${{ secrets.S3_SECRET_ACCESS_KEY }}
+2 -3
View File
@@ -4,7 +4,6 @@
*.sublime-project
*.sublime-workspace
npm-debug.log
sauce_connect.log*
.idea
/yarn-error.log
/yarn.lock
@@ -16,5 +15,5 @@ node_modules
lib/handlebars/compiler/parser.js
/coverage/
/dist/
/integration-testing/*/dist/
/spec/tmp/*
/tests/integration/*/dist/
/spec/tmp/*
+1 -1
View File
@@ -1,3 +1,3 @@
[submodule "spec/mustache"]
path = spec/mustache
url = git://github.com/mustache/spec.git
url = https://github.com/mustache/spec.git
+1 -1
View File
@@ -15,7 +15,7 @@ node_modules
lib/handlebars/compiler/parser.js
/coverage/
/dist/
/integration-testing/*/dist/
/tests/integration/*/dist/
# Third-party or files that must remain unchanged
/spec/expected/
-39
View File
@@ -1,39 +0,0 @@
language: node_js
jobs:
include:
- stage: test
name: check javascript (eslint)
node_js: lts/*
script: npm run lint
- stage: test
name: check formatting (prettier)
node_js: lts/*
script: npm run check-format
- stage: test
name: check typescript definitions (dtslint)
node_js: lts/*
script: npm run dtslint
- stage: test
name: extensive tests and publish to aws
script: npm run extensive-tests-and-publish-to-aws
env:
- S3_BUCKET_NAME=builds.handlebarsjs.com
- secure: ckyEe5dzjdFDjmZ6wIrhGm0CFBEnKq8c1dYptfgVV/Q5/nJFGzu8T0yTjouS/ERxzdT2H327/63VCxhFnLCRHrsh4rlW/rCy4XI3O/0TeMLgFPa4TXkO8359qZ4CB44TBb3NsJyQXNMYdJpPLTCVTMpuiqqkFFOr+6OeggR7ufA=
- secure: Nm4AgSfsgNB21kgKrF9Tl7qVZU8YYREhouQunFracTcZZh2NZ2XH5aHuSiXCj88B13Cr/jGbJKsZ4T3QS3wWYtz6lkyVOx3H3iI+TMtqhD9RM3a7A4O+4vVN8IioB2YjhEu0OKjwgX5gp+0uF+pLEi7Hpj6fupD3AbbL5uYcKg8=
- SAUCE_USERNAME=handlebars
- secure: 1VkLQhbsEug4ZMQ52tTOus/WLvW3Etqe7GbCzZfzsI8d2ygJPjFfzU8fNm4pVVwoTI21MaM5AQq7SVPu8DWN1YbDjJycMdY1zO3DsB9aZBxTal98fIB7ZIUce9r5z2EP6mETrsbYjZkeckzIBI0A4UVa+F2BO4KbRDXP1Db3u3I=
node_js: '10'
- stage: test
name: test with latest nodejs-lts
node_js: lts/*
script: npm run test
- stage: test
name: test with active nodejs
node_js: node
script: npm run test
cache: npm
email:
on_failure: change
on_success: never
git:
depth: 100
+92 -28
View File
@@ -2,13 +2,13 @@
## Reporting Issues
Please see our [FAQ](https://github.com/wycats/handlebars.js/blob/master/FAQ.md) for common issues that people run into.
Please see our [FAQ](https://github.com/handlebars-lang/handlebars.js/blob/master/FAQ.md) for common issues that people run into.
Should you run into other issues with the project, please don't hesitate to let us know by filing an [issue][issue]! In general we are going to ask for an example of the problem failing, which can be as simple as a jsfiddle/jsbin/etc. We've put together a jsfiddle [template][jsfiddle] to ease this. (We will keep this link up to date as new releases occur, so feel free to check back here)
Pull requests containing only failing tests demonstrating the issue are welcomed and this also helps ensure that your issue won't regress in the future once it's fixed.
Documentation issues on the handlebarsjs.com site should be reported on [handlebars-site](https://github.com/wycats/handlebars-site).
Documentation issues on the [handlebarsjs.com](https://handlebarsjs.com) site should be reported on [handlebars-lang/docs](https://github.com/handlebars-lang/docs).
## Branches
@@ -47,9 +47,9 @@ You can also run our set of benchmarks with `grunt bench`.
The `grunt dev` implements watching for tests and allows for in browser testing at `http://localhost:9999/spec/`.
If you notice any problems, please report them to the GitHub issue tracker at
[http://github.com/wycats/handlebars.js/issues](http://github.com/wycats/handlebars.js/issues).
[http://github.com/handlebars-lang/handlebars.js/issues](http://github.com/handlebars-lang/handlebars.js/issues).
##Running Tests
## Running Tests
To run tests locally, first install all dependencies.
@@ -78,43 +78,107 @@ We do linting and formatting in two phases:
- Committed files are linted and formatted in a pre-commit hook. In this stage eslint-errors are forbidden,
while warnings are allowed.
- The travis-ci job also lints all files and checks if they are formatted correctly. In this stage, warnings
- The GitHub CI job also lints all files and checks if they are formatted correctly. In this stage, warnings
are forbidden.
You can use the following scripts to make sure that the travis-job does not fail:
You can use the following scripts to make sure that the CI job does not fail:
- **npm run lint** will run `eslint` and fail on warnings
- **npm run format** will run `prettier` on all files
- **npm run check-before-pull-request** will perform all most checks that travis does in its build-job, excluding the "integration-test".
- **npm run integration-test** will run integration tests (using old NodeJS versions and integrations with webpack, babel and so on)
- **npm run check-before-pull-request** will perform all most checks that our CI job does in its build-job, excluding the "integration-test".
- **npm run test:integration** will run integration tests (using old NodeJS versions and integrations with webpack, babel and so on)
These tests only work on a Linux-machine with `nvm` installed (for running tests in multiple versions of NodeJS).
## Releasing the latest version
Before attempting the release Handlebars, please make sure that you have the following authorizations:
- Push-access to `wycats/handlebars.js`
- Publishing rights on npmjs.com for the `handlebars` package
- Publishing rights on gemfury for the `handlebars-source` package
- Push-access to the repo for legacy package managers: `components/handlebars`
- Push-access to the production-repo of the handlebars site: `handlebars-lang/handlebarsjs.com-github-pages`
- Push-access to [handlebars-lang/handlebars.js](https://github.com/handlebars-lang/handlebars.js/)
- Publishing rights on npmjs.com for the [handlebars](https://www.npmjs.com/package/handlebars) package
- Publishing rights on rubygems for the [handlebars-source](https://rubygems.org/gems/handlebars-source) package
- Push-access to the repo for legacy package managers: [components/handlebars.js](https://github.com/components/handlebars.js)
- Push-access to the production-repo of the handlebars site: [handlebars-lang/docs](https://github.com/handlebars-lang/docs)
_When releasing a previous version of Handlebars, please look into the CONTRIBUNG.md in the corresponding branch._
Handlebars utilizes the [release yeoman generator][generator-release] to perform most release tasks.
A full release via Docker may be completed with the following:
A full release may be completed with the following:
1. Create a `Dockerfile` in this folder for releasing
```Dockerfile
FROM node:10-slim
ENV EDITOR=vim
# Update stretch repositories
RUN sed -i -e 's/deb.debian.org/archive.debian.org/g' \
-e 's|security.debian.org|archive.debian.org/|g' \
-e '/stretch-updates/d' /etc/apt/sources.list
# Install release dependencies
RUN apt-get update
RUN apt-get install -y git vim
# Work around deprecated npm dependency install via unauthenticated git-protocol:
# https://github.com/kpdecker/generator-release/blob/87aab9b84c9f083635c3fcc822f18acce1f48736/package.json#L31
RUN git config --system url."https://github.com/".insteadOf git://github.com/
# Configure git
RUN git config --system user.email "release@handlebarsjs.com"
RUN git config --system user.name "handlebars-lang"
RUN mkdir /home/node/.config
RUN mkdir /home/node/.ssh
RUN mkdir /home/node/tmp
# Generate config for yo generator-release:
# https://github.com/kpdecker/generator-release#example
# You have to add a valid GitHub OAuth token!
RUN echo "module.exports = {\n auth: 'oauth',\n token: 'GitHub OAuth token'\n};" > /home/node/.config/generator-release
RUN chown -R node:node /home/node/.config
# Add the generated key to GitHub: https://github.com/settings/keys
RUN ssh-keygen -q -t ed25519 -N '' -f /home/node/.ssh/id_ed25519 -C "release@handlebarsjs.com"
RUN chmod 0600 /home/node/.ssh/id_ed25519*
RUN chown node:node /home/node/.ssh/id_ed25519*
```
2. Build and run the Docker image
```bash
docker build --tag handlebars:release .
docker run --rm --interactive --tty \
--volume $PWD:/app \
--workdir /app \
--user $(id -u):$(id -g) \
--env NPM_CONFIG_PREFIX=/home/node/.npm-global \
handlebars:release bash -c 'export PATH=$PATH:/home/node/.npm-global/bin; bash'
```
* Add SSH key to GitHub: `cat /home/node/.ssh/id_ed25519.pub` (https://github.com/settings/keys)
* Add GitHub API token: `vi /home/node/.config/generator-release`
* Execute the following steps:
```bash
npm ci
npm install -g yo@1 grunt@1 generator-release
npm run release
yo release
npm login
npm publish
yo release:publish components handlebars.js dist/components/
```
6. Publish Ruby `handlebars-source` gem:
```bash
docker run --rm --interactive --tty \
--volume $PWD:/app \
--workdir /app \
--user $(id -u):$(id -g) \
ruby:3.2-slim bash
```
* Execute the following steps:
```bash
cd dist/components/
gem build handlebars-source.gemspec
gem push handlebars-source-*.gem
```
```
npm ci
yo release
npm publish
yo release:publish components handlebars.js dist/components/
cd dist/components/
gem build handlebars-source.gemspec
gem push handlebars-source-*.gem
```
### After the release
After the release, you should check that all places have really been updated. Especially verify that the `latest`-tags
in those places still point to the latest version
@@ -126,13 +190,13 @@ in those places still point to the latest version
When everything is OK, the **handlebars site** needs to be updated.
Go to the master branch of the repo [handlebars-lang/handlebarsjs.com-github-pages](https://github.com/handlebars-lang/handlebarsjs.com-github-pages/tree/master)
Go to the master branch of the repo [handlebars-lang/docs](https://github.com/handlebars-lang/docs/tree/master)
and make a minimal change to the README. This will invoke a github-action that redeploys
the site, fetching the latest version-number from the npm-registry.
(note that the default-branch of this repo is not the master and regular changes are done
in the `handlebars-lang/docs`-repo).
[generator-release]: https://github.com/walmartlabs/generator-release
[pull-request]: https://github.com/wycats/handlebars.js/pull/new/master
[issue]: https://github.com/wycats/handlebars.js/issues/new
[pull-request]: https://github.com/handlebars-lang/handlebars.js/pull/new/master
[issue]: https://github.com/handlebars-lang/handlebars.js/issues/new
[jsfiddle]: https://jsfiddle.net/9D88g/180/
+7 -5
View File
@@ -2,11 +2,11 @@
1. How can I file a bug report:
See our guidelines on [reporting issues](https://github.com/wycats/handlebars.js/blob/master/CONTRIBUTING.md#reporting-issues).
See our guidelines on [reporting issues](https://github.com/handlebars-lang/handlebars.js/blob/master/CONTRIBUTING.md#reporting-issues).
1. Why isn't my Mustache template working?
Handlebars deviates from Mustache slightly on a few behaviors. These variations are documented in our [readme](https://github.com/wycats/handlebars.js#differences-between-handlebarsjs-and-mustache).
Handlebars deviates from Mustache slightly on a few behaviors. These variations are documented in our [readme](https://github.com/handlebars-lang/handlebars.js#differences-between-handlebarsjs-and-mustache).
1. Why is it slower when compiling?
@@ -36,16 +36,18 @@
```sh
handlebars --version
```
If using the integrated precompiler and
```javascript
console.log(Handlebars.VERSION);
```
On the client side.
We include the built client libraries in the npm package for those who want to be certain that they are using the same client libraries as the compiler.
Should these match, please file an issue with us, per our [issue filing guidelines](https://github.com/wycats/handlebars.js/blob/master/CONTRIBUTING.md#reporting-issues).
Should these match, please file an issue with us, per our [issue filing guidelines](https://github.com/handlebars-lang/handlebars.js/blob/master/CONTRIBUTING.md#reporting-issues).
1. Why doesn't IE like the `default` name in the AMD module?
@@ -53,8 +55,8 @@
1. How do I load the runtime library when using AMD?
There are two options for loading under AMD environments. The first is to use the `handlebars.runtime.amd.js` file. This may require a [path mapping](https://github.com/wycats/handlebars.js/blob/master/spec/amd-runtime.html#L31) as well as access via the `default` field.
There are two options for loading under AMD environments. The first is to use the `handlebars.runtime.amd.js` file. This may require a [path mapping](https://github.com/handlebars-lang/handlebars.js/blob/master/spec/amd-runtime.html#L31) as well as access via the `default` field.
The other option is to load the `handlebars.runtime.js` UMD build, which might not require path configuration and exposes the library as both the module root and the `default` field for compatibility.
The other option is to load the `handlebars.runtime.js` UMD build, which might not require path configuration and exposes the library as both the module root and the `default` field for compatibility.
If not using ES6 transpilers or accessing submodules in the build the former option should be sufficient for most use cases.
+21 -82
View File
@@ -7,7 +7,7 @@ module.exports = function(grunt) {
'tmp',
'dist',
'lib/handlebars/compiler/parser.js',
'integration-testing/**/node_modules'
'/tests/integration/**/node_modules'
],
copy: {
@@ -165,54 +165,10 @@ module.exports = function(grunt) {
}
}
},
'saucelabs-mocha': {
all: {
options: {
build: process.env.TRAVIS_JOB_ID,
urls: [
'http://localhost:9999/spec/?headless=true',
'http://localhost:9999/spec/amd.html?headless=true'
],
detailedError: true,
concurrency: 4,
browsers: [
{ browserName: 'chrome' },
{ browserName: 'firefox', platform: 'Linux' }
// {browserName: 'safari', version: 9, platform: 'OS X 10.11'},
// {browserName: 'safari', version: 8, platform: 'OS X 10.10'},
// {
// browserName: 'internet explorer',
// version: 11,
// platform: 'Windows 8.1'
// },
// {
// browserName: 'internet explorer',
// version: 10,
// platform: 'Windows 8'
// }
]
}
},
sanity: {
options: {
build: process.env.TRAVIS_JOB_ID,
urls: [
'http://localhost:9999/spec/umd.html?headless=true',
'http://localhost:9999/spec/amd-runtime.html?headless=true',
'http://localhost:9999/spec/umd-runtime.html?headless=true'
],
detailedError: true,
concurrency: 2,
browsers: [{ browserName: 'chrome' }]
}
}
},
bgShell: {
shell: {
integrationTests: {
cmd: './integration-testing/run-integration-tests.sh',
bg: false,
fail: true
command: './tests/integration/run-integration-tests.sh'
}
},
@@ -237,23 +193,15 @@ module.exports = function(grunt) {
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-babel');
grunt.loadNpmTasks('grunt-bg-shell');
grunt.loadNpmTasks('@knappi/grunt-saucelabs');
grunt.loadNpmTasks('grunt-shell');
grunt.loadNpmTasks('grunt-webpack');
grunt.task.loadTasks('tasks');
this.registerTask(
'build',
'Builds a distributable version of the current project',
['parser', 'node', 'globals']
);
this.registerTask('node', ['babel:cjs']);
this.registerTask('globals', ['webpack']);
this.registerTask('release', 'Build final packages', [
'amd',
grunt.registerTask('node', ['babel:cjs']);
grunt.registerTask('amd', ['babel:amd', 'requirejs']);
grunt.registerTask('globals', ['webpack']);
grunt.registerTask('release', 'Build final packages', [
'uglify',
'test:min',
'copy:dist',
@@ -261,38 +209,29 @@ module.exports = function(grunt) {
'copy:cdnjs'
]);
this.registerTask('amd', ['babel:amd', 'requirejs']);
this.registerTask('test', ['test:bin', 'test:cov']);
grunt.registerTask('bench', ['metrics']);
if (process.env.SAUCE_ACCESS_KEY) {
grunt.registerTask('sauce', ['concat:tests', 'connect', 'saucelabs-mocha']);
} else {
grunt.registerTask('sauce', []);
}
// Requires secret properties (saucelabs-credentials etc.) from .travis.yaml
// Requires secret properties from .travis.yaml
grunt.registerTask('extensive-tests-and-publish-to-aws', [
'default',
'bgShell:integrationTests',
'sauce',
'shell:integrationTests',
'metrics',
'publish-to-aws'
]);
grunt.registerTask('on-file-change', [
'build',
'amd',
'concat:tests',
'test'
]);
grunt.registerTask('on-file-change', ['build', 'concat:tests', 'test']);
// === Primary tasks ===
grunt.registerTask('dev', ['clean', 'connect', 'watch']);
grunt.registerTask('default', ['clean', 'build', 'test', 'release']);
grunt.registerTask('test', ['test:bin', 'test:cov']);
grunt.registerTask('bench', ['metrics']);
grunt.registerTask('prepare', ['build', 'concat:tests']);
grunt.registerTask(
'build',
'Builds a distributable version of the current project',
['parser', 'node', 'amd', 'globals']
);
grunt.registerTask('integration-tests', [
'default',
'bgShell:integrationTests'
'shell:integrationTests'
]);
};
+15 -16
View File
@@ -1,17 +1,18 @@
[![Travis Build Status](https://img.shields.io/travis/wycats/handlebars.js/master.svg)](https://travis-ci.org/wycats/handlebars.js)
[![Appveyor Build Status](https://ci.appveyor.com/api/projects/status/github/wycats/handlebars.js?branch=master&svg=true)](https://ci.appveyor.com/project/wycats/handlebars-js)
[![Selenium Test Status](https://saucelabs.com/buildstatus/handlebars)](https://saucelabs.com/u/handlebars)
[![CI Build Status](https://github.com/handlebars-lang/handlebars.js/actions/workflows/ci.yml/badge.svg)](https://github.com/handlebars-lang/handlebars.js/actions/workflows/ci.yml)
[![jsDelivr Hits](https://data.jsdelivr.com/v1/package/npm/handlebars/badge?style=rounded)](https://www.jsdelivr.com/package/npm/handlebars)
[![npm downloads](https://badgen.net/npm/dm/handlebars)](https://www.npmjs.com/package/handlebars)
[![npm version](https://badgen.net/npm/v/handlebars)](https://www.npmjs.com/package/handlebars)
[![Bundle size](https://badgen.net/bundlephobia/minzip/handlebars?label=minified%20%2B%20gzipped)](https://bundlephobia.com/package/handlebars)
[![Install size](https://packagephobia.com/badge?p=handlebars)](https://packagephobia.com/result?p=handlebars)
Handlebars.js
=============
Handlebars.js is an extension to the [Mustache templating
language](http://mustache.github.com/) created by Chris Wanstrath.
Handlebars.js and Mustache are both logicless templating languages that
keep the view and the code separated like we all know they should be.
Handlebars provides the power necessary to let you build **semantic templates** effectively with no frustration.
Handlebars is largely compatible with Mustache templates. In most cases it is possible to swap out Mustache with Handlebars and continue using your current templates.
Checkout the official Handlebars docs site at
[https://handlebarsjs.com/](https://handlebarsjs.com) and the live demo at [http://tryhandlebarsjs.com/](http://tryhandlebarsjs.com/).
[handlebarsjs.com](https://handlebarsjs.com) and try our [live demo](https://handlebarsjs.com/playground.html).
Installing
----------
@@ -22,7 +23,7 @@ Usage
-----
In general, the syntax of Handlebars.js templates is a superset
of Mustache templates. For basic syntax, check out the [Mustache
manpage](http://mustache.github.com/mustache.5.html).
manpage](https://mustache.github.io/mustache.5.html).
Once you have a template, use the `Handlebars.compile` method to compile
the template into a function. The generated function takes a context
@@ -64,7 +65,7 @@ templates easier and also changes a tiny detail of how partials work.
- [Literal Values](https://handlebarsjs.com/guide/expressions.html#literal-segments)
- [Delimited Comments](https://handlebarsjs.com/guide/#template-comments)
Block expressions have the same syntax as mustache sections but should not be confused with one another. Sections are akin to an implicit `each` or `with` statement depending on the input data and helpers are explicit pieces of code that are free to implement whatever behavior they like. The [mustache spec](http://mustache.github.io/mustache.5.html) defines the exact behavior of sections. In the case of name conflicts, helpers are given priority.
Block expressions have the same syntax as mustache sections but should not be confused with one another. Sections are akin to an implicit `each` or `with` statement depending on the input data and helpers are explicit pieces of code that are free to implement whatever behavior they like. The [mustache spec](https://mustache.github.io/mustache.5.html) defines the exact behavior of sections. In the case of name conflicts, helpers are given priority.
### Compatibility
@@ -89,8 +90,6 @@ Handlebars has been designed to work in any ECMAScript 3 environment. This inclu
Older versions and other runtimes are likely to work but have not been formally
tested. The compiler requires `JSON.stringify` to be implemented natively or via a polyfill. If using the precompiler this is not necessary.
[![Selenium Test Status](https://saucelabs.com/browser-matrix/handlebars.svg)](https://saucelabs.com/u/handlebars)
Performance
-----------
@@ -102,18 +101,18 @@ does have some big performance advantages. Justin Marney, a.k.a.
[gotascii](http://github.com/gotascii), confirmed that with an
[independent test](http://sorescode.com/2010/09/12/benchmarks.html). The
rewritten Handlebars (current version) is faster than the old version,
with many [performance tests](https://travis-ci.org/wycats/handlebars.js/builds/33392182#L538) being 5 to 7 times faster than the Mustache equivalent.
with many performance tests being 5 to 7 times faster than the Mustache equivalent.
Upgrading
---------
See [release-notes.md](https://github.com/wycats/handlebars.js/blob/master/release-notes.md) for upgrade notes.
See [release-notes.md](https://github.com/handlebars-lang/handlebars.js/blob/master/release-notes.md) for upgrade notes.
Known Issues
------------
See [FAQ.md](https://github.com/wycats/handlebars.js/blob/master/FAQ.md) for known issues and common pitfalls.
See [FAQ.md](https://github.com/handlebars-lang/handlebars.js/blob/master/FAQ.md) for known issues and common pitfalls.
Handlebars in the Wild
@@ -165,4 +164,4 @@ License
-------
Handlebars.js is released under the MIT license.
[pull-request]: https://github.com/wycats/handlebars.js/pull/new/master
[pull-request]: https://github.com/handlebars-lang/handlebars.js/pull/new/master
-36
View File
@@ -1,36 +0,0 @@
# Test against these versions of Node.js
environment:
matrix:
- nodejs_version: "10"
platform:
- x64
# Install scripts (runs after repo cloning)
install:
# Get the latest stable version of Node.js
- ps: Install-Product node $env:nodejs_version $env:platform
# Clone submodules (mustache spec)
- cmd: git submodule update --init --recursive
# Install modules
- cmd: npm ci
# Post-install test scripts
test_script:
# Output useful info for debugging
- cmd: node --version
- cmd: npm --version
# Run tests
- cmd: npm run test
# Don't actually build
build: off
on_failure:
- cmd: 7z a coverage.zip coverage
- cmd: appveyor PushArtifact coverage.zip
# Set build version format here instead of in the admin panel
version: "{build}"
-15
View File
@@ -1,15 +0,0 @@
{
"extends": "prettier",
"globals": {
"require": true
},
"rules": {
// Disabling for tests, for now.
"no-path-concat": 0,
"no-var": 0,
"no-shadow": 0,
"handle-callback-err": 0,
"no-console": 0
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "handlebars",
"version": "4.7.7",
"version": "4.7.8",
"main": "handlebars.js",
"license": "MIT",
"dependencies": {}
+1 -1
View File
@@ -10,7 +10,7 @@ Gem::Specification.new do |gem|
gem.date = Time.now.strftime("%Y-%m-%d")
gem.description = %q{Handlebars.js source code wrapper for (pre)compilation gems.}
gem.summary = %q{Handlebars.js source code wrapper}
gem.homepage = "https://github.com/wycats/handlebars.js/"
gem.homepage = "https://github.com/handlebars-lang/handlebars.js/"
gem.version = package["version"].sub "-", "."
gem.license = "MIT"
+3 -3
View File
@@ -2,10 +2,10 @@
<package>
<metadata>
<id>handlebars.js</id>
<version>4.7.7</version>
<version>4.7.8</version>
<authors>handlebars.js Authors</authors>
<licenseUrl>https://github.com/wycats/handlebars.js/blob/master/LICENSE</licenseUrl>
<projectUrl>https://github.com/wycats/handlebars.js/</projectUrl>
<licenseUrl>https://github.com/handlebars-lang/handlebars.js/blob/master/LICENSE</licenseUrl>
<projectUrl>https://github.com/handlebars-lang/handlebars.js/</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Extension of the Mustache logicless template language</description>
<releaseNotes></releaseNotes>
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "handlebars",
"version": "4.7.7",
"version": "4.7.8",
"license": "MIT",
"jspm": {
"main": "handlebars",
+1 -1
View File
@@ -16,4 +16,4 @@ Decorators are executed when the block program is instantiated and are passed `(
Decorators may set values on `props` or return a modified function that wraps `program` in particular behaviors. If the decorator returns nothing, then `program` is left unaltered.
The [inline partial](https://github.com/wycats/handlebars.js/blob/master/lib/handlebars/decorators/inline.js) implementation provides an example of decorators being used for both metadata and wrapping behaviors.
The [inline partial](https://github.com/handlebars-lang/handlebars.js/blob/master/lib/handlebars/decorators/inline.js) implementation provides an example of decorators being used for both metadata and wrapping behaviors.
@@ -1,21 +0,0 @@
{
"name": "webpack-test",
"description": "Various tests with Handlebars and Webpack",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"build": "webpack --config webpack.config.js",
"test": "node dist/main.js"
},
"private": true,
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {},
"devDependencies": {
"handlebars": "file:../..",
"handlebars-loader": "^1.7.1",
"webpack": "^4.39.3",
"webpack-cli": "^3.3.7"
}
}
+8
View File
@@ -0,0 +1,8 @@
module.exports = {
env: {
// Handlebars should not use node or browser-specific APIs
'shared-node-browser': true,
node: false,
browser: false
}
};
+1 -1
View File
@@ -5,7 +5,7 @@ import { registerDefaultDecorators } from './decorators';
import logger from './logger';
import { resetLoggedProperties } from './internal/proto-access';
export const VERSION = '4.7.7';
export const VERSION = '4.7.8';
export const COMPILER_REVISION = 8;
export const LAST_COMPATIBLE_COMPILER_REVISION = 7;
+2 -2
View File
@@ -1,4 +1,4 @@
/* global define */
/* global define, require */
import { isArray } from '../utils';
let SourceNode;
@@ -6,7 +6,7 @@ let SourceNode;
try {
/* istanbul ignore next */
if (typeof define !== 'function' || !define.amd) {
// We don't support this in AMD environments. For these environments, we asusme that
// We don't support this in AMD environments. For these environments, we assume that
// they are running on the browser and thus have no need for the source-map library.
let SourceMap = require('source-map');
SourceNode = SourceMap.SourceNode;
@@ -308,7 +308,7 @@ JavaScriptCompiler.prototype = {
if (appendOnly) {
if (bufferStart) {
bufferStart.prepend('return ');
bufferStart.prepend('return ""+');
bufferEnd.add(';');
} else if (!sourceSeen) {
this.source.push('return "";');
@@ -537,7 +537,9 @@ JavaScriptCompiler.prototype = {
resolvePath: function(type, parts, i, falsy, strict) {
if (this.options.strict || this.options.assumeObjects) {
this.push(strictLookup(this.options.strict && strict, this, parts, type));
this.push(
strictLookup(this.options.strict && strict, this, parts, i, type)
);
return;
}
@@ -1261,9 +1263,8 @@ JavaScriptCompiler.isValidJavaScriptVariableName = function(name) {
);
};
function strictLookup(requireTerminal, compiler, parts, type) {
function strictLookup(requireTerminal, compiler, parts, i, type) {
let stack = compiler.popStack(),
i = 0,
len = parts.length;
if (requireTerminal) {
len--;
+2 -2
View File
@@ -63,9 +63,9 @@ export default function(instance) {
execIteration(i, i, i === context.length - 1);
}
}
} else if (global.Symbol && context[global.Symbol.iterator]) {
} else if (typeof Symbol === 'function' && context[Symbol.iterator]) {
const newContext = [];
const iterator = context[global.Symbol.iterator]();
const iterator = context[Symbol.iterator]();
for (let it = iterator.next(); !it.done; it = iterator.next()) {
newContext.push(it.value);
}
+1 -1
View File
@@ -1,5 +1,5 @@
import { createNewLookupObject } from './create-new-lookup-object';
import * as logger from '../logger';
import logger from '../logger';
const loggedProperties = Object.create(null);
+15 -4
View File
@@ -1,11 +1,22 @@
/* global globalThis */
export default function(Handlebars) {
/* istanbul ignore next */
let root = typeof global !== 'undefined' ? global : window,
$Handlebars = root.Handlebars;
// https://mathiasbynens.be/notes/globalthis
(function() {
if (typeof globalThis === 'object') return;
Object.prototype.__defineGetter__('__magic__', function() {
return this;
});
__magic__.globalThis = __magic__; // eslint-disable-line no-undef
delete Object.prototype.__magic__;
})();
const $Handlebars = globalThis.Handlebars;
/* istanbul ignore next */
Handlebars.noConflict = function() {
if (root.Handlebars === Handlebars) {
root.Handlebars = $Handlebars;
if (globalThis.Handlebars === Handlebars) {
globalThis.Handlebars = $Handlebars;
}
return Handlebars;
};
+1
View File
@@ -1,5 +1,6 @@
// USAGE:
// var handlebars = require('handlebars');
/* eslint-env node */
/* eslint-disable no-var */
// var local = handlebars.create();
+1
View File
@@ -1,3 +1,4 @@
/* eslint-env node */
/* eslint-disable no-console */
import Async from 'neo-async';
import fs from 'fs';
+16904 -294
View File
File diff suppressed because it is too large Load Diff
+22 -21
View File
@@ -1,9 +1,9 @@
{
"name": "handlebars",
"barename": "handlebars",
"version": "4.7.7",
"version": "4.7.8",
"description": "Handlebars provides the power necessary to let you build semantic templates effectively with no frustration",
"homepage": "http://www.handlebarsjs.com/",
"homepage": "https://handlebarsjs.com/",
"keywords": [
"handlebars",
"mustache",
@@ -12,7 +12,7 @@
],
"repository": {
"type": "git",
"url": "https://github.com/wycats/handlebars.js.git"
"url": "https://github.com/handlebars-lang/handlebars.js.git"
},
"author": "Yehuda Katz",
"license": "MIT",
@@ -22,7 +22,7 @@
},
"dependencies": {
"minimist": "^1.2.5",
"neo-async": "^2.6.0",
"neo-async": "^2.6.2",
"source-map": "^0.6.1",
"wordwrap": "^1.0.0"
},
@@ -30,13 +30,12 @@
"uglify-js": "^3.1.4"
},
"devDependencies": {
"@knappi/grunt-saucelabs": "^9.0.2",
"@playwright/test": "^1.17.1",
"aws-sdk": "^2.1.49",
"babel-loader": "^5.0.0",
"babel-runtime": "^5.1.10",
"benchmark": "~1.0",
"chai": "^4.2.0",
"chai-diff": "^1.0.1",
"concurrently": "^5.0.0",
"dirty-chai": "^2.0.1",
"dtslint": "^0.5.5",
@@ -44,12 +43,11 @@
"eco": "~1.1.0-rc-3",
"eslint": "^6.7.2",
"eslint-config-prettier": "^6.7.0",
"eslint-plugin-compat": "^3.3.0",
"eslint-plugin-compat": "^3.13.0",
"eslint-plugin-es5": "^1.4.1",
"fs-extra": "^8.1.0",
"grunt": "^1.0.4",
"grunt-babel": "^5.0.0",
"grunt-bg-shell": "^2.3.3",
"grunt-cli": "^1",
"grunt-contrib-clean": "^1",
"grunt-contrib-concat": "^1",
@@ -58,6 +56,7 @@
"grunt-contrib-requirejs": "^1",
"grunt-contrib-uglify": "^1",
"grunt-contrib-watch": "^1.1.0",
"grunt-shell": "^4.0.0",
"grunt-webpack": "^1.0.8",
"husky": "^3.1.0",
"jison": "~0.3.0",
@@ -76,23 +75,26 @@
},
"main": "lib/index.js",
"types": "types/index.d.ts",
"browser": {
".": "./dist/cjs/handlebars.js",
"./runtime": "./dist/cjs/handlebars.runtime.js"
},
"browser": "./dist/cjs/handlebars.js",
"bin": {
"handlebars": "bin/handlebars"
},
"scripts": {
"build": "grunt build",
"release": "npm run build && grunt release",
"format": "prettier --write '**/*.js' && eslint --fix .",
"check-format": "prettier --check '**/*.js'",
"lint": "eslint --max-warnings 0 .",
"dtslint": "dtslint types",
"test": "grunt",
"extensive-tests-and-publish-to-aws": "npx mocha tasks/task-tests/ && grunt --stack extensive-tests-and-publish-to-aws",
"integration-test": "grunt integration-tests",
"lint": "npm run lint:eslint && npm run lint:prettier && npm run lint:types",
"lint:eslint": "eslint --max-warnings 0 .",
"lint:prettier": "prettier --check '**/*.js'",
"lint:types": "dtslint types",
"test": "npm run test:mocha",
"test:mocha": "grunt build && grunt test",
"test:browser": "playwright test --config tests/browser/playwright.config.js tests/browser/spec.js",
"test:integration": "grunt integration-tests",
"test:serve": "grunt connect:server:keepalive",
"extensive-tests-and-publish-to-aws": "npx mocha tasks/tests/ && grunt --stack extensive-tests-and-publish-to-aws",
"--- combined tasks ---": "",
"check-before-pull-request": "concurrently --kill-others-on-fail npm:lint npm:dtslint npm:check-format npm:test"
"check-before-pull-request": "concurrently --kill-others-on-fail npm:lint npm:test"
},
"jspm": {
"main": "handlebars",
@@ -109,7 +111,6 @@
"dist/amd/**/*.js",
"dist/cjs/**/*.js",
"lib",
"print-script",
"release-notes.md",
"runtime.js",
"types/*.d.ts",
@@ -121,7 +122,7 @@
}
},
"lint-staged": {
"*.{js,css,json,md}": [
"*.{js,css,json}": [
"prettier --write",
"git add"
],
+12 -1
View File
@@ -2,7 +2,18 @@
## Development
[Commits](https://github.com/handlebars-lang/handlebars.js/compare/v4.7.7...master)
[Commits](https://github.com/handlebars-lang/handlebars.js/compare/v4.7.8...master)
## v4.7.8 - July 27th, 2023
- Make library compatible with workers (#1894) - 3d3796c
- Don't rely on Node.js global object (#1776) - 2954e7e
- Fix compiling of each block params in strict mode (#1855) - 30dbf04
- Fix rollup warning when importing Handlebars as ESM - 03d387b
- Fix bundler issue with webpack 5 (#1862) - c6c6bbb
- Use https instead of git for mustache submodule - 88ac068
[Commits](https://github.com/handlebars-lang/handlebars.js/compare/v4.7.7...v4.7.8)
## v4.7.7 - February 15th, 2021
+1 -1
View File
@@ -59,7 +59,7 @@
}
var runner = mocha.run();
//Reporting for saucelabs
// Reporting to test-runner
var failedTests = [];
runner.on('end', function(){
window.mochaResults = runner.stats;
+1 -1
View File
@@ -79,7 +79,7 @@
}
var runner = mocha.run();
//Reporting for saucelabs
// Reporting to test-runner
var failedTests = [];
runner.on('end', function(){
window.mochaResults = runner.stats;
+9
View File
@@ -324,6 +324,15 @@ describe('builtin helpers', function() {
);
});
it('each with block params and strict compilation', function() {
expectTemplate(
'{{#each goodbyes as |value index|}}{{index}}. {{value.text}}!{{/each}}'
)
.withCompileOptions({ strict: true })
.withInput({ goodbyes: [{ text: 'goodbye' }, { text: 'Goodbye' }] })
.toCompileTo('0. goodbye!1. Goodbye!');
});
it('each object with @index', function() {
expectTemplate(
'{{#each goodbyes}}{{@index}}. {{text}}! {{/each}}cruel {{world}}!'
+5 -5
View File
@@ -1,6 +1,6 @@
define(['handlebars.runtime'], function(Handlebars) {
Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
return templates['bom'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
return "a";
},"useData":true});
});
Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
return templates['bom'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
return "a";
},"useData":true});
});
+2 -2
View File
@@ -1,3 +1,3 @@
{"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
return "";
},"useData":true}
return "";
},"useData":true}
+5 -5
View File
@@ -1,6 +1,6 @@
define(['some-path/handlebars.runtime'], function(Handlebars) {
Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
return templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
return "";
},"useData":true});
});
Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
return templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
return "";
},"useData":true});
});
+1 -2
View File
@@ -1,6 +1,5 @@
Precompile handlebar templates.
Usage: handlebars [template|directory]...
Options:
-f, --output Output File [string]
--map Source Map File [string]
@@ -22,4 +21,4 @@ Options:
-e, --extension Template extension. [string] [default: "handlebars"]
-b, --bom Removes the BOM (Byte Order Mark) from the beginning of the templates. [boolean]
-v, --version Prints the current compiler version [boolean]
--help Outputs this message [boolean]
--help Outputs this message [boolean]
+9 -9
View File
@@ -1,10 +1,10 @@
define(['handlebars.runtime'], function(Handlebars) {
Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = someNameSpace = someNameSpace || {};
templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
return "";
},"useData":true});
templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
return "";
},"useData":true});
return templates;
});
Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = someNameSpace = someNameSpace || {};
templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
return "";
},"useData":true});
templates['empty'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
return "";
},"useData":true});
return templates;
});
+5 -5
View File
@@ -1,6 +1,6 @@
define(['handlebars.runtime'], function(Handlebars) {
Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
return templates['non.default.extension'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
return "<div>This is a test</div>";
},"useData":true});
});
Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
return templates['non.default.extension'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
return "<div>This is a test</div>";
},"useData":true});
});
+20 -19
View File
@@ -1,24 +1,25 @@
define(['handlebars.runtime'], function(Handlebars) {
Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
return templates['known.helpers'] = template({"1":function(container,depth0,helpers,partials,data) {
var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
return parent[propertyName];
}
return undefined
};
return " <div>Some known helper</div>\n"
+ ((stack1 = lookupProperty(helpers,"anotherHelper").call(depth0 != null ? depth0 : (container.nullContext || {}),true,{"name":"anotherHelper","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":3,"column":4},"end":{"line":5,"column":22}}})) != null ? stack1 : "");
var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
return parent[propertyName];
}
return undefined
};
return ""+" <div>Some known helper</div>\n"
+ ((stack1 = lookupProperty(helpers,"anotherHelper").call(depth0 != null ? depth0 : (container.nullContext || {}),true,{"name":"anotherHelper","hash":{},"fn":container.program(2, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":3,"column":4},"end":{"line":5,"column":22}}})) != null ? stack1 : "");
},"2":function(container,depth0,helpers,partials,data) {
return " <div>Another known helper</div>\n";
return " <div>Another known helper</div>\n";
},"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
return parent[propertyName];
}
return undefined
};
return ((stack1 = lookupProperty(helpers,"someHelper").call(depth0 != null ? depth0 : (container.nullContext || {}),true,{"name":"someHelper","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":15}}})) != null ? stack1 : "");
var stack1, lookupProperty = container.lookupProperty || function(parent, propertyName) {
if (Object.prototype.hasOwnProperty.call(parent, propertyName)) {
return parent[propertyName];
}
return undefined
};
return ""+((stack1 = lookupProperty(helpers,"someHelper").call(depth0 != null ? depth0 : (container.nullContext || {}),true,{"name":"someHelper","hash":{},"fn":container.program(1, data, 0),"inverse":container.noop,"data":data,"loc":{"start":{"line":1,"column":0},"end":{"line":6,"column":15}}})) != null ? stack1 : "");
},"useData":true});
});
});
+5 -5
View File
@@ -1,6 +1,6 @@
define(['handlebars.runtime'], function(Handlebars) {
Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
return Handlebars.partials['partial.template'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
return "<div>Test Partial</div>";
},"useData":true});
});
Handlebars = Handlebars["default"]; var template = Handlebars.template, templates = Handlebars.templates = Handlebars.templates || {};
return Handlebars.partials['partial.template'] = template({"compiler":[8,">= 4.3.0"],"main":function(container,depth0,helpers,partials,data) {
return "<div>Test Partial</div>";
},"useData":true});
});
+1 -1
View File
@@ -62,7 +62,7 @@
}
var runner = mocha.run();
//Reporting for saucelabs
// Reporting to test-runner
var failedTests = [];
runner.on('end', function(){
window.mochaResults = runner.stats;
+11
View File
@@ -34,6 +34,7 @@ describe('javascript-compiler api', function() {
.toCompileTo('food');
});
});
describe('#compilerInfo', function() {
var $superCheck, $superInfo;
beforeEach(function() {
@@ -58,6 +59,7 @@ describe('javascript-compiler api', function() {
.toCompileTo('food ');
});
});
describe('buffer', function() {
var $superAppend, $superCreate;
beforeEach(function() {
@@ -116,4 +118,13 @@ describe('javascript-compiler api', function() {
});
});
});
describe('options', function() {
it('should append `noEscape` statements as string', function() {
expectTemplate('{{a}}{{b}}')
.withCompileOptions({ noEscape: true })
.withInput({ a: 1, b: 1 })
.toCompileTo('11');
});
});
});
+1 -1
View File
@@ -54,7 +54,7 @@
}
var runner = mocha.run();
//Reporting for saucelabs
// Reporting to test-runner
var failedTests = [];
runner.on('end', function(){
window.mochaResults = runner.stats;
+1 -1
View File
@@ -74,7 +74,7 @@
}
var runner = mocha.run();
//Reporting for saucelabs
// Reporting to test-runner
var failedTests = [];
runner.on('end', function(){
window.mochaResults = runner.stats;
+1 -1
View File
@@ -1,4 +1,4 @@
const metrics = require('../bench');
const metrics = require('../tests/bench');
const { createRegisterAsyncTaskFn } = require('./util/async-grunt-task');
module.exports = function(grunt) {
-1
View File
@@ -1 +0,0 @@
Use `mocha tasks/task-tests` to run these tests
+3 -6
View File
@@ -4,7 +4,6 @@ const os = require('os');
const path = require('path');
const chai = require('chai');
chai.use(require('chai-diff'));
const expect = chai.expect;
const testCases = [
@@ -192,11 +191,9 @@ module.exports = function(grunt) {
fs.unlinkSync(outputLocation);
}
expect(normalizedOutput).not.to.be.differentFrom(
expect(normalizedOutput).to.be.equal(
normalizedExpectedOutput,
{
relaxedSpace: true
}
`Failed on ${expectedOutputSpec}`
);
}
);
@@ -226,7 +223,7 @@ function addPathToNodeJs(pathEnvironment) {
function normalizeCrlf(string) {
if (typeof string === 'string') {
return string.replace(/\r\n/g, '\n');
return string.replace(/\r\n/g, '\n').trim();
}
return string;
}
+1
View File
@@ -0,0 +1 @@
Use `mocha tasks/tests` to run these tests
+10
View File
@@ -0,0 +1,10 @@
module.exports = {
root: true,
extends: ['eslint:recommended', 'prettier'],
env: {
node: true
},
parserOptions: {
ecmaVersion: 6
}
};
@@ -3,7 +3,7 @@ var _ = require('underscore'),
module.exports = function(grunt, callback) {
// Deferring to here in case we have a build for parser, etc as part of this grunt exec
var Handlebars = require('../lib');
var Handlebars = require('../../lib');
var templateSizes = {};
_.each(templates, function(info, template) {
@@ -145,7 +145,7 @@ function makeSuite(bench, name, template, handlebarsOnly) {
module.exports = function(grunt, callback) {
// Deferring load incase we are being run inline with the grunt build
Handlebars = require('../lib');
Handlebars = require('../../lib');
console.log('Execution Throughput');
runner(grunt, makeSuite, function(times, scaled) {
@@ -11,8 +11,6 @@ function BenchWarmer() {
this.errors = {};
}
var print = require('util').print;
BenchWarmer.prototype = {
winners: function(benches) {
return Benchmark.filter(benches, 'fastest');
@@ -69,7 +67,7 @@ BenchWarmer.prototype = {
self.startLine('');
print('\n');
console.log('\n');
self.printHeader('scaled');
_.each(self.scaled, function(value, name) {
self.startLine(name);
@@ -78,7 +76,7 @@ BenchWarmer.prototype = {
self.writeValue(value[lang] || '');
});
});
print('\n');
console.log('\n');
var errors = false,
prop,
@@ -94,16 +92,16 @@ BenchWarmer.prototype = {
}
if (errors) {
print('\n\nErrors:\n');
console.log('\n\nErrors:\n');
Object.keys(self.errors).forEach(function(prop) {
if (self.errors[prop].error.message !== 'EWOT') {
bench = self.errors[prop];
print('\n' + bench.name + ':\n');
print(bench.error.message);
console.log('\n' + bench.name + ':\n');
console.log(bench.error.message);
if (bench.error.stack) {
print(bench.error.stack.join('\n'));
console.log(bench.error.stack.join('\n'));
}
print('\n');
console.log('\n');
}
});
}
@@ -112,7 +110,7 @@ BenchWarmer.prototype = {
}
});
print('\n');
console.log('\n');
},
scaleTimes: function() {
@@ -163,11 +161,11 @@ BenchWarmer.prototype = {
}
if (winners) {
print('WINNER(S)');
console.log('WINNER(S)');
horSize = horSize + 'WINNER(S)'.length;
}
print('\n' + new Array(horSize + 1).join('-'));
console.log('\n' + new Array(horSize + 1).join('-'));
},
startLine: function(name) {
@@ -179,8 +177,8 @@ BenchWarmer.prototype = {
this.currentBenches = [];
print(winners.join(', '));
print('\n');
console.log(winners.join(', '));
console.log('\n');
if (name) {
this.writeValue(name);
@@ -216,7 +214,7 @@ BenchWarmer.prototype = {
writeValue: function(out) {
var padding = this.benchSize - out.length + 1;
out = out + new Array(padding).join(' ');
print(out);
console.log(out);
}
};
+5
View File
@@ -0,0 +1,5 @@
module.exports = {
parserOptions: {
ecmaVersion: 2020
}
};
+14
View File
@@ -0,0 +1,14 @@
# Browser Tests with Playwright
These tests execute Mocha tests from the `spec`-folder in multiple browsers.
## Using Docker
Execute the following commands in the project root:
```bash
npm install
npx grunt prepare
docker pull mcr.microsoft.com/playwright:focal
docker run -it --rm --volume $(pwd):/srv/app --workdir /srv/app --ipc=host mcr.microsoft.com/playwright:focal npm run test:browser
```
+27
View File
@@ -0,0 +1,27 @@
const { devices } = require('@playwright/test');
/** @type {import('@playwright/test').PlaywrightTestConfig} */
const config = {
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] }
},
{
name: 'firefox',
use: { ...devices['Desktop Firefox'] }
},
{
name: 'webkit',
use: { ...devices['Desktop Safari'] }
}
],
reporter: 'list',
webServer: {
command: 'npm run test:serve',
port: 9999,
reuseExistingServer: false
}
};
module.exports = config;
+33
View File
@@ -0,0 +1,33 @@
const { test, expect } = require('@playwright/test');
async function waitForMochaAndAssertResult(page) {
await page.waitForFunction(() => window.mochaResults); // eslint-disable-line no-undef
const mochaResults = await page.evaluate('window.mochaResults');
expect(mochaResults.failures).toBe(0);
}
test('Spec handlebars.js', async ({ page, baseURL }) => {
await page.goto(`${baseURL}/spec/?headless=true`);
await waitForMochaAndAssertResult(page);
});
test('Spec handlebars.amd.js (AMD)', async ({ page, baseURL }) => {
await page.goto(`${baseURL}/spec/amd.html?headless=true`);
await waitForMochaAndAssertResult(page);
});
test('Spec handlebars.runtime.amd.js (AMD)', async ({ page, baseURL }) => {
await page.goto(`${baseURL}/spec/amd-runtime.html?headless=true`);
await waitForMochaAndAssertResult(page);
});
test('Spec handlebars.js (UMD)', async ({ page, baseURL }) => {
await page.goto(`${baseURL}/spec/umd.html?headless=true`);
await waitForMochaAndAssertResult(page);
});
test('Spec handlebars.runtime.js (UMD)', async ({ page, baseURL }) => {
await page.goto(`${baseURL}/spec/umd-runtime.html?headless=true`);
await waitForMochaAndAssertResult(page);
});
@@ -1,12 +1,10 @@
Add a new integration test by creating a new subfolder
Add a file "test.sh" to that runs the test. "test.sh" should exit with a non-zero exit code
Add a file "test.sh" to that runs the test. "test.sh" should exit with a non-zero exit code
and display an error message, if something goes wrong.
* An integration test should reflect real-world setups that use handlebars.
* It should compile a minimal template and compare the output to an expected output.
* It should use "../.." as dependency for Handlebars so that the currently built library is used.
- An integration test should reflect real-world setups that use handlebars.
- It should compile a minimal template and compare the output to an expected output.
- It should use "../.." as dependency for Handlebars so that the currently built library is used.
Currently, integration tests are only running on Linux, especially in travis-ci.
Currently, integration tests are only running on Linux, especially in our CI GitHub action.
@@ -7,7 +7,7 @@
"private": true,
"license": "MIT",
"dependencies": {
"handlebars": "file:../.."
"handlebars": "file:../../.."
},
"scripts": {
"test": "node run-handlebars.js",
@@ -7,9 +7,6 @@ cd "$( dirname "$( readlink -f "$0" )" )" || exit 1
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"
# This script tests with precompiler and the built distribution with multiple NodeJS version.
# The rest of the travis-build will only work with newer NodeJS versions, because the build
# tools don't support older versions.
# However, the built distribution should work with older NodeJS versions as well.
# This test is simple by design. It merely ensures, that calling Handlebars does not fail with old versions.
# It does (almost) not test for correctness, because that is already done in the mocha-tests.
# And it does not use any NodeJS based testing framework to make this part independent of the Node version.
@@ -17,7 +14,7 @@ cd "$( dirname "$( readlink -f "$0" )" )" || exit 1
unset npm_config_prefix
echo "Handlebars should be able to run in various versions of NodeJS"
for node_version_to_test in 0.10 0.12 4 5 6 7 8 9 10 11 12 13 14 15; do
for node_version_to_test in 0.10 0.12 4 5 6 7 8 9 10 11 12 13 14 15 16 18; do
rm target node_modules package-lock.json -rf
mkdir target
@@ -0,0 +1,11 @@
module.exports = {
root: true,
extends: ['eslint:recommended', 'prettier'],
env: {
browser: true
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 6
}
};
@@ -0,0 +1,14 @@
{
"name": "rollup-test",
"description": "Various tests with Handlebars and rollup",
"version": "1.0.0",
"scripts": {
"build": "rollup --config rollup.config.js --failAfterWarnings"
},
"private": true,
"devDependencies": {
"@rollup/plugin-node-resolve": "^13.1.1",
"handlebars": "file:../../..",
"rollup": "^2.61.1"
}
}
@@ -0,0 +1,10 @@
import { nodeResolve } from '@rollup/plugin-node-resolve';
export default {
input: 'src/index.js',
output: {
file: 'dist/bundle.js',
format: 'es'
},
plugins: [nodeResolve()]
};
@@ -0,0 +1,8 @@
import Handlebars from 'handlebars/lib/handlebars';
const template = Handlebars.compile('Author: {{author}}');
const result = template({ author: 'Yehuda' });
if (result !== 'Author: Yehuda') {
throw Error('Assertion failed');
}
@@ -7,10 +7,5 @@ rm dist package-lock.json -rf
npm install
npm run build
for i in dist/*-test.js ; do
echo "----------------------"
echo "-- Running $i"
echo "----------------------"
node "$i"
echo "Success"
done
node dist/bundle.js
echo "Success"

Some files were not shown because too many files have changed in this diff Show More