Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions crates/mdbook-html/front-end/css/general.css
Original file line number Diff line number Diff line change
Expand Up @@ -406,3 +406,35 @@ dd > p {
/* Add some space between the icon and the text. */
margin-right: 8px;
}

.content .checkbox-img, .checkbox-label > .img-wrapper {
display: none;
}
.content .checkbox-label {
display: block;
max-width: 100%;
}
.content .checkbox-label img {
cursor: zoom-in;
}
.content .checkbox-img:checked + .checkbox-label > .img-wrapper {
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0.4);
z-index: 1001;
display: flex;
align-items: center;
justify-content: center;
cursor: zoom-out;
}
.content .checkbox-img:checked + .checkbox-label > .img-wrapper img {
--img-padding: 5px;
padding: var(--img-padding);
background: #999;
cursor: zoom-out;
max-width: calc(100% - (var(--img-padding) * 2));
max-height: calc(100% - (var(--img-padding) * 2));
}
9 changes: 9 additions & 0 deletions crates/mdbook-html/front-end/js/book.js
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,12 @@ aria-label="Show hidden lines"></button>';
})();

(function chapterNavigation() {
function zoomOutImages() {
for (const elem of Array.from(document.querySelectorAll('input.checkbox-img'))) {
elem.checked = false;
}
}

document.addEventListener('keydown', function(e) {
if (e.altKey ||
e.ctrlKey ||
Expand Down Expand Up @@ -724,6 +730,9 @@ aria-label="Show hidden lines"></button>';
e.preventDefault();
showHelp();
break;
case 'Escape':
zoomOutImages();
break;
}

// Rest of the keys are only active when the Shift key is not pressed
Expand Down
43 changes: 38 additions & 5 deletions crates/mdbook-html/src/html/tree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use super::tokenizer::parse_html;
use super::{HtmlRenderOptions, hide_lines, wrap_rust_main};
use crate::utils::{id_from_content, unique_id};
use ego_tree::{NodeId, NodeRef, Tree};
use html5ever::tendril::StrTendril;
use html5ever::tendril::{SliceExt, StrTendril};
use html5ever::tokenizer::{TagKind, Token};
use html5ever::{LocalName, QualName};
use indexmap::IndexMap;
Expand Down Expand Up @@ -69,7 +69,7 @@ impl Node {
}

/// An HTML element.
#[derive(Debug)]
#[derive(Debug, Clone)]
pub(crate) struct Element {
/// The tag name.
pub(crate) name: QualName,
Expand Down Expand Up @@ -199,6 +199,8 @@ pub(crate) struct MarkdownTreeBuilder<'opts, 'event, EventIter> {
/// tag. After the document has been parsed, all the definitions are moved
/// to the end of the document.
footnote_defs: HashMap<CowStr<'event>, NodeId>,
/// Current ID to be used to generate the images label and checkbox.
img_label_id: usize,
}

impl<'opts, 'event, EventIter> MarkdownTreeBuilder<'opts, 'event, EventIter>
Expand All @@ -222,6 +224,7 @@ where
table_cell_index: 0,
footnote_numbers: HashMap::new(),
footnote_defs: HashMap::new(),
img_label_id: 0,
};
builder.process_events();
builder.add_header_links();
Expand All @@ -230,6 +233,13 @@ where
builder.tree
}

/// Returns the current `img_label_id` and increase its value.
fn get_current_img_label_id(&mut self) -> usize {
let ret = self.img_label_id;
self.img_label_id += 1;
ret
}

/// Append a new child to the current node.
///
/// Returns the [`NodeId`] of the new node.
Expand Down Expand Up @@ -557,16 +567,39 @@ where
title,
id: _,
} => {
let img_input_id = format!("checkbox-img-{}", self.get_current_img_label_id());

let mut input = Element::new("input");
input.insert_attr("id", img_input_id.to_tendril());
input.insert_attr("class", "checkbox-img".to_tendril());
input.insert_attr("type", "checkbox".to_tendril());
self.append(Node::Element(input));

let mut label = Element::new("label");
label.insert_attr("class", "checkbox-label".to_tendril());
label.insert_attr("for", img_input_id.to_tendril());
self.push(Node::Element(label));

let mut img = Element::new("img");
let src = fix_link(dest_url).into_tendril();
img.insert_attr("src", src);
// This will eat TagEnd::Image
let alt = self.text_for_img_alt();
img.insert_attr("alt", alt.to_tendril());
if !title.is_empty() {
img.insert_attr("title", title.into_tendril());
} else {
img.insert_attr("title", alt.into());
}
// This will eat TagEnd::Image
let alt = self.text_for_img_alt();
img.insert_attr("alt", alt.into());
self.append(Node::Element(img.clone()));

let mut wrapper = Element::new("span");
wrapper.insert_attr("class", "img-wrapper".to_tendril());
self.push_no_stack(Node::Element(wrapper));
self.append(Node::Element(img));

// We exit the `label` and the `div`.
self.pop();
return;
}
Tag::MetadataBlock(_) => {
Expand Down
2 changes: 2 additions & 0 deletions tests/gui/books/basic/src/chapter_1.md
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
# Chapter 1

![rust logo](rust-logo.svg)
1 change: 1 addition & 0 deletions tests/gui/books/basic/src/rust-logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
46 changes: 46 additions & 0 deletions tests/gui/image-zoom.goml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// This test ensures that the image zoom-in/zoom-out works as expected.

define-function: (
"check-image-not-zoomed-in",
[],
block {
// The "zoomed in" image should not be displayed.
assert-css: (".checkbox-label > .img-wrapper", {"display": "none"})
// The cursor for the image should be "zoom-in".
assert-css: (".checkbox-label > img", {"cursor": "zoom-in"})
},
)

define-function: (
"check-image-zoomed-in",
[],
block {
// The image wrapper should now be displayed and have a "zoom-out" cursor.
assert-css: (".checkbox-label > .img-wrapper", {"display": "flex", "cursor": "zoom-out"})
// Same for the image it contains.
assert-css: (
".checkbox-label > .img-wrapper img",
{"display": "block", "cursor": "zoom-out"},
)
},
)

go-to: |DOC_PATH| + "basic/index.html"
call-function: ("check-image-not-zoomed-in", {})

// We click on the image to "zoom in".
click: ".checkbox-label > img"
call-function: ("check-image-zoomed-in", {})

// We click on the wrapper to "zoom out".
click: ".checkbox-label > img"
// We check that everything is back to the previous state.
call-function: ("check-image-not-zoomed-in", {})

// We test that the "escape" key also hides the "zoomed in" image.
// We click on the image to "zoom in".
click: ".checkbox-label > img"
call-function: ("check-image-zoomed-in", {})
press-key: "Escape"
// We check that everything is back to the previous state.
call-function: ("check-image-not-zoomed-in", {})
4 changes: 2 additions & 2 deletions tests/testsuite/markdown/basic_markdown/expected/images.html
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
<h1 id="images"><a class="header" href="#images">Images</a></h1>
<p><img src="https://rust-lang.org/logos/rust-logo-256x256.png" alt="Image “alt” &amp; &quot; &quot;text&quot; &amp; &lt;stuff&gt; url &lt;em&gt;html&lt;/em&gt; — hard break "></p>
<p><img src="https://rust-lang.org/logos/rust-logo-256x256.png" title="Some title" alt="Image with title"></p>
<p><input id="checkbox-img-0" class="checkbox-img" type="checkbox"><label class="checkbox-label" for="checkbox-img-0"><img src="https://rust-lang.org/logos/rust-logo-256x256.png" alt="Image “alt” &amp; &quot; &quot;text&quot; &amp; &lt;stuff&gt; url &lt;em&gt;html&lt;/em&gt; — hard break " title="Image “alt” &amp; &quot; &quot;text&quot; &amp; &lt;stuff&gt; url &lt;em&gt;html&lt;/em&gt; — hard break "><span class="img-wrapper"><img src="https://rust-lang.org/logos/rust-logo-256x256.png" alt="Image “alt” &amp; &quot; &quot;text&quot; &amp; &lt;stuff&gt; url &lt;em&gt;html&lt;/em&gt; — hard break " title="Image “alt” &amp; &quot; &quot;text&quot; &amp; &lt;stuff&gt; url &lt;em&gt;html&lt;/em&gt; — hard break "></span></label></p>
<p><input id="checkbox-img-1" class="checkbox-img" type="checkbox"><label class="checkbox-label" for="checkbox-img-1"><img src="https://rust-lang.org/logos/rust-logo-256x256.png" alt="Image with title" title="Some title"><span class="img-wrapper"><img src="https://rust-lang.org/logos/rust-logo-256x256.png" alt="Image with title" title="Some title"></span></label></p>
2 changes: 1 addition & 1 deletion tests/testsuite/print/relative_links/expected/print.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ <h1 id="testing-relative-links-for-the-print-page"><a class="header" href="#test
Link <a href="first/alpha/beta.html#anchor">inside but doesn’t exist with anchor</a>.
Link <a href="first/alpha/gamma.html">inside to html</a>.
Link <a href="first/alpha/gamma.html#anchor">inside to html with anchor</a>.</p>
<p><img src="images/picture.png" alt="Some image"></p>
<p><input id="checkbox-img-0" class="checkbox-img" type="checkbox"><label class="checkbox-label" for="checkbox-img-0"><img src="images/picture.png" alt="Some image" title="Some image"><span class="img-wrapper"><img src="images/picture.png" alt="Some image" title="Some image"></span></label></p>
<p><a href="#first-nested">HTML Link</a></p>
<img src="images/picture.png" alt="raw html">
<h2 id="some-section"><a class="header" href="#some-section">Some section</a></h2>
Expand Down
Loading