mirror of
https://github.com/wassname/template.git
synced 2026-07-17 11:33:44 +08:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a3c9c58c03 |
+2
-2
@@ -2,11 +2,11 @@ language: node_js
|
|||||||
node_js:
|
node_js:
|
||||||
- "node" # latest version
|
- "node" # latest version
|
||||||
cache:
|
cache:
|
||||||
|
yarn: true
|
||||||
directories:
|
directories:
|
||||||
- node_modules
|
- node_modules
|
||||||
script:
|
script:
|
||||||
- npm run build
|
- yarn build
|
||||||
- npm test
|
|
||||||
deploy:
|
deploy:
|
||||||
provider: releases
|
provider: releases
|
||||||
api_key: $GITHUB_OAUTH_TOKEN
|
api_key: $GITHUB_OAUTH_TOKEN
|
||||||
|
|||||||
@@ -2,12 +2,9 @@
|
|||||||
|
|
||||||
<head>
|
<head>
|
||||||
<script src="../dist/template.v2.js"></script>
|
<script src="../dist/template.v2.js"></script>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1" >
|
|
||||||
<meta charset="utf8">
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<distill-header></distill-header>
|
|
||||||
<d-front-matter>
|
<d-front-matter>
|
||||||
<script id='distill-front-matter' type="text/json">{
|
<script id='distill-front-matter' type="text/json">{
|
||||||
"title": "Why Momentum Really Works",
|
"title": "Why Momentum Really Works",
|
||||||
@@ -61,7 +58,6 @@
|
|||||||
</d-math>
|
</d-math>
|
||||||
<a class="marker" href="#section-1.1" id="section-1.1"><span>1.1</span></a>
|
<a class="marker" href="#section-1.1" id="section-1.1"><span>1.1</span></a>
|
||||||
<h3>Citations</h3>
|
<h3>Citations</h3>
|
||||||
<p><d-slider style="width: 200px;"></d-slider></p>
|
|
||||||
<p>We can<d-cite key="mercier2011humans"></d-cite> also cite <d-cite key="gregor2015draw,mercier2011humans"></d-cite> external publications. <d-cite key="dong2014image,dumoulin2016guide,mordvintsev2015inceptionism"></d-cite>. We should also be testing footnotes<d-footnote>This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote.</d-footnote>. There are multiple footnotes, and they appear in the appendix<d-footnote>Given I have coded them right. Also, here's math in a footnote: <d-math>c = \sum_0^i{x}</d-math>. Also, a citation. Box-ception<d-cite key='gregor2015draw'></d-cite>!</d-footnote> as well.</p>
|
<p>We can<d-cite key="mercier2011humans"></d-cite> also cite <d-cite key="gregor2015draw,mercier2011humans"></d-cite> external publications. <d-cite key="dong2014image,dumoulin2016guide,mordvintsev2015inceptionism"></d-cite>. We should also be testing footnotes<d-footnote>This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote. This will become a hoverable footnote.</d-footnote>. There are multiple footnotes, and they appear in the appendix<d-footnote>Given I have coded them right. Also, here's math in a footnote: <d-math>c = \sum_0^i{x}</d-math>. Also, a citation. Box-ception<d-cite key='gregor2015draw'></d-cite>!</d-footnote> as well.</p>
|
||||||
<a class="marker" href="#section-2" id="section-2"><span>2</span></a>
|
<a class="marker" href="#section-2" id="section-2"><span>2</span></a>
|
||||||
<h2>Displaying code snippets</h2>
|
<h2>Displaying code snippets</h2>
|
||||||
|
|||||||
Generated
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "distill-template",
|
"name": "distill-template",
|
||||||
"version": "2.2.4",
|
"version": "2.2.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "distill-template",
|
"name": "distill-template",
|
||||||
"version": "2.2.4",
|
"version": "2.2.0",
|
||||||
"description": "Template for creating Distill articles.",
|
"description": "Template for creating Distill articles.",
|
||||||
"main": "dist/template.v2.js",
|
"main": "dist/template.v2.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
+1
-2
@@ -16,7 +16,6 @@ import { Code } from './components/d-code';
|
|||||||
import { Footnote } from './components/d-footnote';
|
import { Footnote } from './components/d-footnote';
|
||||||
import { FootnoteList } from './components/d-footnote-list';
|
import { FootnoteList } from './components/d-footnote-list';
|
||||||
import { FrontMatter } from './components/d-front-matter';
|
import { FrontMatter } from './components/d-front-matter';
|
||||||
import { HoverBox } from './components/d-hover-box';
|
|
||||||
import { Title } from './components/d-title';
|
import { Title } from './components/d-title';
|
||||||
import { DMath } from './components/d-math';
|
import { DMath } from './components/d-math';
|
||||||
import { References } from './components/d-references';
|
import { References } from './components/d-references';
|
||||||
@@ -54,7 +53,7 @@ const distillMain = function() {
|
|||||||
/* Article will register controller which takes control from there */
|
/* Article will register controller which takes control from there */
|
||||||
const components = [
|
const components = [
|
||||||
Abstract, Appendix, Article, Bibliography, Byline, Cite, CitationList, Code,
|
Abstract, Appendix, Article, Bibliography, Byline, Cite, CitationList, Code,
|
||||||
Footnote, FootnoteList, FrontMatter, HoverBox, Title, DMath, References, TOC, Figure,
|
Footnote, FootnoteList, FrontMatter, Title, DMath, References, TOC, Figure,
|
||||||
Slider, Interstitial
|
Slider, Interstitial
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
// import { Template } from '../mixins/template';
|
import { Template } from '../mixins/template';
|
||||||
import { Controller } from '../controller';
|
import { Controller } from '../controller';
|
||||||
|
import style from '../styles/d-article.css';
|
||||||
|
|
||||||
const isOnlyWhitespace = /^\s*$/;
|
const isOnlyWhitespace = /^\s*$/;
|
||||||
|
|
||||||
@@ -31,7 +32,7 @@ export class Article extends HTMLElement {
|
|||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
document.onreadystatechange = function () {
|
document.onreadystatechange = function () {
|
||||||
console.log('onreadystatechange:');
|
console.log("onreadystatechange:");
|
||||||
console.log(document.readyState);
|
console.log(document.readyState);
|
||||||
};
|
};
|
||||||
console.info('Article tag connected, we can now listen to controller events.');
|
console.info('Article tag connected, we can now listen to controller events.');
|
||||||
|
|||||||
@@ -35,12 +35,6 @@ export class Bibliography extends HTMLElement {
|
|||||||
observer.observe(this, options);
|
observer.observe(this, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
requestAnimationFrame(() => {
|
|
||||||
this.parseIfPossible();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
parseIfPossible() {
|
parseIfPossible() {
|
||||||
const scriptTag = this.querySelector('script');
|
const scriptTag = this.querySelector('script');
|
||||||
if (!scriptTag) return;
|
if (!scriptTag) return;
|
||||||
|
|||||||
+83
-19
@@ -1,5 +1,6 @@
|
|||||||
import { Template } from '../mixins/template';
|
import { Template } from '../mixins/template';
|
||||||
import { hover_cite, bibliography_cite } from '../helpers/citation';
|
import { hover_cite, bibliography_cite } from '../helpers/citation';
|
||||||
|
import { HoverBox } from '../helpers/hover-box';
|
||||||
|
|
||||||
const T = Template('d-cite', `
|
const T = Template('d-cite', `
|
||||||
<style>
|
<style>
|
||||||
@@ -34,13 +35,31 @@ figcaption .citation-number {
|
|||||||
line-height: 1em;
|
line-height: 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
d-hover-box {
|
.container {
|
||||||
margin-top: 1.9em;
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
left: 0;
|
||||||
|
z-index: 10000;
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dt-hover-box {
|
||||||
|
margin: 0 auto;
|
||||||
|
width: 400px;
|
||||||
|
max-width: 700px;
|
||||||
|
background-color: #FFF;
|
||||||
|
opacity: 0.95;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.25);
|
||||||
|
padding: 8px 16px;
|
||||||
|
border-radius: 3px;
|
||||||
|
box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<d-hover-box id="hover-box"></d-hover-box>
|
<div class="container">
|
||||||
|
<div id="hover-box" class="dt-hover-box"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="citation-" class="citation"><slot></slot><span class="citation-number"></span></div>
|
<div id="citation-" class="citation"><slot></slot><span class="citation-number"></span></div>
|
||||||
`);
|
`);
|
||||||
@@ -49,23 +68,43 @@ export class Cite extends T(HTMLElement) {
|
|||||||
|
|
||||||
/* Lifecycle */
|
/* Lifecycle */
|
||||||
|
|
||||||
|
// constructor() {
|
||||||
|
// super();
|
||||||
|
// // Cite.currentId += 1;
|
||||||
|
// // this.citeId = Cite.currentId;
|
||||||
|
// }
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
|
// this.notify();
|
||||||
|
|
||||||
|
this.hoverDiv = this.root.querySelector('.dt-hover-box');
|
||||||
this.outerSpan = this.root.querySelector('#citation-');
|
this.outerSpan = this.root.querySelector('#citation-');
|
||||||
this.innerSpan = this.root.querySelector('.citation-number');
|
this.innerSpan = this.root.querySelector('.citation-number');
|
||||||
this.hoverBox = this.root.querySelector('d-hover-box');
|
// this.outerSpan.id = `citation-${this.citeId}`;
|
||||||
window.customElements.whenDefined('d-hover-box').then(() => {
|
// this.hoverDiv.id = `dt-cite-hover-box-${this.citeId}`;
|
||||||
this.hoverBox.listen(this);
|
// console.log(this, this.hoverDiv, this.outerSpan, this.innerSpan);
|
||||||
});
|
this.hoverbox = new HoverBox(this.hoverDiv, this.outerSpan);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO This causes an infinite loop on firefox with polyfills.
|
disconnectedCallback() {
|
||||||
// This is only needed for interactive editing so no priority.
|
const options = { detail: [this, this.keys], bubbles: true };
|
||||||
// disconnectedCallback() {
|
const event = new CustomEvent('onCiteKeyRemoved', options);
|
||||||
// const options = { detail: [this, this.keys], bubbles: true };
|
document.dispatchEvent(event);
|
||||||
// const event = new CustomEvent('onCiteKeyRemoved', options);
|
}
|
||||||
// document.dispatchEvent(event);
|
|
||||||
|
/* Observed Attributes */
|
||||||
|
|
||||||
|
// renderCitationNumbers(citations) {
|
||||||
|
// const numbers = this._keys.map( (key) => {
|
||||||
|
// const index = citations.indexOf(key);
|
||||||
|
// return index == -1 ? '?' : index + 1 + '';
|
||||||
|
// });
|
||||||
|
// const text = "[" + numbers.join(", ") + "]";
|
||||||
|
// this.innerSpan.textContent = text;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* observe 'key' attribute */
|
/* observe 'key' attribute */
|
||||||
|
|
||||||
static get observedAttributes() {
|
static get observedAttributes() {
|
||||||
@@ -99,15 +138,40 @@ export class Cite extends T(HTMLElement) {
|
|||||||
return index == -1 ? '?' : index + 1 + '';
|
return index == -1 ? '?' : index + 1 + '';
|
||||||
});
|
});
|
||||||
const textContent = '[' + numberStrings.join(', ') + ']';
|
const textContent = '[' + numberStrings.join(', ') + ']';
|
||||||
if (this.innerSpan) {
|
const innerSpan = this.root.querySelector('.citation-number');
|
||||||
this.innerSpan.textContent = textContent;
|
innerSpan.textContent = textContent;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
set entries(entries) {
|
set entries(entries) {
|
||||||
if (this.hoverBox) {
|
const div = this.root.querySelector('#hover-box');
|
||||||
this.hoverBox.innerHTML = entries.map(hover_cite).join('<br><br>');
|
div.innerHTML = entries.map(hover_cite).join('<br><br>');
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// renderContent() {
|
||||||
|
// const bibliography = document.querySelector('d-bibliography');
|
||||||
|
// if (bibliography && bibliography.finishedLoading) {
|
||||||
|
// customElements.whenDefined('d-bibliography').then( () => {
|
||||||
|
// const keys = this.key.split(",");
|
||||||
|
//
|
||||||
|
// // set up hidden hover box
|
||||||
|
// const div = this.root.querySelector('.dt-hover-box');
|
||||||
|
// div.innerHTML = keys.map( (key) => {
|
||||||
|
// return bibliography.getEntry(key);
|
||||||
|
// }).map(hover_cite).join('<br><br>');
|
||||||
|
// div.id ='dt-cite-hover-box-' + this.citeId;
|
||||||
|
//
|
||||||
|
// // set up visible citation marker
|
||||||
|
// const outerSpan = this.root.querySelector('#citation-');
|
||||||
|
// outerSpan.id = `citation-${this.citeId}`;
|
||||||
|
// // outerSpan.setAttribute('data-hover', dataHoverString); // directly tell HoverBox instead?
|
||||||
|
// const innerSpan = this.root.querySelector('.citation-number');
|
||||||
|
// innerSpan.textContent = inline_cite_short(keys, bibliography);
|
||||||
|
//
|
||||||
|
// HoverBox.get_box(div).bind(outerSpan);
|
||||||
|
// });
|
||||||
|
// } else {
|
||||||
|
// console.error(`You used a d-cite tag (${key}) without including a d-bibliography tag in your article. We can't lookup your citation this way.`)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import { Template } from '../mixins/template.js';
|
import { Template } from '../mixins/template.js';
|
||||||
|
import { HoverBox } from '../helpers/hover-box';
|
||||||
|
|
||||||
const T = Template('d-footnote', `
|
const T = Template('d-footnote', `
|
||||||
<style>
|
<style>
|
||||||
@@ -8,6 +9,7 @@ d-math[block] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
:host {
|
:host {
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
sup {
|
sup {
|
||||||
@@ -24,7 +26,7 @@ span {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
position: absolute;
|
position: fixed;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
left: 0;
|
left: 0;
|
||||||
z-index: 10000;
|
z-index: 10000;
|
||||||
@@ -32,22 +34,23 @@ span {
|
|||||||
|
|
||||||
.dt-hover-box {
|
.dt-hover-box {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
width: 704px;
|
width: 400px;
|
||||||
max-width: 100vw;
|
max-width: 700px;
|
||||||
background-color: #FFF;
|
background-color: #FFF;
|
||||||
opacity: 0.95;
|
opacity: 0.95;
|
||||||
border: 1px solid rgba(0, 0, 0, 0.25);
|
border: 1px solid rgba(0, 0, 0, 0.25);
|
||||||
padding: 8px 16px;
|
padding: 8px 16px;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.2);
|
box-shadow: 0px 2px 10px 2px rgba(0, 0, 0, 0.2);
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<d-hover-box>
|
<div class="container">
|
||||||
<slot id="slot"></slot>
|
<div id="hover-box" class="dt-hover-box">
|
||||||
</d-hover-box>
|
<slot id="slot"></slot>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<sup>
|
<sup>
|
||||||
<span id="fn-" data-hover-ref=""></span>
|
<span id="fn-" data-hover-ref=""></span>
|
||||||
@@ -76,24 +79,23 @@ export class Footnote extends T(HTMLElement) {
|
|||||||
// const slot = this.shadowRoot.querySelector('#slot');
|
// const slot = this.shadowRoot.querySelector('#slot');
|
||||||
// console.warn(slot.textContent);
|
// console.warn(slot.textContent);
|
||||||
// slot.addEventListener('slotchange', this.notify);
|
// slot.addEventListener('slotchange', this.notify);
|
||||||
this.hoverBox = this.root.querySelector('d-hover-box');
|
|
||||||
window.customElements.whenDefined('d-hover-box').then(() => {
|
|
||||||
this.hoverBox.listen(this);
|
|
||||||
});
|
|
||||||
// create numeric ID
|
// create numeric ID
|
||||||
Footnote.currentFootnoteId += 1;
|
Footnote.currentFootnoteId += 1;
|
||||||
const IdString = Footnote.currentFootnoteId.toString();
|
const IdString = Footnote.currentFootnoteId.toString();
|
||||||
this.root.host.id = 'd-footnote-' + IdString;
|
this.root.host.id = 'd-footnote-' + IdString;
|
||||||
|
|
||||||
// set up hidden hover box
|
// set up hidden hover box
|
||||||
const id = 'dt-fn-hover-box-' + IdString;
|
const div = this.root.querySelector('.dt-hover-box');
|
||||||
this.hoverBox.id = id
|
div.id = 'dt-fn-hover-box-' + IdString;
|
||||||
|
|
||||||
// set up visible footnote marker
|
// set up visible footnote marker
|
||||||
const span = this.root.querySelector('#fn-');
|
const span = this.root.querySelector('#fn-');
|
||||||
span.setAttribute('id', 'fn-' + IdString);
|
span.setAttribute('id', 'fn-' + IdString);
|
||||||
span.setAttribute('data-hover-ref', id);
|
span.setAttribute('data-hover-ref', div.id);
|
||||||
span.textContent = IdString;
|
span.textContent = IdString;
|
||||||
|
|
||||||
|
this.hoverbox = new HoverBox(div, span);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,132 +0,0 @@
|
|||||||
import { Template } from '../mixins/template.js';
|
|
||||||
|
|
||||||
const T = Template('d-hover-box', `
|
|
||||||
<style>
|
|
||||||
|
|
||||||
:host {
|
|
||||||
position: absolute;
|
|
||||||
width: 100%;
|
|
||||||
left: 0;
|
|
||||||
z-index: 10000;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
position: relative;
|
|
||||||
width: 704px;
|
|
||||||
max-width: 100vw;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.panel {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100%;
|
|
||||||
border: 1px solid rgba(0, 0, 0, 0.1);
|
|
||||||
background-color: rgb(250, 250, 250);
|
|
||||||
box-shadow: 0 0 7px rgba(0, 0, 0, 0.1);
|
|
||||||
border-radius: 4px;
|
|
||||||
padding: 10px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
<div class="panel">
|
|
||||||
<slot></slot>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`);
|
|
||||||
|
|
||||||
export class HoverBox extends T(HTMLElement) {
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
listen(element) {
|
|
||||||
console.log(element)
|
|
||||||
this.bindDivEvents(this);
|
|
||||||
this.bindTriggerEvents(element);
|
|
||||||
// this.style.display = "block";
|
|
||||||
}
|
|
||||||
|
|
||||||
bindDivEvents(element) {
|
|
||||||
// For mice, same behavior as hovering on links
|
|
||||||
element.addEventListener('mouseover', () => {
|
|
||||||
if (!this.visible) this.showAtNode(element);
|
|
||||||
this.stopTimeout();
|
|
||||||
});
|
|
||||||
element.addEventListener('mouseout', () => {
|
|
||||||
this.extendTimeout(500);
|
|
||||||
});
|
|
||||||
// Don't trigger body touchstart event when touching within box
|
|
||||||
element.addEventListener('touchstart', (event) => {
|
|
||||||
event.stopPropagation();
|
|
||||||
}, {passive: true});
|
|
||||||
// Close box when touching outside box
|
|
||||||
document.body.addEventListener('touchstart', () => {
|
|
||||||
this.hide();
|
|
||||||
}, {passive: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
bindTriggerEvents(node) {
|
|
||||||
node.addEventListener('mouseover', () => {
|
|
||||||
if (!this.visible) {
|
|
||||||
this.showAtNode(node);
|
|
||||||
}
|
|
||||||
this.stopTimeout();
|
|
||||||
});
|
|
||||||
|
|
||||||
node.addEventListener('mouseout', () => {
|
|
||||||
this.extendTimeout(300);
|
|
||||||
});
|
|
||||||
|
|
||||||
node.addEventListener('touchstart', (event) => {
|
|
||||||
if (this.visible) {
|
|
||||||
this.hide();
|
|
||||||
} else {
|
|
||||||
this.showAtNode(node);
|
|
||||||
}
|
|
||||||
// Don't trigger body touchstart event when touching link
|
|
||||||
event.stopPropagation();
|
|
||||||
}, {passive: true});
|
|
||||||
}
|
|
||||||
|
|
||||||
show(position) {
|
|
||||||
this.visible = true;
|
|
||||||
this.style.display = 'block';
|
|
||||||
}
|
|
||||||
|
|
||||||
showAtNode(node) {
|
|
||||||
const bbox = node.getBoundingClientRect();
|
|
||||||
this.show([bbox.right, bbox.bottom]);
|
|
||||||
}
|
|
||||||
|
|
||||||
hide() {
|
|
||||||
this.visible = false;
|
|
||||||
this.style.display = 'none';
|
|
||||||
this.stopTimeout();
|
|
||||||
}
|
|
||||||
|
|
||||||
stopTimeout() {
|
|
||||||
if (this.timeout) {
|
|
||||||
clearTimeout(this.timeout);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
extendTimeout(time) {
|
|
||||||
this.stopTimeout();
|
|
||||||
this.timeout = setTimeout(() => {
|
|
||||||
this.hide();
|
|
||||||
}, time);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,3 +1,50 @@
|
|||||||
export class Title extends HTMLElement {
|
import { Template } from '../mixins/template';
|
||||||
static get is() { return 'd-title'; }
|
|
||||||
|
const T = Template('d-title', `
|
||||||
|
<style>
|
||||||
|
|
||||||
|
:host {
|
||||||
|
padding: 4rem 0 1.5rem;
|
||||||
|
contain: content;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
::slotted(h1) {
|
||||||
|
grid-column: text;
|
||||||
|
font-size: 60px;
|
||||||
|
font-weight: 600;
|
||||||
|
line-height: 1.05em;
|
||||||
|
margin: 0 0 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
::slotted(p) {
|
||||||
|
font-weight: 300;
|
||||||
|
font-size: 1.5rem;
|
||||||
|
line-height: 1.2em;
|
||||||
|
grid-column: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status {
|
||||||
|
margin-top: 0px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #009688;
|
||||||
|
opacity: 0.8;
|
||||||
|
grid-column: kicker;
|
||||||
|
}
|
||||||
|
.status span {
|
||||||
|
line-height: 1;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 6px 0;
|
||||||
|
border-bottom: 1px solid #80cbc4;
|
||||||
|
font-size: 11px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<!-- <div class="status"><span>✓ Peer Reviewed</span></div> -->
|
||||||
|
<slot></slot>
|
||||||
|
`);
|
||||||
|
|
||||||
|
export class Title extends T(HTMLElement) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-2
@@ -38,7 +38,7 @@ export const Controller = {
|
|||||||
citeTag.entries = entries;
|
citeTag.entries = entries;
|
||||||
},
|
},
|
||||||
|
|
||||||
onCiteKeyChanged() {
|
onCiteKeyChanged(event) {
|
||||||
// const [citeTag, keys] = event.detail;
|
// const [citeTag, keys] = event.detail;
|
||||||
|
|
||||||
// update citations
|
// update citations
|
||||||
@@ -71,6 +71,7 @@ export const Controller = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
onBibliographyChanged(event) {
|
onBibliographyChanged(event) {
|
||||||
|
console.info('BibliographyChanged');
|
||||||
const citationListTag = document.querySelector('d-citation-list');
|
const citationListTag = document.querySelector('d-citation-list');
|
||||||
|
|
||||||
const bibliography = event.detail;
|
const bibliography = event.detail;
|
||||||
@@ -145,7 +146,7 @@ export const Controller = {
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
Controller.loaded = true;
|
Controller.loaded = true;
|
||||||
console.log('Controller running DOMContentLoaded');
|
console.log('Controller running DOMContentLoaded')
|
||||||
}
|
}
|
||||||
|
|
||||||
const frontMatterTag = document.querySelector('d-front-matter');
|
const frontMatterTag = document.querySelector('d-front-matter');
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const T = Template('distill-footer', `
|
|||||||
:host {
|
:host {
|
||||||
color: rgba(255, 255, 255, 0.5);
|
color: rgba(255, 255, 255, 0.5);
|
||||||
font-weight: 300;
|
font-weight: 300;
|
||||||
padding: 2rem 0;
|
padding: 60px 0;
|
||||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
background-color: hsl(180, 5%, 15%); /*hsl(200, 60%, 15%);*/
|
background-color: hsl(180, 5%, 15%); /*hsl(200, 60%, 15%);*/
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|||||||
@@ -0,0 +1,109 @@
|
|||||||
|
function make_hover_css(target_node, pos) {
|
||||||
|
const pretty = window.innerWidth > 600;
|
||||||
|
const padding = pretty? 18 : 12;
|
||||||
|
const outer_padding = pretty ? 18 : 0;
|
||||||
|
// const bbox = document.querySelector('body').getBoundingClientRect();
|
||||||
|
const bbox = target_node.offsetParent.getBoundingClientRect();
|
||||||
|
let left = pos[0] - bbox.left, top = pos[1] - bbox.top;
|
||||||
|
let 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};`);
|
||||||
|
}
|
||||||
|
|
||||||
|
export class HoverBox {
|
||||||
|
|
||||||
|
constructor(contentHTML, triggerElement) {
|
||||||
|
this.visible = false;
|
||||||
|
// div hold teh contents of the box that will become visible
|
||||||
|
this.div = contentHTML;
|
||||||
|
this.bindDivEvents(this.div);
|
||||||
|
// triggerElement holds the element that needs to be hovered etc to show contents
|
||||||
|
this.triggerElement = triggerElement;
|
||||||
|
this.bindTriggerEvents(this.triggerElement);
|
||||||
|
this.hide();
|
||||||
|
}
|
||||||
|
|
||||||
|
bindDivEvents(node) {
|
||||||
|
// For mice, same behavior as hovering on links
|
||||||
|
this.div.addEventListener('mouseover', () => {
|
||||||
|
if (!this.visible) this.showAtNode(node);
|
||||||
|
this.stopTimeout();
|
||||||
|
});
|
||||||
|
this.div.addEventListener('mouseout', () => {
|
||||||
|
this.extendTimeout(500);
|
||||||
|
});
|
||||||
|
// Don't trigger body touchstart event when touching within box
|
||||||
|
this.div.addEventListener('touchstart', (event) => {
|
||||||
|
event.stopPropagation();
|
||||||
|
}, {passive: true});
|
||||||
|
// Close box when touching outside box
|
||||||
|
document.body.addEventListener('touchstart', () => {
|
||||||
|
this.hide();
|
||||||
|
}, {passive: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
bindTriggerEvents(node) {
|
||||||
|
node.addEventListener('mouseover', () => {
|
||||||
|
if (!this.visible) {
|
||||||
|
this.showAtNode(node);
|
||||||
|
}
|
||||||
|
this.stopTimeout();
|
||||||
|
});
|
||||||
|
|
||||||
|
node.addEventListener('mouseout', () => {
|
||||||
|
this.extendTimeout(500);
|
||||||
|
});
|
||||||
|
|
||||||
|
node.addEventListener('touchstart', (event) => {
|
||||||
|
if (this.visible) {
|
||||||
|
this.hide();
|
||||||
|
} else {
|
||||||
|
this.showAtNode(node);
|
||||||
|
}
|
||||||
|
// Don't trigger body touchstart event when touching link
|
||||||
|
event.stopPropagation();
|
||||||
|
}, {passive: true});
|
||||||
|
}
|
||||||
|
|
||||||
|
show(position) {
|
||||||
|
this.visible = true;
|
||||||
|
// const css = make_hover_css(this.triggerElement, position);
|
||||||
|
this.div.setAttribute('style', 'display: block;' );
|
||||||
|
}
|
||||||
|
|
||||||
|
showAtNode(node) {
|
||||||
|
const bbox = node.getBoundingClientRect();
|
||||||
|
this.show([bbox.right, bbox.bottom]);
|
||||||
|
}
|
||||||
|
|
||||||
|
hide() {
|
||||||
|
this.visible = false;
|
||||||
|
this.div.setAttribute('style', 'display: none;');
|
||||||
|
this.stopTimeout();
|
||||||
|
}
|
||||||
|
|
||||||
|
stopTimeout() {
|
||||||
|
if (this.timeout) {
|
||||||
|
clearTimeout(this.timeout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extendTimeout(time) {
|
||||||
|
this.stopTimeout();
|
||||||
|
this.timeout = setTimeout(() => {
|
||||||
|
this.hide();
|
||||||
|
}, time);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -3,7 +3,6 @@ d-article {
|
|||||||
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
border-top: 1px solid rgba(0, 0, 0, 0.1);
|
||||||
padding-top: 2rem;
|
padding-top: 2rem;
|
||||||
color: rgba(0, 0, 0, 0.8);
|
color: rgba(0, 0, 0, 0.8);
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d-article > * {
|
d-article > * {
|
||||||
@@ -18,7 +17,7 @@ d-article > * {
|
|||||||
|
|
||||||
@media(min-width: 1024px) {
|
@media(min-width: 1024px) {
|
||||||
d-article {
|
d-article {
|
||||||
font-size: 1.06rem;
|
font-size: 1rem;
|
||||||
line-height: 1.7em;
|
line-height: 1.7em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,6 +102,7 @@ d-article blockquote {
|
|||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
margin-right: 0;
|
margin-right: 0;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
}
|
}
|
||||||
|
|
||||||
d-article blockquote {
|
d-article blockquote {
|
||||||
@@ -132,15 +132,11 @@ d-article ol {
|
|||||||
}
|
}
|
||||||
|
|
||||||
d-article li {
|
d-article li {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 24px;
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
d-article li:last-child {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
d-article pre {
|
d-article pre {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
@@ -169,14 +165,11 @@ d-article span.equation-mimic {
|
|||||||
d-article > d-code,
|
d-article > d-code,
|
||||||
d-article section > d-code {
|
d-article section > d-code {
|
||||||
display: block;
|
display: block;
|
||||||
overflow-x: scroll;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d-article > d-math[block],
|
d-article > d-math[block],
|
||||||
d-article section > d-math[block] {
|
d-article section > d-math[block] {
|
||||||
display: block;
|
display: block;
|
||||||
overflow-x: scroll;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d-article .citation {
|
d-article .citation {
|
||||||
|
|||||||
+1
-15
@@ -7,28 +7,14 @@ d-byline {
|
|||||||
min-height: 1.8em;
|
min-height: 1.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
d-byline .byline {
|
d-byline .byline {
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 2fr 1fr 1fr;
|
||||||
grid-column: text;
|
grid-column: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(min-width: 768px) {
|
|
||||||
d-byline .byline {
|
|
||||||
grid-template-columns: 1fr 1fr 1fr 1fr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
d-byline .authors-affiliations {
|
d-byline .authors-affiliations {
|
||||||
grid-column-end: span 2;
|
|
||||||
grid-template-columns: 1fr 1fr;
|
grid-template-columns: 1fr 1fr;
|
||||||
margin-bottom: 1em;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(min-width: 768px) {
|
|
||||||
d-byline .authors-affiliations {
|
|
||||||
margin-bottom: 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
d-byline h3 {
|
d-byline h3 {
|
||||||
|
|||||||
@@ -1,55 +0,0 @@
|
|||||||
d-title {
|
|
||||||
padding: 2rem 0 1.5rem;
|
|
||||||
contain: content;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(min-width: 768px) {
|
|
||||||
d-title {
|
|
||||||
padding: 4rem 0 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
d-title h1 {
|
|
||||||
grid-column: text;
|
|
||||||
font-size: 40px;
|
|
||||||
font-weight: 700;
|
|
||||||
line-height: 1.05em;
|
|
||||||
margin: 0 0 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(min-width: 768px) {
|
|
||||||
d-title h1 {
|
|
||||||
font-size: 60px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
d-title p {
|
|
||||||
font-weight: 300;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
line-height: 1.7em;
|
|
||||||
grid-column: text;
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(min-width: 768px) {
|
|
||||||
d-title p {
|
|
||||||
font-size: 1.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
d-title .status {
|
|
||||||
margin-top: 0px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: #009688;
|
|
||||||
opacity: 0.8;
|
|
||||||
grid-column: kicker;
|
|
||||||
}
|
|
||||||
|
|
||||||
d-title .status span {
|
|
||||||
line-height: 1;
|
|
||||||
display: inline-block;
|
|
||||||
padding: 6px 0;
|
|
||||||
border-bottom: 1px solid #80cbc4;
|
|
||||||
font-size: 11px;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
html {
|
html {
|
||||||
font-size: 14px;
|
font-size: 16px;
|
||||||
line-height: 1.6em;
|
line-height: 1.6em;
|
||||||
/* font-family: "Libre Franklin", "Helvetica Neue", sans-serif; */
|
/* font-family: "Libre Franklin", "Helvetica Neue", sans-serif; */
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Arial, sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", "Helvetica Neue", Arial, sans-serif;
|
||||||
@@ -9,12 +9,6 @@ html {
|
|||||||
-webkit-text-size-adjust: 100%;
|
-webkit-text-size-adjust: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media(min-width: 768px) {
|
|
||||||
html {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
body {
|
body {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,10 +3,9 @@ import layout from './styles-layout.css';
|
|||||||
import print from './styles-print.css';
|
import print from './styles-print.css';
|
||||||
import byline from './d-byline.css';
|
import byline from './d-byline.css';
|
||||||
import article from './d-article.css';
|
import article from './d-article.css';
|
||||||
import title from './d-title.css';
|
|
||||||
import math from './d-math.css';
|
import math from './d-math.css';
|
||||||
|
|
||||||
export const styles = base + layout + title + byline + article + math + print;
|
export const styles = base + layout + byline + article + math + print;
|
||||||
|
|
||||||
export function makeStyleTag(dom) {
|
export function makeStyleTag(dom) {
|
||||||
|
|
||||||
|
|||||||
@@ -37,11 +37,6 @@ export default function(dom, data) {
|
|||||||
<meta property="description" itemprop="description" content="${escape(data.description)}" />
|
<meta property="description" itemprop="description" content="${escape(data.description)}" />
|
||||||
<meta property="article:published" itemprop="datePublished" content="${data.publishedISODateOnly}" />
|
<meta property="article:published" itemprop="datePublished" content="${data.publishedISODateOnly}" />
|
||||||
<meta property="article:created" itemprop="dateCreated" content="${data.publishedISODateOnly}" />
|
<meta property="article:created" itemprop="dateCreated" content="${data.publishedISODateOnly}" />
|
||||||
`);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (data.updatedDate) {
|
|
||||||
appendHead(`
|
|
||||||
<meta property="article:modified" itemprop="dateModified" content="${data.updatedDate.toISOString()}" />
|
<meta property="article:modified" itemprop="dateModified" content="${data.updatedDate.toISOString()}" />
|
||||||
`);
|
`);
|
||||||
}
|
}
|
||||||
|
|||||||
+36
-67
@@ -1,78 +1,47 @@
|
|||||||
const webcomponentPath = 'https://distill.pub/third-party/polyfills/webcomponents-lite.js';
|
const webcomponentPath = 'https://distill.pub/third-party/polyfills/webcomponents-lite.js';
|
||||||
const intersectionObserverPath = 'https://distill.pub/third-party/polyfills/intersection-observer.js';
|
const intersectionObserverPath = 'https://distill.pub/third-party/polyfills/intersection-observer.js';
|
||||||
|
|
||||||
// const template = `
|
const template = `
|
||||||
// if ('IntersectionObserver' in window &&
|
if ('IntersectionObserver' in window &&
|
||||||
// 'IntersectionObserverEntry' in window &&
|
'IntersectionObserverEntry' in window &&
|
||||||
// 'intersectionRatio' in IntersectionObserverEntry.prototype) {
|
'intersectionRatio' in IntersectionObserverEntry.prototype) {
|
||||||
// // Platform supports IntersectionObserver natively! :-)
|
// Platform supports IntersectionObserver natively! :-)
|
||||||
// if (!('isIntersecting' in IntersectionObserverEntry.prototype)) {
|
if (!('isIntersecting' in IntersectionObserverEntry.prototype)) {
|
||||||
// Object.defineProperty(IntersectionObserverEntry.prototype,
|
Object.defineProperty(IntersectionObserverEntry.prototype,
|
||||||
// 'isIntersecting', {
|
'isIntersecting', {
|
||||||
// get: function () {
|
get: function () {
|
||||||
// return this.intersectionRatio > 0;
|
return this.intersectionRatio > 0;
|
||||||
// }
|
}
|
||||||
// });
|
});
|
||||||
// }
|
}
|
||||||
// } else {
|
} else {
|
||||||
// // Platform does not support webcomponents--loading polyfills synchronously.
|
// Platform does not support webcomponents--loading polyfills synchronously.
|
||||||
// const scriptTag = document.createElement('script');
|
const scriptTag = document.createElement('script');
|
||||||
// scriptTag.src = '${intersectionObserverPath}';
|
scriptTag.src = '${intersectionObserverPath}';
|
||||||
// scriptTag.async = false;
|
scriptTag.async = false;
|
||||||
// document.currentScript.parentNode.insertBefore(scriptTag, document.currentScript.nextSibling);
|
document.currentScript.parentNode.insertBefore(scriptTag, document.currentScript.nextSibling);
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// if ('registerElement' in document &&
|
|
||||||
// 'import' in document.createElement('link') &&
|
|
||||||
// 'content' in document.createElement('template')) {
|
|
||||||
// // Platform supports webcomponents natively! :-)
|
|
||||||
// } else {
|
|
||||||
// // Platform does not support webcomponents--loading polyfills synchronously.
|
|
||||||
// const scriptTag = document.createElement('script');
|
|
||||||
// scriptTag.src = '${webcomponentPath}';
|
|
||||||
// scriptTag.async = false;
|
|
||||||
// document.currentScript.parentNode.insertBefore(scriptTag, document.currentScript.nextSibling);
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
//
|
|
||||||
// `;
|
|
||||||
|
|
||||||
|
if ('registerElement' in document &&
|
||||||
const addBackIn = `
|
'import' in document.createElement('link') &&
|
||||||
window.addEventListener('WebComponentsReady', function() {
|
'content' in document.createElement('template')) {
|
||||||
console.warn('WebComponentsReady');
|
// Platform supports webcomponents natively! :-)
|
||||||
const loaderTag = document.createElement('script');
|
} else {
|
||||||
loaderTag.src = 'http://localhost:8888/dist/template.v2.js';
|
// Platform does not support webcomponents--loading polyfills synchronously.
|
||||||
document.head.insertBefore(loaderTag, document.head.firstChild);
|
const scriptTag = document.createElement('script');
|
||||||
});
|
scriptTag.src = '${webcomponentPath}';
|
||||||
|
scriptTag.async = false;
|
||||||
|
document.currentScript.parentNode.insertBefore(scriptTag, document.currentScript.nextSibling);
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
export default function render(dom) {
|
export default function render(dom) {
|
||||||
// pull out template script tag
|
|
||||||
const templateTag = dom.querySelector('script[src*="template.v2.js"]');
|
|
||||||
if (templateTag) {
|
|
||||||
templateTag.parentNode.removeChild(templateTag);
|
|
||||||
} else {
|
|
||||||
console.info('FYI: Did not find template tag when trying to remove it. You may not have added it. Be aware that our polyfills will add it.')
|
|
||||||
}
|
|
||||||
|
|
||||||
// add loader
|
|
||||||
const loaderTag = dom.createElement('script');
|
|
||||||
loaderTag.src = 'https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/1.0.17/webcomponents-loader.js';
|
|
||||||
dom.head.insertBefore(loaderTag, dom.head.firstChild);
|
|
||||||
|
|
||||||
// add loader event listener to add tempalrte back in
|
|
||||||
const addTag = dom.createElement('script');
|
|
||||||
addTag.innerHTML = addBackIn;
|
|
||||||
dom.head.insertBefore(addTag, dom.head.firstChild);
|
|
||||||
|
|
||||||
|
|
||||||
// create polyfill script tag
|
// create polyfill script tag
|
||||||
// const polyfillScriptTag = dom.createElement('script');
|
const polyfillScriptTag = dom.createElement('script');
|
||||||
// polyfillScriptTag.innerHTML = template;
|
polyfillScriptTag.innerHTML = template;
|
||||||
// polyfillScriptTag.id = 'polyfills';
|
polyfillScriptTag.id = 'polyfills';
|
||||||
|
|
||||||
// insert at appropriate position--before any other script tag
|
// insert at appropriate position--before any other script tag
|
||||||
// const firstScriptTag = dom.head.querySelector('script');
|
const firstScriptTag = dom.head.querySelector('script');
|
||||||
// dom.head.insertBefore(polyfillScriptTag, firstScriptTag);
|
dom.head.insertBefore(polyfillScriptTag, firstScriptTag);
|
||||||
}
|
}
|
||||||
|
|||||||
+86
-84
@@ -2,7 +2,8 @@ import { Template } from '../mixins/template';
|
|||||||
import { scaleLinear } from 'd3-scale';
|
import { scaleLinear } from 'd3-scale';
|
||||||
import { range } from 'd3-array';
|
import { range } from 'd3-array';
|
||||||
import { drag } from 'd3-drag';
|
import { drag } from 'd3-drag';
|
||||||
import { select, event as currentEvent } from 'd3-selection';
|
import { select } from 'd3-selection';
|
||||||
|
import {event as currentEvent } from 'd3-selection';
|
||||||
|
|
||||||
const T = Template('d-slider', `
|
const T = Template('d-slider', `
|
||||||
<style>
|
<style>
|
||||||
@@ -90,14 +91,14 @@ const T = Template('d-slider', `
|
|||||||
|
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<div class='background'>
|
<div class="background">
|
||||||
<div class='track'></div>
|
<div class="track"></div>
|
||||||
<div class='track-fill'></div>
|
<div class="track-fill"></div>
|
||||||
<div class='knob-container'>
|
<div class="knob-container">
|
||||||
<div class='knob-highlight'></div>
|
<div class="knob-highlight"></div>
|
||||||
<div class='knob'></div>
|
<div class="knob"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class='ticks'></div>
|
<div class="ticks"></div>
|
||||||
</div>
|
</div>
|
||||||
`);
|
`);
|
||||||
|
|
||||||
@@ -121,18 +122,18 @@ export class Slider extends T(HTMLElement) {
|
|||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
this.connected = true;
|
this.connected = true;
|
||||||
this.setAttribute('role', 'slider');
|
this.setAttribute("role", "slider");
|
||||||
// Makes the element tab-able.
|
// Makes the element tab-able.
|
||||||
if (!this.hasAttribute('tabindex')) { this.setAttribute('tabindex', 0); }
|
if (!this.hasAttribute("tabindex")) { this.setAttribute("tabindex", 0); }
|
||||||
|
|
||||||
// Keeps track of keyboard vs. mouse interactions for focus rings
|
// Keeps track of keyboard vs. mouse interactions for focus rings
|
||||||
this.mouseEvent = false;
|
this.mouseEvent = false;
|
||||||
|
|
||||||
// Handles to shadow DOM elements
|
// Handles to shadow DOM elements
|
||||||
this.knob = this.root.querySelector('.knob-container');
|
this.knob = this.root.querySelector(".knob-container");
|
||||||
this.background = this.root.querySelector('.background');
|
this.background = this.root.querySelector(".background");
|
||||||
this.trackFill = this.root.querySelector('.track-fill');
|
this.trackFill = this.root.querySelector(".track-fill");
|
||||||
this.track = this.root.querySelector('.track');
|
this.track = this.root.querySelector(".track");
|
||||||
|
|
||||||
// Default values for attributes
|
// Default values for attributes
|
||||||
this.min = this.min ? this.min : 0;
|
this.min = this.min ? this.min : 0;
|
||||||
@@ -147,109 +148,109 @@ export class Slider extends T(HTMLElement) {
|
|||||||
this.renderTicks();
|
this.renderTicks();
|
||||||
|
|
||||||
this.drag = drag()
|
this.drag = drag()
|
||||||
.container(this.background)
|
.container(this.track)
|
||||||
.on('start', () => {
|
.on("start", () => {
|
||||||
this.mouseEvent = true;
|
this.mouseEvent = true;
|
||||||
this.background.classList.add('mousedown');
|
this.background.classList.add("mousedown");
|
||||||
this.changeValue = this.value;
|
this.changeValue = this.value;
|
||||||
this.dragUpdate();
|
this.dragUpdate();
|
||||||
})
|
})
|
||||||
.on('drag', () => {
|
.on("drag", () => {
|
||||||
this.dragUpdate();
|
this.dragUpdate();
|
||||||
})
|
})
|
||||||
.on('end', () => {
|
.on("end", () => {
|
||||||
this.mouseEvent = false;
|
this.mouseEvent = false;
|
||||||
this.background.classList.remove('mousedown');
|
this.background.classList.remove("mousedown");
|
||||||
this.dragUpdate();
|
this.dragUpdate();
|
||||||
if (this.changeValue !== this.value) this.dispatchChange();
|
if (this.changeValue !== this.value) this.dispatchChange();
|
||||||
this.changeValue = this.value;
|
this.changeValue = this.value;
|
||||||
});
|
});
|
||||||
this.drag(select(this.background));
|
this.drag(select(this.background));
|
||||||
|
|
||||||
this.addEventListener('focusin', () => {
|
this.addEventListener("focusin", (e) => {
|
||||||
if(!this.mouseEvent) {
|
if(!this.mouseEvent) {
|
||||||
this.background.classList.add('focus');
|
this.background.classList.add("focus");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.addEventListener('focusout', () => {
|
this.addEventListener("focusout", (e) => {
|
||||||
this.background.classList.remove('focus');
|
this.background.classList.remove("focus");
|
||||||
});
|
});
|
||||||
this.addEventListener('keydown', this.onKeyDown);
|
this.addEventListener("keydown", this.onKeyDown);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static get observedAttributes() {return ['min', 'max', 'value', 'step', 'ticks', 'origin', 'tickValues', 'tickLabels']; }
|
static get observedAttributes() {return ["min", "max", "value", "step", "ticks", "origin", "tickValues", "tickLabels"]; }
|
||||||
|
|
||||||
attributeChangedCallback(attr, oldValue, newValue) {
|
attributeChangedCallback(attr, oldValue, newValue) {
|
||||||
if (attr == 'min') {
|
if (attr == "min") {
|
||||||
this.min = +newValue;
|
this.min = +newValue;
|
||||||
this.setAttribute('aria-valuemin', this.min);
|
this.setAttribute("aria-valuemin", this.min);
|
||||||
}
|
}
|
||||||
if (attr == 'max') {
|
if (attr == "max") {
|
||||||
this.max = +newValue;
|
this.max = +newValue;
|
||||||
this.setAttribute('aria-valuemax', this.max);
|
this.setAttribute("aria-valuemax", this.max);
|
||||||
}
|
}
|
||||||
if (attr == 'value') {
|
if (attr == "value") {
|
||||||
this.update(+newValue);
|
this.update(+newValue);
|
||||||
}
|
}
|
||||||
if (attr == 'origin') {
|
if (attr == "origin") {
|
||||||
this.origin = +newValue;
|
this.origin = +newValue;
|
||||||
this.update(this.value);
|
this.update(this.value);
|
||||||
}
|
}
|
||||||
if (attr == 'step') {
|
if (attr == "step") {
|
||||||
if (newValue > 0) {
|
if (newValue > 0) {
|
||||||
this.step = +newValue;
|
this.step = +newValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (attr == 'ticks') {
|
if (attr == "ticks") {
|
||||||
this.ticks = (newValue === '' ? true : newValue);
|
this.ticks = (newValue === "" ? true : newValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onKeyDown(event) {
|
onKeyDown(e) {
|
||||||
this.changeValue = this.value;
|
this.changeValue = this.value;
|
||||||
let stopPropagation = false;
|
let stopPropagation = false;
|
||||||
switch (event.keyCode) {
|
switch (event.keyCode) {
|
||||||
case keyCodes.left:
|
case keyCodes.left:
|
||||||
case keyCodes.down:
|
case keyCodes.down:
|
||||||
this.update(this.value - this.step);
|
this.update(this.value - this.step)
|
||||||
stopPropagation = true;
|
stopPropagation = true;
|
||||||
break;
|
break;
|
||||||
case keyCodes.right:
|
case keyCodes.right:
|
||||||
case keyCodes.up:
|
case keyCodes.up:
|
||||||
this.update(this.value + this.step);
|
this.update(this.value + this.step)
|
||||||
stopPropagation = true;
|
stopPropagation = true;
|
||||||
break;
|
break;
|
||||||
case keyCodes.pageUp:
|
case keyCodes.pageUp:
|
||||||
this.update(this.value + this.step * 10);
|
this.update(this.value + this.step * 10)
|
||||||
stopPropagation = true;
|
stopPropagation = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case keyCodes.pageDown:
|
case keyCodes.pageDown:
|
||||||
this.update(this.value + this.step * 10);
|
this.update(this.value + this.step * 10)
|
||||||
stopPropagation = true;
|
stopPropagation = true;
|
||||||
break;
|
break;
|
||||||
case keyCodes.home:
|
case keyCodes.home:
|
||||||
this.update(this.min);
|
this.update(this.min);
|
||||||
stopPropagation = true;
|
stopPropagation = true;
|
||||||
break;
|
break;
|
||||||
case keyCodes.end:
|
case keyCodes.end:
|
||||||
this.update(this.max);
|
this.update(this.max);
|
||||||
stopPropagation = true;
|
stopPropagation = true;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (stopPropagation) {
|
if (stopPropagation) {
|
||||||
this.background.classList.add('focus');
|
this.background.classList.add("focus");
|
||||||
event.preventDefault();
|
e.preventDefault();
|
||||||
event.stopPropagation();
|
e.stopPropagation();
|
||||||
if (this.changeValue !== this.value) this.dispatchChange();
|
if (this.changeValue !== this.value) this.dispatchChange();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
validateValueRange(min, max, value) {
|
validateValueRange(min, max, value) {
|
||||||
return Math.max(Math.min(max, value), min);
|
return Math.max(Math.min(max, value), min)
|
||||||
}
|
}
|
||||||
|
|
||||||
quantizeValue(value, step) {
|
quantizeValue(value, step) {
|
||||||
@@ -258,60 +259,61 @@ export class Slider extends T(HTMLElement) {
|
|||||||
|
|
||||||
dragUpdate() {
|
dragUpdate() {
|
||||||
const bbox = this.background.getBoundingClientRect();
|
const bbox = this.background.getBoundingClientRect();
|
||||||
const x = currentEvent.x;
|
const left = bbox.left;
|
||||||
|
const x = event.x - left;
|
||||||
const width = bbox.width;
|
const width = bbox.width;
|
||||||
this.update(this.scale.invert(x / width));
|
this.update(this.scale.invert(x / width));
|
||||||
}
|
}
|
||||||
|
|
||||||
update(value) {
|
update(value) {
|
||||||
let v = value;
|
let v = value;
|
||||||
if (this.step !== 'any') {
|
if (this.step !== "any") {
|
||||||
v = this.quantizeValue(value, this.step);
|
v = this.quantizeValue(value, this.step);
|
||||||
}
|
}
|
||||||
v = this.validateValueRange(this.min, this.max, v);
|
v = this.validateValueRange(this.min, this.max, v);
|
||||||
if (this.connected) {
|
if (this.connected) {
|
||||||
this.knob.style.left = this.scale(v) * 100 + '%';
|
this.knob.style.left = this.scale(v) * 100 + "%";
|
||||||
this.trackFill.style.width = this.scale(this.min + Math.abs(v - this.origin)) * 100 + '%';
|
this.trackFill.style.width = this.scale(this.min + Math.abs(v - this.origin)) * 100 + "%";
|
||||||
this.trackFill.style.left = this.scale(Math.min(v, this.origin)) * 100 + '%';
|
this.trackFill.style.left = this.scale(Math.min(v, this.origin)) * 100 + "%";
|
||||||
}
|
}
|
||||||
if (this.value !== v) {
|
if (this.value !== v) {
|
||||||
this.value = v;
|
this.value = v;
|
||||||
this.setAttribute('aria-valuenow', this.value);
|
this.setAttribute("aria-valuenow", this.value);
|
||||||
this.dispatchInput();
|
this.dispatchInput();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispatches only on a committed change (basically only on mouseup).
|
// Dispatches only on a committed change (basically only on mouseup).
|
||||||
dispatchChange() {
|
dispatchChange() {
|
||||||
const e = new Event('change');
|
const e = new Event("change");
|
||||||
this.dispatchEvent(e, {});
|
this.dispatchEvent(e, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispatches on each value change.
|
// Dispatches on each value change.
|
||||||
dispatchInput() {
|
dispatchInput() {
|
||||||
const e = new Event('input');
|
const e = new Event("input");
|
||||||
this.dispatchEvent(e, {});
|
this.dispatchEvent(e, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
renderTicks() {
|
renderTicks() {
|
||||||
const ticksContainer = this.root.querySelector('.ticks');
|
const ticksContainer = this.root.querySelector(".ticks");
|
||||||
if (this.ticks !== false) {
|
if (this.ticks !== false) {
|
||||||
let tickData = [];
|
let tickData = [];
|
||||||
if (this.ticks > 0) {
|
if (this.ticks > 0) {
|
||||||
tickData = this.scale.ticks(this.ticks);
|
tickData = this.scale.ticks(this.ticks);
|
||||||
} else if (this.step === 'any') {
|
} else if (this.step === "any") {
|
||||||
tickData = this.scale.ticks();
|
tickData = this.scale.ticks();
|
||||||
} else {
|
} else {
|
||||||
tickData = range(this.min, this.max + 1e-6, this.step);
|
tickData = range(this.min, this.max + 1e-6, this.step);
|
||||||
}
|
}
|
||||||
tickData.forEach(d => {
|
tickData.forEach(d => {
|
||||||
const tick = document.createElement('div');
|
const tick = document.createElement("div");
|
||||||
tick.classList.add('tick');
|
tick.classList.add("tick");
|
||||||
tick.style.left = this.scale(d) * 100 + '%';
|
tick.style.left = this.scale(d) * 100 + "%";
|
||||||
ticksContainer.appendChild(tick);
|
ticksContainer.appendChild(tick)
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
ticksContainer.style.display = 'none';
|
ticksContainer.style.display = "none";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user