├── .github └── CONTRIBUTING.md ├── .gitignore ├── .vscode ├── launch.json └── settings.json ├── CODE_OF_CONDUCT.md ├── LICENSE ├── README.md ├── SECURITY.md ├── build └── pipeline.yml ├── media └── css-completion.png ├── samples ├── helloworld │ ├── .vscode │ │ └── settings.json │ ├── README.md │ ├── css.css-data.json │ ├── html.html-data.json │ ├── test.css │ └── test.html ├── svg │ ├── .gitignore │ ├── .vscode │ │ ├── launch.json │ │ ├── settings.json │ │ └── tasks.json │ ├── README.md │ ├── build │ │ ├── index.ts │ │ ├── mdn-bcd.ts │ │ ├── mdn-data.ts │ │ ├── mdn-description.ts │ │ ├── postprocess.ts │ │ ├── svg-spec.ts │ │ └── util.ts │ ├── data │ │ ├── svg.css-data.json │ │ └── svg.html-data.json │ ├── package-lock.json │ ├── package.json │ ├── raw-data │ │ ├── definitions.xml │ │ ├── svg-css-contribution.json │ │ └── svg-html-contribution.json │ ├── test.css │ ├── test.html │ ├── tsconfig.json │ └── yarn.lock └── webcomponents │ ├── .vscode │ └── settings.json │ ├── README.md │ ├── demo.gif │ ├── index.html │ ├── node_modules │ └── @github │ │ └── time-elements │ │ ├── LICENSE │ │ ├── README.md │ │ ├── dist │ │ ├── time-elements-legacy.js │ │ ├── time-elements-legacy.js.flow │ │ ├── time-elements.js │ │ └── time-elements.js.flow │ │ ├── index.d.ts │ │ ├── package.json │ │ └── web-components.html-data.json │ └── src │ ├── components │ └── my-component │ │ ├── docs.md │ │ └── main.js │ └── web-components.html-data.json ├── web-data ├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── css │ ├── add-atrule-descriptors.mjs │ ├── chromestatus │ │ ├── applyRelevance.mjs │ │ ├── attributeRelevance.mjs │ │ └── updateRelevance.mjs │ ├── css-schema.json │ ├── generateData.mjs │ ├── mdn │ │ ├── mdn-browser-compat-data-importer.mjs │ │ ├── mdn-data-importer.mjs │ │ ├── mdn-data-selector-importer.mjs │ │ └── mdn-documentation.mjs │ └── utils.mjs ├── data │ ├── browsers.css-data.json │ └── browsers.html-data.json ├── html │ ├── ariaData.json │ ├── ariaSpec.json │ ├── generateData.mjs │ ├── htmlEvents.json │ ├── htmlGlobalAttributes.json │ ├── htmlTags.json │ ├── mdnTagDescriptions.json │ ├── oldEvents.json │ └── valueSets.json ├── package-lock.json └── package.json └── yarn.lock /.github/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to VS Code Custom Data 2 | 3 | ## I want to update a specific HTML/CSS entity 4 | 5 | If you go to `web-data`, the `generate-data` script will regenerate `data/browsers.html-data.json` and `data/browsers.css-data.json`. 6 | 7 | Some data are pulled remotely from MDN and other sources. For all the local xml and json files, you can edit them and run `yarn generate-data` to update the files in [`web-data/data`](../web-data/data). -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Logs 2 | logs 3 | *.log 4 | npm-debug.log* 5 | yarn-debug.log* 6 | yarn-error.log* 7 | 8 | # Runtime data 9 | pids 10 | *.pid 11 | *.seed 12 | *.pid.lock 13 | 14 | # Directory for instrumented libs generated by jscoverage/JSCover 15 | lib-cov 16 | 17 | # Coverage directory used by tools like istanbul 18 | coverage 19 | 20 | # nyc test coverage 21 | .nyc_output 22 | 23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 24 | .grunt 25 | 26 | # Bower dependency directory (https://bower.io/) 27 | bower_components 28 | 29 | # node-waf configuration 30 | .lock-wscript 31 | 32 | # Compiled binary addons (https://nodejs.org/api/addons.html) 33 | build/Release 34 | 35 | # Dependency directories 36 | node_modules/ 37 | jspm_packages/ 38 | 39 | # TypeScript v1 declaration files 40 | typings/ 41 | 42 | # Optional npm cache directory 43 | .npm 44 | 45 | # Optional eslint cache 46 | .eslintcache 47 | 48 | # Optional REPL history 49 | .node_repl_history 50 | 51 | # Output of 'npm pack' 52 | *.tgz 53 | 54 | # Yarn Integrity file 55 | .yarn-integrity 56 | 57 | # dotenv environment variables file 58 | .env 59 | 60 | # next.js build output 61 | .next 62 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "type": "pwa-node", 9 | "request": "launch", 10 | "name": "Launch Program", 11 | "skipFiles": [ 12 | "/**" 13 | ], 14 | "program": "${workspaceFolder}/web-data/css/generateData.mjs" 15 | } 16 | ] 17 | } -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "git.branchProtection": [ 3 | "main" 4 | ], 5 | "git.branchProtectionPrompt": "alwaysCommitToNewBranch", 6 | "git.branchRandomName.enable": true, 7 | "githubPullRequests.assignCreated": "${user}", 8 | "githubPullRequests.defaultMergeMethod": "squash" 9 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Microsoft Open Source Code of Conduct 2 | 3 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 4 | 5 | Resources: 6 | 7 | - [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/) 8 | - [Microsoft Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) 9 | - Contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with questions or concerns 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Microsoft Corporation. 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 |

2 |

VS Code Custom Data

3 | Documentation, sample and data for using VS Code's HTML/CSS custom data format. 4 |

