mirror of
https://github.com/lawrencehook/remove-youtube-suggestions.git
synced 2026-07-25 06:54:31 +00:00
Squashed commit of the following:
commit 42f6ef437a4054f2aed6467d8c85a8c1ec7f03c2
Author: Lawrence Hook <lawrencehook@gmail.com>
Date: Sun Dec 15 12:12:01 2024 -0500
Implement password removal. Fix button styling
commit 6503b2ac8460b148a17e42015a732b248048fa40
Author: Lawrence Hook <lawrencehook@gmail.com>
Date: Sun Dec 15 11:38:32 2024 -0500
Convert to password attributes to snake_case and add them to import/export.
commit 5f6f0e95e693a3ba8c2c59dc7311e30cd9af096d
Merge: 06edb5a e9b2af8
Author: Lawrence Hook <lawrencehook@gmail.com>
Date: Sat Dec 14 19:27:49 2024 -0500
Merge branch 'main' into feature/password
commit 06edb5a13151e6228723ecae409c75fea74ede37
Author: Lawrence Hook <lawrencehook@gmail.com>
Date: Sat Dec 14 19:26:54 2024 -0500
push progress on password feature
This commit is contained in:
+117
-2
@@ -57,7 +57,7 @@ html[foo="bar"] {
|
||||
margin-right: auto;
|
||||
padding: 5px 20px;
|
||||
|
||||
z-index: 11;
|
||||
z-index: 110;
|
||||
|
||||
color: var(--body-background-color);
|
||||
background-color: var(--body-color);
|
||||
@@ -275,6 +275,121 @@ html[schedule="false"] #schedule_container > *:not(#schedule_modal_header) {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
/* Password lock screen */
|
||||
html:not([password='true']) #password_lock_container,
|
||||
html[passwordentered='true'] #password_lock_container,
|
||||
html[foo=bar] {
|
||||
display: none;
|
||||
}
|
||||
#password_lock_container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
bottom: calc(var(--footer-height) + 3px);
|
||||
width: 100vw;
|
||||
z-index: 100;
|
||||
font-size: 1rem;
|
||||
|
||||
background-color: var(--body-background-color);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 15px;
|
||||
}
|
||||
#password_lock_container button {
|
||||
color: black;
|
||||
}
|
||||
|
||||
/* Password Modal */
|
||||
#password_container_background {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
z-index: 100;
|
||||
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
|
||||
display: flex;
|
||||
}
|
||||
|
||||
#password_container_background button {
|
||||
color: black;
|
||||
}
|
||||
|
||||
#enable_password_container, #enable_password_container * {
|
||||
color: var(--body-color);
|
||||
}
|
||||
|
||||
#enable_password_container, #disable_password_container {
|
||||
position: relative;
|
||||
|
||||
height: fit-content;
|
||||
width: min(90vw, 450px);
|
||||
margin-top: calc(1.2 * var(--header-height));
|
||||
margin-right: auto;
|
||||
margin-left: auto;
|
||||
padding: 20px 10px;
|
||||
|
||||
text-align: center;
|
||||
|
||||
background-color: var(--body-background-color);
|
||||
box-shadow: 0px 0px .5px .5px var(--box-shadow-color);
|
||||
box-sizing: border-box;
|
||||
|
||||
border: 1px solid var(--box-shadow-color);
|
||||
border-radius: 2px;
|
||||
|
||||
display: flex;
|
||||
gap: 20px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#password_modal_header {
|
||||
display: flex;
|
||||
gap: 15px;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
#password_modal_header div:first-child {
|
||||
font-size: 1.1rem;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#enable-password {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
#password-entries {
|
||||
font-size: 0.85rem;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: repeat(2, 1fr);
|
||||
grid-template-rows: repeat(2, 1fr);
|
||||
grid-gap: 10px;
|
||||
}
|
||||
|
||||
#password-entries > * {
|
||||
justify-self: start;
|
||||
}
|
||||
|
||||
#password-button button {
|
||||
color: var(--body-background-color);
|
||||
}
|
||||
|
||||
#disable_password_container a:first-child {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
|
||||
/* Menu Timer */
|
||||
#timer_container {
|
||||
position: fixed;
|
||||
@@ -285,7 +400,7 @@ html[schedule="false"] #schedule_container > *:not(#schedule_modal_header) {
|
||||
z-index: 100;
|
||||
font-size: 1rem;
|
||||
|
||||
background-color: rgba(255, 255, 255, 0.97);
|
||||
background-color: var(--body-background-color);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
<link rel="stylesheet" type="text/css" href="/options/body.css">
|
||||
<link rel="stylesheet" type="text/css" href="/options/footer.css">
|
||||
|
||||
<script defer src="/shared/md5.js"></script>
|
||||
<script defer src="/shared/main.js"></script>
|
||||
<script defer src="/shared/https.js"></script>
|
||||
<script defer src="/shared/analytics.js"></script>
|
||||
@@ -93,6 +94,32 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="password_container_background" hidden>
|
||||
|
||||
<div id="enable_password_container" hidden>
|
||||
<div id='password_modal_header'>
|
||||
<div>Lock RYS settings with a password.</div>
|
||||
</div>
|
||||
|
||||
<div id='password-entries'>
|
||||
<a>Enter Password</a>
|
||||
<input id="password-input-1" type='password'>
|
||||
<a>Re-enter Password</a>
|
||||
<input id="password-input-2" type='password'>
|
||||
</div>
|
||||
|
||||
<div id='password-button'><button disabled>Confirm</button></div>
|
||||
</div>
|
||||
|
||||
<div id='disable_password_container' hidden>
|
||||
<a>Password protection is enabled.</a>
|
||||
<a>To disable, re-enter below.</a>
|
||||
<input id='disable-password-input' type='password'>
|
||||
<button id='disable-password-button'>Remove Password</button>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<div id="timer_container">
|
||||
<div>Menu Timer</div>
|
||||
<div></div>
|
||||
@@ -105,6 +132,7 @@
|
||||
</div>
|
||||
|
||||
<div id='settings-menu' class='hidden'>
|
||||
<div id='settings-password'>Password</div>
|
||||
<div id='settings-schedule'>Schedule</div>
|
||||
<hr>
|
||||
<div id='import-settings'>Import settings</div>
|
||||
@@ -196,6 +224,12 @@
|
||||
<div id="disabled_message_open_schedule">Edit schedule</div>
|
||||
</div>
|
||||
|
||||
<div id="password_lock_container">
|
||||
<a>Enter Password.</a>
|
||||
<input id='unlock-password-input' type="password">
|
||||
<button id='unlock-password-button'>Confirm</button>
|
||||
</div>
|
||||
|
||||
<div id="main_container">
|
||||
|
||||
<div id="sidebar">
|
||||
|
||||
+112
-11
@@ -35,17 +35,17 @@ POWER_OPTIONS.forEach(o => {
|
||||
/**************
|
||||
* Scheduling *
|
||||
**************/
|
||||
const scheduleModalContainer = document.getElementById('schedule_container_background');
|
||||
const SCHEDULING_OPTION = document.getElementById('settings-schedule');
|
||||
const OPEN_SCHEDULE_OPTION = qs('#open-schedule');
|
||||
const RESUME_SCHEDULE_OPTION = qs('#resume-schedule');
|
||||
const scheduleToggleContainer = document.getElementById('enable-schedule');
|
||||
const scheduleToggle = scheduleToggleContainer.querySelector('svg');
|
||||
const SCHEDULE_TIMES = document.getElementById('schedule-times');
|
||||
const SCHEDULE_DAYS = document.getElementById('schedule-days');
|
||||
const SCHEDULE_DAYS_OPTIONS = qsa('div', SCHEDULE_DAYS);
|
||||
const TIME_PRESETS = qsa('#times-container .predefined-options a');
|
||||
const DAY_PRESETS = qsa('#days-container .predefined-options a');
|
||||
const scheduleModalContainer = qs('#schedule_container_background');
|
||||
const SCHEDULING_OPTION = qs('#settings-schedule');
|
||||
const OPEN_SCHEDULE_OPTION = qs('#open-schedule');
|
||||
const RESUME_SCHEDULE_OPTION = qs('#resume-schedule');
|
||||
const scheduleToggleContainer = qs('#enable-schedule');
|
||||
const scheduleToggle = qs('svg', scheduleToggleContainer);
|
||||
const SCHEDULE_TIMES = qs('#schedule-times');
|
||||
const SCHEDULE_DAYS = qs('#schedule-days');
|
||||
const SCHEDULE_DAYS_OPTIONS = qsa('div', SCHEDULE_DAYS);
|
||||
const TIME_PRESETS = qsa('#times-container .predefined-options a');
|
||||
const DAY_PRESETS = qsa('#days-container .predefined-options a');
|
||||
|
||||
function updateTimes(times) {
|
||||
SCHEDULE_TIMES.value = times;
|
||||
@@ -147,6 +147,107 @@ DAY_PRESETS.forEach(node => {
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/************
|
||||
* Password *
|
||||
************/
|
||||
const passwordModalContainer = qs('#password_container_background');
|
||||
const ENABLE_PASSWORD_CONTAINER = qs('#enable_password_container');
|
||||
const PASSWORD_OPTION = qs('#settings-password');
|
||||
const PASSWORD_INPUT1 = qs('#password-input-1');
|
||||
const PASSWORD_INPUT2 = qs('#password-input-2');
|
||||
const PASSWORD_BUTTON = qs('#password-button button');
|
||||
const UNLOCK_PASSWORD_INPUT = qs('#unlock-password-input');
|
||||
const UNLOCK_PASSWORD_BUTTON = qs('#unlock-password-button');
|
||||
const DISABLE_PASSWORD_CONTAINER = qs('#disable_password_container');
|
||||
const DISABLE_PASSWORD_INPUT = qs('#disable-password-input');
|
||||
const DISABLE_PASSWORD_BUTTON = qs('#disable-password-button');
|
||||
|
||||
function closePasswordModal() {
|
||||
passwordModalContainer.toggleAttribute('hidden', true);
|
||||
}
|
||||
passwordModalContainer.addEventListener('click', e => {
|
||||
if (e.target !== passwordModalContainer) return;
|
||||
closePasswordModal();
|
||||
});
|
||||
|
||||
function openPasswordModal() {
|
||||
passwordModalContainer.toggleAttribute('hidden', false);
|
||||
|
||||
PASSWORD_INPUT1.value = '';
|
||||
PASSWORD_INPUT2.value = '';
|
||||
|
||||
// Get local data.
|
||||
browser.storage.local.get(PASSWORD_SETTINGS, settings => {
|
||||
const { password, hashed_password } = settings;
|
||||
ENABLE_PASSWORD_CONTAINER.toggleAttribute('hidden', password);
|
||||
DISABLE_PASSWORD_CONTAINER.toggleAttribute('hidden', !password);
|
||||
});
|
||||
}
|
||||
PASSWORD_OPTION.addEventListener('click', e => {
|
||||
openPasswordModal();
|
||||
});
|
||||
|
||||
function lockWithPassword() {
|
||||
HTML.removeAttribute('passwordEntered');
|
||||
}
|
||||
function unlockWithPassword() {
|
||||
HTML.setAttribute('passwordEntered', 'true');
|
||||
}
|
||||
|
||||
PASSWORD_INPUT2.addEventListener('input', e => {
|
||||
const password = PASSWORD_INPUT1.value;
|
||||
const reentry = PASSWORD_INPUT2.value;
|
||||
const matching = password !== '' && password === reentry;
|
||||
PASSWORD_BUTTON.toggleAttribute('disabled', !matching);
|
||||
});
|
||||
|
||||
PASSWORD_BUTTON.addEventListener('click', e => {
|
||||
const password = PASSWORD_INPUT1.value;
|
||||
const reentry = PASSWORD_INPUT2.value;
|
||||
const matching = password !== '' && password === reentry;
|
||||
if (!matching) return;
|
||||
|
||||
// Set password.
|
||||
const hashed = md5(password);
|
||||
updateSetting('password', true, { manual: true });
|
||||
updateSetting('hashed_password', hashed, { manual: true });
|
||||
lockWithPassword();
|
||||
closePasswordModal();
|
||||
});
|
||||
|
||||
UNLOCK_PASSWORD_BUTTON.addEventListener('click', e => {
|
||||
const hashedInput = md5(UNLOCK_PASSWORD_INPUT.value);
|
||||
const hashedPassword = HTML.getAttribute('hashed_password');
|
||||
const matching = hashedInput === hashedPassword;
|
||||
|
||||
if (!matching) {
|
||||
displayStatus('Wrong password');
|
||||
} else {
|
||||
displayStatus('Unlocked');
|
||||
unlockWithPassword();
|
||||
}
|
||||
});
|
||||
|
||||
DISABLE_PASSWORD_BUTTON.addEventListener('click', e => {
|
||||
const password = DISABLE_PASSWORD_INPUT.value;
|
||||
const hashedInput = md5(password);
|
||||
const hashedPassword = HTML.getAttribute('hashed_password');
|
||||
const matching = hashedInput === hashedPassword;
|
||||
|
||||
if (!matching) {
|
||||
displayStatus('Wrong password');
|
||||
return;
|
||||
}
|
||||
|
||||
// Disable password settings.
|
||||
updateSetting('password', false, { manual: true });
|
||||
updateSetting('hashed_password', '', { manual: true });
|
||||
closePasswordModal();
|
||||
displayStatus('Password disabled');
|
||||
});
|
||||
|
||||
|
||||
// Logging toggle
|
||||
const LOG_ENABLE = document.getElementById('log-enable');
|
||||
LOG_ENABLE.addEventListener('click', e => {
|
||||
|
||||
@@ -594,12 +594,18 @@ const SCHEDULE_SETTINGS = {
|
||||
scheduleDays: 'mo,tu,we,th,fr',
|
||||
};
|
||||
|
||||
const PASSWORD_SETTINGS = {
|
||||
"password": false,
|
||||
"hashed_password": '',
|
||||
}
|
||||
|
||||
const OTHER_SETTINGS = {
|
||||
global_enable: true,
|
||||
dark_mode: false,
|
||||
log_enabled: true,
|
||||
...TIMED_SETTINGS,
|
||||
...SCHEDULE_SETTINGS,
|
||||
...PASSWORD_SETTINGS,
|
||||
};
|
||||
|
||||
const DEFAULT_SETTINGS = SECTIONS.reduce((acc, fieldset) => {
|
||||
@@ -695,6 +701,8 @@ const idToShortId = {
|
||||
"lock_code": '82',
|
||||
"remove_clip_button": '83',
|
||||
"shrink_video_thumbnails": '84',
|
||||
"password": '85',
|
||||
"hashed_password": '86',
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,186 @@
|
||||
/* Source: http://www.myersdaily.org/joseph/javascript/md5.js */
|
||||
|
||||
function md5cycle(x, k) {
|
||||
var a = x[0], b = x[1], c = x[2], d = x[3];
|
||||
|
||||
a = ff(a, b, c, d, k[0], 7, -680876936);
|
||||
d = ff(d, a, b, c, k[1], 12, -389564586);
|
||||
c = ff(c, d, a, b, k[2], 17, 606105819);
|
||||
b = ff(b, c, d, a, k[3], 22, -1044525330);
|
||||
a = ff(a, b, c, d, k[4], 7, -176418897);
|
||||
d = ff(d, a, b, c, k[5], 12, 1200080426);
|
||||
c = ff(c, d, a, b, k[6], 17, -1473231341);
|
||||
b = ff(b, c, d, a, k[7], 22, -45705983);
|
||||
a = ff(a, b, c, d, k[8], 7, 1770035416);
|
||||
d = ff(d, a, b, c, k[9], 12, -1958414417);
|
||||
c = ff(c, d, a, b, k[10], 17, -42063);
|
||||
b = ff(b, c, d, a, k[11], 22, -1990404162);
|
||||
a = ff(a, b, c, d, k[12], 7, 1804603682);
|
||||
d = ff(d, a, b, c, k[13], 12, -40341101);
|
||||
c = ff(c, d, a, b, k[14], 17, -1502002290);
|
||||
b = ff(b, c, d, a, k[15], 22, 1236535329);
|
||||
|
||||
a = gg(a, b, c, d, k[1], 5, -165796510);
|
||||
d = gg(d, a, b, c, k[6], 9, -1069501632);
|
||||
c = gg(c, d, a, b, k[11], 14, 643717713);
|
||||
b = gg(b, c, d, a, k[0], 20, -373897302);
|
||||
a = gg(a, b, c, d, k[5], 5, -701558691);
|
||||
d = gg(d, a, b, c, k[10], 9, 38016083);
|
||||
c = gg(c, d, a, b, k[15], 14, -660478335);
|
||||
b = gg(b, c, d, a, k[4], 20, -405537848);
|
||||
a = gg(a, b, c, d, k[9], 5, 568446438);
|
||||
d = gg(d, a, b, c, k[14], 9, -1019803690);
|
||||
c = gg(c, d, a, b, k[3], 14, -187363961);
|
||||
b = gg(b, c, d, a, k[8], 20, 1163531501);
|
||||
a = gg(a, b, c, d, k[13], 5, -1444681467);
|
||||
d = gg(d, a, b, c, k[2], 9, -51403784);
|
||||
c = gg(c, d, a, b, k[7], 14, 1735328473);
|
||||
b = gg(b, c, d, a, k[12], 20, -1926607734);
|
||||
|
||||
a = hh(a, b, c, d, k[5], 4, -378558);
|
||||
d = hh(d, a, b, c, k[8], 11, -2022574463);
|
||||
c = hh(c, d, a, b, k[11], 16, 1839030562);
|
||||
b = hh(b, c, d, a, k[14], 23, -35309556);
|
||||
a = hh(a, b, c, d, k[1], 4, -1530992060);
|
||||
d = hh(d, a, b, c, k[4], 11, 1272893353);
|
||||
c = hh(c, d, a, b, k[7], 16, -155497632);
|
||||
b = hh(b, c, d, a, k[10], 23, -1094730640);
|
||||
a = hh(a, b, c, d, k[13], 4, 681279174);
|
||||
d = hh(d, a, b, c, k[0], 11, -358537222);
|
||||
c = hh(c, d, a, b, k[3], 16, -722521979);
|
||||
b = hh(b, c, d, a, k[6], 23, 76029189);
|
||||
a = hh(a, b, c, d, k[9], 4, -640364487);
|
||||
d = hh(d, a, b, c, k[12], 11, -421815835);
|
||||
c = hh(c, d, a, b, k[15], 16, 530742520);
|
||||
b = hh(b, c, d, a, k[2], 23, -995338651);
|
||||
|
||||
a = ii(a, b, c, d, k[0], 6, -198630844);
|
||||
d = ii(d, a, b, c, k[7], 10, 1126891415);
|
||||
c = ii(c, d, a, b, k[14], 15, -1416354905);
|
||||
b = ii(b, c, d, a, k[5], 21, -57434055);
|
||||
a = ii(a, b, c, d, k[12], 6, 1700485571);
|
||||
d = ii(d, a, b, c, k[3], 10, -1894986606);
|
||||
c = ii(c, d, a, b, k[10], 15, -1051523);
|
||||
b = ii(b, c, d, a, k[1], 21, -2054922799);
|
||||
a = ii(a, b, c, d, k[8], 6, 1873313359);
|
||||
d = ii(d, a, b, c, k[15], 10, -30611744);
|
||||
c = ii(c, d, a, b, k[6], 15, -1560198380);
|
||||
b = ii(b, c, d, a, k[13], 21, 1309151649);
|
||||
a = ii(a, b, c, d, k[4], 6, -145523070);
|
||||
d = ii(d, a, b, c, k[11], 10, -1120210379);
|
||||
c = ii(c, d, a, b, k[2], 15, 718787259);
|
||||
b = ii(b, c, d, a, k[9], 21, -343485551);
|
||||
|
||||
x[0] = add32(a, x[0]);
|
||||
x[1] = add32(b, x[1]);
|
||||
x[2] = add32(c, x[2]);
|
||||
x[3] = add32(d, x[3]);
|
||||
|
||||
}
|
||||
|
||||
function cmn(q, a, b, x, s, t) {
|
||||
a = add32(add32(a, q), add32(x, t));
|
||||
return add32((a << s) | (a >>> (32 - s)), b);
|
||||
}
|
||||
|
||||
function ff(a, b, c, d, x, s, t) {
|
||||
return cmn((b & c) | ((~b) & d), a, b, x, s, t);
|
||||
}
|
||||
|
||||
function gg(a, b, c, d, x, s, t) {
|
||||
return cmn((b & d) | (c & (~d)), a, b, x, s, t);
|
||||
}
|
||||
|
||||
function hh(a, b, c, d, x, s, t) {
|
||||
return cmn(b ^ c ^ d, a, b, x, s, t);
|
||||
}
|
||||
|
||||
function ii(a, b, c, d, x, s, t) {
|
||||
return cmn(c ^ (b | (~d)), a, b, x, s, t);
|
||||
}
|
||||
|
||||
function md51(s) {
|
||||
txt = '';
|
||||
var n = s.length,
|
||||
state = [1732584193, -271733879, -1732584194, 271733878], i;
|
||||
for (i=64; i<=s.length; i+=64) {
|
||||
md5cycle(state, md5blk(s.substring(i-64, i)));
|
||||
}
|
||||
s = s.substring(i-64);
|
||||
var tail = [0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0];
|
||||
for (i=0; i<s.length; i++)
|
||||
tail[i>>2] |= s.charCodeAt(i) << ((i%4) << 3);
|
||||
tail[i>>2] |= 0x80 << ((i%4) << 3);
|
||||
if (i > 55) {
|
||||
md5cycle(state, tail);
|
||||
for (i=0; i<16; i++) tail[i] = 0;
|
||||
}
|
||||
tail[14] = n*8;
|
||||
md5cycle(state, tail);
|
||||
return state;
|
||||
}
|
||||
|
||||
/* there needs to be support for Unicode here,
|
||||
* unless we pretend that we can redefine the MD-5
|
||||
* algorithm for multi-byte characters (perhaps
|
||||
* by adding every four 16-bit characters and
|
||||
* shortening the sum to 32 bits). Otherwise
|
||||
* I suggest performing MD-5 as if every character
|
||||
* was two bytes--e.g., 0040 0025 = @%--but then
|
||||
* how will an ordinary MD-5 sum be matched?
|
||||
* There is no way to standardize text to something
|
||||
* like UTF-8 before transformation; speed cost is
|
||||
* utterly prohibitive. The JavaScript standard
|
||||
* itself needs to look at this: it should start
|
||||
* providing access to strings as preformed UTF-8
|
||||
* 8-bit unsigned value arrays.
|
||||
*/
|
||||
function md5blk(s) { /* I figured global was faster. */
|
||||
var md5blks = [], i; /* Andy King said do it this way. */
|
||||
for (i=0; i<64; i+=4) {
|
||||
md5blks[i>>2] = s.charCodeAt(i)
|
||||
+ (s.charCodeAt(i+1) << 8)
|
||||
+ (s.charCodeAt(i+2) << 16)
|
||||
+ (s.charCodeAt(i+3) << 24);
|
||||
}
|
||||
return md5blks;
|
||||
}
|
||||
|
||||
var hex_chr = '0123456789abcdef'.split('');
|
||||
|
||||
function rhex(n)
|
||||
{
|
||||
var s='', j=0;
|
||||
for(; j<4; j++)
|
||||
s += hex_chr[(n >> (j * 8 + 4)) & 0x0F]
|
||||
+ hex_chr[(n >> (j * 8)) & 0x0F];
|
||||
return s;
|
||||
}
|
||||
|
||||
function hex(x) {
|
||||
for (var i=0; i<x.length; i++)
|
||||
x[i] = rhex(x[i]);
|
||||
return x.join('');
|
||||
}
|
||||
|
||||
function md5(s) {
|
||||
return hex(md51(s));
|
||||
}
|
||||
|
||||
/* this function is much faster,
|
||||
so if possible we use it. Some IEs
|
||||
are the only ones I know of that
|
||||
need the idiotic second function,
|
||||
generated by an if clause. */
|
||||
|
||||
function add32(a, b) {
|
||||
return (a + b) & 0xFFFFFFFF;
|
||||
}
|
||||
|
||||
if (md5('hello') != '5d41402abc4b2a76b9719d911017c592') {
|
||||
function add32(x, y) {
|
||||
var lsw = (x & 0xFFFF) + (y & 0xFFFF),
|
||||
msw = (x >> 16) + (y >> 16) + (lsw >> 16);
|
||||
return (msw << 16) | (lsw & 0xFFFF);
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -118,8 +118,8 @@ function parseTimeRemaining(ms) {
|
||||
function hydrateDropdown(
|
||||
root,
|
||||
dropdown,
|
||||
show = d => d.removeAttribute('hidden'),
|
||||
hide = d => d.setAttribute('hidden', '')
|
||||
show = d => d.toggleAttribute('hidden', false),
|
||||
hide = d => d.toggleAttribute('hidden', true)
|
||||
) {
|
||||
|
||||
function clickListener(e) {
|
||||
|
||||
Reference in New Issue
Block a user