vanilla-framework 4.34.0 → 4.34.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +11 -2
- package/scss/_layouts_application.scss +3 -3
- package/scss/_layouts_docs.scss +1 -1
- package/scss/_layouts_full-width.scss +1 -1
- package/scss/_layouts_site.scss +1 -1
- package/scss/_patterns_navigation.scss +5 -4
- package/scss/_patterns_side-navigation.scss +1 -1
- package/templates/_macros/vf_logo-section.jinja +1 -1
- package/templates/static/js/example-tools.js +181 -0
- package/templates/static/js/example.js +554 -0
- package/templates/static/js/index.js +16 -0
- package/templates/static/js/package.json +3 -0
- package/templates/static/js/prism.min.js +8 -0
- package/templates/static/js/scripts.js +418 -0
- package/templates/static/js/tabs.js +111 -0
|
@@ -0,0 +1,554 @@
|
|
|
1
|
+
(function () {
|
|
2
|
+
if (!window.VANILLA_VERSION) {
|
|
3
|
+
throw Error('VANILLA_VERSION not specified.');
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
// throttling function calls, by Remy Sharp
|
|
7
|
+
// http://remysharp.com/2010/07/21/throttling-function-calls/
|
|
8
|
+
const throttle = function (fn, delay) {
|
|
9
|
+
let timer = null;
|
|
10
|
+
return function () {
|
|
11
|
+
const context = this,
|
|
12
|
+
args = arguments;
|
|
13
|
+
clearTimeout(timer);
|
|
14
|
+
timer = setTimeout(function () {
|
|
15
|
+
fn.apply(context, args);
|
|
16
|
+
}, delay);
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Mapping of example keys to the regex patterns used to strip them out of an example
|
|
22
|
+
* @type {{body: RegExp, jinja: RegExp, title: RegExp, head: RegExp}}
|
|
23
|
+
*/
|
|
24
|
+
const EXAMPLE_CONTENT_PATTERNS = {
|
|
25
|
+
body: /<body[^>]*>((.|[\n\r])*)<\/body>/im,
|
|
26
|
+
jinja: /{% block content %}([\s\S]*?){% endblock( content)? %}/,
|
|
27
|
+
title: /<title[^>]*>((.|[\n\r])*)<\/title>/im,
|
|
28
|
+
head: /<head[^>]*>((.|[\n\r])*)<\/head>/im,
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Object representing the structure for language option mappings.
|
|
33
|
+
* @typedef {Object} ExampleLanguageConfig
|
|
34
|
+
* @property {string} label - Human-readable label.
|
|
35
|
+
* @property {string} langIdentifier - Prism language identifier.
|
|
36
|
+
*/
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Mapping of example keys to their configurations.
|
|
40
|
+
* @type {{jinja: ExampleLanguageConfig, css: ExampleLanguageConfig, js: ExampleLanguageConfig, html: ExampleLanguageConfig}}
|
|
41
|
+
*/
|
|
42
|
+
const EXAMPLE_LANGUAGE_OPTION_CONFIG = {
|
|
43
|
+
html: {
|
|
44
|
+
label: 'HTML',
|
|
45
|
+
langIdentifier: 'html',
|
|
46
|
+
},
|
|
47
|
+
css: {
|
|
48
|
+
label: 'CSS',
|
|
49
|
+
langIdentifier: 'css',
|
|
50
|
+
},
|
|
51
|
+
js: {
|
|
52
|
+
label: 'JS',
|
|
53
|
+
langIdentifier: 'js',
|
|
54
|
+
},
|
|
55
|
+
jinja: {
|
|
56
|
+
label: 'Jinja',
|
|
57
|
+
// While `jinja2` is an option on Prism, it does not seem to highlight syntax properly. So use HTML instead.
|
|
58
|
+
langIdentifier: 'html',
|
|
59
|
+
},
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
const CODEPEN_CONFIG = {
|
|
63
|
+
title: 'Vanilla framework example',
|
|
64
|
+
head: "<meta name='viewport' content='width=device-width, initial-scale=1'>",
|
|
65
|
+
stylesheets: [
|
|
66
|
+
// link to latest Vanilla CSS
|
|
67
|
+
// if it's a demo, use local build.css for better QA, otherwise use latest published Vanilla
|
|
68
|
+
/demos\.haus$/.test(window.location.host)
|
|
69
|
+
? `${window.location.origin}/static/build/css/build.css`
|
|
70
|
+
: 'https://assets.ubuntu.com/v1/vanilla_framework_version_' + VANILLA_VERSION.replaceAll('.', '_') + '_min.css',
|
|
71
|
+
// link to example stylesheet (to set margin on body)
|
|
72
|
+
'https://assets.ubuntu.com/v1/4653d9ba-example.css',
|
|
73
|
+
],
|
|
74
|
+
tags: ['Vanilla framework'],
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
document.addEventListener('DOMContentLoaded', function () {
|
|
78
|
+
const examples = document.querySelectorAll('.js-example');
|
|
79
|
+
|
|
80
|
+
[].slice.call(examples).forEach((placementElement) => {
|
|
81
|
+
renderExample(placementElement).catch((error) => {
|
|
82
|
+
console.error('Failed to render example', {placementElement, error});
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* `fetch()` wrapper that throws an error if the response is not OK.
|
|
89
|
+
* @param {String} url Address to fetch
|
|
90
|
+
* @param {RequestInit} opts Options for the fetch request
|
|
91
|
+
* @returns {Promise<Response>} Response object
|
|
92
|
+
* @throws {Error} If the response is not in the 200 (OK) range
|
|
93
|
+
*/
|
|
94
|
+
const fetchResponse = async function (url, opts = {}) {
|
|
95
|
+
try {
|
|
96
|
+
const response = await fetch(url, opts);
|
|
97
|
+
if (!response.ok) {
|
|
98
|
+
throw new Error(`Failed to fetch example ${url} with status ${response.status}`);
|
|
99
|
+
}
|
|
100
|
+
return response;
|
|
101
|
+
} catch (err) {
|
|
102
|
+
console.error('An error occurred while performing a fetch request', err);
|
|
103
|
+
throw err;
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Fetch the response text of a URL.
|
|
109
|
+
* @param {String} url Address to fetch
|
|
110
|
+
* @returns {Promise<String>} Response text
|
|
111
|
+
* @throws {Error} If the response is not in the 200 (OK) range
|
|
112
|
+
*/
|
|
113
|
+
const fetchResponseText = async function (url) {
|
|
114
|
+
return fetchResponse(url).then((response) => response.text());
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Format source code based on language
|
|
119
|
+
* @param {String} source - source code to format
|
|
120
|
+
* @param {'html'|'jinja'|'js'|'css'} lang - language of the source code
|
|
121
|
+
* @returns {String} formatted source code
|
|
122
|
+
*/
|
|
123
|
+
function formatSource(source, lang) {
|
|
124
|
+
try {
|
|
125
|
+
switch (lang) {
|
|
126
|
+
case 'html':
|
|
127
|
+
case 'jinja':
|
|
128
|
+
return window.html_beautify(source, {indent_size: 2});
|
|
129
|
+
case 'js':
|
|
130
|
+
return window.js_beautify(source, {indent_size: 2});
|
|
131
|
+
case 'css':
|
|
132
|
+
return window.css_beautify(source, {indent_size: 2});
|
|
133
|
+
default:
|
|
134
|
+
return source;
|
|
135
|
+
}
|
|
136
|
+
} catch (error) {
|
|
137
|
+
// If beautify fails (e.g. invalid source, CDN outage, error upstream), return original source
|
|
138
|
+
console.error(`Failed to format ${lang} source code: ${error}`, `This could be due to invalid ${lang} source code, an issue with the formatter, or a CDN outage.`, {source});
|
|
139
|
+
return source;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Create `pre`-formatted code for a block of source
|
|
145
|
+
* @param {String} source Formatted source code
|
|
146
|
+
* @param {'html'|'jinja'|'js'|'css'} lang Language of the source code
|
|
147
|
+
* @param {Boolean} isHidden Whether the pre-code should be hidden initially
|
|
148
|
+
* @returns {HTMLPreElement} Code snippet containing the source code
|
|
149
|
+
*/
|
|
150
|
+
function createPreCode(source, lang, isHidden = true) {
|
|
151
|
+
const code = document.createElement('code');
|
|
152
|
+
code.appendChild(document.createTextNode(source));
|
|
153
|
+
|
|
154
|
+
const pre = document.createElement('pre');
|
|
155
|
+
pre.classList.add('p-code-snippet__block');
|
|
156
|
+
|
|
157
|
+
// TODO: move max-height elsewhere to CSS?
|
|
158
|
+
pre.style.maxHeight = '300px';
|
|
159
|
+
|
|
160
|
+
if (isHidden) {
|
|
161
|
+
pre.classList.add('u-hide');
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (lang) {
|
|
165
|
+
pre.setAttribute('data-lang', lang);
|
|
166
|
+
pre.classList.add('language-' + (EXAMPLE_LANGUAGE_OPTION_CONFIG[lang]?.langIdentifier || lang));
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
pre.appendChild(code);
|
|
170
|
+
return pre;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Extract a section of HTML from the document
|
|
175
|
+
* @param {'body'|'jinja'|'title'|'head'} sectionKey The key/type of content to be extracted
|
|
176
|
+
* @param {String} documentHTML The example's full HTML content. This may be rendered or raw Jinja template.
|
|
177
|
+
* @returns {String} The requested section of the document, or an empty string if it was not found.
|
|
178
|
+
*/
|
|
179
|
+
function getExampleSection(sectionKey, documentHTML) {
|
|
180
|
+
const pattern = EXAMPLE_CONTENT_PATTERNS[sectionKey];
|
|
181
|
+
return pattern?.exec(documentHTML)?.[1]?.trim() || '';
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
/**
|
|
185
|
+
* Fetches the rendered HTML of an example and extracts the relevant sections for rendering and code snippets.
|
|
186
|
+
* @param {HTMLAnchorElement} placementElement The placeholder element for the example
|
|
187
|
+
* @returns {Promise<{renderedHtml: String, bodyHtml: String, title: String, jsSource: String, externalScripts: NodeListOf<Element>, cssSource: String}>} The extracted sections of the example
|
|
188
|
+
*/
|
|
189
|
+
async function fetchRenderedHtml(placementElement) {
|
|
190
|
+
const renderedHtml = await fetchResponseText(placementElement.href);
|
|
191
|
+
let bodyHtml = getExampleSection('body', renderedHtml);
|
|
192
|
+
|
|
193
|
+
// Extract JS from the body before we strip it out
|
|
194
|
+
let jsSource = getScriptFromSource(bodyHtml);
|
|
195
|
+
const externalScripts = getExternalScriptsFromSource(renderedHtml);
|
|
196
|
+
|
|
197
|
+
// Filter external scripts to only include project-local scripts (not CDN/third-party)
|
|
198
|
+
// and exclude utility/tool files that aren't part of the actual example
|
|
199
|
+
const baseUrl = new URL(placementElement.href);
|
|
200
|
+
const projectScripts = externalScripts.filter((scriptSrc) => {
|
|
201
|
+
try {
|
|
202
|
+
const scriptUrl = new URL(scriptSrc, baseUrl);
|
|
203
|
+
// Only include scripts from the same origin (project scripts)
|
|
204
|
+
if (scriptUrl.origin !== baseUrl.origin) {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// Exclude common utility files that aren't part of the actual example code
|
|
209
|
+
const excludedFiles = ['example-tools.js', 'example.js', 'build.js'];
|
|
210
|
+
|
|
211
|
+
const scriptPath = scriptUrl.pathname;
|
|
212
|
+
return !excludedFiles.some((excludedFile) => scriptPath.includes(excludedFile));
|
|
213
|
+
} catch (error) {
|
|
214
|
+
return false;
|
|
215
|
+
}
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
// Render external scripts, if no inline-script was found
|
|
219
|
+
if (!jsSource && projectScripts.length > 0) {
|
|
220
|
+
const projectScriptContents = await Promise.all(
|
|
221
|
+
projectScripts.map(async (scriptSrc) => {
|
|
222
|
+
try {
|
|
223
|
+
const absoluteUrl = new URL(scriptSrc, baseUrl).href;
|
|
224
|
+
const scriptContent = await fetchResponseText(absoluteUrl);
|
|
225
|
+
return scriptContent;
|
|
226
|
+
} catch (error) {
|
|
227
|
+
console.warn(`Failed to fetch project script: ${scriptSrc}`, error);
|
|
228
|
+
return `// Failed to load: ${scriptSrc}`;
|
|
229
|
+
}
|
|
230
|
+
}),
|
|
231
|
+
);
|
|
232
|
+
|
|
233
|
+
const allJsContent = projectScriptContents.filter(Boolean);
|
|
234
|
+
jsSource = allJsContent.length > 0 ? allJsContent.join('\n\n') : null;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
jsSource = jsSource ? formatSource(jsSource, 'js') : null;
|
|
238
|
+
bodyHtml = formatSource(stripScriptsFromSource(bodyHtml), 'html');
|
|
239
|
+
|
|
240
|
+
const title = getExampleSection('title', renderedHtml).split('|')[0];
|
|
241
|
+
const headHtml = getExampleSection('head', renderedHtml);
|
|
242
|
+
const cssSource = formatSource(getStyleFromSource(headHtml), 'css');
|
|
243
|
+
|
|
244
|
+
return {renderedHtml, bodyHtml, title, jsSource, externalScripts, cssSource};
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* Fetches the raw Jinja template of an example and returns the Jinja content block
|
|
249
|
+
* @param {HTMLElement} placementElement The placeholder element for the example
|
|
250
|
+
* @returns {Promise<String>} The Jinja content block of the example
|
|
251
|
+
*/
|
|
252
|
+
async function fetchJinjaContentBlock(placementElement) {
|
|
253
|
+
// Raw templates are not served at standalone paths, so strip it from the URL if it was found.
|
|
254
|
+
const exampleUrl = new URL(`${placementElement.href.replace(/standalone/, '/')}`);
|
|
255
|
+
|
|
256
|
+
// Add `?raw=true` query parameter to the URL to request the raw Jinja template
|
|
257
|
+
const queryParams = new URLSearchParams(exampleUrl.search);
|
|
258
|
+
queryParams.set('raw', true);
|
|
259
|
+
exampleUrl.search = queryParams.toString();
|
|
260
|
+
|
|
261
|
+
const rawJinjaTemplate = await fetchResponseText(exampleUrl.toString());
|
|
262
|
+
return formatSource(getExampleSection('jinja', rawJinjaTemplate), 'jinja');
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Replaces an example placeholder element with its rendered result and code snippet.
|
|
267
|
+
* @param {HTMLAnchorElement} placementElement `a.js-example` element used as a placeholder for the example to render
|
|
268
|
+
*/
|
|
269
|
+
async function renderExample(placementElement) {
|
|
270
|
+
const codeSnippet = document.createElement('div');
|
|
271
|
+
codeSnippet.classList.add('p-code-snippet', 'is-bordered');
|
|
272
|
+
|
|
273
|
+
const header = document.createElement('div');
|
|
274
|
+
header.classList.add('p-code-snippet__header');
|
|
275
|
+
|
|
276
|
+
const titleEl = document.createElement('h5');
|
|
277
|
+
titleEl.classList.add('p-code-snippet__title');
|
|
278
|
+
|
|
279
|
+
// Example data will be asynchronously fetched and placed here on promise resolution.
|
|
280
|
+
const srcData = {
|
|
281
|
+
html: undefined,
|
|
282
|
+
renderedHtml: undefined,
|
|
283
|
+
jinja: undefined,
|
|
284
|
+
css: undefined,
|
|
285
|
+
js: undefined,
|
|
286
|
+
codePen: undefined,
|
|
287
|
+
title: undefined,
|
|
288
|
+
};
|
|
289
|
+
|
|
290
|
+
const exampleRequests = [];
|
|
291
|
+
|
|
292
|
+
const fetchHtml = fetchRenderedHtml(placementElement).then(({renderedHtml, bodyHtml, title, jsSource, externalScripts, cssSource}) => {
|
|
293
|
+
// There are required, so throw if they failed
|
|
294
|
+
if (renderedHtml && bodyHtml && title) {
|
|
295
|
+
srcData.renderedHtml = renderedHtml;
|
|
296
|
+
srcData.html = bodyHtml;
|
|
297
|
+
srcData.title = title;
|
|
298
|
+
} else {
|
|
299
|
+
throw new Error('Failed to fetch HTML for example iframe and HTML source.');
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// The rest of the views are optional
|
|
303
|
+
srcData.js = jsSource;
|
|
304
|
+
srcData.css = cssSource;
|
|
305
|
+
srcData.codePen = {
|
|
306
|
+
html: bodyHtml,
|
|
307
|
+
css: cssSource,
|
|
308
|
+
js: jsSource,
|
|
309
|
+
externalJS: externalScripts,
|
|
310
|
+
};
|
|
311
|
+
});
|
|
312
|
+
exampleRequests.push(fetchHtml);
|
|
313
|
+
|
|
314
|
+
if (placementElement.getAttribute('data-lang') === 'jinja') {
|
|
315
|
+
// Perform jinja template fetching if the example was marked as a Jinja template
|
|
316
|
+
const fetchJinja = fetchJinjaContentBlock(placementElement).then((contentBlock) => {
|
|
317
|
+
const hasJinjaTemplate = contentBlock?.length > 0;
|
|
318
|
+
if (hasJinjaTemplate) {
|
|
319
|
+
srcData.jinja = contentBlock;
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
exampleRequests.push(fetchJinja);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
// Perform as much of the data fetching and processing as possible in parallel
|
|
326
|
+
await Promise.all(exampleRequests);
|
|
327
|
+
// Code after this point depends on the data above being fully fetched, so must come after an `await`
|
|
328
|
+
|
|
329
|
+
titleEl.innerText = srcData.title;
|
|
330
|
+
header.appendChild(titleEl);
|
|
331
|
+
codeSnippet.appendChild(header);
|
|
332
|
+
placementElement.parentNode.insertBefore(codeSnippet, placementElement);
|
|
333
|
+
renderIframe(codeSnippet, srcData.renderedHtml, placementElement.getAttribute('data-height'));
|
|
334
|
+
|
|
335
|
+
// Gather the languages that have source code available, in the order they should be displayed
|
|
336
|
+
// We can't rely on order of these languages being made available in the promise blocks above due to async nature
|
|
337
|
+
const languageOptions = ['jinja', 'html', 'js', 'css'].filter((lang) => srcData[lang]);
|
|
338
|
+
const sourceBlocks = languageOptions
|
|
339
|
+
// THe first language option that was found is displayed by default. The rest are viewable using dropdown.
|
|
340
|
+
.map((lang, idx) => createPreCode(srcData[lang], lang, idx > 0));
|
|
341
|
+
|
|
342
|
+
// Code snippet must be populated with code before Prism can highlight it
|
|
343
|
+
sourceBlocks.forEach((block) => codeSnippet.appendChild(block));
|
|
344
|
+
if (Prism) {
|
|
345
|
+
Prism.highlightAllUnder(codeSnippet);
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
if (srcData.codePen) {
|
|
349
|
+
renderCodePenEditLink(codeSnippet, srcData.codePen);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
renderDropdown(header, languageOptions);
|
|
353
|
+
|
|
354
|
+
// The example has been rendered successfully, hide the placeholder element.
|
|
355
|
+
placementElement.style.display = 'none';
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Renders a dropdown containing the code snippet options, allowing user to switch between multiple views.
|
|
360
|
+
* @param {HTMLDivElement} codeSnippetHeader The header element of the code snippet
|
|
361
|
+
* @param {('html'|'jinja'|'js'|'css')[]} codeSnippetModes List of code snippet mode options
|
|
362
|
+
*/
|
|
363
|
+
function renderDropdown(codeSnippetHeader, codeSnippetModes) {
|
|
364
|
+
// only add dropdown if there is more than one code block
|
|
365
|
+
if (codeSnippetModes.length <= 1) return;
|
|
366
|
+
|
|
367
|
+
const dropdownsEl = document.createElement('div');
|
|
368
|
+
dropdownsEl.classList.add('p-code-snippet__dropdowns');
|
|
369
|
+
|
|
370
|
+
const selectEl = document.createElement('select');
|
|
371
|
+
selectEl.classList.add('p-code-snippet__dropdown');
|
|
372
|
+
|
|
373
|
+
codeSnippetModes.forEach(function (option) {
|
|
374
|
+
const optionHTML = document.createElement('option');
|
|
375
|
+
optionHTML.value = option.toLowerCase();
|
|
376
|
+
optionHTML.innerText = EXAMPLE_LANGUAGE_OPTION_CONFIG[option]?.label || option.toLowerCase();
|
|
377
|
+
selectEl.appendChild(optionHTML);
|
|
378
|
+
});
|
|
379
|
+
|
|
380
|
+
dropdownsEl.appendChild(selectEl);
|
|
381
|
+
codeSnippetHeader.appendChild(dropdownsEl);
|
|
382
|
+
attachDropdownEvents(selectEl);
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
function resizeIframe(iframe) {
|
|
386
|
+
if (iframe.contentDocument.readyState == 'complete') {
|
|
387
|
+
const frameHeight = iframe.contentDocument.body.scrollHeight;
|
|
388
|
+
iframe.height = frameHeight + 32 + 'px'; // accommodate for body margin
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
function renderIframe(container, html, height) {
|
|
393
|
+
const iframe = document.createElement('iframe');
|
|
394
|
+
|
|
395
|
+
if (height) {
|
|
396
|
+
iframe.height = height + 'px';
|
|
397
|
+
}
|
|
398
|
+
container.appendChild(iframe);
|
|
399
|
+
const doc = iframe.contentWindow.document;
|
|
400
|
+
doc.open();
|
|
401
|
+
doc.write(html);
|
|
402
|
+
doc.close();
|
|
403
|
+
|
|
404
|
+
// if height wasn't specified, try to determine it from example content
|
|
405
|
+
if (!height) {
|
|
406
|
+
// Wait for content to load before determining height
|
|
407
|
+
const resizeInterval = setInterval(function () {
|
|
408
|
+
if (iframe.contentDocument.readyState == 'complete') {
|
|
409
|
+
resizeIframe(iframe);
|
|
410
|
+
clearInterval(resizeInterval);
|
|
411
|
+
fixScroll();
|
|
412
|
+
}
|
|
413
|
+
}, 100);
|
|
414
|
+
|
|
415
|
+
// cancel resizing if frame didn't load in 5s
|
|
416
|
+
setTimeout(function () {
|
|
417
|
+
clearInterval(resizeInterval);
|
|
418
|
+
}, 5000);
|
|
419
|
+
|
|
420
|
+
window.addEventListener(
|
|
421
|
+
'resize',
|
|
422
|
+
throttle(function () {
|
|
423
|
+
resizeIframe(iframe);
|
|
424
|
+
}, 10),
|
|
425
|
+
);
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
return iframe;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
function renderCodePenEditLink(snippet, sourceData) {
|
|
432
|
+
const html = sourceData.html === null ? '' : sourceData.html;
|
|
433
|
+
const css = sourceData.css === null ? '' : sourceData.css;
|
|
434
|
+
const js = sourceData.js === null ? '' : sourceData.js;
|
|
435
|
+
|
|
436
|
+
if (html || css || js) {
|
|
437
|
+
const container = document.createElement('div');
|
|
438
|
+
const form = document.createElement('form');
|
|
439
|
+
const input = document.createElement('input');
|
|
440
|
+
const link = document.createElement('a');
|
|
441
|
+
const data = {
|
|
442
|
+
title: CODEPEN_CONFIG.title,
|
|
443
|
+
head: CODEPEN_CONFIG.head,
|
|
444
|
+
html: html,
|
|
445
|
+
css: css,
|
|
446
|
+
js: js,
|
|
447
|
+
css_external: CODEPEN_CONFIG.stylesheets.join(';'),
|
|
448
|
+
js_external: sourceData.externalJS.join(';'),
|
|
449
|
+
};
|
|
450
|
+
// Replace double quotes to avoid errors on CodePen
|
|
451
|
+
const JSONstring = JSON.stringify(data).replace(/"/g, '"').replace(/'/g, ''');
|
|
452
|
+
|
|
453
|
+
container.classList.add('p-code-snippet__header');
|
|
454
|
+
|
|
455
|
+
form.setAttribute('action', 'https://codepen.io/pen/define');
|
|
456
|
+
form.setAttribute('method', 'POST');
|
|
457
|
+
form.setAttribute('target', '_blank');
|
|
458
|
+
|
|
459
|
+
input.setAttribute('type', 'hidden');
|
|
460
|
+
input.setAttribute('name', 'data');
|
|
461
|
+
input.setAttribute('value', JSONstring);
|
|
462
|
+
|
|
463
|
+
link.innerHTML = 'Edit on CodePen';
|
|
464
|
+
link.style.cssText = 'display: block; padding: 0.5rem 0;';
|
|
465
|
+
|
|
466
|
+
form.appendChild(input);
|
|
467
|
+
form.appendChild(link);
|
|
468
|
+
container.appendChild(form);
|
|
469
|
+
handleCodePenClick(link, form);
|
|
470
|
+
snippet.appendChild(container);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
function handleCodePenClick(link, form) {
|
|
475
|
+
link.addEventListener('click', function (e) {
|
|
476
|
+
e.preventDefault();
|
|
477
|
+
form.submit();
|
|
478
|
+
});
|
|
479
|
+
|
|
480
|
+
// handle middle mouse button click
|
|
481
|
+
link.addEventListener('mouseup', function (e) {
|
|
482
|
+
if (e.which === 2) {
|
|
483
|
+
link.click();
|
|
484
|
+
}
|
|
485
|
+
});
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
function getStyleFromSource(source) {
|
|
489
|
+
const div = document.createElement('div');
|
|
490
|
+
div.innerHTML = source;
|
|
491
|
+
const style = div.querySelector('style');
|
|
492
|
+
return style ? style.innerHTML.trim() : null;
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
function stripScriptsFromSource(source) {
|
|
496
|
+
const div = document.createElement('div');
|
|
497
|
+
div.innerHTML = source;
|
|
498
|
+
const scripts = div.getElementsByTagName('script');
|
|
499
|
+
let i = scripts.length;
|
|
500
|
+
while (i--) {
|
|
501
|
+
scripts[i].parentNode.removeChild(scripts[i]);
|
|
502
|
+
}
|
|
503
|
+
return div.innerHTML.trim();
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
function getScriptFromSource(source) {
|
|
507
|
+
const div = document.createElement('div');
|
|
508
|
+
div.innerHTML = source;
|
|
509
|
+
const script = div.querySelector('script');
|
|
510
|
+
return script ? script.innerHTML.trim() : null;
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
function getExternalScriptsFromSource(source) {
|
|
514
|
+
const div = document.createElement('div');
|
|
515
|
+
div.innerHTML = source;
|
|
516
|
+
let scripts = div.querySelectorAll('script[src]');
|
|
517
|
+
scripts = [].slice.apply(scripts).map(function (s) {
|
|
518
|
+
return s.src;
|
|
519
|
+
});
|
|
520
|
+
return scripts;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
function fixScroll() {
|
|
524
|
+
const titleId = window.location.hash;
|
|
525
|
+
if (titleId) {
|
|
526
|
+
const title = document.querySelector(titleId);
|
|
527
|
+
title.scrollIntoView();
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
Attaches change event listener to a given select.
|
|
533
|
+
@param {HTMLElement} dropdown Select element belonging to a code snippet.
|
|
534
|
+
*/
|
|
535
|
+
function attachDropdownEvents(dropdown) {
|
|
536
|
+
dropdown.addEventListener('change', function (e) {
|
|
537
|
+
const snippet = e.target.closest('.p-code-snippet');
|
|
538
|
+
|
|
539
|
+
// toggle code blocks visibility based on selected language
|
|
540
|
+
for (let i = 0; i < dropdown.options.length; i++) {
|
|
541
|
+
const lang = dropdown.options[i].value;
|
|
542
|
+
const block = snippet && snippet.querySelector("[data-lang='" + lang + "']");
|
|
543
|
+
|
|
544
|
+
if (lang === e.target.value) {
|
|
545
|
+
block.classList.remove('u-hide');
|
|
546
|
+
block.setAttribute('aria-hidden', false);
|
|
547
|
+
} else {
|
|
548
|
+
block.classList.add('u-hide');
|
|
549
|
+
block.setAttribute('aria-hidden', true);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
});
|
|
553
|
+
}
|
|
554
|
+
})();
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vanilla Framework JavaScript modules
|
|
3
|
+
*
|
|
4
|
+
* This is the main entry point for importing Vanilla Framework JavaScript modules.
|
|
5
|
+
* You can import individual modules or all modules from this module.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
// Re-export tabs as a namespace for organized imports
|
|
9
|
+
import * as tabs from './tabs.js';
|
|
10
|
+
export {tabs};
|
|
11
|
+
|
|
12
|
+
// Default export for convenience
|
|
13
|
+
export default {
|
|
14
|
+
tabs,
|
|
15
|
+
// Add future modules here as they are created
|
|
16
|
+
};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/* PrismJS 1.23.0
|
|
2
|
+
https://prismjs.com/download#themes=prism&languages=markup+css+clike+javascript&plugins=keep-markup */
|
|
3
|
+
var _self="undefined"!=typeof window?window:"undefined"!=typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope?self:{},Prism=function(u){var c=/\blang(?:uage)?-([\w-]+)\b/i,n=0,M={manual:u.Prism&&u.Prism.manual,disableWorkerMessageHandler:u.Prism&&u.Prism.disableWorkerMessageHandler,util:{encode:function e(n){return n instanceof W?new W(n.type,e(n.content),n.alias):Array.isArray(n)?n.map(e):n.replace(/&/g,"&").replace(/</g,"<").replace(/\u00a0/g," ")},type:function(e){return Object.prototype.toString.call(e).slice(8,-1)},objId:function(e){return e.__id||Object.defineProperty(e,"__id",{value:++n}),e.__id},clone:function r(e,t){var a,n;switch(t=t||{},M.util.type(e)){case"Object":if(n=M.util.objId(e),t[n])return t[n];for(var i in a={},t[n]=a,e)e.hasOwnProperty(i)&&(a[i]=r(e[i],t));return a;case"Array":return n=M.util.objId(e),t[n]?t[n]:(a=[],t[n]=a,e.forEach(function(e,n){a[n]=r(e,t)}),a);default:return e}},getLanguage:function(e){for(;e&&!c.test(e.className);)e=e.parentElement;return e?(e.className.match(c)||[,"none"])[1].toLowerCase():"none"},currentScript:function(){if("undefined"==typeof document)return null;if("currentScript"in document)return document.currentScript;try{throw new Error}catch(e){var n=(/at [^(\r\n]*\((.*):.+:.+\)$/i.exec(e.stack)||[])[1];if(n){var r=document.getElementsByTagName("script");for(var t in r)if(r[t].src==n)return r[t]}return null}},isActive:function(e,n,r){for(var t="no-"+n;e;){var a=e.classList;if(a.contains(n))return!0;if(a.contains(t))return!1;e=e.parentElement}return!!r}},languages:{extend:function(e,n){var r=M.util.clone(M.languages[e]);for(var t in n)r[t]=n[t];return r},insertBefore:function(r,e,n,t){var a=(t=t||M.languages)[r],i={};for(var l in a)if(a.hasOwnProperty(l)){if(l==e)for(var o in n)n.hasOwnProperty(o)&&(i[o]=n[o]);n.hasOwnProperty(l)||(i[l]=a[l])}var s=t[r];return t[r]=i,M.languages.DFS(M.languages,function(e,n){n===s&&e!=r&&(this[e]=i)}),i},DFS:function e(n,r,t,a){a=a||{};var i=M.util.objId;for(var l in n)if(n.hasOwnProperty(l)){r.call(n,l,n[l],t||l);var o=n[l],s=M.util.type(o);"Object"!==s||a[i(o)]?"Array"!==s||a[i(o)]||(a[i(o)]=!0,e(o,r,l,a)):(a[i(o)]=!0,e(o,r,null,a))}}},plugins:{},highlightAll:function(e,n){M.highlightAllUnder(document,e,n)},highlightAllUnder:function(e,n,r){var t={callback:r,container:e,selector:'code[class*="language-"], [class*="language-"] code, code[class*="lang-"], [class*="lang-"] code'};M.hooks.run("before-highlightall",t),t.elements=Array.prototype.slice.apply(t.container.querySelectorAll(t.selector)),M.hooks.run("before-all-elements-highlight",t);for(var a,i=0;a=t.elements[i++];)M.highlightElement(a,!0===n,t.callback)},highlightElement:function(e,n,r){var t=M.util.getLanguage(e),a=M.languages[t];e.className=e.className.replace(c,"").replace(/\s+/g," ")+" language-"+t;var i=e.parentElement;i&&"pre"===i.nodeName.toLowerCase()&&(i.className=i.className.replace(c,"").replace(/\s+/g," ")+" language-"+t);var l={element:e,language:t,grammar:a,code:e.textContent};function o(e){l.highlightedCode=e,M.hooks.run("before-insert",l),l.element.innerHTML=l.highlightedCode,M.hooks.run("after-highlight",l),M.hooks.run("complete",l),r&&r.call(l.element)}if(M.hooks.run("before-sanity-check",l),!l.code)return M.hooks.run("complete",l),void(r&&r.call(l.element));if(M.hooks.run("before-highlight",l),l.grammar)if(n&&u.Worker){var s=new Worker(M.filename);s.onmessage=function(e){o(e.data)},s.postMessage(JSON.stringify({language:l.language,code:l.code,immediateClose:!0}))}else o(M.highlight(l.code,l.grammar,l.language));else o(M.util.encode(l.code))},highlight:function(e,n,r){var t={code:e,grammar:n,language:r};return M.hooks.run("before-tokenize",t),t.tokens=M.tokenize(t.code,t.grammar),M.hooks.run("after-tokenize",t),W.stringify(M.util.encode(t.tokens),t.language)},tokenize:function(e,n){var r=n.rest;if(r){for(var t in r)n[t]=r[t];delete n.rest}var a=new i;return I(a,a.head,e),function e(n,r,t,a,i,l){for(var o in t)if(t.hasOwnProperty(o)&&t[o]){var s=t[o];s=Array.isArray(s)?s:[s];for(var u=0;u<s.length;++u){if(l&&l.cause==o+","+u)return;var c=s[u],g=c.inside,f=!!c.lookbehind,h=!!c.greedy,d=c.alias;if(h&&!c.pattern.global){var v=c.pattern.toString().match(/[imsuy]*$/)[0];c.pattern=RegExp(c.pattern.source,v+"g")}for(var p=c.pattern||c,m=a.next,y=i;m!==r.tail&&!(l&&y>=l.reach);y+=m.value.length,m=m.next){var k=m.value;if(r.length>n.length)return;if(!(k instanceof W)){var b,x=1;if(h){if(!(b=z(p,y,n,f)))break;var w=b.index,A=b.index+b[0].length,P=y;for(P+=m.value.length;P<=w;)m=m.next,P+=m.value.length;if(P-=m.value.length,y=P,m.value instanceof W)continue;for(var S=m;S!==r.tail&&(P<A||"string"==typeof S.value);S=S.next)x++,P+=S.value.length;x--,k=n.slice(y,P),b.index-=y}else if(!(b=z(p,0,k,f)))continue;var w=b.index,E=b[0],O=k.slice(0,w),L=k.slice(w+E.length),N=y+k.length;l&&N>l.reach&&(l.reach=N);var j=m.prev;O&&(j=I(r,j,O),y+=O.length),q(r,j,x);var C=new W(o,g?M.tokenize(E,g):E,d,E);if(m=I(r,j,C),L&&I(r,m,L),1<x){var _={cause:o+","+u,reach:N};e(n,r,t,m.prev,y,_),l&&_.reach>l.reach&&(l.reach=_.reach)}}}}}}(e,a,n,a.head,0),function(e){var n=[],r=e.head.next;for(;r!==e.tail;)n.push(r.value),r=r.next;return n}(a)},hooks:{all:{},add:function(e,n){var r=M.hooks.all;r[e]=r[e]||[],r[e].push(n)},run:function(e,n){var r=M.hooks.all[e];if(r&&r.length)for(var t,a=0;t=r[a++];)t(n)}},Token:W};function W(e,n,r,t){this.type=e,this.content=n,this.alias=r,this.length=0|(t||"").length}function z(e,n,r,t){e.lastIndex=n;var a=e.exec(r);if(a&&t&&a[1]){var i=a[1].length;a.index+=i,a[0]=a[0].slice(i)}return a}function i(){var e={value:null,prev:null,next:null},n={value:null,prev:e,next:null};e.next=n,this.head=e,this.tail=n,this.length=0}function I(e,n,r){var t=n.next,a={value:r,prev:n,next:t};return n.next=a,t.prev=a,e.length++,a}function q(e,n,r){for(var t=n.next,a=0;a<r&&t!==e.tail;a++)t=t.next;(n.next=t).prev=n,e.length-=a}if(u.Prism=M,W.stringify=function n(e,r){if("string"==typeof e)return e;if(Array.isArray(e)){var t="";return e.forEach(function(e){t+=n(e,r)}),t}var a={type:e.type,content:n(e.content,r),tag:"span",classes:["token",e.type],attributes:{},language:r},i=e.alias;i&&(Array.isArray(i)?Array.prototype.push.apply(a.classes,i):a.classes.push(i)),M.hooks.run("wrap",a);var l="";for(var o in a.attributes)l+=" "+o+'="'+(a.attributes[o]||"").replace(/"/g,""")+'"';return"<"+a.tag+' class="'+a.classes.join(" ")+'"'+l+">"+a.content+"</"+a.tag+">"},!u.document)return u.addEventListener&&(M.disableWorkerMessageHandler||u.addEventListener("message",function(e){var n=JSON.parse(e.data),r=n.language,t=n.code,a=n.immediateClose;u.postMessage(M.highlight(t,M.languages[r],r)),a&&u.close()},!1)),M;var e=M.util.currentScript();function r(){M.manual||M.highlightAll()}if(e&&(M.filename=e.src,e.hasAttribute("data-manual")&&(M.manual=!0)),!M.manual){var t=document.readyState;"loading"===t||"interactive"===t&&e&&e.defer?document.addEventListener("DOMContentLoaded",r):window.requestAnimationFrame?window.requestAnimationFrame(r):window.setTimeout(r,16)}return M}(_self);"undefined"!=typeof module&&module.exports&&(module.exports=Prism),"undefined"!=typeof global&&(global.Prism=Prism);
|
|
4
|
+
Prism.languages.markup={comment:/<!--[\s\S]*?-->/,prolog:/<\?[\s\S]+?\?>/,doctype:{pattern:/<!DOCTYPE(?:[^>"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|<!--(?:[^-]|-(?!->))*-->)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^<!|>$|[[\]]/,"doctype-tag":/^DOCTYPE/,name:/[^\s<>'"]+/}},cdata:/<!\[CDATA\[[\s\S]*?]]>/i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},Prism.languages.markup.tag.inside["attr-value"].inside.entity=Prism.languages.markup.entity,Prism.languages.markup.doctype.inside["internal-subset"].inside=Prism.languages.markup,Prism.hooks.add("wrap",function(a){"entity"===a.type&&(a.attributes.title=a.content.replace(/&/,"&"))}),Object.defineProperty(Prism.languages.markup.tag,"addInlined",{value:function(a,e){var s={};s["language-"+e]={pattern:/(^<!\[CDATA\[)[\s\S]+?(?=\]\]>$)/i,lookbehind:!0,inside:Prism.languages[e]},s.cdata=/^<!\[CDATA\[|\]\]>$/i;var n={"included-cdata":{pattern:/<!\[CDATA\[[\s\S]*?\]\]>/i,inside:s}};n["language-"+e]={pattern:/[\s\S]+/,inside:Prism.languages[e]};var t={};t[a]={pattern:RegExp("(<__[^>]*>)(?:<!\\[CDATA\\[(?:[^\\]]|\\](?!\\]>))*\\]\\]>|(?!<!\\[CDATA\\[)[^])*?(?=</__>)".replace(/__/g,function(){return a}),"i"),lookbehind:!0,greedy:!0,inside:n},Prism.languages.insertBefore("markup","cdata",t)}}),Prism.languages.html=Prism.languages.markup,Prism.languages.mathml=Prism.languages.markup,Prism.languages.svg=Prism.languages.markup,Prism.languages.xml=Prism.languages.extend("markup",{}),Prism.languages.ssml=Prism.languages.xml,Prism.languages.atom=Prism.languages.xml,Prism.languages.rss=Prism.languages.xml;
|
|
5
|
+
!function(s){var e=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;s.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+e.source+"|(?:[^\\\\\r\n()\"']|\\\\[^])*)\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+e.source+"$"),alias:"url"}}},selector:RegExp("[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+e.source+")*(?=\\s*\\{)"),string:{pattern:e,greedy:!0},property:/(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},s.languages.css.atrule.inside.rest=s.languages.css;var t=s.languages.markup;t&&(t.tag.addInlined("style","css"),s.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/(^|["'\s])style\s*=\s*(?:"[^"]*"|'[^']*')/i,lookbehind:!0,inside:{"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{style:{pattern:/(["'])[\s\S]+(?=["']$)/,lookbehind:!0,alias:"language-css",inside:s.languages.css},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},"attr-name":/^style/i}}},t.tag))}(Prism);
|
|
6
|
+
Prism.languages.clike={comment:[{pattern:/(^|[^\\])\/\*[\s\S]*?(?:\*\/|$)/,lookbehind:!0,greedy:!0},{pattern:/(^|[^\\:])\/\/.*/,lookbehind:!0,greedy:!0}],string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"class-name":{pattern:/(\b(?:class|interface|extends|implements|trait|instanceof|new)\s+|\bcatch\s+\()[\w.\\]+/i,lookbehind:!0,inside:{punctuation:/[.\\]/}},keyword:/\b(?:if|else|while|do|for|return|in|instanceof|function|new|try|throw|catch|finally|null|break|continue)\b/,boolean:/\b(?:true|false)\b/,function:/\w+(?=\()/,number:/\b0x[\da-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?/i,operator:/[<>]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/};
|
|
7
|
+
Prism.languages.javascript=Prism.languages.extend("clike",{"class-name":[Prism.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:/\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),Prism.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,Prism.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:Prism.languages.regex},"regex-flags":/[a-z]+$/,"regex-delimiter":/^\/|\/$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,inside:Prism.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:Prism.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:Prism.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),Prism.languages.insertBefore("javascript","string",{"template-string":{pattern:/`(?:\\[\s\S]|\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}|(?!\${)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\${(?:[^{}]|{(?:[^{}]|{[^}]*})*})+}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\${|}$/,alias:"punctuation"},rest:Prism.languages.javascript}},string:/[\s\S]+/}}}),Prism.languages.markup&&Prism.languages.markup.tag.addInlined("script","javascript"),Prism.languages.js=Prism.languages.javascript;
|
|
8
|
+
"undefined"!=typeof self&&self.Prism&&self.document&&document.createRange&&(Prism.plugins.KeepMarkup=!0,Prism.hooks.add("before-highlight",function(e){if(e.element.children.length&&Prism.util.isActive(e.element,"keep-markup",!0)){var a=0,s=[],l=function(e,n){var o={};n||(o.clone=e.cloneNode(!1),o.posOpen=a,s.push(o));for(var t=0,d=e.childNodes.length;t<d;t++){var r=e.childNodes[t];1===r.nodeType?l(r):3===r.nodeType&&(a+=r.data.length)}n||(o.posClose=a)};l(e.element,!0),s&&s.length&&(e.keepMarkup=s)}}),Prism.hooks.add("after-highlight",function(n){if(n.keepMarkup&&n.keepMarkup.length){var a=function(e,n){for(var o=0,t=e.childNodes.length;o<t;o++){var d=e.childNodes[o];if(1===d.nodeType){if(!a(d,n))return!1}else 3===d.nodeType&&(!n.nodeStart&&n.pos+d.data.length>n.node.posOpen&&(n.nodeStart=d,n.nodeStartPos=n.node.posOpen-n.pos),n.nodeStart&&n.pos+d.data.length>=n.node.posClose&&(n.nodeEnd=d,n.nodeEndPos=n.node.posClose-n.pos),n.pos+=d.data.length);if(n.nodeStart&&n.nodeEnd){var r=document.createRange();return r.setStart(n.nodeStart,n.nodeStartPos),r.setEnd(n.nodeEnd,n.nodeEndPos),n.node.clone.appendChild(r.extractContents()),r.insertNode(n.node.clone),r.detach(),!1}}return!0};n.keepMarkup.forEach(function(e){a(n.element,{node:e,pos:0})}),n.highlightedCode=n.element.innerHTML}}));
|