├── .gitignore ├── netlify.toml ├── public ├── favicon.ico ├── embed │ ├── assets │ │ └── flag.png │ ├── index.html │ ├── style.css │ ├── script.js │ └── caniuse-embed.min.js ├── caniuse-embed.min.js ├── website │ ├── index.css │ ├── clipboard.min.js │ └── index.js └── index.html ├── src ├── embed │ ├── scss │ │ ├── style.scss │ │ ├── _reset.scss │ │ ├── _base.scss │ │ ├── _legend.scss │ │ ├── _vars.scss │ │ ├── _layout.scss │ │ ├── _table.scss │ │ └── _colours.scss │ ├── index.html │ └── script.js └── caniuse-embed.js ├── package.json ├── README.md ├── gulpfile.js └── PRIVACY.md /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .idea 3 | .netlify 4 | -------------------------------------------------------------------------------- /netlify.toml: -------------------------------------------------------------------------------- 1 | [build] 2 | publish = "public/" 3 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ireade/caniuse-embed/HEAD/public/favicon.ico -------------------------------------------------------------------------------- /public/embed/assets/flag.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ireade/caniuse-embed/HEAD/public/embed/assets/flag.png -------------------------------------------------------------------------------- /src/embed/scss/style.scss: -------------------------------------------------------------------------------- 1 | /* CanIUse Embed Styles */ 2 | 3 | @import "vars"; 4 | @import "reset"; 5 | @import "base"; 6 | @import "layout"; 7 | @import "table"; 8 | @import "legend"; 9 | @import "colours"; 10 | -------------------------------------------------------------------------------- /src/embed/scss/_reset.scss: -------------------------------------------------------------------------------- 1 | /* RESET */ 2 | 3 | html, body, div, span, 4 | h1, p, a, small, strong, 5 | table, tbody, thead, tr, th, td, 6 | footer, header, main { 7 | margin: 0; 8 | padding: 0; 9 | border: 0; 10 | font: inherit; 11 | font-size: 100%; 12 | vertical-align: baseline; 13 | } 14 | 15 | footer, 16 | header { 17 | display: block; 18 | } 19 | 20 | html { 21 | box-sizing: border-box; 22 | } 23 | 24 | *, 25 | *::before, 26 | *::after { 27 | box-sizing: inherit; 28 | } 29 | -------------------------------------------------------------------------------- /src/embed/scss/_base.scss: -------------------------------------------------------------------------------- 1 | /* BASE */ 2 | 3 | html { 4 | font-size: 62.5%; 5 | } 6 | 7 | body { 8 | font-size: 1.4rem; 9 | line-height: 1.4; 10 | font-family: 'Open Sans', sans-serif; 11 | font-weight: 300; 12 | } 13 | 14 | a { 15 | color: inherit; 16 | } 17 | 18 | body.screenshot a { 19 | text-decoration: none; 20 | } 21 | 22 | h1 a { 23 | text-decoration: none; 24 | } 25 | 26 | small, 27 | .legend { 28 | font-size: 1.1rem; 29 | } 30 | 31 | strong { 32 | font-weight: 600; 33 | } 34 | 35 | [hidden] { 36 | display: none; 37 | } 38 | -------------------------------------------------------------------------------- /src/embed/scss/_legend.scss: -------------------------------------------------------------------------------- 1 | 2 | .legend div { 3 | display: inline-block; 4 | width: auto; 5 | padding: 3px 5px; 6 | margin-right: 5px; 7 | 8 | @media screen and (max-width: 450px) { 9 | margin-bottom: 5px; 10 | } 11 | } 12 | 13 | .legend .d { 14 | background-color: #FFF; 15 | color: #000; 16 | 17 | img { 18 | height: 10px; 19 | width: auto; 20 | margin-right: 5px; 21 | } 22 | } 23 | 24 | .note { 25 | float: right; 26 | font-weight: 600; 27 | 28 | @media (max-width: 500px) { 29 | float: none; 30 | display: block; 31 | margin-bottom: 5px; 32 | } 33 | } 34 | 35 | span.a { 36 | color: $partial; 37 | } 38 | 39 | span.y { 40 | color: $supported; 41 | } 42 | -------------------------------------------------------------------------------- /src/embed/scss/_vars.scss: -------------------------------------------------------------------------------- 1 | // Variables ************************** */ 2 | 3 | $theme: #DB5600; 4 | 5 | $theme-caniuse: #DB5600; 6 | $theme-mdn: #3d7e9a; 7 | 8 | $bg-colour: #F2E8D5; 9 | $dark-grey: #584E3B; 10 | 11 | $supported: #39B54A; 12 | $partial: #A8BD04; 13 | $not-supported: #C44230; 14 | 15 | $supported-a: #99FFB8; 16 | $partial-a: #8090F9; 17 | $not-supported-a: #E17085; 18 | 19 | $unknown: #838383; 20 | 21 | $font-colour: #FFF; 22 | 23 | body { 24 | --supported: #39B54A; 25 | --partial: #A8BD04; 26 | --not-supported: #C44230; 27 | --font-colour: #FFF; 28 | } 29 | 30 | body.accessible-colours { 31 | --supported: #99FFB8; 32 | --partial: #8090F9; 33 | --not-supported: #E17085; 34 | --font-colour: #000; 35 | } 36 | 37 | // Mixins ************************** */ 38 | 39 | @mixin supports-grid { 40 | @supports (display: grid) { 41 | @content; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "caniuse-embed", 3 | "version": "1.4.0", 4 | "description": "Embed up-to-date data from caniuse.com and mozilla browser compat", 5 | "main": "caniuse-embed.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1", 8 | "start": "gulp", 9 | "dev": "netlify dev" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/ireade/caniuse-embed.git" 14 | }, 15 | "author": "Ire Aderinokun", 16 | "license": "Apache 2", 17 | "bugs": { 18 | "url": "https://github.com/ireade/caniuse-embed/issues" 19 | }, 20 | "homepage": "https://github.com/ireade/caniuse-embed", 21 | "devDependencies": { 22 | "gulp": "^4.0.0", 23 | "gulp-connect": "^5.7.0", 24 | "gulp-minify-html": "^1.0.6", 25 | "gulp-sass": "^5.0.1", 26 | "gulp-uglifyjs": "^0.6.2", 27 | "gulp-util": "^3.0.8", 28 | "sass": "^1.71.0" 29 | }, 30 | "dependencies": {}, 31 | "resolutions": { 32 | "graceful-fs": "^4.2.11" 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /public/caniuse-embed.min.js: -------------------------------------------------------------------------------- 1 | !function(){function e(){for(var e=document.getElementsByClassName("ciu_embed"),t=0;t';a.innerHTML=o}else a.innerHTML="A feature was not included. Go to https://caniuse.bitsofco.de/#how-to-use to generate an embed."}var c=window.addEventListener?"addEventListener":"attachEvent";(0,window[c])("attachEvent"==c?"onmessage":"message",function(t){var a=t.data;if("string"==typeof a&&a.indexOf("ciu_embed")>-1)for(var i=a.split(":")[1],n=a.split(":")[2],s=0;s 10 | 11 | 12 | ### Mobile 13 | 14 | Mobile View of Embed 15 | 16 | 17 | ### Accessible Colours (Toggleable) 18 | 19 | Toggleable Accessible Colours 20 | 21 | ### Live Image 22 | 23 | 24 | 25 | ## How to Use 26 | 27 | Follow instructions [here](https://caniuse.bitsofco.de/#how-to-use) to generate an embed code. 28 | 29 | ## Polymer Element 30 | 31 | [Visit repo of Polymer Element](https://github.com/ireade/caniuse-embed-polymer) 32 | 33 | ## Copyright and Licence 34 | 35 | - All data is from [caniuse](https://github.com/fyrd/caniuse), which is licenced under the [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) license. 36 | 37 | - This embed is created by [Ire Aderinokun](https://twitter.com/ireaderinokun), and is licenced under the [Apache 2](https://www.apache.org/licenses/LICENSE-2.0) license. 38 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | const gulp = require('gulp'); 2 | const sass = require('gulp-sass')(require('sass')); 3 | const gutil = require('gulp-util'); 4 | const uglify = require('gulp-uglifyjs'); 5 | const minifyHTML = require('gulp-minify-html'); 6 | const connect = require('gulp-connect'); 7 | 8 | const paths = { 9 | caniuseEmbed: "src/caniuse-embed.js", 10 | embedStyle: "src/embed/scss/style.scss", 11 | embedScript: "src/embed/script.js", 12 | embedHTML: "src/embed/index.html" 13 | }; 14 | 15 | function script() { 16 | return gulp.src(paths.caniuseEmbed) 17 | .pipe(uglify('caniuse-embed.min.js')) 18 | .pipe(gulp.dest('public')) 19 | .pipe(gulp.src(paths.embedScript)) 20 | .pipe(uglify()) 21 | .pipe(gulp.dest('public/embed')); 22 | } 23 | 24 | function sassTask() { 25 | return gulp.src(paths.embedStyle) 26 | .pipe(sass({ 27 | outputStyle: 'compressed' 28 | }) 29 | .on('error', gutil.log)) 30 | .pipe(gulp.dest('public/embed')); 31 | } 32 | 33 | function minifyHtml() { 34 | return gulp.src(paths.embedHTML) 35 | .pipe(minifyHTML({ empty: true })) 36 | .pipe(gulp.dest('public/embed')); 37 | } 38 | 39 | function connectServer() { 40 | return connect.server({ 41 | port: 8000 42 | }); 43 | } 44 | 45 | function watch() { 46 | gulp.watch(paths.caniuseEmbed, script); 47 | gulp.watch(paths.embedScript, script); 48 | gulp.watch("src/embed/scss/*.scss", sassTask); 49 | gulp.watch(paths.embedHTML, minifyHtml); 50 | } 51 | 52 | exports.default = gulp.series(script, sassTask, minifyHtml, watch); 53 | exports.full = gulp.series(connectServer, script, sassTask, minifyHtml, watch); 54 | -------------------------------------------------------------------------------- /src/embed/scss/_layout.scss: -------------------------------------------------------------------------------- 1 | /* LAYOUT */ 2 | 3 | .feature { 4 | background-color: $bg-colour; 5 | position: relative; 6 | border: 3px solid $theme; 7 | border-bottom: 0; 8 | display: none; 9 | } 10 | 11 | body.caniuse .feature { 12 | border-color: $theme-caniuse; 13 | } 14 | 15 | body.mdn .feature { 16 | border-color: $theme-mdn; 17 | } 18 | 19 | body.screenshot { 20 | padding-top: 10px; 21 | } 22 | 23 | .header { 24 | padding: 10px 10px 0; 25 | 26 | .title { 27 | margin-bottom: 5px; 28 | font-size: 2rem; 29 | 30 | span { 31 | margin-bottom: 5px; 32 | padding-right: 10px; 33 | } 34 | } 35 | 36 | .description { 37 | font-size: 1.6rem; 38 | } 39 | 40 | .icon-external-link { 41 | height: auto; 42 | max-height: 20px; 43 | } 44 | } 45 | 46 | .main { 47 | padding: 10px 5px; 48 | 49 | @media (min-width: 500px) { 50 | padding: 10px; 51 | } 52 | } 53 | 54 | .footer { 55 | padding: 5px 10px; 56 | margin-top: 20px; 57 | background-color: $theme; 58 | color: #FFF; 59 | font-size: 1.1rem; 60 | display: flex; 61 | justify-content: space-between; 62 | } 63 | 64 | body.caniuse .footer { 65 | background-color: $theme-caniuse; 66 | } 67 | 68 | body.mdn .footer { 69 | background-color: $theme-mdn; 70 | } 71 | 72 | .footer button { 73 | background: none; 74 | border: 1px solid #FFF; 75 | border-radius: 3px; 76 | color: #FFF; 77 | font-family: 'Open Sans', sans-serif; 78 | font-weight: 300; 79 | cursor: pointer; 80 | display: none; 81 | } 82 | 83 | @supports (color: var(--supported)) { 84 | .footer button { 85 | display: inline-block; 86 | } 87 | } 88 | 89 | .footer button { 90 | .enable { display: inline; } 91 | .disable { display: none; } 92 | } 93 | 94 | .accessible-colours .footer button { 95 | .enable { display: none; } 96 | .disable { display: inline; } 97 | } 98 | -------------------------------------------------------------------------------- /src/caniuse-embed.js: -------------------------------------------------------------------------------- 1 | (function() { 2 | function init() { 3 | 4 | var caniuse_embeds = document.getElementsByClassName("ciu_embed"); 5 | 6 | for (var i = 0; i < caniuse_embeds.length; i++) { 7 | 8 | var embed = caniuse_embeds[i]; 9 | var feature = embed.getAttribute('data-feature'); 10 | var periods = embed.getAttribute('data-periods'); 11 | var accessibleColours = embed.getAttribute('data-accessible-colours') || 'false'; 12 | var imageBase = embed.getAttribute('data-image-base') || 'none'; 13 | 14 | if (feature) { 15 | 16 | var url = 'https://caniuse.bitsofco.de/embed/index.html'; 17 | var iframe = ''; 18 | 19 | embed.innerHTML = iframe; 20 | 21 | } else { 22 | 23 | embed.innerHTML = "A feature was not included. Go to https://caniuse.bitsofco.de/#how-to-use to generate an embed."; 24 | } 25 | } 26 | 27 | 28 | // GET RESPONSIVE HEIGHT PASSED FROM IFRAME 29 | 30 | var eventMethod = window.addEventListener ? "addEventListener" : "attachEvent"; 31 | var eventer = window[eventMethod]; 32 | var messageEvent = eventMethod == "attachEvent" ? "onmessage" : "message"; 33 | 34 | eventer(messageEvent,function(e) { 35 | var data = e.data; 36 | if ( (typeof data === 'string') && (data.indexOf('ciu_embed') > -1) ) { 37 | 38 | var featureID = data.split(':')[1]; 39 | var height = data.split(':')[2]; 40 | 41 | for (var i = 0; i < caniuse_embeds.length; i++) { 42 | 43 | var embed = caniuse_embeds[i]; 44 | 45 | if ( embed.getAttribute('data-feature') === featureID ) { 46 | var iframeHeight = parseInt(height) + 30; 47 | embed.childNodes[0].height = iframeHeight + 'px'; 48 | break; 49 | } 50 | } 51 | } 52 | },false); 53 | 54 | } 55 | 56 | if (document.readyState === "loading") { 57 | // The document hasn't finished loading 58 | document.addEventListener("DOMContentLoaded", init); 59 | } else { 60 | // `DOMContentLoaded` has already fired 61 | init(); 62 | } 63 | 64 | }()); 65 | -------------------------------------------------------------------------------- /public/embed/index.html: -------------------------------------------------------------------------------- 1 | CanIUse Embed

External Link

 

IEEdgeFirefoxChromeSafariiOS SafariOpera MiniChrome for AndroidAndroid BrowserSamsung Internet
?
Partial Support
Prefixed
Behind a Flag
-------------------------------------------------------------------------------- /src/embed/scss/_table.scss: -------------------------------------------------------------------------------- 1 | /* Table Layout ************************** */ 2 | 3 | // Table 4 | 5 | table { 6 | width: 100%; 7 | border-collapse: collapse; 8 | border-spacing: 0; 9 | line-height: 1.2; 10 | margin-bottom: 20px; 11 | font-size: 1.2rem; 12 | 13 | @media (min-width: 700px) { 14 | font-size: 1.4rem; 15 | } 16 | } 17 | 18 | // Table Head 19 | 20 | table thead th { 21 | width: 10%; 22 | vertical-align: bottom; 23 | 24 | @include supports-grid() { 25 | width: 100%; 26 | } 27 | } 28 | 29 | .browser-title { 30 | display: block; 31 | margin-bottom: 5px; 32 | padding-bottom: 5px; 33 | border-bottom-style: solid; 34 | border-bottom-width: 5px; 35 | position: relative; 36 | 37 | @media (max-width: 700px) { 38 | height: 150px; 39 | 40 | span { 41 | position: absolute; 42 | border-bottom: 0; 43 | padding-left: 5px; 44 | padding-bottom: 0; 45 | 46 | -webkit-transform: rotate(-90deg); 47 | -moz-transform: rotate(-90deg); 48 | -ms-transform: rotate(-90deg); 49 | -o-transform: rotate(-90deg); 50 | transform: rotate(-90deg); 51 | white-space: nowrap; 52 | 53 | left: 0; 54 | bottom: 20px; 55 | text-align: left; 56 | width: 100%; 57 | } 58 | } 59 | } 60 | 61 | table thead th, 62 | .browser-title { 63 | @include supports-grid() { 64 | display: grid; 65 | } 66 | } 67 | 68 | .browser-title span { 69 | @include supports-grid() { 70 | align-self: end; 71 | } 72 | } 73 | 74 | // Table Body 75 | 76 | table tbody { 77 | @include supports-grid() { 78 | display: grid; 79 | grid-row-gap: 5px; 80 | } 81 | } 82 | 83 | table tbody td { 84 | text-align: center; 85 | position: relative; 86 | } 87 | 88 | table tbody td:hover { 89 | cursor: default; 90 | } 91 | 92 | table tbody td span:not(.usage) { 93 | display: block; 94 | height: 100%; 95 | width: 100%; 96 | padding: 7px 0; 97 | position: relative; 98 | } 99 | 100 | // Header or Body Rows 101 | 102 | table tr { 103 | @include supports-grid() { 104 | display: grid; 105 | grid-template-columns: repeat(10, 1fr); 106 | grid-gap: 5px; 107 | } 108 | } 109 | 110 | table td, 111 | table th { 112 | border: 5px solid $bg-colour; 113 | 114 | @include supports-grid() { 115 | border: none; 116 | } 117 | } 118 | 119 | // Current Row 120 | 121 | tr.current { 122 | @include supports-grid() { 123 | background-color: $dark-grey; 124 | outline: 5px solid $dark-grey; 125 | margin-top: 5px; 126 | margin-bottom: 5px; 127 | } 128 | } 129 | 130 | tr.current td { 131 | border: 5px solid $dark-grey; 132 | position: relative; 133 | 134 | @include supports-grid() { 135 | border: none; 136 | } 137 | } 138 | 139 | tr.current td span { 140 | border-top: 5px solid $dark-grey; 141 | 142 | @include supports-grid() { 143 | border: 0; 144 | } 145 | } 146 | 147 | // First Future Row 148 | 149 | tr.future_1 td span { 150 | border-top: 5px solid $bg-colour; 151 | 152 | @include supports-grid() { 153 | border: 0; 154 | } 155 | } 156 | 157 | /* Usage Information ************************** */ 158 | 159 | span.usage { 160 | padding-top: 7px; 161 | position: absolute; 162 | width: 100%; 163 | background-color: #FFF; 164 | height: 100%; 165 | top: 0; 166 | left: 0; 167 | display: none; 168 | } 169 | 170 | td:hover span.usage { 171 | display: block; 172 | } 173 | -------------------------------------------------------------------------------- /src/embed/scss/_colours.scss: -------------------------------------------------------------------------------- 1 | /* Table Head: Browser Names ************************** */ 2 | 3 | th.ie .browser-title, 4 | th.edge .browser-title { 5 | border-bottom-color: #233D61; 6 | } 7 | 8 | th.chrome .browser-title { 9 | border-bottom-color: #3F77BB; 10 | } 11 | 12 | th.firefox .browser-title { 13 | border-bottom-color: #A36223; 14 | } 15 | 16 | th.safari .browser-title { 17 | border-bottom-color: #666; 18 | } 19 | 20 | th.ios_saf .browser-title { 21 | border-bottom-color: #333; 22 | } 23 | 24 | th.op_mini .browser-title { 25 | border-bottom-color: #992626; 26 | } 27 | 28 | th.android .browser-title { 29 | border-bottom-color: #7BA13B; 30 | } 31 | 32 | th.samsung .browser-title { 33 | border-bottom-color: #9753ff; 34 | } 35 | 36 | /* Usage Information ************************** */ 37 | 38 | // Supported 39 | 40 | tr.statistics td.y span:not(.usage), 41 | .legend .y { 42 | background-color: $supported; 43 | background-color: var(--supported); 44 | color: $font-colour; 45 | color: var(--font-colour); 46 | } 47 | 48 | body.accessible-colours tr.statistics td.y span:not(.usage), 49 | body.accessible-colours .legend .y { 50 | background-color: $supported-a; 51 | background-color: var(--supported); 52 | } 53 | 54 | // Not Supported 55 | 56 | tr.statistics td.n span:not(.usage), 57 | tr.statistics td.p span:not(.usage), 58 | tr.statistics td.d span:not(.usage), 59 | .legend .n { 60 | background-color: $not-supported; 61 | background-color: var(--not-supported); 62 | color: #FFF; 63 | } 64 | 65 | body.accessible-colours tr.statistics td.n span:not(.usage), 66 | body.accessible-colours tr.statistics td.p span:not(.usage), 67 | body.accessible-colours tr.statistics td.d span:not(.usage), 68 | .legend .n { 69 | background-color: $not-supported-a; 70 | background-color: var(--not-supported); 71 | color: #000; 72 | } 73 | 74 | // Partial Support 75 | 76 | tr.statistics td.a span:not(.usage), 77 | .legend .a { 78 | background-color: $partial; 79 | background-color: var(--partial); 80 | color: $font-colour; 81 | color: var(--font-colour); 82 | } 83 | 84 | body.accessible-colours tr.statistics td.a span:not(.usage), 85 | body.accessible-colours .legend .a { 86 | background-color: $partial-a; 87 | background-color: var(--partial); 88 | } 89 | 90 | // Unknown Support 91 | 92 | tr.statistics td.u span:not(.usage), 93 | .legend .u { 94 | background-color: $unknown; 95 | color: #FFF; 96 | } 97 | 98 | // Prefixed 99 | 100 | tr.statistics td.x span:not(.usage)::after { 101 | // with Prefix 102 | content: ' '; 103 | position: absolute; 104 | top: 0; 105 | right: 0; 106 | background-color: #FF6; 107 | color: #000; 108 | line-height: 1; 109 | font-size: 1pt; 110 | height: 10px; 111 | width: 10px; 112 | 113 | @media screen and (max-width: 600px) { 114 | height: 6px; 115 | } 116 | } 117 | 118 | .legend .x { 119 | background-color: #FF6; 120 | color: #000; 121 | } 122 | 123 | // Behind a Flag 124 | 125 | tr.statistics td.d span:not(.usage)::after { 126 | // with Prefix 127 | content: ' '; 128 | position: absolute; 129 | top: 0; 130 | right: 0; 131 | color: #000; 132 | line-height: 1; 133 | font-size: 1pt; 134 | height: 20px; 135 | width: 20px; 136 | background-image: url(/embed/assets/flag.png); 137 | background-position: top 3px right 3px; 138 | background-repeat: no-repeat; 139 | background-size: 10px; 140 | 141 | @media screen and (max-width: 600px) { 142 | background-position: top 3px right 3px; 143 | background-size: 8px; 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/embed/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | CanIUse Embed 5 | 6 | 7 | 8 | 9 |
10 | 11 |
12 |
13 |

14 | 15 | 16 | 17 | External Link 18 | 19 | 20 | 21 | 22 | 23 | 24 |

25 | 26 |

 

27 |
28 | 29 | 30 |
31 | 32 | 33 | 34 | 35 | 38 | 41 | 44 | 47 | 50 | 53 | 56 | 59 | 62 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 |
36 | IE 37 | 39 | Edge 40 | 42 | Firefox 43 | 45 | Chrome 46 | 48 | Safari 49 | 51 | iOS Safari 52 | 54 | Opera Mini 55 | 57 | Chrome for Android 58 | 60 | Android Browser 61 | 63 | Samsung Internet 64 |
74 | 75 | 76 | 77 |
78 |
79 |
80 |
?
81 |
Partial Support
82 |
Prefixed
83 |
Behind a Flag
84 |
85 |
86 | 87 | 99 | 100 |
101 | 102 | 103 | 104 | 105 | -------------------------------------------------------------------------------- /public/embed/style.css: -------------------------------------------------------------------------------- 1 | body{--supported: #39B54A;--partial: #A8BD04;--not-supported: #C44230;--font-colour: #FFF}body.accessible-colours{--supported: #99FFB8;--partial: #8090F9;--not-supported: #E17085;--font-colour: #000}html,body,div,span,h1,p,a,small,strong,table,tbody,thead,tr,th,td,footer,header,main{margin:0;padding:0;border:0;font:inherit;font-size:100%;vertical-align:baseline}footer,header{display:block}html{box-sizing:border-box}*,*::before,*::after{box-sizing:inherit}html{font-size:62.5%}body{font-size:1.4rem;line-height:1.4;font-family:"Open Sans",sans-serif;font-weight:300}a{color:inherit}body.screenshot a{text-decoration:none}h1 a{text-decoration:none}small,.legend{font-size:1.1rem}strong{font-weight:600}[hidden]{display:none}.feature{background-color:#f2e8d5;position:relative;border:3px solid #db5600;border-bottom:0;display:none}body.caniuse .feature{border-color:#db5600}body.mdn .feature{border-color:#3d7e9a}body.screenshot{padding-top:10px}.header{padding:10px 10px 0}.header .title{margin-bottom:5px;font-size:2rem}.header .title span{margin-bottom:5px;padding-right:10px}.header .description{font-size:1.6rem}.header .icon-external-link{height:auto;max-height:20px}.main{padding:10px 5px}@media(min-width: 500px){.main{padding:10px}}.footer{padding:5px 10px;margin-top:20px;background-color:#db5600;color:#fff;font-size:1.1rem;display:flex;justify-content:space-between}body.caniuse .footer{background-color:#db5600}body.mdn .footer{background-color:#3d7e9a}.footer button{background:none;border:1px solid #fff;border-radius:3px;color:#fff;font-family:"Open Sans",sans-serif;font-weight:300;cursor:pointer;display:none}@supports(color: var(--supported)){.footer button{display:inline-block}}.footer button .enable{display:inline}.footer button .disable{display:none}.accessible-colours .footer button .enable{display:none}.accessible-colours .footer button .disable{display:inline}table{width:100%;border-collapse:collapse;border-spacing:0;line-height:1.2;margin-bottom:20px;font-size:1.2rem}@media(min-width: 700px){table{font-size:1.4rem}}table thead th{width:10%;vertical-align:bottom}@supports(display: grid){table thead th{width:100%}}.browser-title{display:block;margin-bottom:5px;padding-bottom:5px;border-bottom-style:solid;border-bottom-width:5px;position:relative}@media(max-width: 700px){.browser-title{height:150px}.browser-title span{position:absolute;border-bottom:0;padding-left:5px;padding-bottom:0;-webkit-transform:rotate(-90deg);-moz-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-o-transform:rotate(-90deg);transform:rotate(-90deg);white-space:nowrap;left:0;bottom:20px;text-align:left;width:100%}}@supports(display: grid){table thead th,.browser-title{display:grid}}@supports(display: grid){.browser-title span{align-self:end}}@supports(display: grid){table tbody{display:grid;grid-row-gap:5px}}table tbody td{text-align:center;position:relative}table tbody td:hover{cursor:default}table tbody td span:not(.usage){display:block;height:100%;width:100%;padding:7px 0;position:relative}@supports(display: grid){table tr{display:grid;grid-template-columns:repeat(10, 1fr);grid-gap:5px}}table td,table th{border:5px solid #f2e8d5}@supports(display: grid){table td,table th{border:none}}@supports(display: grid){tr.current{background-color:#584e3b;outline:5px solid #584e3b;margin-top:5px;margin-bottom:5px}}tr.current td{border:5px solid #584e3b;position:relative}@supports(display: grid){tr.current td{border:none}}tr.current td span{border-top:5px solid #584e3b}@supports(display: grid){tr.current td span{border:0}}tr.future_1 td span{border-top:5px solid #f2e8d5}@supports(display: grid){tr.future_1 td span{border:0}}span.usage{padding-top:7px;position:absolute;width:100%;background-color:#fff;height:100%;top:0;left:0;display:none}td:hover span.usage{display:block}.legend div{display:inline-block;width:auto;padding:3px 5px;margin-right:5px}@media screen and (max-width: 450px){.legend div{margin-bottom:5px}}.legend .d{background-color:#fff;color:#000}.legend .d img{height:10px;width:auto;margin-right:5px}.note{float:right;font-weight:600}@media(max-width: 500px){.note{float:none;display:block;margin-bottom:5px}}span.a{color:#a8bd04}span.y{color:#39b54a}th.ie .browser-title,th.edge .browser-title{border-bottom-color:#233d61}th.chrome .browser-title{border-bottom-color:#3f77bb}th.firefox .browser-title{border-bottom-color:#a36223}th.safari .browser-title{border-bottom-color:#666}th.ios_saf .browser-title{border-bottom-color:#333}th.op_mini .browser-title{border-bottom-color:#992626}th.android .browser-title{border-bottom-color:#7ba13b}th.samsung .browser-title{border-bottom-color:#9753ff}tr.statistics td.y span:not(.usage),.legend .y{background-color:#39b54a;background-color:var(--supported);color:#fff;color:var(--font-colour)}body.accessible-colours tr.statistics td.y span:not(.usage),body.accessible-colours .legend .y{background-color:#99ffb8;background-color:var(--supported)}tr.statistics td.n span:not(.usage),tr.statistics td.p span:not(.usage),tr.statistics td.d span:not(.usage),.legend .n{background-color:#c44230;background-color:var(--not-supported);color:#fff}body.accessible-colours tr.statistics td.n span:not(.usage),body.accessible-colours tr.statistics td.p span:not(.usage),body.accessible-colours tr.statistics td.d span:not(.usage),.legend .n{background-color:#e17085;background-color:var(--not-supported);color:#000}tr.statistics td.a span:not(.usage),.legend .a{background-color:#a8bd04;background-color:var(--partial);color:#fff;color:var(--font-colour)}body.accessible-colours tr.statistics td.a span:not(.usage),body.accessible-colours .legend .a{background-color:#8090f9;background-color:var(--partial)}tr.statistics td.u span:not(.usage),.legend .u{background-color:#838383;color:#fff}tr.statistics td.x span:not(.usage)::after{content:" ";position:absolute;top:0;right:0;background-color:#ff6;color:#000;line-height:1;font-size:1pt;height:10px;width:10px}@media screen and (max-width: 600px){tr.statistics td.x span:not(.usage)::after{height:6px}}.legend .x{background-color:#ff6;color:#000}tr.statistics td.d span:not(.usage)::after{content:" ";position:absolute;top:0;right:0;color:#000;line-height:1;font-size:1pt;height:20px;width:20px;background-image:url(/embed/assets/flag.png);background-position:top 3px right 3px;background-repeat:no-repeat;background-size:10px}@media screen and (max-width: 600px){tr.statistics td.d span:not(.usage)::after{background-position:top 3px right 3px;background-size:8px}} -------------------------------------------------------------------------------- /public/website/index.css: -------------------------------------------------------------------------------- 1 | html, body, div, span, applet, object, iframe, 2 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 3 | a, abbr, acronym, address, big, cite, code, 4 | del, dfn, em, img, ins, kbd, q, s, samp, 5 | small, strike, strong, sub, sup, tt, var, 6 | b, u, i, center, 7 | dl, dt, dd, ol, ul, li, 8 | fieldset, form, label, legend, 9 | table, caption, tbody, tfoot, thead, tr, th, td, 10 | article, aside, canvas, details, embed, 11 | figure, figcaption, footer, header, hgroup, 12 | menu, nav, output, ruby, section, summary, 13 | time, mark, audio, video { 14 | margin: 0; 15 | padding: 0; 16 | border: 0; 17 | font: inherit; 18 | font-size: 100%; 19 | vertical-align: baseline; 20 | } 21 | 22 | article, aside, details, figcaption, figure, 23 | footer, header, hgroup, menu, nav, section { 24 | display: block; 25 | } 26 | ul { 27 | list-style: none; 28 | } 29 | blockquote, q { 30 | quotes: none; 31 | } 32 | blockquote:before, blockquote:after, 33 | q:before, q:after { 34 | content: ''; 35 | content: none; 36 | } 37 | table { 38 | border-collapse: collapse; 39 | border-spacing: 0; 40 | } 41 | 42 | /* Box sizing */ 43 | 44 | html { 45 | box-sizing: border-box; 46 | } 47 | 48 | *, *:before, *:after { 49 | box-sizing: inherit; 50 | } 51 | 52 | /* Clearfix */ 53 | 54 | .cf:after { 55 | content:""; 56 | display:table; 57 | clear:both; 58 | } 59 | 60 | [hidden] { 61 | display: none; 62 | } 63 | 64 | 65 | 66 | /* Typography ---------------*/ 67 | 68 | html { 69 | font-size: 62.5%; 70 | } 71 | body { 72 | font-size: 1.6rem; 73 | line-height: 1.4; 74 | font-family: 'Be Vietnam', sans-serif; 75 | font-weight: 300; 76 | color: rgb(50, 50, 50); 77 | } 78 | 79 | a { 80 | color: inherit; 81 | } 82 | 83 | small { 84 | font-size: 1rem; 85 | display: block; 86 | text-align: right; 87 | } 88 | 89 | strong { 90 | font-weight: 500; 91 | } 92 | 93 | h1 { 94 | font-size: 4rem; 95 | margin-bottom: 20px; 96 | font-weight: 600; 97 | } 98 | 99 | p.about { 100 | font-size: 2.5rem; 101 | margin-bottom: 20px; 102 | } 103 | 104 | p { 105 | margin-bottom: 15px; 106 | } 107 | 108 | h2 { 109 | font-size: 2.5rem; 110 | font-weight: 600; 111 | padding-bottom: 10px; 112 | margin-bottom: 20px; 113 | border-bottom: 1px solid rgb(220, 220, 220); 114 | } 115 | 116 | 117 | h3 { 118 | font-size: 1.8rem; 119 | font-weight: 600; 120 | margin-bottom: 10px; 121 | } 122 | 123 | img { 124 | max-width: 100%; 125 | height: auto; 126 | } 127 | 128 | .uo { 129 | color: rgb(180, 180, 180); 130 | } 131 | 132 | 133 | .container { 134 | margin: 100px auto; 135 | width: 90%; 136 | max-width: 800px; 137 | } 138 | 139 | @media screen and (max-width: 600px) { 140 | .container { 141 | margin: 50px auto; 142 | } 143 | } 144 | 145 | section.site-section { 146 | margin-bottom: 50px; 147 | padding-bottom: 30px; 148 | } 149 | section:not(.site-section) { 150 | margin-bottom: 40px; 151 | } 152 | 153 | .highlight { 154 | margin-bottom: 15px; 155 | } 156 | 157 | pre { 158 | background-color: rgb(220, 220, 220); 159 | padding: 10px; 160 | display: block; 161 | font-family: 'Source Code Pro', monospace; 162 | font-size: 1.2rem; 163 | color: #000; 164 | 165 | white-space: pre-line; 166 | word-wrap: break-word; 167 | position: relative; 168 | } 169 | 170 | 171 | 172 | 173 | .copy-code { 174 | display: inline-block; 175 | width: auto; 176 | border: 2px solid rgb(220, 220, 220); 177 | border-top: 0; 178 | background-color: rgb(250, 250, 250); 179 | padding: 0px 10px; 180 | cursor: pointer; 181 | float: right; 182 | } 183 | .copy-code:hover { 184 | background-color: rgb(220, 220, 220); 185 | } 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | .input-group { 194 | margin-bottom: 20px; 195 | } 196 | 197 | label { 198 | display: block; 199 | } 200 | 201 | .main-label { 202 | font-weight: 600; 203 | margin-bottom: 5px; 204 | } 205 | 206 | label:not(.main-label) { 207 | padding: 5px 0; 208 | } 209 | 210 | select, 211 | #generate-embed { 212 | height: 40px; 213 | display: inline-block; 214 | font-size: 1.6rem; 215 | font-family: inherit; 216 | } 217 | 218 | select { 219 | padding: 5px; 220 | background-color: #fff; 221 | margin-right: 10px; 222 | margin-bottom: 10px; 223 | width: 100%; 224 | } 225 | 226 | #generate-embed { 227 | width: auto; 228 | cursor: pointer; 229 | padding: 5px 10px; 230 | background-color: #DB5600; 231 | border: 0; 232 | border-radius: 5px; 233 | color: #fff; 234 | 235 | } 236 | 237 | label.current { 238 | font-weight: 600; 239 | } 240 | 241 | input[type="checkbox"] { 242 | } 243 | 244 | 245 | 246 | 247 | /* Twemoji Awesome - http://ellekasai.github.io/twemoji-awesome/ */ 248 | .twa { 249 | display: inline-block; 250 | height: 1em; 251 | width: 1em; 252 | margin: 0 .05em 0 .1em; 253 | vertical-align: -0.1em; 254 | background-repeat: no-repeat; 255 | background-position: center center; 256 | background-size: 1em 1em; } 257 | 258 | .twa-heart { 259 | background-image: url("https://twemoji.maxcdn.com/svg/2764.svg"); 260 | } 261 | 262 | 263 | 264 | /* Loader - https://loading.io/css/ */ 265 | 266 | .lds-ellipsis { 267 | display: inline-block; 268 | position: relative; 269 | width: 64px; 270 | height: 40px; 271 | } 272 | .lds-ellipsis div { 273 | position: absolute; 274 | top: 10px; 275 | width: 11px; 276 | height: 11px; 277 | border-radius: 50%; 278 | background: #fff; 279 | animation-timing-function: cubic-bezier(0, 1, 1, 0); 280 | } 281 | .lds-ellipsis div:nth-child(1) { 282 | left: 6px; 283 | animation: lds-ellipsis1 0.6s infinite; 284 | } 285 | .lds-ellipsis div:nth-child(2) { 286 | left: 6px; 287 | animation: lds-ellipsis2 0.6s infinite; 288 | } 289 | .lds-ellipsis div:nth-child(3) { 290 | left: 26px; 291 | animation: lds-ellipsis2 0.6s infinite; 292 | } 293 | .lds-ellipsis div:nth-child(4) { 294 | left: 45px; 295 | animation: lds-ellipsis3 0.6s infinite; 296 | } 297 | @keyframes lds-ellipsis1 { 298 | 0% { 299 | transform: scale(0); 300 | } 301 | 100% { 302 | transform: scale(1); 303 | } 304 | } 305 | @keyframes lds-ellipsis3 { 306 | 0% { 307 | transform: scale(1); 308 | } 309 | 100% { 310 | transform: scale(0); 311 | } 312 | } 313 | @keyframes lds-ellipsis2 { 314 | 0% { 315 | transform: translate(0, 0); 316 | } 317 | 100% { 318 | transform: translate(19px, 0); 319 | } 320 | } 321 | 322 | 323 | -------------------------------------------------------------------------------- /public/embed/script.js: -------------------------------------------------------------------------------- 1 | function setGlobalOptions(){var e=window.location.search.split("?")[1].split("&"),t={};e.forEach(function(e){var n=e.split("=")[0],a=e.split("=")[1];switch(n){case"feat":t.featureID=a,t.dataSource=0===t.featureID.indexOf("mdn-")?"mdn":"caniuse";break;case"periods":t.periods=a.split(",");break;case"accessible-colours":t.accessibleColours="true"===a;break;case"image-base":"none"!==a&&(t.imageBase=a);break;case"screenshot":t.screenshot="true"===a}}),t.periods||(t.periods=["future_1","current","past_1","past_2"]),OPTIONS=t}function getShortenedBrowserVersion(e){return e&&e.indexOf("-")>-1&&(e=e.split("-")[1]),e}function get(e){return new Promise(function(t,n){var a=new XMLHttpRequest;a.open("GET",e,!0),a.onload=function(){200===a.status?t(JSON.parse(a.response)):n(Error(a.statusText))},a.onerror=function(){n(Error("Network Error"))},a.send()})}function post(e,t){return new Promise(function(n,a){var r=new XMLHttpRequest;r.open("POST",e,!0),r.setRequestHeader("Content-type","application/json; charset=utf-8"),r.onload=function(){200===r.status?n(JSON.parse(r.response)):a(Error(r.statusText))},r.onerror=function(){a(Error("Network Error"))},r.send(JSON.stringify(t))})}function getFeature(){switch(OPTIONS.dataSource){case"mdn":return post(embedAPI+"/mdn-browser-compat-data",{feature:OPTIONS.featureID}).then(function(e){return FEATURE=Object.assign({url:e.mdn_url},e),getBrowserData()});case"caniuse":return get(caniuseDataUrl).then(function(e){return FEATURE=Object.assign({url:"https://caniuse.com/#feat="+OPTIONS.featureID},e.data[OPTIONS.featureID]),getBrowserData(e.agents)})}}function getBrowserData(e){return Promise.resolve().then(function(){return e||get(caniuseDataUrl).then(function(e){return e.agents})}).then(function(e){return parseBrowserData(e)})}function parseBrowserData(e){for(var t={},a=0;a-1?(n=parseInt(c.split("_")[1]),t[s][c]=e[s].version_list[r-n]?e[s].version_list[r-n].version:null):c.indexOf("future")>-1&&(n=parseInt(c.split("_")[1]),t[s][c]=e[s].version_list[r+n]?e[s].version_list[r+n].version:null)}}for(var u={},a=0;a0?c=!0:parseFloat(s)>=parseFloat(o)&&(c=!0),i&&parseFloat(s)<=parseFloat(i)&&(c=!1);var u=c?FEATURE_IDENTIFIERS.supported:FEATURE_IDENTIFIERS.unsupported;n[e][t]=u}}for(var n={},a=0;aData on support for the '+OPTIONS.featureID+' feature across the major browsers':"Can I Use "+OPTIONS.featureID+"? Data on support for the "+OPTIONS.featureID+" feature across the major browsers. (Embed Loading)":"No feature ID was specified",document.getElementById("defaultMessage").innerHTML=e}function displayFeatureInformation(){if(document.getElementById("featureTitle").textContent=FEATURE.title,document.getElementById("featureLink").href=FEATURE.url,FEATURE.description){var e=FEATURE.description;e=e.replace(//g,">"),e=e.replace(/<code>/g,""),e=e.replace(/<\/code>/g,""),document.getElementById("featureDescription").innerHTML=e}if(FEATURE.usage_perc_y){var t=FEATURE.usage_perc_y,n=FEATURE.usage_perc_a,a=t+n;a=a.toFixed(2),document.getElementById("note").innerHTML='Global: '+t+'% + '+n+"% = "+a+"%"}else FEATURE.status&&(FEATURE.status.experimental&&(document.getElementById("note").innerHTML="Experimental feature"),FEATURE.status.deprecated&&(document.getElementById("note").innerHTML="Deprecated feature"));if(OPTIONS.accessibleColours&&document.body.classList.add("accessible-colours"),OPTIONS.screenshot){document.body.classList.add("screenshot");var r=new Date,s=["January","February","March","April","May","June","July","August","September","October","November","December"];document.getElementById("footer-right").innerHTML=r.getDate()+" "+s[r.getMonth()]+" "+r.getFullYear(),document.querySelector(".icon-external-link").setAttribute("hidden","true")}else document.getElementById("accessibleColoursToggle").addEventListener("click",function(){document.body.classList.toggle("accessible-colours")});switch(OPTIONS.dataSource){case"mdn":document.getElementById("footer-left").innerHTML='Data from mozilla.org | Embed from caniuse.bitsofco.de';break;case"caniuse":document.getElementById("footer-left").innerHTML='Data from caniuse.com | Embed from caniuse.bitsofco.de'}document.body.classList.add(OPTIONS.dataSource)}function displayTable(e){for(var t=OPTIONS.periods.length-1;t>-1;t--){for(var n="",a=0;a';var r=document.createElement("tr");r.className="statistics "+OPTIONS.periods[t],r.innerHTML=n,document.getElementById("tableBody").appendChild(r)}for(var s=!1,o=!1,i=!1,t=0;t-1&&(d=f[p]);void 0!=e[c][l]&&(d.className+=" "+e[c][l]);var g=getShortenedBrowserVersion(BROWSER_DATA.versions[c][l]),m=""+g+''+BROWSER_DATA.usage[c][l]+"%";void 0!=BROWSER_DATA.versions[c][l]?d.innerHTML=m:d.innerHTML="",void 0!=e[c][l]&&e[c][l].indexOf(FEATURE_IDENTIFIERS.prefixed)>-1&&(s=!0),void 0!=e[c][l]&&e[c][l].indexOf(FEATURE_IDENTIFIERS.unknown)>-1&&(o=!0),void 0!=e[c][l]&&e[c][l].indexOf(FEATURE_IDENTIFIERS.flagged)>-1&&(i=!0)}document.getElementById("legendX").style.display=s?"inline-block":"none",document.getElementById("legendU").style.display=o?"inline-block":"none",document.getElementById("legendD").style.display=i?"inline-block":"none"}function postDocumentHeight(){var e=document.getElementsByClassName("feature")[0].scrollHeight,t="ciu_embed:"+OPTIONS.featureID+":"+e;parent.postMessage(t,"*"),window.onresize=function(t){e=document.getElementsByClassName("feature")[0].scrollHeight;var n="ciu_embed:"+OPTIONS.featureID+":"+e;parent.postMessage(n,"*")}}var OPTIONS,BROWSER_DATA,FEATURE,caniuseDataUrl="https://raw.githubusercontent.com/Fyrd/caniuse/master/fulldata-json/data-2.0.json",embedAPI="https://api.caniuse.bitsofco.de",BROWSERS=["ie","edge","firefox","chrome","safari","ios_saf","op_mini","and_chr","android","samsung"],MDN_BROWSERS_KEY={ie:"ie",edge:"edge",firefox:"firefox",chrome:"chrome",safari:"safari",ios_saf:"safari_ios",op_mini:"op_mini",and_chr:"chrome_android",android:"android",samsung:"samsunginternet_android"},FEATURE_IDENTIFIERS={supported:"y",unsupported:"n",partial:"a",unknown:"u",prefixed:"x",flagged:"d"};!function(){setGlobalOptions(),displayLoadingMessage(),getFeature().then(function(){return parseSupportData()}).then(function(e){console.log(FEATURE),console.log(e),displayFeatureInformation(),displayTable(e),document.getElementById("defaultMessage").style.display="none",document.getElementsByClassName("feature")[0].style.display="block",postDocumentHeight()}).catch(function(e){document.getElementById("defaultMessage").innerHTML="Feature not found...",console.error(e)})}(); -------------------------------------------------------------------------------- /public/website/clipboard.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * clipboard.js v1.5.5 3 | * https://zenorocha.github.io/clipboard.js 4 | * 5 | * Licensed MIT © Zeno Rocha 6 | */ 7 | !function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{var e;e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this,e.Clipboard=t()}}(function(){var t,e,n;return function t(e,n,r){function o(a,c){if(!n[a]){if(!e[a]){var s="function"==typeof require&&require;if(!c&&s)return s(a,!0);if(i)return i(a,!0);var u=new Error("Cannot find module '"+a+"'");throw u.code="MODULE_NOT_FOUND",u}var l=n[a]={exports:{}};e[a][0].call(l.exports,function(t){var n=e[a][1][t];return o(n?n:t)},l,l.exports,t,e,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;ar;r++)n[r].fn.apply(n[r].ctx,e);return this},off:function(t,e){var n=this.e||(this.e={}),r=n[t],o=[];if(r&&e)for(var i=0,a=r.length;a>i;i++)r[i].fn!==e&&r[i].fn._!==e&&o.push(r[i]);return o.length?n[t]=o:delete n[t],this}},e.exports=r},{}],8:[function(t,e,n){"use strict";function r(t){return t&&t.__esModule?t:{"default":t}}function o(t,e){if(!(t instanceof e))throw new TypeError("Cannot call a class as a function")}n.__esModule=!0;var i=function(){function t(t,e){for(var n=0;n 0 ? checkboxesChecked : null; 21 | } 22 | 23 | /* ===================== 24 | * Get list of available features for 115 | 116 | 117 | 118 |
119 |

Select Embed Type

120 |

What type of embed would you like? See examples above for more information

121 | 122 |
123 | 124 | 125 | 126 | 127 | 128 |
129 |
130 | 131 |
132 |

Additional Settings

133 | 134 |
135 | 136 | 137 | 138 | 139 | 140 | 141 | 143 | 144 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 |
158 | 159 |
160 | 161 | 162 | 163 | 164 | 165 |
166 |
167 | 168 |
169 | 170 |
171 | 172 | 182 | 183 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 213 | 214 | 215 | -------------------------------------------------------------------------------- /PRIVACY.md: -------------------------------------------------------------------------------- 1 | # PRIVACY POLICY 2 | 3 | **Last updated December 04, 2022** 4 | 5 | 6 | This privacy notice for The CanIUse Embed ('**Company**', '**we**', '**us**', or '**our**'), describes how and why we might collect, store, use, and/or share ('**process**') your information when you use our services ('**Services**'), such as when you: 7 | 8 | * Visit our website at [https://caniuse.bitsofco.de/](https://caniuse.bitsofco.de/), or any website of ours that links to this privacy notice 9 | 10 | * Engage with us in other related ways, including any sales, marketing, or events 11 | 12 | **Questions or concerns?** Reading this privacy notice will help you understand your privacy rights and choices. If you do not agree with our policies and practices, please do not use our Services. If you still have any questions or concerns, please contact us at ire@ireaderinokun.com. 13 | 14 | 15 | 16 | 17 | 18 | ## SUMMARY OF KEY POINTS** 19 | 20 | 21 | 22 | **_This summary provides key points from our privacy notice, but you can find out more details about any of these topics by clicking the link following each key point or by using our table of contents below to find the section you are looking for. You can also click_** [**_here_**](#toc) **_to go directly to our table of contents._** 23 | 24 | 25 | 26 | **What personal information do we process?** When you visit, use, or navigate our Services, we may process personal information depending on how you interact with The CanIUse Embed and the Services, the choices you make, and the products and features you use. Click [here](#personalinfo) to learn more. 27 | 28 | 29 | 30 | **Do we process any sensitive personal information?** We do not process sensitive personal information. 31 | 32 | 33 | 34 | **Do we receive any information from third parties?** We do not receive any information from third parties. 35 | 36 | 37 | 38 | **How do we process your information?** We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent. We process your information only when we have a valid legal reason to do so. Click [here](#infouse) to learn more. 39 | 40 | 41 | 42 | **In what situations and with which parties do we share personal information?** We may share information in specific situations and with specific third parties. Click [here](#whoshare) to learn more. 43 | 44 | 45 | 46 | **What are your rights?** Depending on where you are located geographically, the applicable privacy law may mean you have certain rights regarding your personal information. Click [here](#privacyrights) to learn more. 47 | 48 | 49 | 50 | **How do you exercise your rights?** The easiest way to exercise your rights is by filling out our data subject request form available [here](https://app.termly.io/notify/0aa09f96-8546-431b-974e-82fb98d5f670), or by contacting us. We will consider and act upon any request in accordance with applicable data protection laws. 51 | 52 | 53 | 54 | Want to learn more about what The CanIUse Embed does with any information we collect? Click [here](#toc) to review the notice in full. 55 | 56 | 57 | 58 | 59 | 60 | ## TABLE OF CONTENTS 61 | 62 | 63 | 64 | [1\. WHAT INFORMATION DO WE COLLECT?](#infocollect) 65 | 66 | [2\. HOW DO WE PROCESS YOUR INFORMATION?](#infouse) 67 | 68 | [3\. WHAT LEGAL BASES DO WE RELY ON TO PROCESS YOUR PERSONAL INFORMATION?](#legalbases) 69 | 70 | [4\. WHEN AND WITH WHOM DO WE SHARE YOUR PERSONAL INFORMATION?](#whoshare) 71 | 72 | [5\. HOW LONG DO WE KEEP YOUR INFORMATION?](#inforetain) 73 | 74 | [6\. DO WE COLLECT INFORMATION FROM MINORS?](#infominors) 75 | 76 | [7\. WHAT ARE YOUR PRIVACY RIGHTS?](#privacyrights) 77 | 78 | [8\. CONTROLS FOR DO-NOT-TRACK FEATURES](#DNT) 79 | 80 | [9\. DO CALIFORNIA RESIDENTS HAVE SPECIFIC PRIVACY RIGHTS?](#caresidents) 81 | 82 | [10\. DO WE MAKE UPDATES TO THIS NOTICE?](#policyupdates) 83 | 84 | [11\. HOW CAN YOU CONTACT US ABOUT THIS NOTICE?](#contact) 85 | 86 | [12\. HOW CAN YOU REVIEW, UPDATE, OR DELETE THE DATA WE COLLECT FROM YOU?](#request) 87 | 88 | 89 | 90 | 91 | 92 | **1\. WHAT INFORMATION DO WE COLLECT?** 93 | 94 | 95 | 96 | **Personal information you disclose to us** 97 | 98 | 99 | 100 | **_In Short:_** _We collect personal information that you provide to us._ 101 | 102 | 103 | 104 | We collect personal information that you voluntarily provide to us when you express an interest in obtaining information about us or our products and Services, when you participate in activities on the Services, or otherwise when you contact us. 105 | 106 | 107 | 108 | **Sensitive Information.** We do not process sensitive information. 109 | 110 | 111 | 112 | All personal information that you provide to us must be true, complete, and accurate, and you must notify us of any changes to such personal information. 113 | 114 | 115 | 116 | **2\. HOW DO WE PROCESS YOUR INFORMATION?** 117 | 118 | 119 | 120 | **_In Short:_** _We process your information to provide, improve, and administer our Services, communicate with you, for security and fraud prevention, and to comply with law. We may also process your information for other purposes with your consent._ 121 | 122 | 123 | 124 | **We process your personal information for a variety of reasons, depending on how you interact with our Services, including:** 125 | 126 | * **To save or protect an individual's vital interest.** We may process your information when necessary to save or protect an individual’s vital interest, such as to prevent harm. 127 | 128 | 129 | 130 | **3\. WHAT LEGAL BASES DO WE RELY ON TO PROCESS YOUR INFORMATION?** 131 | 132 | 133 | 134 | _**In Short:** We only process your personal information when we believe it is necessary and we have a valid legal reason (i.e. legal basis) to do so under applicable law, like with your consent, to comply with laws, to provide you with services to enter into or fulfil our contractual obligations, to protect your rights, or to fulfil our legitimate business interests._ 135 | 136 | 137 | 138 | _**If you are located in the EU or UK, this section applies to you.**_ 139 | 140 | 141 | 142 | The General Data Protection Regulation (GDPR) and UK GDPR require us to explain the valid legal bases we rely on in order to process your personal information. As such, we may rely on the following legal bases to process your personal information: 143 | 144 | * **Consent.** We may process your information if you have given us permission (i.e. consent) to use your personal information for a specific purpose. You can withdraw your consent at any time. Click [here](#withdrawconsent) to learn more. 145 | 146 | * **Legal Obligations.** We may process your information where we believe it is necessary for compliance with our legal obligations, such as to cooperate with a law enforcement body or regulatory agency, exercise or defend our legal rights, or disclose your information as evidence in litigation in which we are involved. 147 | 148 | 149 | * **Vital Interests.** We may process your information where we believe it is necessary to protect your vital interests or the vital interests of a third party, such as situations involving potential threats to the safety of any person. 150 | 151 | 152 | 153 | **_If you are located in Canada, this section applies to you._** 154 | 155 | 156 | 157 | We may process your information if you have given us specific permission (i.e. express consent) to use your personal information for a specific purpose, or in situations where your permission can be inferred (i.e. implied consent). You can withdraw your consent at any time. Click [here](#withdrawconsent) to learn more. 158 | 159 | 160 | 161 | In some exceptional cases, we may be legally permitted under applicable law to process your information without your consent, including, for example: 162 | 163 | * If collection is clearly in the interests of an individual and consent cannot be obtained in a timely way 164 | 165 | * For investigations and fraud detection and prevention 166 | 167 | * For business transactions provided certain conditions are met 168 | 169 | * If it is contained in a witness statement and the collection is necessary to assess, process, or settle an insurance claim 170 | 171 | * For identifying injured, ill, or deceased persons and communicating with next of kin 172 | 173 | * If we have reasonable grounds to believe an individual has been, is, or may be victim of financial abuse 174 | 175 | * If it is reasonable to expect collection and use with consent would compromise the availability or the accuracy of the information and the collection is reasonable for purposes related to investigating a breach of an agreement or a contravention of the laws of Canada or a province 176 | 177 | * If disclosure is required to comply with a subpoena, warrant, court order, or rules of the court relating to the production of records 178 | 179 | * If it was produced by an individual in the course of their employment, business, or profession and the collection is consistent with the purposes for which the information was produced 180 | 181 | * If the collection is solely for journalistic, artistic, or literary purposes 182 | 183 | * If the information is publicly available and is specified by the regulations 184 | 185 | 186 | 187 | **4\. WHEN AND WITH WHOM DO WE SHARE YOUR PERSONAL INFORMATION?** 188 | 189 | 190 | 191 | **_In Short:_** _We may share information in specific situations described in this section and/or with the following third parties._ 192 | 193 | 194 | 195 | We may need to share your personal information in the following situations: 196 | 197 | * **Business Transfers.** We may share or transfer your information in connection with, or during negotiations of, any merger, sale of company assets, financing, or acquisition of all or a portion of our business to another company. 198 | 199 | 200 | 201 | **5\. HOW LONG DO WE KEEP YOUR INFORMATION?** 202 | 203 | 204 | 205 | **_In Short:_** _We keep your information for as long as necessary to fulfil the purposes outlined in this privacy notice unless otherwise required by law._ 206 | 207 | 208 | 209 | We will only keep your personal information for as long as it is necessary for the purposes set out in this privacy notice, unless a longer retention period is required or permitted by law (such as tax, accounting, or other legal requirements). 210 | 211 | 212 | 213 | When we have no ongoing legitimate business need to process your personal information, we will either delete or anonymise such information, or, if this is not possible (for example, because your personal information has been stored in backup archives), then we will securely store your personal information and isolate it from any further processing until deletion is possible. 214 | 215 | 216 | 217 | **6\. DO WE COLLECT INFORMATION FROM MINORS?** 218 | 219 | 220 | 221 | **_In Short:_** _We do not knowingly collect data from or market to children under 18 years of age._ 222 | 223 | 224 | 225 | We do not knowingly solicit data from or market to children under 18 years of age. By using the Services, you represent that you are at least 18 or that you are the parent or guardian of such a minor and consent to such minor dependent’s use of the Services. If we learn that personal information from users less than 18 years of age has been collected, we will deactivate the account and take reasonable measures to promptly delete such data from our records. If you become aware of any data we may have collected from children under age 18, please contact us at ire@ireaderinokun.com. 226 | 227 | 228 | 229 | **7\. WHAT ARE YOUR PRIVACY RIGHTS?** 230 | 231 | 232 | 233 | **_In Short:_** _In some regions, such as the European Economic Area (EEA), United Kingdom (UK), and Canada, you have rights that allow you greater access to and control over your personal information. You may review, change, or terminate your account at any time._ 234 | 235 | 236 | 237 | In some regions (like the EEA, UK, and Canada), you have certain rights under applicable data protection laws. These may include the right (i) to request access and obtain a copy of your personal information, (ii) to request rectification or erasure; (iii) to restrict the processing of your personal information; and (iv) if applicable, to data portability. In certain circumstances, you may also have the right to object to the processing of your personal information. You can make such a request by contacting us by using the contact details provided in the section '[HOW CAN YOU CONTACT US ABOUT THIS NOTICE?](#contact)' below. 238 | 239 | 240 | 241 | We will consider and act upon any request in accordance with applicable data protection laws. 242 | 243 | If you are located in the EEA or UK and you believe we are unlawfully processing your personal information, you also have the right to complain to your local data protection supervisory authority. You can find their contact details here: [https://ec.europa.eu/justice/data-protection/bodies/authorities/index\_en.htm](https://ec.europa.eu/justice/data-protection/bodies/authorities/index_en.htm). 244 | 245 | 246 | 247 | If you are located in Switzerland, the contact details for the data protection authorities are available here: [https://www.edoeb.admin.ch/edoeb/en/home.html](https://www.edoeb.admin.ch/edoeb/en/home.html). 248 | 249 | 250 | 251 | **Withdrawing your consent:** If we are relying on your consent to process your personal information, which may be express and/or implied consent depending on the applicable law, you have the right to withdraw your consent at any time. You can withdraw your consent at any time by contacting us by using the contact details provided in the section '[HOW CAN YOU CONTACT US ABOUT THIS NOTICE?](#contact)' below. 252 | 253 | 254 | 255 | However, please note that this will not affect the lawfulness of the processing before its withdrawal nor, when applicable law allows, will it affect the processing of your personal information conducted in reliance on lawful processing grounds other than consent. 256 | 257 | 258 | 259 | If you have questions or comments about your privacy rights, you may email us at ire@ireaderinokun.com. 260 | 261 | 262 | 263 | **8\. CONTROLS FOR DO-NOT-TRACK FEATURES** 264 | 265 | 266 | 267 | Most web browsers and some mobile operating systems and mobile applications include a Do-Not-Track ('DNT') feature or setting you can activate to signal your privacy preference not to have data about your online browsing activities monitored and collected. At this stage no uniform technology standard for recognising and implementing DNT signals has been finalised. As such, we do not currently respond to DNT browser signals or any other mechanism that automatically communicates your choice not to be tracked online. If a standard for online tracking is adopted that we must follow in the future, we will inform you about that practice in a revised version of this privacy notice. 268 | 269 | 270 | 271 | **9\. DO CALIFORNIA RESIDENTS HAVE SPECIFIC PRIVACY RIGHTS?** 272 | 273 | 274 | 275 | **_In Short:_** _Yes, if you are a resident of California, you are granted specific rights regarding access to your personal information._ 276 | 277 | 278 | 279 | California Civil Code Section 1798.83, also known as the 'Shine The Light' law, permits our users who are California residents to request and obtain from us, once a year and free of charge, information about categories of personal information (if any) we disclosed to third parties for direct marketing purposes and the names and addresses of all third parties with which we shared personal information in the immediately preceding calendar year. If you are a California resident and would like to make such a request, please submit your request in writing to us using the contact information provided below. 280 | 281 | 282 | 283 | If you are under 18 years of age, reside in California, and have a registered account with Services, you have the right to request removal of unwanted data that you publicly post on the Services. To request removal of such data, please contact us using the contact information provided below and include the email address associated with your account and a statement that you reside in California. We will make sure the data is not publicly displayed on the Services, but please be aware that the data may not be completely or comprehensively removed from all our systems (e.g. backups, etc.). 284 | 285 | 286 | 287 | **10\. DO WE MAKE UPDATES TO THIS NOTICE?** 288 | 289 | _**In Short:** Yes, we will update this notice as necessary to stay compliant with relevant laws._ 290 | 291 | We may update this privacy notice from time to time. The updated version will be indicated by an updated 'Revised' date and the updated version will be effective as soon as it is accessible. If we make material changes to this privacy notice, we may notify you either by prominently posting a notice of such changes or by directly sending you a notification. We encourage you to review this privacy notice frequently to be informed of how we are protecting your information. 292 | 293 | 294 | 295 | **11\. HOW CAN YOU CONTACT US ABOUT THIS NOTICE?** 296 | 297 | If you have questions or comments about this notice, you may email me at ire@ireaderinokun.com 298 | 299 | 300 | **12\. HOW CAN YOU REVIEW, UPDATE, OR DELETE THE DATA WE COLLECT FROM YOU?** 301 | 302 | Based on the applicable laws of your country, you may have the right to request access to the personal information we collect from you, change that information, or delete it. To request to review, update, or delete your personal information, please submit a request form by clicking [here](https://app.termly.io/notify/0aa09f96-8546-431b-974e-82fb98d5f670). 303 | 304 | This privacy policy was created using Termly's [Privacy Policy Generator](https://termly.io/products/privacy-policy-generator/). 305 | -------------------------------------------------------------------------------- /src/embed/script.js: -------------------------------------------------------------------------------- 1 | /* ******************************* 2 | * 3 | * Global Variables 4 | * 5 | * ******************************* */ 6 | 7 | var OPTIONS; 8 | /* 9 | OPTIONS: { 10 | featureID*, 11 | periods*, 12 | accessibleColours, 13 | imageBase, 14 | screenshot 15 | } 16 | */ 17 | var BROWSER_DATA; 18 | /* 19 | BROWSER_DATA: { 20 | browserVersions: { 21 | chrome: { 22 | past_1: "80" 23 | } 24 | }, 25 | browserUsage: { 26 | chrome: { 27 | past_1: "34.80" 28 | } 29 | } 30 | } 31 | */ 32 | 33 | var FEATURE; 34 | /* 35 | FEATURE: { 36 | feature: { 37 | title*, 38 | 39 | description, 40 | usage_perc_y, 41 | usage_perc_a, 42 | global_a, 43 | 44 | stats[browser][BROWSER_DATA.versions[browser][period]] 45 | 46 | stats: { 47 | chrome: { 48 | 49 | } 50 | } 51 | } 52 | } 53 | */ 54 | 55 | 56 | var caniuseDataUrl = 'https://raw.githubusercontent.com/Fyrd/caniuse/main/fulldata-json/data-2.0.json'; 57 | var embedAPI = 'https://api.caniuse.bitsofco.de'; 58 | 59 | var BROWSERS = ['ie', 'edge', 'firefox', 'chrome', 'safari', 'ios_saf', 'op_mini', 'and_chr', 'android', 'samsung']; 60 | var MDN_BROWSERS_KEY = { 61 | 'ie': 'ie', 62 | 'edge': 'edge', 63 | 'firefox': 'firefox', 64 | 'chrome': 'chrome', 65 | 'safari': 'safari', 66 | 'ios_saf': 'safari_ios', 67 | 'op_mini': 'op_mini', 68 | 'and_chr': 'chrome_android', 69 | 'android': 'android', 70 | 'samsung': 'samsunginternet_android', 71 | }; 72 | 73 | var FEATURE_IDENTIFIERS = { 74 | supported: 'y', 75 | unsupported: 'n', 76 | partial: 'a', 77 | unknown: 'u', 78 | prefixed: 'x', 79 | flagged: 'd' 80 | }; 81 | 82 | 83 | 84 | /* ******************************* 85 | * 86 | * Functions - Utilities 87 | * 88 | * ******************************* */ 89 | 90 | function setGlobalOptions() { 91 | 92 | var params = window.location.search.split("?")[1].split("&"); 93 | var opts = {}; 94 | 95 | params.forEach(function (param) { 96 | var key = param.split("=")[0]; 97 | var value = param.split("=")[1]; 98 | 99 | switch (key) { 100 | case "feat": 101 | opts.featureID = value; 102 | opts.dataSource = opts.featureID.indexOf('mdn-') === 0 ? 'mdn' : 'caniuse'; 103 | break; 104 | case "periods": 105 | opts.periods = value.split(","); 106 | break; 107 | case "accessible-colours": 108 | opts.accessibleColours = value === "true"; 109 | break; 110 | case "image-base": 111 | if (value !== 'none') opts.imageBase = value; 112 | break; 113 | case "screenshot": 114 | opts.screenshot = value === "true"; 115 | break; 116 | } 117 | }); 118 | 119 | if (!opts.periods) opts.periods = ['future_1', 'current', 'past_1', 'past_2']; 120 | 121 | OPTIONS = opts; 122 | } 123 | 124 | function getShortenedBrowserVersion(version) { 125 | if (version && version.indexOf('-') > -1) { 126 | version = version.split('-')[1]; 127 | } 128 | return version; 129 | } 130 | 131 | function get(url) { 132 | return new Promise(function(resolve, reject) { 133 | var req = new XMLHttpRequest(); 134 | req.open('GET', url, true); 135 | 136 | req.onload = function() { 137 | if (req.status === 200) { 138 | resolve( JSON.parse(req.response)); 139 | } else { 140 | reject(Error(req.statusText)); 141 | } 142 | }; 143 | 144 | req.onerror = function() { reject(Error("Network Error")); }; 145 | req.send(); 146 | }); 147 | } 148 | 149 | function post(url, body) { 150 | return new Promise(function(resolve, reject) { 151 | var req = new XMLHttpRequest(); 152 | req.open('POST', url, true); 153 | req.setRequestHeader('Content-type', 'application/json; charset=utf-8'); 154 | 155 | req.onload = function() { 156 | if (req.status === 200) { 157 | resolve( JSON.parse(req.response)); 158 | } else { 159 | reject(Error(req.statusText)); 160 | } 161 | }; 162 | 163 | req.onerror = function() { reject(Error("Network Error")); }; 164 | req.send( JSON.stringify(body) ); 165 | }); 166 | } 167 | 168 | 169 | 170 | /* ******************************* 171 | * 172 | * Functions - Get Information 173 | * 174 | * ******************************* */ 175 | 176 | function getFeature() { 177 | switch (OPTIONS.dataSource) { 178 | 179 | case 'mdn': 180 | 181 | var url = embedAPI + '/mdn-browser-compat-data'; 182 | var body = { feature: OPTIONS.featureID }; 183 | return post(url, body) 184 | .then(function (feature) { 185 | FEATURE = Object.assign({ 186 | url: feature.mdn_url, 187 | }, feature); 188 | 189 | return getBrowserData() 190 | }); 191 | 192 | case 'caniuse': 193 | 194 | return get(caniuseDataUrl) 195 | .then(function (res) { 196 | FEATURE = Object.assign({ 197 | url: 'https://caniuse.com/#feat=' + OPTIONS.featureID, 198 | }, res.data[OPTIONS.featureID]); 199 | 200 | return getBrowserData(res.agents); 201 | }); 202 | } 203 | } 204 | 205 | function getBrowserData(agents) { 206 | return Promise.resolve() 207 | .then(function () { 208 | if (agents) return agents; 209 | 210 | return get(caniuseDataUrl) 211 | .then(function (res) { 212 | return res.agents; 213 | }); 214 | }) 215 | .then(function (a) { 216 | return parseBrowserData(a); 217 | }); 218 | } 219 | 220 | 221 | 222 | /* ******************************* 223 | * 224 | * Functions - Parsing Data 225 | * 226 | * ******************************* */ 227 | 228 | function parseBrowserData(agents) { 229 | 230 | var browserVersions = {}; 231 | 232 | for (var i = 0; i < BROWSERS.length; i++) { 233 | var browser = BROWSERS[i]; 234 | 235 | // GET INDEX OF CURRENT VERSION 236 | var currentVersion = agents[browser].current_version; 237 | var currentVersionIndex; 238 | for (var x = 0; x < agents[browser].version_list.length; x++) { 239 | if (agents[browser].version_list[x].era === 0) { 240 | currentVersionIndex = x; 241 | break; 242 | } 243 | } 244 | currentVersionIndex = parseInt(currentVersionIndex); 245 | 246 | 247 | browserVersions[browser] = {}; 248 | 249 | for (var x = 0; x < OPTIONS.periods.length; x++) { 250 | 251 | var period = OPTIONS.periods[x]; 252 | 253 | if (period === 'current') { 254 | 255 | browserVersions[browser][period] = currentVersion; 256 | } else if (period.indexOf('past') > -1) { 257 | 258 | n = parseInt(period.split('_')[1]); 259 | browserVersions[browser][period] = agents[browser].version_list[currentVersionIndex - n] ? agents[browser].version_list[currentVersionIndex - n].version : null 260 | } else if (period.indexOf('future') > -1) { 261 | 262 | n = parseInt(period.split('_')[1]); 263 | browserVersions[browser][period] = agents[browser].version_list[currentVersionIndex + n] ? agents[browser].version_list[currentVersionIndex + n].version : null 264 | } 265 | 266 | 267 | } 268 | } 269 | 270 | 271 | var browserUsage = {}; 272 | 273 | for (var i = 0; i < BROWSERS.length; i++) { 274 | var browser = BROWSERS[i]; 275 | browserUsage[browser] = {}; 276 | 277 | for (var x = 0; x < OPTIONS.periods.length; x++) { 278 | var period = OPTIONS.periods[x]; 279 | 280 | var period_version = browserVersions[browser][period]; 281 | var period_usage = agents[browser].usage_global[period_version]; 282 | period_usage = period_usage ? period_usage.toFixed(2) : 0; 283 | 284 | browserUsage[browser][period] = period_usage; 285 | } 286 | } 287 | 288 | return BROWSER_DATA = { 289 | versions: browserVersions, 290 | usage: browserUsage 291 | }; 292 | } 293 | 294 | function parseSupportData() { 295 | 296 | var browserSupport = {}; 297 | 298 | function parseCanIUseData(browser, period) { 299 | browserSupport[browser][period] = FEATURE.stats[browser][BROWSER_DATA.versions[browser][period]]; 300 | } 301 | 302 | function parseMDNData(browser, period) { 303 | 304 | if (!BROWSER_DATA.versions[browser][period]) return; 305 | 306 | var supportData = FEATURE.support[MDN_BROWSERS_KEY[browser]]; 307 | if (!supportData) { 308 | browserSupport[browser][period] = FEATURE_IDENTIFIERS.unknown; 309 | return; 310 | } 311 | 312 | var this_version = BROWSER_DATA.versions[browser][period]; 313 | 314 | function getValue(key) { 315 | var val; 316 | 317 | if (supportData[key]) { 318 | val = supportData[key] 319 | } else if (supportData[0] && supportData[0][key]) { 320 | val = supportData[0][key] 321 | } else if (supportData[1] && supportData[1][key]) { 322 | val = supportData[1][key] 323 | } 324 | 325 | if (val) val = val.replace(/≤/g, ""); 326 | 327 | return val; 328 | } 329 | 330 | var version_added = getValue('version_added'); 331 | var version_removed = getValue('version_removed'); 332 | 333 | var isSupported = false; 334 | 335 | if (version_added === true) { 336 | isSupported = true; 337 | } else if (this_version === 'TP' && version_added > 0) { 338 | isSupported = true; 339 | } else if (parseFloat(this_version) >= parseFloat(version_added)) { 340 | isSupported = true; 341 | } 342 | if (version_removed && (parseFloat(this_version) <= parseFloat(version_removed))) { 343 | isSupported = false; 344 | } 345 | 346 | var supportString = isSupported ? FEATURE_IDENTIFIERS.supported : FEATURE_IDENTIFIERS.unsupported; 347 | browserSupport[browser][period] = supportString; 348 | } 349 | 350 | for (var i = 0; i < BROWSERS.length; i++) { 351 | var browser = BROWSERS[i]; 352 | 353 | browserSupport[browser] = {}; 354 | 355 | for (var x = 0; x < OPTIONS.periods.length; x++) { 356 | var period = OPTIONS.periods[x]; 357 | 358 | switch (OPTIONS.dataSource) { 359 | case 'mdn': 360 | parseMDNData(browser, period); 361 | break; 362 | case 'caniuse': 363 | parseCanIUseData(browser, period); 364 | break; 365 | } 366 | } 367 | } 368 | 369 | return browserSupport; 370 | } 371 | 372 | 373 | 374 | /* ******************************* 375 | * 376 | * Functions - Displaying Data 377 | * 378 | * ******************************* */ 379 | 380 | function displayLoadingMessage() { 381 | var defaultMessage; 382 | 383 | if (!OPTIONS.featureID) { 384 | defaultMessage = 'No feature ID was specified'; 385 | } else if (OPTIONS.imageBase) { 386 | defaultMessage = '' + 387 | '' + 388 | '' + 389 | '' + 390 | 'Data on support for the ' + OPTIONS.featureID + ' feature across the major browsers' + 391 | ''; 392 | } else { 393 | defaultMessage = 'Can I Use ' + OPTIONS.featureID + '? Data on support for the ' + OPTIONS.featureID + ' feature across the major browsers. (Embed Loading)'; 394 | } 395 | 396 | document.getElementById('defaultMessage').innerHTML = defaultMessage; 397 | } 398 | 399 | function displayFeatureInformation() { 400 | 401 | document.getElementById('featureTitle').textContent = FEATURE.title; 402 | document.getElementById('featureLink').href = FEATURE.url; 403 | 404 | if (FEATURE.description) { 405 | var featureDescription = FEATURE.description; 406 | featureDescription = featureDescription.replace(//g, ">"); 408 | featureDescription = featureDescription.replace(/<code>/g, ""); 409 | featureDescription = featureDescription.replace(/<\/code>/g, ""); 410 | document.getElementById('featureDescription').innerHTML = featureDescription; 411 | } 412 | 413 | if (FEATURE.usage_perc_y) { 414 | var global_y = FEATURE.usage_perc_y; 415 | var global_a = FEATURE.usage_perc_a; 416 | var global_total = global_y + global_a; 417 | global_total = global_total.toFixed(2); 418 | 419 | document.getElementById('note').innerHTML = 'Global: ' + global_y + '% + ' + global_a + '% = ' + global_total + '%'; 420 | } else if (FEATURE.status) { 421 | 422 | if (FEATURE.status.experimental) { 423 | document.getElementById('note').innerHTML = 'Experimental feature'; 424 | } 425 | 426 | if (FEATURE.status.deprecated) { 427 | document.getElementById('note').innerHTML = 'Deprecated feature'; 428 | } 429 | } 430 | 431 | if (OPTIONS.accessibleColours) { 432 | document.body.classList.add("accessible-colours"); 433 | } 434 | 435 | if (OPTIONS.screenshot) { 436 | document.body.classList.add("screenshot"); 437 | 438 | var d = new Date(); 439 | var months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]; 440 | document.getElementById("footer-right").innerHTML = d.getDate() + ' ' + months[d.getMonth()] + ' ' + d.getFullYear(); 441 | document.querySelector(".icon-external-link").setAttribute("hidden", "true"); 442 | } else { 443 | document.getElementById("accessibleColoursToggle").addEventListener("click", function () { 444 | document.body.classList.toggle("accessible-colours") 445 | }); 446 | } 447 | 448 | switch (OPTIONS.dataSource) { 449 | case 'mdn': 450 | document.getElementById("footer-left").innerHTML = "Data from MDN | Embed from caniuse.bitsofco.de"; 451 | break; 452 | case 'caniuse': 453 | document.getElementById("footer-left").innerHTML = "Data from caniuse.com | Embed from caniuse.bitsofco.de"; 454 | break; 455 | } 456 | 457 | document.body.classList.add(OPTIONS.dataSource); 458 | } 459 | 460 | function displayTable(featureSupport) { 461 | 462 | // Create empty table cells for each browser and each period 463 | 464 | for (var i = OPTIONS.periods.length - 1; i > -1; i--) { 465 | 466 | var tableCells = ""; 467 | 468 | for (var j = 0; j < BROWSERS.length; j++) { 469 | tableCells += ''; 470 | } 471 | 472 | var row = document.createElement("tr"); 473 | row.className = 'statistics ' + OPTIONS.periods[i]; 474 | row.innerHTML = tableCells; 475 | 476 | document.getElementById('tableBody').appendChild(row); 477 | } 478 | 479 | 480 | // DISPLAY DATA 481 | // ************************* 482 | 483 | 484 | var hasPrefixed = false; 485 | var hasUnknown = false; 486 | var hasFlag = false; 487 | 488 | 489 | for (var i = 0; i < BROWSERS.length; i++) { 490 | 491 | var browser = BROWSERS[i]; 492 | 493 | 494 | // LOOP THROUGH PERIODS (BROWSER VERSIONS) 495 | for (var x = 0; x < OPTIONS.periods.length; x++) { 496 | 497 | var period = OPTIONS.periods[x]; 498 | var period_element; 499 | 500 | // LOOP THROUGH ROW CHILDREN TO FIND THE CURRENT TABLE CELL 501 | var row = document.getElementsByClassName(period)[0]; 502 | var rowChildren = row.childNodes; 503 | for (var r = 0; r < rowChildren.length; r++) { 504 | if (rowChildren[r].className.indexOf(browser) > -1) { 505 | period_element = rowChildren[r]; 506 | } 507 | } 508 | 509 | 510 | // ADD SUPPORT CLASS TO TABLE CELL 511 | featureSupport[browser][period] != undefined ? period_element.className += ' ' + featureSupport[browser][period] : false; 512 | 513 | // GET VERSION NUMBER + BROWSER USAGE 514 | var browserVersion = getShortenedBrowserVersion(BROWSER_DATA.versions[browser][period]); 515 | var versionString = '' + browserVersion + '' + BROWSER_DATA.usage[browser][period] + '%'; 516 | 517 | // ADD VERSION NUMBER TO TABLE CELL 518 | BROWSER_DATA.versions[browser][period] != undefined ? period_element.innerHTML = versionString : period_element.innerHTML = ''; 519 | 520 | // CHECK IF ANY HAS PREFIX OR UNKNOWN 521 | if (featureSupport[browser][period] != undefined && featureSupport[browser][period].indexOf(FEATURE_IDENTIFIERS.prefixed) > -1) { 522 | hasPrefixed = true; 523 | } 524 | if (featureSupport[browser][period] != undefined && featureSupport[browser][period].indexOf(FEATURE_IDENTIFIERS.unknown) > -1) { 525 | hasUnknown = true; 526 | } 527 | if (featureSupport[browser][period] != undefined && featureSupport[browser][period].indexOf(FEATURE_IDENTIFIERS.flagged) > -1) { 528 | hasFlag = true; 529 | } 530 | 531 | 532 | } // end loop through period 533 | 534 | } // end display data loop 535 | 536 | // DISPLAY PREFIX LEGEND IF DATA HAS PREFIXED 537 | hasPrefixed ? document.getElementById('legendX').style.display = "inline-block" : document.getElementById('legendX').style.display = "none"; 538 | hasUnknown ? document.getElementById('legendU').style.display = "inline-block" : document.getElementById('legendU').style.display = "none"; 539 | hasFlag ? document.getElementById('legendD').style.display = "inline-block" : document.getElementById('legendD').style.display = "none"; 540 | } 541 | 542 | function postDocumentHeight() { 543 | // PASS HEIGHT TO PARENT DOCUMENT 544 | var documentHeight = document.getElementsByClassName('feature')[0].scrollHeight; 545 | var infoString = 'ciu_embed:' + OPTIONS.featureID + ':' + documentHeight; 546 | parent.postMessage(infoString, "*"); 547 | 548 | window.onresize = function (event) { 549 | documentHeight = document.getElementsByClassName('feature')[0].scrollHeight; 550 | var infoString = 'ciu_embed:' + OPTIONS.featureID + ':' + documentHeight; 551 | parent.postMessage(infoString, "*"); 552 | } 553 | } 554 | 555 | 556 | 557 | /* ******************************* 558 | * 559 | * Start 560 | * 561 | * ******************************* */ 562 | 563 | (function () { 564 | 565 | setGlobalOptions(); 566 | displayLoadingMessage(); 567 | 568 | getFeature() 569 | .then(function () { 570 | return parseSupportData(); 571 | }) 572 | .then(function (featureSupport) { 573 | 574 | console.log(FEATURE); 575 | console.log(featureSupport); 576 | 577 | displayFeatureInformation(); 578 | displayTable(featureSupport); 579 | 580 | document.getElementById('defaultMessage').style.display = "none"; 581 | document.getElementsByClassName('feature')[0].style.display = "block"; 582 | 583 | postDocumentHeight(); 584 | }) 585 | .catch(function (err) { 586 | document.getElementById('defaultMessage').innerHTML = 'Feature not found...'; 587 | console.error(err); 588 | }); 589 | 590 | })(); 591 | --------------------------------------------------------------------------------