```
- * __`test` commit messages__
+ * **`test` commit messages**
Test coverage tasks.
@@ -647,11 +648,11 @@
done
```
-### 2.3. __Tell your boss how Git enables collaborative process models.__
+### 2.3. **Tell your boss how Git enables collaborative process models.**

-* __Git enables collaboration with structured (business) process models.__ Git is a collaboration tool that grants people the opportunity to contribute to software products using simple and consistent process models called workflows.
+* **Git enables collaboration with structured (business) process models.** Git is a collaboration tool that grants people the opportunity to contribute to software products using simple and consistent process models called workflows.
---
@@ -659,13 +660,13 @@
Toggle view of a workflow example.
⌦ Git is a collaboration tool that grants people the opportunity to contribute to software products using simple and consistent process models called _workflows_.
- Git __repositories__ store software products, as well as the historical changes to these products.
- Git workflows begin with either __cloning__ or __forking__ a repository, which __pulls__ a duplicate of the entire codebase onto a local computer.
- Contributors then create a local __topic branch__ in which they introduce changes—-features, fixes, documentation, tests, and design improvements—-which allows others to develop in parallel.
- Contributors __push__ their topic branch to others (usually another `remote` repository called `origin`) and submit __pull requests (PRs)__ to their announce their changes. __Pull requests are central to almost all Git workflows, since PRs allow Product Owners and their community to review suggested modifications. Product owners can approve or reject PRs at any time.__
- Other contributors answer the request to __pull__ the changes so they can review and test them.
+ Git **repositories** store software products, as well as the historical changes to these products.
+ Git workflows begin with either **cloning** or **forking** a repository, which **pulls** a duplicate of the entire codebase onto a local computer.
+ Contributors then create a local **topic branch** in which they introduce changes—-features, fixes, documentation, tests, and design improvements—-which allows others to develop in parallel.
+ Contributors **push** their topic branch to others (usually another `remote` repository called `origin`) and submit **pull requests (PRs)** to their announce their changes. **Pull requests are central to almost all Git workflows, since PRs allow Product Owners and their community to review suggested modifications. Product owners can approve or reject PRs at any time.**
+ Other contributors answer the request to **pull** the changes so they can review and test them.
The changes in the PR are approved.
- The topic branch is either __merged__ or __rebased__ into the the software product.
+ The topic branch is either **merged** or **rebased** into the the software product.
The topic branch gets deleted, and (ultimately) its changes are delivered to the world.
@@ -678,22 +679,22 @@
* #### 2.3.1. Explain that inner and open source are _process models_.
_Why:_
- > ⌦ Git is a __collaboration__ tool that grants people the opportunity to contribute to software products using simple and consistent process models called __workflows.__
+ > ⌦ Git is a **collaboration** tool that grants people the opportunity to contribute to software products using simple and consistent process models called **workflows.**
* #### 2.3.2. Describe a typical Git workflow in collaborative terms.
_Why:_
> ⌦ Many engineers can discuss Git's _technicalities_, but cannot articulate Git's as an applied _technology_ for collaboration.
-## 3. __Code standards__
+## 3. **Code standards**
-[![JavaScript Style Guide][standard-js-badge-image]][standard-js-url] [![ESLint logo][eslint-logo-image]][eslint-url]
+[![JavaScript Style Guide][standard-js-badge-image]][standard-js-url] [![ESLint logo][eslint-logo-image]][eslint-url] [![Google Java Style][checkstyle-icon-image]][checkstyle-url]
-* ### 3.1. Use the Standard JS Style.
+* ### 3.1. Use the JavaScript Standard Style.
- `spring-boot-starter-thymeleaf` follows the [Standard JS Style][standard-js-url].
+ `mvn-spring-boot-thymeleaf-nodejs` follows the [Standard JS Style][standard-js-url].
-* ### 3.2. Use ESLint to analyze source code.
+* ### 3.2. Use ESLint to analyze JavaScript source code.
_Why:_
> ⌦ [ESLint][eslint-url] evaluates JavaScript code (and `--fix`es what it can) whenever `npm test` runs. You can run ESLint directly with:
@@ -703,9 +704,29 @@
```
>
- View [`spring-boot-starter-thymeleaf's` ESLint rules][eslint-rules-table-url] and their enforcement.
+ View [`mvn-spring-boot-thymeleaf-nodejs's` ESLint rules][eslint-rules-table-url] and their enforcement.
-## 4. __Unit testing__
+* ### 3.3. Run `./mvnw test` to evaluate Java code quality.
+
+ _Why:_
+ > ⌦ `./mvnw test` runs
+ > 1. Checkstyle (Google Java Style)
+ > 1. CPD
+ > 1. Dependency Analysis
+ > 1. Dependency and Plugin Updates
+ > 1. Dependency Convergence
+ > 1. Duplicate Finder
+ > 1. Enforcer
+ > 1. FindBugs
+ > 1. Jacoco code coverage
+ > 1. JDepend
+ > 1. JUnit and BDDMockito tests
+ > 1. Licenses
+ > 1. PMD
+ > 1. Source and Test Javadocs
+
+
+## 4. **Unit testing**
[![Jest JavaScript Testing][jest-logo-image]][jest-url]
@@ -714,9 +735,9 @@
_Why:_
> ⌦ Behavior-driven development specifications are executable documentation.
- * **Put test files in the \__test\__ directory.**
+ * **Put test files in the \**test\** directory.**
- * __Use the `.spec.js` suffix for all tests.__
+ * **Use the `.spec.js` suffix for all tests.**
* ### 4.2. Reach 100% code coverage.
@@ -730,8 +751,8 @@
> jest --config=jest.config.json
- PASS __tests__/app.js
- spring-boot-starter-thymeleaf:app
+ PASS **tests**/app.js
+ mvn-spring-boot-thymeleaf-nodejs:app
✓ creates files (1ms)
Test Suites: 1 passed, 1 total
@@ -739,49 +760,68 @@
Snapshots: 0 total
Time: 2.595s
Ran all test suites.
- ----------|----------|----------|----------|----------|----------------|
- File | % Stmts | % Branch | % Funcs | % Lines |Uncovered Lines |
- ----------|----------|----------|----------|----------|----------------|
- All files | 100 | 100 | 100 | 100 | |
- index.js | 100 | 100 | 100 | 100 | |
- ----------|----------|----------|----------|----------|----------------|
+|:-----------|:-----------|:-----------|:-----------|:-----------|:-----------------|
+| File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Lines |
+| ---------- | ---------- | ---------- | ---------- | ---------- | ---------------- |
+| All files | 100 | 100 | 100 | 100 | |
+| index.js | 100 | 100 | 100 | 100 | |
+| ---------- | ---------- | ---------- | ---------- | ---------- | ---------------- |
```
* Open `/coverage/lcov-report/index.html` in a Web browser to view detailed coverage reports.
-## 5. __Directory structure__
-
+## 5. **Directory structure**
-## 6. __Logging__
+## 6. **Logging**
-## 7. __Dependencies__
+## 7. **Dependencies**
![Package tech stack][tech-stack-image]
[![StackShare][stackshare-badge-image]][stackshare-url]
-`spring-boot-starter-thymeleaf` requires the following tech stack to either run, build, test, or deploy:
+`mvn-spring-boot-thymeleaf-nodejs` requires the following tech stack to either run, build, test, or deploy:
| **Dependency** | **Description** | **Version** | **License** | **Type** |
| -------------- | --------------- | ----------- | ----------- | -------- |
+ | [babel-jest@21.2.0](https://github.com/facebook/jest#readme) | Jest plugin to use babel for transformation. | 21.2.0 | MIT | dev |
+ | [babel-preset-env@1.6.1](https://babeljs.io/) | A Babel preset for each environment. | 1.6.1 | MIT | dev |
+ | [babelify@8.0.0](https://github.com/babel/babelify) | Babel browserify transform | 8.0.0 | MIT | dev |
+ | [check-node-version@2.1.0](https://github.com/parshap/check-node-version#readme) | Check installed versions of node and npm | 2.1.0 | WTFPL | dev |
| [commitplease@3.1.0](https://github.com/jzaefferer/commitplease#readme) | Validates strings as commit messages | 3.1.0 | MIT | dev |
+ | [eslint@4.11.0](https://eslint.org) | An AST-based pattern checker for JavaScript. | 4.11.0 | MIT | dev |
+ | [eslint-config-xo-space@0.17.0](https://github.com/sindresorhus/eslint-config-xo-space#readme) | ESLint shareable config for XO with 2-space indent | 0.17.0 | MIT | dev |
+ | [eslint-plugin-import@2.8.0](https://github.com/benmosher/eslint-plugin-import) | Import with sanity. | 2.8.0 | MIT | dev |
+ | [eslint-plugin-jest@21.3.2](https://github.com/jest-community/eslint-plugin-jest#readme) | Eslint rules for Jest | 21.3.2 | MIT | dev |
+ | [eslint-plugin-jsdoc@3.2.0](https://github.com/gajus/eslint-plugin-jsdoc#readme) | JSDoc linting rules for ESLint. | 3.2.0 | BSD-3-Clause | dev |
+ | [eslint-plugin-no-unsafe-innerhtml@1.0.16](https://github.com/mozfreddyb/eslint-plugin-no-unsafe-innerhtml/) | custom ESLint rule to disallows unsafe innerHTML, outerHTML and insertAdjacentHTML | 1.0.16 | MPL-2.0 | dev |
+ | [eslint-plugin-no-unsanitized@2.0.1](https://github.com/mozilla/eslint-plugin-no-unsanitized/) | ESLint rule to disallow unsanitized code | 2.0.1 | MPL-2.0 | dev |
+ | [eslint-plugin-node@5.2.1](https://github.com/mysticatea/eslint-plugin-node#readme) | Additional ESLint's rules for Node.js | 5.2.1 | MIT | dev |
+ | [eslint-plugin-promise@3.6.0](https://github.com/xjamundx/eslint-plugin-promise#readme) | Enforce best practices for JavaScript promises | 3.6.0 | ISC | dev |
+ | [eslint-plugin-scanjs-rules@0.2.1](https://github.com/mozfreddyb/eslint-plugin-scanjs-rules/) | ESLint plugin that contains ScanJS rules | 0.2.1 | MPL-2.0 | dev |
+ | [eslint-plugin-security@1.4.0](https://github.com/nodesecurity/eslint-plugin-security#readme) | Security rules for eslint | 1.4.0 | Apache-2.0 | dev |
+ | [eslint-plugin-standard@3.0.1](https://github.com/xjamundx/eslint-plugin-standard#readme) | ESlint Plugin for the Standard Linter | 3.0.1 | MIT | dev |
+ | [eslint-plugin-xss@0.1.8](https://npmjs.org/package/eslint-plugin-xss) | Validates XSS related issues of mixing HTML and non-HTML content in variables. | 0.1.8 | ISC | dev |
| [fixpack@2.3.1](https://github.com/henrikjoreteg/fixpack) | cli tool that cleans up package.json files. | 2.3.1 | MIT | dev |
+ | [jest@21.2.1](http://facebook.github.io/jest/) | Delightful JavaScript Testing. | 21.2.1 | MIT | dev |
+ | [jest-cli@21.2.1](http://facebook.github.io/jest/) | Delightful JavaScript Testing. | 21.2.1 | MIT | dev |
| [markdown-magic@0.1.19](https://github.com/DavidWells/markdown-magic#readme) | Automatically update markdown files with content from external sources | 0.1.19 | MIT | dev |
| [markdown-magic-dependency-table@1.3.2](https://github.com/camacho/markdown-magic-dependency-table#readme) | Generate table of information about dependencies automatically in markdown | 1.3.2 | MIT | dev |
| [markdown-magic-install-command@1.3.1](https://github.com/camacho/markdown-magic-install-command#readme) | Print install command for markdown file | 1.3.1 | MIT | dev |
| [markdown-magic-package-scripts@1.2.1](https://github.com/camacho/markdown-magic-package-scripts#readme) | Print list of scripts in package.json with descriptions | 1.2.1 | MIT | dev |
+ | [markdown-toc@1.2.0](https://github.com/jonschlinkert/markdown-toc) | Generate a markdown TOC (table of contents) with Remarkable. | 1.2.0 | MIT | dev |
| [nsp@3.1.0](https://github.com/nodesecurity/nsp#readme) | The Node Security (nodesecurity.io) command line interface | 3.1.0 | Apache-2.0 | dev |
- | [snyk@1.48.1](https://github.com/snyk/snyk#readme) | snyk library and cli utility | 1.48.1 | Apache-2.0 | dev |
+ | [snyk@1.49.2](https://github.com/snyk/snyk#readme) | snyk library and cli utility | 1.49.2 | Apache-2.0 | dev |
| [standard-version@4.2.0](https://github.com/conventional-changelog/standard-version#readme) | replacement for `npm version` with automatic CHANGELOG generation | 4.2.0 | ISC | dev |
-## 8. __APIs__
+## 8. **APIs**
![APIs][icon-rest-api-image]
-* ### 8.1 __API design__
+* ### 8.1 **API design**
_Why:_
> ⌦ Because we try to enforce development of sanely constructed RESTful interfaces, which team members and clients can consume simply and consistently.
@@ -965,7 +1005,7 @@
```
* Pagination, filtering, and sorting don’t need to be supported from start for all resources. Document those resources that offer filtering and sorting.
-* ### 8.2 __API security__
+* ### 8.2 **API security**
These are some basic security best practices:
@@ -1001,7 +1041,7 @@
_Why:_
> ⌦ For instance, accepting the `application/x-www-form-urlencoded` mime type allows the attacker to create a form and trigger a simple POST request. The server should never assume the Content-Type. A lack of Content-Type header or an unexpected Content-Type header should result in the server rejecting the content with a `4XX` response.
-* ### 8.3 __API documentation__
+* ### 8.3 **API documentation**
* Fill the `API Reference` section in [README.md template](./README.sample.md) for API.
* Describe API authentication methods with a code sample.
@@ -1017,21 +1057,21 @@
* If the request type is POST, provide working examples. URL Params rules apply here too. Separate the section into Optional and Required.
- * __Success Responses.__ What should be the status code and is there any return data? This is useful when people need to know what their callbacks should expect:
+ * **Success Responses.** What should be the status code and is there any return data? This is useful when people need to know what their callbacks should expect:
```
Code: 200
Content: { id : 12 }
```
- * __Error Responses.__ Most endpoints have many ways to fail. From unauthorized access to wrongful parameters etc. All of those should be listed here. It might seem repetitive, but it helps prevent assumptions from being made. For example:
+ * **Error Responses.** Most endpoints have many ways to fail. From unauthorized access to wrongful parameters etc. All of those should be listed here. It might seem repetitive, but it helps prevent assumptions from being made. For example:
- * __HTTP status code__
+ * **HTTP status code**
```
404 Not Found
```
- * __Response body__
+ * **Response body**
```json
{
"code" : 404,
@@ -1042,7 +1082,7 @@
}
```
- * __Response headers__
+ * **Response headers**
```
accept-ranges: bytes
access-control-allow-headers: Authorization
@@ -1062,7 +1102,7 @@
* Use API design tools, There are lots of open source tools for good documentation such as [API Blueprint](https://apiblueprint.org/) and [Swagger](https://swagger.io/).
-## 9. __Licensing__
+## 9. **Licensing**
![Licensing][osi-logo-image]
@@ -1076,7 +1116,7 @@
[autosquashing-git-commits-url]: https://robots.thoughtbot.com/autosquashing-git-commits
[changelog-url]: ./CHANGELOG.md
[cite-interview-torvalds-url]: https://techcrunch.com/2012/04/19/an-interview-with-millenium-technology-prize-finalist-linus-torvalds/
-[cla-url]: https://www.clahub.com/agreements/gregswindle/spring-boot-starter-thymeleaf
+[cla-url]: https://www.clahub.com/agreements/gregswindle/mvn-spring-boot-thymeleaf-nodejs
[code-of-conduct-url]: ./CODE_OF_CONDUCT.md
[commitplease-url]: https://www.npmjs.com/package/commitplease
[gregswindle-palette-image]: ./docs/img/palette.svg
@@ -1102,9 +1142,9 @@
[icon-issue-image]: ./docs/img/icons8/icon-issues.png
[icon-pr-image]: ./docs/img/icons8/icon-pr.png
[icon-rest-api-image]: ./docs/img/icons8/icon-rest-api.png
-[issues-new-defect-url]: https://github.com/gregswindle/spring-boot-starter-thymeleaf/issues/new?title=fix%28affected-scope%29%3A+subject-line-with-very-few-words&labels=Priority%3A+Medium%2CStatus%3A+Review+Needed%2CType%3A+Defect&body=%2A%2A%F0%9F%92%A1+TIP%3A%2A%2A+Select+the+%E2%86%96%EF%B8%8E%E2%8E%BE+Preview+%E2%8F%8B+Tab+above+help+read+these+instructions.%0D%0A%0D%0A%23%23+1.+Issue+type%0D%0A%3E%E2%8C%A6+Type+the+letter+%22x%22+in+the+%22checkbox%22+the+best+describe+this+issue.%0D%0A%0D%0A-+%5Bx%5D+__Feature%3A__+I%27m+requesting+a+product+enhancement.%0D%0A%0D%0A%23%23+2.+User+story+summary%0D%0A%3E%E2%8C%A6+Describe+what+you+want+to+accomplish%2C+in+what+role%2Fcapacity%2C+and+why+it%27s+important+to+you.%0D%0A%0D%0A%3E+__EXAMPLE%3A__%0D%0A%3E+As+a+Applicant%2C%0D%0A%3E+I+want+to+submit+my+resume%0D%0A%3E+In+order+to+be+considered+for+a+job+opening.%0D%0A%0D%0AAs+a+%7Brole%7D%2C%0D%0AI+must%2Fneed%2Fwant%2Fshould+%7Bdo+something%7D%0D%0AIn+order+to+%7Bachieve+value%7D.%0D%0A%0D%0A%23%23+3.+Acceptance+criteria%0D%0A%3E%E2%8C%A6+Replace+the+examples+below+with+your+own+imperative%2C+%22true%2Ffalse%22+statements+for+the+__behavior+you+expect__+to+see%2C+or+the+behavior+that+__would__+be+true+if+there+were+no+errors+%28for+defects%29.%0D%0A%0D%0A-+%5B+%5D+1.+Job+Applicants+receive+a+confirmation+email+after+they+submit+their+resumes.%0D%0A-+%5B+%5D+2.+An+Applicant%27s+resume+information+isn%27t+lost+when+errors+occur.%0D%0A-+%5B+%5D+3.+%7Bcriterion-three%7D%0D%0A-+%5B+%5D+4.+%7Bcriterion-four%7D%0D%0A%0D%0A%3C%21--+%E2%9B%94%EF%B8%8F++Do+not+remove+anything+below+this+comment.+%E2%9B%94%EF%B8%8F++--%3E%0D%0A%5Bicon-info-image%5D%3A+..%2Fdocs%2Fimg%2Ficons8%2Ficon-info-50.png%0D%0A
-[issues-new-feat-url]: https://github.com/gregswindle/spring-boot-starter-thymeleaf/issues/new?title=feat%28affected-scope%29%3A+subject-line-with-very-few-words&labels=Priority%3A+Medium%2CStatus%3A+Review+Needed%2CType%3A+Feature&body=%2A%2A%F0%9F%92%A1+TIP%3A%2A%2A+Select+the+%E2%86%96%EF%B8%8E%E2%8E%BE+Preview+%E2%8F%8B+Tab+above+help+read+these+instructions.%0D%0A%0D%0A%23%23+1.+Issue+type%0D%0A%3E%E2%8C%A6+Type+the+letter+%22x%22+in+the+%22checkbox%22+the+best+describe+this+issue.%0D%0A%0D%0A-+%5Bx%5D+__Feature%3A__+I%27m+requesting+a+product+enhancement.%0D%0A%0D%0A%23%23+2.+User+story+summary%0D%0A%3E%E2%8C%A6+Describe+what+you+want+to+accomplish%2C+in+what+role%2Fcapacity%2C+and+why+it%27s+important+to+you.%0D%0A%0D%0A%3E+__EXAMPLE%3A__%0D%0A%3E+As+a+Applicant%2C%0D%0A%3E+I+want+to+submit+my+resume%0D%0A%3E+In+order+to+be+considered+for+a+job+opening.%0D%0A%0D%0AAs+a+%7Brole%7D%2C%0D%0AI+must%2Fneed%2Fwant%2Fshould+%7Bdo+something%7D%0D%0AIn+order+to+%7Bachieve+value%7D.%0D%0A%0D%0A%23%23+3.+Acceptance+criteria%0D%0A%3E%E2%8C%A6+Replace+the+examples+below+with+your+own+imperative%2C+%22true%2Ffalse%22+statements+for+the+__behavior+you+expect__+to+see%2C+or+the+behavior+that+__would__+be+true+if+there+were+no+errors+%28for+defects%29.%0D%0A%0D%0A-+%5B+%5D+1.+Job+Applicants+receive+a+confirmation+email+after+they+submit+their+resumes.%0D%0A-+%5B+%5D+2.+An+Applicant%27s+resume+information+isn%27t+lost+when+errors+occur.%0D%0A-+%5B+%5D+3.+%7Bcriterion-three%7D%0D%0A-+%5B+%5D+4.+%7Bcriterion-four%7D%0D%0A%0D%0A%3C%21--+%E2%9B%94%EF%B8%8F++Do+not+remove+anything+below+this+comment.+%E2%9B%94%EF%B8%8F++--%3E%0D%0A%5Bicon-info-image%5D%3A+..%2Fdocs%2Fimg%2Ficons8%2Ficon-info-50.png%0D%0A
-[issues-url]: https://github.com/gregswindle/spring-boot-starter-thymeleaf/issues
+[issues-new-defect-url]: https://github.com/gregswindle/mvn-spring-boot-thymeleaf-nodejs/issues/new?title=fix%28affected-scope%29%3A+subject-line-with-very-few-words&labels=Priority%3A+Medium%2CStatus%3A+Review+Needed%2CType%3A+Defect&body=%2A%2A%F0%9F%92%A1+TIP%3A%2A%2A+Select+the+%E2%86%96%EF%B8%8E%E2%8E%BE+Preview+%E2%8F%8B+Tab+above+help+read+these+instructions.%0D%0A%0D%0A%23%23+1.+Issue+type%0D%0A%3E%E2%8C%A6+Type+the+letter+%22x%22+in+the+%22checkbox%22+the+best+describe+this+issue.%0D%0A%0D%0A-+%5Bx%5D+**Feature%3A**+I%27m+requesting+a+product+enhancement.%0D%0A%0D%0A%23%23+2.+User+story+summary%0D%0A%3E%E2%8C%A6+Describe+what+you+want+to+accomplish%2C+in+what+role%2Fcapacity%2C+and+why+it%27s+important+to+you.%0D%0A%0D%0A%3E+**EXAMPLE%3A**%0D%0A%3E+As+a+Applicant%2C%0D%0A%3E+I+want+to+submit+my+resume%0D%0A%3E+In+order+to+be+considered+for+a+job+opening.%0D%0A%0D%0AAs+a+%7Brole%7D%2C%0D%0AI+must%2Fneed%2Fwant%2Fshould+%7Bdo+something%7D%0D%0AIn+order+to+%7Bachieve+value%7D.%0D%0A%0D%0A%23%23+3.+Acceptance+criteria%0D%0A%3E%E2%8C%A6+Replace+the+examples+below+with+your+own+imperative%2C+%22true%2Ffalse%22+statements+for+the+**behavior+you+expect**+to+see%2C+or+the+behavior+that+**would**+be+true+if+there+were+no+errors+%28for+defects%29.%0D%0A%0D%0A-+%5B+%5D+1.+Job+Applicants+receive+a+confirmation+email+after+they+submit+their+resumes.%0D%0A-+%5B+%5D+2.+An+Applicant%27s+resume+information+isn%27t+lost+when+errors+occur.%0D%0A-+%5B+%5D+3.+%7Bcriterion-three%7D%0D%0A-+%5B+%5D+4.+%7Bcriterion-four%7D%0D%0A%0D%0A%3C%21--+%E2%9B%94%EF%B8%8F++Do+not+remove+anything+below+this+comment.+%E2%9B%94%EF%B8%8F++--%3E%0D%0A%5Bicon-info-image%5D%3A+..%2Fdocs%2Fimg%2Ficons8%2Ficon-info-50.png%0D%0A
+[issues-new-feat-url]: https://github.com/gregswindle/mvn-spring-boot-thymeleaf-nodejs/issues/new?title=feat%28affected-scope%29%3A+subject-line-with-very-few-words&labels=Priority%3A+Medium%2CStatus%3A+Review+Needed%2CType%3A+Feature&body=%2A%2A%F0%9F%92%A1+TIP%3A%2A%2A+Select+the+%E2%86%96%EF%B8%8E%E2%8E%BE+Preview+%E2%8F%8B+Tab+above+help+read+these+instructions.%0D%0A%0D%0A%23%23+1.+Issue+type%0D%0A%3E%E2%8C%A6+Type+the+letter+%22x%22+in+the+%22checkbox%22+the+best+describe+this+issue.%0D%0A%0D%0A-+%5Bx%5D+**Feature%3A**+I%27m+requesting+a+product+enhancement.%0D%0A%0D%0A%23%23+2.+User+story+summary%0D%0A%3E%E2%8C%A6+Describe+what+you+want+to+accomplish%2C+in+what+role%2Fcapacity%2C+and+why+it%27s+important+to+you.%0D%0A%0D%0A%3E+**EXAMPLE%3A**%0D%0A%3E+As+a+Applicant%2C%0D%0A%3E+I+want+to+submit+my+resume%0D%0A%3E+In+order+to+be+considered+for+a+job+opening.%0D%0A%0D%0AAs+a+%7Brole%7D%2C%0D%0AI+must%2Fneed%2Fwant%2Fshould+%7Bdo+something%7D%0D%0AIn+order+to+%7Bachieve+value%7D.%0D%0A%0D%0A%23%23+3.+Acceptance+criteria%0D%0A%3E%E2%8C%A6+Replace+the+examples+below+with+your+own+imperative%2C+%22true%2Ffalse%22+statements+for+the+**behavior+you+expect**+to+see%2C+or+the+behavior+that+**would**+be+true+if+there+were+no+errors+%28for+defects%29.%0D%0A%0D%0A-+%5B+%5D+1.+Job+Applicants+receive+a+confirmation+email+after+they+submit+their+resumes.%0D%0A-+%5B+%5D+2.+An+Applicant%27s+resume+information+isn%27t+lost+when+errors+occur.%0D%0A-+%5B+%5D+3.+%7Bcriterion-three%7D%0D%0A-+%5B+%5D+4.+%7Bcriterion-four%7D%0D%0A%0D%0A%3C%21--+%E2%9B%94%EF%B8%8F++Do+not+remove+anything+below+this+comment.+%E2%9B%94%EF%B8%8F++--%3E%0D%0A%5Bicon-info-image%5D%3A+..%2Fdocs%2Fimg%2Ficons8%2Ficon-info-50.png%0D%0A
+[issues-url]: https://github.com/gregswindle/mvn-spring-boot-thymeleaf-nodejs/issues
[jest-logo-image]: ./docs/img/logo-jest.png
[jest-url]: https://facebook.github.io/jest/
[license-url]: ./LICENSE
@@ -1116,8 +1156,10 @@
[product-repo-logo-image]: ./docs/img/logo-commonalaxy.png
[product-repo-url]: .
[stackshare-badge-image]: https://img.shields.io/badge/tech-stack-0690fa.svg?style=flat-square
-[stackshare-url]: https://stackshare.io/gregswindle/spring-boot-starter-thymeleaf
+[stackshare-url]: https://stackshare.io/gregswindle/mvn-spring-boot-thymeleaf-nodejs
[standard-js-badge-image]: https://cdn.rawgit.com/standard/standard/master/badge.svg
[standard-js-url]: https://github.com/standard/standard
[standard-version-url]: https://github.com/conventional-changelog/standard-version
[tech-stack-image]: ./docs/img/icons8/icon-package-filled.png
+[checkstyle-icon-image]: ./docs/img/icon-checkstyle.png
+[checkstyle-url]: ./docs/google-java-style-guide.htm
diff --git a/README.md b/README.md
index f21cae8..2f8e128 100644
--- a/README.md
+++ b/README.md
@@ -1,18 +1,16 @@
-# `spring-boot-starter-thymeleaf`
+# `mvn-spring-boot-thymeleaf-nodejs`
[![License][license-badge-image]][license-url]
-[](https://snyk.io/test/github/gregswindle/spring-boot-starter-thymeleaf)
-[](https://dependencyci.com/github/gregswindle/spring-boot-starter-thymeleaf)
-[![Node.js Dependency Status][depstat-image]][depstat-url]
-[![Node.js DevDependency Status][depstat-dev-image]][depstat-dev-url]
-[](https://greenkeeper.io/)
+[](https://snyk.io/test/github/gregswindle/mvn-spring-boot-thymeleaf-nodejs)
+[](https://dependencyci.com/github/gregswindle/mvn-spring-boot-thymeleaf-nodejs)
+[](https://greenkeeper.io/)
[![Appveyor Status][appveyor-image]][appveyor-url]
[![Build Status][travis-image]][travis-url]
[![Coveralls Status][coveralls-image]][coveralls-url]
-> Starter project for designing HTML templates with Spring Boot, Thymeleaf, and Node.js tooling.
+>  Starter project for designing HTML templates with Spring Boot, Thymeleaf, and Node.js tooling.
## Table of contents
@@ -28,40 +26,42 @@
* [4.4. List all build dependencies](#44-list-all-build-dependencies)
* [4.5. Generate Javadocs](#45-generate-javadocs)
* [4.6. Generate project reports](#46-generate-project-reports)
+ * [4.7. Run DevSecOps helper scripts](#47-run-devsecops-helper-scripts)
- [5. Semantic version and `CHANGELOG`](#5-semantic-version-and-changelog)
- [6. Contributing](#6-contributing)
-- [7. License](#7-license)
+- [7. Roadmap](#7-roadmap)
+- [8. License](#8-license)
## 1. Overview
-`spring-boot-starter-thymeleaf` uses the Spring Project [`spring-boot-starter-thymeleaf`][spring-boot-starter-thymeleaf-mvn-repo-url] with the [`exec-maven-plugin`][exec-maven-plugin-url] in order to execute [`npm-run-scripts`][npm-run-script-url] during [Maven's build lifecycle][maven-build-lifecycle-url].
+`mvn-spring-boot-thymeleaf-nodejs` uses the Spring Project [`mvn-spring-boot-thymeleaf-nodejs`][mvn-spring-boot-thymeleaf-nodejs-mvn-repo-url] with the [`exec-maven-plugin`][exec-maven-plugin-url] in order to execute [`npm-run-scripts`][npm-run-script-url] during [Maven's build lifecycle][maven-build-lifecycle-url].
## 2. Getting started
### 2.1. Prerequisite software
-`spring-boot-starter-thymeleaf` is written in Java and JavaScript, both of which must be installed prior to use. Java and JavaScript require npm and Maven respectively, which are used for installing dependencies and executing build, test, and deploy tasks.
+`mvn-spring-boot-thymeleaf-nodejs` is written in Java and JavaScript, both of which must be installed prior to use. Java and JavaScript require npm and Maven respectively, which are used for installing dependencies and executing build, test, and deploy tasks.
-| Dependency | Required | OS | Notes |
-|-------------------------|----------------------------------------------------|-----------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| Java JDK 8 (or greater) | **Yes**. | All | Required for all software products that depend on the Spring Framework. |
-| Maven | **No**. This product is bundled with `mvnw`. | All | A Java build, test, and deploy management framework. Maven also manages dependencies. |
-| Node.js (includes npm) | **Yes**. If you cannot install `nvm`, install Node.js. | All | Required for JavaScript build, test, and deploy automation. |
-| `nvm` | **No**, but _highly_ recommended. | macOS and Linux | Node Version Manager allows you to install and switch among multiple versions of Node.js (and npm) via the CLI. Most cloud-based CI services (e.g., Travis CI) use `nvm`. |
+| Dependency | Required | OS | Notes |
+|:--------------------------------------------------------------------------------------------------------------------------|:-------------------------------------------------------|:----------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Java JDK 8 (or greater) [`oracle64-1.8.x1`][oracle64-jdk8-url] or [`openjdk:8-jdk-alpine`][openjdk8-jdk-alpine-url] | **Yes**. | All | Required for all software products that depend on the Spring Framework. |
+| [Maven][maven-url] | **No**. This product is bundled with `mvnw`. | All | A Java build, test, and deploy management framework. Maven also manages dependencies. |
+| Node.js (includes npm) | **Yes**. If you cannot install `nvm`, install Node.js. | All | Required for JavaScript build, test, and deploy automation. |
+| `nvm` | **No**, but _highly_ recommended. | macOS and Linux | Node Version Manager allows you to install and switch among multiple versions of Node.js (and npm) via the CLI. Most cloud-based CI services (e.g., Travis CI) use `nvm`. |
### 2.2. Installation
Open a Terminal and run:
```bash
-$ git clone https://github.com/gregswindle/spring-boot-starter-thymeleaf.git
+$ git clone https://github.com/gregswindle/mvn-spring-boot-thymeleaf-nodejs.git
```
Go into the installation directory:
```bash
-$ cd spring-boot-starter-thymeleaf
+$ cd mvn-spring-boot-thymeleaf-nodejs
```
Install all Java and JavaScript dependencies:
@@ -72,16 +72,16 @@ $ ./mvnw clean install -DskipTests
## 3. Configuration
-`spring-boot-starter-thymeleaf` uses several CI-services to automate build and test execution. All are optional, but if you choose to use them, you'll need to modify your `pom.xml` and `package.json` manifest files.
+`mvn-spring-boot-thymeleaf-nodejs` uses several CI-services to automate build and test execution. All are optional, but if you choose to use them, you'll need to modify your `pom.xml` and `package.json` manifest files.
-| Service | Category | Required | Notes |
-|--------------|------------------|-------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
-| Appveyor | CI | **No** | Build and test on Windows servers. |
-| Coveralls | Test | **No** | Tracks test coverage over time. |
-| DependencyCI | Dependency drift | **No** | Tracks Java and JavaScript dependencies for updates. |
-| SonarCloud | Code quality | **No** | "All-in-one" code quality inspection service. We use SonarCloud's measure badges in our PULL_REQUEST_TEMPLATE to quickly assess the quality of PRs. |
-| Snyk | Security | **No** | This is enabled by default. To disable, use the flag `--DskipSnykScan`. To use Snyk, you'll need to follow these [Snyk installation instructions](https://github.com/snyk/snyk-maven-plugin#installation). |
-| Travis CI | CI | **No** | Build and test on Linux and macOS. |
+| Service | Category | Required | Notes |
+|:-------------|:-----------------|:---------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
+| Appveyor | CI | **No** | Build and test on Windows servers. |
+| Coveralls | Test | **No** | Tracks test coverage over time. |
+| DependencyCI | Dependency drift | **No** | Tracks Java and JavaScript dependencies for updates. |
+| SonarCloud | Code quality | **No** | "All-in-one" code quality inspection service. We use SonarCloud's measure badges in our PULL_REQUEST_TEMPLATE to quickly assess the quality of PRs. |
+| Snyk | Security | **No** | This is enabled by default. To disable, use the flag `--DskipSnykScan`. To use Snyk, you'll need to follow these [Snyk installation instructions](https://github.com/snyk/snyk-maven-plugin#installation). |
+| Travis CI | CI | **No** | Build and test on Linux and macOS. |
## 4. Usage
@@ -92,7 +92,7 @@ $ ./mvnw clean install -DskipTests
$ ./mvnw spring-boot:run
```
-> **:bulb: TIP:** Open http://localhost:8080/hello?name=Thymeleaf%20professional in a web browser to view the web site.
+> **:bulb: TIP:** Open http://localhost:8080/home?name=Thymeleaf%20professional in a web browser to view the web site.
### 4.2. Build the site
@@ -129,53 +129,77 @@ $ ./mvnw site
> **:bulb: Tip:** Open `./target/site/index.html` in a web browser to view the Project Information reports.
-
+| Script | Description |
+|:------------------------|:-----------------------------------------------------------------------------------------------------------|
+| `docs` | `md-magic --path '{.github/*.md,**/*.md}' '**/*.md' --ignore 'node_modules' --config ./markdown.config.js` |
+| `docs:script` | `node ./markdown.config.js` |
+| `lint` | `npm run lint:node-version && npm run lint:js && npm run lint:manifest` |
+| `lint:js` | `eslint ./src/!{test}/resources/**/*.js --fix` |
+| `lint:manifest` | `./node_modules/.bin/fixpack` |
+| `lint:node-version` | `check-node-version --package` |
+| `outdated` | `npm outdated` |
+| `prepublish` | `npm run security` |
+| `release` | `standard-version` |
+| `security` | `npm run security:nsp:scan && npm run security:snyk:scan` |
+| `security:nsp:scan` | `nsp check` |
+| `security:snyk:monitor` | `snyk monitor` |
+| `security:snyk:scan` | `snyk test` |
+| `pretest` | `npm prune && npm run lint` |
+| `test` | `jest --forceExit --config=jest.config.json` |
+| `posttest` | `npm run security` |
+
+
-_If `spring-boot-starter-thymeleaf` depends on important but not widely known abstractions or other ecosystems, explain them here. This is also a good place to explain the product's motivation if similar products already exist._
--->
## 5. Semantic version and `CHANGELOG`
-The latest version of `spring-boot-starter-thymeleaf` is `0.0.1-SNAPSHOT`. View the [`CHANGELOG`][changelog-url] for details.
+The latest version of `mvn-spring-boot-thymeleaf-nodejs` is `0.0.1-SNAPSHOT`. View the [`CHANGELOG`][changelog-url] for details.
## 6. Contributing
> [![Learn how to make a Pull Request with free training][prs-welcome-badge-image]][prs-welcome-url]
>
> We welcome contributors with [Pull Requests][prs-welcome-url]!
+**[Read Contributing to `mvn-spring-boot-thymeleaf-nodejs` to get started.][contributing-url]**
+
Contributions in the form of GitHub pull requests are welcome. Before embarking on a significant change, please adhere to the following guidelines:
1. Read the [Code of Conduct][code-of-conduct-url].
1. Create an issue to discuss the proposed change and ensure that it is likely to be merged:
* [Report a defect][issues-new-defect-url] (aka "bug")
* [Request a new feature][issues-new-feat-url]
- 1. Follow [Contributing to `spring-boot-starter-thymeleaf`][contributing-url]'s coding conventions and Git workflow if you're willing and able to program (or want to learn how).
-
-## 7. License
+ 1. Follow [Contributing to `mvn-spring-boot-thymeleaf-nodejs`][contributing-url]'s coding conventions and Git workflow if you're willing and able to program (or want to learn how).
-[MIT][license-url] © [Greg Swindle][author-url].
+## 7. Roadmap
+To make these quality assurance goals easier to consume and manage, I'll likely bundle everything into a maven-plugin. I need to test and analyze stuff more in the meantime, however.
+## 8. License
+[MIT][license-url] © [Greg Swindle][author-url].
-[appveyor-image]: https://ci.appveyor.com/api/projects/status/github/gregswindle/spring-boot-starter-thymeleaf?retina=true&svg=true
-[appveyor-url]: https://ci.appveyor.com/api/projects/status/github/gregswindle/spring-boot-starter-thymeleaf?retina=true&svg=true
+[appveyor-image]: https://ci.appveyor.com/api/projects/status/github/gregswindle/mvn-spring-boot-thymeleaf-nodejs?retina=true&svg=true
+[appveyor-url]: https://ci.appveyor.com/api/projects/status/github/gregswindle/mvn-spring-boot-thymeleaf-nodejs?retina=true&svg=true
[author-url]: https://github.com/gregswindle
[changelog-url]: ./CHANGELOG.md
[code-of-conduct-url]: ./CODE_OF_CONDUCT.md
[contributing-url]: ./CONTRIBUTING.md
-[coveralls-image]: https://img.shields.io/coveralls/gregswindle/spring-boot-starter-thymeleaf/master.svg?style=flat-square
-[coveralls-url]: https://coveralls.io/r/gregswindle/spring-boot-starter-thymeleaf
-[depstat-dev-image]: https://david-dm.org/gregswindle/spring-boot-starter-thymeleaf/dev-status.svg?style=flat-square
-[depstat-dev-url]: https://david-dm.org/gregswindle/spring-boot-starter-thymeleaf#info=devDependencies
-[depstat-image]: https://david-dm.org/gregswindle/spring-boot-starter-thymeleaf.svg?style=flat-square
-[depstat-url]: https://david-dm.org/gregswindle/spring-boot-starter-thymeleaf
+[coveralls-image]: https://img.shields.io/coveralls/gregswindle/mvn-spring-boot-thymeleaf-nodejs/master.svg?style=flat-square
+[coveralls-url]: https://coveralls.io/r/gregswindle/mvn-spring-boot-thymeleaf-nodejs
+[depstat-dev-image]: https://david-dm.org/gregswindle/mvn-spring-boot-thymeleaf-nodejs/dev-status.svg?style=flat-square
+[depstat-dev-url]: https://david-dm.org/gregswindle/mvn-spring-boot-thymeleaf-nodejs#info=devDependencies
+[depstat-image]: https://david-dm.org/gregswindle/mvn-spring-boot-thymeleaf-nodejs.svg?style=flat-square
+[depstat-url]: https://david-dm.org/gregswindle/mvn-spring-boot-thymeleaf-nodejs
[exec-maven-plugin-url]: http://www.mojohaus.org/exec-maven-plugin/index.html
-[issues-new-defect-url]: /gregswindle/spring-boot-starter-thymeleaf/issues/new?title=fix%28affected-scope%29%3A+subject-line-with-very-few-words&labels=Priority%3A+Medium%2CStatus%3A+Review+Needed%2CType%3A+Defect&body=%2A%2A%F0%9F%92%A1+TIP%3A%2A%2A+Select+the+%E2%86%96%EF%B8%8E%E2%8E%BE+Preview+%E2%8F%8B+Tab+above+help+read+these+instructions.%0D%0A%0D%0A%23%23+1.+Issue+type%0D%0A%3E%E2%8C%A6+Type+the+letter+%22x%22+in+the+%22checkbox%22+the+best+describe+this+issue.%0D%0A%0D%0A-+%5Bx%5D+__Feature%3A__+I%27m+requesting+a+product+enhancement.%0D%0A%0D%0A%23%23+2.+User+story+summary%0D%0A%3E%E2%8C%A6+Describe+what+you+want+to+accomplish%2C+in+what+role%2Fcapacity%2C+and+why+it%27s+important+to+you.%0D%0A%0D%0A%3E+__EXAMPLE%3A__%0D%0A%3E+As+a+Applicant%2C%0D%0A%3E+I+want+to+submit+my+resume%0D%0A%3E+In+order+to+be+considered+for+a+job+opening.%0D%0A%0D%0AAs+a+%7Brole%7D%2C%0D%0AI+must%2Fneed%2Fwant%2Fshould+%7Bdo+something%7D%0D%0AIn+order+to+%7Bachieve+value%7D.%0D%0A%0D%0A%23%23+3.+Acceptance+criteria%0D%0A%3E%E2%8C%A6+Replace+the+examples+below+with+your+own+imperative%2C+%22true%2Ffalse%22+statements+for+the+__behavior+you+expect__+to+see%2C+or+the+behavior+that+__would__+be+true+if+there+were+no+errors+%28for+defects%29.%0D%0A%0D%0A-+%5B+%5D+1.+Job+Applicants+receive+a+confirmation+email+after+they+submit+their+resumes.%0D%0A-+%5B+%5D+2.+An+Applicant%27s+resume+information+isn%27t+lost+when+errors+occur.%0D%0A-+%5B+%5D+3.+%7Bcriterion-three%7D%0D%0A-+%5B+%5D+4.+%7Bcriterion-four%7D%0D%0A%0D%0A%3C%21--+%E2%9B%94%EF%B8%8F++Do+not+remove+anything+below+this+comment.+%E2%9B%94%EF%B8%8F++--%3E%0D%0A%5Bicon-info-image%5D%3A+..%2Fdocs%2Fimg%2Ficons8%2Ficon-info-50.png%0D%0A
-[issues-new-feat-url]: /gregswindle/spring-boot-starter-thymeleaf/issues/new?title=feat%28affected-scope%29%3A+subject-line-with-very-few-words&labels=Priority%3A+Medium%2CStatus%3A+Review+Needed%2CType%3A+Feature&body=%2A%2A%F0%9F%92%A1+TIP%3A%2A%2A+Select+the+%E2%86%96%EF%B8%8E%E2%8E%BE+Preview+%E2%8F%8B+Tab+above+help+read+these+instructions.%0D%0A%0D%0A%23%23+1.+Issue+type%0D%0A%3E%E2%8C%A6+Type+the+letter+%22x%22+in+the+%22checkbox%22+the+best+describe+this+issue.%0D%0A%0D%0A-+%5Bx%5D+__Feature%3A__+I%27m+requesting+a+product+enhancement.%0D%0A%0D%0A%23%23+2.+User+story+summary%0D%0A%3E%E2%8C%A6+Describe+what+you+want+to+accomplish%2C+in+what+role%2Fcapacity%2C+and+why+it%27s+important+to+you.%0D%0A%0D%0A%3E+__EXAMPLE%3A__%0D%0A%3E+As+a+Applicant%2C%0D%0A%3E+I+want+to+submit+my+resume%0D%0A%3E+In+order+to+be+considered+for+a+job+opening.%0D%0A%0D%0AAs+a+%7Brole%7D%2C%0D%0AI+must%2Fneed%2Fwant%2Fshould+%7Bdo+something%7D%0D%0AIn+order+to+%7Bachieve+value%7D.%0D%0A%0D%0A%23%23+3.+Acceptance+criteria%0D%0A%3E%E2%8C%A6+Replace+the+examples+below+with+your+own+imperative%2C+%22true%2Ffalse%22+statements+for+the+__behavior+you+expect__+to+see%2C+or+the+behavior+that+__would__+be+true+if+there+were+no+errors+%28for+defects%29.%0D%0A%0D%0A-+%5B+%5D+1.+Job+Applicants+receive+a+confirmation+email+after+they+submit+their+resumes.%0D%0A-+%5B+%5D+2.+An+Applicant%27s+resume+information+isn%27t+lost+when+errors+occur.%0D%0A-+%5B+%5D+3.+%7Bcriterion-three%7D%0D%0A-+%5B+%5D+4.+%7Bcriterion-four%7D%0D%0A%0D%0A%3C%21--+%E2%9B%94%EF%B8%8F++Do+not+remove+anything+below+this+comment.+%E2%9B%94%EF%B8%8F++--%3E%0D%0A%5Bicon-info-image%5D%3A+..%2Fdocs%2Fimg%2Ficons8%2Ficon-info-50.png%0D%0A
+[issues-new-defect-url]: /gregswindle/mvn-spring-boot-thymeleaf-nodejs/issues/new?title=fix%28affected-scope%29%3A+subject-line-with-very-few-words&labels=Priority%3A+Medium%2CStatus%3A+Review+Needed%2CType%3A+Defect&body=%2A%2A%F0%9F%92%A1+TIP%3A%2A%2A+Select+the+%E2%86%96%EF%B8%8E%E2%8E%BE+Preview+%E2%8F%8B+Tab+above+help+read+these+instructions.%0D%0A%0D%0A%23%23+1.+Issue+type%0D%0A%3E%E2%8C%A6+Type+the+letter+%22x%22+in+the+%22checkbox%22+the+best+describe+this+issue.%0D%0A%0D%0A-+%5Bx%5D+__Feature%3A__+I%27m+requesting+a+product+enhancement.%0D%0A%0D%0A%23%23+2.+User+story+summary%0D%0A%3E%E2%8C%A6+Describe+what+you+want+to+accomplish%2C+in+what+role%2Fcapacity%2C+and+why+it%27s+important+to+you.%0D%0A%0D%0A%3E+__EXAMPLE%3A__%0D%0A%3E+As+a+Applicant%2C%0D%0A%3E+I+want+to+submit+my+resume%0D%0A%3E+In+order+to+be+considered+for+a+job+opening.%0D%0A%0D%0AAs+a+%7Brole%7D%2C%0D%0AI+must%2Fneed%2Fwant%2Fshould+%7Bdo+something%7D%0D%0AIn+order+to+%7Bachieve+value%7D.%0D%0A%0D%0A%23%23+3.+Acceptance+criteria%0D%0A%3E%E2%8C%A6+Replace+the+examples+below+with+your+own+imperative%2C+%22true%2Ffalse%22+statements+for+the+__behavior+you+expect__+to+see%2C+or+the+behavior+that+__would__+be+true+if+there+were+no+errors+%28for+defects%29.%0D%0A%0D%0A-+%5B+%5D+1.+Job+Applicants+receive+a+confirmation+email+after+they+submit+their+resumes.%0D%0A-+%5B+%5D+2.+An+Applicant%27s+resume+information+isn%27t+lost+when+errors+occur.%0D%0A-+%5B+%5D+3.+%7Bcriterion-three%7D%0D%0A-+%5B+%5D+4.+%7Bcriterion-four%7D%0D%0A%0D%0A%3C%21--+%E2%9B%94%EF%B8%8F++Do+not+remove+anything+below+this+comment.+%E2%9B%94%EF%B8%8F++--%3E%0D%0A%5Bicon-info-image%5D%3A+..%2Fdocs%2Fimg%2Ficons8%2Ficon-info-50.png%0D%0A
+[issues-new-feat-url]: /gregswindle/mvn-spring-boot-thymeleaf-nodejs/issues/new?title=feat%28affected-scope%29%3A+subject-line-with-very-few-words&labels=Priority%3A+Medium%2CStatus%3A+Review+Needed%2CType%3A+Feature&body=%2A%2A%F0%9F%92%A1+TIP%3A%2A%2A+Select+the+%E2%86%96%EF%B8%8E%E2%8E%BE+Preview+%E2%8F%8B+Tab+above+help+read+these+instructions.%0D%0A%0D%0A%23%23+1.+Issue+type%0D%0A%3E%E2%8C%A6+Type+the+letter+%22x%22+in+the+%22checkbox%22+the+best+describe+this+issue.%0D%0A%0D%0A-+%5Bx%5D+__Feature%3A__+I%27m+requesting+a+product+enhancement.%0D%0A%0D%0A%23%23+2.+User+story+summary%0D%0A%3E%E2%8C%A6+Describe+what+you+want+to+accomplish%2C+in+what+role%2Fcapacity%2C+and+why+it%27s+important+to+you.%0D%0A%0D%0A%3E+__EXAMPLE%3A__%0D%0A%3E+As+a+Applicant%2C%0D%0A%3E+I+want+to+submit+my+resume%0D%0A%3E+In+order+to+be+considered+for+a+job+opening.%0D%0A%0D%0AAs+a+%7Brole%7D%2C%0D%0AI+must%2Fneed%2Fwant%2Fshould+%7Bdo+something%7D%0D%0AIn+order+to+%7Bachieve+value%7D.%0D%0A%0D%0A%23%23+3.+Acceptance+criteria%0D%0A%3E%E2%8C%A6+Replace+the+examples+below+with+your+own+imperative%2C+%22true%2Ffalse%22+statements+for+the+__behavior+you+expect__+to+see%2C+or+the+behavior+that+__would__+be+true+if+there+were+no+errors+%28for+defects%29.%0D%0A%0D%0A-+%5B+%5D+1.+Job+Applicants+receive+a+confirmation+email+after+they+submit+their+resumes.%0D%0A-+%5B+%5D+2.+An+Applicant%27s+resume+information+isn%27t+lost+when+errors+occur.%0D%0A-+%5B+%5D+3.+%7Bcriterion-three%7D%0D%0A-+%5B+%5D+4.+%7Bcriterion-four%7D%0D%0A%0D%0A%3C%21--+%E2%9B%94%EF%B8%8F++Do+not+remove+anything+below+this+comment.+%E2%9B%94%EF%B8%8F++--%3E%0D%0A%5Bicon-info-image%5D%3A+..%2Fdocs%2Fimg%2Ficons8%2Ficon-info-50.png%0D%0A
[license-badge-image]: https://img.shields.io/badge/License-MIT-blue.svg?style=flat-square
[license-choose-url]: https://choosealicense.com/
[license-no-license-url]: https://choosealicense.com/no-license/
@@ -183,14 +207,17 @@ Contributions in the form of GitHub pull requests are welcome. Before embarking
[license-url]: ./LICENSE
[license-url]: ./LICENSE
[maven-build-lifecycle-url]: https://maven.apache.org/guides/introduction/introduction-to-the-lifecycle.html
+[mvn-spring-boot-thymeleaf-nodejs-mvn-repo-url]: https://mvnrepository.com/artifact/org.springframework.boot/mvn-spring-boot-thymeleaf-nodejs
+[maven-url]: https://maven.apache.org/
[nodejs-url]: https://nodejs.org
-[npm-image]: https://img.shields.io/npm/v/spring-boot-starter-thymeleaf.svg?style=flat-square
+[npm-image]: https://img.shields.io/npm/v/mvn-spring-boot-thymeleaf-nodejs.svg?style=flat-square
[npm-run-script-url]: https://docs.npmjs.com/cli/run-script
[npm-script-url]: https://docs.npmjs.com/misc/scripts
-[npm-url]: https://npmjs.org/package/spring-boot-starter-thymeleaf
+[npm-url]: https://npmjs.org/package/mvn-spring-boot-thymeleaf-nodejs
[npmjs-url]: https://www.npmjs.com/
+[openjdk8-jdk-alpine-url]: https://github.com/docker-library/openjdk/blob/b4f29ba829765552239bd18f272fcdaf09eca259/8-jdk/alpine/Dockerfile
+[oracle64-jdk8-url]: http://www.oracle.com/technetwork/java/javaee/downloads/index.html
[prs-welcome-badge-image]: https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat-square
[prs-welcome-url]: http://makeapullrequest.com
-[spring-boot-starter-thymeleaf-mvn-repo-url]: https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-thymeleaf
-[travis-image]: https://img.shields.io/travis/gregswindle/spring-boot-starter-thymeleaf/master.svg?style=flat-square
-[travis-url]: https://travis-ci.org/gregswindle/spring-boot-starter-thymeleaf
+[travis-image]: https://img.shields.io/travis/gregswindle/mvn-spring-boot-thymeleaf-nodejs/master.svg?style=flat-square
+[travis-url]: https://travis-ci.org/gregswindle/mvn-spring-boot-thymeleaf-nodejs
diff --git a/docs/img/site/jacoco/index.html b/docs/img/site/jacoco/index.html
deleted file mode 100644
index 2288dd6..0000000
--- a/docs/img/site/jacoco/index.html
+++ /dev/null
@@ -1 +0,0 @@
-spring-boot-starter-thymeleaf spring-boot-starter-thymeleaf
\ No newline at end of file
diff --git a/docs/img/site/jacoco/jacoco-resources/branchfc.gif b/docs/img/site/jacoco/jacoco-resources/branchfc.gif
deleted file mode 100644
index 989b46d..0000000
Binary files a/docs/img/site/jacoco/jacoco-resources/branchfc.gif and /dev/null differ
diff --git a/docs/img/site/jacoco/jacoco-resources/branchnc.gif b/docs/img/site/jacoco/jacoco-resources/branchnc.gif
deleted file mode 100644
index 1933e07..0000000
Binary files a/docs/img/site/jacoco/jacoco-resources/branchnc.gif and /dev/null differ
diff --git a/docs/img/site/jacoco/jacoco-resources/branchpc.gif b/docs/img/site/jacoco/jacoco-resources/branchpc.gif
deleted file mode 100644
index cbf711b..0000000
Binary files a/docs/img/site/jacoco/jacoco-resources/branchpc.gif and /dev/null differ
diff --git a/docs/img/site/jacoco/jacoco-resources/bundle.gif b/docs/img/site/jacoco/jacoco-resources/bundle.gif
deleted file mode 100644
index fca9c53..0000000
Binary files a/docs/img/site/jacoco/jacoco-resources/bundle.gif and /dev/null differ
diff --git a/docs/img/site/jacoco/jacoco-resources/class.gif b/docs/img/site/jacoco/jacoco-resources/class.gif
deleted file mode 100644
index eb348fb..0000000
Binary files a/docs/img/site/jacoco/jacoco-resources/class.gif and /dev/null differ
diff --git a/docs/img/site/jacoco/jacoco-resources/down.gif b/docs/img/site/jacoco/jacoco-resources/down.gif
deleted file mode 100644
index 440a14d..0000000
Binary files a/docs/img/site/jacoco/jacoco-resources/down.gif and /dev/null differ
diff --git a/docs/img/site/jacoco/jacoco-resources/greenbar.gif b/docs/img/site/jacoco/jacoco-resources/greenbar.gif
deleted file mode 100644
index 0ba6567..0000000
Binary files a/docs/img/site/jacoco/jacoco-resources/greenbar.gif and /dev/null differ
diff --git a/docs/img/site/jacoco/jacoco-resources/group.gif b/docs/img/site/jacoco/jacoco-resources/group.gif
deleted file mode 100644
index a4ea580..0000000
Binary files a/docs/img/site/jacoco/jacoco-resources/group.gif and /dev/null differ
diff --git a/docs/img/site/jacoco/jacoco-resources/method.gif b/docs/img/site/jacoco/jacoco-resources/method.gif
deleted file mode 100644
index 7d24707..0000000
Binary files a/docs/img/site/jacoco/jacoco-resources/method.gif and /dev/null differ
diff --git a/docs/img/site/jacoco/jacoco-resources/package.gif b/docs/img/site/jacoco/jacoco-resources/package.gif
deleted file mode 100644
index 131c28d..0000000
Binary files a/docs/img/site/jacoco/jacoco-resources/package.gif and /dev/null differ
diff --git a/docs/img/site/jacoco/jacoco-resources/prettify.css b/docs/img/site/jacoco/jacoco-resources/prettify.css
deleted file mode 100644
index be5166e..0000000
--- a/docs/img/site/jacoco/jacoco-resources/prettify.css
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Pretty printing styles. Used with prettify.js. */
-
-.str { color: #2A00FF; }
-.kwd { color: #7F0055; font-weight:bold; }
-.com { color: #3F5FBF; }
-.typ { color: #606; }
-.lit { color: #066; }
-.pun { color: #660; }
-.pln { color: #000; }
-.tag { color: #008; }
-.atn { color: #606; }
-.atv { color: #080; }
-.dec { color: #606; }
diff --git a/docs/img/site/jacoco/jacoco-resources/prettify.js b/docs/img/site/jacoco/jacoco-resources/prettify.js
deleted file mode 100644
index ab27882..0000000
--- a/docs/img/site/jacoco/jacoco-resources/prettify.js
+++ /dev/null
@@ -1,1510 +0,0 @@
-// Copyright (C) 2006 Google Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-
-/**
- * @fileoverview
- * some functions for browser-side pretty printing of code contained in html.
- *
- *
- * For a fairly comprehensive set of languages see the
- * README
- * file that came with this source. At a minimum, the lexer should work on a
- * number of languages including C and friends, Java, Python, Bash, SQL, HTML,
- * XML, CSS, Javascript, and Makefiles. It works passably on Ruby, PHP and Awk
- * and a subset of Perl, but, because of commenting conventions, doesn't work on
- * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class.
- *
- * Usage:
- * include this source file in an html page via
- * {@code }
- * define style rules. See the example page for examples.
- * mark the {@code } and {@code } tags in your source with
- * {@code class=prettyprint.}
- * You can also use the (html deprecated) {@code } tag, but the pretty
- * printer needs to do more substantial DOM manipulations to support that, so
- * some css styles may not be preserved.
- *
- * That's it. I wanted to keep the API as simple as possible, so there's no
- * need to specify which language the code is in, but if you wish, you can add
- * another class to the {@code } or {@code } element to specify the
- * language, as in {@code }. Any class that
- * starts with "lang-" followed by a file extension, specifies the file type.
- * See the "lang-*.js" files in this directory for code that implements
- * per-language file handlers.
- *
- * Change log:
- * cbeust, 2006/08/22
- *
- * Java annotations (start with "@") are now captured as literals ("lit")
- *
- * @requires console
- */
-
-// JSLint declarations
-/*global console, document, navigator, setTimeout, window */
-
-/**
- * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
- * UI events.
- * If set to {@code false}, {@code prettyPrint()} is synchronous.
- */
-window['PR_SHOULD_USE_CONTINUATION'] = true;
-
-/** the number of characters between tab columns */
-window['PR_TAB_WIDTH'] = 8;
-
-/** Walks the DOM returning a properly escaped version of innerHTML.
- * @param {Node} node
- * @param {Array.} out output buffer that receives chunks of HTML.
- */
-window['PR_normalizedHtml']
-
-/** Contains functions for creating and registering new language handlers.
- * @type {Object}
- */
- = window['PR']
-
-/** Pretty print a chunk of code.
- *
- * @param {string} sourceCodeHtml code as html
- * @return {string} code as html, but prettier
- */
- = window['prettyPrintOne']
-/** Find all the {@code } and {@code } tags in the DOM with
- * {@code class=prettyprint} and prettify them.
- * @param {Function?} opt_whenDone if specified, called when the last entry
- * has been finished.
- */
- = window['prettyPrint'] = void 0;
-
-/** browser detection. @extern @returns false if not IE, otherwise the major version. */
-window['_pr_isIE6'] = function () {
- var ieVersion = navigator && navigator.userAgent &&
- navigator.userAgent.match(/\bMSIE ([678])\./);
- ieVersion = ieVersion ? +ieVersion[1] : false;
- window['_pr_isIE6'] = function () { return ieVersion; };
- return ieVersion;
-};
-
-
-(function () {
- // Keyword lists for various languages.
- var FLOW_CONTROL_KEYWORDS =
- "break continue do else for if return while ";
- var C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "auto case char const default " +
- "double enum extern float goto int long register short signed sizeof " +
- "static struct switch typedef union unsigned void volatile ";
- var COMMON_KEYWORDS = C_KEYWORDS + "catch class delete false import " +
- "new operator private protected public this throw true try typeof ";
- var CPP_KEYWORDS = COMMON_KEYWORDS + "alignof align_union asm axiom bool " +
- "concept concept_map const_cast constexpr decltype " +
- "dynamic_cast explicit export friend inline late_check " +
- "mutable namespace nullptr reinterpret_cast static_assert static_cast " +
- "template typeid typename using virtual wchar_t where ";
- var JAVA_KEYWORDS = COMMON_KEYWORDS +
- "abstract boolean byte extends final finally implements import " +
- "instanceof null native package strictfp super synchronized throws " +
- "transient ";
- var CSHARP_KEYWORDS = JAVA_KEYWORDS +
- "as base by checked decimal delegate descending event " +
- "fixed foreach from group implicit in interface internal into is lock " +
- "object out override orderby params partial readonly ref sbyte sealed " +
- "stackalloc string select uint ulong unchecked unsafe ushort var ";
- var JSCRIPT_KEYWORDS = COMMON_KEYWORDS +
- "debugger eval export function get null set undefined var with " +
- "Infinity NaN ";
- var PERL_KEYWORDS = "caller delete die do dump elsif eval exit foreach for " +
- "goto if import last local my next no our print package redo require " +
- "sub undef unless until use wantarray while BEGIN END ";
- var PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "and as assert class def del " +
- "elif except exec finally from global import in is lambda " +
- "nonlocal not or pass print raise try with yield " +
- "False True None ";
- var RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "alias and begin case class def" +
- " defined elsif end ensure false in module next nil not or redo rescue " +
- "retry self super then true undef unless until when yield BEGIN END ";
- var SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "case done elif esac eval fi " +
- "function in local set then until ";
- var ALL_KEYWORDS = (
- CPP_KEYWORDS + CSHARP_KEYWORDS + JSCRIPT_KEYWORDS + PERL_KEYWORDS +
- PYTHON_KEYWORDS + RUBY_KEYWORDS + SH_KEYWORDS);
-
- // token style names. correspond to css classes
- /** token style for a string literal */
- var PR_STRING = 'str';
- /** token style for a keyword */
- var PR_KEYWORD = 'kwd';
- /** token style for a comment */
- var PR_COMMENT = 'com';
- /** token style for a type */
- var PR_TYPE = 'typ';
- /** token style for a literal value. e.g. 1, null, true. */
- var PR_LITERAL = 'lit';
- /** token style for a punctuation string. */
- var PR_PUNCTUATION = 'pun';
- /** token style for a punctuation string. */
- var PR_PLAIN = 'pln';
-
- /** token style for an sgml tag. */
- var PR_TAG = 'tag';
- /** token style for a markup declaration such as a DOCTYPE. */
- var PR_DECLARATION = 'dec';
- /** token style for embedded source. */
- var PR_SOURCE = 'src';
- /** token style for an sgml attribute name. */
- var PR_ATTRIB_NAME = 'atn';
- /** token style for an sgml attribute value. */
- var PR_ATTRIB_VALUE = 'atv';
-
- /**
- * A class that indicates a section of markup that is not code, e.g. to allow
- * embedding of line numbers within code listings.
- */
- var PR_NOCODE = 'nocode';
-
- /** A set of tokens that can precede a regular expression literal in
- * javascript.
- * http://www.mozilla.org/js/language/js20/rationale/syntax.html has the full
- * list, but I've removed ones that might be problematic when seen in
- * languages that don't support regular expression literals.
- *
- * Specifically, I've removed any keywords that can't precede a regexp
- * literal in a syntactically legal javascript program, and I've removed the
- * "in" keyword since it's not a keyword in many languages, and might be used
- * as a count of inches.
- *
- *
The link a above does not accurately describe EcmaScript rules since
- * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
- * very well in practice.
- *
- * @private
- */
- var REGEXP_PRECEDER_PATTERN = function () {
- var preceders = [
- "!", "!=", "!==", "#", "%", "%=", "&", "&&", "&&=",
- "&=", "(", "*", "*=", /* "+", */ "+=", ",", /* "-", */ "-=",
- "->", /*".", "..", "...", handled below */ "/", "/=", ":", "::", ";",
- "<", "<<", "<<=", "<=", "=", "==", "===", ">",
- ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[",
- "^", "^=", "^^", "^^=", "{", "|", "|=", "||",
- "||=", "~" /* handles =~ and !~ */,
- "break", "case", "continue", "delete",
- "do", "else", "finally", "instanceof",
- "return", "throw", "try", "typeof"
- ];
- var pattern = '(?:^^|[+-]';
- for (var i = 0; i < preceders.length; ++i) {
- pattern += '|' + preceders[i].replace(/([^=<>:&a-z])/g, '\\$1');
- }
- pattern += ')\\s*'; // matches at end, and matches empty string
- return pattern;
- // CAVEAT: this does not properly handle the case where a regular
- // expression immediately follows another since a regular expression may
- // have flags for case-sensitivity and the like. Having regexp tokens
- // adjacent is not valid in any language I'm aware of, so I'm punting.
- // TODO: maybe style special characters inside a regexp as punctuation.
- }();
-
- // Define regexps here so that the interpreter doesn't have to create an
- // object each time the function containing them is called.
- // The language spec requires a new object created even if you don't access
- // the $1 members.
- var pr_amp = /&/g;
- var pr_lt = //g;
- var pr_quot = /\"/g;
- /** like textToHtml but escapes double quotes to be attribute safe. */
- function attribToHtml(str) {
- return str.replace(pr_amp, '&')
- .replace(pr_lt, '<')
- .replace(pr_gt, '>')
- .replace(pr_quot, '"');
- }
-
- /** escapest html special characters to html. */
- function textToHtml(str) {
- return str.replace(pr_amp, '&')
- .replace(pr_lt, '<')
- .replace(pr_gt, '>');
- }
-
-
- var pr_ltEnt = /</g;
- var pr_gtEnt = />/g;
- var pr_aposEnt = /'/g;
- var pr_quotEnt = /"/g;
- var pr_ampEnt = /&/g;
- var pr_nbspEnt = / /g;
- /** unescapes html to plain text. */
- function htmlToText(html) {
- var pos = html.indexOf('&');
- if (pos < 0) { return html; }
- // Handle numeric entities specially. We can't use functional substitution
- // since that doesn't work in older versions of Safari.
- // These should be rare since most browsers convert them to normal chars.
- for (--pos; (pos = html.indexOf('', pos + 1)) >= 0;) {
- var end = html.indexOf(';', pos);
- if (end >= 0) {
- var num = html.substring(pos + 3, end);
- var radix = 10;
- if (num && num.charAt(0) === 'x') {
- num = num.substring(1);
- radix = 16;
- }
- var codePoint = parseInt(num, radix);
- if (!isNaN(codePoint)) {
- html = (html.substring(0, pos) + String.fromCharCode(codePoint) +
- html.substring(end + 1));
- }
- }
- }
-
- return html.replace(pr_ltEnt, '<')
- .replace(pr_gtEnt, '>')
- .replace(pr_aposEnt, "'")
- .replace(pr_quotEnt, '"')
- .replace(pr_nbspEnt, ' ')
- .replace(pr_ampEnt, '&');
- }
-
- /** is the given node's innerHTML normally unescaped? */
- function isRawContent(node) {
- return 'XMP' === node.tagName;
- }
-
- var newlineRe = /[\r\n]/g;
- /**
- * Are newlines and adjacent spaces significant in the given node's innerHTML?
- */
- function isPreformatted(node, content) {
- // PRE means preformatted, and is a very common case, so don't create
- // unnecessary computed style objects.
- if ('PRE' === node.tagName) { return true; }
- if (!newlineRe.test(content)) { return true; } // Don't care
- var whitespace = '';
- // For disconnected nodes, IE has no currentStyle.
- if (node.currentStyle) {
- whitespace = node.currentStyle.whiteSpace;
- } else if (window.getComputedStyle) {
- // Firefox makes a best guess if node is disconnected whereas Safari
- // returns the empty string.
- whitespace = window.getComputedStyle(node, null).whiteSpace;
- }
- return !whitespace || whitespace === 'pre';
- }
-
- function normalizedHtml(node, out, opt_sortAttrs) {
- switch (node.nodeType) {
- case 1: // an element
- var name = node.tagName.toLowerCase();
-
- out.push('<', name);
- var attrs = node.attributes;
- var n = attrs.length;
- if (n) {
- if (opt_sortAttrs) {
- var sortedAttrs = [];
- for (var i = n; --i >= 0;) { sortedAttrs[i] = attrs[i]; }
- sortedAttrs.sort(function (a, b) {
- return (a.name < b.name) ? -1 : a.name === b.name ? 0 : 1;
- });
- attrs = sortedAttrs;
- }
- for (var i = 0; i < n; ++i) {
- var attr = attrs[i];
- if (!attr.specified) { continue; }
- out.push(' ', attr.name.toLowerCase(),
- '="', attribToHtml(attr.value), '"');
- }
- }
- out.push('>');
- for (var child = node.firstChild; child; child = child.nextSibling) {
- normalizedHtml(child, out, opt_sortAttrs);
- }
- if (node.firstChild || !/^(?:br|link|img)$/.test(name)) {
- out.push('<\/', name, '>');
- }
- break;
- case 3: case 4: // text
- out.push(textToHtml(node.nodeValue));
- break;
- }
- }
-
- /**
- * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
- * matches the union o the sets o strings matched d by the input RegExp.
- * Since it matches globally, if the input strings have a start-of-input
- * anchor (/^.../), it is ignored for the purposes of unioning.
- * @param {Array.} regexs non multiline, non-global regexs.
- * @return {RegExp} a global regex.
- */
- function combinePrefixPatterns(regexs) {
- var capturedGroupIndex = 0;
-
- var needToFoldCase = false;
- var ignoreCase = false;
- for (var i = 0, n = regexs.length; i < n; ++i) {
- var regex = regexs[i];
- if (regex.ignoreCase) {
- ignoreCase = true;
- } else if (/[a-z]/i.test(regex.source.replace(
- /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
- needToFoldCase = true;
- ignoreCase = false;
- break;
- }
- }
-
- function decodeEscape(charsetPart) {
- if (charsetPart.charAt(0) !== '\\') { return charsetPart.charCodeAt(0); }
- switch (charsetPart.charAt(1)) {
- case 'b': return 8;
- case 't': return 9;
- case 'n': return 0xa;
- case 'v': return 0xb;
- case 'f': return 0xc;
- case 'r': return 0xd;
- case 'u': case 'x':
- return parseInt(charsetPart.substring(2), 16)
- || charsetPart.charCodeAt(1);
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7':
- return parseInt(charsetPart.substring(1), 8);
- default: return charsetPart.charCodeAt(1);
- }
- }
-
- function encodeEscape(charCode) {
- if (charCode < 0x20) {
- return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
- }
- var ch = String.fromCharCode(charCode);
- if (ch === '\\' || ch === '-' || ch === '[' || ch === ']') {
- ch = '\\' + ch;
- }
- return ch;
- }
-
- function caseFoldCharset(charSet) {
- var charsetParts = charSet.substring(1, charSet.length - 1).match(
- new RegExp(
- '\\\\u[0-9A-Fa-f]{4}'
- + '|\\\\x[0-9A-Fa-f]{2}'
- + '|\\\\[0-3][0-7]{0,2}'
- + '|\\\\[0-7]{1,2}'
- + '|\\\\[\\s\\S]'
- + '|-'
- + '|[^-\\\\]',
- 'g'));
- var groups = [];
- var ranges = [];
- var inverse = charsetParts[0] === '^';
- for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
- var p = charsetParts[i];
- switch (p) {
- case '\\B': case '\\b':
- case '\\D': case '\\d':
- case '\\S': case '\\s':
- case '\\W': case '\\w':
- groups.push(p);
- continue;
- }
- var start = decodeEscape(p);
- var end;
- if (i + 2 < n && '-' === charsetParts[i + 1]) {
- end = decodeEscape(charsetParts[i + 2]);
- i += 2;
- } else {
- end = start;
- }
- ranges.push([start, end]);
- // If the range might intersect letters, then expand it.
- if (!(end < 65 || start > 122)) {
- if (!(end < 65 || start > 90)) {
- ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
- }
- if (!(end < 97 || start > 122)) {
- ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
- }
- }
- }
-
- // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
- // -> [[1, 12], [14, 14], [16, 17]]
- ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1] - a[1]); });
- var consolidatedRanges = [];
- var lastRange = [NaN, NaN];
- for (var i = 0; i < ranges.length; ++i) {
- var range = ranges[i];
- if (range[0] <= lastRange[1] + 1) {
- lastRange[1] = Math.max(lastRange[1], range[1]);
- } else {
- consolidatedRanges.push(lastRange = range);
- }
- }
-
- var out = ['['];
- if (inverse) { out.push('^'); }
- out.push.apply(out, groups);
- for (var i = 0; i < consolidatedRanges.length; ++i) {
- var range = consolidatedRanges[i];
- out.push(encodeEscape(range[0]));
- if (range[1] > range[0]) {
- if (range[1] + 1 > range[0]) { out.push('-'); }
- out.push(encodeEscape(range[1]));
- }
- }
- out.push(']');
- return out.join('');
- }
-
- function allowAnywhereFoldCaseAndRenumberGroups(regex) {
- // Split into character sets, escape sequences, punctuation strings
- // like ('(', '(?:', ')', '^'), and runs of characters that do not
- // include any of the above.
- var parts = regex.source.match(
- new RegExp(
- '(?:'
- + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]' // a character set
- + '|\\\\u[A-Fa-f0-9]{4}' // a unicode escape
- + '|\\\\x[A-Fa-f0-9]{2}' // a hex escape
- + '|\\\\[0-9]+' // a back-reference or octal escape
- + '|\\\\[^ux0-9]' // other escape sequence
- + '|\\(\\?[:!=]' // start of a non-capturing group
- + '|[\\(\\)\\^]' // start/emd of a group, or line start
- + '|[^\\x5B\\x5C\\(\\)\\^]+' // run of other characters
- + ')',
- 'g'));
- var n = parts.length;
-
- // Maps captured group numbers to the number they will occupy in
- // the output or to -1 if that has not been determined, or to
- // undefined if they need not be capturing in the output.
- var capturedGroups = [];
-
- // Walk over and identify back references to build the capturedGroups
- // mapping.
- for (var i = 0, groupIndex = 0; i < n; ++i) {
- var p = parts[i];
- if (p === '(') {
- // groups are 1-indexed, so max group index is count of '('
- ++groupIndex;
- } else if ('\\' === p.charAt(0)) {
- var decimalValue = +p.substring(1);
- if (decimalValue && decimalValue <= groupIndex) {
- capturedGroups[decimalValue] = -1;
- }
- }
- }
-
- // Renumber groups and reduce capturing groups to non-capturing groups
- // where possible.
- for (var i = 1; i < capturedGroups.length; ++i) {
- if (-1 === capturedGroups[i]) {
- capturedGroups[i] = ++capturedGroupIndex;
- }
- }
- for (var i = 0, groupIndex = 0; i < n; ++i) {
- var p = parts[i];
- if (p === '(') {
- ++groupIndex;
- if (capturedGroups[groupIndex] === undefined) {
- parts[i] = '(?:';
- }
- } else if ('\\' === p.charAt(0)) {
- var decimalValue = +p.substring(1);
- if (decimalValue && decimalValue <= groupIndex) {
- parts[i] = '\\' + capturedGroups[groupIndex];
- }
- }
- }
-
- // Remove any prefix anchors so that the output will match anywhere.
- // ^^ really does mean an anchored match though.
- for (var i = 0, groupIndex = 0; i < n; ++i) {
- if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
- }
-
- // Expand letters to groupts to handle mixing of case-sensitive and
- // case-insensitive patterns if necessary.
- if (regex.ignoreCase && needToFoldCase) {
- for (var i = 0; i < n; ++i) {
- var p = parts[i];
- var ch0 = p.charAt(0);
- if (p.length >= 2 && ch0 === '[') {
- parts[i] = caseFoldCharset(p);
- } else if (ch0 !== '\\') {
- // TODO: handle letters in numeric escapes.
- parts[i] = p.replace(
- /[a-zA-Z]/g,
- function (ch) {
- var cc = ch.charCodeAt(0);
- return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
- });
- }
- }
- }
-
- return parts.join('');
- }
-
- var rewritten = [];
- for (var i = 0, n = regexs.length; i < n; ++i) {
- var regex = regexs[i];
- if (regex.global || regex.multiline) { throw new Error('' + regex); }
- rewritten.push(
- '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
- }
-
- return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
- }
-
- var PR_innerHtmlWorks = null;
- function getInnerHtml(node) {
- // inner html is hopelessly broken in Safari 2.0.4 when the content is
- // an html description of well formed XML and the containing tag is a PRE
- // tag, so we detect that case and emulate innerHTML.
- if (null === PR_innerHtmlWorks) {
- var testNode = document.createElement('PRE');
- testNode.appendChild(
- document.createTextNode('\n '));
- PR_innerHtmlWorks = !/)[\r\n]+/g, '$1')
- .replace(/(?:[\r\n]+[ \t]*)+/g, ' ');
- }
- return content;
- }
-
- var out = [];
- for (var child = node.firstChild; child; child = child.nextSibling) {
- normalizedHtml(child, out);
- }
- return out.join('');
- }
-
- /** returns a function that expand tabs to spaces. This function can be fed
- * successive chunks of text, and will maintain its own internal state to
- * keep track of how tabs are expanded.
- * @return {function (string) : string} a function that takes
- * plain text and return the text with tabs expanded.
- * @private
- */
- function makeTabExpander(tabWidth) {
- var SPACES = ' ';
- var charInLine = 0;
-
- return function (plainText) {
- // walk over each character looking for tabs and newlines.
- // On tabs, expand them. On newlines, reset charInLine.
- // Otherwise increment charInLine
- var out = null;
- var pos = 0;
- for (var i = 0, n = plainText.length; i < n; ++i) {
- var ch = plainText.charAt(i);
-
- switch (ch) {
- case '\t':
- if (!out) { out = []; }
- out.push(plainText.substring(pos, i));
- // calculate how much space we need in front of this part
- // nSpaces is the amount of padding -- the number of spaces needed
- // to move us to the next column, where columns occur at factors of
- // tabWidth.
- var nSpaces = tabWidth - (charInLine % tabWidth);
- charInLine += nSpaces;
- for (; nSpaces >= 0; nSpaces -= SPACES.length) {
- out.push(SPACES.substring(0, nSpaces));
- }
- pos = i + 1;
- break;
- case '\n':
- charInLine = 0;
- break;
- default:
- ++charInLine;
- }
- }
- if (!out) { return plainText; }
- out.push(plainText.substring(pos));
- return out.join('');
- };
- }
-
- var pr_chunkPattern = new RegExp(
- '[^<]+' // A run of characters other than '<'
- + '|<\!--[\\s\\S]*?--\>' // an HTML comment
- + '|' // a CDATA section
- // a probable tag that should not be highlighted
- + '|<\/?[a-zA-Z](?:[^>\"\']|\'[^\']*\'|\"[^\"]*\")*>'
- + '|<', // A '<' that does not begin a larger chunk
- 'g');
- var pr_commentPrefix = /^<\!--/;
- var pr_cdataPrefix = /^) into their textual equivalent.
- *
- * @param {string} s html where whitespace is considered significant.
- * @return {Object} source code and extracted tags.
- * @private
- */
- function extractTags(s) {
- // since the pattern has the 'g' modifier and defines no capturing groups,
- // this will return a list of all chunks which we then classify and wrap as
- // PR_Tokens
- var matches = s.match(pr_chunkPattern);
- var sourceBuf = [];
- var sourceBufLen = 0;
- var extractedTags = [];
- if (matches) {
- for (var i = 0, n = matches.length; i < n; ++i) {
- var match = matches[i];
- if (match.length > 1 && match.charAt(0) === '<') {
- if (pr_commentPrefix.test(match)) { continue; }
- if (pr_cdataPrefix.test(match)) {
- // strip CDATA prefix and suffix. Don't unescape since it's CDATA
- sourceBuf.push(match.substring(9, match.length - 3));
- sourceBufLen += match.length - 12;
- } else if (pr_brPrefix.test(match)) {
- // tags are lexically significant so convert them to text.
- // This is undone later.
- sourceBuf.push('\n');
- ++sourceBufLen;
- } else {
- if (match.indexOf(PR_NOCODE) >= 0 && isNoCodeTag(match)) {
- // A will start a section that should be
- // ignored. Continue walking the list until we see a matching end
- // tag.
- var name = match.match(pr_tagNameRe)[2];
- var depth = 1;
- var j;
- end_tag_loop:
- for (j = i + 1; j < n; ++j) {
- var name2 = matches[j].match(pr_tagNameRe);
- if (name2 && name2[2] === name) {
- if (name2[1] === '/') {
- if (--depth === 0) { break end_tag_loop; }
- } else {
- ++depth;
- }
- }
- }
- if (j < n) {
- extractedTags.push(
- sourceBufLen, matches.slice(i, j + 1).join(''));
- i = j;
- } else { // Ignore unclosed sections.
- extractedTags.push(sourceBufLen, match);
- }
- } else {
- extractedTags.push(sourceBufLen, match);
- }
- }
- } else {
- var literalText = htmlToText(match);
- sourceBuf.push(literalText);
- sourceBufLen += literalText.length;
- }
- }
- }
- return { source: sourceBuf.join(''), tags: extractedTags };
- }
-
- /** True if the given tag contains a class attribute with the nocode class. */
- function isNoCodeTag(tag) {
- return !!tag
- // First canonicalize the representation of attributes
- .replace(/\s(\w+)\s*=\s*(?:\"([^\"]*)\"|'([^\']*)'|(\S+))/g,
- ' $1="$2$3$4"')
- // Then look for the attribute we want.
- .match(/[cC][lL][aA][sS][sS]=\"[^\"]*\bnocode\b/);
- }
-
- /**
- * Apply the given language handler to sourceCode and add the resulting
- * decorations to out.
- * @param {number} basePos the index of sourceCode within the chunk of source
- * whose decorations are already present on out.
- */
- function appendDecorations(basePos, sourceCode, langHandler, out) {
- if (!sourceCode) { return; }
- var job = {
- source: sourceCode,
- basePos: basePos
- };
- langHandler(job);
- out.push.apply(out, job.decorations);
- }
-
- /** Given triples of [style, pattern, context] returns a lexing function,
- * The lexing function interprets the patterns to find token boundaries and
- * returns a decoration list of the form
- * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
- * where index_n is an index into the sourceCode, and style_n is a style
- * constant like PR_PLAIN. index_n-1 <= index_n, and style_n-1 applies to
- * all characters in sourceCode[index_n-1:index_n].
- *
- * The stylePatterns is a list whose elements have the form
- * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
- *
- * Style is a style constant like PR_PLAIN, or can be a string of the
- * form 'lang-FOO', where FOO is a language extension describing the
- * language of the portion of the token in $1 after pattern executes.
- * E.g., if style is 'lang-lisp', and group 1 contains the text
- * '(hello (world))', then that portion of the token will be passed to the
- * registered lisp handler for formatting.
- * The text before and after group 1 will be restyled using this decorator
- * so decorators should take care that this doesn't result in infinite
- * recursion. For example, the HTML lexer rule for SCRIPT elements looks
- * something like ['lang-js', /<[s]cript>(.+?)<\/script>/]. This may match
- * 'HumanResourceDept