The action's title is visible when mousing over the extension's action button.
+
+
+
+
+ Default appearance
+
+
+
+ Title appears on hover
+
+
+
+
+
diff --git a/api/action/demo/index.js b/api/action/demo/index.js
new file mode 100644
index 00000000..ba85a253
--- /dev/null
+++ b/api/action/demo/index.js
@@ -0,0 +1,240 @@
+// Copyright 2021 Google LLC
+//
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file or at
+// https://developers.google.com/open-source/licenses/bsd
+
+/**
+ * @param {number} timeout
+ * @param {(event: Event) => void} callback
+ * @return {(event: Event) => void}
+ */
+function debounce(timeout, callback) {
+ let timeoutID = 0;
+ return (event) => {
+ clearTimeout(timeoutID);
+ timeoutID = setTimeout(() => callback(event), timeout);
+ };
+}
+
+// ------------------
+// .enable / .disable
+// ------------------
+
+// The action API does not expose a way to read the action's current enabled/disabled state, so we
+// have to track it ourselves.
+// Relevant feature request: https://bugs.chromium.org/p/chromium/issues/detail?id=1189295
+let actionEnabled = true;
+let showToggleState = document.getElementById('show-toggle-state');
+document.getElementById('toggle-state-button').addEventListener('click', (_event) => {
+ if (actionEnabled) {
+ chrome.action.disable();
+ } else {
+ chrome.action.enable();
+ }
+ actionEnabled = !actionEnabled;
+});
+
+document.getElementById('popup-options').addEventListener('change', async (event) => {
+ let popup = event.target.value;
+ await chrome.action.setPopup({ popup });
+
+ // Show the updated popup path
+ await getCurrentPopup();
+});
+
+async function getCurrentPopup() {
+ let popup = await chrome.action.getPopup({});
+ document.getElementById('current-popup-value').value = popup;
+ return popup;
+};
+
+async function showCurrentPage() {
+ let popup = await getCurrentPopup();
+ let pathname = '';
+ if (popup) {
+ pathname = new URL(popup).pathname;
+ }
+
+ let options = document.getElementById('popup-options');
+ let option = options.querySelector(`option[value="${pathname}"]`);
+ option.selected = true;
+}
+
+// Populate popup inputs on on page load
+showCurrentPage();
+
+// ----------
+// .onClicked
+// ----------
+
+// If a popup is specified, our on click handler won't be called. We declare it here rather than in
+// the `onclicked-button` handler to prevent the user from accidentally registering multiple
+// onClicked listeners.
+chrome.action.onClicked.addListener((tab) => {
+ chrome.tabs.create({ url: 'https://html5zombo.com/' });
+});
+
+document.getElementById('onclicked-button').addEventListener('click', async () => {
+ // Our listener will only receive the action's click event after clear out the popup URL
+ await chrome.action.setPopup({ popup: '' });
+ await showCurrentPage();
+});
+
+document.getElementById('onclicked-reset-button').addEventListener('click', async () => {
+ await chrome.action.setPopup({ popup: 'popups/popup.html' });
+ await showCurrentPage();
+});
+
+// ----------
+// badge text
+// ----------
+
+async function showBadgeText() {
+ let text = await chrome.action.getBadgeText({});
+ document.getElementById('current-badge-text').value = text;
+}
+
+// Populate badge text inputs on on page load
+showBadgeText();
+
+document.getElementById('badge-text-input').addEventListener('input', async (event) => {
+ let text = event.target.value;
+ await chrome.action.setBadgeText({ text });
+
+ showBadgeText();
+});
+
+document.getElementById('clear-badge-button').addEventListener('click', async () => {
+ await chrome.action.setBadgeText({ text: '' });
+
+ showBadgeText();
+});
+
+// ----------------------
+// badge background color
+// ----------------------
+
+async function showBadgeColor() {
+ let color = await chrome.action.getBadgeBackgroundColor({});
+ document.getElementById('current-badge-bg-color').value = JSON.stringify(color, null, 0);
+}
+
+// Populate badge background color inputs on on page load
+showBadgeColor();
+
+document.getElementById('set-badge-background-color-button').addEventListener('click', async () => {
+ // To show off this method, we must first make sure the badge has text
+ let currentText = await chrome.action.getBadgeText({});
+ if (!currentText) {
+ chrome.action.setBadgeText({ text: 'hi :)' });
+ showBadgeText();
+ }
+
+ // Next, generate a random RGBA color
+ let color = [0, 0, 0].map(() => Math.floor(Math.random * 255));
+
+ // Use the default background color ~10% of the time.
+ //
+ // NOTE: Alpha color cannot be set due to crbug.com/1184905. At the time of writing (Chrome 89),
+ // an alpha value of 0 sets the default color while a value of 1-255 will make the RGB color
+ // fully opaque.
+ if (Math.random() < 0.1) {
+ color.push(0);
+ } else {
+ color.push(255);
+ }
+
+ chrome.action.setBadgeBackgroundColor({ color });
+ showBadgeColor();
+});
+
+document.getElementById('reset-badge-background-color-button').addEventListener('click', async () => {
+ chrome.action.setBadgeBackgroundColor({ color: [0, 0, 0, 0] });
+ showBadgeColor();
+});
+
+// -----------
+// action icon
+// -----------
+
+const EMOJI = [
+ 'confetti',
+ 'suit',
+ 'bow',
+ 'dog',
+ 'skull',
+ 'yoyo',
+ 'cat',
+];
+
+let lastIconIndex = 0;
+document.getElementById('set-icon-button').addEventListener('click', async () => {
+ // Clear out the badge text in order to make the icon change easier to see
+ chrome.action.setBadgeText({ text: '' });
+
+ // Randomly pick a new icon
+ let index = lastIconIndex;
+ index = Math.floor(Math.random() * (EMOJI.length));
+ if (index === lastIconIndex) {
+ // Dupe detected! Increment the index & modulo to make sure we don't go out of bounds
+ index = (index + 1) % EMOJI.length;
+ }
+ let emojiFile = `images/emoji-${EMOJI[index]}.png`;
+ lastIconIndex = index;
+
+ // There are easier ways for a page to extract an image's imageData, but the OffscreenCanvas
+ // approach used here works in both extension pages and service workers.
+ let response = await fetch(emojiFile);
+ let blob = await response.blob();
+ let imageBitmap = await createImageBitmap(blob);
+ let osc = new OffscreenCanvas(imageBitmap.width, imageBitmap.height);
+ let ctx = osc.getContext('2d');
+ ctx.drawImage(imageBitmap, 0, 0);
+ let imageData = ctx.getImageData(0, 0, osc.width, osc.height);
+
+ chrome.action.setIcon({ imageData });
+});
+
+document.getElementById('reset-icon-button').addEventListener('click', () => {
+ let manifest = chrome.runtime.getManifest();
+ chrome.action.setIcon({ path: manifest.action.default_icon });
+});
+
+// -------------
+// get/set title
+// -------------
+
+let titleInput = document.getElementById('title-input');
+let titleInputDebounce = Number.parseInt(titleInput.dataset.debounce || 100);
+titleInput.addEventListener('input', debounce(200, async (event) => {
+ let title = event.target.value;
+ chrome.action.setTitle({ title });
+
+ showActionTitle();
+}));
+
+document.getElementById('reset-title-button').addEventListener('click', async (event) => {
+ let manifest = chrome.runtime.getManifest();
+ let title = manifest.action.default_title;
+
+ chrome.action.setTitle({ title });
+
+ showActionTitle();
+});
+
+async function showActionTitle() {
+ let title = await chrome.action.getTitle({});
+
+ // If empty, the title falls back to the name of the extension
+ if (title === '') {
+ // … which we can get from the extension's manifest
+ let manifest = chrome.runtime.getManifest();
+ title = manifest.name;
+ }
+
+ document.getElementById('current-title').value = title;
+}
+
+// Populate action title inputs on on page load
+showActionTitle();
diff --git a/api/action/icons/128.png b/api/action/icons/128.png
new file mode 100644
index 00000000..c3f6975e
Binary files /dev/null and b/api/action/icons/128.png differ
diff --git a/api/action/icons/32.png b/api/action/icons/32.png
new file mode 100644
index 00000000..24e728cd
Binary files /dev/null and b/api/action/icons/32.png differ
diff --git a/api/action/icons/512.png b/api/action/icons/512.png
new file mode 100644
index 00000000..ea0dd17a
Binary files /dev/null and b/api/action/icons/512.png differ
diff --git a/api/action/icons/72.png b/api/action/icons/72.png
new file mode 100644
index 00000000..1cbac06e
Binary files /dev/null and b/api/action/icons/72.png differ
diff --git a/api/action/images/action-disabled.png b/api/action/images/action-disabled.png
new file mode 100644
index 00000000..ae22acfa
Binary files /dev/null and b/api/action/images/action-disabled.png differ
diff --git a/api/action/images/action-enabled.png b/api/action/images/action-enabled.png
new file mode 100644
index 00000000..2278ed5a
Binary files /dev/null and b/api/action/images/action-enabled.png differ
diff --git a/api/action/images/emoji-bow.png b/api/action/images/emoji-bow.png
new file mode 100644
index 00000000..c02d09ed
Binary files /dev/null and b/api/action/images/emoji-bow.png differ
diff --git a/api/action/images/emoji-cat.png b/api/action/images/emoji-cat.png
new file mode 100644
index 00000000..d113ee3d
Binary files /dev/null and b/api/action/images/emoji-cat.png differ
diff --git a/api/action/images/emoji-confetti.png b/api/action/images/emoji-confetti.png
new file mode 100644
index 00000000..24e728cd
Binary files /dev/null and b/api/action/images/emoji-confetti.png differ
diff --git a/api/action/images/emoji-dog.png b/api/action/images/emoji-dog.png
new file mode 100644
index 00000000..f636d1a9
Binary files /dev/null and b/api/action/images/emoji-dog.png differ
diff --git a/api/action/images/emoji-skull.png b/api/action/images/emoji-skull.png
new file mode 100644
index 00000000..2c6e6743
Binary files /dev/null and b/api/action/images/emoji-skull.png differ
diff --git a/api/action/images/emoji-suit.png b/api/action/images/emoji-suit.png
new file mode 100644
index 00000000..5e7f36b7
Binary files /dev/null and b/api/action/images/emoji-suit.png differ
diff --git a/api/action/images/emoji-yoyo.png b/api/action/images/emoji-yoyo.png
new file mode 100644
index 00000000..dfdf8914
Binary files /dev/null and b/api/action/images/emoji-yoyo.png differ
diff --git a/api/action/images/pin-action.png b/api/action/images/pin-action.png
new file mode 100644
index 00000000..86aeba42
Binary files /dev/null and b/api/action/images/pin-action.png differ
diff --git a/api/action/images/title-hover.png b/api/action/images/title-hover.png
new file mode 100644
index 00000000..d5c1cf60
Binary files /dev/null and b/api/action/images/title-hover.png differ
diff --git a/api/action/images/title-no-hover.png b/api/action/images/title-no-hover.png
new file mode 100644
index 00000000..4ca286fc
Binary files /dev/null and b/api/action/images/title-no-hover.png differ
diff --git a/api/action/manifest.json b/api/action/manifest.json
new file mode 100644
index 00000000..3eac1304
--- /dev/null
+++ b/api/action/manifest.json
@@ -0,0 +1,24 @@
+{
+ "name": "Action API Demo",
+ "version": "1.0",
+ "manifest_version": 3,
+ "background": {
+ "service_worker": "background.js"
+ },
+ "action": {
+ "default_title": "Default Title",
+ "default_popup": "popups/popup.html",
+ "default_icon": {
+ "32": "icons/32.png",
+ "72": "icons/72.png",
+ "128": "icons/128.png",
+ "512": "icons/512.png"
+ }
+ },
+ "icons": {
+ "32": "icons/32.png",
+ "72": "icons/72.png",
+ "128": "icons/128.png",
+ "512": "icons/512.png"
+ }
+}
diff --git a/api/action/popups/a.html b/api/action/popups/a.html
new file mode 100644
index 00000000..cbd03b75
--- /dev/null
+++ b/api/action/popups/a.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
Document
+
+
+
+
Action API Demo
+
+ A
+
+
+
diff --git a/api/action/popups/b.html b/api/action/popups/b.html
new file mode 100644
index 00000000..eda5b65f
--- /dev/null
+++ b/api/action/popups/b.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
Document
+
+
+
+
Action API Demo
+
+ B
+
+
+
diff --git a/api/action/popups/popup.html b/api/action/popups/popup.html
new file mode 100644
index 00000000..79727541
--- /dev/null
+++ b/api/action/popups/popup.html
@@ -0,0 +1,32 @@
+
+
+
+
+
+
+
Document
+
+
+
+
Action API Demo
+
+ Hello, world!
+
+
+
diff --git a/api/action/third-party/awsm/awsm.css b/api/action/third-party/awsm/awsm.css
new file mode 100644
index 00000000..45a1ee54
--- /dev/null
+++ b/api/action/third-party/awsm/awsm.css
@@ -0,0 +1,7 @@
+@charset "UTF-8";
+/*!
+ * awsm.css v3.0.7 (https://igoradamenko.github.io/awsm.css/)
+ * Copyright 2015 Igor Adamenko
(https://igoradamenko.com)
+ * Licensed under MIT (https://github.com/igoradamenko/awsm.css/blob/master/LICENSE.md)
+ */
+html{font-family:system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"PT Sans","Open Sans","Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:100%;line-height:1.4;background:#fff;color:#000;-webkit-overflow-scrolling:touch}body{margin:1.2em;font-size:1rem}@media (min-width:20rem){body{font-size:calc(1rem + .00625*(100vw - 20rem))}}@media (min-width:40rem){body{font-size:1.125rem}}body article,body footer,body header,body main{position:relative;max-width:40rem;margin:0 auto}body>header{margin-bottom:3.5em}body>header h1{margin:0;font-size:1.5em}body>header p{margin:0;font-size:.85em}body>footer{margin-top:6em;padding-bottom:1.5em;text-align:center;font-size:.8rem;color:#aaa}details,nav{margin:1em 0}nav ul{list-style:none;margin:0;padding:0}nav li{display:inline-block;margin-right:1em;margin-bottom:.25em}nav li:last-child{margin-right:0}a,nav a:visited{color:#0064c1}article header h1 a:visited:hover,article header h2 a:visited:hover,nav a:hover{color:#f00000}ol,ul{margin-top:0;padding-top:0;padding-left:2.5em}article header h1+p,article header h2+p,ol li+li,ul li+li{margin-top:.25em}ol li>details,ul li>details{margin:0}p{margin:1em 0;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}aside:first-child,form legend:first-child+label,p:first-child{margin-top:0}aside:last-child,p:last-child{margin-bottom:0}p+ol,p+ul{margin-top:-.75em}p img,p picture{float:right;margin-bottom:.5em;margin-left:.5em}p picture img{float:none;margin:0}blockquote,dd{padding-left:2.5em}dd{margin-bottom:1em;margin-left:0}dt{font-weight:700}blockquote{margin:0}aside{margin:.5em 0;font-style:italic;color:#aaa}@media (min-width:65rem){aside{position:absolute;right:-12.5rem;width:9.375rem;max-width:9.375rem;margin:0;padding-left:.5em;font-size:.8em;border-left:1px solid #f2f2f2}}section+section{margin-top:2em}h1,h2,h3,h4,h5,h6{margin:1.25em 0 0;line-height:1.2}h1:focus>a[href^="#"][id]:empty,h1:hover>a[href^="#"][id]:empty,h2:focus>a[href^="#"][id]:empty,h2:hover>a[href^="#"][id]:empty,h3:focus>a[href^="#"][id]:empty,h3:hover>a[href^="#"][id]:empty,h4:focus>a[href^="#"][id]:empty,h4:hover>a[href^="#"][id]:empty,h5:focus>a[href^="#"][id]:empty,h5:hover>a[href^="#"][id]:empty,h6:focus>a[href^="#"][id]:empty,h6:hover>a[href^="#"][id]:empty{opacity:1}figure+p,h1+details,h1+p,h2+details,h2+p,h3+details,h3+p,h4+details,h4+p,h5+details,h5+p,h6+details,h6+p{margin-top:.5em}h1>a[href^="#"][id]:empty,h2>a[href^="#"][id]:empty,h3>a[href^="#"][id]:empty,h4>a[href^="#"][id]:empty,h5>a[href^="#"][id]:empty,h6>a[href^="#"][id]:empty{position:absolute;left:-.65em;opacity:0;text-decoration:none;font-weight:400;line-height:1;color:#aaa}@media (min-width:40rem){h1>a[href^="#"][id]:empty,h2>a[href^="#"][id]:empty,h3>a[href^="#"][id]:empty,h4>a[href^="#"][id]:empty,h5>a[href^="#"][id]:empty,h6>a[href^="#"][id]:empty{left:-.8em}}h1>a[href^="#"][id]:empty:focus,h1>a[href^="#"][id]:empty:hover,h1>a[href^="#"][id]:empty:target,h2>a[href^="#"][id]:empty:focus,h2>a[href^="#"][id]:empty:hover,h2>a[href^="#"][id]:empty:target,h3>a[href^="#"][id]:empty:focus,h3>a[href^="#"][id]:empty:hover,h3>a[href^="#"][id]:empty:target,h4>a[href^="#"][id]:empty:focus,h4>a[href^="#"][id]:empty:hover,h4>a[href^="#"][id]:empty:target,h5>a[href^="#"][id]:empty:focus,h5>a[href^="#"][id]:empty:hover,h5>a[href^="#"][id]:empty:target,h6>a[href^="#"][id]:empty:focus,h6>a[href^="#"][id]:empty:hover,h6>a[href^="#"][id]:empty:target{opacity:1;box-shadow:none;color:#000}h1>a[href^="#"][id]:empty:target:focus,h2>a[href^="#"][id]:empty:target:focus,h3>a[href^="#"][id]:empty:target:focus,h4>a[href^="#"][id]:empty:target:focus,h5>a[href^="#"][id]:empty:target:focus,h6>a[href^="#"][id]:empty:target:focus{outline:0}h1>a[href^="#"][id]:empty::before,h2>a[href^="#"][id]:empty::before,h3>a[href^="#"][id]:empty::before,h4>a[href^="#"][id]:empty::before,h5>a[href^="#"][id]:empty::before,h6>a[href^="#"][id]:empty::before{content:"§ "}h1{font-size:2.5em}h2{font-size:1.75em}h3{font-size:1.25em}h4{font-size:1.15em}a abbr,h5,h6{font-size:1em}h6{margin-top:1em}article+article{margin-top:4em}article header p{font-size:.6em;color:#aaa}article header p+h1,article header p+h2{margin-top:-.25em}article header h1 a,article header h2 a{color:#000}article header h1 a:visited,article header h2 a:visited,h6,legend{color:#aaa}article>footer{margin-top:1.5em;font-size:.85em}a:visited{color:#8d39d0}a:active,a:hover{outline-width:0}a:hover{color:#f00000}abbr{margin-right:-.075em;text-decoration:none;-webkit-hyphens:none;-ms-hyphens:none;hyphens:none;letter-spacing:.075em;font-size:.9em}img,picture{display:block;max-width:100%;margin:0 auto}audio,video{width:100%;max-width:100%}figure{margin:1em 0 .5em;padding:0}figure figcaption{opacity:.65;font-size:.85em}table{display:inline-block;border-spacing:0;border-collapse:collapse;overflow-x:auto;max-width:100%;text-align:left;vertical-align:top;background:linear-gradient(rgba(0,0,0,.15) 0%,rgba(0,0,0,.15) 100%) 0 0,linear-gradient(rgba(0,0,0,.15) 0%,rgba(0,0,0,.15) 100%) 100% 0;background-attachment:scroll,scroll;background-size:1px 100%,1px 100%;background-repeat:no-repeat,no-repeat}table caption{font-size:.9em;background:#fff}table td,table th{padding:.35em .75em;vertical-align:top;font-size:.9em;border:1px solid #f2f2f2;border-top:0;border-left:0}table td:first-child,table th:first-child{padding-left:0;background-image:linear-gradient(to right,#fff 50%,rgba(255,255,255,0) 100%);background-size:2px 100%;background-repeat:no-repeat}table td:last-child,table th:last-child{padding-right:0;border-right:0;background-image:linear-gradient(to left,#fff 50%,rgba(255,255,255,0) 100%);background-position:100% 0;background-size:2px 100%;background-repeat:no-repeat}table td:only-child,table th:only-child{background-image:linear-gradient(to right,#fff 50%,rgba(255,255,255,0) 100%),linear-gradient(to left,#fff 50%,rgba(255,255,255,0) 100%);background-position:0 0,100% 0;background-size:2px 100%,2px 100%;background-repeat:no-repeat,no-repeat}table th{line-height:1.2}form{margin-right:auto;margin-left:auto}@media (min-width:40rem){form{max-width:80%}}form label,form select,output{display:block}form label:not(:first-child){margin-top:1em}form p label{display:inline}form p label+label{margin-left:1em}form input[type],form select,form textarea{margin-bottom:1em}form input[type=checkbox],form input[type=radio]{margin-bottom:0}button,fieldset{margin:0;border:1px solid #aaa}fieldset{padding:.5em 1em}button{outline:0;box-sizing:border-box;height:2em;padding:calc(.25em - 1px) .5em;font-family:inherit;font-size:1em;border-radius:2px;background:#fff;display:inline-block;width:auto;background:#f2f2f2;color:#000;cursor:pointer}button:focus,input[type=email]:focus,input[type=month]:focus,input[type=number]:focus,input[type=password]:focus,input[type=search]:focus,input[type=tel]:focus,input[type=text]:focus,input[type=time]:focus,input[type=url]:focus,input[type=week]:focus,input[type^=date]:focus,select:focus{border:1px solid #000}button:not([disabled]):hover,input[type=button]:not([disabled]):hover,input[type=file]:not([disabled]):hover,input[type=reset]:not([disabled]):hover,input[type=submit]:not([disabled]):hover,select:not([disabled]):hover{border:1px solid #000}button:active,select:active{background-color:#aaa}button[disabled],select[disabled]{color:#aaa;cursor:not-allowed}select{outline:0;box-sizing:border-box;height:2em;margin:0;padding:calc(.25em - 1px) .5em;font-family:inherit;font-size:1em;border:1px solid #aaa;border-radius:2px;background:#fff;display:inline-block;width:auto;background:#f2f2f2;color:#000;cursor:pointer;padding-right:1.2em;background-position:top 55% right .35em;background-size:.5em;background-repeat:no-repeat;-webkit-appearance:none;-moz-appearance:none;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 3 2'%3E%3Cpath fill='rgb(170, 170, 170)' fill-rule='nonzero' d='M1.5 2L3 0H0z'/%3E%3C/svg%3E")}select:not([disabled]):focus,select:not([disabled]):hover{background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 3 2'%3E%3Cpath fill='rgb(0, 0, 0)' fill-rule='nonzero' d='M1.5 2L3 0H0z'/%3E%3C/svg%3E")}input[type=email],input[type=month],input[type=number],input[type=password],input[type=search],input[type=tel],input[type=text],input[type=time],input[type=url],input[type=week],input[type^=date]{outline:0;box-sizing:border-box;height:2em;margin:0;padding:calc(.25em - 1px) .5em;font-family:inherit;font-size:1em;border:1px solid #aaa;border-radius:2px;background:#fff;color:#000;display:block;width:100%;line-height:calc(2em - 1px*2 - (.25em - 1px)*2);-webkit-appearance:none;-moz-appearance:none;appearance:none}input[type=email]::-moz-placeholder,input[type=month]::-moz-placeholder,input[type=number]::-moz-placeholder,input[type=password]::-moz-placeholder,input[type=search]::-moz-placeholder,input[type=tel]::-moz-placeholder,input[type=text]::-moz-placeholder,input[type=time]::-moz-placeholder,input[type=url]::-moz-placeholder,input[type=week]::-moz-placeholder,input[type^=date]::-moz-placeholder{color:#aaa}input[type=email]::-webkit-input-placeholder,input[type=month]::-webkit-input-placeholder,input[type=number]::-webkit-input-placeholder,input[type=password]::-webkit-input-placeholder,input[type=search]::-webkit-input-placeholder,input[type=tel]::-webkit-input-placeholder,input[type=text]::-webkit-input-placeholder,input[type=time]::-webkit-input-placeholder,input[type=url]::-webkit-input-placeholder,input[type=week]::-webkit-input-placeholder,input[type^=date]::-webkit-input-placeholder{color:#aaa}input[type=email]:-ms-input-placeholder,input[type=month]:-ms-input-placeholder,input[type=number]:-ms-input-placeholder,input[type=password]:-ms-input-placeholder,input[type=search]:-ms-input-placeholder,input[type=tel]:-ms-input-placeholder,input[type=text]:-ms-input-placeholder,input[type=time]:-ms-input-placeholder,input[type=url]:-ms-input-placeholder,input[type=week]:-ms-input-placeholder,input[type^=date]:-ms-input-placeholder{color:#aaa}input[type=button],input[type=reset],input[type=submit]{outline:0;box-sizing:border-box;height:2em;margin:0;padding:calc(.25em - 1px) .5em;font-family:inherit;font-size:1em;border:1px solid #aaa;border-radius:2px;background:#fff;display:inline-block;width:auto;background:#f2f2f2;color:#000;cursor:pointer;-webkit-appearance:none;-moz-appearance:none;appearance:none}input[type=button]:focus,input[type=reset]:focus,input[type=submit]:focus{border:1px solid #000}input[type=button]:active,input[type=reset]:active,input[type=submit]:active{background-color:#aaa}input[type=button][disabled],input[type=reset][disabled],input[type=submit][disabled]{color:#aaa;cursor:not-allowed}input[type=color]{outline:0;box-sizing:border-box;height:2em;margin:0;padding:calc(.25em - 1px) .5em;font-family:inherit;font-size:1em;border:1px solid #aaa;border-radius:2px;background:#fff;color:#000;display:block;line-height:calc(2em - 1px*2 - (.25em - 1px)*2);-webkit-appearance:none;-moz-appearance:none;appearance:none;width:6em}input[type=color]:focus{border:1px solid #000}input[type=color]::-moz-placeholder,textarea::-moz-placeholder{color:#aaa}input[type=color]::-webkit-input-placeholder,textarea::-webkit-input-placeholder{color:#aaa}input[type=color]:-ms-input-placeholder{color:#aaa}input[type=color]:hover{border:1px solid #000}input[type=file]{outline:0;box-sizing:border-box;margin:0;padding:calc(.25em - 1px) .5em;font-family:inherit;border:1px solid #aaa;border-radius:2px;background:#fff;background:#f2f2f2;color:#000;cursor:pointer;display:block;width:100%;height:auto;padding:.75em .5em;font-size:12px;line-height:1}input[type=file]:focus,textarea:focus{border:1px solid #000}input[type=file]:active{background-color:#aaa}input[type=file][disabled]{color:#aaa;cursor:not-allowed}input[type=checkbox],input[type=radio]{margin:-.2em .75em 0 0;vertical-align:middle}textarea{outline:0;box-sizing:border-box;margin:0;padding:calc(.25em - 1px) .5em;font-family:inherit;font-size:1em;border:1px solid #aaa;border-radius:2px;background:#fff;color:#000;display:block;width:100%;line-height:calc(2em - 1px*2 - (.25em - 1px)*2);-webkit-appearance:none;-moz-appearance:none;appearance:none;height:4.5em;resize:vertical;padding-top:.5em;padding-bottom:.5em}textarea:-ms-input-placeholder{color:#aaa}code,kbd,samp,var{font-family:Consolas,"Lucida Console",Monaco,monospace;font-style:normal}pre{overflow-x:auto;font-size:.8em;background:linear-gradient(rgba(0,0,0,.15) 0%,rgba(0,0,0,.15) 100%) 0 0,linear-gradient(rgba(0,0,0,.15) 0%,rgba(0,0,0,.15) 100%) 100% 0;background-attachment:scroll,scroll;background-size:1px 100%,1px 100%;background-repeat:no-repeat,no-repeat}pre>code,summary{display:inline-block}pre>code{overflow-x:visible;box-sizing:border-box;min-width:100%;border-right:3px solid #fff;border-left:1px solid #fff}hr{height:1px;margin:2em 0;border:0;background:#f2f2f2}details[open]{padding-bottom:.5em;border-bottom:1px solid #f2f2f2}summary{font-weight:700;border-bottom:1px dashed;cursor:pointer}noscript{color:#d00000}::selection{background:rgba(0,100,193,.25)}