5 | 6 | ## Synopsis 7 | 8 | VS Code ships with rich [language feature support](https://code.visualstudio.com/api/language-extensions/programmatic-language-features) for HTML/CSS, such as auto-completion and hover information. The core of these language support are implemented in [vscode-html-languageservice](https://github.com/microsoft/vscode-html-languageservice) and [vscode-css-languageservice](https://github.com/microsoft/vscode-css-languageservice). In the past, these libraries were coupled to outdated schemas that define HTML/CSS entities. Custom data decouples these libraries from the data they use and allows VS Code to offer up-to-date support for latest HTML/CSS proposals or frameworks built on top of HTML/CSS. 9 | 10 | ## Usage 11 | 12 | There are two primary use cases: 13 | 14 | 1. You can use settings, `html.customData` and `css.customData` in your settings to let VS Code load additional HTML/CSS entities, so they would show up in auto-completion, hover information etc. See [helloworld sample](./samples/helloworld) for an example. 15 | 2. You can use [Contribution Points](https://code.visualstudio.com/api/references/contribution-points), `contributes.html.customData` or `contributes.css.customData` to load Custom Data into VS Code. See [vscode-mavo](https://github.com/octref/vscode-mavo) for an example. 16 | 17 | ## Explanation 18 | 19 | Take this HTML auto-completion example: 20 | 21 | `<|` 22 | 23 | - `vscode-html-languageservice` determines that it should provide a list of tag names, such as `div`, `span`, `p`. 24 | - By default, VS Code provides data extracted from HTML spec to `vscode-html-languageservice`, so `<|` completes all HTML tags described in the HTML spec. 25 | - The `html.customData` setting and `contributes.html.customData` allows you to extend this list to include your own definition of HTML tags. 26 | 27 | On the one hand, we continuously curate the data VS Code provides to the HTML/CSS language services. For example, VS Code pulls data from [mdn/data](https://github.com/mdn/data) and [mdn/browser-compat-data](https://github.com/mdn/browser-compat-data) to provide latest information on CSS properties' usage, syntax and browser compatibility. By continously following the latest web spec, VS Code can provide latest information & up-to-date language support for new HTML/CSS entities. 28 | 29 |
30 | CSS completion 31 |
32 |

