Кроссбразуреная, кросплатформенная особенность задания (set) Node.textContent:
<a href="javascript:document.body.textContent = '<div>text</div>';">click</a>
Вставит строчку как html код:
<div>text</div>
Вступление
Для создания пароля можно использовать любые ASCII символы в диапазоне 32-126. Один из этих символов — знак меньше ("<"). Для удобства генерации пароля создал закладку (bookmark) в бразуре, в которой в url вместо ссылки на страницу используется протокол javascript.
JS генерирует пароль длиной n из набора доступных ASCII символов и вставляет в документ получившуюся строку с помощью document.body.textContent.
javascript:for(var a=[],i=0;i<95;i++)a.push(String.fromCharCode(32 + i));for(var b="",i=0;i<16;i++)b+=a[Math.floor(Math.random()*95)];document.body.textContent = b;
document.body.textContent = createPassword(); function createPassword() { var PASSWORD_LENGTH = 16; var random = Math.random; var allowedChars = getAllowedCharsArr(); for (var password = "", i = 0; i < PASSWORD_LENGTH; i++) { var randomIndex = Math.floor(random() * allowedChars.length); password += allowedChars[randomIndex] } return password; } function getAllowedCharsArr() { var FIRST_ALLOWED_ASCII_CHAR_INDEX = 32; var ALLOWED_CHARS_COUNT = 95; for (var allowedChars = [], i = 0; i < ALLOWED_CHARS_COUNT; i++) { var asciiCode = FIRST_ALLOWED_ASCII_CHAR_INDEX + i; var char = String.fromCharCode(asciiCode); allowedChars.push(char) } return allowedChars; }
Обнаружение
После некоторого использования закладки заметил, что иногда пароль отображается не полностью, т.е. первые k символов из всех, заранее заданых n.
Изучение
После некоторого изучения получил следующий код:
document.body.textContent = '<div>text</div>';
Если его запустить в консоли браузера, или в script теге html, javascript отработает как надо, т.е. вставит строку вместе с символами "<" и ">".
<div>text</div>
Особенность
Но если этот же код выполнить в протоколе javascript в документе окажется html элемент:
<a href="javascript:document.body.textContent = '<div>text</div>';">click</a>
<div>text</div>
Эфимерность
Причём если сохранить ссылку на переменную:
<a href="javascript:var str='<div>text</div>';document.body.textContent = str;window.test=function(){str}">click</a>
Текст вставиться как надо:
<div>text</div>
Применение
На сайтах, где пользовательский текст вставляется через протокол javascript с использованием Node.textContent или Node.innerText для исполнения своих скриптов через тег script.
Решение
Для себя более удобным стало не вставлять текст в DOM а сразу копировать пароль в буффер обмена.
javascript:for(var a=[],i=0;i<95;i++)a.push(String.fromCharCode(32 + i));for(var b="",i=0;i<16;i++)b+=a[Math.floor(Math.random()*95)];var c=document.createElement('input');c.style.opacity=0;document.body.appendChild(c); c.value=b;c.style.position='fixed';c.style.zIndex=1000000;c.focus();c.select(); document.execCommand('Copy');c.remove();
copyToClipBoard(createPassword()); function copyToClipBoard(str) { var input = document.createElement('textarea'); document.body.appendChild(input); input.value = str; input.style.position = 'fixed'; input.style.zIndex = 1000000; input.style.opacity = 0; input.focus(); input.select(); document.execCommand('Copy'); input.remove(); } function createPassword() { var PASSWORD_LENGTH = 16; var random = Math.random; var allowedChars = getAllowedCharsArr(); for (var password = "", i = 0; i < PASSWORD_LENGTH; i++) { var randomIndex = Math.floor(random() * allowedChars.length); password += allowedChars[randomIndex] } return password; } function getAllowedCharsArr() { var FIRST_ALLOWED_ASCII_CHAR_INDEX = 32; var ALLOWED_CHARS_COUNT = 95; for (var allowedChars = [], i = 0; i < ALLOWED_CHARS_COUNT; i++) { var asciiCode = FIRST_ALLOWED_ASCII_CHAR_INDEX + i; var char = String.fromCharCode(asciiCode); allowedChars.push(char) } return allowedChars; }
P.S.: Вместо циклов можно использовать Array.map. Кто-то считает, что так элегантнее, кто-то замечает, что это медленнее — это уже дело вкуса.
javascript:var a = Array.apply(null, Array(127)).map(String.fromCharCode, String).slice(32);var b = Array.apply(null, Array(16)).map(() => a[Math.floor(Math.random() * 95)]).join("");var c = document.createElement('input');document.body.appendChild(c);c.value = b;c.style.position = 'fixed';c.style.zIndex = 1000000;c.style.opacity = 0;c.focus();c.select();document.execCommand('Copy');c.remove();
P.P.S.: Вместо закладки можно использовать extenshion: например, chrome — это также дело вкуса.
ссылка на оригинал статьи http://habrahabr.ru/post/272189/
Добавить комментарий