├── .editorconfig ├── .gitignore ├── LICENSE ├── README.md ├── analysis.json ├── demo ├── demo-icons.js └── index.html ├── index.html ├── package-lock.json ├── package.json ├── payment-address.js ├── payment-item.js ├── payment-method.js ├── payment-request.js ├── payment-shipping-option.js └── test ├── index.html └── payment-request_test.html /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # http://editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | # Change these settings to your own preference 9 | indent_style = space 10 | indent_size = 2 11 | 12 | # We recommend you to keep these unchanged 13 | end_of_line = lf 14 | charset = utf-8 15 | trim_trailing_whitespace = true 16 | insert_final_newline = true 17 | 18 | [*.md] 19 | trim_trailing_whitespace = false 20 | indent_style = tab 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | bower_components 2 | *.pem 3 | 4 | node_modules 5 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Jorge del Casar 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Published on webcomponents.org](https://img.shields.io/badge/webcomponents.org-published-blue.svg)](https://www.webcomponents.org/element/jorgecasar/payment-request) 2 | 3 | 4 | # \ API component 5 | 6 | [Payment Request API](https://w3c.github.io/browser-payment-api/) web component build with using Polymer. You can take a look the [demo page](https://jorgecasar.github.io/payment-request/components/payment-request/demo/) to see how it works. 7 | 8 | **Note:** It isn't supported by all browser, check [Payment Request API browser support](http://caniuse.com/#feat=payment-request). 9 | 10 | ## Installation 11 | 12 | Install the component using [Bower](http://bower.io/): 13 | 14 | ```sh 15 | $ bower install payment-request --save 16 | ``` 17 | 18 | Or [download as ZIP](https://github.com/jorgecasar/payment-request/archive/master.zip). 19 | 20 | ## Usage 21 | 22 | 1. Import Web Components' polyfill and Payment Request API shim: 23 | 24 | ```html 25 | 26 | 27 | ``` 28 | 29 | 2. Import Custom Elements: 30 | 31 | ```html 32 | 33 | ``` 34 | 35 | 3. Start using it! 36 | 37 | ```html 38 | 39 | 43 | 44 | 45 | 46 | ``` 47 | 48 | 4. Validate payment data and complete payment request. 49 | 50 | ```javascript 51 | function onLastResponseChange(evt) { 52 | var paymentResponse = evt.detail.value; 53 | // Make your request to server for a real purchase. 54 | // Complete the paymnet. 55 | // More info: https://www.w3.org/TR/payment-request/#complete-method 56 | paymentResponse.complete('success'); 57 | } 58 | var paymentRequestElement = document.querySelector('payment-request'); 59 | paymentRequestElement.addEventListener('last-response-change', onLastResponseChange); 60 | ``` 61 | 62 | ## Viewing component docs & demo 63 | 64 | First, make sure you have the [polymer-serve](https://www.npmjs.com/package/polymer-serve) installed and serve the component: 65 | 66 | ``` 67 | $ polyserve --protocol https/1.1 68 | ``` 69 | 70 | ## Running Tests 71 | 72 | ``` 73 | $ polymer test 74 | ``` 75 | 76 | Your application is already set up to be tested via [web-component-tester](https://github.com/Polymer/web-component-tester). Run `polymer test` to run your application's test suite locally. 77 | 78 | ## Contributing 79 | 80 | 1. Fork it! 81 | 2. Create your feature branch: `git checkout -b my-new-feature` 82 | 3. Commit your changes: `git commit -am 'Add some feature'` 83 | 4. Push to the branch: `git push origin my-new-feature` 84 | 5. Submit a pull request :D 85 | 86 | ## History 87 | 88 | 89 | ## Credits 90 | 91 | - [Payment Request API](https://w3c.github.io/browser-payment-api/) 92 | - [ 93 | Payment Request API: an Integration Guide](https://developers.google.com/web/fundamentals/discovery-and-monetization/payment-request/) 94 | 95 | ## License 96 | 97 | [MIT License](https://opensource.org/licenses/MIT) 98 | -------------------------------------------------------------------------------- /demo/demo-icons.js: -------------------------------------------------------------------------------- 1 | import '@polymer/iron-icon/iron-icon.js'; 2 | import '@polymer/iron-iconset-svg/iron-iconset-svg.js'; 3 | const $_documentContainer = document.createElement('template'); 4 | 5 | $_documentContainer.innerHTML = ` 6 | 7 | 8 | 9 | 10 | 11 | `; 12 | 13 | document.head.appendChild($_documentContainer.content); 14 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | payment-request demo 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 75 | 76 | 77 | 78 | 79 | 150 | 151 | 152 | 198 | 199 | 200 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | payment-request 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "payment-request", 3 | "version": "2.0.0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@polymer/app-layout": { 8 | "version": "3.0.1", 9 | "resolved": "https://registry.npmjs.org/@polymer/app-layout/-/app-layout-3.0.1.tgz", 10 | "integrity": "sha512-Uf4gys9GSH69glSrKl7fsSeM0qeyfzat6tkym4WdZNdnLWou4sOxnAlF0Jg3ets1mumUo2U4/zVcUhPH9LJE+g==", 11 | "dev": true, 12 | "requires": { 13 | "@polymer/iron-flex-layout": "^3.0.0-pre.26", 14 | "@polymer/iron-media-query": "^3.0.0-pre.26", 15 | "@polymer/iron-resizable-behavior": "^3.0.0-pre.26", 16 | "@polymer/iron-scroll-target-behavior": "^3.0.0-pre.26", 17 | "@polymer/polymer": "^3.0.0" 18 | } 19 | }, 20 | "@polymer/font-roboto": { 21 | "version": "3.0.2", 22 | "resolved": "https://registry.npmjs.org/@polymer/font-roboto/-/font-roboto-3.0.2.tgz", 23 | "integrity": "sha512-tx5TauYSmzsIvmSqepUPDYbs4/Ejz2XbZ1IkD7JEGqkdNUJlh+9KU85G56Tfdk/xjEZ8zorFfN09OSwiMrIQWA==", 24 | "dev": true 25 | }, 26 | "@polymer/iron-a11y-announcer": { 27 | "version": "3.0.1", 28 | "resolved": "https://registry.npmjs.org/@polymer/iron-a11y-announcer/-/iron-a11y-announcer-3.0.1.tgz", 29 | "integrity": "sha512-Xiqmpz0AEEbMNGYPpbrXBIrcI/xaR4tn77pmSLfxVKGGwjEUR/YrRgyIwXp4EN7lvst1dFC8kyl2hLga0uDIVQ==", 30 | "dev": true, 31 | "requires": { 32 | "@polymer/polymer": "^3.0.0" 33 | } 34 | }, 35 | "@polymer/iron-a11y-keys-behavior": { 36 | "version": "3.0.1", 37 | "resolved": "https://registry.npmjs.org/@polymer/iron-a11y-keys-behavior/-/iron-a11y-keys-behavior-3.0.1.tgz", 38 | "integrity": "sha512-lnrjKq3ysbBPT/74l0Fj0U9H9C35Tpw2C/tpJ8a+5g8Y3YJs1WSZYnEl1yOkw6sEyaxOq/1DkzH0+60gGu5/PQ==", 39 | "dev": true, 40 | "requires": { 41 | "@polymer/polymer": "^3.0.0" 42 | } 43 | }, 44 | "@polymer/iron-ajax": { 45 | "version": "3.0.1", 46 | "resolved": "https://registry.npmjs.org/@polymer/iron-ajax/-/iron-ajax-3.0.1.tgz", 47 | "integrity": "sha512-7+TPEAfWsRdhj1Y8UeF1759ktpVu+c3sG16rJiUC3wF9+woQ9xI1zUm2d59i7Yc3aDEJrR/Q8Y262KlOvyGVNg==", 48 | "dev": true, 49 | "requires": { 50 | "@polymer/polymer": "^3.0.0" 51 | } 52 | }, 53 | "@polymer/iron-behaviors": { 54 | "version": "3.0.1", 55 | "resolved": "https://registry.npmjs.org/@polymer/iron-behaviors/-/iron-behaviors-3.0.1.tgz", 56 | "integrity": "sha512-IMEwcv1lhf1HSQxuyWOUIL0lOBwmeaoSTpgCJeP9IBYnuB1SPQngmfRuHKgK6/m9LQ9F9miC7p3HeQQUdKAE0w==", 57 | "dev": true, 58 | "requires": { 59 | "@polymer/iron-a11y-keys-behavior": "^3.0.0-pre.26", 60 | "@polymer/polymer": "^3.0.0" 61 | } 62 | }, 63 | "@polymer/iron-checked-element-behavior": { 64 | "version": "3.0.1", 65 | "resolved": "https://registry.npmjs.org/@polymer/iron-checked-element-behavior/-/iron-checked-element-behavior-3.0.1.tgz", 66 | "integrity": "sha512-aDr0cbCNVq49q+pOqa6CZutFh+wWpwPMLpEth9swx+GkAj+gCURhuQkaUYhIo5f2egDbEioR1aeHMnPlU9dQZA==", 67 | "dev": true, 68 | "requires": { 69 | "@polymer/iron-form-element-behavior": "^3.0.0-pre.26", 70 | "@polymer/iron-validatable-behavior": "^3.0.0-pre.26", 71 | "@polymer/polymer": "^3.0.0" 72 | } 73 | }, 74 | "@polymer/iron-component-page": { 75 | "version": "4.0.1", 76 | "resolved": "https://registry.npmjs.org/@polymer/iron-component-page/-/iron-component-page-4.0.1.tgz", 77 | "integrity": "sha512-4ZLhMjCYPA/hTghv03tR283uJFCif+3xiayYJzoTjTLZgJ6hS5ApU/JijmE3yQDaLJ0ZsfciA0Xt73cmd5cwvQ==", 78 | "dev": true, 79 | "requires": { 80 | "@polymer/app-layout": "^3.0.0-pre.26", 81 | "@polymer/iron-ajax": "^3.0.0-pre.26", 82 | "@polymer/iron-doc-viewer": "^4.0.0-pre.4", 83 | "@polymer/iron-icons": "^3.0.0-pre.26", 84 | "@polymer/paper-icon-button": "^3.0.0-pre.26", 85 | "@polymer/paper-styles": "^3.0.0-pre.26", 86 | "@polymer/paper-toast": "^3.0.0-pre.26", 87 | "@polymer/polymer": "^3.0.0" 88 | } 89 | }, 90 | "@polymer/iron-demo-helpers": { 91 | "version": "3.0.2", 92 | "resolved": "https://registry.npmjs.org/@polymer/iron-demo-helpers/-/iron-demo-helpers-3.0.2.tgz", 93 | "integrity": "sha512-VqGEIOEXPgx9G6uLfvnzXVib6sE6lJENV3gywoBTstrMCrFCSGpmTMVAovpHyoDw8Ceu6LeoVuMsxaT1mCEirg==", 94 | "dev": true, 95 | "requires": { 96 | "@polymer/font-roboto": "^3.0.0-pre.25", 97 | "@polymer/iron-flex-layout": "^3.0.0-pre.25", 98 | "@polymer/iron-location": "^3.0.0-pre.25", 99 | "@polymer/marked-element": "^3.0.0-pre.25", 100 | "@polymer/polymer": "^3.0.0", 101 | "@polymer/prism-element": "^3.0.0-pre.25" 102 | } 103 | }, 104 | "@polymer/iron-doc-viewer": { 105 | "version": "4.0.1", 106 | "resolved": "https://registry.npmjs.org/@polymer/iron-doc-viewer/-/iron-doc-viewer-4.0.1.tgz", 107 | "integrity": "sha512-3tyJwSxvHxPuwvxE1FILNHqBPFytoZlp3tQ5iGu4iFE2uoLE1RoENU7SG6K98K5BFq8unfCrMS5GjzVGt+nW/Q==", 108 | "dev": true, 109 | "requires": { 110 | "@polymer/iron-location": "^3.0.0-pre.26", 111 | "@polymer/marked-element": "^3.0.0-pre.26", 112 | "@polymer/paper-styles": "^3.0.0-pre.26", 113 | "@polymer/polymer": "^3.0.0", 114 | "@polymer/prism-element": "^3.0.0-pre.26" 115 | } 116 | }, 117 | "@polymer/iron-fit-behavior": { 118 | "version": "3.0.1", 119 | "resolved": "https://registry.npmjs.org/@polymer/iron-fit-behavior/-/iron-fit-behavior-3.0.1.tgz", 120 | "integrity": "sha512-/M0B1L30k31vmwNBaGuZcxzUAhJSHoGccb/DF0CDKI/hT8UlkTvcyemaWdOpmHHLgY52ceKIkRwA3AeXrKyvaQ==", 121 | "dev": true, 122 | "requires": { 123 | "@polymer/polymer": "^3.0.0" 124 | } 125 | }, 126 | "@polymer/iron-flex-layout": { 127 | "version": "3.0.1", 128 | "resolved": "https://registry.npmjs.org/@polymer/iron-flex-layout/-/iron-flex-layout-3.0.1.tgz", 129 | "integrity": "sha512-7gB869czArF+HZcPTVSgvA7tXYFze9EKckvM95NB7SqYF+NnsQyhoXgKnpFwGyo95lUjUW9TFDLUwDXnCYFtkw==", 130 | "dev": true, 131 | "requires": { 132 | "@polymer/polymer": "^3.0.0" 133 | } 134 | }, 135 | "@polymer/iron-form-element-behavior": { 136 | "version": "3.0.1", 137 | "resolved": "https://registry.npmjs.org/@polymer/iron-form-element-behavior/-/iron-form-element-behavior-3.0.1.tgz", 138 | "integrity": "sha512-G/e2KXyL5AY7mMjmomHkGpgS0uAf4ovNpKhkuUTRnMuMJuf589bKqE85KN4ovE1Tzhv2hJoh/igyD6ekHiYU1A==", 139 | "dev": true, 140 | "requires": { 141 | "@polymer/polymer": "^3.0.0" 142 | } 143 | }, 144 | "@polymer/iron-icon": { 145 | "version": "3.0.1", 146 | "resolved": "https://registry.npmjs.org/@polymer/iron-icon/-/iron-icon-3.0.1.tgz", 147 | "integrity": "sha512-QLPwirk+UPZNaLnMew9VludXA4CWUCenRewgEcGYwdzVgDPCDbXxy6vRJjmweZobMQv/oVLppT2JZtJFnPxX6g==", 148 | "dev": true, 149 | "requires": { 150 | "@polymer/iron-flex-layout": "^3.0.0-pre.26", 151 | "@polymer/iron-meta": "^3.0.0-pre.26", 152 | "@polymer/polymer": "^3.0.0" 153 | } 154 | }, 155 | "@polymer/iron-icons": { 156 | "version": "3.0.1", 157 | "resolved": "https://registry.npmjs.org/@polymer/iron-icons/-/iron-icons-3.0.1.tgz", 158 | "integrity": "sha512-xtEI8erH2GIBiF3QxEMyW81XuVjguu6Le5WjEEpX67qd9z7jjmc4T/ke3zRUlnDydex9p8ytcwVpMIKcyvjYAQ==", 159 | "dev": true, 160 | "requires": { 161 | "@polymer/iron-icon": "^3.0.0-pre.26", 162 | "@polymer/iron-iconset-svg": "^3.0.0-pre.26", 163 | "@polymer/polymer": "^3.0.0" 164 | } 165 | }, 166 | "@polymer/iron-iconset-svg": { 167 | "version": "3.0.1", 168 | "resolved": "https://registry.npmjs.org/@polymer/iron-iconset-svg/-/iron-iconset-svg-3.0.1.tgz", 169 | "integrity": "sha512-XNwURbNHRw6u2fJe05O5fMYye6GSgDlDqCO+q6K1zAnKIrpgZwf2vTkBd5uCcZwsN0FyCB3mvNZx4jkh85dRDw==", 170 | "dev": true, 171 | "requires": { 172 | "@polymer/iron-meta": "^3.0.0-pre.26", 173 | "@polymer/polymer": "^3.0.0" 174 | } 175 | }, 176 | "@polymer/iron-location": { 177 | "version": "3.0.1", 178 | "resolved": "https://registry.npmjs.org/@polymer/iron-location/-/iron-location-3.0.1.tgz", 179 | "integrity": "sha512-almb+p/fdSi4bxG+vyXjY51fDZxHMxwiug51Lfvr86wZRXN/u21Y6BapxG5n9f0hPSy9fimjIAvaYmozi7VjyQ==", 180 | "dev": true, 181 | "requires": { 182 | "@polymer/polymer": "^3.0.0" 183 | } 184 | }, 185 | "@polymer/iron-media-query": { 186 | "version": "3.0.1", 187 | "resolved": "https://registry.npmjs.org/@polymer/iron-media-query/-/iron-media-query-3.0.1.tgz", 188 | "integrity": "sha512-czUX1pm1zfmfcZtq5J57XFkcobBv08Y50exp0/3v8Bos5VL/jv2tU0RwiTfDBxUMhjicGbgwEBFQPY2V5DMzyw==", 189 | "dev": true, 190 | "requires": { 191 | "@polymer/polymer": "^3.0.0" 192 | } 193 | }, 194 | "@polymer/iron-menu-behavior": { 195 | "version": "3.0.1", 196 | "resolved": "https://registry.npmjs.org/@polymer/iron-menu-behavior/-/iron-menu-behavior-3.0.1.tgz", 197 | "integrity": "sha512-yIIBopb9ZaJBzvk20OFRaAXuTEuBw8d19Ja7r0Rfc3sTMt73UHGccBBeH51wCLLhQzNEBfwaQKOGg4INhl3unw==", 198 | "dev": true, 199 | "requires": { 200 | "@polymer/iron-a11y-keys-behavior": "^3.0.0-pre.26", 201 | "@polymer/iron-flex-layout": "^3.0.0-pre.26", 202 | "@polymer/iron-selector": "^3.0.0-pre.26", 203 | "@polymer/polymer": "^3.0.0" 204 | } 205 | }, 206 | "@polymer/iron-meta": { 207 | "version": "3.0.1", 208 | "resolved": "https://registry.npmjs.org/@polymer/iron-meta/-/iron-meta-3.0.1.tgz", 209 | "integrity": "sha512-pWguPugiLYmWFV9UWxLWzZ6gm4wBwQdDy4VULKwdHCqR7OP7u98h+XDdGZsSlDPv6qoryV/e3tGHlTIT0mbzJA==", 210 | "dev": true, 211 | "requires": { 212 | "@polymer/polymer": "^3.0.0" 213 | } 214 | }, 215 | "@polymer/iron-overlay-behavior": { 216 | "version": "3.0.2", 217 | "resolved": "https://registry.npmjs.org/@polymer/iron-overlay-behavior/-/iron-overlay-behavior-3.0.2.tgz", 218 | "integrity": "sha512-j1qmt6mJHCwpe1mKOvqK5kcCUPQr5LSrlqpgRDbUuLgUfNJ/vGTipjrkBlfbEUagm5FEQdc1VLPLSQP6WVuP9g==", 219 | "dev": true, 220 | "requires": { 221 | "@polymer/iron-a11y-keys-behavior": "^3.0.0-pre.26", 222 | "@polymer/iron-fit-behavior": "^3.0.0-pre.26", 223 | "@polymer/iron-resizable-behavior": "^3.0.0-pre.26", 224 | "@polymer/polymer": "^3.0.0" 225 | } 226 | }, 227 | "@polymer/iron-resizable-behavior": { 228 | "version": "3.0.1", 229 | "resolved": "https://registry.npmjs.org/@polymer/iron-resizable-behavior/-/iron-resizable-behavior-3.0.1.tgz", 230 | "integrity": "sha512-FyHxRxFspVoRaeZSWpT3y0C9awomb4tXXolIJcZ7RvXhMP632V5lez+ch5G5SwK0LpnAPkg35eB0LPMFv+YMMQ==", 231 | "dev": true, 232 | "requires": { 233 | "@polymer/polymer": "^3.0.0" 234 | } 235 | }, 236 | "@polymer/iron-scroll-target-behavior": { 237 | "version": "3.0.1", 238 | "resolved": "https://registry.npmjs.org/@polymer/iron-scroll-target-behavior/-/iron-scroll-target-behavior-3.0.1.tgz", 239 | "integrity": "sha512-xg1WanG25BIkQE8rhuReqY9zx1K5M7F+YAIYpswEp5eyDIaZ1Y3vUmVeQ3KG+hiSugzI1M752azXN7kvyhOBcQ==", 240 | "dev": true, 241 | "requires": { 242 | "@polymer/polymer": "^3.0.0" 243 | } 244 | }, 245 | "@polymer/iron-selector": { 246 | "version": "3.0.1", 247 | "resolved": "https://registry.npmjs.org/@polymer/iron-selector/-/iron-selector-3.0.1.tgz", 248 | "integrity": "sha512-sBVk2uas6prW0glUe2xEJJYlvxmYzM40Au9OKbfDK2Qekou/fLKcBRyIYI39kuI8zWRaip8f3CI8qXcUHnKb1A==", 249 | "requires": { 250 | "@polymer/polymer": "^3.0.0" 251 | } 252 | }, 253 | "@polymer/iron-validatable-behavior": { 254 | "version": "3.0.1", 255 | "resolved": "https://registry.npmjs.org/@polymer/iron-validatable-behavior/-/iron-validatable-behavior-3.0.1.tgz", 256 | "integrity": "sha512-wwpYh6wOa4fNI+jH5EYKC7TVPYQ2OfgQqocWat7GsNWcsblKYhLYbwsvEY5nO0n2xKqNfZzDLrUom5INJN7msQ==", 257 | "dev": true, 258 | "requires": { 259 | "@polymer/iron-meta": "^3.0.0-pre.26", 260 | "@polymer/polymer": "^3.0.0" 261 | } 262 | }, 263 | "@polymer/marked-element": { 264 | "version": "3.0.1", 265 | "resolved": "https://registry.npmjs.org/@polymer/marked-element/-/marked-element-3.0.1.tgz", 266 | "integrity": "sha512-WJQzQetxdStVGQbyTBUBgd+hSI0Rl39uJg7b2zL3r6EfMnibzmA/YNT06M8jVZdxPF+B4SumrFWRtasVtGQRUQ==", 267 | "dev": true, 268 | "requires": { 269 | "@polymer/polymer": "^3.0.0", 270 | "marked": "~0.3.9" 271 | } 272 | }, 273 | "@polymer/paper-behaviors": { 274 | "version": "3.0.1", 275 | "resolved": "https://registry.npmjs.org/@polymer/paper-behaviors/-/paper-behaviors-3.0.1.tgz", 276 | "integrity": "sha512-6knhj69fPJejv8qR0kCSUY+Q0XjaUf0OSnkjRjmTJPAwSrRYtgqE+l6P1FfA+py1X/cUjgne9EF5rMZAKJIg1g==", 277 | "dev": true, 278 | "requires": { 279 | "@polymer/iron-behaviors": "^3.0.0-pre.26", 280 | "@polymer/iron-checked-element-behavior": "^3.0.0-pre.26", 281 | "@polymer/paper-ripple": "^3.0.0-pre.26", 282 | "@polymer/polymer": "^3.0.0" 283 | } 284 | }, 285 | "@polymer/paper-button": { 286 | "version": "3.0.1", 287 | "resolved": "https://registry.npmjs.org/@polymer/paper-button/-/paper-button-3.0.1.tgz", 288 | "integrity": "sha512-JRNBc+Oj9EWnmyLr7FcCr8T1KAnEHPh6mosln9BUdkM+qYaYsudSICh3cjTIbnj6AuF5OJidoLkM1dlyj0j6Zg==", 289 | "dev": true, 290 | "requires": { 291 | "@polymer/iron-flex-layout": "^3.0.0-pre.26", 292 | "@polymer/paper-behaviors": "^3.0.0-pre.27", 293 | "@polymer/paper-styles": "^3.0.0-pre.26", 294 | "@polymer/polymer": "^3.0.0" 295 | } 296 | }, 297 | "@polymer/paper-icon-button": { 298 | "version": "3.0.1", 299 | "resolved": "https://registry.npmjs.org/@polymer/paper-icon-button/-/paper-icon-button-3.0.1.tgz", 300 | "integrity": "sha512-iGzCargoYI2yOgedwTvT3kt4bMUsgGzITakPYx1qN1v6xiOAr67Zf/tp2JKqqdtyySDsJYck9o4FLf4ymvZJoA==", 301 | "dev": true, 302 | "requires": { 303 | "@polymer/iron-icon": "^3.0.0-pre.26", 304 | "@polymer/paper-behaviors": "^3.0.0-pre.27", 305 | "@polymer/paper-styles": "^3.0.0-pre.26", 306 | "@polymer/polymer": "^3.0.0" 307 | } 308 | }, 309 | "@polymer/paper-item": { 310 | "version": "3.0.1", 311 | "resolved": "https://registry.npmjs.org/@polymer/paper-item/-/paper-item-3.0.1.tgz", 312 | "integrity": "sha512-KTk2N+GsYiI/HuubL3sxebZ6tteQbBOAp4QVLAnbjSPmwl+mJSDWk+omuadesU0bpkCwaWVs3fHuQsmXxy4pkw==", 313 | "dev": true, 314 | "requires": { 315 | "@polymer/iron-behaviors": "^3.0.0-pre.26", 316 | "@polymer/iron-flex-layout": "^3.0.0-pre.26", 317 | "@polymer/paper-styles": "^3.0.0-pre.26", 318 | "@polymer/polymer": "^3.0.0" 319 | } 320 | }, 321 | "@polymer/paper-listbox": { 322 | "version": "3.0.1", 323 | "resolved": "https://registry.npmjs.org/@polymer/paper-listbox/-/paper-listbox-3.0.1.tgz", 324 | "integrity": "sha512-vMLWFpYcggAPmEDBmK+96fFefacOG3GLB1EguTn8+ZkqI+328hNfw1MzHjH68rgCIIUtjmm+9qgB1Sy/MN0a/A==", 325 | "dev": true, 326 | "requires": { 327 | "@polymer/iron-behaviors": "^3.0.0-pre.26", 328 | "@polymer/iron-menu-behavior": "^3.0.0-pre.26", 329 | "@polymer/paper-styles": "^3.0.0-pre.26", 330 | "@polymer/polymer": "^3.0.0" 331 | } 332 | }, 333 | "@polymer/paper-ripple": { 334 | "version": "3.0.1", 335 | "resolved": "https://registry.npmjs.org/@polymer/paper-ripple/-/paper-ripple-3.0.1.tgz", 336 | "integrity": "sha512-dgOe12GyCF1VZBLUQqnzGWlf3xb255FajNCVB1VFj/AtskYtoamnafa7m3a+1vs+C8qbg4Benn5KwgxVDSW4cg==", 337 | "dev": true, 338 | "requires": { 339 | "@polymer/iron-a11y-keys-behavior": "^3.0.0-pre.26", 340 | "@polymer/polymer": "^3.0.0" 341 | } 342 | }, 343 | "@polymer/paper-styles": { 344 | "version": "3.0.1", 345 | "resolved": "https://registry.npmjs.org/@polymer/paper-styles/-/paper-styles-3.0.1.tgz", 346 | "integrity": "sha512-y6hmObLqlCx602TQiSBKHqjwkE7xmDiFkoxdYGaNjtv4xcysOTdVJsDR/R9UHwIaxJ7gHlthMSykir1nv78++g==", 347 | "dev": true, 348 | "requires": { 349 | "@polymer/font-roboto": "^3.0.1", 350 | "@polymer/iron-flex-layout": "^3.0.0-pre.26", 351 | "@polymer/polymer": "^3.0.0" 352 | } 353 | }, 354 | "@polymer/paper-toast": { 355 | "version": "3.0.1", 356 | "resolved": "https://registry.npmjs.org/@polymer/paper-toast/-/paper-toast-3.0.1.tgz", 357 | "integrity": "sha512-pizuogzObniDdICUc6dSLrnDt2VzzoRne1gCmbD6sfOATVv5tc8UfrqhA2iHngbNBEbniBiciS3iogdp5KTVUQ==", 358 | "dev": true, 359 | "requires": { 360 | "@polymer/iron-a11y-announcer": "^3.0.0-pre.26", 361 | "@polymer/iron-fit-behavior": "^3.0.0-pre.26", 362 | "@polymer/iron-overlay-behavior": "^3.0.0-pre.27", 363 | "@polymer/polymer": "^3.0.0" 364 | } 365 | }, 366 | "@polymer/paper-toolbar": { 367 | "version": "3.0.1", 368 | "resolved": "https://registry.npmjs.org/@polymer/paper-toolbar/-/paper-toolbar-3.0.1.tgz", 369 | "integrity": "sha512-tEdHRorVmnN3kvJg3xxRPnEiEBdGmGwcDNbIcYuXxoRDF0nAB74SW5+He8OlFT1Lw2Hz/xlvMn+wHuqxIJeyQw==", 370 | "dev": true, 371 | "requires": { 372 | "@polymer/iron-flex-layout": "^3.0.0-pre.26", 373 | "@polymer/paper-styles": "^3.0.0-pre.26", 374 | "@polymer/polymer": "^3.0.0" 375 | } 376 | }, 377 | "@polymer/polymer": { 378 | "version": "3.1.0", 379 | "resolved": "https://registry.npmjs.org/@polymer/polymer/-/polymer-3.1.0.tgz", 380 | "integrity": "sha512-hwN8IMERsFATz/9dSMxYHL+84J9uBkPuuarxJWlTsppZ4CAYTZKnepBfNrKoyNsafBmA3yXBiiKPPf+fJtza7A==", 381 | "requires": { 382 | "@webcomponents/shadycss": "^1.5.2" 383 | } 384 | }, 385 | "@polymer/prism-element": { 386 | "version": "3.0.1", 387 | "resolved": "https://registry.npmjs.org/@polymer/prism-element/-/prism-element-3.0.1.tgz", 388 | "integrity": "sha512-mam3oZZwVoxmC8i2srCxaTsvCqZF2HX4yxbm1JN9OGZS2JMwu7bnjjk7O8haoj9u6w+ocUi+vTLjYeIIoPx7vQ==", 389 | "dev": true, 390 | "requires": { 391 | "@polymer/polymer": "^3.0.0", 392 | "prismjs": "^1.11.0" 393 | } 394 | }, 395 | "@polymer/test-fixture": { 396 | "version": "4.0.2", 397 | "resolved": "https://registry.npmjs.org/@polymer/test-fixture/-/test-fixture-4.0.2.tgz", 398 | "integrity": "sha512-tLX8tFE4mkc4p84YG5239G0hbgTVv2irZYrSyO0OblUqIRbRoCPmbydm3HRFQkJeAB3rPCtyeZ2roJULsmTG3A==", 399 | "dev": true 400 | }, 401 | "@webcomponents/shadycss": { 402 | "version": "1.5.2", 403 | "resolved": "https://registry.npmjs.org/@webcomponents/shadycss/-/shadycss-1.5.2.tgz", 404 | "integrity": "sha512-0OyrmVc7S+INtzoqP2ofAo+OdVn2Nj0Qvq4wD9FEGN7nMmLRxaD2mzy6hD6EslzxUSuGH302CDU4KXiY66SEqg==" 405 | }, 406 | "@webcomponents/webcomponentsjs": { 407 | "version": "2.1.3", 408 | "resolved": "https://registry.npmjs.org/@webcomponents/webcomponentsjs/-/webcomponentsjs-2.1.3.tgz", 409 | "integrity": "sha512-0UHJNY88lR3pnEYtBVT7F8cuuxOiITQGWJa0LxoELqkBSB7IabzJFOj5K99PajD3CGAsWpjB0CAeijfe376Y1w==", 410 | "dev": true 411 | }, 412 | "assertion-error": { 413 | "version": "1.1.0", 414 | "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", 415 | "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", 416 | "dev": true 417 | }, 418 | "balanced-match": { 419 | "version": "1.0.0", 420 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 421 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", 422 | "dev": true 423 | }, 424 | "brace-expansion": { 425 | "version": "1.1.11", 426 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", 427 | "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", 428 | "dev": true, 429 | "requires": { 430 | "balanced-match": "^1.0.0", 431 | "concat-map": "0.0.1" 432 | } 433 | }, 434 | "browser-stdout": { 435 | "version": "1.3.1", 436 | "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", 437 | "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", 438 | "dev": true 439 | }, 440 | "chai": { 441 | "version": "4.2.0", 442 | "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", 443 | "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", 444 | "dev": true, 445 | "requires": { 446 | "assertion-error": "^1.1.0", 447 | "check-error": "^1.0.2", 448 | "deep-eql": "^3.0.1", 449 | "get-func-name": "^2.0.0", 450 | "pathval": "^1.1.0", 451 | "type-detect": "^4.0.5" 452 | } 453 | }, 454 | "check-error": { 455 | "version": "1.0.2", 456 | "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", 457 | "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", 458 | "dev": true 459 | }, 460 | "clipboard": { 461 | "version": "2.0.2", 462 | "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.2.tgz", 463 | "integrity": "sha512-kr53YUunMs26TNMZ+O++poRqAVRFskEi7xrqJwMWrTPMOF5pfXkRz8tDw52lKdfkF8b81G8vS6hIR952JgGmIw==", 464 | "dev": true, 465 | "optional": true, 466 | "requires": { 467 | "good-listener": "^1.2.2", 468 | "select": "^1.1.2", 469 | "tiny-emitter": "^2.0.0" 470 | } 471 | }, 472 | "concat-map": { 473 | "version": "0.0.1", 474 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 475 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", 476 | "dev": true 477 | }, 478 | "deep-eql": { 479 | "version": "3.0.1", 480 | "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", 481 | "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", 482 | "dev": true, 483 | "requires": { 484 | "type-detect": "^4.0.0" 485 | } 486 | }, 487 | "delegate": { 488 | "version": "3.2.0", 489 | "resolved": "https://registry.npmjs.org/delegate/-/delegate-3.2.0.tgz", 490 | "integrity": "sha512-IofjkYBZaZivn0V8nnsMJGBr4jVLxHDheKSW88PyxS5QC4Vo9ZbZVvhzlSxY87fVq3STR6r+4cGepyHkcWOQSw==", 491 | "dev": true, 492 | "optional": true 493 | }, 494 | "escape-string-regexp": { 495 | "version": "1.0.5", 496 | "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", 497 | "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", 498 | "dev": true 499 | }, 500 | "fs.realpath": { 501 | "version": "1.0.0", 502 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 503 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", 504 | "dev": true 505 | }, 506 | "get-func-name": { 507 | "version": "2.0.0", 508 | "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", 509 | "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", 510 | "dev": true 511 | }, 512 | "good-listener": { 513 | "version": "1.2.2", 514 | "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", 515 | "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", 516 | "dev": true, 517 | "optional": true, 518 | "requires": { 519 | "delegate": "^3.1.2" 520 | } 521 | }, 522 | "growl": { 523 | "version": "1.10.5", 524 | "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", 525 | "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", 526 | "dev": true 527 | }, 528 | "has-flag": { 529 | "version": "3.0.0", 530 | "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", 531 | "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", 532 | "dev": true 533 | }, 534 | "he": { 535 | "version": "1.1.1", 536 | "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", 537 | "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", 538 | "dev": true 539 | }, 540 | "inflight": { 541 | "version": "1.0.6", 542 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 543 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 544 | "dev": true, 545 | "requires": { 546 | "once": "^1.3.0", 547 | "wrappy": "1" 548 | } 549 | }, 550 | "inherits": { 551 | "version": "2.0.3", 552 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 553 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", 554 | "dev": true 555 | }, 556 | "marked": { 557 | "version": "0.3.19", 558 | "resolved": "http://registry.npmjs.org/marked/-/marked-0.3.19.tgz", 559 | "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==", 560 | "dev": true 561 | }, 562 | "minimatch": { 563 | "version": "3.0.4", 564 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 565 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 566 | "dev": true, 567 | "requires": { 568 | "brace-expansion": "^1.1.7" 569 | } 570 | }, 571 | "minimist": { 572 | "version": "0.0.8", 573 | "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", 574 | "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", 575 | "dev": true 576 | }, 577 | "mkdirp": { 578 | "version": "0.5.1", 579 | "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", 580 | "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", 581 | "dev": true, 582 | "requires": { 583 | "minimist": "0.0.8" 584 | } 585 | }, 586 | "mocha": { 587 | "version": "5.2.0", 588 | "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", 589 | "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", 590 | "dev": true, 591 | "requires": { 592 | "browser-stdout": "1.3.1", 593 | "commander": "2.15.1", 594 | "debug": "3.1.0", 595 | "diff": "3.5.0", 596 | "escape-string-regexp": "1.0.5", 597 | "glob": "7.1.2", 598 | "growl": "1.10.5", 599 | "he": "1.1.1", 600 | "minimatch": "3.0.4", 601 | "mkdirp": "0.5.1", 602 | "supports-color": "5.4.0" 603 | }, 604 | "dependencies": { 605 | "commander": { 606 | "version": "2.15.1", 607 | "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", 608 | "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", 609 | "dev": true 610 | }, 611 | "debug": { 612 | "version": "3.1.0", 613 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", 614 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", 615 | "dev": true, 616 | "requires": { 617 | "ms": "2.0.0" 618 | } 619 | }, 620 | "diff": { 621 | "version": "3.5.0", 622 | "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", 623 | "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", 624 | "dev": true 625 | }, 626 | "glob": { 627 | "version": "7.1.2", 628 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 629 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 630 | "dev": true, 631 | "requires": { 632 | "fs.realpath": "^1.0.0", 633 | "inflight": "^1.0.4", 634 | "inherits": "2", 635 | "minimatch": "^3.0.4", 636 | "once": "^1.3.0", 637 | "path-is-absolute": "^1.0.0" 638 | } 639 | } 640 | } 641 | }, 642 | "ms": { 643 | "version": "2.0.0", 644 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 645 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", 646 | "dev": true 647 | }, 648 | "once": { 649 | "version": "1.4.0", 650 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 651 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 652 | "dev": true, 653 | "requires": { 654 | "wrappy": "1" 655 | } 656 | }, 657 | "path-is-absolute": { 658 | "version": "1.0.1", 659 | "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 660 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", 661 | "dev": true 662 | }, 663 | "pathval": { 664 | "version": "1.1.0", 665 | "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", 666 | "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", 667 | "dev": true 668 | }, 669 | "prismjs": { 670 | "version": "1.15.0", 671 | "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.15.0.tgz", 672 | "integrity": "sha512-Lf2JrFYx8FanHrjoV5oL8YHCclLQgbJcVZR+gikGGMqz6ub5QVWDTM6YIwm3BuPxM/LOV+rKns3LssXNLIf+DA==", 673 | "dev": true, 674 | "requires": { 675 | "clipboard": "^2.0.0" 676 | } 677 | }, 678 | "select": { 679 | "version": "1.1.2", 680 | "resolved": "https://registry.npmjs.org/select/-/select-1.1.2.tgz", 681 | "integrity": "sha1-DnNQrN7ICxEIUoeG7B1EGNEbOW0=", 682 | "dev": true, 683 | "optional": true 684 | }, 685 | "supports-color": { 686 | "version": "5.4.0", 687 | "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", 688 | "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", 689 | "dev": true, 690 | "requires": { 691 | "has-flag": "^3.0.0" 692 | } 693 | }, 694 | "tiny-emitter": { 695 | "version": "2.0.2", 696 | "resolved": "https://registry.npmjs.org/tiny-emitter/-/tiny-emitter-2.0.2.tgz", 697 | "integrity": "sha512-2NM0auVBGft5tee/OxP4PI3d8WItkDM+fPnaRAVo6xTDI2knbz9eC5ArWGqtGlYqiH3RU5yMpdyTTO7MguC4ow==", 698 | "dev": true, 699 | "optional": true 700 | }, 701 | "type-detect": { 702 | "version": "4.0.8", 703 | "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", 704 | "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", 705 | "dev": true 706 | }, 707 | "wct-mocha": { 708 | "version": "1.0.0", 709 | "resolved": "https://registry.npmjs.org/wct-mocha/-/wct-mocha-1.0.0.tgz", 710 | "integrity": "sha512-rvDjW4kJMV8/lpihKMDHMZwycT5ALtoLni/Q0Ggdg1rPRpIW5pjoslSR/UIl2gWRMYqAs9nFRVYxASwEYG6brA==", 711 | "dev": true 712 | }, 713 | "wrappy": { 714 | "version": "1.0.2", 715 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 716 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", 717 | "dev": true 718 | } 719 | } 720 | } 721 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Payment request API implementation in Polymer", 3 | "keywords": [ 4 | "payment", 5 | "polymer", 6 | "web", 7 | "components" 8 | ], 9 | "repository": { 10 | "type": "git", 11 | "url": "git+https://github.com/jorgecasar/payment-request.git" 12 | }, 13 | "homepage": "https://github.com/jorgecasar/payment-request#readme", 14 | "name": "payment-request", 15 | "version": "2.0.0", 16 | "main": "index.js", 17 | "directories": { 18 | "test": "test" 19 | }, 20 | "scripts": { 21 | "test": "polymer test" 22 | }, 23 | "author": "Jorge del Casar ", 24 | "license": "MIT", 25 | "bugs": { 26 | "url": "https://github.com/jorgecasar/payment-request/issues" 27 | }, 28 | "resolutions": { 29 | "inherits": "2.0.3", 30 | "samsam": "1.1.3", 31 | "supports-color": "3.1.2", 32 | "type-detect": "1.0.0" 33 | }, 34 | "dependencies": { 35 | "@polymer/polymer": "^3.0.0", 36 | "@polymer/iron-selector": "^3.0.0" 37 | }, 38 | "devDependencies": { 39 | "@polymer/app-layout": "^3.0.1", 40 | "@polymer/iron-component-page": "^4.0.1", 41 | "@polymer/iron-demo-helpers": "^3.0.0", 42 | "@polymer/iron-flex-layout": "^3.0.0", 43 | "@polymer/paper-button": "^3.0.0", 44 | "@polymer/paper-icon-button": "^3.0.0", 45 | "@polymer/paper-item": "^3.0.0", 46 | "@polymer/paper-listbox": "^3.0.0", 47 | "@polymer/paper-toast": "^3.0.0", 48 | "@polymer/paper-toolbar": "^3.0.0", 49 | "@polymer/test-fixture": "^4.0.2", 50 | "@webcomponents/webcomponentsjs": "^2.0.0", 51 | "chai": "^4.2.0", 52 | "mocha": "^5.2.0", 53 | "wct-mocha": "^1.0.0" 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /payment-address.js: -------------------------------------------------------------------------------- 1 | import { PolymerElement } from '@polymer/polymer/polymer-element.js'; 2 | 3 | const $_documentContainer = document.createElement('template'); 4 | 5 | $_documentContainer.innerHTML = ` 6 | 13 | `; 14 | 15 | document.head.appendChild($_documentContainer.content); 16 | 17 | export const PaymentAddressElement = class extends PolymerElement { 18 | static get is() { 19 | return 'payment-address'; 20 | } 21 | static get properties() { 22 | return { 23 | country: String, 24 | addressLine: Array, 25 | region: String, 26 | city: String, 27 | dependentLocality: String, 28 | postalCode: String, 29 | sortingCode: String, 30 | languageCode: String, 31 | organization: String, 32 | recipient: String, 33 | phone: String 34 | }; 35 | } 36 | }; 37 | 38 | window.customElements.define(PaymentAddressElement.is, PaymentAddressElement); 39 | -------------------------------------------------------------------------------- /payment-item.js: -------------------------------------------------------------------------------- 1 | import { PolymerElement } from '@polymer/polymer/polymer-element.js'; 2 | 3 | const $_documentContainer = document.createElement('template'); 4 | 5 | $_documentContainer.innerHTML = ` 6 | 13 | 14 | 15 | `; 16 | 17 | document.head.appendChild($_documentContainer.content); 18 | 19 | /* 20 | `payment-item` 21 | PaymentItem dictionary implementation from browser payment API 22 | */ 23 | export const PaymentItem = class extends PolymerElement { 24 | 25 | static get is() { 26 | return 'payment-item'; 27 | } 28 | 29 | static get properties() { 30 | return { 31 | /** 32 | * This is a human-readable description of the item. 33 | * The user agent may display this to the user. 34 | */ 35 | label: String, 36 | /** 37 | * A valid decimal monetary value containing a monetary amount of the item. 38 | */ 39 | value: Number, 40 | /** 41 | * A string containing a currency identifier of the item. 42 | * The value of currency can be any string that is valid within 43 | * the currency system indicated by currencySystem. 44 | */ 45 | currency: String, 46 | 47 | /** 48 | * A URL that indicates the currency system 49 | * that the currency identifier belongs to 50 | */ 51 | currencySystem: { 52 | type: String, 53 | value: 'urn:iso:std:iso:4217' 54 | }, 55 | 56 | /** 57 | * Contain the monetary amount for the item. 58 | */ 59 | amount: { 60 | type: Object, 61 | computed: '_computeAmount(value, currency, currencySystem)' 62 | }, 63 | 64 | /** 65 | * When set to true this flag means that the amount member is not final. 66 | * This is commonly used to show items such as shipping or tax amounts 67 | * that depend upon selection of shipping address or shipping option. 68 | */ 69 | pending: { 70 | type: Boolean, 71 | value: false 72 | }, 73 | 74 | dictionary: { 75 | type: Object, 76 | computed: '_computeDictionary(label, amount, pending)' 77 | } 78 | } 79 | } 80 | 81 | _computeAmount(value, currency, currencySystem) { 82 | return { 83 | value: value, 84 | currency: currency, 85 | currencySystem: currencySystem 86 | }; 87 | } 88 | 89 | _computeDictionary(label, amount, pending) { 90 | return { 91 | label: label, 92 | amount: amount, 93 | pending: pending 94 | }; 95 | } 96 | }; 97 | 98 | window.customElements.define(PaymentItem.is, PaymentItem); 99 | -------------------------------------------------------------------------------- /payment-method.js: -------------------------------------------------------------------------------- 1 | /* 2 | `payment-method` 3 | PaymentMethodData dictionary implementation from browser payment API 4 | */ 5 | /* 6 | FIXME(polymer-modulizer): the above comments were extracted 7 | from HTML and may be out of place here. Review them and 8 | then delete this comment! 9 | */ 10 | import { PolymerElement } from '@polymer/polymer/polymer-element.js'; 11 | 12 | const $_documentContainer = document.createElement('template'); 13 | 14 | $_documentContainer.innerHTML = ` 15 | 22 | 23 | 24 | `; 25 | 26 | document.head.appendChild($_documentContainer.content); 27 | 28 | export const PaymentMethod = class extends PolymerElement { 29 | 30 | static get is() { 31 | return 'payment-method'; 32 | } 33 | 34 | static get properties() { 35 | return { 36 | supported: { 37 | type: Array 38 | }, 39 | data: { 40 | type: Object, 41 | value: function() { 42 | return {}; 43 | } 44 | }, 45 | dictionary: { 46 | type: Object, 47 | computed: '_computeDictionary(supported, data)' 48 | } 49 | } 50 | } 51 | 52 | _computeDictionary(supported, data) { 53 | return { 54 | supportedMethods: supported, 55 | data: data 56 | }; 57 | } 58 | }; 59 | 60 | window.customElements.define(PaymentMethod.is, PaymentMethod); 61 | -------------------------------------------------------------------------------- /payment-request.js: -------------------------------------------------------------------------------- 1 | /* 2 | Prepare for 2.0 3 | 4 | */ 5 | /** 6 | `payment-request` 7 | Payment request API implementation 8 | 9 | @demo demo/index.html 10 | */ 11 | /* 12 | FIXME(polymer-modulizer): the above comments were extracted 13 | from HTML and may be out of place here. Review them and 14 | then delete this comment! 15 | */ 16 | import { PolymerElement } from '@polymer/polymer/polymer-element.js'; 17 | import '@polymer/iron-selector/iron-selector.js'; 18 | import { afterNextRender } from '@polymer/polymer/lib/utils/render-status.js'; 19 | import { dom } from '@polymer/polymer/lib/legacy/polymer.dom.js'; 20 | import { FlattenedNodesObserver } from '@polymer/polymer/lib/utils/flattened-nodes-observer.js' 21 | const $_documentContainer = document.createElement('template'); 22 | 23 | $_documentContainer.innerHTML = ` 24 | 38 | 39 | 40 | `; 41 | 42 | document.head.appendChild($_documentContainer.content); 43 | 44 | /** 45 | * Fired when user interaction begins for the payment request. 46 | * 47 | * @event response 48 | * @param {PaymentResponse} paymentResponse The payment information to process. 49 | */ 50 | 51 | /** 52 | * Fired when a PaymentRequest is created. 53 | * 54 | * @event request 55 | * @param {PaymentRequest} paymentRequest The payment request. 56 | */ 57 | 58 | /** 59 | * Fired when the payment request is aborted 60 | * 61 | * @event aborted 62 | */ 63 | 64 | /** 65 | * Fired when payment request generate an error. 66 | * 67 | * @event error 68 | * @param {Error} error The request error. 69 | */ 70 | 71 | /** 72 | * Fired when PaymentRequest object can be used to make a payment. 73 | * 74 | * @event can-make-payment 75 | */ 76 | 77 | /** 78 | * Fired when PaymentRequest object cannot be used to make a payment. 79 | * 80 | * @event cannot-make-payment 81 | */ 82 | export const PaymentRequestElement = class extends PolymerElement { 83 | static get is() { 84 | return 'payment-request'; 85 | } 86 | 87 | static get importMeta() { 88 | return import.meta; 89 | } 90 | 91 | static get properties() { 92 | return { 93 | /** 94 | * This is a human-readable description of the total. 95 | * The user agent may display this to the user. 96 | */ 97 | label: String, 98 | 99 | /** 100 | * A valid decimal monetary value containing a monetary amount of the total 101 | */ 102 | value: Number, 103 | 104 | /** 105 | * A string containing a currency identifier of the total. 106 | * The value of currency can be any string that is valid within 107 | * the currency system indicated by currencySystem. 108 | */ 109 | currency: { 110 | type: String, 111 | value: 'EUR' 112 | }, 113 | 114 | /** 115 | * Contains line items for the payment request that the user agent may display. 116 | */ 117 | items: { 118 | type: Array, 119 | readOnly: true, 120 | notify: true, 121 | value: () => { 122 | return []; 123 | }, 124 | }, 125 | 126 | /** 127 | * Contains the total amount of the payment request. 128 | */ 129 | total: { 130 | type: Object, 131 | readOnly: true, 132 | notify: true, 133 | value: () => { 134 | return {}; 135 | } 136 | }, 137 | 138 | /** 139 | * Is used to store supported payment methods and 140 | * any associated payment method specific data for those methods. 141 | */ 142 | methods: { 143 | type: Array, 144 | readOnly: true, 145 | value: () => { 146 | return []; 147 | } 148 | }, 149 | 150 | /** 151 | * Provides information about the requested transaction. 152 | */ 153 | details: { 154 | type: Object, 155 | computed: '_computeDetails(total, items, shippingItem)', 156 | }, 157 | 158 | payerName: { 159 | type: Boolean, 160 | value: false 161 | }, 162 | payerEmail: { 163 | type: Boolean, 164 | value: false 165 | }, 166 | payerPhone: { 167 | type: Boolean, 168 | value: false 169 | }, 170 | shipping: { 171 | type: Boolean, 172 | value: false 173 | }, 174 | shippingType: { 175 | type: String, 176 | value: 'shipping' 177 | }, 178 | 179 | options: { 180 | type: Object, 181 | computed: '_computeOptions(payerName, payerEmail, payerPhone, shipping, shippingType)' 182 | }, 183 | 184 | shippingOptions: { 185 | type: Array, 186 | value: () => { 187 | return []; 188 | } 189 | }, 190 | 191 | shippingOptionSelected: { 192 | type: String 193 | }, 194 | 195 | shippingItem: { 196 | type: Object, 197 | value: () => { 198 | return null; 199 | } 200 | }, 201 | 202 | lastRequest: { 203 | type: Object, 204 | notify: true, 205 | observer: '_dispatchRequest' 206 | }, 207 | 208 | lastResponse: { 209 | type: Object, 210 | readOnly: true, 211 | notify: true, 212 | observer: '_dispatchResponse' 213 | }, 214 | 215 | lastError: { 216 | type: Object, 217 | readOnly: true, 218 | notify: true, 219 | observer: '_dispatchError' 220 | }, 221 | 222 | lastCanMakePayment: { 223 | type: Boolean, 224 | value: false, 225 | notify: true 226 | } 227 | } 228 | } 229 | 230 | static get observers() { 231 | return [ 232 | '_updateTotal(items.length, shippingItem)', 233 | '_updateShippingOptions(shippingOptionSelected)', 234 | '_updateLastRequest(methods.*, details.*, options.*)', 235 | 'checkCanMakePayment(methods, lastRequest)' 236 | ]; 237 | } 238 | 239 | connectedCallback() { 240 | super.connectedCallback(); 241 | afterNextRender(this, this._updatePropertiesFromNodes); 242 | this.buyButtonTap = this.buyButtonTap.bind(this); 243 | this.onShippingAddressChange = this.onShippingAddressChange.bind(this); 244 | this.onShippingOptionChange = this.onShippingOptionChange.bind(this); 245 | this.__updatePropertyFromNodes = this.__updatePropertyFromNodes.bind(this); 246 | this.$.buyButton.addEventListener('tap', this.buyButtonTap); 247 | } 248 | 249 | disconnectedCallback() { 250 | super.connectedCallback(); 251 | this.__unobserveNodes('methods'); 252 | this.__unobserveNodes('items'); 253 | this.__unobserveNodes('shippingOptions'); 254 | this.$.buyButton.removeEventListener('tap', this.buyButtonTap); 255 | } 256 | 257 | _updatePropertiesFromNodes() { 258 | this.__observeNodes('methods'); 259 | this.__observeNodes('items'); 260 | this.__observeNodes('shippingOptions'); 261 | } 262 | 263 | __updatePropertyFromNodes(observerInfo) { 264 | var property = observerInfo.target.id; 265 | if (!observerInfo) { 266 | observerInfo = { 267 | target: this.$[property], 268 | addedNodes: dom(this.$[property]).getDistributedNodes(), 269 | removedNodes: [] 270 | }; 271 | this.splice(property, 0, this[property].length - 1); 272 | } 273 | // Add items from added nodes 274 | observerInfo.addedNodes.filter(this._isElementNode).forEach(function(node) { 275 | this.splice(property, this[property].length, 0, node.dictionary); 276 | }.bind(this)); 277 | // Remove items from removed nodes 278 | observerInfo.removedNodes.filter(this._isElementNode).forEach(function(node) { 279 | this.splice(property, this[property].indexOf(node.dictionary), 1); 280 | }.bind(this)); 281 | } 282 | 283 | _isElementNode(node) { 284 | return (node.nodeType === Node.ELEMENT_NODE && node.dictionary); 285 | } 286 | 287 | __observerNode(node) { 288 | return '_' + node + 'Observer'; 289 | } 290 | 291 | __observeNodes(property) { 292 | // Watch for future updates. 293 | if (!this[this.__observerNode(property)]) { 294 | this[this.__observerNode(property)] = new FlattenedNodesObserver(this.$[property], this.__updatePropertyFromNodes); 295 | } 296 | } 297 | 298 | __unobserveNodes(property) { 299 | if (this[this.__observerNode(property)]) { 300 | dom(this).unobserveNodes(this[this.__observerNode(property)]); 301 | } 302 | } 303 | 304 | _updateTotal() { 305 | var totalDom = dom(this.$.total); 306 | var total = totalDom.getDistributedNodes()[0]; 307 | if (!total) { 308 | total = document.createElement('payment-item'); 309 | total.setAttribute('slot', 'total'); 310 | totalDom.appendChild(total); 311 | import(PaymentRequestElement.importMeta.url + '/../payment-item.js') 312 | .then(() => this._updateTotal()) 313 | .catch((err) => console.error(err)); 314 | return; 315 | } 316 | var currency = this.items.length && this.items[0]? 317 | this.items[0].amount.currency : 318 | this.currency; 319 | var value = 0; 320 | for (var i = 0; i < this.items.length; i++) { 321 | value += this.items[i] ? this.items[i].amount.value : 0; 322 | } 323 | if (this.shippingItem) { 324 | value += this.shippingItem.amount.value; 325 | } 326 | total.label = this.label || 'Total'; 327 | total.value = value || 0; 328 | total.currency = currency || 'EUR'; 329 | 330 | this._setTotal(total.dictionary); 331 | } 332 | 333 | _computeDetails(total, items, shippingItem) { 334 | return { 335 | total: total, 336 | displayItems: shippingItem ? items.concat(shippingItem): items 337 | }; 338 | } 339 | 340 | _computeOptions(payerName, payerEmail, payerPhone, shipping, shippingType) { 341 | return { 342 | requestPayerName: payerName, 343 | requestPayerEmail: payerEmail, 344 | requestPayerPhone: payerPhone, 345 | requestShipping: shipping, 346 | shippingType: shippingType 347 | }; 348 | } 349 | 350 | /** 351 | * Construct a PaymentRequest using the supplied methodData list including any 352 | * payment method specific data, the payment details, and the payment options 353 | * 354 | * @return {PaymentRequest} 355 | */ 356 | _updateLastRequest(methods, details, options) { 357 | methods = methods.base; 358 | details = details.base; 359 | options = options.base; 360 | this.updateLastRequest(methods, details, options); 361 | } 362 | 363 | updateLastRequest(methods, details, options) { 364 | methods = methods || this.methods; 365 | details = details || this.details; 366 | options = options || this.options; 367 | if (methods.length && 368 | details.displayItems.length && 369 | details.total.amount.currency && 370 | window.PaymentRequest) { 371 | this.lastRequest = new PaymentRequest(methods, details, options); 372 | this.addRequestListeners(); 373 | } else { 374 | this.lastRequest = null; 375 | } 376 | } 377 | 378 | addRequestListeners() { 379 | if (this.shipping) { 380 | this.lastRequest.addEventListener('shippingaddresschange', this.onShippingAddressChange); 381 | this.lastRequest.addEventListener('shippingoptionchange', this.onShippingOptionChange); 382 | } 383 | } 384 | 385 | removeRequestListeners() { 386 | if (this.shipping) { 387 | this.lastRequest.removeEventListener('shippingaddresschange', this.onShippingAddressChange); 388 | this.lastRequest.removeEventListener('shippingoptionchange', this.onShippingOptionChange); 389 | } 390 | } 391 | 392 | /** 393 | * Method executed when payButton is tapped. 394 | * You can override it to do something more complex. 395 | */ 396 | buyButtonTap() { 397 | if ('PaymentRequest' in window) { 398 | this.show(); 399 | } else { 400 | this._setLastError({ 401 | detail: 'Payment Request API not supported' 402 | }); 403 | } 404 | } 405 | 406 | /** 407 | * Determine if the PaymentRequest object can be used to make a payment. 408 | * 409 | * @return {Promise} 410 | */ 411 | checkCanMakePayment(methods, lastRequest) { 412 | var promise; 413 | if (methods.length && lastRequest && lastRequest.canMakePayment) { 414 | promise = lastRequest.canMakePayment() 415 | .then(this.set.bind(this, 'lastCanMakePayment')) 416 | .then(this._setLastError.bind(this, null)) 417 | .catch(this._setLastError.bind(this)); 418 | } else { 419 | promise = new Promise(function(resolve, reject) { 420 | resolve(); 421 | }); 422 | } 423 | return promise; 424 | } 425 | 426 | /** 427 | * Begin user interaction for the payment request. 428 | * 429 | * @return {Promise} 430 | */ 431 | show() { 432 | if (this.lastRequest) { 433 | return this.lastRequest.show() 434 | .then(this._setLastResponse.bind(this)) 435 | .catch(this._setLastError.bind(this)) 436 | .then(this.updateLastRequest.bind(this)); 437 | } else { 438 | var detail; 439 | if (!this.methods.length) { 440 | detail = 'There aren\'t payment methods'; 441 | } else if (!this.details.displayItems.length) { 442 | detail = 'There aren\'t items to pay'; 443 | } else { 444 | detail = 'Payment Request wasn\'t be created'; 445 | } 446 | this._setLastError({ detail: detail }); 447 | } 448 | } 449 | 450 | /** 451 | * Abort the payment request 452 | * @return {Promise} 453 | */ 454 | abort() { 455 | var promise; 456 | if (this.lastRequest) { 457 | promise = this.lastRequest.abort() 458 | .then(function() { 459 | this._setLastResponse(null); 460 | this.dispatchEvent( 461 | new CustomEvent('aborted') 462 | ); 463 | }.bind(this)); 464 | } else { 465 | promise = new Promise(function(resolve, reject) { 466 | resolve('There aren\'t any active request'); 467 | }); 468 | } 469 | return promise 470 | .catch(this._setLastError.bind(this)); 471 | } 472 | 473 | onShippingAddressChange(evt) { 474 | evt.updateWith(this.updateWithShippingAddress(evt)); 475 | } 476 | 477 | onShippingOptionChange(evt) { 478 | evt.updateWith(this.updateWithShippingOptions(evt)); 479 | } 480 | 481 | updateWithShippingAddress(evt) { 482 | this.changeShippingOption(evt.target.shippingOption); 483 | this._updateTotal(); 484 | this._updateShippingOptions(); 485 | return Promise.resolve(this.details); 486 | } 487 | 488 | updateWithShippingOptions(evt) { 489 | this.changeShippingOption(evt.target.shippingOption); 490 | this._updateTotal(); 491 | this._updateShippingOptions(); 492 | return Promise.resolve(this.details); 493 | } 494 | 495 | changeShippingOption(shippingOption) { 496 | shippingOption = shippingOption || this.$.shippingOptionsSelector.selected; 497 | // Add shipping option to displayed items 498 | if (shippingOption) { 499 | this.$.shippingOptionsSelector.select(shippingOption); 500 | this.shippingItem = this.$.shippingOptionsSelector.selectedItem.dictionary; 501 | } 502 | } 503 | 504 | _updateShippingOptions() { 505 | this.set('details.shippingOptions', this.$.shippingOptionsSelector.items.map(function(item) { 506 | return item.dictionary; 507 | })); 508 | } 509 | 510 | _dispatchError(error) { 511 | if (error) { 512 | this.dispatchEvent( 513 | new CustomEvent('error', { 514 | detail: error 515 | }) 516 | ); 517 | } 518 | return error; 519 | } 520 | 521 | _dispatchResponse(response) { 522 | if (response !== null) { 523 | this.dispatchEvent( 524 | new CustomEvent('response', { 525 | detail: response 526 | }) 527 | ); 528 | } 529 | return response; 530 | } 531 | 532 | _dispatchRequest(request) { 533 | this.dispatchEvent( 534 | new CustomEvent('request', { 535 | detail: request 536 | }) 537 | ); 538 | return request; 539 | } 540 | 541 | }; 542 | 543 | window.customElements.define(PaymentRequestElement.is, PaymentRequestElement); 544 | -------------------------------------------------------------------------------- /payment-shipping-option.js: -------------------------------------------------------------------------------- 1 | import {PolymerElement} from '@polymer/polymer/polymer-element.js'; 2 | const $_documentContainer = document.createElement('template'); 3 | 4 | $_documentContainer.innerHTML = ` 5 | 13 | 14 | `; 15 | 16 | document.head.appendChild($_documentContainer.content); 17 | 18 | export const PaymentShippingOption = class extends PolymerElement { 19 | 20 | static get is() { 21 | return 'payment-shipping-option'; 22 | } 23 | static get properties() { 24 | return { 25 | id: String, 26 | /** 27 | * This is a human-readable description of the item. 28 | * The user agent may display this to the user. 29 | */ 30 | label: String, 31 | /** 32 | * A valid decimal monetary value containing a monetary amount of the item. 33 | */ 34 | value: Number, 35 | /** 36 | * A string containing a currency identifier of the item. 37 | * The value of currency can be any string that is valid within 38 | * the currency system indicated by currencySystem. 39 | */ 40 | currency: String, 41 | 42 | /** 43 | * A URL that indicates the currency system 44 | * that the currency identifier belongs to 45 | */ 46 | currencySystem: { 47 | type: String, 48 | value: 'urn:iso:std:iso:4217' 49 | }, 50 | 51 | /** 52 | * Contain the monetary amount for the item. 53 | */ 54 | amount: { 55 | type: Object, 56 | readOnly: true, 57 | computed: '_computeAmount(value, currency, currencySystem)' 58 | }, 59 | 60 | /** 61 | * This is set to true to indicate that this is the default 62 | * selected PaymentShippingOption in a sequence 63 | */ 64 | selected: { 65 | type: Boolean, 66 | value: false 67 | }, 68 | 69 | dictionary: { 70 | type: Object, 71 | computed: '_computeDictionary(id, label, amount, selected)' 72 | } 73 | }; 74 | } 75 | 76 | _computeAmount(value, currency, currencySystem) { 77 | return { 78 | value: value, 79 | currency: currency, 80 | currencySystem: currencySystem 81 | }; 82 | } 83 | 84 | _computeDictionary(id, label, amount, selected) { 85 | return { 86 | id: id, 87 | label: label, 88 | amount: amount, 89 | selected: selected 90 | }; 91 | } 92 | }; 93 | 94 | window.customElements.define(PaymentShippingOption.is, PaymentShippingOption); 95 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /test/payment-request_test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | payment-request test 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 23 | 24 | 25 | 26 | 29 | 30 | 31 | 40 | 41 | 42 | 43 | --------------------------------------------------------------------------------