2018-05-18 03:25:45 +00:00
|
|
|
(() => {
|
|
|
|
const doc = document;
|
|
|
|
const disableBuilds = true;
|
2018-05-13 10:47:00 +00:00
|
|
|
|
2018-05-18 03:25:45 +00:00
|
|
|
let ctr = 0;
|
2018-05-13 10:47:00 +00:00
|
|
|
|
2018-05-18 03:25:45 +00:00
|
|
|
const byId = function (id) {
|
2018-05-18 06:23:36 +00:00
|
|
|
if (typeof id === 'string') { return doc.getElementById(id); }
|
|
|
|
return id;
|
2018-05-13 10:47:00 +00:00
|
|
|
};
|
|
|
|
|
2018-05-18 03:25:45 +00:00
|
|
|
const query = function (query, root) {
|
2018-05-18 06:23:36 +00:00
|
|
|
if (!query) { return []; }
|
2018-05-18 03:25:45 +00:00
|
|
|
if (typeof query !== 'string') { return [...query]; }
|
2018-05-18 06:23:36 +00:00
|
|
|
if (typeof root === 'string') {
|
|
|
|
root = byId(root);
|
|
|
|
if (!root) { return []; }
|
|
|
|
}
|
2018-05-13 10:47:00 +00:00
|
|
|
|
2018-05-18 06:23:36 +00:00
|
|
|
root = root || document;
|
2018-05-18 03:25:45 +00:00
|
|
|
const rootIsDoc = (root.nodeType === 9);
|
|
|
|
const doc = rootIsDoc ? root : (root.ownerDocument || document);
|
2018-05-13 10:47:00 +00:00
|
|
|
|
2018-05-18 06:23:36 +00:00
|
|
|
// rewrite the query to be ID rooted
|
2018-05-18 03:25:45 +00:00
|
|
|
if (!rootIsDoc || ('>~+'.includes(query[0]))) {
|
2018-05-18 06:23:36 +00:00
|
|
|
root.id = root.id || ('qUnique' + (ctr++));
|
|
|
|
query = '#' + root.id + ' ' + query;
|
|
|
|
}
|
|
|
|
// don't choke on something like ".yada.yada >"
|
2018-05-18 03:25:45 +00:00
|
|
|
if ('>~+'.includes(query.slice(-1))) { query += ' *'; }
|
2018-05-13 10:47:00 +00:00
|
|
|
|
2018-05-18 03:25:45 +00:00
|
|
|
return [...doc.querySelectorAll(query)];
|
2018-05-13 10:47:00 +00:00
|
|
|
};
|
|
|
|
|
2018-05-18 03:25:45 +00:00
|
|
|
const ua = navigator.userAgent;
|
|
|
|
const isFF = parseFloat(ua.split('Firefox/')[1]) || undefined;
|
|
|
|
const isWK = parseFloat(ua.split('WebKit/')[1]) || undefined;
|
|
|
|
const isOpera = parseFloat(ua.split('Opera/')[1]) || undefined;
|
2018-05-13 10:47:00 +00:00
|
|
|
|
2018-05-18 03:25:45 +00:00
|
|
|
const canTransition = (function () {
|
|
|
|
const ver = parseFloat(ua.split('Version/')[1]) || undefined;
|
2018-05-18 06:23:36 +00:00
|
|
|
// test to determine if this browser can handle CSS transitions.
|
2018-05-18 03:25:45 +00:00
|
|
|
const cachedCanTransition =
|
2018-05-18 06:23:36 +00:00
|
|
|
(isWK || (isFF && isFF > 3.6) || (isOpera && ver >= 10.5));
|
|
|
|
return function () { return cachedCanTransition; };
|
2018-05-13 10:47:00 +00:00
|
|
|
})();
|
|
|
|
|
|
|
|
//
|
|
|
|
// Slide class
|
|
|
|
//
|
2018-05-18 03:25:45 +00:00
|
|
|
const Slide = function (node, idx) {
|
2018-05-18 06:23:36 +00:00
|
|
|
this._node = node;
|
|
|
|
if (idx >= 0) {
|
|
|
|
this._count = idx + 1;
|
|
|
|
}
|
|
|
|
if (this._node) {
|
2018-05-18 03:25:45 +00:00
|
|
|
this._node.classList.add('slide', 'distant-slide');
|
2018-05-18 06:23:36 +00:00
|
|
|
}
|
|
|
|
this._makeCounter();
|
|
|
|
this._makeBuildList();
|
2018-05-13 10:47:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Slide.prototype = {
|
2018-05-18 06:23:36 +00:00
|
|
|
_node: null,
|
|
|
|
_count: 0,
|
|
|
|
_buildList: [],
|
|
|
|
_visited: false,
|
|
|
|
_currentState: '',
|
|
|
|
_states: [ 'distant-slide', 'far-past',
|
|
|
|
'past', 'current', 'future',
|
|
|
|
'far-future', 'distant-slide' ],
|
2018-05-18 03:25:45 +00:00
|
|
|
setState (state) {
|
2018-05-18 06:23:36 +00:00
|
|
|
if (typeof state !== 'string') {
|
|
|
|
state = this._states[state];
|
|
|
|
}
|
|
|
|
if (state === 'current' && !this._visited) {
|
|
|
|
this._visited = true;
|
|
|
|
this._makeBuildList();
|
|
|
|
}
|
2018-05-18 03:25:45 +00:00
|
|
|
this._node.classList.remove(...this._states);
|
|
|
|
this._node.classList.add(state);
|
2018-05-18 06:23:36 +00:00
|
|
|
this._currentState = state;
|
2018-05-13 10:47:00 +00:00
|
|
|
|
2018-05-18 06:23:36 +00:00
|
|
|
// delay first auto run. Really wish this were in CSS.
|
|
|
|
/*
|
|
|
|
this._runAutos();
|
|
|
|
*/
|
2018-05-18 03:25:45 +00:00
|
|
|
const _t = this;
|
2018-05-18 06:23:36 +00:00
|
|
|
setTimeout(function () { _t._runAutos(); }, 400);
|
|
|
|
},
|
2018-05-18 03:25:45 +00:00
|
|
|
_makeCounter () {
|
2018-05-18 06:23:36 +00:00
|
|
|
if (!this._count || !this._node) { return; }
|
2018-05-18 03:25:45 +00:00
|
|
|
const c = doc.createElement('span');
|
2018-05-18 06:23:36 +00:00
|
|
|
c.innerHTML = this._count;
|
|
|
|
c.className = 'counter';
|
- Breaking change: Extension now formatted as export (and `this` is set to editor, including for `callback`)
- Breaking change: Locale now formatted as export
- Breaking change: Moved out remaining modular i18n (imagelib) to own folder
- Breaking change: Drop `executeAfterLoads` (and getJSPDF/getCanvg)
- Breaking change: `RGBColor` must accept `new`
- Breaking change: canvg - `stackBlurCanvasRGBA` must be set now by function (`setStackBlurCanvasRGBA`) rather than global; `canvg` now a named export
- Breaking change: Avoid passing `canvg`/`buildCanvgCallback` to extensions (have them import)
- Fix: i18nize imaglib more deeply
- Fix: Positioning of Document Properties dialog (Fixes #246)
- Fix (regression): PDF Export (Fixes #249)
- Fix (regression): Add polyfill for `ChildNode`/`ParentNode` (and use further)
- Fix (regression): Apply Babel universally to dependencies
- Fix (regression): Ordering of `uaPrefix` function in `svgEditor.js`
- Fix (regression): Embedded API
- Fix (embedded editor): Fix backspace key in Firefox so it doesn't navigate out of frame
- Fix: Alert if no exportWindow for PDF (e.g., if blocked)
- Refactoring( RGBColor) `RGBColor` as class, without rebuilding constants, optimize string replacement, move methods to prototype, use templates and object literals, use `Object.keys`
- Refactoring (canvg) Use classes more internally, use shorthand objects; array extras, return to lazy-loading
- Refactoring: Use Promises in place of `$.getScript`; always return Promises in case deciding to await resolving
- Refactoring: Avoid importing `RGBColor` into `svgutils.js` (jsPDF imports it itself)
- Refactoring: Arrow functions, destructuring, shorter property references
- Refactoring: Fix `lang` and `dir` for locales (though not in use currently anyways)
- Refactoring: Provide path config for canvg, jspdf
2018-06-02 01:14:38 +00:00
|
|
|
this._node.append(c);
|
2018-05-18 06:23:36 +00:00
|
|
|
},
|
2018-05-18 03:25:45 +00:00
|
|
|
_makeBuildList () {
|
2018-05-18 06:23:36 +00:00
|
|
|
this._buildList = [];
|
|
|
|
if (disableBuilds) { return; }
|
|
|
|
if (this._node) {
|
|
|
|
this._buildList = query('[data-build] > *', this._node);
|
|
|
|
}
|
|
|
|
this._buildList.forEach(function (el) {
|
2018-05-18 03:25:45 +00:00
|
|
|
el.classList.add('to-build');
|
2018-05-18 06:23:36 +00:00
|
|
|
});
|
|
|
|
},
|
2018-05-18 03:25:45 +00:00
|
|
|
_runAutos () {
|
2018-05-18 06:23:36 +00:00
|
|
|
if (this._currentState !== 'current') {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
// find the next auto, slice it out of the list, and run it
|
2018-05-18 03:25:45 +00:00
|
|
|
let idx = -1;
|
2018-05-18 06:23:36 +00:00
|
|
|
this._buildList.some(function (n, i) {
|
|
|
|
if (n.hasAttribute('data-auto')) {
|
|
|
|
idx = i;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
});
|
|
|
|
if (idx >= 0) {
|
2018-05-18 03:25:45 +00:00
|
|
|
const elem = this._buildList.splice(idx, 1)[0];
|
|
|
|
const transitionEnd = isWK ? 'webkitTransitionEnd' : (isFF ? 'mozTransitionEnd' : 'oTransitionEnd');
|
|
|
|
const _t = this;
|
2018-05-18 06:23:36 +00:00
|
|
|
if (canTransition()) {
|
2018-05-18 03:25:45 +00:00
|
|
|
const l = function (evt) {
|
2018-05-18 06:23:36 +00:00
|
|
|
elem.parentNode.removeEventListener(transitionEnd, l, false);
|
|
|
|
_t._runAutos();
|
|
|
|
};
|
|
|
|
elem.parentNode.addEventListener(transitionEnd, l, false);
|
2018-05-18 03:25:45 +00:00
|
|
|
elem.classList.remove('to-build');
|
2018-05-18 06:23:36 +00:00
|
|
|
} else {
|
|
|
|
setTimeout(function () {
|
2018-05-18 03:25:45 +00:00
|
|
|
elem.classList.remove('to-build');
|
2018-05-18 06:23:36 +00:00
|
|
|
_t._runAutos();
|
|
|
|
}, 400);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2018-05-18 03:25:45 +00:00
|
|
|
buildNext () {
|
2018-05-18 06:23:36 +00:00
|
|
|
if (!this._buildList.length) {
|
|
|
|
return false;
|
|
|
|
}
|
2018-05-18 03:25:45 +00:00
|
|
|
this._buildList.shift().classList.remove('to-build');
|
2018-05-18 06:23:36 +00:00
|
|
|
return true;
|
|
|
|
}
|
2018-05-13 10:47:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
//
|
|
|
|
// SlideShow class
|
|
|
|
//
|
2018-05-18 03:25:45 +00:00
|
|
|
const SlideShow = function (slides) {
|
2018-05-18 06:23:36 +00:00
|
|
|
this._slides = (slides || []).map(function (el, idx) {
|
|
|
|
return new Slide(el, idx);
|
|
|
|
});
|
2018-05-13 10:47:00 +00:00
|
|
|
|
2018-05-18 03:25:45 +00:00
|
|
|
const h = window.location.hash;
|
2018-05-18 06:23:36 +00:00
|
|
|
try {
|
|
|
|
this.current = parseInt(h.split('#slide')[1], 10);
|
|
|
|
} catch (e) { /* squeltch */ }
|
|
|
|
this.current = isNaN(this.current) ? 1 : this.current;
|
2018-05-18 03:25:45 +00:00
|
|
|
const _t = this;
|
2018-05-18 06:23:36 +00:00
|
|
|
doc.addEventListener('keydown',
|
|
|
|
function (e) { _t.handleKeys(e); }, false);
|
|
|
|
doc.addEventListener('mousewheel',
|
|
|
|
function (e) { _t.handleWheel(e); }, false);
|
|
|
|
doc.addEventListener('DOMMouseScroll',
|
|
|
|
function (e) { _t.handleWheel(e); }, false);
|
|
|
|
doc.addEventListener('touchstart',
|
|
|
|
function (e) { _t.handleTouchStart(e); }, false);
|
|
|
|
doc.addEventListener('touchend',
|
|
|
|
function (e) { _t.handleTouchEnd(e); }, false);
|
|
|
|
window.addEventListener('popstate',
|
|
|
|
function (e) { _t.go(e.state); }, false);
|
|
|
|
this._update();
|
2018-05-13 10:47:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
SlideShow.prototype = {
|
2018-05-18 06:23:36 +00:00
|
|
|
_slides: [],
|
2018-05-18 03:25:45 +00:00
|
|
|
_update (dontPush) {
|
2018-05-18 06:23:36 +00:00
|
|
|
document.querySelector('#presentation-counter').innerText = this.current;
|
|
|
|
if (history.pushState) {
|
|
|
|
if (!dontPush) {
|
|
|
|
history.pushState(this.current, 'Slide ' + this.current, '#slide' + this.current);
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
window.location.hash = 'slide' + this.current;
|
|
|
|
}
|
2018-05-18 03:25:45 +00:00
|
|
|
for (let x = this.current - 1; x < this.current + 7; x++) {
|
2018-05-18 06:23:36 +00:00
|
|
|
if (this._slides[x - 4]) {
|
|
|
|
this._slides[x - 4].setState(Math.max(0, x - this.current));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
2018-05-13 10:47:00 +00:00
|
|
|
|
2018-05-18 06:23:36 +00:00
|
|
|
current: 0,
|
2018-05-18 03:25:45 +00:00
|
|
|
next () {
|
2018-05-18 06:23:36 +00:00
|
|
|
if (!this._slides[this.current - 1].buildNext()) {
|
|
|
|
this.current = Math.min(this.current + 1, this._slides.length);
|
|
|
|
this._update();
|
|
|
|
}
|
|
|
|
},
|
2018-05-18 03:25:45 +00:00
|
|
|
prev () {
|
2018-05-18 06:23:36 +00:00
|
|
|
this.current = Math.max(this.current - 1, 1);
|
|
|
|
this._update();
|
|
|
|
},
|
2018-05-18 03:25:45 +00:00
|
|
|
go (num) {
|
2018-05-18 06:23:36 +00:00
|
|
|
if (history.pushState && this.current !== num) {
|
|
|
|
history.replaceState(this.current, 'Slide ' + this.current, '#slide' + this.current);
|
|
|
|
}
|
|
|
|
this.current = num;
|
|
|
|
this._update(true);
|
|
|
|
},
|
2018-05-13 10:47:00 +00:00
|
|
|
|
2018-05-18 06:23:36 +00:00
|
|
|
_notesOn: false,
|
2018-05-18 03:25:45 +00:00
|
|
|
showNotes () {
|
|
|
|
const notesOn = this._notesOn = !this._notesOn;
|
2018-05-18 06:23:36 +00:00
|
|
|
query('.notes').forEach(function (el) {
|
|
|
|
el.style.display = (notesOn) ? 'block' : 'none';
|
|
|
|
});
|
|
|
|
},
|
2018-05-18 03:25:45 +00:00
|
|
|
switch3D () {
|
|
|
|
document.body.classList.toggle('three-d');
|
2018-05-18 06:23:36 +00:00
|
|
|
},
|
2018-05-18 03:25:45 +00:00
|
|
|
handleWheel (e) {
|
|
|
|
let delta = 0;
|
2018-05-18 06:23:36 +00:00
|
|
|
if (e.wheelDelta) {
|
|
|
|
delta = e.wheelDelta / 120;
|
|
|
|
if (isOpera) {
|
|
|
|
delta = -delta;
|
|
|
|
}
|
|
|
|
} else if (e.detail) {
|
|
|
|
delta = -e.detail / 3;
|
|
|
|
}
|
2018-05-13 10:47:00 +00:00
|
|
|
|
2018-05-18 06:23:36 +00:00
|
|
|
if (delta > 0) {
|
|
|
|
this.prev();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (delta < 0) {
|
|
|
|
this.next();
|
|
|
|
}
|
|
|
|
},
|
2018-05-18 03:25:45 +00:00
|
|
|
handleKeys (e) {
|
2018-05-18 06:23:36 +00:00
|
|
|
if (/^(input|textarea)$/i.test(e.target.nodeName)) return;
|
2018-05-13 10:47:00 +00:00
|
|
|
|
2018-05-18 06:23:36 +00:00
|
|
|
switch (e.keyCode) {
|
|
|
|
case 37: // left arrow
|
|
|
|
this.prev(); break;
|
|
|
|
case 39: // right arrow
|
|
|
|
case 32: // space
|
|
|
|
this.next(); break;
|
|
|
|
case 50: // 2
|
|
|
|
this.showNotes(); break;
|
|
|
|
case 51: // 3
|
|
|
|
this.switch3D(); break;
|
|
|
|
}
|
|
|
|
},
|
|
|
|
_touchStartX: 0,
|
2018-05-18 03:25:45 +00:00
|
|
|
handleTouchStart (e) {
|
2018-05-18 06:23:36 +00:00
|
|
|
this._touchStartX = e.touches[0].pageX;
|
|
|
|
},
|
2018-05-18 03:25:45 +00:00
|
|
|
handleTouchEnd (e) {
|
|
|
|
const delta = this._touchStartX - e.changedTouches[0].pageX;
|
|
|
|
const SWIPE_SIZE = 150;
|
2018-05-18 06:23:36 +00:00
|
|
|
if (delta > SWIPE_SIZE) {
|
|
|
|
this.next();
|
|
|
|
} else if (delta < -SWIPE_SIZE) {
|
|
|
|
this.prev();
|
|
|
|
}
|
|
|
|
}
|
2018-05-13 10:47:00 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// Initialize
|
2018-05-18 03:25:45 +00:00
|
|
|
const slideshow = new SlideShow(query('.slide')); // eslint-disable-line no-unused-vars
|
2018-05-13 10:47:00 +00:00
|
|
|
|
|
|
|
document.querySelector('#toggle-counter').addEventListener('click', toggleCounter, false);
|
|
|
|
document.querySelector('#toggle-size').addEventListener('click', toggleSize, false);
|
|
|
|
document.querySelector('#toggle-transitions').addEventListener('click', toggleTransitions, false);
|
|
|
|
document.querySelector('#toggle-gradients').addEventListener('click', toggleGradients, false);
|
|
|
|
|
2018-05-18 03:25:45 +00:00
|
|
|
const counters = document.querySelectorAll('.counter');
|
|
|
|
const slides = document.querySelectorAll('.slide');
|
2018-05-13 10:47:00 +00:00
|
|
|
|
|
|
|
function toggleCounter () {
|
2018-05-18 03:25:45 +00:00
|
|
|
[...counters].forEach(function (el) {
|
2018-05-18 06:23:36 +00:00
|
|
|
el.style.display = (el.offsetHeight) ? 'none' : 'block';
|
|
|
|
});
|
2018-05-13 10:47:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function toggleSize () {
|
2018-05-18 03:25:45 +00:00
|
|
|
[...slides].forEach(function (el) {
|
2018-05-18 06:23:36 +00:00
|
|
|
if (!/reduced/.test(el.className)) {
|
2018-05-18 03:25:45 +00:00
|
|
|
el.classList.add('reduced');
|
2018-05-18 06:23:36 +00:00
|
|
|
} else {
|
2018-05-18 03:25:45 +00:00
|
|
|
el.classList.remove('reduced');
|
2018-05-18 06:23:36 +00:00
|
|
|
}
|
|
|
|
});
|
2018-05-13 10:47:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function toggleTransitions () {
|
2018-05-18 03:25:45 +00:00
|
|
|
[...slides].forEach(function (el) {
|
2018-05-18 06:23:36 +00:00
|
|
|
if (!/no-transitions/.test(el.className)) {
|
2018-05-18 03:25:45 +00:00
|
|
|
el.classList.add('no-transitions');
|
2018-05-18 06:23:36 +00:00
|
|
|
} else {
|
2018-05-18 03:25:45 +00:00
|
|
|
el.classList.remove('no-transitions');
|
2018-05-18 06:23:36 +00:00
|
|
|
}
|
|
|
|
});
|
2018-05-13 10:47:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
function toggleGradients () {
|
2018-05-18 03:25:45 +00:00
|
|
|
[...slides].forEach(function (el) {
|
2018-05-18 06:23:36 +00:00
|
|
|
if (!/no-gradients/.test(el.className)) {
|
2018-05-18 03:25:45 +00:00
|
|
|
el.classList.add('no-gradients');
|
2018-05-18 06:23:36 +00:00
|
|
|
} else {
|
2018-05-18 03:25:45 +00:00
|
|
|
el.classList.remove('no-gradients');
|
2018-05-18 06:23:36 +00:00
|
|
|
}
|
|
|
|
});
|
2018-05-13 10:47:00 +00:00
|
|
|
}
|
|
|
|
})();
|