///
//
function ensureSetting(key: string, defaultValue: string): string {
let strValue = localStorage.getItem(key);
if (strValue === null) {
strValue = defaultValue;
localStorage.setItem(key, strValue);
}
return strValue;
}
const settings = new KeyValueStore({
wordWrap: {
value: ensureSetting('word-wrap', '1') === '1',
callbacks: [
value => {
localStorage.setItem('word-wrap', value ? '1' : '0');
}
],
valueRange: [false, true]
},
monospaceFont: {
value: ensureSetting('monospace-font', '1') === '1',
callbacks: [
value => {
localStorage.setItem('monospace-font', value ? '1' : '0');
}
],
valueRange: [false, true]
},
imagePreviews: {
value: ensureSetting('image-previews', '1') === '1',
callbacks: [
value => {
localStorage.setItem('image-previews', value ? '1' : '0');
}
],
valueRange: [false, true]
},
clickablePlainLinks: {
value: ensureSetting('clickable-plain-links', '1') === '1',
callbacks: [
value => {
localStorage.setItem('clickable-plain-links', value ? '1' : '0');
}
],
valueRange: [false, true]
},
});
//
(() => {
const linkQryEls = document.getElementsByClassName('link--QRY');
let i = linkQryEls.length;
while (i--) {
linkQryEls[i].addEventListener('click', e => {
e.preventDefault();
const resp = prompt('Please enter required input: ', '');
if ((resp !== null) && (resp !== "")) {
window.location.href = (e.target as HTMLAnchorElement).href + '?' + resp;
}
return false;
});
}
})();
(() => {
const locationPrefixEls = document.getElementsByClassName('location__prefix');
let i = locationPrefixEls.length;
while (i--) {
locationPrefixEls[i].addEventListener('click', e => {
e.preventDefault();
let resp = prompt('Please enter new location (gopher://... or gemini://...):', '');
if ((resp !== null) && (resp.trim() !== "")) {
resp = resp.trim();
if (resp.indexOf('gopher://') === 0) {
resp = 'gopher/' + resp.substring(9);
} else if (resp.indexOf('gemini://') === 0) {
resp = 'gemini/' + resp.substring(9);
} else {
resp = 'gopher/' + resp;
}
window.location.href = window.location.origin + '/' + resp;
}
return false;
});
}
})();
(() => {
const wrapEl = document.getElementsByClassName('wrap')[0];
const contentEl = wrapEl.getElementsByClassName('content')[0];
//
const settingImagePreviewEl = document.getElementsByClassName('setting--image-previews')[0];
const settingImagePreviewValueEl = settingImagePreviewEl.getElementsByClassName('setting__value')[0];
const settingImagePreviewCallback = (value: boolean, init = false) => {
if (value) {
generateImageThumbnails();
} else if (!init) {
removeImageThumbnails();
}
settingImagePreviewValueEl.textContent = value ? '[yes]' : '[no]';
}
settingImagePreviewValueEl.addEventListener('click', e => {
e.preventDefault();
settings.cycleValue('imagePreviews');
return false;
});
settingImagePreviewCallback(settings.getValue('imagePreviews'), true);
settings.addCallback('imagePreviews', settingImagePreviewCallback);
//
const settingMonospaceFontEl = document.getElementsByClassName('setting--monospace-font')[0];
const settingMonospaceFontValueEl = settingMonospaceFontEl.getElementsByClassName('setting__value')[0];
const settingMonospaceFontCallback = (value: boolean) => {
if (value) {
contentEl.classList.add("content--has-monospace-font");
} else {
contentEl.classList.remove("content--has-monospace-font");
}
settingMonospaceFontValueEl.textContent = value ? '[yes]' : '[no]';
}
settingMonospaceFontValueEl.addEventListener('click', e => {
e.preventDefault();
settings.cycleValue('monospaceFont');
return false;
});
settingMonospaceFontCallback(settings.getValue('monospaceFont'));
settings.addCallback('monospaceFont', settingMonospaceFontCallback);
//
const settingWordWrapEl = document.getElementsByClassName('setting--word-wrap')[0];
const settingWordWrapValueEl = settingWordWrapEl.getElementsByClassName('setting__value')[0];
const settingWordWrapCallback = (value: boolean) => {
if (value) {
wrapEl.classList.add("wrap--word-wrap");
} else {
wrapEl.classList.remove("wrap--word-wrap");
}
settingWordWrapValueEl.textContent = value ? '[yes]' : '[no]';
}
settingWordWrapValueEl.addEventListener('click', e => {
e.preventDefault();
settings.cycleValue('wordWrap');
return false;
});
settingWordWrapCallback(settings.getValue('wordWrap'));
settings.addCallback('wordWrap', settingWordWrapCallback);
//
const clickablePlainLinksEl = document.getElementsByClassName('setting--clickable-plain-links')[0];
const clickablePlainLinksValueEl = clickablePlainLinksEl.getElementsByClassName('setting__value')[0];
const clickablePlainLinksCallback = (value: boolean) => {
if (value) {
generateMarkupForPlainLinks();
} else {
removeMarkupForPlainLinks();
}
clickablePlainLinksValueEl.textContent = value ? '[yes]' : '[no]';
}
clickablePlainLinksValueEl.addEventListener('click', e => {
e.preventDefault();
settings.cycleValue('clickablePlainLinks');
return false;
});
clickablePlainLinksCallback(settings.getValue('clickablePlainLinks'));
settings.addCallback('clickablePlainLinks', clickablePlainLinksCallback);
})();
(() => {
const modalEls = document.getElementsByClassName('modal');
let i = modalEls.length;
while (i--) {
const modalEl = modalEls[i];
const modalContentEl = modalEl.getElementsByClassName('modal__content')[0];
const modalCloseBtnEl = modalEl.getElementsByClassName('modal__close-btn')[0];
document.addEventListener('click', e => {
if (!modalEl.classList.contains('modal--visible')) {
return;
}
if (e.target !== modalContentEl && !modalContentEl.contains(e.target as Element)) {
modalEl.classList.remove('modal--visible');
e.preventDefault();
e.stopPropagation();
}
}, true);
document.addEventListener('keydown', e => {
if (!modalEl.classList.contains('modal--visible')) {
return;
}
if (e.keyCode === 27) {
modalEl.classList.remove('modal--visible');
}
});
modalCloseBtnEl.addEventListener('click', e => {
e.preventDefault();
modalEl.classList.remove('modal--visible');
return false;
});
}
//
const settingsBtnEl = document.getElementsByClassName('settings-btn')[0];
const settingsModalEl = document.getElementsByClassName('modal--settings')[0];
settingsBtnEl.addEventListener('click', e => {
e.preventDefault();
settingsModalEl.classList.add('modal--visible');
return false;
});
})();
function generateImageThumbnails() {
const linkImgEls = document.querySelectorAll('.link--IMG, .link--GIF');
let i = linkImgEls.length;
while (i--) {
const linkImgEl = linkImgEls[i] as HTMLAnchorElement;
const thumbnailUrl = linkImgEl.href.replace(/^(.*?)\/I/, '$1/T');
const lineBreakEl = document.createTextNode('\n');
const typeAnnotEl = document.createElement('span');
typeAnnotEl.classList.add('type-annotation');
typeAnnotEl.textContent = ' -> ';
const thumbnailEl = document.createElement('img');
thumbnailEl.src = thumbnailUrl;
thumbnailEl.addEventListener('load', e => {
thumbnailEl.classList.remove('faded');
});
const thumbnailAnchorEl = document.createElement('a');
thumbnailAnchorEl.classList.add('img-preview');
thumbnailAnchorEl.href = linkImgEl.href;
thumbnailAnchorEl.addEventListener('click', e => {
e.preventDefault();
thumbnailEl.classList.add('faded');
if (thumbnailEl.classList.contains('expanded')) {
thumbnailEl.classList.remove('expanded');
thumbnailEl.src = thumbnailUrl;
} else {
thumbnailEl.classList.add('expanded');
thumbnailEl.src = thumbnailAnchorEl.href;
}
return false;
});
thumbnailAnchorEl.append(thumbnailEl);
linkImgEl.parentNode!.insertBefore(thumbnailAnchorEl, linkImgEl.nextSibling);
linkImgEl.parentNode!.insertBefore(typeAnnotEl, thumbnailAnchorEl);
linkImgEl.parentNode!.insertBefore(lineBreakEl, typeAnnotEl);
}
}
function removeImageThumbnails() {
const linkImgEls = document.querySelectorAll('.link--IMG, .link--GIF');
let i = linkImgEls.length;
while (i--) {
const linkImgEl = linkImgEls[i];
let j = 3;
while (j-- && linkImgEl.nextSibling) {
linkImgEl.nextSibling.remove();
}
}
}
function generateMarkupForPlainLinks() {
if (!document.body.classList.contains('is-plain')) {
return;
}
const contentEl = document.getElementsByClassName('content')[0];
const urlRegex = /\b[a-z]*:\/\/[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,}\b[-a-zA-Z0-9@:%_\+.,~#?&//=]*/g;
const mailRegex = /\bmailto:[-a-zA-Z0-9@:%._\+~#=]+@(?:[-a-zA-Z0-9@:%._\+~#=]+\.)+[a-z]{2,}\b/g;
contentEl.innerHTML = contentEl.innerHTML.replace(urlRegex, match => {
let href: string = match;
if (href.indexOf('gopher://') === 0) {
href = href.replace(/^gopher:\/\/(.*)$/, location.origin + '/gopher/$1');
} else if (href.indexOf('gemini://') === 0) {
href = href.replace(/^gemini:\/\/(.*)$/, location.origin + '/gemini/$1');
}
return `${match}`;
});
contentEl.innerHTML = contentEl.innerHTML.replace(mailRegex, match => {
return `${match}`;
});
}
function removeMarkupForPlainLinks() {
if (!document.body.classList.contains('is-plain')) {
return;
}
const contentEl = document.getElementsByClassName('content')[0];
const anchorEls = contentEl.getElementsByTagName('a');
let i = anchorEls.length;
while (i--) {
const anchorEl = anchorEls[i];
const textNodeEl = document.createTextNode(anchorEl.textContent!);
contentEl.replaceChild(textNodeEl, anchorEl);
}
}