Use embedded SVG instead of fonts for icons
The [downsides of icon fonts] are well-documented, and also, why ship all of the icons when it only uses 14? [downsides of icon fonts]: https://speakerdeck.com/ninjanails/death-to-icon-fonts
This commit is contained in:
parent
c8db0c8ec6
commit
7560a2b9b6
|
@ -327,6 +327,12 @@ version = "1.0.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "font-awesome-as-a-crate"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "86afa981f309a5d0ddbcb682820e5d6066157f903d06b9fb2959707b958f6618"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.0.1"
|
||||
|
@ -806,6 +812,7 @@ dependencies = [
|
|||
"clap_complete",
|
||||
"elasticlunr-rs",
|
||||
"env_logger",
|
||||
"font-awesome-as-a-crate",
|
||||
"futures-util",
|
||||
"gitignore",
|
||||
"handlebars",
|
||||
|
|
|
@ -21,6 +21,7 @@ chrono = "0.4"
|
|||
clap = { version = "3.0", features = ["cargo"] }
|
||||
clap_complete = "3.0"
|
||||
env_logger = "0.9.0"
|
||||
font-awesome-as-a-crate = "0.2.0"
|
||||
handlebars = "4.0"
|
||||
lazy_static = "1.0"
|
||||
log = "0.4"
|
||||
|
|
|
@ -240,41 +240,6 @@ impl HtmlHandlebars {
|
|||
write_file(destination, "ayu-highlight.css", &theme.ayu_highlight_css)?;
|
||||
write_file(destination, "highlight.js", &theme.highlight_js)?;
|
||||
write_file(destination, "clipboard.min.js", &theme.clipboard_js)?;
|
||||
write_file(
|
||||
destination,
|
||||
"FontAwesome/css/font-awesome.css",
|
||||
theme::FONT_AWESOME,
|
||||
)?;
|
||||
write_file(
|
||||
destination,
|
||||
"FontAwesome/fonts/fontawesome-webfont.eot",
|
||||
theme::FONT_AWESOME_EOT,
|
||||
)?;
|
||||
write_file(
|
||||
destination,
|
||||
"FontAwesome/fonts/fontawesome-webfont.svg",
|
||||
theme::FONT_AWESOME_SVG,
|
||||
)?;
|
||||
write_file(
|
||||
destination,
|
||||
"FontAwesome/fonts/fontawesome-webfont.ttf",
|
||||
theme::FONT_AWESOME_TTF,
|
||||
)?;
|
||||
write_file(
|
||||
destination,
|
||||
"FontAwesome/fonts/fontawesome-webfont.woff",
|
||||
theme::FONT_AWESOME_WOFF,
|
||||
)?;
|
||||
write_file(
|
||||
destination,
|
||||
"FontAwesome/fonts/fontawesome-webfont.woff2",
|
||||
theme::FONT_AWESOME_WOFF2,
|
||||
)?;
|
||||
write_file(
|
||||
destination,
|
||||
"FontAwesome/fonts/FontAwesome.ttf",
|
||||
theme::FONT_AWESOME_TTF,
|
||||
)?;
|
||||
if html_config.copy_fonts {
|
||||
write_file(destination, "fonts/fonts.css", theme::fonts::CSS)?;
|
||||
for (file_name, contents) in theme::fonts::LICENSES.iter() {
|
||||
|
@ -341,6 +306,7 @@ impl HtmlHandlebars {
|
|||
handlebars.register_helper("previous", Box::new(helpers::navigation::previous));
|
||||
handlebars.register_helper("next", Box::new(helpers::navigation::next));
|
||||
handlebars.register_helper("theme_option", Box::new(helpers::theme::theme_option));
|
||||
handlebars.register_helper("fa", Box::new(helpers::fontawesome::fa_helper));
|
||||
}
|
||||
|
||||
/// Copy across any additional CSS and JavaScript files which the book
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
use font_awesome_as_a_crate as fa;
|
||||
use handlebars::{Context, Handlebars, Helper, Output, RenderContext, RenderError};
|
||||
use std::str::FromStr;
|
||||
|
||||
pub fn fa_helper(
|
||||
h: &Helper<'_, '_>,
|
||||
_r: &Handlebars<'_>,
|
||||
_ctx: &Context,
|
||||
_rc: &mut RenderContext<'_, '_>,
|
||||
out: &mut dyn Output,
|
||||
) -> Result<(), RenderError> {
|
||||
trace!("fa_helper (handlebars helper)");
|
||||
|
||||
let type_ = h
|
||||
.param(0)
|
||||
.and_then(|v| v.value().as_str())
|
||||
.and_then(|v| fa::Type::from_str(v).ok())
|
||||
.ok_or_else(|| {
|
||||
RenderError::new("Param 0 with String type is required for fontawesome helper.")
|
||||
})?;
|
||||
|
||||
let name = h.param(1).and_then(|v| v.value().as_str()).ok_or_else(|| {
|
||||
RenderError::new("Param 1 with String type is required for fontawesome helper.")
|
||||
})?;
|
||||
|
||||
trace!("fa_helper: {} {}", type_, name);
|
||||
|
||||
let name = if name.starts_with("fa-") {
|
||||
&name[3..]
|
||||
} else {
|
||||
&name[..]
|
||||
};
|
||||
|
||||
if let Some(id) = h.param(2).and_then(|v| v.value().as_str()) {
|
||||
out.write(&format!("<span class=fa-svg id=\"{}\">", id))?;
|
||||
} else {
|
||||
out.write("<span class=fa-svg>")?;
|
||||
}
|
||||
out.write(
|
||||
fa::svg(type_, name).map_err(|_| RenderError::new(format!("Missing font {}", name)))?,
|
||||
)?;
|
||||
out.write("</span>")?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -1,3 +1,4 @@
|
|||
pub mod fontawesome;
|
||||
pub mod navigation;
|
||||
pub mod theme;
|
||||
pub mod toc;
|
||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 434 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -92,6 +92,7 @@ function playground_text(playground) {
|
|||
|
||||
if (all_available) {
|
||||
play_button.classList.remove("hidden");
|
||||
play_button.hidden = false;
|
||||
} else {
|
||||
play_button.classList.add("hidden");
|
||||
}
|
||||
|
@ -187,25 +188,24 @@ function playground_text(playground) {
|
|||
|
||||
var buttons = document.createElement('div');
|
||||
buttons.className = 'buttons';
|
||||
buttons.innerHTML = "<button class=\"fa fa-eye\" title=\"Show hidden lines\" aria-label=\"Show hidden lines\"></button>";
|
||||
buttons.innerHTML = "<button title=\"Show hidden lines\" aria-label=\"Show hidden lines\"></button>";
|
||||
buttons.firstChild.innerHTML = document.getElementById('fa-eye').innerHTML;
|
||||
|
||||
// add expand button
|
||||
var pre_block = block.parentNode;
|
||||
pre_block.insertBefore(buttons, pre_block.firstChild);
|
||||
|
||||
pre_block.querySelector('.buttons').addEventListener('click', function (e) {
|
||||
if (e.target.classList.contains('fa-eye')) {
|
||||
e.target.classList.remove('fa-eye');
|
||||
e.target.classList.add('fa-eye-slash');
|
||||
e.target.title = 'Hide lines';
|
||||
e.target.setAttribute('aria-label', e.target.title);
|
||||
buttons.firstChild.addEventListener('click', function (e) {
|
||||
if (this.title === "Show hidden lines") {
|
||||
this.innerHTML = document.getElementById('fa-eye-slash').innerHTML;
|
||||
this.title = 'Hide lines';
|
||||
this.setAttribute('aria-label', e.target.title);
|
||||
|
||||
block.classList.remove('hide-boring');
|
||||
} else if (e.target.classList.contains('fa-eye-slash')) {
|
||||
e.target.classList.remove('fa-eye-slash');
|
||||
e.target.classList.add('fa-eye');
|
||||
e.target.title = 'Show hidden lines';
|
||||
e.target.setAttribute('aria-label', e.target.title);
|
||||
} else if (this.title === "Hide lines") {
|
||||
this.innerHTML = document.getElementById('fa-eye').innerHTML;
|
||||
this.title = 'Show hidden lines';
|
||||
this.setAttribute('aria-label', e.target.title);
|
||||
|
||||
block.classList.add('hide-boring');
|
||||
}
|
||||
|
@ -224,10 +224,11 @@ function playground_text(playground) {
|
|||
}
|
||||
|
||||
var clipButton = document.createElement('button');
|
||||
clipButton.className = 'fa fa-copy clip-button';
|
||||
clipButton.className = 'clip-button';
|
||||
clipButton.title = 'Copy to clipboard';
|
||||
clipButton.setAttribute('aria-label', clipButton.title);
|
||||
clipButton.innerHTML = '<i class=\"tooltiptext\"></i>';
|
||||
clipButton.innerHTML += document.getElementById('fa-copy').innerHTML;
|
||||
|
||||
buttons.insertBefore(clipButton, buttons.firstChild);
|
||||
}
|
||||
|
@ -245,10 +246,11 @@ function playground_text(playground) {
|
|||
}
|
||||
|
||||
var runCodeButton = document.createElement('button');
|
||||
runCodeButton.className = 'fa fa-play play-button';
|
||||
runCodeButton.className = 'play-button';
|
||||
runCodeButton.hidden = true;
|
||||
runCodeButton.title = 'Run this code';
|
||||
runCodeButton.setAttribute('aria-label', runCodeButton.title);
|
||||
runCodeButton.innerHTML = document.getElementById('fa-play').innerHTML;
|
||||
|
||||
buttons.insertBefore(runCodeButton, buttons.firstChild);
|
||||
runCodeButton.addEventListener('click', function (e) {
|
||||
|
@ -257,8 +259,9 @@ function playground_text(playground) {
|
|||
|
||||
if (window.playground_copyable) {
|
||||
var copyCodeClipboardButton = document.createElement('button');
|
||||
copyCodeClipboardButton.className = 'fa fa-copy clip-button';
|
||||
copyCodeClipboardButton.className = 'clip-button';
|
||||
copyCodeClipboardButton.innerHTML = '<i class="tooltiptext"></i>';
|
||||
copyCodeClipboardButton.innerHTML += document.getElementById('fa-copy').innerHTML;
|
||||
copyCodeClipboardButton.title = 'Copy to clipboard';
|
||||
copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title);
|
||||
|
||||
|
@ -268,9 +271,10 @@ function playground_text(playground) {
|
|||
let code_block = pre_block.querySelector("code");
|
||||
if (window.ace && code_block.classList.contains("editable")) {
|
||||
var undoChangesButton = document.createElement('button');
|
||||
undoChangesButton.className = 'fa fa-history reset-button';
|
||||
undoChangesButton.className = 'reset-button';
|
||||
undoChangesButton.title = 'Undo changes';
|
||||
undoChangesButton.setAttribute('aria-label', undoChangesButton.title);
|
||||
undoChangesButton.innerHTML += document.getElementById('fa-history').innerHTML;
|
||||
|
||||
buttons.insertBefore(undoChangesButton, buttons.firstChild);
|
||||
|
||||
|
@ -580,12 +584,12 @@ function playground_text(playground) {
|
|||
|
||||
function hideTooltip(elem) {
|
||||
elem.firstChild.innerText = "";
|
||||
elem.className = 'fa fa-copy clip-button';
|
||||
elem.className = 'clip-button';
|
||||
}
|
||||
|
||||
function showTooltip(elem, msg) {
|
||||
elem.firstChild.innerText = msg;
|
||||
elem.className = 'fa fa-copy tooltipped';
|
||||
elem.className = 'tooltipped';
|
||||
}
|
||||
|
||||
var clipboardSnippets = new ClipboardJS('.clip-button', {
|
||||
|
|
|
@ -51,7 +51,7 @@ a > .hljs {
|
|||
#menu-bar.bordered {
|
||||
border-bottom-color: var(--table-border-color);
|
||||
}
|
||||
#menu-bar i, #menu-bar .icon-button {
|
||||
#menu-bar .fa-svg, #menu-bar .icon-button {
|
||||
position: relative;
|
||||
padding: 0 8px;
|
||||
z-index: 10;
|
||||
|
@ -60,7 +60,7 @@ a > .hljs {
|
|||
transition: color 0.5s;
|
||||
}
|
||||
@media only screen and (max-width: 420px) {
|
||||
#menu-bar i, #menu-bar .icon-button {
|
||||
#menu-bar .fa-svg, #menu-bar .icon-button {
|
||||
padding: 0 5px;
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ a > .hljs {
|
|||
padding: 0;
|
||||
color: inherit;
|
||||
}
|
||||
.icon-button i {
|
||||
.icon-button .fa-svg {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
|
@ -113,14 +113,14 @@ a > .hljs {
|
|||
.mobile-nav-chapters,
|
||||
.mobile-nav-chapters:visited,
|
||||
.menu-bar .icon-button,
|
||||
.menu-bar a i {
|
||||
.menu-bar a .fa-svg {
|
||||
color: var(--icons);
|
||||
}
|
||||
|
||||
.menu-bar i:hover,
|
||||
.menu-bar .fa-svg:hover,
|
||||
.menu-bar .icon-button:hover,
|
||||
.nav-chapters:hover,
|
||||
.mobile-nav-chapters i:hover {
|
||||
.mobile-nav-chapters .fa-svg:hover {
|
||||
color: var(--icons-hover);
|
||||
}
|
||||
|
||||
|
@ -228,7 +228,7 @@ pre > .buttons :hover {
|
|||
border-color: var(--icons-hover);
|
||||
background-color: var(--theme-hover);
|
||||
}
|
||||
pre > .buttons i {
|
||||
pre > .buttons .fa-svg {
|
||||
margin-left: 8px;
|
||||
}
|
||||
pre > .buttons button {
|
||||
|
|
|
@ -189,3 +189,10 @@ blockquote {
|
|||
.result-no-output {
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.fa-svg svg {
|
||||
width: 1em;
|
||||
height: 1em;
|
||||
fill: currentColor;
|
||||
margin-bottom: -0.1em;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,6 @@
|
|||
{{/if}}
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
|
||||
{{#if copy_fonts}}
|
||||
<link rel="stylesheet" href="{{ path_to_root }}fonts/fonts.css">
|
||||
{{/if}}
|
||||
|
@ -116,10 +115,10 @@
|
|||
<div id="menu-bar" class="menu-bar sticky bordered">
|
||||
<div class="left-buttons">
|
||||
<button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
|
||||
<i class="fa fa-bars"></i>
|
||||
{{fa "solid" "bars"}}
|
||||
</button>
|
||||
<button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
|
||||
<i class="fa fa-paint-brush"></i>
|
||||
{{fa "solid" "paint-brush"}}
|
||||
</button>
|
||||
<ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
|
||||
<li role="none"><button role="menuitem" class="theme" id="light">{{ theme_option "Light" }}</button></li>
|
||||
|
@ -130,7 +129,7 @@
|
|||
</ul>
|
||||
{{#if search_enabled}}
|
||||
<button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
|
||||
<i class="fa fa-search"></i>
|
||||
{{fa "solid" "search"}}
|
||||
</button>
|
||||
{{/if}}
|
||||
</div>
|
||||
|
@ -140,12 +139,12 @@
|
|||
<div class="right-buttons">
|
||||
{{#if print_enable}}
|
||||
<a href="{{ path_to_root }}print.html" title="Print this book" aria-label="Print this book">
|
||||
<i id="print-button" class="fa fa-print"></i>
|
||||
{{fa "solid" "print" "print-button"}}
|
||||
</a>
|
||||
{{/if}}
|
||||
{{#if git_repository_url}}
|
||||
<a href="{{git_repository_url}}" title="Git repository" aria-label="Git repository">
|
||||
<i id="git-repository-button" class="fa {{git_repository_icon}}"></i>
|
||||
{{fa "solid" git_repository_icon}}
|
||||
</a>
|
||||
{{/if}}
|
||||
{{#if git_repository_edit_url}}
|
||||
|
@ -188,13 +187,13 @@
|
|||
<!-- Mobile navigation buttons -->
|
||||
{{#previous}}
|
||||
<a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
{{fa "solid" "angle-left"}}
|
||||
</a>
|
||||
{{/previous}}
|
||||
|
||||
{{#next}}
|
||||
<a rel="next" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
{{fa "solid" "angle-right"}}
|
||||
</a>
|
||||
{{/next}}
|
||||
|
||||
|
@ -206,19 +205,25 @@
|
|||
<nav class="nav-wide-wrapper" aria-label="Page navigation">
|
||||
{{#previous}}
|
||||
<a rel="prev" href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
|
||||
<i class="fa fa-angle-left"></i>
|
||||
{{fa "solid" "angle-left"}}
|
||||
</a>
|
||||
{{/previous}}
|
||||
|
||||
{{#next}}
|
||||
<a rel="next" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
|
||||
<i class="fa fa-angle-right"></i>
|
||||
{{fa "solid" "angle-right"}}
|
||||
</a>
|
||||
{{/next}}
|
||||
</nav>
|
||||
|
||||
</div>
|
||||
|
||||
<template id=fa-eye>{{fa "solid" "eye"}}</template>
|
||||
<template id=fa-eye-slash>{{fa "solid" "eye-slash"}}</template>
|
||||
<template id=fa-copy>{{fa "regular" "copy"}}</template>
|
||||
<template id=fa-play>{{fa "solid" "play"}}</template>
|
||||
<template id=fa-history>{{fa "solid" "history"}}</template>
|
||||
|
||||
{{#if live_reload_endpoint}}
|
||||
<!-- Livereload script (if served using the cli tool) -->
|
||||
<script>
|
||||
|
|
|
@ -29,14 +29,6 @@ pub static TOMORROW_NIGHT_CSS: &[u8] = include_bytes!("tomorrow-night.css");
|
|||
pub static HIGHLIGHT_CSS: &[u8] = include_bytes!("highlight.css");
|
||||
pub static AYU_HIGHLIGHT_CSS: &[u8] = include_bytes!("ayu-highlight.css");
|
||||
pub static CLIPBOARD_JS: &[u8] = include_bytes!("clipboard.min.js");
|
||||
pub static FONT_AWESOME: &[u8] = include_bytes!("FontAwesome/css/font-awesome.min.css");
|
||||
pub static FONT_AWESOME_EOT: &[u8] = include_bytes!("FontAwesome/fonts/fontawesome-webfont.eot");
|
||||
pub static FONT_AWESOME_SVG: &[u8] = include_bytes!("FontAwesome/fonts/fontawesome-webfont.svg");
|
||||
pub static FONT_AWESOME_TTF: &[u8] = include_bytes!("FontAwesome/fonts/fontawesome-webfont.ttf");
|
||||
pub static FONT_AWESOME_WOFF: &[u8] = include_bytes!("FontAwesome/fonts/fontawesome-webfont.woff");
|
||||
pub static FONT_AWESOME_WOFF2: &[u8] =
|
||||
include_bytes!("FontAwesome/fonts/fontawesome-webfont.woff2");
|
||||
pub static FONT_AWESOME_OTF: &[u8] = include_bytes!("FontAwesome/fonts/FontAwesome.otf");
|
||||
|
||||
/// The `Theme` struct should be used instead of the static variables because
|
||||
/// the `new()` method will look if the user has a theme directory in their
|
||||
|
|
Loading…
Reference in New Issue