Lorem ipsum dolor…
18 |your code here...
46 | 47 |your code here...
58 | 59 |\${super.template}
76 | \`; 77 | } 78 | } 79 | 80 |your code here...
106 | 107 |Hello world!
138 | `; 139 | } 140 | } 141 | 142 |` element | {} | 238 | | --code-sample-font-family | font-family applied to `` and `` elements | Operator Mono, Inconsolata, Roboto Mono, monaco, consolas, monospace | 239 | | --code-sample-font-size | font-size applied to `
` and `` elements | 14px | 240 | | --code-sample-line-height | line-height applied to `.hljs` | 1.3 | 241 | | --code-sample-hljs | empty mixin applied to `.hljs` | {} | 242 | | --code-sample-demo-padding | padding applied to the container of the rendered code | 0 0 20px | 243 | | --code-sample-demo-not-empty | empty mixin applied to the demo container when is not empty | {} | 244 | | --code-sample-demo | empty mixin applied to the container of the rendered code | {} | 245 | | --code-sample-code-container | empty mixin applied to code container | {} | 246 | | --code-sample-code-container-hover | empty mixin applied to code container on :hover | {} | 247 | | --code-sample-code-container-hover-button | empty mixin applied to the copy to clipboard button when the code container on :hover | {} | 248 | | --code-sample-copy-button-bg-color | background-color of the copy to clipboard button | #e0e0e0 | 249 | | --code-sample-copy-clipboard-button | empty mixin applied to the copy to clipboard button | {} | 250 | 251 | Included themes contain custom CSS properties to set the background and text color. 252 | You may need to add these CSS properties to your own themes. 253 | 254 | | Custom property | Description | Default | 255 | |:-------------------------------|:----------------------------------------|:------------| 256 | | --code-sample-background | code background color | Depends on the theme | 257 | | --code-sample-color | code text color | Depends on the theme | 258 | 259 | 260 | 261 | -------------------------------------------------------------------------------- /buildconfig.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | server: { 3 | port: 5000, 4 | open: false, 5 | notify: false, 6 | ghostMode: false, 7 | reloadOnRestart: true, 8 | proxy: 'localhost:{{port}}/components/{{component}}/', 9 | }, 10 | watch: { 11 | dist: [ 12 | 'themes/**/*', 13 | ], 14 | }, 15 | pixtorem: { 16 | exclude: [ 17 | 'border', 18 | 'box-shadow', 19 | 'border-radius', 20 | ], 21 | }, 22 | autoprefixer: { 23 | flexbox: 'no-2009', 24 | }, 25 | inlineSource: { 26 | compress: false, 27 | swallowErrors: true, 28 | pretty: true, 29 | }, 30 | }; 31 | -------------------------------------------------------------------------------- /code-sample.js: -------------------------------------------------------------------------------- 1 | import {PolymerElement, html} from '@polymer/polymer/polymer-element.js'; 2 | import {FlattenedNodesObserver} from '@polymer/polymer/lib/utils/flattened-nodes-observer.js'; 3 | import {oneDark} from './themes/one-dark.js'; 4 | import './vendor/highlight/highlight.pack.js'; 5 | 6 | /** 7 | * `
` uses [highlight.js](https://highlightjs.org/) for syntax highlighting. 8 | * @polymer 9 | * @customElement 10 | * @extends {PolymerElement} 11 | * @demo https://kcmr.github.io/code-sample/ 12 | */ 13 | class CodeSample extends PolymerElement { 14 | static get template() { 15 | return html` 16 | ${this.constructor.theme || oneDark} 17 | 77 | 78 | 79 | 80 | 81 | 82 | 88 | 89 |90 | `; 91 | } 92 | 93 | static get properties() { 94 | return { 95 | // Set to true to show a copy to clipboard button. 96 | copyClipboardButton: { 97 | type: Boolean, 98 | value: false, 99 | }, 100 | // Tagged template literal with custom styles. 101 | // Only supported in Shadow DOM. 102 | theme: { 103 | type: String, 104 | observer: '_themeChanged', 105 | }, 106 | // Set to true to render the code inside the template. 107 | render: { 108 | type: Boolean, 109 | value: false, 110 | }, 111 | // Code type (optional). (eg.: html, js, css) 112 | // Options are the same as the available classes for `` tag using highlight.js 113 | type: { 114 | type: String, 115 | }, 116 | }; 117 | } 118 | 119 | _themeChanged(theme) { 120 | if (theme && this._themeCanBeChanged()) { 121 | const previousTheme = this.shadowRoot.querySelector('style:not(#baseStyle)'); 122 | this.shadowRoot.replaceChild( 123 | document.importNode(theme.content, true), 124 | previousTheme 125 | ); 126 | } 127 | } 128 | 129 | _themeCanBeChanged() { 130 | if (window.ShadyCSS) { 131 | console.error('
:', 'Theme changing is not supported in Shady DOM.'); 132 | return; 133 | } 134 | 135 | if (this.theme.tagName !== 'TEMPLATE') { 136 | console.error(' :', 'theme must be a template'); 137 | return; 138 | } 139 | 140 | return true; 141 | } 142 | 143 | connectedCallback() { 144 | super.connectedCallback(); 145 | setTimeout(() => { 146 | if (this.querySelector('template')) { 147 | this._observer = new FlattenedNodesObserver(this.$.content, () => this._updateContent()); 148 | } else if (this.childNodes.length) { 149 | console.error(' :', 'content must be provided inside a tag'); 150 | } 151 | }); 152 | } 153 | 154 | disconnectedCallback() { 155 | if (this._observer) { 156 | this._observer.disconnect(); 157 | this._observer = null; 158 | } 159 | } 160 | 161 | _updateContent() { 162 | if (this._code) this._code.parentNode.removeChild(this._code); 163 | if (this._demo) this.$.demo.innerHTML = ''; 164 | 165 | const template = this._getCodeTemplate(); 166 | 167 | if (this.render) { 168 | this._demo = this.$.demo.appendChild( 169 | document.importNode(template.content, true) 170 | ); 171 | } 172 | 173 | this._highlight(template.innerHTML); 174 | } 175 | 176 | _getCodeTemplate() { 177 | const nodes = FlattenedNodesObserver.getFlattenedNodes(this.$.content); 178 | return [].filter.call(nodes, (node) => node.nodeType === Node.ELEMENT_NODE)[0]; 179 | } 180 | 181 | _highlight(str) { 182 | this._code = document.createElement('code'); 183 | if (this.type) this._code.classList.add(this.type); 184 | this._code.innerHTML = this._entitize(this._cleanIndentation(str)); 185 | this.$.code.appendChild(this._code); 186 | hljs.highlightBlock(this._code); 187 | } 188 | 189 | _cleanIndentation(str) { 190 | const pattern = str.match(/\s*\n[\t\s]*/); 191 | return str.replace(new RegExp(pattern, 'g'), '\n'); 192 | } 193 | 194 | _entitize(str) { 195 | return String(str) 196 | .replace(/</g, '<') 197 | .replace(/>/g, '>') 198 | .replace(/=""/g, '') 199 | .replace(/=>/g, '=>') 200 | .replace(//g, '>') 202 | .replace(/"/g, '"'); 203 | } 204 | 205 | _copyToClipboard(event) { 206 | const copyButton = event.target; 207 | 208 | const textarea = this._textAreaWithClonedContent(); 209 | textarea.select(); 210 | 211 | try { 212 | document.execCommand('copy', false); 213 | copyButton.textContent = 'Done'; 214 | } catch (err) { 215 | console.error(err); 216 | copyButton.textContent = 'Error'; 217 | } 218 | 219 | textarea.remove(); 220 | 221 | setTimeout(() => { 222 | copyButton.textContent = 'Copy'; 223 | }, 1000); 224 | } 225 | 226 | _textAreaWithClonedContent() { 227 | const textarea = document.createElement('textarea'); 228 | document.body.appendChild(textarea); 229 | textarea.value = this._cleanIndentation(this._getCodeTemplate().innerHTML); 230 | 231 | return textarea; 232 | } 233 | } 234 | 235 | customElements.define('code-sample', CodeSample); 236 | -------------------------------------------------------------------------------- /demo/code-sample-theme.js: -------------------------------------------------------------------------------- 1 | const html = (string) => string; // only for highlighting purpuses (editor) 2 | const $documentContainer = document.createElement('div'); 3 | $documentContainer.setAttribute('style', 'display: none;'); 4 | 5 | $documentContainer.innerHTML = html` 6 | 7 | 8 | 104 | 105 | `; 106 | 107 | document.head.appendChild($documentContainer); 108 | 109 | -------------------------------------------------------------------------------- /demo/css/demo.css: -------------------------------------------------------------------------------- 1 | body { 2 | font: caption; 3 | font-size: 100%; 4 | background: #E6E8E8; 5 | -webkit-tap-highlight-color: transparent; 6 | } 7 | 8 | h1 { 9 | font-size: 18px; 10 | font-weight: 500; 11 | margin: 0; 12 | } 13 | 14 | p { font-weight: 300; } 15 | 16 | code { 17 | font-family: Roboto Mono, monospace; 18 | } 19 | 20 | code-sample { 21 | --code-sample-font-family: Roboto Mono, monospace; 22 | } 23 | 24 | .wrapper { 25 | max-width: 800px; 26 | margin: 40px auto 0; 27 | } 28 | 29 | .wrapper > .demo { 30 | margin-bottom: 40px; 31 | padding: 40px; 32 | background-color: #fff; 33 | } 34 | 35 | .demo-text { 36 | margin: 0 0 20px; 37 | padding: 0 0 10px; 38 | border-bottom: 1px solid #e0e0e0; 39 | display: flex; 40 | justify-content: space-between; 41 | align-items: center; 42 | } 43 | 44 | .demo-btn { 45 | font: inherit; 46 | background-color: #EAEDED; 47 | border: 0; 48 | box-shadow: 0 1px 2px rgba(0,0,0,0.25); 49 | height: 40px; 50 | padding: 0 20px; 51 | border-radius: 3px; 52 | } 53 | 54 | .demo-btn:active { 55 | background-color: #D7DBDD; 56 | } 57 | 58 | .title-button { 59 | display: flex; 60 | justify-content: space-between; 61 | align-items: flex-end; 62 | margin-bottom: 20px; 63 | } 64 | 65 | .title-button h1 { margin-bottom: 0; } 66 | 67 | .center { text-align: center; } 68 | 69 | .select { 70 | display: flex; 71 | align-items: center; 72 | margin-right: 8px; 73 | font-size: 14px; 74 | } 75 | 76 | .select span { 77 | margin-right: 8px; 78 | } 79 | 80 | .select select { 81 | font: inherit; 82 | } 83 | 84 | -------------------------------------------------------------------------------- /demo/demo.js: -------------------------------------------------------------------------------- 1 | import {oneDark} from '../themes/one-dark.js'; 2 | import {oneLight} from '../themes/one-light.js'; 3 | import {defaultTheme} from '../themes/default.js'; 4 | import {github} from '../themes/github.js'; 5 | import {solarizedLight} from '../themes/solarized-light.js'; 6 | import {solarizedDark} from '../themes/solarized-dark.js'; 7 | import {kustomLight} from '../themes/kustom-light.js'; 8 | import {kustomDark} from '../themes/kustom-dark.js'; 9 | 10 | const themes = { 11 | oneDark, 12 | oneLight, 13 | defaultTheme, 14 | github, 15 | solarizedLight, 16 | solarizedDark, 17 | kustomLight, 18 | kustomDark, 19 | }; 20 | 21 | const changeTheme = (e) => { 22 | const theme = e.target.value; 23 | const demo = document.querySelector(e.target.dataset.target); 24 | demo.theme = themes[theme]; 25 | }; 26 | 27 | const selects = document.querySelectorAll('select'); 28 | [].forEach.call(selects, (select) => { 29 | select.addEventListener('change', changeTheme); 30 | }); 31 | -------------------------------------------------------------------------------- /demo/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |code-sample demo 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 19 | 20 | 21 |22 |307 | 308 | 349 | 350 | 351 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const gulp = require('gulp'); 4 | const log = require('fancy-log'); 5 | const del = require('del'); 6 | const browserSync = require('browser-sync').create(); 7 | const portfinder = require('portfinder'); 8 | const {spawn} = require('child_process'); 9 | const inlineSource = require('gulp-inline-source'); 10 | const postcss = require('gulp-postcss'); 11 | const autoprefixer = require('autoprefixer'); 12 | const pxtorem = require('postcss-pixels-to-rem'); 13 | const eslint = require('gulp-eslint'); 14 | const config = require('./buildconfig'); 15 | const manifest = require('./package.json'); 16 | 17 | const COMPONENT_PATH = manifest.name; 18 | const COMPONENT_NAME = manifest.main; 19 | 20 | const DIST_DIRECTORY = '.'; 21 | const TMP_DIRECTORY = '.tmp/'; 22 | 23 | const WATCHED_DIST_FILES = [ 24 | COMPONENT_NAME, 25 | 'index.html', 26 | 'demo/**/*', 27 | 'test/**/*', 28 | ].concat(config.watch.dist || []); 29 | 30 | gulp.task('clean', () => del.sync([TMP_DIRECTORY])); 31 | 32 | const startServer = (port) => { 33 | const polymerCliParams = ['serve', '--npm', '-p', port]; 34 | const polymerServe = spawn('polymer', polymerCliParams); 35 | 36 | polymerServe.stdout.on('data', (data) => { 37 | log(`${data}`); 38 | browserSync.init(getServerConfig(port)); 39 | }); 40 | 41 | polymerServe.stderr.on('data', (data) => { 42 | log(`Error: ${data}`); 43 | }); 44 | 45 | polymerServe.on('close', (code) => { 46 | log(`child process exited with code ${code}`); 47 | }); 48 | }; 49 | 50 | const getServerConfig = (port) => { 51 | return JSON.parse( 52 | JSON.stringify(config.server) 53 | .replace(/{{component}}/g, COMPONENT_PATH) 54 | .replace(/{{port}}/g, port) 55 | ); 56 | }; 57 | 58 | gulp.task('styles', () => { 59 | return gulp.src(['src/*.css']) 60 | .pipe(postcss([ 61 | pxtorem(config.pxtorem), 62 | autoprefixer(config.autoprefixer), 63 | ])) 64 | .pipe(gulp.dest(TMP_DIRECTORY)); 65 | }); 66 | 67 | gulp.task('eslint', () => { 68 | return gulp.src(['src/*.js']) 69 | .pipe(eslint()) 70 | .pipe(eslint.format()) 71 | .pipe(gulp.dest(TMP_DIRECTORY)); 72 | }); 73 | 74 | gulp.task('build:dist', ['clean', 'styles', 'eslint'], () => { 75 | return gulp.src(['.tmp/**/*.js']) 76 | .pipe(inlineSource(config.inlineSource)) 77 | .pipe(gulp.dest(DIST_DIRECTORY)); 78 | }); 79 | 80 | gulp.task('start-server', () => { 81 | return portfinder.getPortPromise() 82 | .then(startServer) 83 | .catch((err) => log(err)); 84 | }); 85 | 86 | gulp.task('watch:sources', () => { 87 | gulp.watch(['src/*.{js, css}'], ['styles', 'eslint', 'build:dist']); 88 | }); 89 | 90 | gulp.task('watch:dist', () => { 91 | gulp.watch(WATCHED_DIST_FILES).on('change', browserSync.reload); 92 | }); 93 | 94 | gulp.task('serve', [ 95 | 'build:dist', 96 | 'start-server', 97 | 'watch:sources', 98 | 'watch:dist', 99 | ]); 100 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 |23 |56 | 57 |24 |39 | 40 |HTML and inline JavaScript
25 | 38 |41 |55 |42 | 43 | 54 |content 44 | 45 |46 |48 | 49 | 52 | 53 |Lorem ipsum dolor sit amet, consectetur adipisicing elit. Amet distinctio nam, possimus officia error delectus impedit libero corrupti, sunt, sapiente suscipit. Esse, quisquam tempore similique eveniet veritatis pariatur adipisci sit.
47 |58 |86 | 87 |59 |74 | 75 |JavaScript
60 | 73 |76 |85 |77 | 78 | const something = param => { 79 | // comment 80 | let a = `${param}-something`; 81 | } 82 | 83 | 84 |88 |126 | 127 |89 |104 | 105 |Tagged template literals
90 | 103 |106 |125 |Set the
107 | 108 |type
attribute to js, jsx or javascript when using tagged template literals.109 | 110 | class MyElement extends PolymerElement { 111 | static get template() { 112 | return html` 113 | 118 | 124 |Hello world!
119 | `; 120 | } 121 | } 122 | 123 |128 |160 | 161 |129 |144 | 145 |CSS
130 | 143 |146 |159 |147 | 148 | .my-style { display: block; } 149 | 150 | :host { 151 | display: flex; 152 | box-sizing: border-box; 153 | } 154 | 155 | :host([hidden]) { display: none; } 156 | 157 | 158 |162 |208 | 209 |163 |178 | 179 |Rendered code
164 | 177 |180 |207 |Use the boolean attribute
181 |render
to render the code inside the<template>
tag.182 | 183 | 202 | 203 | 204 | 205 | 206 |210 |238 | 239 |211 |226 | 227 |Copy to clipboard button
212 | 225 |228 |237 |Use the boolean attribute
229 |copy-clipboard-button
to display a "copy" button on the top right corner.230 | 231 | 236 |232 |234 | 235 |Lorem ipsum dolor…
233 |240 |267 | 268 |241 |256 |Change content dynamically
242 | 255 |257 |266 |258 | 259 |
260 |261 | 262 | 265 |Initial content.
263 | 264 |269 |306 |270 |285 | 286 |Custom background colors
271 | 284 |287 |305 |288 | 289 | 296 | 297 |290 | 294 | 295 |lorem...291 |ipsum...292 |dolor...293 |298 | 299 | function algo(param) { 300 | alert('helloooow'); 301 | } 302 | 303 | 304 |code-sample demo 7 | 8 | 9 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "Wrapper element for highlight.js", 3 | "keywords": [ 4 | "polymer", 5 | "web-component", 6 | "syntax highlighting", 7 | "highlight.js", 8 | "highlight", 9 | "code", 10 | "pre", 11 | "theme" 12 | ], 13 | "repository": { 14 | "type": "git", 15 | "url": "git://github.com/kcmr/code-sample.git" 16 | }, 17 | "homepage": "https://github.com/kcmr/code-sample/", 18 | "name": "@kuscamara/code-sample", 19 | "version": "3.0.2", 20 | "main": "code-sample.js", 21 | "author": "Kus Cámara", 22 | "license": "MIT", 23 | "dependencies": { 24 | "@polymer/polymer": "^3.0.0" 25 | }, 26 | "devDependencies": { 27 | "@webcomponents/webcomponentsjs": "^2.0.2", 28 | "autoprefixer": "^9.1.0", 29 | "browser-sync": "^2.24.4", 30 | "del": "^3.0.0", 31 | "eslint": "^5.3.0", 32 | "eslint-config-google": "^0.9.1", 33 | "fancy-log": "^1.3.2", 34 | "gulp": "^3.9.1", 35 | "gulp-eslint": "^5.0.0", 36 | "gulp-inline-source": "^3.2.0", 37 | "gulp-postcss": "^8.0.0", 38 | "portfinder": "^1.0.13", 39 | "postcss-pixels-to-rem": "^0.8.0", 40 | "wct-browser-legacy": "~1.0.0", 41 | "wct-istanbul": "~0.14.3", 42 | "web-component-tester": "~6.6.0" 43 | }, 44 | "scripts": { 45 | "start": "gulp serve", 46 | "test:sauce": "wct --module-resolution=node --npm", 47 | "test": "wct --module-resolution=node --npm --skip-plugin sauce", 48 | "lint:javascript": "eslint . --ext js --fix" 49 | }, 50 | "bugs": { 51 | "url": "https://github.com/kcmr/code-sample/issues" 52 | }, 53 | "directories": { 54 | "test": "test" 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/code-sample.css: -------------------------------------------------------------------------------- 1 | :host { 2 | display: block; 3 | } 4 | 5 | :host([hidden]), 6 | [hidden] { 7 | display: none; 8 | } 9 | 10 | pre { 11 | margin: 0; 12 | @apply --code-sample-pre; 13 | } 14 | 15 | pre, code { 16 | font-family: var(--code-sample-font-family, Operator Mono, Inconsolata, Roboto Mono, monaco, consolas, monospace); 17 | font-size: var(--code-sample-font-size, 14px); 18 | } 19 | 20 | .hljs { 21 | padding: 0 20px; 22 | line-height: var(--code-sample-line-height, 1.3); 23 | @apply --code-sample-hljs; 24 | } 25 | 26 | .demo:not(:empty) { 27 | padding: var(--code-sample-demo-padding, 0 0 20px); 28 | @apply --code-sample-demo-not-empty; 29 | } 30 | 31 | .demo { 32 | @apply --code-sample-demo; 33 | } 34 | 35 | #code-container { 36 | position: relative; 37 | @apply --code-sample-code-container; 38 | } 39 | 40 | #code-container:hover { 41 | @apply --code-sample-code-container-hover; 42 | } 43 | 44 | #code-container:hover > button { 45 | @apply --code-sample-code-container-hover-button; 46 | } 47 | 48 | button { 49 | background: var(--code-sample-copy-button-bg-color, #e0e0e0); 50 | border: none; 51 | cursor: pointer; 52 | display: block; 53 | position: absolute; 54 | right: 0; 55 | top: 0; 56 | text-transform: uppercase; 57 | @apply --code-sample-copy-clipboard-button; 58 | } -------------------------------------------------------------------------------- /src/code-sample.js: -------------------------------------------------------------------------------- 1 | import {PolymerElement, html} from '@polymer/polymer/polymer-element.js'; 2 | import {FlattenedNodesObserver} from '@polymer/polymer/lib/utils/flattened-nodes-observer.js'; 3 | import {oneDark} from './themes/one-dark.js'; 4 | import './vendor/highlight/highlight.pack.js'; 5 | 6 | /** 7 | * ` ` uses [highlight.js](https://highlightjs.org/) for syntax highlighting. 8 | * @polymer 9 | * @customElement 10 | * @extends {PolymerElement} 11 | * @demo https://kcmr.github.io/code-sample/ 12 | */ 13 | class CodeSample extends PolymerElement { 14 | static get template() { 15 | return html` 16 | ${this.constructor.theme || oneDark} 17 | 18 | 19 | 20 | 21 | 22 | 23 | 29 | 30 |31 | `; 32 | } 33 | 34 | static get properties() { 35 | return { 36 | // Set to true to show a copy to clipboard button. 37 | copyClipboardButton: { 38 | type: Boolean, 39 | value: false, 40 | }, 41 | // Tagged template literal with custom styles. 42 | // Only supported in Shadow DOM. 43 | theme: { 44 | type: String, 45 | observer: '_themeChanged', 46 | }, 47 | // Set to true to render the code inside the template. 48 | render: { 49 | type: Boolean, 50 | value: false, 51 | }, 52 | // Code type (optional). (eg.: html, js, css) 53 | // Options are the same as the available classes for `` tag using highlight.js 54 | type: { 55 | type: String, 56 | }, 57 | }; 58 | } 59 | 60 | _themeChanged(theme) { 61 | if (theme && this._themeCanBeChanged()) { 62 | const previousTheme = this.shadowRoot.querySelector('style:not(#baseStyle)'); 63 | this.shadowRoot.replaceChild( 64 | document.importNode(theme.content, true), 65 | previousTheme 66 | ); 67 | } 68 | } 69 | 70 | _themeCanBeChanged() { 71 | if (window.ShadyCSS) { 72 | console.error('
:', 'Theme changing is not supported in Shady DOM.'); 73 | return; 74 | } 75 | 76 | if (this.theme.tagName !== 'TEMPLATE') { 77 | console.error(' :', 'theme must be a template'); 78 | return; 79 | } 80 | 81 | return true; 82 | } 83 | 84 | connectedCallback() { 85 | super.connectedCallback(); 86 | setTimeout(() => { 87 | if (this.querySelector('template')) { 88 | this._observer = new FlattenedNodesObserver(this.$.content, () => this._updateContent()); 89 | } else if (this.childNodes.length) { 90 | console.error(' :', 'content must be provided inside a tag'); 91 | } 92 | }); 93 | } 94 | 95 | disconnectedCallback() { 96 | if (this._observer) { 97 | this._observer.disconnect(); 98 | this._observer = null; 99 | } 100 | } 101 | 102 | _updateContent() { 103 | if (this._code) this._code.parentNode.removeChild(this._code); 104 | if (this._demo) this.$.demo.innerHTML = ''; 105 | 106 | const template = this._getCodeTemplate(); 107 | 108 | if (this.render) { 109 | this._demo = this.$.demo.appendChild( 110 | document.importNode(template.content, true) 111 | ); 112 | } 113 | 114 | this._highlight(template.innerHTML); 115 | } 116 | 117 | _getCodeTemplate() { 118 | const nodes = FlattenedNodesObserver.getFlattenedNodes(this.$.content); 119 | return [].filter.call(nodes, (node) => node.nodeType === Node.ELEMENT_NODE)[0]; 120 | } 121 | 122 | _highlight(str) { 123 | this._code = document.createElement('code'); 124 | if (this.type) this._code.classList.add(this.type); 125 | this._code.innerHTML = this._entitize(this._cleanIndentation(str)); 126 | this.$.code.appendChild(this._code); 127 | hljs.highlightBlock(this._code); 128 | } 129 | 130 | _cleanIndentation(str) { 131 | const pattern = str.match(/\s*\n[\t\s]*/); 132 | return str.replace(new RegExp(pattern, 'g'), '\n'); 133 | } 134 | 135 | _entitize(str) { 136 | return String(str) 137 | .replace(/</g, '<') 138 | .replace(/>/g, '>') 139 | .replace(/=""/g, '') 140 | .replace(/=>/g, '=>') 141 | .replace(//g, '>') 143 | .replace(/"/g, '"'); 144 | } 145 | 146 | _copyToClipboard(event) { 147 | const copyButton = event.target; 148 | 149 | const textarea = this._textAreaWithClonedContent(); 150 | textarea.select(); 151 | 152 | try { 153 | document.execCommand('copy', false); 154 | copyButton.textContent = 'Done'; 155 | } catch (err) { 156 | console.error(err); 157 | copyButton.textContent = 'Error'; 158 | } 159 | 160 | textarea.remove(); 161 | 162 | setTimeout(() => { 163 | copyButton.textContent = 'Copy'; 164 | }, 1000); 165 | } 166 | 167 | _textAreaWithClonedContent() { 168 | const textarea = document.createElement('textarea'); 169 | document.body.appendChild(textarea); 170 | textarea.value = this._cleanIndentation(this._getCodeTemplate().innerHTML); 171 | 172 | return textarea; 173 | } 174 | } 175 | 176 | customElements.define('code-sample', CodeSample); 177 | -------------------------------------------------------------------------------- /test/code-sample_test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 20 | 21 |14 | 15 | 18 | 19 |Some content
16 | 17 |22 | 23 | 28 | 29 |24 | 26 | 27 |Some content
25 |30 | 31 | 34 | 35 |32 | 33 | 36 | 37 | 44 | 45 |38 | 39 | 42 | 43 |iuuu
40 | 41 |46 | 47 | 54 | 55 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /themes/default.js: -------------------------------------------------------------------------------- 1 | import {html} from '@polymer/polymer/polymer-element.js'; 2 | 3 | export const defaultTheme = html` 4 | `; 100 | -------------------------------------------------------------------------------- /themes/github.js: -------------------------------------------------------------------------------- 1 | import {html} from '@polymer/polymer/polymer-element.js'; 2 | 3 | export const github = html` 4 | `; 100 | -------------------------------------------------------------------------------- /themes/kustom-dark.js: -------------------------------------------------------------------------------- 1 | import {html} from '@polymer/polymer/polymer-element.js'; 2 | 3 | export const kustomDark = html` 4 | `; 81 | -------------------------------------------------------------------------------- /themes/kustom-light.js: -------------------------------------------------------------------------------- 1 | import {html} from '@polymer/polymer/polymer-element.js'; 2 | 3 | export const kustomLight = html` 4 | `; 87 | -------------------------------------------------------------------------------- /themes/one-dark.js: -------------------------------------------------------------------------------- 1 | import {html} from '@polymer/polymer/polymer-element.js'; 2 | 3 | export const oneDark = html` 4 | `; 106 | -------------------------------------------------------------------------------- /themes/one-light.js: -------------------------------------------------------------------------------- 1 | import {html} from '@polymer/polymer/polymer-element.js'; 2 | 3 | export const oneLight = html` 4 | `; 101 | -------------------------------------------------------------------------------- /themes/solarized-dark.js: -------------------------------------------------------------------------------- 1 | import {html} from '@polymer/polymer/polymer-element.js'; 2 | 3 | export const solarizedDark = html` 4 | `; 85 | -------------------------------------------------------------------------------- /themes/solarized-light.js: -------------------------------------------------------------------------------- 1 | import {html} from '@polymer/polymer/polymer-element.js'; 2 | 3 | export const solarizedLight = html` 4 | `; 85 | -------------------------------------------------------------------------------- /vendor/highlight/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2006, Ivan Sagalaev 2 | All rights reserved. 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of highlight.js nor the names of its contributors 12 | may be used to endorse or promote products derived from this software 13 | without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY 16 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /vendor/highlight/highlight.pack.js: -------------------------------------------------------------------------------- 1 | /*! highlight.js v9.12.0 | BSD3 License | git.io/hljslicense */ 2 | !function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"!=typeof exports?e(exports):n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs}))}(function(e){function n(e){return e.replace(/&/g,"&").replace(//g,">")}function t(e){return e.nodeName.toLowerCase()}function r(e,n){var t=e&&e.exec(n);return t&&0===t.index}function a(e){return k.test(e)}function i(e){var n,t,r,i,o=e.className+" ";if(o+=e.parentNode?e.parentNode.className:"",t=B.exec(o))return w(t[1])?t[1]:"no-highlight";for(o=o.split(/\s+/),n=0,r=o.length;r>n;n++)if(i=o[n],a(i)||w(i))return i}function o(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function u(e){var n=[];return function r(e,a){for(var i=e.firstChild;i;i=i.nextSibling)3===i.nodeType?a+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:a,node:i}),a=r(i,a),t(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:a,node:i}));return a}(e,0),n}function c(e,r,a){function i(){return e.length&&r.length?e[0].offset!==r[0].offset?e[0].offset48 | 49 | 52 | 53 |wiaa
50 | 51 |"}function u(e){s+=""+t(e)+">"}function c(e){("start"===e.event?o:u)(e.node)}for(var l=0,s="",f=[];e.length||r.length;){var g=i();if(s+=n(a.substring(l,g[0].offset)),l=g[0].offset,g===e){f.reverse().forEach(u);do c(g.splice(0,1)[0]),g=i();while(g===e&&g.length&&g[0].offset===l);f.reverse().forEach(o)}else"start"===g[0].event?f.push(g[0].node):f.pop(),c(g.splice(0,1)[0])}return s+n(a.substr(l))}function l(e){return e.v&&!e.cached_variants&&(e.cached_variants=e.v.map(function(n){return o(e,{v:null},n)})),e.cached_variants||e.eW&&[o(e)]||[e]}function s(e){function n(e){return e&&e.source||e}function t(t,r){return new RegExp(n(t),"m"+(e.cI?"i":"")+(r?"g":""))}function r(a,i){if(!a.compiled){if(a.compiled=!0,a.k=a.k||a.bK,a.k){var o={},u=function(n,t){e.cI&&(t=t.toLowerCase()),t.split(" ").forEach(function(e){var t=e.split("|");o[t[0]]=[n,t[1]?Number(t[1]):1]})};"string"==typeof a.k?u("keyword",a.k):x(a.k).forEach(function(e){u(e,a.k[e])}),a.k=o}a.lR=t(a.l||/\w+/,!0),i&&(a.bK&&(a.b="\\b("+a.bK.split(" ").join("|")+")\\b"),a.b||(a.b=/\B|\b/),a.bR=t(a.b),a.e||a.eW||(a.e=/\B|\b/),a.e&&(a.eR=t(a.e)),a.tE=n(a.e)||"",a.eW&&i.tE&&(a.tE+=(a.e?"|":"")+i.tE)),a.i&&(a.iR=t(a.i)),null==a.r&&(a.r=1),a.c||(a.c=[]),a.c=Array.prototype.concat.apply([],a.c.map(function(e){return l("self"===e?a:e)})),a.c.forEach(function(e){r(e,a)}),a.starts&&r(a.starts,i);var c=a.c.map(function(e){return e.bK?"\\.?("+e.b+")\\.?":e.b}).concat([a.tE,a.i]).map(n).filter(Boolean);a.t=c.length?t(c.join("|"),!0):{exec:function(){return null}}}}r(e)}function f(e,t,a,i){function o(e,n){var t,a;for(t=0,a=n.c.length;a>t;t++)if(r(n.c[t].bR,e))return n.c[t]}function u(e,n){if(r(e.eR,n)){for(;e.endsParent&&e.parent;)e=e.parent;return e}return e.eW?u(e.parent,n):void 0}function c(e,n){return!a&&r(n.iR,e)}function l(e,n){var t=N.cI?n[0].toLowerCase():n[0];return e.k.hasOwnProperty(t)&&e.k[t]}function p(e,n,t,r){var a=r?"":I.classPrefix,i='',i+n+o}function h(){var e,t,r,a;if(!E.k)return n(k);for(a="",t=0,E.lR.lastIndex=0,r=E.lR.exec(k);r;)a+=n(k.substring(t,r.index)),e=l(E,r),e?(B+=e[1],a+=p(e[0],n(r[0]))):a+=n(r[0]),t=E.lR.lastIndex,r=E.lR.exec(k);return a+n(k.substr(t))}function d(){var e="string"==typeof E.sL;if(e&&!y[E.sL])return n(k);var t=e?f(E.sL,k,!0,x[E.sL]):g(k,E.sL.length?E.sL:void 0);return E.r>0&&(B+=t.r),e&&(x[E.sL]=t.top),p(t.language,t.value,!1,!0)}function b(){L+=null!=E.sL?d():h(),k=""}function v(e){L+=e.cN?p(e.cN,"",!0):"",E=Object.create(e,{parent:{value:E}})}function m(e,n){if(k+=e,null==n)return b(),0;var t=o(n,E);if(t)return t.skip?k+=n:(t.eB&&(k+=n),b(),t.rB||t.eB||(k=n)),v(t,n),t.rB?0:n.length;var r=u(E,n);if(r){var a=E;a.skip?k+=n:(a.rE||a.eE||(k+=n),b(),a.eE&&(k=n));do E.cN&&(L+=C),E.skip||(B+=E.r),E=E.parent;while(E!==r.parent);return r.starts&&v(r.starts,""),a.rE?0:n.length}if(c(n,E))throw new Error('Illegal lexeme "'+n+'" for mode "'+(E.cN||" ")+'"');return k+=n,n.length||1}var N=w(e);if(!N)throw new Error('Unknown language: "'+e+'"');s(N);var R,E=i||N,x={},L="";for(R=E;R!==N;R=R.parent)R.cN&&(L=p(R.cN,"",!0)+L);var k="",B=0;try{for(var M,j,O=0;;){if(E.t.lastIndex=O,M=E.t.exec(t),!M)break;j=m(t.substring(O,M.index),M[0]),O=M.index+j}for(m(t.substr(O)),R=E;R.parent;R=R.parent)R.cN&&(L+=C);return{r:B,value:L,language:e,top:E}}catch(T){if(T.message&&-1!==T.message.indexOf("Illegal"))return{r:0,value:n(t)};throw T}}function g(e,t){t=t||I.languages||x(y);var r={r:0,value:n(e)},a=r;return t.filter(w).forEach(function(n){var t=f(n,e,!1);t.language=n,t.r>a.r&&(a=t),t.r>r.r&&(a=r,r=t)}),a.language&&(r.second_best=a),r}function p(e){return I.tabReplace||I.useBR?e.replace(M,function(e,n){return I.useBR&&"\n"===e?" ",I={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};return e.highlight=f,e.highlightAuto=g,e.fixMarkup=p,e.highlightBlock=d,e.configure=b,e.initHighlighting=v,e.initHighlightingOnLoad=m,e.registerLanguage=N,e.listLanguages=R,e.getLanguage=w,e.inherit=o,e.IR="[a-zA-Z]\\w*",e.UIR="[a-zA-Z_]\\w*",e.NR="\\b\\d+(\\.\\d+)?",e.CNR="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",e.BNR="\\b(0b[01]+)",e.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",e.BE={b:"\\\\[\\s\\S]",r:0},e.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[e.BE]},e.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[e.BE]},e.PWM={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},e.C=function(n,t,r){var a=e.inherit({cN:"comment",b:n,e:t,c:[]},r||{});return a.c.push(e.PWM),a.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),a},e.CLCM=e.C("//","$"),e.CBCM=e.C("/\\*","\\*/"),e.HCM=e.C("#","$"),e.NM={cN:"number",b:e.NR,r:0},e.CNM={cN:"number",b:e.CNR,r:0},e.BNM={cN:"number",b:e.BNR,r:0},e.CSSNM={cN:"number",b:e.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},e.RM={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[e.BE,{b:/\[/,e:/\]/,r:0,c:[e.BE]}]},e.TM={cN:"title",b:e.IR,r:0},e.UTM={cN:"title",b:e.UIR,r:0},e.METHOD_GUARD={b:"\\.\\s*"+e.UIR,r:0},e});hljs.registerLanguage("css",function(e){var c="[a-zA-Z-][a-zA-Z0-9_-]*",t={b:/[A-Z\_\.\-]+\s*:/,rB:!0,e:";",eW:!0,c:[{cN:"attribute",b:/\S/,e:":",eE:!0,starts:{eW:!0,eE:!0,c:[{b:/[\w-]+\(/,rB:!0,c:[{cN:"built_in",b:/[\w-]+/},{b:/\(/,e:/\)/,c:[e.ASM,e.QSM]}]},e.CSSNM,e.QSM,e.ASM,e.CBCM,{cN:"number",b:"#[0-9A-Fa-f]+"},{cN:"meta",b:"!important"}]}}]};return{cI:!0,i:/[=\/|'\$]/,c:[e.CBCM,{cN:"selector-id",b:/#[A-Za-z0-9_-]+/},{cN:"selector-class",b:/\.[A-Za-z0-9_-]+/},{cN:"selector-attr",b:/\[/,e:/\]/,i:"$"},{cN:"selector-pseudo",b:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{b:"@",e:"[{;]",i:/:/,c:[{cN:"keyword",b:/\w+/},{b:/\s/,eW:!0,eE:!0,r:0,c:[e.ASM,e.QSM,e.CSSNM]}]},{cN:"selector-tag",b:c,r:0},{b:"{",e:"}",i:/\S/,c:[e.CBCM,t]}]}});hljs.registerLanguage("bash",function(e){var t={cN:"variable",v:[{b:/\$[\w\d#@][\w\d_]*/},{b:/\$\{(.*?)}/}]},s={cN:"string",b:/"/,e:/"/,c:[e.BE,t,{cN:"variable",b:/\$\(/,e:/\)/,c:[e.BE]}]},a={cN:"string",b:/'/,e:/'/};return{aliases:["sh","zsh"],l:/\b-?[a-z\._]+\b/,k:{keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},c:[{cN:"meta",b:/^#![^\n]+sh\s*$/,r:10},{cN:"function",b:/\w[\w\d_]*\s*\(\s*\)\s*\{/,rB:!0,c:[e.inherit(e.TM,{b:/\w[\w\d_]*/})],r:0},e.HCM,s,a,t]}});hljs.registerLanguage("http",function(e){var t="HTTP/[0-9\\.]+";return{aliases:["https"],i:"\\S",c:[{b:"^"+t,e:"$",c:[{cN:"number",b:"\\b\\d{3}\\b"}]},{b:"^[A-Z]+ (.*?) "+t+"$",rB:!0,e:"$",c:[{cN:"string",b:" ",e:" ",eB:!0,eE:!0},{b:t},{cN:"keyword",b:"[A-Z]+"}]},{cN:"attribute",b:"^\\w",e:": ",eE:!0,i:"\\n|\\s|=",starts:{e:"$",r:0}},{b:"\\n\\n",starts:{sL:[],eW:!0}}]}});hljs.registerLanguage("xml",function(s){var e="[A-Za-z0-9\\._:-]+",t={eW:!0,i:/,r:0,c:[{cN:"attr",b:e,r:0},{b:/=\s*/,r:0,c:[{cN:"string",endsParent:!0,v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s"'=<>`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist"],cI:!0,c:[{cN:"meta",b:"",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0}]},{cN:"tag",b:"",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"",rE:!0,sL:["actionscript","javascript","handlebars","xml"]}},{cN:"meta",v:[{b:/<\?xml/,e:/\?>/,r:10},{b:/<\?\w+/,e:/\?>/}]},{cN:"tag",b:"?",e:"/?>",c:[{cN:"name",b:/[^\/><\s]+/,r:0},t]}]}});hljs.registerLanguage("json",function(e){var i={literal:"true false null"},n=[e.QSM,e.CNM],r={e:",",eW:!0,eE:!0,c:n,k:i},t={b:"{",e:"}",c:[{cN:"attr",b:/"/,e:/"/,c:[e.BE],i:"\\n"},e.inherit(r,{b:/:/})],i:"\\S"},c={b:"\\[",e:"\\]",c:[e.inherit(r)],i:"\\S"};return n.splice(n.length,0,t,c),{c:n,k:i,i:"\\S"}});hljs.registerLanguage("javascript",function(e){var r="[A-Za-z$_][0-9A-Za-z$_]*",t={keyword:"in of if for while finally var new function do return void else break catch instanceof with throw case default try this switch continue typeof delete let yield const export super debugger as async await static import from as",literal:"true false null undefined NaN Infinity",built_in:"eval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Error EvalError InternalError RangeError ReferenceError StopIteration SyntaxError TypeError URIError Number Math Date String RegExp Array Float32Array Float64Array Int16Array Int32Array Int8Array Uint16Array Uint32Array Uint8Array Uint8ClampedArray ArrayBuffer DataView JSON Intl arguments require module console window document Symbol Set Map WeakSet WeakMap Proxy Reflect Promise"},a={cN:"number",v:[{b:"\\b(0[bB][01]+)"},{b:"\\b(0[oO][0-7]+)"},{b:e.CNR}],r:0},n={cN:"subst",b:"\\$\\{",e:"\\}",k:t,c:[]},c={cN:"string",b:"`",e:"`",c:[e.BE,n]};n.c=[e.ASM,e.QSM,c,a,e.RM];var s=n.c.concat([e.CBCM,e.CLCM]);return{aliases:["js","jsx"],k:t,c:[{cN:"meta",r:10,b:/^\s*['"]use (strict|asm)['"]/},{cN:"meta",b:/^#!/,e:/$/},e.ASM,e.QSM,c,e.CLCM,e.CBCM,a,{b:/[{,]\s*/,r:0,c:[{b:r+"\\s*:",rB:!0,r:0,c:[{cN:"attr",b:r,r:0}]}]},{b:"("+e.RSR+"|\\b(case|return|throw)\\b)\\s*",k:"return throw case",c:[e.CLCM,e.CBCM,e.RM,{cN:"function",b:"(\\(.*?\\)|"+r+")\\s*=>",rB:!0,e:"\\s*=>",c:[{cN:"params",v:[{b:r},{b:/\(\s*\)/},{b:/\(/,e:/\)/,eB:!0,eE:!0,k:t,c:s}]}]},{b:/,e:/(\/\w+|\w+\/)>/,sL:"xml",c:[{b:/<\w+\s*\/>/,skip:!0},{b:/<\w+/,e:/(\/\w+|\w+\/)>/,skip:!0,c:[{b:/<\w+\s*\/>/,skip:!0},"self"]}]}],r:0},{cN:"function",bK:"function",e:/\{/,eE:!0,c:[e.inherit(e.TM,{b:r}),{cN:"params",b:/\(/,e:/\)/,eB:!0,eE:!0,c:s}],i:/\[|%/},{b:/\$[(.]/},e.METHOD_GUARD,{cN:"class",bK:"class",e:/[{;=]/,eE:!0,i:/[:"\[\]]/,c:[{bK:"extends"},e.UTM]},{bK:"constructor",e:/\{/,eE:!0}],i:/#(?!!)/}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}| )",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("coffeescript",function(e){var c={keyword:"in if for while finally new do return else break catch instanceof throw try this switch continue typeof delete debugger super yield import export from as default await then unless until loop of by when and or is isnt not",literal:"true false null undefined yes no on off",built_in:"npm require console print module global window document"},n="[A-Za-z$_][0-9A-Za-z$_]*",r={cN:"subst",b:/#\{/,e:/}/,k:c},i=[e.BNM,e.inherit(e.CNM,{starts:{e:"(\\s*/)?",r:0}}),{cN:"string",v:[{b:/'''/,e:/'''/,c:[e.BE]},{b:/'/,e:/'/,c:[e.BE]},{b:/"""/,e:/"""/,c:[e.BE,r]},{b:/"/,e:/"/,c:[e.BE,r]}]},{cN:"regexp",v:[{b:"///",e:"///",c:[r,e.HCM]},{b:"//[gim]*",r:0},{b:/\/(?![ *])(\\\/|.)*?\/[gim]*(?=\W|$)/}]},{b:"@"+n},{sL:"javascript",eB:!0,eE:!0,v:[{b:"```",e:"```"},{b:"`",e:"`"}]}];r.c=i;var s=e.inherit(e.TM,{b:n}),t="(\\(.*\\))?\\s*\\B[-=]>",o={cN:"params",b:"\\([^\\(]",rB:!0,c:[{b:/\(/,e:/\)/,k:c,c:["self"].concat(i)}]};return{aliases:["coffee","cson","iced"],k:c,i:/\/\*/,c:i.concat([e.C("###","###"),e.HCM,{cN:"function",b:"^\\s*"+n+"\\s*=\\s*"+t,e:"[-=]>",rB:!0,c:[s,o]},{b:/[:\(,=]\s*/,r:0,c:[{cN:"function",b:t,e:"[-=]>",rB:!0,c:[o]}]},{cN:"class",bK:"class",e:"$",i:/[:="\[\]]/,c:[{bK:"extends",eW:!0,i:/[:="\[\]]/,c:[s]},s]},{b:n+":",e:":",rB:!0,rE:!0,r:0}])}}); -------------------------------------------------------------------------------- /wct.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | suites: [ 3 | 'test', 4 | ], 5 | expanded: true, 6 | plugins: { 7 | local: { 8 | browsers: [ 9 | 'chrome', 10 | 'firefox', 11 | ], 12 | browserOptions: { 13 | chrome: [ 14 | 'headless', 15 | 'disable-gpu', 16 | 'no-sandbox', 17 | ], 18 | firefox: [ 19 | '-headless', 20 | ], 21 | }, 22 | }, 23 | istanbul: { 24 | reporters: [ 25 | 'text', 26 | 'text-summary', 27 | 'lcov', 28 | 'json', 29 | ], 30 | include: [ 31 | '**/code-sample.js', 32 | ], 33 | exclude: [ 34 | '/polymer/polymer.js', 35 | '/platform/platform.js', 36 | ], 37 | thresholds: { 38 | global: { 39 | statements: 80, 40 | branches: 80, 41 | functions: 80, 42 | lines: 80, 43 | }, 44 | }, 45 | }, 46 | sauce: { 47 | browsers: [{ 48 | browserName: 'MicrosoftEdge', 49 | platform: 'Windows 10', 50 | version: '17.17134', 51 | }, { 52 | browserName: 'safari', 53 | platform: 'macOS 10.13', 54 | version: '11.1', 55 | }], 56 | }, 57 | }, 58 | }; 59 | --------------------------------------------------------------------------------
":I.tabReplace?n.replace(/\t/g,I.tabReplace):""}):e}function h(e,n,t){var r=n?L[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}function d(e){var n,t,r,o,l,s=i(e);a(s)||(I.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div"),n.innerHTML=e.innerHTML.replace(/\n/g,"").replace(/
/g,"\n")):n=e,l=n.textContent,r=s?f(s,l,!0):g(l),t=u(n),t.length&&(o=document.createElementNS("http://www.w3.org/1999/xhtml","div"),o.innerHTML=r.value,r.value=c(t,u(o),l)),r.value=p(r.value),e.innerHTML=r.value,e.className=h(e.className,s,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function b(e){I=o(I,e)}function v(){if(!v.called){v.called=!0;var e=document.querySelectorAll("pre code");E.forEach.call(e,d)}}function m(){addEventListener("DOMContentLoaded",v,!1),addEventListener("load",v,!1)}function N(n,t){var r=y[n]=t(e);r.aliases&&r.aliases.forEach(function(e){L[e]=n})}function R(){return x(y)}function w(e){return e=(e||"").toLowerCase(),y[e]||y[L[e]]}var E=[],x=Object.keys,y={},L={},k=/^(no-?highlight|plain|text)$/i,B=/\blang(?:uage)?-([\w-]+)\b/i,M=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,C="