├── .coveralls.yml
├── .eslintrc.json
├── .github
└── workflows
│ └── node.js.yml
├── .gitignore
├── .gitmodules
├── .ignore
├── .jsdocrc.json
├── .npmignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── dist
├── index.js
└── index.js.map
├── docs
├── ReturnTypes.html
├── core_index.js.html
├── core_src_Gesture.js.html
├── core_src_Input.js.html
├── core_src_Point2D.js.html
├── core_src_PointerData.js.html
├── core_src_Region.js.html
├── core_src_Smoothable.js.html
├── core_src_State.js.html
├── core_src_constants.js.html
├── core_src_utils.js.html
├── fonts
│ ├── Montserrat
│ │ ├── Montserrat-Bold.eot
│ │ ├── Montserrat-Bold.ttf
│ │ ├── Montserrat-Bold.woff
│ │ ├── Montserrat-Bold.woff2
│ │ ├── Montserrat-Regular.eot
│ │ ├── Montserrat-Regular.ttf
│ │ ├── Montserrat-Regular.woff
│ │ └── Montserrat-Regular.woff2
│ └── Source-Sans-Pro
│ │ ├── sourcesanspro-light-webfont.eot
│ │ ├── sourcesanspro-light-webfont.svg
│ │ ├── sourcesanspro-light-webfont.ttf
│ │ ├── sourcesanspro-light-webfont.woff
│ │ ├── sourcesanspro-light-webfont.woff2
│ │ ├── sourcesanspro-regular-webfont.eot
│ │ ├── sourcesanspro-regular-webfont.svg
│ │ ├── sourcesanspro-regular-webfont.ttf
│ │ ├── sourcesanspro-regular-webfont.woff
│ │ └── sourcesanspro-regular-webfont.woff2
├── index.html
├── index.js.html
├── scripts
│ ├── collapse.js
│ ├── commonNav.js
│ ├── linenumber.js
│ ├── nav.js
│ ├── polyfill.js
│ ├── prettify
│ │ ├── Apache-License-2.0.txt
│ │ ├── lang-css.js
│ │ └── prettify.js
│ └── search.js
├── src_Pan.js.html
├── src_Pinch.js.html
├── src_Pivotable.js.html
├── src_Press.js.html
├── src_Pull.js.html
├── src_Rotate.js.html
├── src_Swipe.js.html
├── src_Swivel.js.html
├── src_Tap.js.html
├── src_Track.js.html
├── styles
│ ├── jsdoc.css
│ └── prettify.css
├── westures-core.Gesture.html
├── westures-core.Input.html
├── westures-core.Point2D.html
├── westures-core.PointerData.html
├── westures-core.Region.html
├── westures-core.Smoothable.html
├── westures-core.State.html
├── westures-core.html
├── westures.Pan.html
├── westures.Pinch.html
├── westures.Pivotable.html
├── westures.Press.html
├── westures.Pull.html
├── westures.Rotate.html
├── westures.Swipe.html
├── westures.Swivel.html
├── westures.Tap.html
├── westures.Track.html
└── westures.html
├── index.js
├── package-lock.json
├── package.json
├── src
├── Pan.js
├── Pinch.js
├── Pivotable.js
├── Press.js
├── Pull.js
├── Rotate.js
├── Swipe.js
├── Swivel.js
├── Tap.js
└── Track.js
└── test
├── Pan.test.js
├── Pinch.test.js
├── Pivotable.test.js
├── Press.test.js
├── Pull.test.js
├── Rotate.test.js
├── Swipe.test.js
├── Swivel.test.js
├── Tap.test.js
├── Track.test.js
└── Westures.test.js
/.coveralls.yml:
--------------------------------------------------------------------------------
1 | repo_token: 1SMnpKOVOGBAwQSd2qb7yDrzxEQNIcEsy
2 |
--------------------------------------------------------------------------------
/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "env": {
3 | "browser": true,
4 | "commonjs": true,
5 | "es6": true,
6 | "node": true
7 | },
8 | "extends": "eslint:recommended",
9 | "parserOptions": {
10 | "ecmaVersion": 2018
11 | },
12 | "rules": {
13 | "accessor-pairs": "error",
14 | "array-bracket-newline": "off",
15 | "array-bracket-spacing": [
16 | "error",
17 | "never"
18 | ],
19 | "array-callback-return": "error",
20 | "array-element-newline": "off",
21 | "arrow-body-style": "off",
22 | "arrow-parens": "off",
23 | "arrow-spacing": [
24 | "error",
25 | {
26 | "after": true,
27 | "before": true
28 | }
29 | ],
30 | "block-scoped-var": "error",
31 | "block-spacing": [
32 | "error",
33 | "always"
34 | ],
35 | "brace-style": [
36 | "error",
37 | "1tbs",
38 | {
39 | "allowSingleLine": true
40 | }
41 | ],
42 | "callback-return": "error",
43 | "camelcase": "off",
44 | "capitalized-comments": "off",
45 | "class-methods-use-this": "off",
46 | "comma-dangle": ["error", "always-multiline"],
47 | "comma-spacing": "error",
48 | "comma-style": [
49 | "error",
50 | "last"
51 | ],
52 | "complexity": "error",
53 | "computed-property-spacing": [
54 | "error",
55 | "never"
56 | ],
57 | "consistent-return": "error",
58 | "consistent-this": "error",
59 | "curly": "off",
60 | "default-case": "error",
61 | "dot-location": [
62 | "error",
63 | "property"
64 | ],
65 | "dot-notation": "error",
66 | "eol-last": "error",
67 | "eqeqeq": "off",
68 | "func-call-spacing": "error",
69 | "func-name-matching": "error",
70 | "func-names": "error",
71 | "func-style": [
72 | "error",
73 | "declaration",
74 | {
75 | "allowArrowFunctions": true
76 | }
77 | ],
78 | "function-paren-newline": "error",
79 | "generator-star-spacing": "off",
80 | "global-require": "error",
81 | "guard-for-in": "error",
82 | "handle-callback-err": "error",
83 | "id-blacklist": "error",
84 | "id-length": "off",
85 | "id-match": "error",
86 | "implicit-arrow-linebreak": [
87 | "error",
88 | "beside"
89 | ],
90 | "indent": [
91 | "error",
92 | 2
93 | ],
94 | "indent-legacy": "off",
95 | "init-declarations": "error",
96 | "jsx-quotes": "error",
97 | "key-spacing": [
98 | "error",
99 | {
100 | "beforeColon": false,
101 | "afterColon": true,
102 | "mode": "minimum",
103 | "align": "value"
104 | }
105 | ],
106 | "keyword-spacing": [
107 | "error",
108 | {
109 | "after": true,
110 | "before": true
111 | }
112 | ],
113 | "line-comment-position": "off",
114 | "linebreak-style": [
115 | "error",
116 | "unix"
117 | ],
118 | "lines-around-comment": "off",
119 | "lines-around-directive": "error",
120 | "lines-between-class-members": [
121 | "error",
122 | "always",
123 | {
124 | "exceptAfterSingleLine": true
125 | }
126 | ],
127 | "max-classes-per-file": "error",
128 | "max-depth": "error",
129 | "max-len": "error",
130 | "max-lines": "off",
131 | "max-lines-per-function": "off",
132 | "max-nested-callbacks": "error",
133 | "max-params": "off",
134 | "max-statements": "off",
135 | "max-statements-per-line": "error",
136 | "multiline-comment-style": "off",
137 | "new-parens": "error",
138 | "newline-after-var": "off",
139 | "newline-before-return": "off",
140 | "newline-per-chained-call": "error",
141 | "no-alert": "error",
142 | "no-array-constructor": "error",
143 | "no-async-promise-executor": "error",
144 | "no-await-in-loop": "error",
145 | "no-bitwise": "error",
146 | "no-buffer-constructor": "error",
147 | "no-caller": "error",
148 | "no-catch-shadow": "error",
149 | "no-console": [
150 | "error",
151 | {
152 | "allow": [
153 | "info",
154 | "warn",
155 | "error"
156 | ]
157 | }
158 | ],
159 | "no-confusing-arrow": "error",
160 | "no-continue": "error",
161 | "no-div-regex": "error",
162 | "no-duplicate-imports": "error",
163 | "no-else-return": "error",
164 | "no-empty-function": "off",
165 | "no-eq-null": "off",
166 | "no-eval": "error",
167 | "no-extend-native": "error",
168 | "no-extra-bind": "error",
169 | "no-extra-label": "error",
170 | "no-extra-parens": "off",
171 | "no-floating-decimal": "error",
172 | "no-implicit-coercion": "error",
173 | "no-implicit-globals": "error",
174 | "no-implied-eval": "error",
175 | "no-inline-comments": "off",
176 | "no-invalid-this": "off",
177 | "no-iterator": "error",
178 | "no-label-var": "error",
179 | "no-labels": "error",
180 | "no-lone-blocks": "error",
181 | "no-lonely-if": "off",
182 | "no-loop-func": "error",
183 | "no-magic-numbers": "off",
184 | "no-misleading-character-class": "error",
185 | "no-mixed-operators": "off",
186 | "no-mixed-requires": "error",
187 | "no-multi-assign": "error",
188 | "no-multi-spaces": "off",
189 | "no-multi-str": "error",
190 | "no-multiple-empty-lines": "error",
191 | "no-native-reassign": "error",
192 | "no-negated-condition": "error",
193 | "no-negated-in-lhs": "error",
194 | "no-nested-ternary": "error",
195 | "no-new": "off",
196 | "no-new-func": "error",
197 | "no-new-object": "error",
198 | "no-new-require": "error",
199 | "no-new-wrappers": "error",
200 | "no-octal-escape": "error",
201 | "no-param-reassign": "off",
202 | "no-path-concat": "error",
203 | "no-plusplus": "off",
204 | "no-process-env": "error",
205 | "no-process-exit": "error",
206 | "no-proto": "error",
207 | "no-prototype-builtins": "off",
208 | "no-restricted-globals": "error",
209 | "no-restricted-imports": "error",
210 | "no-restricted-modules": "error",
211 | "no-restricted-properties": "error",
212 | "no-restricted-syntax": "error",
213 | "no-return-assign": "error",
214 | "no-return-await": "error",
215 | "no-script-url": "error",
216 | "no-self-compare": "error",
217 | "no-sequences": "error",
218 | "no-shadow": "off",
219 | "no-shadow-restricted-names": "error",
220 | "no-spaced-func": "off",
221 | "no-sync": "error",
222 | "no-tabs": "error",
223 | "no-template-curly-in-string": "error",
224 | "no-ternary": "off",
225 | "no-throw-literal": "off",
226 | "no-trailing-spaces": "error",
227 | "no-undef": "error",
228 | "no-undef-init": "error",
229 | "no-undefined": "error",
230 | "no-underscore-dangle": "error",
231 | "no-unmodified-loop-condition": "error",
232 | "no-unneeded-ternary": "error",
233 | "no-use-before-define": [
234 | "error",
235 | {
236 | "functions": true,
237 | "classes": true
238 | }
239 | ],
240 | "no-useless-call": "error",
241 | "no-useless-catch": "error",
242 | "no-useless-computed-key": "error",
243 | "no-useless-concat": "error",
244 | "no-useless-constructor": "error",
245 | "no-useless-rename": "error",
246 | "no-useless-return": "error",
247 | "no-var": "error",
248 | "no-void": "error",
249 | "no-warning-comments": "off",
250 | "no-whitespace-before-property": "error",
251 | "no-with": "error",
252 | "nonblock-statement-body-position": "error",
253 | "object-curly-newline": "error",
254 | "object-curly-spacing": [
255 | "error",
256 | "always"
257 | ],
258 | "object-shorthand": "off",
259 | "one-var": "off",
260 | "one-var-declaration-per-line": "error",
261 | "operator-assignment": [
262 | "error",
263 | "always"
264 | ],
265 | "operator-linebreak": "off",
266 | "padded-blocks": [
267 | "error",
268 | "never"
269 | ],
270 | "padding-line-between-statements": "error",
271 | "prefer-const": "error",
272 | "prefer-destructuring": "off",
273 | "prefer-numeric-literals": "error",
274 | "prefer-object-spread": "error",
275 | "prefer-promise-reject-errors": "error",
276 | "prefer-reflect": "off",
277 | "prefer-rest-params": "error",
278 | "prefer-spread": "error",
279 | "prefer-template": "error",
280 | "quote-props": "off",
281 | "quotes": [
282 | "error",
283 | "single"
284 | ],
285 | "radix": "error",
286 | "require-atomic-updates": "error",
287 | "require-await": "error",
288 | "require-jsdoc": "off",
289 | "require-unicode-regexp": "error",
290 | "rest-spread-spacing": [
291 | "error",
292 | "never"
293 | ],
294 | "semi": [
295 | "error",
296 | "always"
297 | ],
298 | "semi-spacing": [
299 | "error",
300 | {
301 | "after": true,
302 | "before": false
303 | }
304 | ],
305 | "semi-style": [
306 | "error",
307 | "last"
308 | ],
309 | "sort-imports": "error",
310 | "sort-keys": "off",
311 | "sort-vars": "error",
312 | "space-before-blocks": "error",
313 | "space-before-function-paren": [
314 | "error",
315 | "never"
316 | ],
317 | "space-in-parens": "error",
318 | "space-infix-ops": "error",
319 | "space-unary-ops": [
320 | "error",
321 | {
322 | "nonwords": false,
323 | "words": true
324 | }
325 | ],
326 | "spaced-comment": [
327 | "error",
328 | "always"
329 | ],
330 | "strict": "error",
331 | "switch-colon-spacing": "error",
332 | "symbol-description": "error",
333 | "template-curly-spacing": [
334 | "error",
335 | "never"
336 | ],
337 | "template-tag-spacing": "error",
338 | "unicode-bom": [
339 | "error",
340 | "never"
341 | ],
342 | "valid-jsdoc": "off",
343 | "vars-on-top": "error",
344 | "wrap-iife": "error",
345 | "wrap-regex": "error",
346 | "yield-star-spacing": "error",
347 | "yoda": [
348 | "error",
349 | "never"
350 | ]
351 | }
352 | }
353 |
--------------------------------------------------------------------------------
/.github/workflows/node.js.yml:
--------------------------------------------------------------------------------
1 | # This workflow will do a clean installation of node dependencies,
2 | # cache/restore them, build the source code and run tests across different
3 | # versions of node
4 | # For more information see:
5 | # https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
6 | ---
7 | name: Node.js CI
8 |
9 | on:
10 | push:
11 | branches:
12 | - master
13 | pull_request: null
14 |
15 | jobs:
16 | test:
17 |
18 | runs-on: ubuntu-latest
19 |
20 | strategy:
21 | matrix:
22 | node-version: [18.x, 20.x, 22.x]
23 | # See supported Node.js release schedule at:
24 | # https://nodejs.org/en/about/releases/
25 |
26 | steps:
27 | - uses: actions/checkout@v2
28 | with:
29 | submodules: true
30 | - name: Use Node.js ${{ matrix.node-version }}
31 | uses: actions/setup-node@v2
32 | with:
33 | node-version: ${{ matrix.node-version }}
34 | cache: 'npm'
35 | - run: npm clean-install
36 | - run: npm run build --if-present
37 | - run: npm test
38 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | ._*
4 | bower_components/
5 | .cache/
6 | .idea/
7 | playground/
8 | yarn-error.log
9 | examples/
10 | dist/index.html
11 | *.swp
12 | tags
13 | edit.sh
14 | usage.sh
15 | coverage/
16 | .parcel-cache/
17 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "core"]
2 | path = core
3 | url = https://github.com/mvanderkamp/westures-core
4 |
--------------------------------------------------------------------------------
/.ignore:
--------------------------------------------------------------------------------
1 | *.svg
2 | docs
3 | dist
4 | coverage
5 | node_modules
6 | bundle*
7 | package-lock.json
8 |
9 |
--------------------------------------------------------------------------------
/.jsdocrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "markdown": {
3 | "idInHeadings": true
4 | },
5 | "opts": {
6 | "destination": "docs/",
7 | "encoding": "utf8",
8 | "mainpagetitle": "Home | Westures Documentation",
9 | "package": "package.json",
10 | "readme": "README.md",
11 | "recurse": true,
12 | "template": "node_modules/docdash",
13 | "verbose": true
14 | },
15 | "plugins": [],
16 | "recurseDepth": 10,
17 | "source": {
18 | "include": [
19 | "core",
20 | "src",
21 | "index.js"
22 | ],
23 | "includePattern": ".js$",
24 | "exclude": [
25 | "core/dist",
26 | "core/docs",
27 | "core/node_modules",
28 | "core/test"
29 | ]
30 | },
31 | "sourceType": "module",
32 | "tags": {
33 | "allowUnknownTags": true,
34 | "dictionaries": ["jsdoc"]
35 | },
36 | "docdash": {
37 | "static": false,
38 | "sort": true,
39 | "meta": {
40 | "title": "Westures Documentation",
41 | "description": "Reference documentation for the Westures multitouch gesture library for JavaScript",
42 | "keyword": "javascript, multitouch, gesture"
43 | },
44 | "search": true,
45 | "collapse": true,
46 | "typedefs": true,
47 | "private": false,
48 | "removeQuotes": "trim",
49 | "ShortenTypes": true,
50 | "scopeInOutputPath": false,
51 | "nameInOutputPath": false,
52 | "versionInOutputPath": false
53 | }
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | # local script files
2 | edit.sh
3 | usage.sh
4 |
5 | # tag files
6 | tags
7 |
8 | # documentation
9 | docs
10 |
11 | # test related
12 | test
13 | coverage
14 |
15 | # development assist files
16 | Makefile
17 | arkit.*
18 | .*.json
19 | .cache
20 | .ignore
21 | .gitmodules
22 |
23 | # unneeded core-related files
24 | core/dist
25 | core/*.yml
26 | core/package-lock.json
27 | core/CHANGELOG.md
28 | core/README.md
29 |
30 | # build and development artifacts
31 | .parcel-cache/
32 | .travis.yml
33 | .coveralls.yml
34 | .github
35 |
36 | # Shouldn't have to exclude this, but here we are
37 | node_modules
38 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Changelog
2 |
3 | ## 1.1.0
4 |
5 | - Switch to docdash for documentation.
6 | - Update westures-core to 1.3.0. This introces a "headless" mode which allows westures to be run from a server.
7 |
8 | ## 1.0.0
9 |
10 | - Official first release! The engine is no longer considered to be in beta.
11 | - Refactor Smoothable to be a data type, not a mixin.
12 | - Remove the Binding class and integrate with the Gesture class. It was more of
13 | a hindrance than a help on its own.
14 | - Provide automatic detection of enabled and disabled gestures, including using
15 | keys to enable and disable, in a simple way such that gestures don't need to
16 | check if their enabled inside their hooks.
17 | - 'cancel' phase is now properly called.
18 | - Region class now takes an optional 'options' object instead of lots of
19 | arguments.
20 | - Remove the 'getProgressOfGesture' method from the Input class. Gestures should
21 | track their progress internally, on their own instance!
22 | - Remove the 'radius' property from the outgoing data. It didn't seem useful and
23 | was just cluttering the output.
24 | - Use Sets for tracking Gestures inside the Region instead of Arrays. (Faster
25 | access operations).
26 | - Update the Press gesture to allow multiple presses, one after the other, by
27 | adding successive inputs. Effectively makes it a multi-touch press! Single
28 | touch press is still possible using the min/maxInputs options!
29 | - Use a Pivotable base gesture type for Swivel and Pull.
30 | - Improved documentation by showing all of westures-core
31 | - Change pivotCenter -> dynamicPivot, default to false
32 | - Clean up Rotate implementation to reduce reliance on side effects
33 | - Switch to using pointer events by default, combined with setting touch-action:
34 | none on the gesture elements (not the region itself).
35 | - Provide options on the Region for choosing whether to prefer pointer events
36 | over mouse/touch events (preferPointer) and what to set the touch-action
37 | property to on gesture elements (touchAction).
38 | - Default to using the window as the region if no element provided.
39 | - Add mouseleave to the CANCEL_EVENTS
40 | - Include the core engine as a git submodule instead of relying on the npm package.
41 | - Keeps the core code out of node_modules which simplifies a lot of things...
42 | - Store all options in a consistent Gesture.options object
43 |
44 | ## 0.7.8
45 |
46 | - Add a Pull gesture. Pull is to Pinch as Swivel is to Rotate. In other words,
47 | the data is calculated relative to a fixed point, rather than relative to the
48 | other input points.
49 |
50 | ## 0.7.7
51 |
52 | - Simplify the Swivel class a bit.
53 |
54 | ## 0.7.6
55 |
56 | - Update dev support packages and switch to parcel-bundler for the distributable
57 | instead of browserify. This bundle is now found in the dist/ folder, along
58 | with a source map. Support for the old 'bundle.js' and 'bundle.min.js' is
59 | approximately maintained by providing two copies of 'dist/index.js' under
60 | those names. They will be removed in subsequent releases.
61 |
62 | ## 0.7.5
63 |
64 | - Improvements to the Press gesture. No longer fails as touches are added,
65 | supports layering of Presses. For example, you can have presses that respond
66 | to 1,2,3,... however many touches all attached to the same element, and they
67 | will each fire in turn as touches are added (but not as they are removed!).
68 | - [POSSIBLE BREAKING] The 'numInputs' option was renamed to 'minInputs'.
69 | - Remove confusing and unnceessary console.warn() statements from core engine.
70 |
71 | ## 0.7.4
72 |
73 | - Add a check that ensures smoothing will only ever be applied on devices that
74 | need it. That is, devices with 'coarse' pointers.
75 |
76 | ## 0.7.3
77 |
78 | - [POSSIBLE BREAKING] But only for those who have implemented their own
79 | Smoothable gesture with a non-zero identity value (e.g. Rotate has an identity
80 | of 0, as that represents no change, and Pinch has an identity of 1, as that
81 | represents no change). Such gestures will now need to declare their own
82 | identity value *after* calling super() in the constructor.
83 | - The smoothing algorithm used by the Smoothable mixin has been
84 | simplified. There is no delay to emits, as analysis of the data
85 | revealed this really only occurred for the first emit. Instead a
86 | simple rolling average is maintained.
87 | - Additionally, note that `this.smooth(data, field)` must be called instead
88 | of `this.emit(data, field)`
89 | - Add an experimental Press gesture.
90 |
91 | ## 0.7.2
92 |
93 | - Fix bug in gestures that used the Smoothable mixin which prevented their
94 | default 'smoothing' setting from being used.
95 | - Turn on smoothing by default in Pan.
96 |
97 | ## 0.7.1
98 |
99 | - Add `babelify` transform for `bundle.js`. Should add Edge support, and at the
100 | very least opens up the possibility of expanding browser support a bit.
101 |
102 | ## 0.7.0
103 |
104 | - Use new Smoothable mixin from `westures-core` for Pan, Pinch, Rotate, and
105 | Swivel. Set smoothing as enabled by default, except in Pan (may enable
106 | later...)
107 | - Place the `angularMinus` function into its own file, so that it can be used by
108 | both Rotate and Swivel.
109 | - Make Swivel multitouch-capable.
110 | - Change names of emitted data properties to be more idiomatic. 'rotation' for
111 | Rotate and Swivel instead of delta, 'scale' for Pinch and 'translation' for
112 | Pan instead of change.
113 | - Point2D#midpoint was renamed to Point2D#centroid
114 | - centroid and radius were added to base data for emits.
115 | - Preference is now given to data from the gesture over base data in the case of
116 | property name collisions.
117 |
118 | ## 0.6.3
119 |
120 | - Switch to simple average for Pinch and Rotate smoothing
121 | - This makes the smoothing more general, ensures a 60fps update rate is
122 | maintained, and generally has a nicer feel to it.
123 | - Downside is that there will be a bit of drift, but that's why this setting
124 | is optional!
125 |
126 | ## 0.6.2
127 |
128 | - Add optional smoothing to Pinch and Rotate (on by default).
129 |
130 | ## 0.6.1
131 |
132 | - Treat 'touchcancel' and 'pointercancel' the same way as 'blur'.
133 | - This is an unfortunate hack, necessitated by an apparent bug in Chrome,
134 | wherein only the _first_ (primary?) pointer will receive a 'cancel' event.
135 | The other's are cancelled, but no event is emitted. Their IDs are reused
136 | for subsequent pointers, making gesture state recoverable, but this is
137 | still not a good situation.
138 | - The downside is that this workaround means that if any single pointer is
139 | cancelled, _all_ of the pointers are treated as cancelled. I don't have
140 | enough in depth knowledge to say for sure, but I suspect that this doesn't
141 | have to be the case. If I have time soon I'll post a ticket to Chrome, at
142 | the very least to find out if this is actually a bug (my read of the spec
143 | tells me that it is).
144 | - The upside is that this should be pretty fail-safe, when combined with the
145 | 'blur' listener on the window.
146 |
147 | ## 0.6.0
148 |
149 | - Fix Tap bug preventing rapid taps.
150 | - 'ended' list wasn't being cleared on an emit, preventing further emits if
151 | taps came in rapid succession.
152 | - Expand default deadzone radius of Swivel.
153 | - Fix bugs in Swipe:
154 | - Make sure swipe state is reset on 'start' and after 'end' phases.
155 | - Prevent delayed emits if the user stops suddenly and doesn't move again
156 | before releasing the pointer.
157 | - [BREAKING CHANGE] Use inner fields instead of input progress.
158 | - Breaking because you can't reuse some of the Gesture objects the way you
159 | could previously.
160 | - Slightly more efficient, therefore preferable overall.
161 | - Rotate still uses input progress so that angle changes can be tracked on a
162 | per-input basis, which is more responsive than anything else I've tried so
163 | far.
164 |
165 | ## 0.5.4
166 |
167 | - Add 'cancel' phase support for touchcancel and pointercancel.
168 | - For most gestures, will probably be the same as 'end', but it must be
169 | different for gestures that emit on 'end'.
170 | - Add a 'blur' listener to window to reset the state when the window loses
171 | focus.
172 | - Fix Swivel bug in Edge: Edge doesn't provide 'x' and 'y' fields with
173 | 'getBoundingClientRect', so use 'left' and 'top' instead.
174 | - Make Swipes work for multitouch.
175 |
176 | ## 0.5.3
177 |
178 | - Fix buggy Swivel results caused by >1 active inputs.
179 | - Fix bugs in Swipe:
180 | - Erroneous acceptance of >1 inputs.
181 | - Velocity going to infinity in some cases (division by 0)
182 | - Direction calculation could produce errors, switched to using a more
183 | common mathematical approach.
184 | - Normalize Swipe a bit by taking average velocity instead of max.
185 |
186 | ## 0.5.2
187 |
188 | - Fix bug in Swivel when using the `pivotCenter` option. Initial angle wasn't
189 | being set correctly, causing jumps when initiating a Swivel.
190 |
191 | ## 0.5.0
192 |
193 | - Rename Region#bind() -> Region#addGesture() and Region#unbind() ->
194 | Region#removeGestures().
195 | - I was not happy with the way that the 'bind' naming clashes with the
196 | 'bind' function on the Function prototype.
197 | - Simplified "unbind" function. It now returns null, as the Bindings should not
198 | be exposed to the end user.
199 | - Sped up Binding selection in the Region's `arbitrate` function, while
200 | simultaneously fixing a critical bug!
201 | - Only the bindings associated with elements on the composed path of the
202 | first input to touch the surface will be accessed.
203 | - In other words, this batch of bindings is cached instead of being
204 | recalculated on every input event.
205 | - Previously, if the user started one input in one bound element, then
206 | another input in another bound element, the bindings for both elements
207 | would think they have full control, leading to some potentially weird
208 | behaviour.
209 | - If you want this behaviour, you'll now have to simulate it by creating a
210 | separate region for each binding.
211 | - Removed Region#getBindingsByInitialPos
212 | - Removed State#someInputWasInitiallyInside
213 | - Improved test coverage a bit
214 |
215 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright for portions of project Westures are held by ZingChart, 2016-2018 as
4 | part of project ZingTouch. All other copyright for project Westures are held by
5 | Michael van der Kamp, 2018.
6 |
7 | Permission is hereby granted, free of charge, to any person obtaining a copy
8 | of this software and associated documentation files (the "Software"), to deal
9 | in the Software without restriction, including without limitation the rights
10 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | copies of the Software, and to permit persons to whom the Software is
12 | furnished to do so, subject to the following conditions:
13 |
14 | The above copyright notice and this permission notice shall be included in all
15 | copies or substantial portions of the Software.
16 |
17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 | SOFTWARE.
24 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # westures
2 |
3 | [](https://github.com/mvanderkamp/westures/actions/workflows/node.js.yml)
4 | [](https://coveralls.io/github/mvanderkamp/westures?branch=master)
5 | [](https://codeclimate.com/github/mvanderkamp/westures/maintainability)
6 |
7 | Westures is a robust multitouch gesture engine for JavaScript. Each gesture is
8 | capable of working seamlessly as touch points are added and removed, with no
9 | limit on the number of touch points, and with each touch point contributing to
10 | the gesture.
11 |
12 | Visit this page for an example of the system in action: [Westures Example](
13 | https://mvanderkamp.github.io/westures-example/).
14 |
15 | The library achieves its goals without using any dependencies except for its
16 | own core, yet maintains usability across the main modern browsers.
17 | Transpilation may be necessary for this last point to be achieved, as the
18 | library is written using many of the newer features of the JavaScript language.
19 | A transpiled bundle is provided, but the browser target list is arbitrary and
20 | likely includes some bloat. In most cases you will be better off performing
21 | bundling, transpilation, and minification yourself.
22 |
23 | This module includes
24 | [westures-core](https://mvanderkamp.github.io/westures-core/)
25 | as well as a base set of gestures.
26 |
27 | Westures is a fork of [ZingTouch](https://github.com/zingchart/zingtouch).
28 |
29 | ## Quick Example
30 |
31 | ```javascript
32 | // Import the module.
33 | const wes = require('westures');
34 |
35 | // Declare a region. The default is the window object, but other elements like
36 | // the document body work too.
37 | const region = new wes.Region();
38 |
39 | // Combine an element and a handler into a Gesture.
40 | const pan = new wes.Pan(document.querySelector('#pannable'), (data) => {
41 | console.log(data.translation.x, data.translation.y);
42 | })
43 |
44 | // And add the gesture to the region.
45 | region.addGesture(pan)
46 | ```
47 |
48 | ## Table of Contents
49 |
50 | - [Overview](#overview)
51 | - [Basic Usage](#basic-usage)
52 | - [Implementing Custom Gestures](#implementing-custom-gestures)
53 | - [What's Changed](#changes)
54 | - [Nomenclature and Origins](#nomenclature-and-origins)
55 | - [Issues](#Issues)
56 | - [Links](#links)
57 |
58 | ## Overview
59 |
60 | There are nine gestures defined in this module:
61 |
62 | Name | # of Inputs | Emit Phase | Recognized Input Behaviour
63 | ------ | ----------- | ---------- | -----------------
64 | Pan | 1+ | Move | Sliding around the screen
65 | Pinch | 2+ | Move | Moving together or apart
66 | Press | 1+ | Move | Held down without moving
67 | Pull | 1+ | Move | Moving away from or toward a fixed point
68 | Rotate | 2+ | Move | Rotating around each other
69 | Swipe | 1+ | End | Moving quickly then released
70 | Swivel | 1+ | Move | Rotating around a fixed pivot point
71 | Tap | 1+ | End | Quickly pressing and releasing
72 | Track | 1+ | All | Track locations of all active pointers
73 |
74 | See the [documentation](https://mvanderkamp.github.io/westures/) for more
75 | information about each gesture.
76 |
77 | Note that all x,y positions are obtained from the corresponding `clientX` and
78 | `clientY` properties of the input event.
79 |
80 | ## Basic Usage
81 |
82 | - [Declaring a Region](#declaring-a-region)
83 | - [Instantiating a Gesture](#instantiating-a-gesture)
84 | - [Adding a Gesture to a Region](#adding-a-gesture-to-a-region)
85 |
86 | ### Importing the module
87 |
88 | ```javascript
89 | const wes = require('westures');
90 | ```
91 |
92 | ### Declaring a Region
93 |
94 | First, decide what region should listen for events. This could be the
95 | interactable element itself, or a larger region (possibly containing many
96 | interactable elements). Behaviour may differ slightly based on the approach you
97 | take, as a `Region` will perform locking operations on its interactable
98 | elements and their bound gestures so as to limit interference between elements
99 | during gestures, and no such locking occurs between Regions.
100 |
101 | If you have lots of interactable elements on your page, you may find it
102 | convenient to use smaller elements as regions. Test it out in case, and see what
103 | works better for you.
104 |
105 | By default, the window object is used.
106 |
107 | ```javascript
108 | const region = new wes.Region();
109 | ```
110 |
111 | ### Instantiating a Gesture
112 |
113 | When you instantiate a gesture, you need to provide a handler as well as an
114 | Element. The gesture will only be recognized when the first pointer to interact
115 | with the region was inside the given Element. Therefore unless you want to try
116 | something fancy the gesture element should probably be contained inside the
117 | region element. It could even be the region element.
118 |
119 | Now for an example. Suppose you have a div (id 'pannable', although this is
120 | irrelevant from Westures' perspective) within which you want to detect a Pan
121 | gesture. First we need to find the element.
122 |
123 | ```javascript
124 | const pannable = document.querySelector('#pannable');
125 | ```
126 |
127 | And we also need a handler. This function will be called whenever a gesture
128 | hook returns non-null data. For `Pan`, this is just the move phase, but the
129 | handler doesn't need to know that. The data returned by the hook will be
130 | available inside the handler.
131 |
132 | ```javascript
133 | function panLogger(data) {
134 | console.log(data.translation.x, data.translation.y);
135 | }
136 | ```
137 |
138 | Now we're ready to combine the element and its handler into a gesture.
139 |
140 | ```javascript
141 | pan = new wes.Pan(pannable, panLogger);
142 | ```
143 |
144 | We're not quite done though, as none of this will actually work until you add
145 | the gesture to the region.
146 |
147 | ### Adding a Gesture to a Region
148 |
149 | Simple:
150 |
151 | ```javascript
152 | region.addGesture(pan);
153 | ```
154 |
155 | Now the `panLogger` function will be called whenever a `pan` gesture is
156 | detected on the `#pannable` element inside the region.
157 |
158 | ## Implementing Custom Gestures
159 |
160 | The technique used by Westures (originally conceived for ZingTouch) is to
161 | filter all user inputs through four key lifecycle phases: `start`, `move`,
162 | `end`, and `cancel`. Gestures are defined by how they respond to these phases.
163 | To respond to the phases, a gesture extends the `Gesture` class provided by
164 | this module and overrides the method (a.k.a. "hook") corresponding to the name
165 | of the phase.
166 |
167 | The hook, when called, will receive the current `State` object of the region.
168 | To maintain responsiveness, the functionality within a hook should be short and
169 | as efficient as possible.
170 |
171 | For example, a simple way to implement a `Tap` gesture would be as follows:
172 |
173 | ```javascript
174 | const { Gesture } = require('westures');
175 |
176 | const TIMEOUT = 100;
177 |
178 | class Tap extends Gesture {
179 | constructor() {
180 | super('tap');
181 | this.startTime = null;
182 | }
183 |
184 | start(state) {
185 | this.startTime = Date.now();
186 | }
187 |
188 | end(state) {
189 | if (Date.now() - this.startTime <= TIMEOUT) {
190 | return state.getInputsInPhase('end')[0].current.point;
191 | }
192 | return null;
193 | }
194 | }
195 | ```
196 |
197 | There are problems with this example, and it should probably not be used as an
198 | actual Tap gesture, it is merely to illustrate the basic idea.
199 |
200 | The default hooks for all Gestures simply return null. Data will only be
201 | forwarded to bound handlers when a non-null value is returned by a hook.
202 | Returned values should be packed inside an object. For example, instead of just
203 | `return 42;`, a custom hook should do `return { value: 42 };`
204 |
205 | If your Gesture subclass needs to track any kind of complex state, remember that
206 | it may be necessary to reset the state in the `cancel` phase.
207 |
208 | For information about what data is accessible via the State object, see the full
209 | documentation [here](https://mvanderkamp.github.io/westures-core/State.html).
210 | Note that his documentation was generated with `jsdoc`.
211 |
212 | ### Data Passed to Handlers
213 |
214 | As you can see from above, it is the gesture which decides when data gets passed
215 | to handlers, and for the most part what that data will be. Note though that a
216 | few properties will get added to the outgoing data object before the handler is
217 | called. Those properties are:
218 |
219 | Name | Type | Value
220 | -------- | -------- | -----
221 | centroid | Point2D | The centroid of the input points.
222 | event | Event | The input event which caused the gesture to be recognized
223 | phase | String | `'start'`, `'move'`, `'end'`, or `'cancel'`
224 | type | String | The name of the gesture as specified by its designer.
225 | target | Element | The Element that is associated with the recognized gesture.
226 |
227 | If data properties returned by a hook have a name collision with one of these
228 | properties, the value from the hook gets precedent and the default is
229 | overwritten.
230 |
231 | ## Changes
232 |
233 | See the [changelog](
234 | https://github.com/mvanderkamp/westures/blob/master/CHANGELOG.md) for the most
235 | recent updates.
236 |
237 | ## Nomenclature and Origins
238 |
239 | In my last year of univerisity, I was working on an API for building
240 | multi-device interfaces called "WAMS" (Workspaces Across Multiple Surfaces),
241 | which included the goal of supporting multi-device gestures.
242 |
243 | After an extensive search I found that none of the available multitouch
244 | libraries for JavaScript provided the fidelity I needed, and concluded that I
245 | would need to write my own, or at least fork an existing one. ZingTouch proved
246 | to the be the most approachable, so I decided it would make a good starting
247 | point.
248 |
249 | The name "westures" is a mash-up of "WAMS" and "gestures".
250 |
251 | ## Issues
252 |
253 | If you find any issues, please let me know!
254 |
255 | ## Links
256 |
257 | ### westures
258 |
259 | - [npm](https://www.npmjs.com/package/westures)
260 | - [github](https://github.com/mvanderkamp/westures)
261 | - [documentation](https://mvanderkamp.github.io/westures/)
262 |
263 | ### westures-core
264 |
265 | - [npm](https://www.npmjs.com/package/westures-core)
266 | - [github](https://github.com/mvanderkamp/westures-core)
267 | - [documentation](https://mvanderkamp.github.io/westures-core/)
268 |
269 |
--------------------------------------------------------------------------------
/docs/core_index.js.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
125 |
126 |
127 |
128 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
--------------------------------------------------------------------------------
/docs/scripts/collapse.js:
--------------------------------------------------------------------------------
1 | function hideAllButCurrent(){
2 | //by default all submenut items are hidden
3 | //but we need to rehide them for search
4 | document.querySelectorAll("nav > ul").forEach(function(parent) {
5 | if (parent.className.indexOf("collapse_top") !== -1) {
6 | parent.style.display = "none";
7 | }
8 | });
9 | document.querySelectorAll("nav > ul > li > ul li").forEach(function(parent) {
10 | parent.style.display = "none";
11 | });
12 | document.querySelectorAll("nav > h3").forEach(function(section) {
13 | if (section.className.indexOf("collapsed_header") !== -1) {
14 | section.addEventListener("click", function(){
15 | if (section.nextSibling.style.display === "none") {
16 | section.nextSibling.style.display = "block";
17 | } else {
18 | section.nextSibling.style.display = "none";
19 | }
20 | });
21 | }
22 | });
23 |
24 | //only current page (if it exists) should be opened
25 | var file = window.location.pathname.split("/").pop().replace(/\.html/, '');
26 | document.querySelectorAll("nav > ul > li > a").forEach(function(parent) {
27 | var href = parent.attributes.href.value.replace(/\.html/, '');
28 | if (file === href) {
29 | if (parent.parentNode.parentNode.className.indexOf("collapse_top") !== -1) {
30 | parent.parentNode.parentNode.style.display = "block";
31 | }
32 | parent.parentNode.querySelectorAll("ul li").forEach(function(elem) {
33 | elem.style.display = "block";
34 | });
35 | }
36 | });
37 | }
38 |
39 | hideAllButCurrent();
--------------------------------------------------------------------------------
/docs/scripts/commonNav.js:
--------------------------------------------------------------------------------
1 | if (typeof fetch === 'function') {
2 | const init = () => {
3 | if (typeof scrollToNavItem !== 'function') return false
4 | scrollToNavItem()
5 | // hideAllButCurrent not always loaded
6 | if (typeof hideAllButCurrent === 'function') hideAllButCurrent()
7 | return true
8 | }
9 | fetch('./nav.inc.html')
10 | .then(response => response.ok ? response.text() : `${response.url} => ${response.status} ${response.statusText}`)
11 | .then(body => {
12 | document.querySelector('nav').innerHTML += body
13 | // nav.js should be quicker to load than nav.inc.html, a fallback just in case
14 | return init()
15 | })
16 | .then(done => {
17 | if (done) return
18 | let i = 0
19 | ;(function waitUntilNavJs () {
20 | if (init()) return
21 | if (i++ < 100) return setTimeout(waitUntilNavJs, 300)
22 | console.error(Error('nav.js not loaded after 30s waiting for it'))
23 | })()
24 | })
25 | .catch(error => console.error(error))
26 | } else {
27 | console.error(Error('Browser too old to display commonNav (remove commonNav docdash option)'))
28 | }
29 |
--------------------------------------------------------------------------------
/docs/scripts/linenumber.js:
--------------------------------------------------------------------------------
1 | /*global document */
2 | (function() {
3 | var source = document.getElementsByClassName('prettyprint source linenums');
4 | var i = 0;
5 | var lineNumber = 0;
6 | var lineId;
7 | var lines;
8 | var totalLines;
9 | var anchorHash;
10 |
11 | if (source && source[0]) {
12 | anchorHash = document.location.hash.substring(1);
13 | lines = source[0].getElementsByTagName('li');
14 | totalLines = lines.length;
15 |
16 | for (; i < totalLines; i++) {
17 | lineNumber++;
18 | lineId = 'line' + lineNumber;
19 | lines[i].id = lineId;
20 | if (lineId === anchorHash) {
21 | lines[i].className += ' selected';
22 | }
23 | }
24 | }
25 | })();
26 |
--------------------------------------------------------------------------------
/docs/scripts/nav.js:
--------------------------------------------------------------------------------
1 | function scrollToNavItem() {
2 | var path = window.location.href.split('/').pop().replace(/\.html/, '');
3 | document.querySelectorAll('nav a').forEach(function(link) {
4 | var href = link.attributes.href.value.replace(/\.html/, '');
5 | if (path === href) {
6 | link.scrollIntoView({block: 'center'});
7 | return;
8 | }
9 | })
10 | }
11 |
12 | scrollToNavItem();
13 |
--------------------------------------------------------------------------------
/docs/scripts/polyfill.js:
--------------------------------------------------------------------------------
1 | //IE Fix, src: https://www.reddit.com/r/programminghorror/comments/6abmcr/nodelist_lacks_foreach_in_internet_explorer/
2 | if (typeof(NodeList.prototype.forEach)!==typeof(alert)){
3 | NodeList.prototype.forEach=Array.prototype.forEach;
4 | }
--------------------------------------------------------------------------------
/docs/scripts/prettify/Apache-License-2.0.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/docs/scripts/prettify/lang-css.js:
--------------------------------------------------------------------------------
1 | PR.registerLangHandler(PR.createSimpleLexer([["pln",/^[\t\n\f\r ]+/,null," \t\r\n"]],[["str",/^"(?:[^\n\f\r"\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*"/,null],["str",/^'(?:[^\n\f\r'\\]|\\(?:\r\n?|\n|\f)|\\[\S\s])*'/,null],["lang-css-str",/^url\(([^"')]*)\)/i],["kwd",/^(?:url|rgb|!important|@import|@page|@media|@charset|inherit)(?=[^\w-]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*)\s*:/i],["com",/^\/\*[^*]*\*+(?:[^*/][^*]*\*+)*\//],["com",
2 | /^(?:<\!--|--\>)/],["lit",/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],["lit",/^#[\da-f]{3,6}/i],["pln",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i],["pun",/^[^\s\w"']+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[["kwd",/^-?(?:[_a-z]|\\[\da-f]+ ?)(?:[\w-]|\\\\[\da-f]+ ?)*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[["str",/^[^"')]+/]]),["css-str"]);
3 |
--------------------------------------------------------------------------------
/docs/scripts/prettify/prettify.js:
--------------------------------------------------------------------------------
1 | var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
2 | (function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
3 | [],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;ci[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
9 | l=[],p={},d=0,g=e.length;d=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
10 | q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
11 | q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
12 | "");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
13 | a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
14 | for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
18 | "catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"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,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
19 | H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,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"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"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"],
20 | J=[v,"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"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"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"+
21 | I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^]+/],["dec",/^]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^