├── .nvmrc
├── .vscode
└── settings.json
├── .npmrc
├── .gitignore
├── jsdoc-template
├── tmpl
│ ├── example.tmpl
│ ├── source.tmpl
│ ├── mainpage.tmpl
│ ├── type.tmpl
│ ├── augments.tmpl
│ ├── examples.tmpl
│ ├── returns.tmpl
│ ├── tutorial.tmpl
│ ├── exceptions.tmpl
│ ├── members.tmpl
│ ├── layout.tmpl
│ ├── method.tmpl
│ ├── properties.tmpl
│ ├── params.tmpl
│ ├── details.tmpl
│ └── container.tmpl
├── static
│ ├── styles
│ │ ├── arrow-down.svg
│ │ ├── hljs.css
│ │ └── jsdoc.css
│ └── scripts
│ │ └── hljs
│ │ └── highlight.min.js
└── publish.js
├── .github
├── CODEOWNERS
├── workflows
│ ├── dependabot-approve-and-request-merge.yml
│ ├── main.yaml
│ ├── codeql.yml
│ └── release.yaml
├── ISSUE_TEMPLATE
│ ├── config.yml
│ ├── bug_report.md
│ └── feature_request.md
├── dependabot.yml
└── PULL_REQUEST_TEMPLATE.md
├── README.md
├── .contentful
└── vault-secrets.yaml
├── catalog-info.yaml
├── LICENSE
├── bin
└── publish-docs.sh
└── package.json
/.nvmrc:
--------------------------------------------------------------------------------
1 | v18
2 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | ignore-scripts=true
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | *.log
3 | .lock-wscript
4 | out
5 | *.swp
6 | *.swp
7 | *.swo
8 | .idea
9 |
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/example.tmpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | * @contentful/team-developer-experience
2 |
3 | package.json
4 | package-lock.json
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # contentful-sdk-jsdoc
2 |
3 |
4 | Contentful [JSDoc](http://usejsdoc.org/) template for [contentful.js](https://contentful.github.io/contentful.js) and [contentful-management.js](contentful.github.io/contentful-management.js).
5 |
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/source.tmpl:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/mainpage.tmpl:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/.contentful/vault-secrets.yaml:
--------------------------------------------------------------------------------
1 | version: 1
2 | services:
3 | github-action:
4 | policies:
5 | - dependabot
6 | - semantic-release
7 | - packages-read
8 | circleci:
9 | policies:
10 | - semantic-release-ecosystem
11 |
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/type.tmpl:
--------------------------------------------------------------------------------
1 |
5 |
6 | |
7 |
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/augments.tmpl:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
10 |
11 |
--------------------------------------------------------------------------------
/jsdoc-template/static/styles/arrow-down.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/examples.tmpl:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/returns.tmpl:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | Type
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/jsdoc-template/static/styles/hljs.css:
--------------------------------------------------------------------------------
1 | // Syntax highlighting
2 | .hljs-attr {
3 | color: #8091a5;
4 | }
5 |
6 | .hljs-string {
7 | color: #16c98d;
8 | }
9 |
10 | .hljs-literal {
11 | color: #e0534e;
12 | }
13 |
14 | .hljs-number {
15 | color: #5b9fef;
16 | }
17 |
18 | .hljs-comment {
19 | color: #a9b9c0;
20 | }
21 |
22 | .hljs-keyword,
23 | .hljs-built_in {
24 | color: #4a90e2;
25 | font-weight: bold;
26 | }
27 |
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/tutorial.tmpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 0) { ?>
5 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/.github/workflows/dependabot-approve-and-request-merge.yml:
--------------------------------------------------------------------------------
1 | name: "dependabot approve-and-request-merge"
2 |
3 | on: pull_request_target
4 |
5 | jobs:
6 | worker:
7 | permissions:
8 | contents: write
9 | id-token: write
10 | runs-on: ubuntu-latest
11 | if: github.actor == 'dependabot[bot]'
12 | steps:
13 | - uses: contentful/github-auto-merge@v1
14 | with:
15 | VAULT_URL: ${{ secrets.VAULT_URL }}
16 |
--------------------------------------------------------------------------------
/.github/workflows/main.yaml:
--------------------------------------------------------------------------------
1 | name: CI
2 | permissions:
3 | contents: read
4 |
5 | on:
6 | push:
7 | branches: ['**']
8 |
9 | jobs:
10 |
11 | release:
12 | if: github.event_name == 'push' && contains(fromJSON('["refs/heads/master", "refs/heads/dev"]'), github.ref)
13 | permissions:
14 | contents: write
15 | id-token: write
16 | actions: read
17 | uses: ./.github/workflows/release.yaml
18 | secrets:
19 | VAULT_URL: ${{ secrets.VAULT_URL }}
20 |
--------------------------------------------------------------------------------
/catalog-info.yaml:
--------------------------------------------------------------------------------
1 | apiVersion: backstage.io/v1alpha1
2 | kind: Component
3 | metadata:
4 | name: contentful-sdk-jsdoc
5 | description: Contentful JSDoc template for contentful.js and contentful-management.js
6 | annotations:
7 | github.com/project-slug: contentful/contentful-sdk-jsdoc
8 | contentful.com/ci-alert-slack: prd-ecosystem-dx-bots
9 | contentful.com/service-tier: "4"
10 | tags:
11 | - tier-4
12 | spec:
13 | type: library
14 | lifecycle: production
15 | owner: group:team-developer-experience
16 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/config.yml:
--------------------------------------------------------------------------------
1 | blank_issues_enabled: true
2 | contact_links:
3 | - name: Question or Discussion
4 | url: https://github.com/contentful/contentful-sdk-jsdoc/discussions
5 | about: Ask questions or discuss ideas with the community
6 | - name: Documentation
7 | url: https://contentful.com/docs
8 | about: Check out our documentation for help and guides
9 | - name: Security Vulnerability
10 | url: https://github.com/contentful/contentful-sdk-jsdoc/security/advisories/new
11 | about: Report a security vulnerability privately
12 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | # Enable version updates for npm
4 | - package-ecosystem: 'npm'
5 | directory: '/'
6 | schedule:
7 | interval: 'weekly'
8 | day: 'monday'
9 | open-pull-requests-limit: 10
10 | reviewers:
11 | - 'contentful/team-developer-experience'
12 | labels:
13 | - 'dependencies'
14 | commit-message:
15 | prefix: 'chore'
16 | include: 'scope'
17 | ignore:
18 | - dependency-name: husky
19 | versions:
20 | - ">=5.0.0"
21 |
22 | cooldown:
23 | default-days: 15
--------------------------------------------------------------------------------
/.github/workflows/codeql.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: "CodeQL Scan for GitHub Actions Workflows"
3 |
4 | on:
5 | push:
6 | branches: [master]
7 | paths: [".github/workflows/**"]
8 | pull_request:
9 | branches: [master]
10 | paths: [".github/workflows/**"]
11 |
12 | jobs:
13 | analyze:
14 | name: Analyze GitHub Actions workflows
15 | runs-on: ubuntu-latest
16 | permissions:
17 | actions: read
18 | contents: read
19 | security-events: write
20 |
21 | steps:
22 | - uses: actions/checkout@v5
23 |
24 | - name: Initialize CodeQL
25 | uses: github/codeql-action/init@v4
26 | with:
27 | languages: actions
28 |
29 | - name: Run CodeQL Analysis
30 | uses: github/codeql-action/analyze@v4
31 | with:
32 | category: actions
33 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
7 |
8 | ## Summary
9 |
10 |
11 |
12 | ## Description
13 |
14 |
15 |
16 | ## Motivation and Context
17 |
18 |
22 |
23 | ## PR Checklist
24 |
25 | - [ ] I have read the `CONTRIBUTING.md` file
26 | - [ ] All commits follow [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/)
27 | - [ ] Documentation is updated (if necessary)
28 | - [ ] PR doesn't contain any sensitive information
29 | - [ ] There are no breaking changes
30 |
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/exceptions.tmpl:
--------------------------------------------------------------------------------
1 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | Type
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/members.tmpl:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 | Type:
21 |
26 |
27 |
28 |
29 | Fires:
30 |
33 |
34 |
35 |
36 | Example 1? 's':'' ?>
37 |
38 |
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Contentful
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug Report
3 | about: Create a report to help us improve
4 | title: '[BUG] '
5 | labels: bug
6 | assignees: ''
7 | ---
8 |
9 | ## Bug Description
10 |
11 | A clear and concise description of what the bug is.
12 |
13 | ## Steps to Reproduce
14 |
15 | 1. Go to '...'
16 | 2. Execute '...'
17 | 3. See error
18 |
19 | ## Expected Behavior
20 |
21 | A clear and concise description of what you expected to happen.
22 |
23 | ## Actual Behavior
24 |
25 | A clear and concise description of what actually happened.
26 |
27 | ## Code Sample
28 |
29 | ```javascript
30 | // Minimal code to reproduce the issue
31 | ```
32 |
33 | ## Environment
34 |
35 | - OS: [e.g. macOS 13.0, Windows 11, Ubuntu 22.04]
36 | - Package Version: [e.g. 1.2.3]
37 | - Node Version: [e.g. 18.0.0]
38 | - Package Manager: [e.g. npm 9.0.0, yarn 1.22.0]
39 |
40 | ## Error Messages/Logs
41 |
42 | ```
43 | Paste any error messages or relevant logs here
44 | ```
45 |
46 | ## Screenshots
47 |
48 | If applicable, add screenshots to help explain your problem.
49 |
50 | ## Additional Context
51 |
52 | Add any other context about the problem here.
53 |
54 | ## Possible Solution
55 |
56 | If you have suggestions on how to fix the bug, please describe them here.
57 |
--------------------------------------------------------------------------------
/bin/publish-docs.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -e
3 |
4 | REPO_NAME=$1
5 | NAMESPACE=$2
6 | PAGES_DIR=./gh-pages
7 | DOCS_DIR=./out
8 | if [[ -n "${GITHUB_TOKEN}" ]]; then # If the GITHUB_TOKEN (which is an app token) is not empty we use an app token auth URL
9 | REPO="https://x-access-token:${GITHUB_TOKEN}@github.com/contentful/${REPO_NAME}.git"
10 | else # Legacy variant
11 | REPO="https://${GH_TOKEN}@github.com/contentful/${REPO_NAME}.git"
12 | fi
13 |
14 |
15 | VERSION=$(cat package.json | jq -r .version)
16 |
17 | echo "Publishing docs"
18 |
19 | if ! [ -d $DOCS_DIR ] ; then
20 | echo "Docs can't be found. Maybe you haven't generated them?"
21 | exit 1
22 | fi
23 |
24 | # get the gh-pages branch of the repo
25 | if [ ! -d $PAGES_DIR ] ; then
26 | git clone --single-branch --branch gh-pages $REPO $PAGES_DIR
27 | fi
28 |
29 | if ! [ -d $PAGES_DIR/$NAMESPACE/$VERSION ] ; then
30 | mkdir $PAGES_DIR/$NAMESPACE/$VERSION
31 | fi
32 | cp -r $DOCS_DIR/* $PAGES_DIR/$NAMESPACE/$VERSION
33 |
34 | rm -rf $PAGES_DIR/$NAMESPACE/latest
35 |
36 | cp -r $PAGES_DIR/$NAMESPACE/$VERSION $PAGES_DIR/$NAMESPACE/latest
37 |
38 | echo " " > $PAGES_DIR/index.html
39 |
40 | pushd $PAGES_DIR
41 | git add .
42 | git commit -a -m "Docs update for $VERSION [skip ci]"
43 | if [ $? -eq 1 ] ; then
44 | echo "Nothing to update"
45 | else
46 | git push origin gh-pages
47 | fi
48 | popd
49 |
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/layout.tmpl:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | - Documentation
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "contentful-sdk-jsdoc",
3 | "version": "2.2.0",
4 | "description": "JSDoc template and config for the Contentful JS SDKs",
5 | "homepage": "https://www.contentful.com/developers/docs/javascript/",
6 | "main": "index.js",
7 | "repository": {
8 | "type": "git",
9 | "url": "https://github.com/contentful/contentful-sdk-jsdoc.git"
10 | },
11 | "author": "Contentful ",
12 | "license": "MIT",
13 | "scripts": {
14 | "test": "true",
15 | "semantic-release": "semantic-release"
16 | },
17 | "files": [
18 | "jsdoc*",
19 | "bin"
20 | ],
21 | "devDependencies": {
22 | "@semantic-release/changelog": "^6.0.0",
23 | "cz-conventional-changelog": "^3.3.0",
24 | "jsdoc": "^4.0.0",
25 | "json": "^11.0.0",
26 | "semantic-release": "^25.0.2"
27 | },
28 | "config": {
29 | "commitizen": {
30 | "path": "./node_modules/cz-conventional-changelog"
31 | }
32 | },
33 | "release": {
34 | "branches": [
35 | "master",
36 | {
37 | "name": "dev",
38 | "channel": "dev",
39 | "prerelease": true
40 | }
41 | ],
42 | "plugins": [
43 | [
44 | "@semantic-release/commit-analyzer",
45 | {
46 | "releaseRules": [
47 | {
48 | "type": "build",
49 | "scope": "deps",
50 | "release": "patch"
51 | }
52 | ]
53 | }
54 | ],
55 | "@semantic-release/release-notes-generator",
56 | "@semantic-release/npm",
57 | "@semantic-release/changelog",
58 | "@semantic-release/github"
59 | ]
60 | },
61 | "dependencies": {
62 | "@jsdoc/salty": "^0.2.8"
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature Request
3 | about: Suggest an idea for this project
4 | title: '[FEATURE] '
5 | labels: enhancement
6 | assignees: ''
7 | ---
8 |
9 | ## Feature Description
10 |
11 | A clear and concise description of the feature you'd like to see.
12 |
13 | ## Problem Statement
14 |
15 | Is your feature request related to a problem? Please describe.
16 | Example: I'm always frustrated when [...]
17 |
18 | ## Proposed Solution
19 |
20 | A clear and concise description of what you want to happen.
21 |
22 | ## Use Case
23 |
24 | Describe the use case for this feature. How would you use it?
25 |
26 | ```javascript
27 | // Example of how the feature would be used
28 | const example = new Feature({
29 | option: 'value',
30 | });
31 | ```
32 |
33 | ## Alternatives Considered
34 |
35 | A clear and concise description of any alternative solutions or features you've considered.
36 |
37 | ## Benefits
38 |
39 | What are the benefits of implementing this feature?
40 |
41 | - Benefit 1
42 | - Benefit 2
43 | - Benefit 3
44 |
45 | ## Potential Drawbacks
46 |
47 | Are there any potential drawbacks or challenges with this feature?
48 |
49 | ## Additional Context
50 |
51 | Add any other context, screenshots, or examples about the feature request here.
52 |
53 | ## Implementation Suggestions
54 |
55 | If you have ideas about how this could be implemented, please share them here.
56 |
57 | ## Priority
58 |
59 | How important is this feature to you?
60 |
61 | - [ ] Critical - Blocking my usage
62 | - [ ] High - Important for my use case
63 | - [ ] Medium - Would be nice to have
64 | - [ ] Low - Just a suggestion
65 |
66 | ## Willingness to Contribute
67 |
68 | - [ ] I'd be willing to submit a PR for this feature
69 | - [ ] I can help test this feature
70 | - [ ] I can help with documentation
71 |
--------------------------------------------------------------------------------
/.github/workflows/release.yaml:
--------------------------------------------------------------------------------
1 | name: Release
2 |
3 | on:
4 | workflow_call:
5 | secrets:
6 | VAULT_URL:
7 | required: true
8 |
9 | jobs:
10 | release:
11 | runs-on: ubuntu-latest
12 |
13 | permissions:
14 | contents: write
15 | id-token: write
16 | actions: read
17 |
18 | steps:
19 | - name: 'Retrieve Secrets from Vault'
20 | id: vault
21 | uses: hashicorp/vault-action@v3.4.0
22 | with:
23 | url: ${{ secrets.VAULT_URL }}
24 | role: ${{ github.event.repository.name }}-github-action
25 | method: jwt
26 | path: github-actions
27 | exportEnv: false
28 | secrets: |
29 | github/token/${{ github.event.repository.name }}-semantic-release token | GITHUB_TOKEN;
30 |
31 | - name: Get Automation Bot User ID
32 | id: get-user-id
33 | run: echo "user-id=$(gh api "/users/contentful-automation[bot]" --jq .id)" >> "$GITHUB_OUTPUT"
34 | env:
35 | GITHUB_TOKEN: ${{ steps.vault.outputs.GITHUB_TOKEN }}
36 |
37 | - name: Setting up Git User Credentials
38 | run: |
39 | git config --global user.name 'contentful-automation[bot]'
40 | git config --global user.email '${{ steps.get-user-id.outputs.user-id }}+contentful-automation[bot]@users.noreply.github.com'
41 |
42 | - name: Checkout code
43 | uses: actions/checkout@v5
44 | with:
45 | fetch-depth: 0
46 |
47 | - name: Setup Node.js
48 | uses: actions/setup-node@v6
49 | with:
50 | node-version: '22'
51 | cache: 'npm'
52 |
53 | - name: Install latest npm
54 | run: npm install -g npm@latest
55 |
56 | - name: Install dependencies
57 | run: npm ci
58 |
59 | - name: Restore the build folders
60 | uses: actions/cache/restore@v4
61 | with:
62 | path: |
63 | dist
64 | key: build-cache-${{ github.run_id }}-${{ github.run_attempt }}
65 |
66 | - name: Run Release
67 | run: |
68 | echo "Starting Semantic Release Process"
69 | echo "npm version: $(npm -v)"
70 | npm run semantic-release
71 | env:
72 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
73 |
74 | - name: Get latest release tag
75 | id: get-tag
76 | run: |
77 | TAG=$(gh api repos/${{ github.repository }}/releases/latest --jq .tag_name)
78 | echo "tag=$TAG" >> $GITHUB_OUTPUT
79 | env:
80 | GITHUB_TOKEN: ${{ steps.vault.outputs.GITHUB_TOKEN }}
81 |
82 | - name: Summary
83 | run: |
84 | VERSION=$(echo "${{ steps.get-tag.outputs.tag }}" | sed 's/^v//')
85 | echo "## Release Summary" >> $GITHUB_STEP_SUMMARY
86 | echo "" >> $GITHUB_STEP_SUMMARY
87 | echo "- **Version**: ${{ steps.get-tag.outputs.tag }}" >> $GITHUB_STEP_SUMMARY
88 | echo "- **GitHub Release**: https://github.com/${{ github.repository }}/releases/tag/${{ steps.get-tag.outputs.tag }}" >> $GITHUB_STEP_SUMMARY
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/method.tmpl:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 | Constructor
8 |
9 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | Extends:
28 |
29 |
30 |
31 |
32 | Type:
33 |
38 |
39 |
40 |
41 | This:
42 |
43 |
44 |
45 |
46 | Example 1? 's':'' ?>
47 |
48 |
49 |
50 |
51 | Parameters:
52 |
53 |
54 |
55 |
56 | Requires:
57 |
60 |
61 |
62 |
63 | Fires:
64 |
67 |
68 |
69 |
70 | Listens to Events:
71 |
74 |
75 |
76 |
77 | Listeners of This Event:
78 |
81 |
82 |
83 |
84 | Throws:
85 | 1) { ?>
91 |
92 |
94 |
95 |
96 | Returns:
97 | 1) { ?>
103 |
104 |
106 |
107 |
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/properties.tmpl:
--------------------------------------------------------------------------------
1 |
41 |
42 |
43 |
44 |
45 |
46 | Name
47 |
48 |
49 | Type
50 |
51 |
52 | Attributes
53 |
54 |
55 |
56 | Default
57 |
58 |
59 | Description
60 |
61 |
62 |
63 |
64 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 | <optional>
85 |
86 |
87 |
88 | <nullable>
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 | Properties
103 |
104 |
105 |
106 |
107 |
108 |
109 |
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/params.tmpl:
--------------------------------------------------------------------------------
1 |
52 |
53 |
54 |
55 |
56 |
57 | Name
58 |
59 |
60 | Type
61 |
62 |
63 | Attributes
64 |
65 |
66 |
67 | Default
68 |
69 |
70 | Description
71 |
72 |
73 |
74 |
75 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 | <optional>
96 |
97 |
98 |
99 | <nullable>
100 |
101 |
102 |
103 | <repeatable>
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | Properties
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/details.tmpl:
--------------------------------------------------------------------------------
1 | " + data.defaultvalue + "";
13 | defaultObjectClass = ' class="object-value"';
14 | }
15 | ?>
16 |
17 |
18 |
19 |
20 | Source:
21 |
24 |
25 |
26 |
27 | Version:
28 |
29 |
30 |
31 |
32 | Since:
33 |
34 |
35 |
36 |
37 | Inherited From:
38 |
41 |
42 |
43 |
44 | Overrides:
45 |
48 |
49 |
50 |
51 | Implementations:
52 |
57 |
58 |
59 |
60 | Implements:
61 |
66 |
67 |
68 |
69 | Mixes In:
70 |
71 |
76 |
77 |
78 |
79 | Deprecated:
83 |
84 |
85 |
86 | Author:
87 |
88 |
91 |
92 |
93 |
94 |
95 | Copyright:
96 |
97 |
98 |
99 |
100 | License:
101 |
102 |
103 |
104 |
105 | Default Value:
106 |
109 |
110 |
111 |
112 | Tutorials:
113 |
114 |
117 |
118 |
119 |
120 |
121 | See:
122 |
123 |
126 |
127 |
128 |
129 |
130 | To Do:
131 |
132 |
135 |
136 |
137 |
138 |
139 |
143 |
144 | Properties:
145 |
146 |
147 |
148 |
149 |
--------------------------------------------------------------------------------
/jsdoc-template/tmpl/container.tmpl:
--------------------------------------------------------------------------------
1 |
7 |
8 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
Example 1? 's':'' ?>
64 |
65 |
66 |
67 |
68 |
69 |
70 | Extends
71 |
72 |
73 |
74 |
75 |
76 | Requires
77 |
78 |
81 |
82 |
83 |
87 | Classes
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
99 | Mixins
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
111 | Namespaces
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
130 | Members
131 |
132 |
133 |
134 |
135 |
136 |
140 | Type Definitions
141 |
142 |
145 |
146 |
150 |
151 |
154 |
155 |
156 |
160 | Methods
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
172 | Events
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
--------------------------------------------------------------------------------
/jsdoc-template/static/scripts/hljs/highlight.min.js:
--------------------------------------------------------------------------------
1 | /*! highlight.js v9.10.0 | BSD3 License | git.io/hljslicense */
2 | !function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/[&<>]/gm,function(e){return j[e]})}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset"}function u(e){l+=""+t(e)+">"}function c(e){("start"===e.event?o:u)(e.node)}for(var s=0,l="",f=[];e.length||r.length;){var g=i();if(l+=n(a.substring(s,g[0].offset)),s=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===s);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return l+n(a.substr(s))}function s(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function l(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return s("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var c=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=c.length?t(c.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function s(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?"":I.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=s(E,r),e?(B+=e[1],a+=p(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!L[E.sL])return n(k);var t=e?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(B+=t.r),e&&(x[E.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){y+=null!=E.sL?d():h(),k=""}function v(e){y+=e.cN?p(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(k+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),b(),t.rB||t.eB||(k=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),b(),a.eE&&(k=n));do E.cN&&(y+=C),E.skip||(B+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||"")+'"');return k+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');l(N);var R,E=i||N,x={},y="";for(R=E;R!==N;R=R.parent)R.cN&&(y=p(R.cN,"",!0)+y);var k="",B=0;try{for(var M,j,O=0;;){if(E.t.lastIndex=O,M=E.t.exec(t),!M)break;j=m(t.substring(O,M.index),M[0]),O=M.index+j}for(m(t.substr(O)),R=E;R.parent;R=R.parent)R.cN&&(y+=C);return{r:B,value:y,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function g(e,t){t=t||I.languages||x(L);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR&&"\n"===e?" ":I.tabReplace?n.replace(/\t/g,I.tabReplace):""}):e}function h(e,n,t){var r=n?y[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n,t,r,o,s,l=i(e);a(l)||(I.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/ /g,"\n")):n=e,s=n.textContent,r=l?f(l,s,!0):g(s),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),s)),r.value=p(r.value),e.innerHTML=r.value,e.className=h(e.className,l,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){I=o(I,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,d)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=L[n]=t(e);r.aliases&&r.aliases.forEach(function(e){y[e]=n})}function R(){return x(L)}function w(e){return e=(e||"").toLowerCase(),L[e]||L[y[e]]}var E=[],x=Object.keys,L={},y={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C=" ",I={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0},j={"&":"&","<":"<",">":">"};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=d,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|like)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b:/,e:/(\/\w+|\w+\/)>/,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/,r:0,c:[{cN:"attr",b:e,r:0},{b:/=\s*/,r:0,c:[{cN:"string",endsParent:!0,v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s"'=<>`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"?",e:"/?>",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});
--------------------------------------------------------------------------------
/jsdoc-template/static/styles/jsdoc.css:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Montserrat:400,700);
2 |
3 | * {
4 | box-sizing: border-box
5 | }
6 |
7 | html, body {
8 | height: 100%;
9 | width: 100%;
10 | }
11 |
12 | body {
13 | color: #4d4e53;
14 | background-color: #fff;
15 | margin: 0 auto;
16 | padding: 0 20px;
17 | font-family: 'Helvetica Neue', Helvetica, sans-serif;
18 | font-size: 16px;
19 | line-height: 160%;
20 | }
21 |
22 | img {
23 | max-width: 100%;
24 | }
25 |
26 | a,
27 | a:active {
28 | color: #1683d0;
29 | text-decoration: none;
30 | }
31 |
32 | a:hover {
33 | text-decoration: none;
34 | }
35 |
36 | article a {
37 | border-bottom: 1px solid #ddd;
38 | }
39 |
40 | article a:hover, article a:active {
41 | border-bottom-color: #222;
42 | }
43 |
44 | p, ul, ol, blockquote {
45 | margin-bottom: 1em;
46 | }
47 |
48 | h1, h2, h3, h4, h5, h6 {
49 | font-family: 'Montserrat', sans-serif;
50 | }
51 |
52 | h1, h2, h3, h4, h5, h6 {
53 | color: #000;
54 | font-weight: 400;
55 | margin: 0;
56 | }
57 |
58 | h1 {
59 | font-weight: 300;
60 | font-size: 48px;
61 | margin: 1em 0 .5em;
62 | }
63 |
64 | h1.page-title {
65 | font-size: 48px;
66 | margin: 1em 30px;
67 | }
68 |
69 | h2 {
70 | font-size: 24px;
71 | margin: 1.5em 0 .3em;
72 | }
73 |
74 | h3 {
75 | font-size: 24px;
76 | margin: 1.2em 0 .3em;
77 | }
78 |
79 | h4 {
80 | font-size: 18px;
81 | margin: 1em 0 .2em;
82 | color: #4d4e53;
83 | }
84 |
85 | h4.name {
86 | color: #000;
87 | background: #f7f9fa;
88 | box-shadow: 0 .25em .5em #d3d3d3;
89 | border-top: 1px solid #d3d3d3;
90 | border-bottom: 1px solid #d3d3d3;
91 | margin: 1.5em 0 0.5em;
92 | padding: .75em 0 .75em 10px;
93 | }
94 |
95 | h4.name a {
96 | color: #1683d0;
97 | }
98 |
99 | h4.name a:hover {
100 | border-bottom-color: #0c2c52;
101 | }
102 |
103 | h5, .container-overview .subsection-title {
104 | font-size: 120%;
105 | letter-spacing: -0.01em;
106 | margin: 8px 0 3px 0;
107 | }
108 |
109 | h6 {
110 | font-size: 100%;
111 | letter-spacing: -0.01em;
112 | margin: 6px 0 3px 0;
113 | font-style: italic;
114 | }
115 |
116 | tt, code, kbd, samp {
117 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
118 | background: #f4f4f4;
119 | padding: 1px 5px;
120 | }
121 |
122 | .class-description {
123 | font-size: 130%;
124 | line-height: 140%;
125 | margin-bottom: 1em;
126 | margin-top: 1em;
127 | }
128 |
129 | .class-description:empty {
130 | margin: 0
131 | }
132 |
133 | #main {
134 | float: right;
135 | min-width: 360px;
136 | width: calc(100% - 240px);
137 | }
138 |
139 | header {
140 | display: block
141 | }
142 |
143 | section {
144 | display: block;
145 | background-color: #fff;
146 | padding: 0 0 0 30px;
147 | }
148 |
149 | .variation {
150 | display: none
151 | }
152 |
153 | .signature-attributes {
154 | font-size: 60%;
155 | color: #bbb;
156 | font-style: italic;
157 | font-weight: lighter;
158 | }
159 |
160 | .cfnext-select-box {
161 | color: inherit;
162 | font-size: inherit;
163 | font-family: inherit;
164 | cursor: inherit;
165 | background: none;
166 | line-height: normal;
167 | border: 0;
168 | outline: 0;
169 | -webkit-appearance: none;
170 | -moz-appearance: none;
171 | appearance: none;
172 | font-size: inherit;
173 | height: 33px;
174 | line-height: normal;
175 | -webkit-box-sizing: border-box;
176 | -moz-box-sizing: border-box;
177 | box-sizing: border-box;
178 | padding-top: 6px;
179 | padding-bottom: 7px;
180 | border: 1px solid #d6dce4;
181 | border-color: #969fa6;
182 | -webkit-border-radius: 2px;
183 | border-radius: 2px;
184 | background-color: #f7f9fa;
185 | padding-left: 1ex;
186 | padding-right: 8ex;
187 | -o-text-overflow: ellipsis;
188 | text-overflow: ellipsis;
189 | overflow: hidden;
190 | white-space: nowrap;
191 | background-image: url(arrow-down.svg), none;
192 | background-position: center right 0.8em;
193 | background-repeat: no-repeat, repeat;
194 | -webkit-background-size: 0.7em, 100%;
195 | -moz-background-size: 0.7em, 100%;
196 | background-size: 0.7em, 100%;
197 | width:100%;
198 | }
199 |
200 | nav {
201 | float: left;
202 | display: block;
203 | width: 250px;
204 | background: #fff;
205 | overflow: auto;
206 | position: fixed;
207 | height: 100%;
208 | padding: 15px;
209 | -webkit-box-shadow: 0px 1px 2px 0px rgba(0,0,0,0.1);
210 | box-shadow: 0px 1px 2px 0px rgba(0,0,0,0.1);
211 | }
212 |
213 | nav h3 {
214 | margin-top: 12px;
215 | font-size: 13px;
216 | text-transform: uppercase;
217 | letter-spacing: 1px;
218 | font-weight: 700;
219 | line-height: 24px;
220 | margin: 15px 0 10px;
221 | padding: 0;
222 | color: #000;
223 | }
224 |
225 | nav ul {
226 | font-family: 'Lucida Grande', 'Lucida Sans Unicode', arial, sans-serif;
227 | font-size: 100%;
228 | line-height: 17px;
229 | padding: 0;
230 | margin: 0;
231 | list-style-type: none;
232 | }
233 |
234 | nav ul a,
235 | nav ul a:active {
236 | font-family: 'Montserrat', sans-serif;
237 | line-height: 18px;
238 | padding: 0;
239 | display: block;
240 | font-size: 12px;
241 | }
242 |
243 | nav a:hover,
244 | nav a:active {
245 | color: #0c2c52;
246 | }
247 |
248 | nav > ul {
249 | padding: 0 10px;
250 | }
251 |
252 | nav > ul > li > a {
253 | color: #8091a5;
254 | }
255 |
256 | nav ul ul {
257 | margin-bottom: 10px
258 | }
259 |
260 | nav ul ul + ul {
261 | margin-top: -10px;
262 | }
263 |
264 | nav ul ul a {
265 | color: hsl(207, 1%, 60%);
266 | border-left: 1px solid hsl(207, 10%, 86%);
267 | }
268 |
269 | nav ul ul a,
270 | nav ul ul a:active {
271 | padding-left: 20px
272 | }
273 |
274 | nav h2 {
275 | font-size: 12px;
276 | margin: 0;
277 | padding: 0;
278 | }
279 |
280 | nav > h2 > a {
281 | display: block;
282 | margin: 10px 0 -10px;
283 | color: #1683d0 !important;
284 | }
285 |
286 | footer {
287 | color: hsl(0, 0%, 28%);
288 | margin-left: 250px;
289 | display: block;
290 | padding: 15px;
291 | font-style: italic;
292 | font-size: 90%;
293 | }
294 |
295 | .ancestors {
296 | color: #999
297 | }
298 |
299 | .ancestors a {
300 | color: #999 !important;
301 | }
302 |
303 | .clear {
304 | clear: both
305 | }
306 |
307 | .important {
308 | font-weight: bold;
309 | color: #950B02;
310 | }
311 |
312 | .yes-def {
313 | text-indent: -1000px
314 | }
315 |
316 | .type-signature {
317 | color: #1683d0;
318 | }
319 |
320 | .type-signature:last-child {
321 | color: #000;
322 | }
323 |
324 | .name, .signature {
325 | font-family: Consolas, Monaco, 'Andale Mono', monospace
326 | }
327 |
328 | .signature {
329 | color: #1683d0;
330 | }
331 |
332 | .details {
333 | margin-top: 6px;
334 | border-left: 2px solid #DDD;
335 | line-height: 20px;
336 | font-size: 14px;
337 | }
338 |
339 | .details dt {
340 | width: 120px;
341 | float: left;
342 | padding-left: 10px;
343 | }
344 |
345 | .details dd {
346 | margin-left: 70px;
347 | margin-top: 6px;
348 | margin-bottom: 6px;
349 | }
350 |
351 | .details ul {
352 | margin: 0
353 | }
354 |
355 | .details ul {
356 | list-style-type: none
357 | }
358 |
359 | .details pre.prettyprint {
360 | margin: 0
361 | }
362 |
363 | .details .object-value {
364 | padding-top: 0
365 | }
366 |
367 | .description {
368 | margin-bottom: 1em;
369 | margin-top: 1em;
370 | }
371 |
372 | .code-caption {
373 | font-style: italic;
374 | font-size: 107%;
375 | margin: 0;
376 | }
377 |
378 | .prettyprint {
379 | font-size: 14px;
380 | overflow: auto;
381 | }
382 |
383 | .prettyprint.source {
384 | width: inherit;
385 | line-height: 18px;
386 | display: block;
387 | background-color: #0d152a;
388 | color: ##536171;
389 | }
390 |
391 | .prettyprint code {
392 | line-height: 18px;
393 | display: block;
394 | background-color: #f7f9fa;
395 | }
396 |
397 | .prettyprint > code {
398 | padding: 15px;
399 | }
400 |
401 | .prettyprint .linenums code {
402 | padding: 0 15px
403 | }
404 |
405 | .prettyprint .linenums li:first-of-type code {
406 | padding-top: 15px
407 | }
408 |
409 | .prettyprint code span.line {
410 | display: inline-block
411 | }
412 |
413 | .prettyprint.linenums {
414 | padding-left: 70px;
415 | -webkit-user-select: none;
416 | -moz-user-select: none;
417 | -ms-user-select: none;
418 | user-select: none;
419 | }
420 |
421 | .prettyprint.linenums ol {
422 | padding-left: 0
423 | }
424 |
425 | .prettyprint.linenums li {
426 | border-left: 3px #34446B solid;
427 | }
428 |
429 | .prettyprint.linenums li.selected, .prettyprint.linenums li.selected * {
430 | background-color: #34446B;
431 | }
432 |
433 | .prettyprint.linenums li * {
434 | -webkit-user-select: text;
435 | -moz-user-select: text;
436 | -ms-user-select: text;
437 | user-select: text;
438 | }
439 |
440 | .params, .props {
441 | border-spacing: 0;
442 | border: 1px solid #ddd;
443 | border-collapse: collapse;
444 | border-radius: 3px;
445 | box-shadow: 0 1px 3px rgba(0,0,0,0.1);
446 | width: 100%;
447 | font-size: 14px;
448 | margin: 1em 0;
449 | }
450 |
451 | .params .type {
452 | white-space: nowrap;
453 | }
454 |
455 | .params code {
456 | white-space: pre;
457 | }
458 |
459 | .params td, .params .name, .props .name, .name code {
460 | color: #4D4E53;
461 | font-family: Consolas, Monaco, 'Andale Mono', monospace;
462 | font-size: 100%;
463 | }
464 |
465 | .params td, .params th, .props td, .props th {
466 | margin: 0px;
467 | text-align: left;
468 | vertical-align: top;
469 | padding: 10px;
470 | display: table-cell;
471 | }
472 |
473 | .params td {
474 | border-top: 1px solid #eee
475 | }
476 |
477 | .params thead tr, .props thead tr {
478 | background-color: #fff;
479 | font-weight: bold;
480 | }
481 |
482 | .params .params thead tr, .props .props thead tr {
483 | background-color: #fff;
484 | font-weight: bold;
485 | }
486 |
487 | .params td.description > p:first-child, .props td.description > p:first-child {
488 | margin-top: 0;
489 | padding-top: 0;
490 | }
491 |
492 | .params td.description > p:last-child, .props td.description > p:last-child {
493 | margin-bottom: 0;
494 | padding-bottom: 0;
495 | }
496 |
497 | span.param-type, .params td .param-type, .param-type dd {
498 | color: #1683d0;
499 | font-family: Consolas, Monaco, 'Andale Mono', monospace
500 | }
501 |
502 | .param-type dt, .param-type dd {
503 | display: inline-block
504 | }
505 |
506 | .param-type {
507 | margin: 14px 0;
508 | }
509 |
510 | .disabled {
511 | color: #454545
512 | }
513 |
514 | /* navicon button */
515 | .navicon-button {
516 | display: none;
517 | position: relative;
518 | padding: 2.0625rem 1.5rem;
519 | transition: 0.25s;
520 | cursor: pointer;
521 | -webkit-user-select: none;
522 | -moz-user-select: none;
523 | -ms-user-select: none;
524 | user-select: none;
525 | opacity: .8;
526 | }
527 | .navicon-button .navicon:before, .navicon-button .navicon:after {
528 | transition: 0.25s;
529 | }
530 | .navicon-button:hover {
531 | transition: 0.5s;
532 | opacity: 1;
533 | }
534 | .navicon-button:hover .navicon:before, .navicon-button:hover .navicon:after {
535 | transition: 0.25s;
536 | }
537 | .navicon-button:hover .navicon:before {
538 | top: .825rem;
539 | }
540 | .navicon-button:hover .navicon:after {
541 | top: -.825rem;
542 | }
543 |
544 | /* navicon */
545 | .navicon {
546 | position: relative;
547 | width: 2.5em;
548 | height: .3125rem;
549 | background: #000;
550 | transition: 0.3s;
551 | border-radius: 2.5rem;
552 | }
553 | .navicon:before, .navicon:after {
554 | display: block;
555 | content: "";
556 | height: .3125rem;
557 | width: 2.5rem;
558 | background: #000;
559 | position: absolute;
560 | z-index: -1;
561 | transition: 0.3s 0.25s;
562 | border-radius: 1rem;
563 | }
564 | .navicon:before {
565 | top: .625rem;
566 | }
567 | .navicon:after {
568 | top: -.625rem;
569 | }
570 |
571 | /* open */
572 | .nav-trigger:checked + label:not(.steps) .navicon:before,
573 | .nav-trigger:checked + label:not(.steps) .navicon:after {
574 | top: 0 !important;
575 | }
576 |
577 | .nav-trigger:checked + label .navicon:before,
578 | .nav-trigger:checked + label .navicon:after {
579 | transition: 0.5s;
580 | }
581 |
582 | /* Minus */
583 | .nav-trigger:checked + label {
584 | -webkit-transform: scale(0.75);
585 | transform: scale(0.75);
586 | }
587 |
588 | /* × and + */
589 | .nav-trigger:checked + label.plus .navicon,
590 | .nav-trigger:checked + label.x .navicon {
591 | background: transparent;
592 | }
593 |
594 | .nav-trigger:checked + label.plus .navicon:before,
595 | .nav-trigger:checked + label.x .navicon:before {
596 | -webkit-transform: rotate(-45deg);
597 | transform: rotate(-45deg);
598 | background: #FFF;
599 | }
600 |
601 | .nav-trigger:checked + label.plus .navicon:after,
602 | .nav-trigger:checked + label.x .navicon:after {
603 | -webkit-transform: rotate(45deg);
604 | transform: rotate(45deg);
605 | background: #FFF;
606 | }
607 |
608 | .nav-trigger:checked + label.plus {
609 | -webkit-transform: scale(0.75) rotate(45deg);
610 | transform: scale(0.75) rotate(45deg);
611 | }
612 |
613 | .nav-trigger:checked ~ nav {
614 | left: 0 !important;
615 | }
616 |
617 | .nav-trigger:checked ~ .overlay {
618 | display: block;
619 | }
620 |
621 | .nav-trigger {
622 | position: fixed;
623 | top: 0;
624 | clip: rect(0, 0, 0, 0);
625 | }
626 |
627 | .overlay {
628 | display: none;
629 | position: fixed;
630 | top: 0;
631 | bottom: 0;
632 | left: 0;
633 | right: 0;
634 | width: 100%;
635 | height: 100%;
636 | background: hsla(0, 0%, 0%, 0.5);
637 | z-index: 1;
638 | }
639 |
640 | @media only screen and (min-width: 320px) and (max-width: 680px) {
641 | body {
642 | overflow-x: hidden;
643 | }
644 |
645 | nav {
646 | background: #FFF;
647 | width: 250px;
648 | height: 100%;
649 | position: fixed;
650 | top: 0;
651 | right: 0;
652 | bottom: 0;
653 | left: -250px;
654 | z-index: 3;
655 | padding: 0 10px;
656 | transition: left 0.2s;
657 | }
658 |
659 | .navicon-button {
660 | display: inline-block;
661 | position: fixed;
662 | top: 1.5em;
663 | right: 0;
664 | z-index: 2;
665 | }
666 |
667 | #main {
668 | width: 100%;
669 | min-width: 360px;
670 | }
671 |
672 | #main h1.page-title {
673 | margin: 1em 0;
674 | }
675 |
676 | #main section {
677 | padding: 0;
678 | }
679 |
680 | footer {
681 | margin-left: 0;
682 | }
683 | }
684 |
685 | /** Add a '#' to static members */
686 | [data-type="member"] a::before {
687 | content: '#';
688 | display: inline-block;
689 | margin-left: -14px;
690 | margin-right: 5px;
691 | }
692 |
--------------------------------------------------------------------------------
/jsdoc-template/publish.js:
--------------------------------------------------------------------------------
1 | /*global env: true */
2 | 'use strict';
3 |
4 | var doop = require('jsdoc/util/doop');
5 | var fs = require('jsdoc/fs');
6 | var helper = require('jsdoc/util/templateHelper');
7 | var logger = require('jsdoc/util/logger');
8 | var path = require('jsdoc/path');
9 | // https://github.com/jsdoc/jsdoc/tree/main/packages/jsdoc-salty#use-salty-in-a-jsdoc-template
10 | var taffy = require('@jsdoc/salty').taffy;
11 | var template = require('jsdoc/template');
12 | var util = require('util');
13 |
14 | var htmlsafe = helper.htmlsafe;
15 | var linkto = helper.linkto;
16 | var resolveAuthorLinks = helper.resolveAuthorLinks;
17 | var scopeToPunc = helper.scopeToPunc;
18 | var hasOwnProp = Object.prototype.hasOwnProperty;
19 |
20 | var data;
21 | var view;
22 |
23 | var outdir = path.normalize(env.opts.destination);
24 |
25 | function find(spec) {
26 | return helper.find(data, spec);
27 | }
28 |
29 | function tutoriallink(tutorial) {
30 | return helper.toTutorial(tutorial, null, { tag: 'em', classname: 'disabled', prefix: 'Tutorial: ' });
31 | }
32 |
33 | function getAncestorLinks(doclet) {
34 | return helper.getAncestorLinks(data, doclet);
35 | }
36 |
37 | function hashToLink(doclet, hash) {
38 | if ( !/^(#.+)/.test(hash) ) { return hash; }
39 |
40 | var url = helper.createLink(doclet);
41 |
42 | url = url.replace(/(#.+|$)/, hash);
43 | return '' + hash + ' ';
44 | }
45 |
46 | function needsSignature(doclet) {
47 | var needsSig = false;
48 |
49 | // function and class definitions always get a signature
50 | if (doclet.kind === 'function' || doclet.kind === 'class') {
51 | needsSig = true;
52 | }
53 | // typedefs that contain functions get a signature, too
54 | else if (doclet.kind === 'typedef' && doclet.type && doclet.type.names &&
55 | doclet.type.names.length) {
56 | for (var i = 0, l = doclet.type.names.length; i < l; i++) {
57 | if (doclet.type.names[i].toLowerCase() === 'function') {
58 | needsSig = true;
59 | break;
60 | }
61 | }
62 | }
63 |
64 | return needsSig;
65 | }
66 |
67 | function getSignatureAttributes(item) {
68 | var attributes = [];
69 |
70 | if (item.optional) {
71 | attributes.push('opt');
72 | }
73 |
74 | if (item.nullable === true) {
75 | attributes.push('nullable');
76 | }
77 | else if (item.nullable === false) {
78 | attributes.push('non-null');
79 | }
80 |
81 | return attributes;
82 | }
83 |
84 | function updateItemName(item) {
85 | var attributes = getSignatureAttributes(item);
86 | var itemName = item.name || '';
87 |
88 | if (item.variable) {
89 | itemName = '…' + itemName;
90 | }
91 |
92 | if (attributes && attributes.length) {
93 | itemName = util.format( '%s%s ', itemName,
94 | attributes.join(', ') );
95 | }
96 |
97 | return itemName;
98 | }
99 |
100 | function addParamAttributes(params) {
101 | return params.filter(function(param) {
102 | return param.name && param.name.indexOf('.') === -1;
103 | }).map(updateItemName);
104 | }
105 |
106 | function buildItemTypeStrings(item) {
107 | var types = [];
108 |
109 | if (item && item.type && item.type.names) {
110 | item.type.names.forEach(function(name) {
111 | types.push( linkto(name, htmlsafe(name)) );
112 | });
113 | }
114 |
115 | return types;
116 | }
117 |
118 | function buildAttribsString(attribs) {
119 | var attribsString = '';
120 |
121 | if (attribs && attribs.length) {
122 | attribsString = htmlsafe( util.format('(%s) ', attribs.join(', ')) );
123 | }
124 |
125 | return attribsString;
126 | }
127 |
128 | function addNonParamAttributes(items) {
129 | var types = [];
130 |
131 | items.forEach(function(item) {
132 | types = types.concat( buildItemTypeStrings(item) );
133 | });
134 |
135 | return types;
136 | }
137 |
138 | function addSignatureParams(f) {
139 | var params = f.params ? addParamAttributes(f.params) : [];
140 | f.signature = util.format( '%s(%s)', (f.signature || ''), params.join(', ') );
141 | }
142 |
143 | function addSignatureReturns(f) {
144 | var attribs = [];
145 | var attribsString = '';
146 | var returnTypes = [];
147 | var returnTypesString = '';
148 |
149 | // jam all the return-type attributes into an array. this could create odd results (for example,
150 | // if there are both nullable and non-nullable return types), but let's assume that most people
151 | // who use multiple @return tags aren't using Closure Compiler type annotations, and vice-versa.
152 | if (f.returns) {
153 | f.returns.forEach(function(item) {
154 | helper.getAttribs(item).forEach(function(attrib) {
155 | if (attribs.indexOf(attrib) === -1) {
156 | attribs.push(attrib);
157 | }
158 | });
159 | });
160 |
161 | attribsString = buildAttribsString(attribs);
162 | }
163 |
164 | if (f.returns) {
165 | returnTypes = addNonParamAttributes(f.returns);
166 | }
167 | if (returnTypes.length) {
168 | returnTypesString = util.format( ' → %s{%s}', attribsString, returnTypes.join('|') );
169 | }
170 |
171 | f.signature = '' + (f.signature || '') + ' ' +
172 | '' + returnTypesString + ' ';
173 | }
174 |
175 | function addSignatureTypes(f) {
176 | var types = f.type ? buildItemTypeStrings(f) : [];
177 |
178 | f.signature = (f.signature || '') + '' +
179 | (types.length ? ' :' + types.join('|') : '') + ' ';
180 | }
181 |
182 | function addAttribs(f) {
183 | var attribs = helper.getAttribs(f);
184 | var attribsString = buildAttribsString(attribs);
185 |
186 | f.attribs = util.format('%s ', attribsString);
187 | }
188 |
189 | function shortenPaths(files, commonPrefix) {
190 | Object.keys(files).forEach(function(file) {
191 | files[file].shortened = files[file].resolved.replace(commonPrefix, '')
192 | // always use forward slashes
193 | .replace(/\\/g, '/');
194 | });
195 |
196 | return files;
197 | }
198 |
199 | function getPathFromDoclet(doclet) {
200 | if (!doclet.meta) {
201 | return null;
202 | }
203 |
204 | return doclet.meta.path && doclet.meta.path !== 'null' ?
205 | path.join(doclet.meta.path, doclet.meta.filename) :
206 | doclet.meta.filename;
207 | }
208 |
209 | function generate(type, title, docs, filename, resolveLinks) {
210 | resolveLinks = resolveLinks === false ? false : true;
211 |
212 | var docData = {
213 | type: type,
214 | title: title,
215 | docs: docs
216 | };
217 |
218 | var outpath = path.join(outdir, filename),
219 | html = view.render('container.tmpl', docData);
220 |
221 | if (resolveLinks) {
222 | html = helper.resolveLinks(html); // turn {@link foo} into foo
223 | }
224 |
225 | fs.writeFileSync(outpath, html, 'utf8');
226 | }
227 |
228 | function generateSourceFiles(sourceFiles, encoding) {
229 | encoding = encoding || 'utf8';
230 | Object.keys(sourceFiles).forEach(function(file) {
231 | var source;
232 | // links are keyed to the shortened path in each doclet's `meta.shortpath` property
233 | var sourceOutfile = helper.getUniqueFilename(sourceFiles[file].shortened);
234 | helper.registerLink(sourceFiles[file].shortened, sourceOutfile);
235 |
236 | try {
237 | source = {
238 | kind: 'source',
239 | code: helper.htmlsafe( fs.readFileSync(sourceFiles[file].resolved, encoding) )
240 | };
241 | }
242 | catch(e) {
243 | logger.error('Error while generating source file %s: %s', file, e.message);
244 | }
245 |
246 | generate('Source', sourceFiles[file].shortened, [source], sourceOutfile, false);
247 | });
248 | }
249 |
250 | /**
251 | * Look for classes or functions with the same name as modules (which indicates that the module
252 | * exports only that class or function), then attach the classes or functions to the `module`
253 | * property of the appropriate module doclets. The name of each class or function is also updated
254 | * for display purposes. This function mutates the original arrays.
255 | *
256 | * @private
257 | * @param {Array.} doclets - The array of classes and functions to
258 | * check.
259 | * @param {Array.} modules - The array of module doclets to search.
260 | */
261 | function attachModuleSymbols(doclets, modules) {
262 | var symbols = {};
263 |
264 | // build a lookup table
265 | doclets.forEach(function(symbol) {
266 | symbols[symbol.longname] = symbols[symbol.longname] || [];
267 | symbols[symbol.longname].push(symbol);
268 | });
269 |
270 | return modules.map(function(module) {
271 | if (symbols[module.longname]) {
272 | module.modules = symbols[module.longname]
273 | // Only show symbols that have a description. Make an exception for classes, because
274 | // we want to show the constructor-signature heading no matter what.
275 | .filter(function(symbol) {
276 | return symbol.description || symbol.kind === 'class';
277 | })
278 | .map(function(symbol) {
279 | symbol = doop(symbol);
280 |
281 | if (symbol.kind === 'class' || symbol.kind === 'function') {
282 | symbol.name = symbol.name.replace('module:', '(require("') + '"))';
283 | }
284 |
285 | return symbol;
286 | });
287 | }
288 | });
289 | }
290 |
291 | function buildMemberNav(items, itemHeading, itemsSeen, linktoFn) {
292 | var nav = '';
293 |
294 | if (items && items.length) {
295 | var itemsNav = '';
296 |
297 | items.forEach(function(item) {
298 | var methods = find({kind:'function', memberof: item.longname});
299 | var members = find({kind:'member', memberof: item.longname});
300 | var docdash = env && env.conf && env.conf.docdash || {};
301 |
302 | if ( !hasOwnProp.call(item, 'longname') ) {
303 | itemsNav += '' + linktoFn('', item.name);
304 | itemsNav += ' ';
305 | } else if ( !hasOwnProp.call(itemsSeen, item.longname) ) {
306 | itemsNav += '' + linktoFn(item.longname, item.name.replace(/^module:/, ''));
307 |
308 | if (docdash.static && members.find(function (m) { return m.scope === 'static'; } )) {
309 | itemsNav += "";
310 |
311 | members.forEach(function (member) {
312 | if (!member.scope === 'static') return;
313 | itemsNav += "";
314 | itemsNav += linkto(member.longname, member.name);
315 | itemsNav += " ";
316 | });
317 |
318 | itemsNav += " ";
319 | }
320 |
321 | if (methods.length) {
322 | itemsNav += "";
323 |
324 | methods.forEach(function (method) {
325 | itemsNav += "";
326 | itemsNav += linkto(method.longname, method.name);
327 | itemsNav += " ";
328 | });
329 |
330 | itemsNav += " ";
331 | }
332 |
333 | itemsNav += ' ';
334 | itemsSeen[item.longname] = true;
335 | }
336 | });
337 |
338 | if (itemsNav !== '') {
339 | nav += '' + itemHeading + ' ';
340 | }
341 | }
342 |
343 | return nav;
344 | }
345 |
346 | function linktoTutorial(longName, name) {
347 | return tutoriallink(name);
348 | }
349 |
350 | function linktoExternal(longName, name) {
351 | return linkto(longName, name.replace(/(^"|"$)/g, ''));
352 | }
353 |
354 | /**
355 | * Create the navigation sidebar.
356 | * @param {object} members The members that will be used to create the sidebar.
357 | * @param {array} members.classes
358 | * @param {array} members.externals
359 | * @param {array} members.globals
360 | * @param {array} members.mixins
361 | * @param {array} members.modules
362 | * @param {array} members.namespaces
363 | * @param {array} members.tutorials
364 | * @param {array} members.events
365 | * @param {array} members.interfaces
366 | * @return {s
367 | ring} The HTML for the navigation sidebar.
368 | */
369 |
370 | function buildNav(members) {
371 | var nav = '';
372 | var seen = {};
373 | var seenTutorials = {};
374 |
375 | nav += buildMemberNav(members.classes, 'Classes', seen, linkto);
376 | nav += buildMemberNav(members.modules, 'Modules', {}, linkto);
377 | nav += buildMemberNav(members.externals, 'Externals', seen, linktoExternal);
378 | nav += buildMemberNav(members.events, 'Events', seen, linkto);
379 | nav += buildMemberNav(members.namespaces, 'Namespaces', seen, linkto);
380 | nav += buildMemberNav(members.mixins, 'Mixins', seen, linkto);
381 | nav += buildMemberNav(members.tutorials, 'Tutorials', seenTutorials, linktoTutorial);
382 | nav += buildMemberNav(members.interfaces, 'Interfaces', seen, linkto);
383 |
384 | if (members.globals.length) {
385 | var globalNav = '';
386 |
387 | members.globals.forEach(function(g) {
388 | if ( g.kind !== 'typedef' && !hasOwnProp.call(seen, g.longname) ) {
389 | globalNav += '' + linkto(g.longname, g.name) + ' ';
390 | }
391 | seen[g.longname] = true;
392 | });
393 |
394 | if (!globalNav) {
395 | // turn the heading into a link so you can actually get to the global page
396 | nav += '' + linkto('global', 'Global') + ' ';
397 | }
398 | else {
399 | nav += 'Global ';
400 | }
401 | }
402 |
403 | return nav;
404 | }
405 |
406 | /**
407 | @param {TAFFY} taffyData See .
408 | @param {object} opts
409 | @param {Tutorial} tutorials
410 | */
411 | exports.publish = function(taffyData, opts, tutorials) {
412 | var docdash = env && env.conf && env.conf.docdash || {};
413 | data = taffyData;
414 |
415 | var conf = env.conf.templates || {};
416 | conf.default = conf.default || {};
417 |
418 | var templatePath = path.normalize(opts.template);
419 | view = new template.Template( path.join(templatePath, 'tmpl') );
420 |
421 | // claim some special filenames in advance, so the All-Powerful Overseer of Filename Uniqueness
422 | // doesn't try to hand them out later
423 | var indexUrl = helper.getUniqueFilename('index');
424 | // don't call registerLink() on this one! 'index' is also a valid longname
425 |
426 | var globalUrl = helper.getUniqueFilename('global');
427 | helper.registerLink('global', globalUrl);
428 |
429 | // set up templating
430 | view.layout = conf.default.layoutFile ?
431 | path.getResourcePath(path.dirname(conf.default.layoutFile),
432 | path.basename(conf.default.layoutFile) ) :
433 | 'layout.tmpl';
434 |
435 | // set up tutorials for helper
436 | helper.setTutorials(tutorials);
437 |
438 | data = helper.prune(data);
439 |
440 | docdash.sort !== false && data.sort('longname, version, since');
441 | helper.addEventListeners(data);
442 |
443 | var sourceFiles = {};
444 | var sourceFilePaths = [];
445 | data().each(function(doclet) {
446 | doclet.attribs = '';
447 |
448 | if (doclet.examples) {
449 | doclet.examples = doclet.examples.map(function(example) {
450 | var caption, code;
451 |
452 | if (example.match(/^\s*([\s\S]+?)<\/caption>(\s*[\n\r])([\s\S]+)$/i)) {
453 | caption = RegExp.$1;
454 | code = RegExp.$3;
455 | }
456 |
457 | return {
458 | caption: caption || '',
459 | code: code || example
460 | };
461 | });
462 | }
463 | if (doclet.see) {
464 | doclet.see.forEach(function(seeItem, i) {
465 | doclet.see[i] = hashToLink(doclet, seeItem);
466 | });
467 | }
468 |
469 | // build a list of source files
470 | var sourcePath;
471 | if (doclet.meta) {
472 | sourcePath = getPathFromDoclet(doclet);
473 | sourceFiles[sourcePath] = {
474 | resolved: sourcePath,
475 | shortened: null
476 | };
477 | if (sourceFilePaths.indexOf(sourcePath) === -1) {
478 | sourceFilePaths.push(sourcePath);
479 | }
480 | }
481 | });
482 |
483 | // update outdir if necessary, then create outdir
484 | var packageInfo = ( find({kind: 'package'}) || [] ) [0];
485 | if (packageInfo && packageInfo.name) {
486 | outdir = path.join( outdir, packageInfo.name, (packageInfo.version || '') );
487 | }
488 | fs.mkPath(outdir);
489 |
490 | // copy the template's static files to outdir
491 | var fromDir = path.join(templatePath, 'static');
492 | var staticFiles = fs.ls(fromDir, 3);
493 |
494 | staticFiles.forEach(function(fileName) {
495 | var toDir = fs.toDir( fileName.replace(fromDir, outdir) );
496 | fs.mkPath(toDir);
497 | fs.copyFileSync(fileName, toDir);
498 | });
499 |
500 | // copy user-specified static files to outdir
501 | var staticFilePaths;
502 | var staticFileFilter;
503 | var staticFileScanner;
504 | if (conf.default.staticFiles) {
505 | // The canonical property name is `include`. We accept `paths` for backwards compatibility
506 | // with a bug in JSDoc 3.2.x.
507 | staticFilePaths = conf.default.staticFiles.include ||
508 | conf.default.staticFiles.paths ||
509 | [];
510 | staticFileFilter = new (require('jsdoc/src/filter')).Filter(conf.default.staticFiles);
511 | staticFileScanner = new (require('jsdoc/src/scanner')).Scanner();
512 |
513 | staticFilePaths.forEach(function(filePath) {
514 | var extraStaticFiles = staticFileScanner.scan([filePath], 10, staticFileFilter);
515 |
516 | extraStaticFiles.forEach(function(fileName) {
517 | var sourcePath = fs.toDir(filePath);
518 | var toDir = fs.toDir( fileName.replace(sourcePath, outdir) );
519 | fs.mkPath(toDir);
520 | fs.copyFileSync(fileName, toDir);
521 | });
522 | });
523 | }
524 |
525 | if (sourceFilePaths.length) {
526 | sourceFiles = shortenPaths( sourceFiles, path.commonPrefix(sourceFilePaths) );
527 | }
528 | data().each(function(doclet) {
529 | var url = helper.createLink(doclet);
530 | helper.registerLink(doclet.longname, url);
531 |
532 | // add a shortened version of the full path
533 | var docletPath;
534 | if (doclet.meta) {
535 | docletPath = getPathFromDoclet(doclet);
536 | docletPath = sourceFiles[docletPath].shortened;
537 | if (docletPath) {
538 | doclet.meta.shortpath = docletPath;
539 | }
540 | }
541 | });
542 |
543 | data().each(function(doclet) {
544 | var url = helper.longnameToUrl[doclet.longname];
545 |
546 | if (url.indexOf('#') > -1) {
547 | doclet.id = helper.longnameToUrl[doclet.longname].split(/#/).pop();
548 | }
549 | else {
550 | doclet.id = doclet.name;
551 | }
552 |
553 | if ( needsSignature(doclet) ) {
554 | addSignatureParams(doclet);
555 | addSignatureReturns(doclet);
556 | addAttribs(doclet);
557 | }
558 | });
559 |
560 | // do this after the urls have all been generated
561 | data().each(function(doclet) {
562 | doclet.ancestors = getAncestorLinks(doclet);
563 |
564 | if (doclet.kind === 'member') {
565 | addSignatureTypes(doclet);
566 | addAttribs(doclet);
567 | }
568 |
569 | if (doclet.kind === 'constant') {
570 | addSignatureTypes(doclet);
571 | addAttribs(doclet);
572 | doclet.kind = 'member';
573 | }
574 | });
575 |
576 | var members = helper.getMembers(data);
577 | members.tutorials = tutorials.children;
578 |
579 | // output pretty-printed source files by default
580 | var outputSourceFiles = conf.default && conf.default.outputSourceFiles !== false
581 | ? true
582 | : false;
583 |
584 | // add template helpers
585 | view.find = find;
586 | view.linkto = linkto;
587 | view.resolveAuthorLinks = resolveAuthorLinks;
588 | view.tutoriallink = tutoriallink;
589 | view.htmlsafe = htmlsafe;
590 | view.outputSourceFiles = outputSourceFiles;
591 |
592 | // once for all
593 | view.nav = buildNav(members);
594 | attachModuleSymbols( find({ longname: {left: 'module:'} }), members.modules );
595 |
596 | // generate the pretty-printed source files first so other pages can link to them
597 | if (outputSourceFiles) {
598 | generateSourceFiles(sourceFiles, opts.encoding);
599 | }
600 |
601 | if (members.globals.length) {
602 | generate('', 'Global', [{kind: 'globalobj'}], globalUrl);
603 | }
604 |
605 | // index page displays information from package.json and lists files
606 | var files = find({kind: 'file'});
607 | var packages = find({kind: 'package'});
608 |
609 | generate('', 'Home',
610 | packages.concat(
611 | [{kind: 'mainpage', readme: opts.readme, longname: (opts.mainpagetitle) ? opts.mainpagetitle : 'Main Page'}]
612 | ).concat(files),
613 | indexUrl);
614 |
615 | // set up the lists that we'll use to generate pages
616 | var classes = taffy(members.classes);
617 | var modules = taffy(members.modules);
618 | var namespaces = taffy(members.namespaces);
619 | var mixins = taffy(members.mixins);
620 | var externals = taffy(members.externals);
621 | var interfaces = taffy(members.interfaces);
622 |
623 | Object.keys(helper.longnameToUrl).forEach(function(longname) {
624 | var myModules = helper.find(modules, {longname: longname});
625 | if (myModules.length) {
626 | generate('Module', myModules[0].name, myModules, helper.longnameToUrl[longname]);
627 | }
628 |
629 | var myClasses = helper.find(classes, {longname: longname});
630 | if (myClasses.length) {
631 | generate('Class', myClasses[0].name, myClasses, helper.longnameToUrl[longname]);
632 | }
633 |
634 | var myNamespaces = helper.find(namespaces, {longname: longname});
635 | if (myNamespaces.length) {
636 | generate('Namespace', myNamespaces[0].name, myNamespaces, helper.longnameToUrl[longname]);
637 | }
638 |
639 | var myMixins = helper.find(mixins, {longname: longname});
640 | if (myMixins.length) {
641 | generate('Mixin', myMixins[0].name, myMixins, helper.longnameToUrl[longname]);
642 | }
643 |
644 | var myExternals = helper.find(externals, {longname: longname});
645 | if (myExternals.length) {
646 | generate('External', myExternals[0].name, myExternals, helper.longnameToUrl[longname]);
647 | }
648 |
649 | var myInterfaces = helper.find(interfaces, {longname: longname});
650 | if (myInterfaces.length) {
651 | generate('Interface', myInterfaces[0].name, myInterfaces, helper.longnameToUrl[longname]);
652 | }
653 | });
654 |
655 | // TODO: move the tutorial functions to templateHelper.js
656 | function generateTutorial(title, tutorial, filename) {
657 | var tutorialData = {
658 | title: title,
659 | header: tutorial.title,
660 | content: tutorial.parse(),
661 | children: tutorial.children
662 | };
663 |
664 | var tutorialPath = path.join(outdir, filename);
665 | var html = view.render('tutorial.tmpl', tutorialData);
666 |
667 | // yes, you can use {@link} in tutorials too!
668 | html = helper.resolveLinks(html); // turn {@link foo} into foo
669 | fs.writeFileSync(tutorialPath, html, 'utf8');
670 | }
671 |
672 | // tutorials can have only one parent so there is no risk for loops
673 | function saveChildren(node) {
674 | node.children.forEach(function(child) {
675 | generateTutorial('Tutorial: ' + child.title, child, helper.tutorialToUrl(child.name));
676 | saveChildren(child);
677 | });
678 | }
679 |
680 | saveChildren(tutorials);
681 | };
682 |
--------------------------------------------------------------------------------