From 22fd0e2b212331bbffde94c4788d9af1deee8631 Mon Sep 17 00:00:00 2001 From: Christopher Olah Date: Thu, 6 Apr 2017 15:10:35 -0700 Subject: [PATCH] better hover box system --- components/citation.js | 24 ++++- components/footnote.js | 23 ++++- components/hover-box.txt | 186 +++++++++++++++++---------------------- 3 files changed, 127 insertions(+), 106 deletions(-) diff --git a/components/citation.js b/components/citation.js index 7fdba78..8be8efc 100644 --- a/components/citation.js +++ b/components/citation.js @@ -35,6 +35,25 @@ export default function(dom, data) { return a.author.localeCompare(b.author); }); }*/ + + var appendCiteHoverDiv = (function() { + function nodeFromString(str) { + var div = dom.createElement("div"); + div.innerHTML = str; + return div.firstChild; + } + var hover_boxes_container = nodeFromString(`
`) + dom.querySelector("body").appendChild(hover_boxes_container); + var hover_n = 0; + return function appendHoverDiv(content) { + var id = `dt-cite-hover-box-${hover_n}`; + hover_n += 1; + var str = ``; + var div = nodeFromString(str); + hover_boxes_container.appendChild(div); + return id; + } + })(); var citeTags = [].slice.apply(dom.querySelectorAll("dt-cite")); citeTags.forEach((el,n) => { @@ -47,10 +66,11 @@ export default function(dom, data) { if (n>0) cite_hover_str += "

"; cite_hover_str += hover_cite(data.bibliography[key]); }); - cite_hover_str = cite_hover_str.replace(/"/g, "'") + var ref_id = appendCiteHoverDiv(cite_hover_str); + //cite_hover_str = cite_hover_str.replace(/"/g, "'") var orig_string = el.innerHTML; if (orig_string != "") orig_string += " "; - el.innerHTML = `${orig_string}${cite_string}`; + el.innerHTML = `${orig_string}${cite_string}`; } }); diff --git a/components/footnote.js b/components/footnote.js index a7d771d..adbe8ac 100644 --- a/components/footnote.js +++ b/components/footnote.js @@ -1,14 +1,35 @@ export default function(dom, data) { + var appendFootnoteHoverDiv = (function() { + function nodeFromString(str) { + var div = dom.createElement("div"); + div.innerHTML = str; + return div.firstChild; + } + var hover_boxes_container = nodeFromString(`
`) + dom.querySelector("body").appendChild(hover_boxes_container); + var hover_n = 0; + return function appendHoverDiv(content) { + var id = `dt-fn-hover-box-${hover_n}`; + hover_n += 1; + var str = ``; + var div = nodeFromString(str); + hover_boxes_container.appendChild(div); + return id; + } + })(); + + var fnTags = [].slice.apply(dom.querySelectorAll("dt-fn")); var fnContent = []; fnTags.forEach((el,n) => { var content = el.innerHTML; + var ref_id = appendFootnoteHoverDiv(content) fnContent.push(content); n = (n+1)+""; var key = "fn-"+n; var escaped_content = content.replace(/"/g, "'"); - el.innerHTML = `${n}`; + el.innerHTML = `${n}`; }); let fnList = dom.querySelector("dt-fn-list"); diff --git a/components/hover-box.txt b/components/hover-box.txt index 8900f69..7f9c803 100644 --- a/components/hover-box.txt +++ b/components/hover-box.txt @@ -1,101 +1,4 @@ -// DistillHoverBox -//===================================== -function DistillHoverBox(key, pos){ - - if (!(key in DistillHoverBox.contentMap)){ - console.error("No DistillHoverBox content registered for key", key); - } - if (key in DistillHoverBox.liveBoxes) { - console.error("There already exists a DistillHoverBox for key", key); - } else { - for (var k in DistillHoverBox.liveBoxes) - DistillHoverBox.liveBoxes[k].remove(); - DistillHoverBox.liveBoxes[key] = this; - } - this.key = key; - - var pretty = window.innerWidth > 600; - - var padding = pretty? 18 : 12; - var outer_padding = pretty ? 18 : 0; - var bbox = document.querySelector("body").getBoundingClientRect(); - var left = pos[0] - bbox.left, top = pos[1] - bbox.top; - var width = Math.min(window.innerWidth-2*outer_padding, 648); - left = Math.min(left, window.innerWidth-width-outer_padding); - width = width - 2*padding; - - var str = `
- ${DistillHoverBox.contentMap[key]} -
`; - - this.div = appendBody(str); - - DistillHoverBox.bind (this.div, key); -} - -DistillHoverBox.prototype.remove = function remove(){ - if (this.div) this.div.remove(); - if (this.timeout) clearTimeout(this.timeout); - delete DistillHoverBox.liveBoxes[this.key]; -} - -DistillHoverBox.prototype.stopTimeout = function stopTimeout() { - if (this.timeout) clearTimeout(this.timeout); -} - -DistillHoverBox.prototype.extendTimeout = function extendTimeout(T) { - //console.log("extend", T) - var this_ = this; - this.stopTimeout(); - this.timeout = setTimeout(() => this_.remove(), T); -} - -DistillHoverBox.liveBoxes = {}; -DistillHoverBox.contentMap = {}; - -DistillHoverBox.bind = function bind(node, key) { - if (typeof node == "string"){ - node = document.querySelector(node); - } - node.addEventListener("mouseover", () => { - var bbox = node.getBoundingClientRect(); - if (!(key in DistillHoverBox.liveBoxes)){ - new DistillHoverBox(key, [bbox.right, bbox.bottom]); - } - DistillHoverBox.liveBoxes[key].stopTimeout(); - }); - node.addEventListener("mouseout", () => { - if (key in DistillHoverBox.liveBoxes){ - DistillHoverBox.liveBoxes[key].extendTimeout(250); - } - }); - node.addEventListener("touchend", () => { - if (key in DistillHoverBox.liveBoxes){ - DistillHoverBox.liveBoxes[key].extendTimeout(250); - } - }); - -} - - -function appendBody(str){ - var node = nodeFromString(str); - var body = document.querySelector("body"); - body.appendChild(node); - return node; -} function nodeFromString(str) { var div = document.createElement("div"); @@ -103,11 +6,88 @@ function nodeFromString(str) { return div.firstChild; } -var hover_es = document.querySelectorAll("span[data-hover]"); +function make_hover_css(pos) { + var pretty = window.innerWidth > 600; + var padding = pretty? 18 : 12; + var outer_padding = pretty ? 18 : 0; + var bbox = document.querySelector("body").getBoundingClientRect(); + var left = pos[0] - bbox.left, top = pos[1] - bbox.top; + var width = Math.min(window.innerWidth-2*outer_padding, 648); + left = Math.min(left, window.innerWidth-width-outer_padding); + width = width - 2*padding; + return (`position: absolute; + background-color: #FFF; + opacity: 0.95; + max-width: ${width}px; + top: ${top}px; + left: ${left}px; + border: 1px solid rgba(0, 0, 0, 0.25); + padding: ${padding}px; + border-radius: ${pretty? 3 : 0}px; + box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.2); + z-index: ${1e6};`); +} + + +function DtHoverBox(div_id) { + this.div = document.querySelector("#"+div_id); + this.visible = false; + this.bind(this.div); + DtHoverBox.box_map[div_id] = this; +} + +DtHoverBox.box_map = {}; + +DtHoverBox.get_box = function get_box(div_id) { + if (div_id in DtHoverBox.box_map) { + return DtHoverBox.box_map[div_id]; + } else { + return new DtHoverBox(div_id); + } +} + +DtHoverBox.prototype.show = function show(pos){ + this.visible = true; + this.div.setAttribute("style", make_hover_css(pos) ); + for (var box_id in DtHoverBox.box_map) { + var box = DtHoverBox.box_map[box_id]; + if (box != this) box.hide(); + } +} + +DtHoverBox.prototype.hide = function hide(){ + this.visible = false; + if (this.div) this.div.setAttribute("style", "display:none"); + if (this.timeout) clearTimeout(this.timeout); +} + +DtHoverBox.prototype.stopTimeout = function stopTimeout() { + if (this.timeout) clearTimeout(this.timeout); +} + +DtHoverBox.prototype.extendTimeout = function extendTimeout(T) { + //console.log("extend", T) + var this_ = this; + this.stopTimeout(); + this.timeout = setTimeout(() => this_.hide(), T); +} + +DtHoverBox.prototype.bind = function bind(node) { + if (typeof node == "string"){ + node = document.querySelector(node); + } + node.addEventListener("mouseover", () => { + var bbox = node.getBoundingClientRect(); + if (!this.visible) this.show([bbox.right, bbox.bottom]); + this.stopTimeout(); + }); + node.addEventListener("mouseout", () => this.extendTimeout(250) ); + node.addEventListener("touchend", () => this.extendTimeout(250) ); +} + +var hover_es = document.querySelectorAll("span[data-hover-ref]"); hover_es = [].slice.apply(hover_es); hover_es.forEach((e,n) => { - var key = "hover-"+n; - var content = e.getAttribute("data-hover"); - DistillHoverBox.contentMap[key] = content; - DistillHoverBox.bind(e, key); -}); + var ref_id = e.getAttribute("data-hover-ref"); + DtHoverBox.get_box(ref_id).bind(e); +})