MediaWiki:Common.js: различия между версиями
Hloth (обсуждение | вклад) Нет описания правки |
Hloth (обсуждение | вклад) Нет описания правки |
||
| Строка 3: | Строка 3: | ||
} | } | ||
const | const decodeCyrillic = (url) => { | ||
if( | return url.replace(/%[0-9A-F]{2}/gi, (match) => { | ||
try { | |||
const char = decodeURIComponent(match) | |||
return /[\u0400-\u04FF]/.test(char) ? char : match | |||
} catch { | |||
return match | |||
} | |||
}) | |||
} | |||
const copyLink = document.querySelector('nav#p-tb ul #t-page-link') | |||
let copyLinkTimeout | |||
if(copyLink) { | |||
copyLink.addEventListener('click', e => { | |||
copy(decodeCyrillic(window.document.location.href)) | |||
e.target.textContent = 'Ссылка скопирована!' | |||
if(copyLinkTimeout !== undefined) clearTimeout(copyLinkTimeout) | |||
copyLinkTimeout = setTimeout(() => { | |||
e.textContent = 'Скопировать ссылку' | |||
}, 3000) | |||
}) | |||
} | |||
// ====== https://github.com/sudodoki/copy-to-clipboard/blob/main/index.js ====== | |||
// ====== https://github.com/sudodoki/toggle-selection/blob/gh-pages/index.js ====== | |||
var deselectCurrent = () => { | |||
var selection = document.getSelection(); | |||
if (!selection.rangeCount) { | |||
return function () {}; | |||
} | |||
var active = document.activeElement; | |||
var ranges = []; | |||
for (var i = 0; i < selection.rangeCount; i++) { | |||
ranges.push(selection.getRangeAt(i)); | |||
} | |||
switch ( | |||
active.tagName.toUpperCase() // .toUpperCase handles XHTML | |||
) { | |||
case "INPUT": | |||
case "TEXTAREA": | |||
active.blur(); | |||
break; | |||
default: | |||
active = null; | |||
break; | |||
} | |||
selection.removeAllRanges(); | |||
return function () { | |||
if(selection.type === "Caret") selection.removeAllRanges(); | |||
if (!selection.rangeCount) { | |||
ranges.forEach(function (range) { | |||
selection.addRange(range); | |||
}); | |||
} | |||
if(active) active.focus(); | |||
}; | |||
}; | |||
var clipboardToIE11Formatting = { | |||
"text/plain": "Text", | |||
"text/html": "Url", | |||
default: "Text", | |||
}; | |||
var defaultMessage = "Copy to clipboard: #{key}, Enter"; | |||
function format(message) { | |||
var copyKey = (/mac os x/i.test(navigator.userAgent) ? "⌘" : "Ctrl") + "+C"; | |||
return message.replace(/#{\s*key\s*}/g, copyKey); | |||
} | |||
function copy(text, options) { | |||
var debug, | |||
message, | |||
reselectPrevious, | |||
range, | |||
selection, | |||
mark, | |||
success = false; | |||
if (!options) { | |||
options = {}; | |||
} | |||
debug = options.debug || false; | |||
try { | |||
reselectPrevious = deselectCurrent(); | |||
range = document.createRange(); | |||
selection = document.getSelection(); | |||
mark = document.createElement("span"); | |||
mark.textContent = text; | |||
// avoid screen readers from reading out loud the text | |||
mark.ariaHidden = "true"; | |||
// reset user styles for span element | |||
mark.style.all = "unset"; | |||
// prevents scrolling to the end of the page | |||
mark.style.position = "fixed"; | |||
mark.style.top = 0; | |||
mark.style.clip = "rect(0, 0, 0, 0)"; | |||
// used to preserve spaces and line breaks | |||
mark.style.whiteSpace = "pre"; | |||
// do not inherit user-select (it may be `none`) | |||
mark.style.webkitUserSelect = "text"; | |||
mark.style.MozUserSelect = "text"; | |||
mark.style.msUserSelect = "text"; | |||
mark.style.userSelect = "text"; | |||
mark.addEventListener("copy", function (e) { | |||
e.stopPropagation(); | |||
if (options.format) { | |||
e.preventDefault(); | |||
if (typeof e.clipboardData === "undefined") { | |||
// IE 11 | |||
if(debug) console.warn("unable to use e.clipboardData"); | |||
if(debug) console.warn("trying IE specific stuff"); | |||
window.clipboardData.clearData(); | |||
var format = | |||
clipboardToIE11Formatting[options.format] || | |||
clipboardToIE11Formatting["default"]; | |||
window.clipboardData.setData(format, text); | |||
} else { | |||
// all other browsers | |||
e.clipboardData.clearData(); | |||
e.clipboardData.setData(options.format, text); | |||
} | |||
} | |||
if (options.onCopy) { | |||
e.preventDefault(); | |||
options.onCopy(e.clipboardData); | |||
} | |||
}); | |||
document.body.appendChild(mark); | |||
range.selectNodeContents(mark); | |||
selection.addRange(range); | |||
var successful = document.execCommand("copy"); | |||
if (!successful) { | |||
throw new Error("copy command was unsuccessful"); | |||
} | |||
success = true; | |||
} catch (err) { | |||
if(debug) console.error("unable to copy using execCommand: ", err); | |||
if(debug) console.warn("trying IE specific stuff"); | |||
try { | |||
window.clipboardData.setData(options.format || "text", text); | |||
if(options.onCopy) options.onCopy(window.clipboardData); | |||
success = true; | |||
} catch (err) { | |||
if(debug) console.error("unable to copy using clipboardData: ", err); | |||
if(debug) console.error("falling back to prompt"); | |||
message = format("message" in options ? options.message : defaultMessage); | |||
window.prompt(message, text); | |||
} | |||
} finally { | |||
if (selection) { | |||
if (typeof selection.removeRange == "function") { | |||
selection.removeRange(range); | |||
} else { | |||
selection.removeAllRanges(); | |||
} | |||
} | |||
if (mark) { | |||
document.body.removeChild(mark); | |||
} | |||
reselectPrevious(); | |||
} | |||
return success; | |||
} | } | ||