diff --git a/.github/ISSUE_TEMPLATE/highlighting-bug-report.md b/.github/ISSUE_TEMPLATE/highlighting-bug-report.md index 7ca00dc6b3..1e8c5e6fde 100644 --- a/.github/ISSUE_TEMPLATE/highlighting-bug-report.md +++ b/.github/ISSUE_TEMPLATE/highlighting-bug-report.md @@ -13,8 +13,9 @@ assignees: '' - Plugins: [a list of plugins you are using or 'none'] **Description** @@ -22,6 +23,11 @@ A clear and concise description of what is being highlighted incorrectly and how **Code snippet** + +[Test page]() +
The code being highlighted incorrectly. diff --git a/test.html b/test.html index 55caccfcd7..1c2aef4da1 100644 --- a/test.html +++ b/test.html @@ -91,6 +91,44 @@ margin: 0 1px; } +#options { + position: relative; +} + +.share-wrapper { + position: absolute; + top: 0; + right: 0; + background-color: white; +} +.share-wrapper .hidden-wrapper { + display: none; +} + +.share-wrapper:hover { + top: -.5em; + right: -1em; + width: 300px; + padding: .5em 1em; + outline: 1px solid #888; +} +.share-wrapper:hover .hidden-wrapper { + display: block; +} + +.share-wrapper input { + width: 100%; + box-sizing: border-box; +} + +.share-wrapper button { + border: none; + background: none; + font: inherit; + text-decoration: underline; + cursor: pointer; +} + @@ -115,9 +153,16 @@

Test drive

Result:

-

+

-

+ +

Language:

@@ -151,18 +196,41 @@

Test drive

code = newCode; }; - +function getHashParams() { + return parseUrlParams((location.hash || '').substr(1)); +} +function setHashParams(params) { + location.hash = stringifyUrlParams(params); +} function updateHashLanguage(lang) { - location.hash = lang ? 'language=' + lang : ''; + var params = getHashParams(); + params.language = lang; + setHashParams(params); } function getHashLanguage() { - var match = /[#&]language=([^&]+)/.exec(location.hash); - return match ? match[1] : null; + return getHashParams().language; } function getRadio(lang) { return $('input[name=language][value="' + lang + '"]'); } +function copyShare() { + const link = $('#share-link').href; + try { + navigator.clipboard.writeText(link).then(function () { + $('#copy-share-link').textContent = 'Copied!'; + }, function () { + $('#copy-share-link').textContent = 'Failed to copy!'; + }); + } catch (e) { + $('#copy-share-link').textContent = 'Failed to copy!'; + } + setTimeout(function () { + $('#copy-share-link').textContent = 'Copy to clipboard'; + }, 5000); +} +window.copyShare = copyShare; + window.onhashchange = function () { var input = getRadio(getHashLanguage()); @@ -196,6 +264,7 @@

Test drive

code.className = 'language-' + lang; code.textContent = code.textContent; updateHashLanguage(lang); + updateShareLink(); // loadLanguage() returns a promise, so we use highlightCode() // as resolve callback. The promise will be immediately @@ -277,9 +346,14 @@

Test drive

var textarea = $('textarea', form); try { - var lastCode = sessionStorage.getItem('test-code'); - if (lastCode) { - textarea.value = lastCode; + var hashText = getHashParams().text; + if (hashText) { + textarea.value = hashText; + } else { + var lastCode = sessionStorage.getItem('test-code'); + if (lastCode) { + textarea.value = lastCode; + } } } catch (e) { // ignore sessionStorage errors @@ -290,6 +364,8 @@

Test drive

code.textContent = codeText; highlightCode(); + updateShareLink(); + try { sessionStorage.setItem('test-code', codeText); } catch (error) { @@ -308,8 +384,57 @@

Test drive

}; $('#option-show-tokens').onchange(); -})(); +function updateShareLink() { + var params = { + language: /\blang(?:uage)?-([\w-]+)\b/i.exec(code.className)[1], + text: code.textContent, + }; + $('#share-link').href = '#' + stringifyUrlParams(params); + $('#share-link-input').value = $('#share-link').href; +} + + +/** + * @param {Record} params + * @returns {string} + */ +function stringifyUrlParams(params) { + var parts = []; + for (var name in params) { + if (params.hasOwnProperty(name)) { + var value = params[name]; + if (typeof value === 'boolean') { + if (value) { + parts.push(name); + } + } else { + parts.push(name + '=' + encodeURIComponent(value)); + } + } + } + return parts.join('&'); +} +/** + * @param {string} str + * @returns {Record} + */ +function parseUrlParams(str) { + /** @type {Record} */ + var params = {}; + str.split(/&/g).filter(Boolean).forEach(function (part) { + var parts = part.split(/=/); + var name = parts[0]; + if (parts.length === 1) { + params[name] = true; + } else { + params[name] = decodeURIComponent(parts[1]); + } + }); + return params; +} + +})();