33 | 34 | On the other hand, for users and framework authors who build new technologies and frameworks on top of HTML/CSS, custom data offers an easy way for them to add support for their custom frameworks. For example: 35 | - WebComponents-based frameworks can statically analyze their components and emit a JSON file following the custom data schema to get language support. 36 | - Vue language server can analyze Vue components and load custom data into its `vscode-html-languageservice` based Language Server to provide Vue-specific auto-completions. 37 | 38 |
39 | WebComponents completion 40 |
41 | 42 | ## Documentation 43 | 44 | - [HTML Custom Data](https://github.com/microsoft/vscode-html-languageservice/blob/master/docs/customData.md) 45 | - [CSS Custom Data](https://github.com/microsoft/vscode-css-languageservice/blob/master/docs/customData.md) 46 | 47 | ## Schemas and Versioning 48 | 49 | - [Latest HTML Schema, V1.1](https://github.com/microsoft/vscode-html-languageservice/blob/master/docs/customData.schema.json) 50 | - [Latest CSS Schema, V1.1](https://github.com/microsoft/vscode-CSS-languageservice/blob/master/docs/customData.schema.json) 51 | 52 | ### Versioning 53 | 54 | - Schemas are versioned in the format of `.`. 55 | - `Minor` changes are backwards compatible. Custom data that satisfies `V1.X` spec would be valid according to `V1.0` spec. 56 | - `Major` changes introduce breaking changes. Custom data that satisfies `V2.X` spec would likely be invalid according to `V1.0` spec. 57 | 58 | ## Samples 59 | 60 | - [`samples/helloworld`](./samples/helloworld): Open this sample in VS Code and start playing with custom data. 61 | - [`samples/svg`](./samples/svg): A real-world sample that loads SVG-related HTML/CSS entities in VS Code. 62 | - [`samples/webcomponents`](./samples/webcomponents): Use custom data to get web component editor support in HTML. 63 | - [`octref/vscode-mavo`](https://github.com/octref/vscode-mavo): Use custom data to support the [Mavo framework](https://mavo.io) built on top of HTML/CSS. 64 | 65 | ## Web Data 66 | 67 | `/web-data` contains the data collection pipelines and the actual data being used in the VS Code [HTML extension](https://github.com/microsoft/vscode/tree/master/extensions/html-language-features) and [CSS extension](https://github.com/microsoft/vscode/tree/master/extensions/css-language-features). It pulls data from sources such as HTML/CSS spec and MDN and massages them into the custom data format ready to use. 68 | 69 | ## Updating Web Data 70 | 71 | - Run `yarn update-sources`, which updates `@mdn/browser-compat-data`, `mdn-data` and `attributeRelevance.js` 72 | - After all updates are done, run `yarn generate-data` 73 | - Review the diff. Make sure the updates look reasonable. If there are new properties, make sure that they don't have blank descriptions. There is no API for pulling descriptions. Each time you regenerate the data, if there are properties with missing descriptions, find its MDN page, go to https://github.com/microsoft/vscode-custom-data/blob/master/web-data/css/mdn/mdn-documentation.js and update it manually 74 | - Finally, commit and publish the data to [@vscode/web-custom-data](https://www.npmjs.com/package/@vscode/web-custom-data) on NPM. 75 | 76 | ## Contributing 77 | 78 | This project welcomes contributions and suggestions. Most contributions require you to agree to a 79 | Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us 80 | the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com. 81 | 82 | When you submit a pull request, a CLA bot will automatically determine whether you need to provide 83 | a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions 84 | provided by the bot. You will only need to do this once across all repos using our CLA. 85 | 86 | This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). 87 | For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or 88 | contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments. 89 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | ## Security 4 | 5 | Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet), [Xamarin](https://github.com/xamarin), and [many more](https://opensource.microsoft.com/). 6 | 7 | If you believe you have found a security vulnerability in any Microsoft-owned repository that meets Microsoft's [definition](https://docs.microsoft.com/en-us/previous-versions/tn-archive/cc751383(v=technet.10)) of a security vulnerability, please report it to us as described below. 8 | 9 | ## Reporting Security Issues 10 | 11 | **Please do not report security vulnerabilities through public GitHub issues.** Instead, please report them to the Microsoft Security Response Center at [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://technet.microsoft.com/en-us/security/dn606155). 12 | 13 | You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc). 14 | 15 | Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue: 16 | 17 | * Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.) 18 | * Full paths of source file(s) related to the manifestation of the issue 19 | * The location of the affected source code (tag/branch/commit or direct URL) 20 | * Any special configuration required to reproduce the issue 21 | * Step-by-step instructions to reproduce the issue 22 | * Proof-of-concept or exploit code (if possible) 23 | * Impact of the issue, including how an attacker might exploit the issue 24 | 25 | This information will help us triage your report more quickly. 26 | 27 | ## Preferred Languages 28 | 29 | We prefer all communications to be in English. 30 | 31 | ## Policy 32 | 33 | Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://www.microsoft.com/en-us/msrc/cvd). 34 | 35 | -------------------------------------------------------------------------------- /build/pipeline.yml: -------------------------------------------------------------------------------- 1 | name: $(Date:yyyyMMdd)$(Rev:.r) 2 | 3 | trigger: 4 | batch: true 5 | branches: 6 | include: 7 | - main 8 | pr: none 9 | 10 | resources: 11 | repositories: 12 | - repository: templates 13 | type: github 14 | name: microsoft/vscode-engineering 15 | ref: main 16 | endpoint: Monaco 17 | 18 | parameters: 19 | - name: publishPackage 20 | displayName: 🚀 Publish web-custom-data 21 | type: boolean 22 | default: false 23 | 24 | extends: 25 | template: azure-pipelines/npm-package/pipeline.yml@templates 26 | parameters: 27 | npmPackages: 28 | - name: web-custom-data 29 | 30 | testPlatforms: 31 | - name: Linux 32 | nodeVersions: 33 | - 20.x 34 | 35 | publishPackage: ${{ parameters.publishPackage }} 36 | publishRequiresApproval: false 37 | workingDirectory: $(Build.SourcesDirectory)/web-data 38 | -------------------------------------------------------------------------------- /media/css-completion.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-custom-data/d17efbb5d4da22adcdbf3316b2f0e91e2eac7325/media/css-completion.png -------------------------------------------------------------------------------- /samples/helloworld/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "html.customData": ["./html.html-data.json"], 3 | "css.customData": ["./css.css-data.json"] 4 | } 5 | -------------------------------------------------------------------------------- /samples/helloworld/README.md: -------------------------------------------------------------------------------- 1 | # Custom Data for HTML/CSS support in VS Code 2 | 3 | This demonstrates Custom HTML/CSS data support for VS Code. 4 | 5 | See https://code.visualstudio.com/updates/v1_31 for details. 6 | 7 | ## Usage 8 | 9 | - Open this folder in VS Code 1.31+ 10 | - Try completion/hover in the test.html and test.css 11 | - In `test.html`, try typing `` HTML tag. 12 | - In `test.css` try typing `my-` inside a selector to complete `my-size` CSS property. 13 | - Edit data in html.json and css.json and reload VS Code to reload the custom data 14 | 15 | ## Docs 16 | 17 | - [HTML Custom Data](https://github.com/Microsoft/vscode-html-languageservice/blob/master/docs/customData.md) 18 | - [CSS Custom Data](https://github.com/Microsoft/vscode-css-languageservice/blob/master/docs/customData.md) -------------------------------------------------------------------------------- /samples/helloworld/css.css-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1.1, 3 | "properties": [{ 4 | "name": "my-size", 5 | "description": "Compiles down to `width` and `height`. See details at https://github.com/postcss/postcss-size", 6 | "references": [ 7 | { 8 | "name": "GitHub", 9 | "url": "https://github.com/postcss/postcss-size" 10 | } 11 | ] 12 | }], 13 | "pseudoClasses": [{ 14 | "name": ":my-link", 15 | "description": ":any-link pseudo class. See details at https://preset-env.cssdb.org/features#any-link-pseudo-class" 16 | }] 17 | } -------------------------------------------------------------------------------- /samples/helloworld/html.html-data.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": 1.1, 3 | "tags": [ 4 | { 5 | "name": "my-button", 6 | "description": "My button. You should use it as in ``.", 7 | "attributes": [ 8 | { 9 | "name": "type", 10 | "description": "My button type", 11 | "values": [{ "name": "alert" }] 12 | } 13 | ], 14 | "references": [ 15 | { 16 | "name": "Bootstrap buttons", 17 | "url": "https://getbootstrap.com/docs/4.0/components/buttons/" 18 | } 19 | ] 20 | } 21 | ] 22 | } 23 | -------------------------------------------------------------------------------- /samples/helloworld/test.css: -------------------------------------------------------------------------------- 1 | :my-link { 2 | my-size: 4px; 3 | } -------------------------------------------------------------------------------- /samples/helloworld/test.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /samples/svg/.gitignore: -------------------------------------------------------------------------------- 1 | dist 2 | node_modules 3 | .vscode-test/ 4 | *.vsix 5 | -------------------------------------------------------------------------------- /samples/svg/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [{ 4 | "name": "Run Extension", 5 | "type": "extensionHost", 6 | "request": "launch", 7 | "runtimeExecutable": "${execPath}", 8 | "args": [ 9 | "--extensionDevelopmentPath=${workspaceFolder}" 10 | ], 11 | "outFiles": [ 12 | "${workspaceFolder}/out/**/*.js" 13 | ] 14 | }, 15 | { 16 | "name": "Update Data", 17 | "program": "${workspaceFolder}/dist/index.js", 18 | "request": "launch", 19 | "skipFiles": [ 20 | "/**" 21 | ], 22 | "type": "pwa-node", 23 | "preLaunchTask": "npm: compile" 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /samples/svg/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "html.customData": ["./data/svg.html-data.json"], 3 | "css.customData": ["./data/svg.css-data.json"], 4 | } 5 | -------------------------------------------------------------------------------- /samples/svg/.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | // See https://go.microsoft.com/fwlink/?LinkId=733558 2 | // for the documentation about the tasks.json format 3 | { 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "type": "npm", 8 | "script": "watch", 9 | "problemMatcher": "$tsc-watch", 10 | "isBackground": true, 11 | "presentation": { 12 | "reveal": "never" 13 | }, 14 | "group": { 15 | "kind": "build", 16 | "isDefault": true 17 | } 18 | } 19 | ] 20 | } -------------------------------------------------------------------------------- /samples/svg/README.md: -------------------------------------------------------------------------------- 1 | # SVG Sample 2 | 3 | SVG support in HTML/CSS files using plain JSON files. 4 | 5 | - HTML support: https://github.com/Microsoft/vscode/issues/62976 6 | - CSS support: https://github.com/Microsoft/vscode/issues/64164 7 | 8 | The data are pulled from: 9 | 10 | - SVG 2 [spec](https://www.w3.org/TR/SVG2/) and [GitHub](https://github.com/w3c/svgwg) 11 | - [MDN SVG reference](https://developer.mozilla.org/en-US/docs/Web/SVG) 12 | - [mdn/browser-compat-data](https://github.com/mdn/browser-compat-data) 13 | 14 | ## Usage 15 | 16 | - Open this folder in VS Code 1.31+ 17 | - Try editing the test.html or test.css files. You should get SVG tags and attributes in HTML files, and SVG specific CSS properties in CSS files. 18 | - Look into the `contributes` section of `package.json`. You can package this project into an extension with [`vsce`](https://code.visualstudio.com/api/working-with-extensions/publishing-extension#vsce). Alternatively, you can download the pre-packaged versions from [releases](https://github.com/octref/svg-data/releases). 19 | 20 | ## Docs 21 | 22 | - [HTML Custom Data](https://github.com/Microsoft/vscode-html-languageservice/blob/master/docs/customData.md) 23 | - [CSS Custom Data](https://github.com/Microsoft/vscode-css-languageservice/blob/master/docs/customData.md) 24 | 25 | ## License 26 | 27 | MIT -------------------------------------------------------------------------------- /samples/svg/build/index.ts: -------------------------------------------------------------------------------- 1 | import { getSVGSpec, HTMLElement, HTMLAttribute, CSSProperty } from './svg-spec' 2 | import { getMDNMDDescription } from './mdn-description' 3 | 4 | import { sleep } from './util' 5 | import * as path from 'path' 6 | import * as fs from 'fs' 7 | import { addCSSMDNData } from './mdn-data' 8 | 9 | /** 10 | * Get static CSS data from 11 | * - Spec 12 | * - mdn-data and mdn-browser-compat-data 13 | */ 14 | function getStaticHTMLData() { 15 | const { elements, globalAttributes } = getSVGSpec() 16 | 17 | return { 18 | elements, 19 | globalAttributes 20 | } 21 | } 22 | 23 | /** 24 | * Attach HTML descriptions from MDN to input properties 25 | */ 26 | async function attachAsyncHTMLDataFromMDN( 27 | elements: HTMLElement[], 28 | globalAttributes: HTMLAttribute[] 29 | ): Promise { 30 | // Collect all attribute 31 | const allAttributes = globalAttributes 32 | elements.forEach(el => { 33 | el.attributes.forEach(a => { 34 | if (!allAttributes.find(ta => ta.name === a.name)) { 35 | allAttributes.push(a) 36 | } 37 | }) 38 | }) 39 | 40 | for (let e of elements) { 41 | let desc 42 | try { 43 | desc = await getMDNMDDescription(e.name, 'tag') 44 | } catch (err) { 45 | return false 46 | } 47 | 48 | if (desc) { 49 | e.description = desc 50 | await sleep(1000) 51 | console.log(`Done with ${e.name} tag`) 52 | } 53 | } 54 | 55 | for (let a of allAttributes) { 56 | let desc 57 | try { 58 | desc = await getMDNMDDescription(a.name, 'attribute') 59 | } catch (err) { 60 | return false 61 | } 62 | 63 | if (desc) { 64 | a.description = desc 65 | await sleep(1000) 66 | console.log(`Done with ${a.name} attribute`) 67 | } 68 | } 69 | 70 | return true 71 | } 72 | 73 | async function generateHTMLData() { 74 | const { elements, globalAttributes } = getStaticHTMLData() 75 | const getMdnDataSuccess = attachAsyncHTMLDataFromMDN(elements, globalAttributes) 76 | 77 | if (!getMdnDataSuccess) { 78 | console.log('Failed to get data from MDN') 79 | return 80 | } 81 | 82 | const htmlOut = { 83 | version: 1.1, 84 | tags: elements, 85 | globalAttributes 86 | } 87 | 88 | console.log('Writing svg-html-contribution.json') 89 | fs.writeFileSync(path.resolve(__dirname, '../raw-data/svg-html-contribution.json'), JSON.stringify(htmlOut, null, 2)) 90 | console.log('Done writing svg-html-contribution.json') 91 | } 92 | 93 | /** 94 | * Get static CSS data from 95 | * - Spec 96 | * - mdn-data and mdn-browser-compat-data 97 | */ 98 | function getStaticCSSData(): CSSProperty[] { 99 | const { cssSpecProperties } = getSVGSpec() 100 | 101 | return cssSpecProperties.map(addCSSMDNData) 102 | } 103 | 104 | /** 105 | * Attach CSS descriptions from MDN to input properties 106 | */ 107 | async function attachAsyncCSSDataFromMDN(cssProperties: CSSProperty[]): Promise { 108 | for (let p of cssProperties) { 109 | let desc 110 | try { 111 | desc = await getMDNMDDescription(p.name, 'attribute') 112 | } catch (err) { 113 | return false 114 | } 115 | 116 | if (desc) { 117 | p.description = desc 118 | await sleep(1000) 119 | } 120 | console.log(`Done with ${p.name} property`) 121 | } 122 | 123 | return true 124 | } 125 | 126 | async function generateCSSData() { 127 | const cssProperties = getStaticCSSData() 128 | const getMdnDataSuccess = await attachAsyncCSSDataFromMDN(cssProperties) 129 | 130 | if (!getMdnDataSuccess) { 131 | console.log('Failed to get data from MDN') 132 | return 133 | } 134 | 135 | const cssOut = { 136 | version: 1.1, 137 | properties: cssProperties 138 | } 139 | 140 | console.log('Writing svg-css-contribution.json') 141 | fs.writeFileSync(path.resolve(__dirname, '../raw-data/svg-css-contribution.json'), JSON.stringify(cssOut, null, 2)) 142 | console.log('Done writing svg-css-contribution.json') 143 | } 144 | 145 | async function getHTMLData() { 146 | const { elements, globalAttributes } = getSVGSpec() 147 | 148 | for (let e of elements) { 149 | const desc = await getMDNMDDescription(e.name, 'tag') 150 | if (desc) { 151 | e.description = desc 152 | await sleep(1000) 153 | console.log(`Done with ${e.name} tag`) 154 | } 155 | } 156 | 157 | const allAttributes = globalAttributes 158 | elements.forEach(el => { 159 | el.attributes.forEach(a => { 160 | if (!allAttributes.find(ta => ta.name === a.name)) { 161 | allAttributes.push(a) 162 | } 163 | }) 164 | }) 165 | 166 | for (let a of allAttributes) { 167 | const desc = await getMDNMDDescription(a.name, 'attribute') 168 | if (desc) { 169 | a.description = desc 170 | await sleep(1000) 171 | console.log(`Done with ${a.name} attribute`) 172 | } 173 | } 174 | 175 | const htmlOut = { 176 | tags: elements, 177 | globalAttributes 178 | } 179 | 180 | fs.writeFileSync(path.resolve(__dirname, '../raw-data/svg-html-contribution.json'), JSON.stringify(htmlOut, null, 2)) 181 | } 182 | 183 | ;(async () => { 184 | await generateHTMLData() 185 | await generateCSSData() 186 | })() 187 | -------------------------------------------------------------------------------- /samples/svg/build/mdn-bcd.ts: -------------------------------------------------------------------------------- 1 | const bcd = require('@mdn/browser-compat-data') 2 | 3 | import * as fs from 'fs' 4 | import * as path from 'path' 5 | import { CSSProperty } from './svg-spec'; 6 | 7 | const el = bcd.svg.elements as any 8 | const at = bcd.svg.attributes as any 9 | 10 | function htmlExport() { 11 | const tags = [] 12 | for (let e in el) { 13 | tags.push({ 14 | label: e, 15 | description: `svg tag: ${e}`, 16 | attributes: [] 17 | }) 18 | } 19 | 20 | const serializedTags = JSON.stringify({ tags }, null, 2) 21 | 22 | fs.writeFileSync(path.resolve(__dirname, '../data/svg-tags.json'), serializedTags) 23 | 24 | const attributes = [] 25 | for (let category in at) { 26 | for (let a in at[category]) { 27 | attributes.push({ 28 | label: a, 29 | description: `svg attribute: ${a}` 30 | }) 31 | } 32 | } 33 | 34 | const serializedAttributes = JSON.stringify({ attributes }, null, 2) 35 | 36 | fs.writeFileSync(path.resolve(__dirname, '../data/svg-attributes.json'), serializedAttributes) 37 | } 38 | 39 | function cssExport() { 40 | const properties = [] 41 | for (let category in at) { 42 | for (let a in at[category]) { 43 | properties.push({ 44 | name: a, 45 | desc: `svg attribute: ${a}` 46 | }) 47 | } 48 | } 49 | 50 | const serializedProperties = JSON.stringify({ properties }, null, 2) 51 | fs.writeFileSync(path.resolve(__dirname, '../data/svg-properties.json'), serializedProperties) 52 | } 53 | 54 | // htmlExport() 55 | // cssExport() 56 | 57 | 58 | /** 59 | * In 60 | */ 61 | function addMDNData(properties: Partial[]) { 62 | 63 | } -------------------------------------------------------------------------------- /samples/svg/build/mdn-data.ts: -------------------------------------------------------------------------------- 1 | 2 | const mdnData = require('mdn-data'); 3 | const bcdData = require('@mdn/browser-compat-data') 4 | 5 | import { CSSProperty, CSSSpecProperty } from './svg-spec'; 6 | import { toCompatString, isSupportedInAllBrowsers } from './util'; 7 | 8 | const properties = mdnData.css.properties 9 | const bcdProperties = bcdData.css.properties 10 | 11 | export function addCSSMDNData(specProperty: CSSSpecProperty): CSSProperty { 12 | const property: CSSProperty = { ...specProperty } 13 | 14 | if (getPropertyStatus(specProperty.name)) { 15 | property.status = getPropertyStatus(specProperty.name) 16 | } 17 | if (getPropertySyntax(specProperty.name)) { 18 | property.syntax = getPropertySyntax(specProperty.name) 19 | } 20 | if (getPropertyBrowsers(specProperty.name)) { 21 | property.browsers = getPropertyBrowsers(specProperty.name) 22 | } 23 | 24 | return property 25 | } 26 | 27 | function getPropertyStatus(name: string) { 28 | if (properties[name]) { 29 | let status = properties[name].status; 30 | let mdnCompatEntry = bcdProperties[name]; 31 | if (!mdnCompatEntry) { 32 | for (const contextName in mdnCompatEntry) { 33 | if (mdnCompatEntry[contextName].__compat) { 34 | mdnCompatEntry = mdnCompatEntry[contextName].__compat; 35 | break; 36 | } 37 | } 38 | } 39 | 40 | const compatStatus = mdnCompatEntry?.status; 41 | if (compatStatus) { 42 | if (compatStatus.experimental) { 43 | status = 'experimental'; 44 | } else if (compatStatus.deprecated) { 45 | status = 'obsolete'; 46 | } else if (compatStatus.standard_track) { 47 | status = 'standard'; 48 | } else { 49 | status = 'nonstandard'; 50 | } 51 | } 52 | return status; 53 | } 54 | } 55 | 56 | function getPropertySyntax(name: string) { 57 | if (properties[name]) { 58 | return properties[name].syntax 59 | } 60 | } 61 | 62 | function getPropertyBrowsers(name: string) { 63 | if (bcdProperties[name]) { 64 | if (!isSupportedInAllBrowsers(bcdProperties[name])) { 65 | return toCompatString(bcdProperties[name]) 66 | } 67 | } 68 | } -------------------------------------------------------------------------------- /samples/svg/build/mdn-description.ts: -------------------------------------------------------------------------------- 1 | 2 | export type PropertyType = 'tag' | 'attribute' 3 | 4 | export async function getMDNMDDescription(name: string, type: PropertyType) { 5 | // todo; get a desscription, e.g. from https://github.com/mdn/content/edit/main/files/en-us/web/svg/attribute/{name}/index.md 6 | return null; 7 | } 8 | -------------------------------------------------------------------------------- /samples/svg/build/postprocess.ts: -------------------------------------------------------------------------------- 1 | import * as fs from 'fs' 2 | import * as path from 'path' 3 | 4 | const htmlData = require(path.resolve(__dirname, '../raw-data/svg-html-contribution.json')) 5 | const cssData = require(path.resolve(__dirname, '../raw-data/svg-css-contribution.json')) 6 | 7 | function transform(entry : any) { 8 | const result = { 9 | kind: 'markdown', 10 | value: '' 11 | } 12 | 13 | if (entry.description) { 14 | result.value += entry.description 15 | } 16 | 17 | if (entry.syntax) { 18 | result.value += `\n\nSyntax: ${entry.syntax}` 19 | delete entry.syntax 20 | } 21 | 22 | if (entry.status) { 23 | result.value += `\n\nStatus: ${entry.status}` 24 | delete entry.status 25 | } 26 | 27 | if (entry.browsers) { 28 | result.value += `\n\nSupported browsers: ${entry.browsers.join(',')}` 29 | delete entry.browsers 30 | } 31 | console.log(result.value) 32 | 33 | entry.description = result 34 | } 35 | 36 | cssData.properties.forEach(transform) 37 | 38 | // fs.writeFileSync(path.resolve(__dirname, '../data/svg.html-data.json'), JSON.stringify(htmlData, null, 2)); 39 | fs.writeFileSync(path.resolve(__dirname, '../data/svg.css-data.json'), JSON.stringify(cssData, null, 2)); 40 | console.log('Done') -------------------------------------------------------------------------------- /samples/svg/build/svg-spec.ts: -------------------------------------------------------------------------------- 1 | import * as path from 'path' 2 | import * as fs from 'fs' 3 | 4 | const DEFINITION_PATH = path.resolve(__dirname, '../raw-data/definitions.xml') 5 | 6 | import * as cheerio from 'cheerio' 7 | 8 | interface Reference { 9 | name: string 10 | url: string 11 | } 12 | 13 | export interface HTMLElement { 14 | name: string 15 | description?: string 16 | attributes: HTMLAttribute[] 17 | attributeCategories: string[] 18 | references?: Reference[] 19 | } 20 | 21 | export interface HTMLAttribute { 22 | name: string 23 | description?: string 24 | references?: Reference[] 25 | } 26 | 27 | interface HTMLAttributeCategory { 28 | name: string 29 | attributes: HTMLAttribute[] 30 | references?: Reference[] 31 | } 32 | 33 | export interface CSSProperty { 34 | name: string 35 | description?: string 36 | browsers?: string[] 37 | status?: string 38 | syntax?: string 39 | values?: CSSPropertyValue[] 40 | references?: Reference[] 41 | } 42 | 43 | export interface CSSSpecProperty { 44 | name: string 45 | references?: Reference[] 46 | } 47 | 48 | export interface CSSPropertyValue { 49 | name: string 50 | descriptipn: string 51 | references?: Reference[] 52 | } 53 | 54 | const globalAttributes: HTMLAttribute[] = [] 55 | const attributeCategories: HTMLAttributeCategory[] = [] 56 | const elements: HTMLElement[] = [] 57 | const cssSpecProperties: CSSSpecProperty[] = [] 58 | 59 | function handleHref(href: string) { 60 | return href.startsWith('https://') ? href : 'https://www.w3.org/TR/SVG/' + href 61 | } 62 | 63 | function parseStringList(str: string) { 64 | return str.split(',').map(s => s.trim()) 65 | } 66 | 67 | 68 | export function getSVGSpec() { 69 | const src = fs.readFileSync(DEFINITION_PATH, 'utf-8') 70 | const $ = cheerio.load(src, { 71 | xmlMode: true 72 | }) 73 | 74 | $('definitions > attribute').each((_, e) => { 75 | const x = $(e), name = x.attr('name'), href = x.attr('href'); 76 | if (name && href) { 77 | globalAttributes.push({ 78 | name, 79 | references: [ 80 | { 81 | name: 'SVG Spec', 82 | url: handleHref(href) 83 | } 84 | ] 85 | }) 86 | } 87 | 88 | 89 | }) 90 | 91 | $('attributecategory').each((_, e) => { 92 | const x = $(e), name = x.attr('name'), href = x.attr('href'); 93 | if (name && href) { 94 | const attrCate = { 95 | name, 96 | attributes: [] as any, 97 | references: [ 98 | { 99 | name: 'SVG Spec', 100 | url: handleHref(href) 101 | } 102 | ] 103 | } 104 | 105 | $(e) 106 | .find('attribute') 107 | .each((_, e) => { 108 | const x = $(e), name = x.attr('name'), href = x.attr('href'); 109 | if (name && href) { 110 | attrCate.attributes.push({ 111 | name, 112 | references: [ 113 | { 114 | name: 'SVG Spec', 115 | url: handleHref(href) 116 | } 117 | ] 118 | }) 119 | } 120 | }) 121 | 122 | 123 | attributeCategories.push(attrCate) 124 | } 125 | 126 | }) 127 | 128 | $('element').each((_, e) => { 129 | const x = $(e), name = x.attr('name'), href = x.attr('href'), attributes = x.attr('attributes'), attributecategories = x.attr('attributecategories'); 130 | if (name && href) { 131 | const el = { 132 | name, 133 | attributes: [] as HTMLAttribute[], 134 | attributeCategories: [] as string[], 135 | references: [ 136 | { 137 | name: 'SVG Spec', 138 | url: handleHref(href) 139 | } 140 | ] 141 | } 142 | 143 | if (attributes) { 144 | parseStringList(attributes).forEach(s => { 145 | const matchingAttr = globalAttributes.find(a => a.name === s) 146 | if (matchingAttr) { 147 | el.attributes.push(matchingAttr) 148 | } 149 | }) 150 | } 151 | 152 | $(e) 153 | .find('attribute') 154 | .each((_, ea) => { 155 | const x = $(ea), name = x.attr('name'), href = x.attr('href'); 156 | if (name && href) { 157 | el.attributes.push({ 158 | name, 159 | references: [ 160 | { 161 | name: 'SVG Spec', 162 | url: handleHref(href) 163 | } 164 | ] 165 | }) 166 | } 167 | }) 168 | 169 | if (attributecategories) { 170 | parseStringList(attributecategories).forEach(s => { 171 | el.attributeCategories.push(s) 172 | }) 173 | } 174 | 175 | elements.push(el) 176 | } 177 | }) 178 | 179 | $('property').each((_, e) => { 180 | const x = $(e), name = x.attr('name'), href = x.attr('href'); 181 | if (name && href) { 182 | cssSpecProperties.push({ 183 | name, 184 | references: [ 185 | { 186 | name: 'SVG Spec', 187 | url: handleHref(href) 188 | } 189 | ] 190 | }) 191 | 192 | } 193 | }) 194 | 195 | return { 196 | elements, 197 | globalAttributes, 198 | cssSpecProperties 199 | } 200 | } 201 | -------------------------------------------------------------------------------- /samples/svg/build/util.ts: -------------------------------------------------------------------------------- 1 | export function sleep(ms: number) { 2 | return new Promise(resolve => { 3 | setTimeout(() => { 4 | resolve() 5 | }, ms) 6 | }) 7 | } 8 | 9 | const browserNames : { [browser: string]: string }= { 10 | E: 'Edge', 11 | FF: 'Firefox', 12 | S: 'Safari', 13 | C: 'Chrome', 14 | IE: 'IE', 15 | O: 'Opera' 16 | } 17 | 18 | export function toCompatString(bcdProperty: any) :string[] { 19 | let s : string[] = [] 20 | 21 | if (bcdProperty.__compat) { 22 | Object.keys(browserNames).forEach((abbrev) => { 23 | const browserName = browserNames[abbrev].toLowerCase() 24 | const browserSupport = bcdProperty.__compat.support[browserName] 25 | if (browserSupport) { 26 | const shortCompatString = supportToShortCompatString(browserSupport, abbrev) 27 | if (shortCompatString) { 28 | s.push(shortCompatString) 29 | } 30 | } 31 | }) 32 | } else { 33 | Object.keys(browserNames).forEach((abbrev) => { 34 | const browserName = browserNames[abbrev].toLowerCase() 35 | 36 | // Select the most recent versions from all contexts as the short compat string 37 | let shortCompatStringAggregatedFromContexts : string | undefined; 38 | 39 | Object.keys(bcdProperty).forEach(contextName => { 40 | const context = bcdProperty[contextName] 41 | if (context.__compat && context.__compat.support[browserName]) { 42 | const browserSupport = context.__compat.support[browserName] 43 | const shortCompatString = supportToShortCompatString(browserSupport, abbrev) 44 | if (!shortCompatStringAggregatedFromContexts || shortCompatString > shortCompatStringAggregatedFromContexts) { 45 | shortCompatStringAggregatedFromContexts = shortCompatString 46 | } 47 | } 48 | }) 49 | 50 | if (shortCompatStringAggregatedFromContexts) { 51 | s.push(shortCompatStringAggregatedFromContexts) 52 | } 53 | }) 54 | 55 | } 56 | return s; 57 | } 58 | 59 | /** 60 | * Check that a property is supported in all major browsers: Edge, Firefox, Safari, Chrome, IE, Opera 61 | */ 62 | export function isSupportedInAllBrowsers(bcdProperty: any) { 63 | if (bcdProperty.__compat) { 64 | return Object.keys(browserNames).every((abbrev) => { 65 | const browserName = browserNames[abbrev].toLowerCase() 66 | if (bcdProperty.__compat && bcdProperty.__compat.support[browserName]) { 67 | const browserSupport = bcdProperty.__compat.support[browserName] 68 | if (browserSupport) { 69 | return isSupported(browserSupport) 70 | } 71 | } 72 | 73 | return false 74 | }) 75 | } else { 76 | return Object.keys(browserNames).every((abbrev) => { 77 | const browserName = browserNames[abbrev].toLowerCase() 78 | 79 | return Object.keys(bcdProperty).some(contextName => { 80 | const context = bcdProperty[contextName] 81 | if (context.__compat && context.__compat.support[browserName]) { 82 | const browserSupport = context.__compat.support[browserName] 83 | if (browserSupport) { 84 | return isSupported(browserSupport) 85 | } 86 | } 87 | 88 | return false 89 | }) 90 | }) 91 | } 92 | } 93 | 94 | /** 95 | * https://github.com/mdn/browser-compat-data/blob/master/schemas/compat-data-schema.md 96 | * 97 | * Convert a support statement to a short compat string. 98 | * For example: 99 | * { "ie": { "version_added": "6.0" } } => "IE6.0" 100 | * { 101 | * "support": { 102 | * "firefox": [ 103 | * { 104 | * "version_added": "6" 105 | * }, 106 | * { 107 | * "prefix": "-moz-", 108 | * "version_added": "3.5", 109 | * "version_removed": "9" 110 | * } 111 | * ] 112 | * } 113 | * } => "FF6" 114 | */ 115 | function supportToShortCompatString(support: any, browserAbbrev: any) { 116 | let version_added 117 | if (Array.isArray(support) && support[0] && support[0].version_added) { 118 | version_added = support[0].version_added 119 | } else if (support.version_added) { 120 | version_added = support.version_added 121 | } 122 | 123 | if (version_added) { 124 | if (typeof(version_added) === 'boolean') { 125 | return browserAbbrev 126 | } else { 127 | return `${browserAbbrev}${version_added}` 128 | } 129 | } 130 | 131 | return null 132 | } 133 | 134 | function isSupported(support: any) { 135 | let version_added 136 | if (Array.isArray(support) && support[0] && support[0].version_added) { 137 | version_added = support[0].version_added 138 | } else if (support.version_added) { 139 | version_added = support.version_added 140 | } 141 | 142 | if (version_added) { 143 | if (typeof(version_added) === 'boolean') { 144 | return version_added 145 | } else if (typeof(version_added) === 'string') { 146 | if (typeof(parseInt(version_added)) === 'number') { 147 | return true 148 | } 149 | } 150 | } 151 | 152 | return false 153 | } -------------------------------------------------------------------------------- /samples/svg/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svg", 3 | "displayName": "svg", 4 | "description": "svg", 5 | "version": "0.1.0", 6 | "publisher": "octref", 7 | "repository": "https://github.com/Microsoft/vscode-extension-samples/helloworld-sample", 8 | "license": "MIT", 9 | "engines": { 10 | "vscode": "^1.25.0" 11 | }, 12 | "categories": [ 13 | "Other" 14 | ], 15 | "contributes": { 16 | "html": { 17 | "customData": [ 18 | "./data/svg-html-contribution.json" 19 | ] 20 | }, 21 | "css": { 22 | "customData": [ 23 | "./data/svg-css-contribution.json" 24 | ] 25 | } 26 | }, 27 | "scripts": { 28 | "vscode:prepublish": "npm run compile", 29 | "compile": "tsc -p ./", 30 | "watch": "tsc -watch -p ./", 31 | "update-data": "npm run compile && node ./dist/index.js" 32 | }, 33 | "devDependencies": { 34 | "@mdn/browser-compat-data": "^5.3.13", 35 | "@types/cheerio": "^0.22.31", 36 | "@types/got": "^9.6.12", 37 | "@types/node": "^18.11.18", 38 | "@types/turndown": "^5.0.1", 39 | "@types/vscode": "^1.81.0", 40 | "cheerio": "1.0.0-rc.12", 41 | "mdn-data": "^2.0.33", 42 | "turndown": "^7.1.2", 43 | "typescript": "^5.2.2" 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /samples/svg/test.css: -------------------------------------------------------------------------------- 1 | .foo { 2 | baseline 3 | } -------------------------------------------------------------------------------- /samples/svg/test.html: -------------------------------------------------------------------------------- 1 | ` or `` completions yet. 46 | - [ ] No emmet support yet. Tracked in https://github.com/Microsoft/vscode/issues/64032. 47 | - [ ] There's no description for events yet. 48 | -------------------------------------------------------------------------------- /samples/webcomponents/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/vscode-custom-data/d17efbb5d4da22adcdbf3316b2f0e91e2eac7325/samples/webcomponents/demo.gif -------------------------------------------------------------------------------- /samples/webcomponents/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | April 1, 2014 15 | 16 | 17 | 18 | April 1, 2024 19 | 20 | 21 | 22 | April 1, 2014 23 | 24 | 25 | 26 | April 1, 2014 27 | 28 | 29 | 35 | April 1, 2014 4:30PM PDT 36 | 37 | 38 | -------------------------------------------------------------------------------- /samples/webcomponents/node_modules/@github/time-elements/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2018 GitHub, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /samples/webcomponents/node_modules/@github/time-elements/README.md: -------------------------------------------------------------------------------- 1 | # <time> element extensions 2 | 3 | Formats a timestamp as a localized string or as relative text that auto-updates in the user's browser. 4 | 5 | This allows the server to cache HTML fragments containing dates and lets the browser choose how to localize the displayed time according to the user's preferences. For example, the server may have cached the following generated markup: 6 | 7 | ```html 8 | 9 | April 1, 2014 4:30pm 10 | 11 | ``` 12 | 13 | Every visitor is served the same markup from the server's cache. When it reaches the browser, the custom `local-time` JavaScript localizes the element's text into the local timezone and formatting. 14 | 15 | ```html 16 | 17 | 1 Apr 2014 21:30 18 | 19 | ``` 20 | 21 | Dates are displayed before months, and a 24-hour clock is used, according to the user's browser settings. 22 | 23 | If the browser's JavaScript is disabled, the default text served in the cached markup is still displayed. 24 | 25 | ## Installation 26 | 27 | Available on [npm](https://www.npmjs.com/) as [**@github/time-elements**](https://www.npmjs.com/package/@github/time-elements). 28 | 29 | ``` 30 | $ npm install @github/time-elements 31 | ``` 32 | 33 | ## Usage 34 | 35 | This component provides three custom subtypes of the standard HTML `