diff --git a/build/generate_browserjs.js b/build/generate_browserjs.js index 441e91a9..f7981f01 100644 --- a/build/generate_browserjs.js +++ b/build/generate_browserjs.js @@ -3,14 +3,13 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ /* global __dirname */ -var fs = require('fs'); -var path = require('path'); -var xml2js = require('xml2js'); -var os = require('os'); -var util = require('util'); +const fs = require('fs') +const path = require('path') +const xml2js = require('xml2js') +const os = require('os') // keep in sync with data from language facts -var colors = { +const colors = { aliceblue: '#f0f8ff', antiquewhite: '#faebd7', aqua: '#00ffff', @@ -159,9 +158,9 @@ var colors = { whitesmoke: '#f5f5f5', yellow: '#ffff00', yellowgreen: '#9acd32' -}; +} -var otherColors = { +const otherColors = { "ActiveBorder": "Active window border.", "ActiveCaption": "Active window caption.", "AppWorkspace": "Background color of multiple document interface.", @@ -199,196 +198,198 @@ var otherColors = { "-webkit-focus-ring-color": '', "-webkit-link": '', "-webkit-text": '' -}; +} function clone(obj) { - var copy = {}; - for (var i in obj) { - copy[i] = obj[i]; - } - return copy; + var copy = {} + for (var i in obj) { + copy[i] = obj[i] + } + return copy } function getProperties(obj) { - var res = []; - for (var i in obj) { - res.push(i); - } - return res; + var res = [] + for (var i in obj) { + res.push(i) + } + return res } function getValues(valArr, restriction, ruleName) { - if (!Array.isArray(valArr)) { - if (valArr.$) { - valArr = [ valArr ]; - } else { - return []; - } - } - var vals = valArr.map(function (v) { - return { - name: v.$.name, - desc: v.desc, - browsers: v.$.browsers !== 'all' ? v.$.browsers : void 0 - }; - }).filter(function (v) { - if (v.browsers === 'none') { - return false; - } - return true; - }); - if (restriction.indexOf('color') !== -1) { + if (!Array.isArray(valArr)) { + if (valArr.$) { + valArr = [valArr] + } else { + return [] + } + } + var vals = valArr + .map(function(v) { + return { + name: v.$.name, + desc: v.desc, + browsers: v.$.browsers !== 'all' ? v.$.browsers : void 0 + } + }) + .filter(function(v) { + if (v.browsers === 'none') { + return false + } + return true + }) + if (restriction.indexOf('color') !== -1) { + var colorsCopy = clone(colors) + var otherColorsCopy = clone(otherColors) - var colorsCopy = clone(colors); - var otherColorsCopy = clone(otherColors); + var moreColors = {} - var moreColors = {}; + vals = vals.filter(function(v) { + if (typeof colorsCopy[v.name] === 'string') { + delete colorsCopy[v.name] + return false + } + if (typeof otherColorsCopy[v.name] === 'string') { + delete otherColorsCopy[v.name] + return false + } + moreColors[v.name] = v.desc + return true + }) + var notCovered = [] + for (var i in colorsCopy) { + notCovered.push(i) + } + for (var i in otherColorsCopy) { + notCovered.push(i) + } + if (notCovered.length > 0) { + console.log('***' + ruleName + ' uncovered: ' + notCovered.length) // + ' - ' + JSON.stringify(notCovered)); + } - vals = vals.filter(function (v) { - if (typeof colorsCopy[v.name] === 'string') { - delete colorsCopy[v.name]; - return false; - } - if (typeof otherColorsCopy[v.name] === 'string') { - delete otherColorsCopy[v.name]; - return false; - } - moreColors[v.name] = v.desc; - return true; - }); - var notCovered = []; - for (var i in colorsCopy) { - notCovered.push(i); - } - for (var i in otherColorsCopy) { - notCovered.push(i); - } - if (notCovered.length > 0) { - console.log('***' + ruleName + ' uncovered: ' + notCovered.length); // + ' - ' + JSON.stringify(notCovered)); - } + if (restriction === 'color') { + var properties = getProperties(moreColors) - if (restriction === 'color') { - var properties = getProperties(moreColors); + console.log('---' + ruleName + ' others : ' + properties.length) // + ' - ' + JSON.stringify(properties)); + } + } - console.log('---' + ruleName + ' others : ' + properties.length); // + ' - ' + JSON.stringify(properties)); - } - } - - return vals; + return vals } function internalizeDescriptions(entries) { - var descriptions = {}; - var conflicts = {}; - entries.forEach(function (e) { - if (e.values) { - e.values.forEach(function (d) { - if (!d.desc) { - conflicts[d.name] = true; - return; - } - var existing = descriptions[d.name]; - if (existing) { - if (existing !== d.desc) { - conflicts[d.name] = true; - } - } - descriptions[d.name] = d.desc; - }); - } - }); - entries.forEach(function (e) { - if (e.values) { - e.values.forEach(function (d) { - if (!conflicts[d.name]) { - delete d.desc; - } else { - delete descriptions[d.name]; - } - }); - } - }); - return descriptions; + var descriptions = {} + var conflicts = {} + entries.forEach(function(e) { + if (e.values) { + e.values.forEach(function(d) { + if (!d.desc) { + conflicts[d.name] = true + return + } + var existing = descriptions[d.name] + if (existing) { + if (existing !== d.desc) { + conflicts[d.name] = true + } + } + descriptions[d.name] = d.desc + }) + } + }) + entries.forEach(function(e) { + if (e.values) { + e.values.forEach(function(d) { + if (!conflicts[d.name]) { + delete d.desc + } else { + delete descriptions[d.name] + } + }) + } + }) + return descriptions } function toSource(object, keyName) { - if (!object.css[keyName]) { - return []; - } - var result = []; - var entryArr = object.css[keyName].entry; - entryArr.forEach(function (e) { - if (e.$.browsers === 'none') { - return; - } - var data = { - name: e.$.name, - desc: e.desc, - browsers: e.$.browsers !== 'all' ? e.$.browsers : void 0 - }; - if (e.$.restriction) { - data.restriction= e.$.restriction; - } - if (e.values) { - data.values= getValues(e.values.value, data.restriction || '', data.name); - } - - result.push(data); - }); + if (!object.css[keyName]) { + return [] + } + var result = [] + var entryArr = object.css[keyName].entry + entryArr.forEach(function(e) { + if (e.$.browsers === 'none') { + return + } + var data = { + name: e.$.name, + desc: e.desc, + browsers: e.$.browsers !== 'all' ? e.$.browsers : void 0 + } + if (e.$.restriction) { + data.restriction = e.$.restriction + } + if (e.values) { + data.values = getValues(e.values.value, data.restriction || '', data.name) + } - return result; + result.push(data) + }) + return result } -var parser = new xml2js.Parser({explicitArray : false}); -var schemaFileName= 'css-schema.xml'; +const parser = new xml2js.Parser({ explicitArray: false }) +const schemaFileName = 'css-schema.xml' -var { buildPropertiesWithMDNData } = require('./mdn-data-importer') +const { buildPropertiesWithMDNData } = require('./mdn-data-importer') +const { addBrowserCompatDataToProperties } = require('./mdn-browser-compat-data-importer') fs.readFile(path.resolve(__dirname, schemaFileName), function(err, data) { - parser.parseString(data, function (err, result) { + parser.parseString(data, function(err, result) { + const atdirectives = toSource(result, 'atDirectives') + const pseudoclasses = toSource(result, 'pseudoClasses') + const pseudoelements = toSource(result, 'pseudoElements') - //console.log(util.inspect(result, {depth: null})); //Work + let properties = toSource(result, 'properties') + properties = buildPropertiesWithMDNData(properties) - var atdirectives = toSource(result, 'atDirectives'); - var pseudoclasses = toSource(result, 'pseudoClasses'); - var pseudoelements = toSource(result, 'pseudoElements'); - var properties = toSource(result, 'properties'); + addBrowserCompatDataToProperties(atdirectives, pseudoclasses, pseudoelements, properties) - var descriptions = internalizeDescriptions([].concat(atdirectives, pseudoclasses, pseudoelements, properties)); + const descriptions = internalizeDescriptions([].concat(atdirectives, pseudoclasses, pseudoelements, properties)) - var resultObject = { - css: { - atdirectives: atdirectives, - pseudoclasses: pseudoclasses, - pseudoelements: pseudoelements, - properties: buildPropertiesWithMDNData(properties) - } - }; + const resultObject = { + css: { + atdirectives, + pseudoclasses, + pseudoelements, + properties, + } + } - function toJavaScript(obj) { - var str = JSON.stringify(obj, null, '\t'); - return str.replace(/\"(name|desc|browsers|restriction|values)\"/g, '$1'); - } - - var descriptionsStr = JSON.stringify(descriptions, null, '\t'); + function toJavaScript(obj) { + const str = JSON.stringify(obj, null, '\t') + return str.replace(/\"(name|desc|browsers|restriction|values)\"/g, '$1') + } - var output = [ - '/*---------------------------------------------------------------------------------------------', - ' * Copyright (c) Microsoft Corporation. All rights reserved.', - ' * Licensed under the MIT License. See License.txt in the project root for license information.', - ' *--------------------------------------------------------------------------------------------*/', - '// file generated from ' + schemaFileName + ' and https://github.com/mdn/data using css-exclude_generate_browserjs.js', - '', - 'export const data : any = ' + toJavaScript(resultObject) + ';', - 'export const descriptions : any = ' + toJavaScript(descriptions) + ';', - ]; + const output = [ + '/*---------------------------------------------------------------------------------------------', + ' * Copyright (c) Microsoft Corporation. All rights reserved.', + ' * Licensed under the MIT License. See License.txt in the project root for license information.', + ' *--------------------------------------------------------------------------------------------*/', + '// file generated from ' + + schemaFileName + + ' and https://github.com/mdn/data using css-exclude_generate_browserjs.js', + '', + 'export const data : any = ' + toJavaScript(resultObject) + ';', + 'export const descriptions : any = ' + toJavaScript(descriptions) + ';' + ] - var outputPath = path.resolve(__dirname, '../src/data/browsers.ts'); - console.log('Writing to: ' + outputPath); - var content = output.join(os.EOL); - fs.writeFileSync(outputPath, content); - console.log('Done'); - }); -}); \ No newline at end of file + var outputPath = path.resolve(__dirname, '../src/data/browsers.ts') + console.log('Writing to: ' + outputPath) + var content = output.join(os.EOL) + fs.writeFileSync(outputPath, content) + console.log('Done') + }) +}) \ No newline at end of file diff --git a/build/mdn-browser-compat-data-importer.js b/build/mdn-browser-compat-data-importer.js new file mode 100644 index 00000000..e162ce44 --- /dev/null +++ b/build/mdn-browser-compat-data-importer.js @@ -0,0 +1,155 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +const bcd = require('mdn-browser-compat-data') + +function addBrowserCompatDataToProperties(atdirectives, pseudoclasses, pseudoelements, properties) { + atdirectives.forEach(item => { + if (bcd.css['at-rules'][item.name.slice(1)]) { + const matchingBCDItem = bcd.css['at-rules'][item.name.slice(1)] + addBCDToBrowsers(item, matchingBCDItem) + } + }) + + pseudoclasses.forEach(item => { + if (bcd.css.selectors[item.name.slice(1)]) { + const matchingBCDItem = bcd.css.selectors[item.name.slice(1)] + addBCDToBrowsers(item, matchingBCDItem) + } + }) + + pseudoelements.forEach(item => { + if (bcd.css.selectors[item.name.slice(2)]) { + const matchingBCDItem = bcd.css.selectors[item.name.slice(2)] + addBCDToBrowsers(item, matchingBCDItem) + } + }) + + properties.forEach(item => { + if (bcd.css.properties[item.name]) { + const matchingBCDItem = bcd.css.properties[item.name] + addBCDToBrowsers(item, matchingBCDItem) + } + }) +} + +const browserNames = { + E: 'Edge', + FF: 'Firefox', + S: 'Safari', + C: 'Chrome', + IE: 'IE', + O: 'Opera' +} + +function addBCDToBrowsers(item, matchingBCDItem) { + const compatString = toCompatString(matchingBCDItem) + + if (compatString !== '') { + if (!item.browsers) { + item.browsers = compatString + } else { + if (item.browsers !== compatString) { + item.browsers = compatString + } + } + } +} + +function toCompatString(bcdProperty) { + if (isSupportedInAllBrowsers(bcdProperty)) { + return 'all' + } + + let s = [] + Object.keys(browserNames).forEach((abbrev) => { + if (bcdProperty.__compat && bcdProperty.__compat.support[browserNames[abbrev].toLowerCase()]) { + const browserSupport = bcdProperty.__compat.support[browserNames[abbrev].toLowerCase()] + if (browserSupport) { + const shortCompatString = supportToShortCompatString(browserSupport, abbrev) + if (shortCompatString) { + s.push(shortCompatString) + } + } + } + }) + return s.join(',') +} + +function isSupportedInAllBrowsers(bcdProperty) { + return Object.keys(browserNames).every((abbrev) => { + if (bcdProperty.__compat && bcdProperty.__compat.support[browserNames[abbrev].toLowerCase()]) { + const browserSupport = bcdProperty.__compat.support[browserNames[abbrev].toLowerCase()] + if (browserSupport) { + return isSupported(browserSupport) + } + } + + return false + }) +} + +/** + * https://github.com/mdn/browser-compat-data/blob/master/schemas/compat-data-schema.md + * + * Convert a support statement to a short compat string. + * For example: + * { "ie": { "version_added": "6.0" } } => "IE6.0" + * { + * "support": { + * "firefox": [ + * { + * "version_added": "6" + * }, + * { + * "prefix": "-moz-", + * "version_added": "3.5", + * "version_removed": "9" + * } + * ] + * } + * } => "FF6" + */ +function supportToShortCompatString(support, browserAbbrev) { + let version_added + if (Array.isArray(support) && support[0] && support[0].version_added) { + version_added = support[0].version_added + } else if (support.version_added) { + version_added = support.version_added + } + + if (version_added) { + if (typeof(version_added) === 'boolean') { + return browserAbbrev + } else { + return `${browserAbbrev}${version_added}` + } + } + + return null +} + +function isSupported(support) { + let version_added + if (Array.isArray(support) && support[0] && support[0].version_added) { + version_added = support[0].version_added + } else if (support.version_added) { + version_added = support.version_added + } + + if (version_added) { + if (typeof(version_added) === 'boolean') { + return version_added + } else if (typeof(version_added) === 'string') { + if (typeof(parseInt(version_added)) === 'number') { + return true + } + } + } + + return false +} + +module.exports.addBrowserCompatDataToProperties = addBrowserCompatDataToProperties \ No newline at end of file diff --git a/build/mdn-data-importer.js b/build/mdn-data-importer.js index 31f602ce..29029c3f 100644 --- a/build/mdn-data-importer.js +++ b/build/mdn-data-importer.js @@ -3,13 +3,10 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -const path = require('path') -const fs = require('fs') - const mdnDocumentations = require('./mdn-documentation') const mdnExcludedProperties = [ - '--*', // custom properties + '--*' // custom properties ] function buildPropertiesWithMDNData(vscProperties) { @@ -89,7 +86,7 @@ function abbreviateStatus(status) { nonstandard: 'n', experimental: 'e', obsolete: 'o' - }[status]; + }[status] } module.exports = { diff --git a/build/post-publish.js b/build/post-publish.js index e7eb46ee..c148f01c 100644 --- a/build/post-publish.js +++ b/build/post-publish.js @@ -3,32 +3,30 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -const cp = require('child_process'); -const path = require('path'); -const fs = require('fs'); -const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm'; +const cp = require('child_process') +const path = require('path') +const fs = require('fs') +const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm' function updateNextTag() { + // read package.json from the current working directory + var packageJSON = JSON.parse(fs.readFileSync('package.json').toString()) + var name = packageJSON.name + var version = packageJSON.version + if (version.indexOf('next') !== -1) { + return + } - // read package.json from the current working directory - var packageJSON = JSON.parse(fs.readFileSync('package.json').toString()); - var name = packageJSON.name; - var version = packageJSON.version; - if (version.indexOf('next') !== -1) { - return; - } + opts = {} + opts.stdio = 'inherit' - opts = {}; - opts.stdio = 'inherit'; + console.log(name + ": set 'next' tag to latest version") - console.log(name + ": set 'next' tag to latest version"); + const result = cp.spawnSync(npm, ['dist-tags', 'add', name + '@' + version, 'next'], opts) - const result = cp.spawnSync(npm, ['dist-tags', 'add', name + '@' + version, 'next'], opts); - - if (result.error || result.status !== 0) { - process.exit(1); - } + if (result.error || result.status !== 0) { + process.exit(1) + } } -updateNextTag(); - +updateNextTag() diff --git a/package.json b/package.json index 8faba678..960ec339 100644 --- a/package.json +++ b/package.json @@ -18,6 +18,7 @@ "@types/mocha": "^2.2.33", "@types/node": "^7.0.43", "istanbul": "^0.4.5", + "mdn-browser-compat-data": "^0.0.38", "mdn-data": "^1.1.2", "mkdirp": "^0.5.1", "mocha": "^5.2.0", diff --git a/src/data/browsers.ts b/src/data/browsers.ts index 8545432e..ddbf6ce1 100644 --- a/src/data/browsers.ts +++ b/src/data/browsers.ts @@ -9,7 +9,8 @@ export const data : any = { "atdirectives": [ { name: "@charset", - desc: "Defines character set of the document." + desc: "Defines character set of the document.", + browsers: "FF1.5,S4,C2,IE5.5,O9" }, { name: "@counter-style", @@ -18,25 +19,28 @@ export const data : any = { }, { name: "@font-face", - desc: "Allows for linking to fonts that are automatically activated when needed. This permits authors to work around the limitation of 'web-safe' fonts, allowing for consistent rendering independent of the fonts available in a given user's environment." + desc: "Allows for linking to fonts that are automatically activated when needed. This permits authors to work around the limitation of 'web-safe' fonts, allowing for consistent rendering independent of the fonts available in a given user's environment.", + browsers: "all" }, { name: "@font-feature-values", desc: "Defines named values for the indices used to select alternate glyphs for a given font family.", - browsers: "FF34" + browsers: "FF34,S9.1" }, { name: "@import", - desc: "Includes content of another file." + desc: "Includes content of another file.", + browsers: "all" }, { name: "@keyframes", desc: "Defines set of animation key frames.", - browsers: "E,C43,FF16,IE10,O30,S9" + browsers: "all" }, { name: "@media", - desc: "Defines a stylesheet for a particular media type." + desc: "Defines a stylesheet for a particular media type.", + browsers: "all" }, { name: "@-moz-document", @@ -56,7 +60,7 @@ export const data : any = { { name: "@namespace", desc: "Declares a prefix and associates it with a namespace name.", - browsers: "E,C,FF1,IE9,O8,S1" + browsers: "all" }, { name: "@-o-keyframes", @@ -70,12 +74,13 @@ export const data : any = { }, { name: "@page", - desc: "Directive defines various page parameters." + desc: "Directive defines various page parameters.", + browsers: "E,FF19,C2,IE8,O6" }, { name: "@supports", desc: "A conditional group rule whose condition tests whether the user agent supports CSS property:value pairs.", - browsers: "E,C28,FF22,O12.1,S9" + browsers: "E12,FF22,S9,C28,O12.1" }, { name: "@-webkit-keyframes", @@ -86,17 +91,18 @@ export const data : any = { "pseudoclasses": [ { name: ":active", - desc: "Applies while an element is being activated by the user. For example, between the times the user presses the mouse button and releases it." + desc: "Applies while an element is being activated by the user. For example, between the times the user presses the mouse button and releases it.", + browsers: "all" }, { name: ":any-link", desc: "Represents an element that acts as the source anchor of a hyperlink. Applies to both visited and unvisited links.", - browsers: "S9" + browsers: "FF,S,C,O" }, { name: ":checked", desc: "Radio and checkbox elements can be toggled by the user. Some menu items are 'checked' when the user selects them. When such elements are toggled 'on' the :checked pseudo-class applies.", - browsers: "E,C,FF1,IE9,O9,S3.13" + browsers: "all" }, { name: ":corner-present", @@ -111,12 +117,12 @@ export const data : any = { { name: ":default", desc: "Applies to the one or more UI elements that are the default among a set of similar elements. Typically applies to context menu items, buttons, and select lists/menus.", - browsers: "C,FF3,O10,S5" + browsers: "FF4,S5,C10,O10" }, { name: ":disabled", desc: "Represents user interface elements that are in a disabled state; such elements have a corresponding enabled state.", - browsers: "E,C,FF1.5,IE9,O9,S3.1" + browsers: "all" }, { name: ":double-button", @@ -126,12 +132,12 @@ export const data : any = { { name: ":empty", desc: "Represents an element that has no children at all.", - browsers: "E,C,FF1.5,IE9,O9,S3.1" + browsers: "all" }, { name: ":enabled", desc: "Represents user interface elements that are in an enabled state; such elements have a corresponding disabled state.", - browsers: "E,C,FF1.5,IE9,O9,S3.1" + browsers: "all" }, { name: ":end", @@ -140,26 +146,28 @@ export const data : any = { }, { name: ":first", - desc: "When printing double-sided documents, the page boxes on left and right pages may be different. This can be expressed through CSS pseudo-classes defined in the page context." + desc: "When printing double-sided documents, the page boxes on left and right pages may be different. This can be expressed through CSS pseudo-classes defined in the page context.", + browsers: "E,IE8,O9.2" }, { name: ":first-child", desc: "Same as :nth-child(1). Represents an element that is the first child of some other element.", - browsers: "E,C,FF3,IE7,O9.5,S3.1" + browsers: "all" }, { name: ":first-of-type", desc: "Same as :nth-of-type(1). Represents an element that is the first sibling of its type in the list of children of its parent element.", - browsers: "E,C,FF3.5,IE9,O9.5,S3.2" + browsers: "all" }, { name: ":focus", - desc: "Applies while an element has the focus (accepts keyboard or mouse events, or other forms of input)." + desc: "Applies while an element has the focus (accepts keyboard or mouse events, or other forms of input).", + browsers: "all" }, { name: ":fullscreen", desc: "Matches any element that has its fullscreen flag set.", - browsers: "E" + browsers: "E12,FF9,S6,C15,IE11" }, { name: ":future", @@ -174,7 +182,7 @@ export const data : any = { { name: ":host", desc: "When evaluated in the context of a shadow tree, matches the shadow tree’s host element.", - browsers: "C35,O22" + browsers: "FF61,S,C,O" }, { name: ":host()", @@ -188,7 +196,8 @@ export const data : any = { }, { name: ":hover", - desc: "Applies while the user designates an element with a pointing device, but does not necessarily activate it. For example, a visual user agent could apply this pseudo-class when the cursor (mouse pointer) hovers over a box generated by the element." + desc: "Applies while the user designates an element with a pointing device, but does not necessarily activate it. For example, a visual user agent could apply this pseudo-class when the cursor (mouse pointer) hovers over a box generated by the element.", + browsers: "all" }, { name: ":increment", @@ -198,17 +207,17 @@ export const data : any = { { name: ":indeterminate", desc: "Applies to UI elements whose value is in an indeterminate state.", - browsers: "E,C,FF3.6,IE9,O10.6,S3" + browsers: "all" }, { name: ":in-range", desc: "Used in conjunction with the min and max attributes, whether on a range input, a number field, or any other types that accept those attributes.", - browsers: "E13,C,FF10,O9.6,S5.1" + browsers: "E,FF29,S,C10,O11" }, { name: ":invalid", desc: "An element is :valid or :invalid when it is, respectively, valid or invalid with respect to data validity semantics defined by a different specification.", - browsers: "E,C,FF4,IE10,O10,S5" + browsers: "all" }, { name: ":lang()", @@ -218,20 +227,22 @@ export const data : any = { { name: ":last-child", desc: "Same as :nth-last-child(1). Represents an element that is the last child of some other element.", - browsers: "E,C,FF1,IE9,O9.5,S3.1" + browsers: "all" }, { name: ":last-of-type", desc: "Same as :nth-last-of-type(1). Represents an element that is the last sibling of its type in the list of children of its parent element.", - browsers: "E,C,FF3.5,IE9,O9.5,S3.1" + browsers: "all" }, { name: ":left", - desc: "When printing double-sided documents, the page boxes on left and right pages may be different. This can be expressed through CSS pseudo-classes defined in the page context." + desc: "When printing double-sided documents, the page boxes on left and right pages may be different. This can be expressed through CSS pseudo-classes defined in the page context.", + browsers: "E,IE8,O9.2" }, { name: ":link", - desc: "Applies to links that have not yet been visited." + desc: "Applies to links that have not yet been visited.", + browsers: "all" }, { name: ":matches()", @@ -376,22 +387,22 @@ export const data : any = { { name: ":only-child", desc: "Represents an element that has a parent element and whose parent element has no other element children. Same as :first-child:last-child or :nth-child(1):nth-last-child(1), but with a lower specificity.", - browsers: "E,C,FF1.5,IE9,O9.5,S3.1" + browsers: "all" }, { name: ":only-of-type", desc: "Matches every element that is the only child of its type, of its parent. Same as :first-of-type:last-of-type or :nth-of-type(1):nth-last-of-type(1), but with a lower specificity.", - browsers: "E,C,FF3.5,IE9,O9.5,S3.2" + browsers: "all" }, { name: ":optional", desc: "A form element is :required or :optional if a value for it is, respectively, required or optional before the form it belongs to is submitted. Elements that are not form elements are neither required nor optional.", - browsers: "E,C,FF4,IE10,O10,S5" + browsers: "all" }, { name: ":out-of-range", desc: "Used in conjunction with the min and max attributes, whether on a range input, a number field, or any other types that accept those attributes.", - browsers: "E13,C,FF10,O9.6,S5.1" + browsers: "E,FF29,S,C10,O11" }, { name: ":past", @@ -401,31 +412,32 @@ export const data : any = { { name: ":read-only", desc: "An element whose contents are not user-alterable is :read-only. However, elements whose contents are user-alterable (such as text input fields) are considered to be in a :read-write state. In typical documents, most elements are :read-only.", - browsers: "E13,C,FF10,O9,S4" + browsers: "E,FF,S,C,O" }, { name: ":read-write", desc: "An element whose contents are not user-alterable is :read-only. However, elements whose contents are user-alterable (such as text input fields) are considered to be in a :read-write state. In typical documents, most elements are :read-only.", - browsers: "E13,C,FF10,O9,S4" + browsers: "E,FF,S,C,O" }, { name: ":required", desc: "A form element is :required or :optional if a value for it is, respectively, required or optional before the form it belongs to is submitted. Elements that are not form elements are neither required nor optional.", - browsers: "E,C,FF4,IE10,O10,S5" + browsers: "all" }, { name: ":right", - desc: "When printing double-sided documents, the page boxes on left and right pages may be different. This can be expressed through CSS pseudo-classes defined in the page context." + desc: "When printing double-sided documents, the page boxes on left and right pages may be different. This can be expressed through CSS pseudo-classes defined in the page context.", + browsers: "E,IE8,O9.2" }, { name: ":root", desc: "Represents an element that is the root of the document. In HTML 4, this is always the HTML element.", - browsers: "E,C,FF1,IE9,O9.5,S1" + browsers: "FF1,S1,C1,IE9,O9.5" }, { name: ":scope", desc: "Represents any element that is in the contextual reference element set.", - browsers: "FF32,S6" + browsers: "FF32,S7,O15" }, { name: ":single-button", @@ -440,12 +452,12 @@ export const data : any = { { name: ":target", desc: "Some URIs refer to a location within a resource. This kind of URI ends with a 'number sign' (#) followed by an anchor identifier (called the fragment identifier).", - browsers: "E,C,FF1,IE9,O9.5,S1" + browsers: "all" }, { name: ":valid", desc: "An element is :valid or :invalid when it is, respectively, valid or invalid with respect to data validity semantics defined by a different specification.", - browsers: "E,C,FF4,IE10,O10,S5" + browsers: "all" }, { name: ":vertical", @@ -454,7 +466,8 @@ export const data : any = { }, { name: ":visited", - desc: "Applies once the link has been visited by the user." + desc: "Applies once the link has been visited by the user.", + browsers: "all" }, { name: ":-webkit-any()", @@ -476,17 +489,17 @@ export const data : any = { { name: "::after", desc: "Represents a styleable child pseudo-element immediately after the originating element’s actual content.", - browsers: "E,C,FF1.5,IE9,O9,S4" + browsers: "all" }, { name: "::backdrop", desc: "Used to create a backdrop that hides the underlying document for an element in a top layer (such as an element that is displayed fullscreen).", - browsers: "E" + browsers: "E,FF47,C37,IE11" }, { name: "::before", desc: "Represents a styleable child pseudo-element immediately before the originating element’s actual content.", - browsers: "E,C,FF1.5,IE9,O9,S4" + browsers: "all" }, { name: "::content", @@ -495,7 +508,7 @@ export const data : any = { }, { name: "::cue", - browsers: "C,O16,S6" + browsers: "FF55,C" }, { name: "::cue()", @@ -512,12 +525,12 @@ export const data : any = { { name: "::first-letter", desc: "Represents the first letter of an element, if it is not preceded by any other content (such as images or inline tables) on its line.", - browsers: "E,C,FF1.5,IE9,O7,S1" + browsers: "all" }, { name: "::first-line", desc: "Describes the contents of the first formatted line of its originating element.", - browsers: "E,C,FF1.5,IE9,O7,S1" + browsers: "all" }, { name: "::-moz-focus-inner", @@ -630,7 +643,7 @@ export const data : any = { { name: "::selection", desc: "Represents the portion of a document that has been highlighted by the user.", - browsers: "E,C,IE9,O9.5,S1.1" + browsers: "all" }, { name: "::shadow", @@ -655,15 +668,15 @@ export const data : any = { }, { name: "::-webkit-meter-bar", - browsers: "E13,C,O15,S6" + browsers: "S,C,O" }, { name: "::-webkit-meter-even-less-good-value", - browsers: "E13,C,O15,S6" + browsers: "S,C,O" }, { name: "::-webkit-meter-optimum-value", - browsers: "E13,C,O15,S6" + browsers: "S,C,O" }, { name: "::-webkit-meter-suboptimal-value", @@ -675,15 +688,15 @@ export const data : any = { }, { name: "::-webkit-progress-bar", - browsers: "C,S3" + browsers: "S,C,O" }, { name: "::-webkit-progress-inner-element", - browsers: "C,S3" + browsers: "S,C,O" }, { name: "::-webkit-progress-value", - browsers: "C,S3" + browsers: "S,C,O" }, { name: "::-webkit-resizer", @@ -715,7 +728,7 @@ export const data : any = { }, { name: "::-webkit-search-cancel-button", - browsers: "C,S4" + browsers: "S,C" }, { name: "::-webkit-search-decoration", @@ -723,7 +736,7 @@ export const data : any = { }, { name: "::-webkit-search-results-button", - browsers: "C,S4" + browsers: "S,C" }, { name: "::-webkit-search-results-decoration", @@ -777,7 +790,7 @@ export const data : any = { { name: "align-content", desc: "Aligns a flex container’s lines within the flex container when there is extra space in the cross-axis, similar to how 'justify-content' aligns individual items within the main-axis.", - browsers: "E,C29,FF22,IE11,O12.1,S9", + browsers: "all", restriction: "enum", values: [ { @@ -839,7 +852,7 @@ export const data : any = { { name: "justify-items", desc: "Defines the default justify-self for all items of the box, given them the default way of justifying each box along the appropriate axi", - browsers: "FF45", + browsers: "E16,FF45", restriction: "enum", values: [ { @@ -906,7 +919,7 @@ export const data : any = { { name: "justify-self", desc: "Defines the way of justifying a box inside its container along the appropriate axis.", - browsers: "FF45", + browsers: "E16,FF45", restriction: "enum", values: [ { @@ -970,7 +983,7 @@ export const data : any = { { name: "align-self", desc: "Allows the default alignment along the cross axis to be overridden for individual flex items.", - browsers: "E,C29,FF22,IE11,O12.1,S9", + browsers: "E12,FF20,C36,IE11,O12.1", restriction: "enum", values: [ { @@ -1003,7 +1016,7 @@ export const data : any = { { name: "all", desc: "Shorthand that resets all properties except 'direction' and 'unicode-bidi'.", - browsers: "C37,FF27,O24", + browsers: "FF27,C37,O24", restriction: "enum", values: [], "syntax": "initial | inherit | unset | revert" @@ -1018,7 +1031,7 @@ export const data : any = { { name: "animation", desc: "Shorthand property combines six of the animation properties into a single property.", - browsers: "E,C43,FF16,IE10,O12.1,S9", + browsers: "all", restriction: "time, timing-function, enum, identifier, number", values: [ { @@ -1059,14 +1072,14 @@ export const data : any = { { name: "animation-delay", desc: "Defines when the animation will start.", - browsers: "E,C43,FF16,IE10,O12.1,S9", + browsers: "all", restriction: "time", "syntax": "