Remove font awesome, use utf-8 icons instead

This commit is contained in:
Tuxedo Takodachi 2023-04-29 20:36:23 +02:00
parent be62c12b9e
commit 0c2d652e85
24 changed files with 67 additions and 157 deletions

View File

@ -72,8 +72,5 @@
* src/Monitoring/ThreadUpdater/beep.wav from http://freesound.org/people/pierrecartoons1979/sounds/90112/
* cc-by-nc-3.0
*
* Font Awesome by Dave Gandy (http://fontawesome.io)
* license: http://fontawesome.io/license/
*
* Icons used to identify various websites are property of the respective websites.
*/

14
package-lock.json generated
View File

@ -1,10 +1,10 @@
{
"name": "4chan-X",
"name": "4chan-XT",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "4chan-X",
"name": "4chan-XT",
"license": "MIT",
"devDependencies": {
"@rollup/plugin-typescript": "^11.0.0",
@ -14,7 +14,6 @@
"@violentmonkey/types": "^0.1.5",
"chrome-webstore-upload": "^1.0.0",
"esprima": "^4.0.1",
"font-awesome": "=4.7.0",
"jshint": "^2.13.4",
"jszip": "^3.10.0",
"lodash.template": "^4.5.0",
@ -577,15 +576,6 @@
"integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
"dev": true
},
"node_modules/font-awesome": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/font-awesome/-/font-awesome-4.7.0.tgz",
"integrity": "sha512-U6kGnykA/6bFmg1M/oT9EkFeIYv7JlX3bozwQJWiiLz6L0w3F5vBVPxHlwyX/vtNq1ckcpRKOB9f2Qal/VtFpg==",
"dev": true,
"engines": {
"node": ">=0.10.3"
}
},
"node_modules/forever-agent": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",

View File

@ -108,7 +108,6 @@
"@violentmonkey/types": "^0.1.5",
"chrome-webstore-upload": "^1.0.0",
"esprima": "^4.0.1",
"font-awesome": "=4.7.0",
"jshint": "^2.13.4",
"jszip": "^3.10.0",
"lodash.template": "^4.5.0",

View File

@ -213,10 +213,8 @@ var PostHiding = {
makeButton(post, type) {
const span = $.el('span', {
className: `fa fa-${type === 'hide' ? 'minus' : 'plus'}-square-o`,
textContent: ""
}
);
textContent: type === 'hide' ? '' : '',
});
const a = $.el('a', {
className: `${type}-reply-button`,
href: 'javascript:;'
@ -247,7 +245,7 @@ var PostHiding = {
toggle() {
const post = Get.postFromNode(this);
PostHiding[(post.isHidden ? 'show' : 'hide')](post);
PostHiding[(post.isHidden ? 'show' : 'hide')](post);
return PostHiding.saveHiddenState(post, post.isHidden);
},

View File

@ -137,7 +137,7 @@ var ThreadHiding = {
href: 'javascript:;'
}
);
$.on(div, 'click', ThreadHiding.menu.show);
$.on(div, 'click', ThreadHiding.menu.show);
Menu.menu.addEntry({
el: div,
@ -200,7 +200,7 @@ var ThreadHiding = {
href: 'javascript:;'
}
);
$.extend(a, {innerHTML: "<span class=\"fa fa-" + ((type === "hide") ? "minus" : "plus") + "-square\"></span>"});
$.extend(a, {textContent: type === "hide" ? '' : '' });
a.dataset.fullID = thread.fullID;
$.on(a, 'click', ThreadHiding.toggle);
return a;

View File

@ -143,7 +143,7 @@ var Header = {
const cs = $.el('a', {href: 'javascript:;'});
if (g.VIEW === 'catalog') {
cs.title = (cs.textContent = 'Catalog Settings');
cs.className = 'fa fa-book';
cs.textContent = '🕮︎';
} else {
cs.title = (cs.textContent = '4chan Settings');
cs.className = 'native-settings';

View File

@ -82,10 +82,9 @@ var Index = {
// Header refresh button
this.button = $.el('a', {
className: 'fa fa-refresh',
title: 'Refresh',
href: 'javascript:;',
textContent: 'Refresh Index'
textContent: '🗘'
}
);
$.on(this.button, 'click', () => Index.update());
@ -768,14 +767,14 @@ var Index = {
'Index',
Index.load
);
return $.addClass(Index.button, 'fa-spin');
return $.addClass(Index.button, 'spin');
},
load() {
let err;
if (this !== Index.req) { return; } // aborted
$.rmClass(Index.button, 'fa-spin');
$.rmClass(Index.button, 'spin');
const {notice, nTimeout} = Index;
if (nTimeout) { clearTimeout(nTimeout); }
delete Index.nTimeout;

View File

@ -38,8 +38,8 @@ var Settings = {
init() {
// 4chan X settings link
const link = $.el('a', {
className: 'settings-link fa fa-wrench',
textContent: 'Settings',
className: 'settings-link',
textContent: '🔧︎',
title: `${meta.name} Settings`,
href: 'javascript:;'
}

View File

@ -17,7 +17,7 @@ const settingsHtml = <div id="fourchanx-settings" class="dialog">
<a href={meta.page} target="_blank">{meta.name}</a>{separator}
<a href={meta.changelog} target="_blank">{g.VERSION}</a>{separator}
<a href={meta.issues} target="_blank">Issues</a>{separator}
<a href="javascript:;" class="close fa fa-times" title="Close"></a>
<a href="javascript:;" class="close" title="Close"></a>
</div>
</nav>
<div class="section-container"><section></section></div>

View File

@ -30,10 +30,8 @@ var Gallery = {
const el = $.el('a', {
href: 'javascript:;',
title: 'Gallery',
className: 'fa fa-picture-o',
textContent: 'Gallery'
}
);
textContent: '🖼︎',
});
$.on(el, 'click', this.cb.toggle);

View File

@ -21,8 +21,8 @@ var ImageExpand = {
if (!(this.enabled = Conf['Image Expansion'] && ['index', 'thread'].includes(g.VIEW))) { return; }
this.EAI = $.el('a', {
className: 'expand-all-shortcut fa fa-expand',
textContent: 'EAI',
className: 'expand-all-shortcut',
textContent: '',
title: 'Expand All Images',
href: 'javascript:;'
}
@ -44,7 +44,7 @@ var ImageExpand = {
if (!this.file || (!this.file.isImage && !this.file.isVideo)) { return; }
$.on(this.file.thumbLink, 'click', ImageExpand.cb.toggle);
if (this.isClone) {
if (this.isClone) {
if (this.file.isExpanding) {
// If we clone a post where the image is still loading,
// make it loading in the clone too.
@ -96,12 +96,14 @@ var ImageExpand = {
};
if (ImageExpand.on = $.hasClass(ImageExpand.EAI, 'expand-all-shortcut')) {
ImageExpand.EAI.className = 'contract-all-shortcut fa fa-compress';
ImageExpand.EAI.title = 'Contract All Images';
ImageExpand.EAI.className = 'contract-all-shortcut';
ImageExpand.EAI.title = 'Contract All Images';
ImageExpand.EAI.textContent = '';
func = ImageExpand.expand;
} else {
ImageExpand.EAI.className = 'expand-all-shortcut fa fa-expand';
ImageExpand.EAI.title = 'Expand All Images';
ImageExpand.EAI.className = 'expand-all-shortcut';
ImageExpand.EAI.title = 'Expand All Images';
ImageExpand.EAI.textContent = '';
func = ImageExpand.contract;
}

View File

@ -35,8 +35,7 @@ var ImageLoader = {
const el = $.el('a', {
href: 'javascript:;',
title: 'Prefetch Images',
className: 'fa fa-bolt disabled',
textContent: 'Prefetch'
innerHTML: '🗲︎'
}
);

View File

@ -18,7 +18,7 @@ var Menu = {
}
);
$.extend(this.button, {innerHTML: "<i class=\"fa fa-angle-down\"></i>"});
$.extend(this.button, {textContent: "🞃"});
this.menu = new UI.Menu('post');
Callbacks.Post.push({

View File

@ -82,9 +82,9 @@ var FileInfo = {
}
},
N() { return { innerHTML: E(this.file.name), [isEscaped]: true }; },
d() { return <a href={this.file.url} download={this.file.name} class="fa fa-download download-button"></a> },
d() { return <a href={this.file.url} download={this.file.name} class="download-button">📥</a> },
f() {
return { innerHTML: "<a href=\"javascript:;\" class=\"fa fa-times quick-filter-md5\"></a>", [isEscaped]: true };
return { innerHTML: "<a href=\"javascript:;\" class=\"quick-filter-md5\"></a>", [isEscaped]: true };
},
p() { return { innerHTML: ((this.file.isSpoiler) ? "Spoiler, " : ""), [isEscaped]: true }; },
s() { return { innerHTML: E(this.file.size), [isEscaped]: true }; },

View File

@ -40,9 +40,10 @@ var PSAHiding = {
$.on(entry.el, 'click', PSAHiding.toggle);
PSAHiding.btn = (btn = $.el('a', {
title: 'Mark announcement as read and hide.',
className: 'hide-announcement-button fa fa-minus-square',
href: 'javascript:;'
title: 'Mark announcement as read and hide.',
className: 'hide-announcement-button',
href: 'javascript:;',
textContent: '',
}
));
$.on(btn, 'click', PSAHiding.toggle);

View File

@ -36,11 +36,10 @@ var ThreadWatcher = {
if (!(this.enabled = Conf['Thread Watcher'])) { return; }
this.shortcut = (sc = $.el('a', {
id: 'watcher-link',
textContent: 'Watcher',
title: 'Thread Watcher',
href: 'javascript:;',
className: 'fa fa-eye'
id: 'watcher-link',
textContent: '👁︎',
title: 'Thread Watcher',
href: 'javascript:;',
}
));
@ -276,7 +275,7 @@ var ThreadWatcher = {
fetch(url, {siteID, force}, args, cb) {
if (ThreadWatcher.requests.length === 0) {
ThreadWatcher.status.textContent = '...';
$.addClass(ThreadWatcher.refreshButton, 'fa-spin');
$.addClass(ThreadWatcher.refreshButton, 'spin');
}
const onloadend = function() {
if (this.finished) { return; }
@ -306,7 +305,7 @@ var ThreadWatcher = {
ThreadWatcher.requests = [];
ThreadWatcher.fetched = 0;
ThreadWatcher.status.textContent = '';
return $.rmClass(ThreadWatcher.refreshButton, 'fa-spin');
return $.rmClass(ThreadWatcher.refreshButton, 'spin');
},
abort() {
@ -361,7 +360,7 @@ var ThreadWatcher = {
fetchAllStatus(interval=0) {
ThreadWatcher.status.textContent = '...';
$.addClass(ThreadWatcher.refreshButton, 'fa-spin');
$.addClass(ThreadWatcher.refreshButton, 'spin');
ThreadWatcher.syncing = true;
const dbs = [ThreadWatcher.db, ThreadWatcher.unreaddb, QuoteYou.db].filter(x => x);
let n = 0;
@ -572,7 +571,7 @@ var ThreadWatcher = {
makeLine(siteID, boardID, threadID, data) {
let page;
const x = $.el('a', {
className: 'fa fa-times',
textContent: '✕',
href: 'javascript:;'
}
);

View File

@ -1,7 +1,7 @@
<div class="move">
Thread Watcher <a class="refresh fa fa-refresh" title="Check threads" href="javascript:;"></a>
Thread Watcher <a class="refresh" title="Check threads" href="javascript:;">🗘</a>
<span id="watcher-status"></span>
<a class="menu-button" href="javascript:;"><i class="fa fa-angle-down"></i></a>
<a class="menu-button" href="javascript:;">🞃</a>
<a class="close" href="javascript:;">×</a>
</div>
<div id="watched-threads"></div>

View File

@ -64,8 +64,8 @@ var QR = {
});
this.shortcut = (sc = $.el('a', {
className: 'fa fa-comment-o disabled',
textContent: 'QR',
className: 'disabled',
textContent: '',
title: 'Quick Reply',
href: 'javascript:;'
}
@ -1646,7 +1646,7 @@ var QR = {
href: 'javascript:;'
}
);
$.extend(el, { innerHTML: '<a class="remove fa fa-times-circle" title="Remove"></a><label class="qr-preview-spoiler"><input type="checkbox"> Spoiler</label><span></span>' });
$.extend(el, { innerHTML: '<a class="remove" title="Remove"></a><label class="qr-preview-spoiler"><input type="checkbox"> Spoiler</label><span></span>' });
this.nodes = {
el,

View File

@ -40,12 +40,12 @@
<input type="checkbox" id="qr-file-spoiler" title="Spoiler image">
<a class="checkbox-letter">S</a>
</label>
<a id="qr-oekaki-button" title="Edit in Tegaki"><i class="fa fa-edit"></i></a>
<a href="javascript:;" id="qr-filerm" title="Remove file"><i class="fa fa-times-circle"></i></a>
<a id="url-button" title="Post from URL"><i class="fa fa-link"></i></a>
<a hidden id="paste-area" title="Select to paste images" class="fa fa-clipboard" tabindex="-1" contentEditable="true"></a>
<a id="custom-cooldown-button" title="Toggle custom cooldown" class="disabled"><i class="fa fa-clock-o"></i></a>
<a id="dump-button" title="Dump list"><i class="fa fa-plus-square"></i></a>
<a id="qr-oekaki-button" title="Edit in Tegaki">✎︎</a>
<a href="javascript:;" id="qr-filerm" title="Remove file"></a>
<a id="url-button" title="Post from URL">🔗︎</a>
<a hidden id="paste-area" title="Select to paste images" tabindex="-1" contentEditable="true">📋︎</a>
<a id="custom-cooldown-button" title="Toggle custom cooldown" class="disabled">🕒︎</a>
<a id="dump-button" title="Dump list">+</a>
</span>
<input type="submit">
</div>
@ -62,4 +62,4 @@
</form>
<datalist id="list-name"></datalist>
<datalist id="list-email"></datalist>
<datalist id="list-sub"></datalist>
<datalist id="list-sub"></datalist>

View File

@ -15,7 +15,7 @@ export default class Notice {
this.timeout = timeout;
this.onclose = onclose;
this.el = $.el('div',
{innerHTML: "<a href=\"javascript:;\" class=\"close fa fa-times\" title=\"Close\"></a><div class=\"message\"></div>"});
{innerHTML: "<a href=\"javascript:;\" class=\"close\" title=\"Close\"></a><div class=\"message\"></div>"});
this.el.style.opacity = 0;
this.setType(type);
$.on(this.el.firstElementChild, 'click', this.close);

View File

@ -1,13 +1,10 @@
// cSpell:ignore installGentoo, fontawesome, webfont
// cSpell:ignore installGentoo, webfont
import $ from '../platform/$';
// import boardCss from './board.css';
import faCSS from '../../node_modules/font-awesome/css/font-awesome.css';
import faWebFont from '../../node_modules/font-awesome/fonts/fontawesome-webfont.woff';
import burichan from './burichan.css';
import fontAwesome from './font-awesome.css';
import futaba from './futaba.css';
import linkifyAudio from './linkify.audio.png';
import linkifyBitchute from './linkify.bitchute.png';
@ -41,19 +38,18 @@ import tomorrow from './tomorrow.css';
import www from './www.css';
import yotsubaB from './yotsuba-b.css';
import yotsuba from './yotsuba.css';
import { fa, icons } from './style';
import { icons } from './style';
import { g } from '../globals/globals';
// <%
// var inc = require['style'];
// var faCSS = read('/node_modules/font-awesome/css/font-awesome.css');
// var faWebFont = readBase64('/node_modules/font-awesome/fonts/fontawesome-webfont.woff');
// var mainCSS = ['font-awesome', 'style', 'yotsuba', 'yotsuba-b', 'futaba', 'burichan', 'tomorrow', 'photon', 'spooky'].map(x => read(`${x}.css`)).join('');
// var iconNames = files.filter(f => /^linkify\.[^.]+\.png$/.test(f));
// var icons = iconNames.map(readBase64);
// %>
const mainCSS = fontAwesome + style + yotsuba +yotsubaB+futaba+burichan+tomorrow + photon + spooky;
const mainCSS = style + yotsuba +yotsubaB+futaba+burichan+tomorrow + photon + spooky;
const faIcons: { name: string, data: string }[] = [
{ name: "Audio", data: linkifyAudio },
{ name: "Bitchute", data: linkifyBitchute },
@ -80,7 +76,7 @@ const faIcons: { name: string, data: string }[] = [
const CSS = {
boards: fa(faCSS, faWebFont) + mainCSS + icons(faIcons) + supports,
boards: mainCSS + icons(faIcons) + supports,
report,

View File

@ -1,54 +0,0 @@
.fa::before {
font-family: FontAwesome;
font-weight: 400;
font-style: normal;
-webkit-font-smoothing: antialiased;
text-decoration: inherit;
speak: none;
display: inline-block;
font-size: 13px;
visibility: visible;
}
:root:not(.shortcut-icons) #shortcuts .fa::before {
display: none;
}
:root.shortcut-icons #shortcuts .fa::before {
font-size: 15px !important;
margin-top: -3px !important;
position: relative;
top: 1px;
}
:root.shortcut-icons #shortcuts .fa, .menu-button .fa {
font-size: 0;
visibility: hidden;
}
:root.shortcut-icons .shortcut.brackets-wrap::after,
:root.shortcut-icons .shortcut.brackets-wrap::before {
display: none;
}
:root.shortcut-icons #shortcuts a .fa,
.menu-button .fa,
.hide-reply-button .fa,
.hide-thread-button .fa {
display: inline;
}
.fa-spin::before {
-webkit-animation:spin 2s infinite linear;
-moz-animation:spin 2s infinite linear;
-o-animation:spin 2s infinite linear;
animation:spin 2s infinite linear;
}
@-moz-keyframes spin {
0% {-moz-transform:rotate(0deg);}
100% {-moz-transform:rotate(359deg);}
}
@-webkit-keyframes spin {
0% {-webkit-transform:rotate(0deg);}
100% {-webkit-transform:rotate(359deg);}
}
@keyframes spin {
0% {transform:rotate(0deg);}
100% {transform:rotate(359deg);}
}

View File

@ -2480,3 +2480,12 @@ a:only-of-type > .remove {
.fcx-announcement a {
text-decoration: underline;
}
@keyframes spin {
0% {transform:rotate(0deg);}
100% {transform:rotate(359deg);}
}
.spin {
animation:spin 2s infinite linear;
}

View File

@ -1,26 +1,3 @@
// == Reprocess Font Awesome CSS == //
export const fa = (css: string, font: string) => (
// Font Awesome CSS attribution and license
css.match(/\/\*\![^]*?\*\//)[0] + '\n' +
// Font Awesome web font
`@font-face {
font-family: FontAwesome;
src: url('data:application/font-woff;base64,${font}') format('woff');
font-weight: 400;
font-style: normal;
}
` +
// fa-[icon name] classes
css
.match(/(\.fa-[^{]*{\s*content:[^}]*}\s*)+/)[0]
.replace(/([,{;])\s+/g, '$1')
.replace(/,/g, ', ')
);
// == Create CSS for Link Title Favicons == //
export const icons = (data: { name: string, data: string }[]) => (