diff --git a/.editorconfig b/.editorconfig
index 0a837c4..6fb8ff7 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -6,4 +6,8 @@ indent_style = tab
end_of_line = lf
trim_trailing_whitespace = true
insert_final_newline = false
-charset = utf-8
\ No newline at end of file
+charset = utf-8
+
+[*.json]
+indent_style = space
+indent_size = 2
\ No newline at end of file
diff --git a/.gitmodules b/.gitmodules
deleted file mode 100644
index 9aa4ec7..0000000
--- a/.gitmodules
+++ /dev/null
@@ -1,6 +0,0 @@
-[submodule "themes/ribbon"]
- path = themes/ribbon
- url = git://github.com/shower/ribbon.git
-[submodule "themes/bright"]
- path = themes/bright
- url = git://github.com/shower/bright.git
diff --git a/.npmignore b/.npmignore
new file mode 100644
index 0000000..7f87621
--- /dev/null
+++ b/.npmignore
@@ -0,0 +1,4 @@
+.editorconfig
+.gitignore
+Contributing.md
+bower.json
\ No newline at end of file
diff --git a/Contributing.md b/Contributing.md
index 624d291..8791460 100644
--- a/Contributing.md
+++ b/Contributing.md
@@ -1,33 +1,34 @@
# Contributing to Shower
-You're always welcome to contibute! There are five repositories in Shower project:
+You’re always welcome to contibute! There are seven repositories in Shower project:
-- [Shower](https://github.com/shower/shower) engine with Ribbon theme
-- [Template](https://github.com/shower/template) for Shower engine and built-in themes
+- [Core](https://github.com/shower/core) of Shower
+- [Shower](https://github.com/shower/template) template
- [Ribbon](https://github.com/shower/ribbon) theme for Shower
- [Bright](https://github.com/shower/bright) theme for Shower
- [Jekyller](https://github.com/shower/jekyller) generator for Shower
+- [Sho.io](https://github.com/shower/sho.io) online service
+- [Shwr.me](https://github.com/shower/sho.io) service project
-The most important part of the project is the [Shower](https://github.com/shower/shower) repository, containing [shower.js](https://github.com/shower/shower/blob/master/shower.js) file.
+The most important part of the project is the [Core](https://github.com/shower/core) repository, containing [shower.js](https://github.com/shower/core/blob/master/shower.js) file.
## Issues
-Before contributing to Shower, please read through [Issues](https://github.com/shower/shower/issues?state=open) to see open bugs and feature requests. If you have any feature to add to Shower, please make sure that you file an issue with your ideas first. If you've found a bug and want to fix it, please file an issue first. It might be a feature!
-
+Before contributing to Shower, please read through [Issues](https://github.com/shower/shower/issues) to see open bugs and feature requests. If you have any feature to add to Shower or found a bug and want to fix it, please make sure you file an issue first.
## Process
-To contribute to Shower, fork needed repository and start making changes. Don't forget to add upstream link to original repository and keep your fork updated. When you finish, send pull request back to original repository and supply clear description or link to existing issue.
+To contribute to Shower fork needed repository and start making changes. Don’t forget to add upstream link to original repository and keep your fork updated. Once you finished, send pull request back to original repository and supply clear description or link to existing issue.
## Code style
-Please keep existing code style while contributing to Shower and be ready for code review by Shower authors and contributors. It's strongly recommended to validate your JavaScript changes using [JSHint](http://jshint.com/).
+Please keep existing code style while contributing to Shower and be ready for code review by Shower maintainers. It’s strongly recommended to install [EditorConfig](http://editorconfig.org) extension to your editor and validate your JavaScript changes using [JSHint](http://jshint.com/).
-By historical reasons, Shower project is using tabs instead of spaces for code indentation. It's not a big deal to keep this rule while contributing using you code editor options, even if your code style is 13.4 spaces.
+By historical reasons, Shower project is using tabs instead of spaces for code indentation. It’s not a big deal to keep this rule while contributing using you code editor options, even if your code style is 13.4 spaces.
## Language
-English is the main language for Shower project. All discussions and commit messages should be in English, no matter if it's good or bad. The second language of Shower is Russian. Offical Shower themes are always compatible with Cyrillic and Russian typography. All documentation to Shower is always localized to Russian.
+English is the main language for Shower project. All discussions and commit messages should be in English, no matter if it’s good or bad. The second language of Shower is Russian. Offical Shower themes are always compatible with Cyrillic and Russian typography. All documentation to Shower is always localized to Russian.
---
-If you have any questions, please ask [@shower_me](http://twitter.com/shower_me/) or file an [issue](https://github.com/shower/shower/issues?state=open).
+If you have any questions, please ask [@shower_me](http://twitter.com/shower_me/) or file an [issue](https://github.com/shower/shower/issues/new).
\ No newline at end of file
diff --git a/Gruntfile.js b/Gruntfile.js
deleted file mode 100644
index 32f3a1c..0000000
--- a/Gruntfile.js
+++ /dev/null
@@ -1,38 +0,0 @@
-module.exports = function(grunt) {
-
- grunt.initConfig({
- uglify: {
- options: {
- mangle: true,
- banner: '/**\n * Shower HTML presentation engine: github.com/shower/shower\n * @copyright 2010–<%= grunt.template.today("yyyy") %> Vadim Makeev, pepelsbey.net\n * @license MIT license: github.com/shower/shower/wiki/MIT-License\n */\n'
- },
- build: {
- src: 'shower.js',
- dest: 'shower.min.js'
- }
- },
- connect: {
- ribbon: {
- options: {
- port: 7497
- }
- }
- },
- dalek: {
- options: {
- browser: ['chrome']
- },
- src: [
- 'tests/*.js'
- ]
- }
- });
-
- grunt.loadNpmTasks('grunt-contrib-uglify');
- grunt.loadNpmTasks('grunt-contrib-connect');
- grunt.loadNpmTasks('grunt-dalek');
-
- grunt.registerTask('default', ['uglify']);
- grunt.registerTask('test', ['connect', 'dalek']);
-
-};
\ No newline at end of file
diff --git a/Readme.md b/Readme.md
index 5d15d24..a42abf2 100644
--- a/Readme.md
+++ b/Readme.md
@@ -1,44 +1,57 @@
-# Shower
+# Shower HTML presentation engine
-HTML presentation engine. Follow [@shower_me](http://twitter.com/shower_me/) for support and updates.
+Follow [@shower_me](https://twitter.com/shower_me) for support and updates
To see Shower in action:
- Open [shwr.me](http://shwr.me/)
- Click any slide to enter presentation mode
-- Use arrow keys to navigate
+- Use arrow keys or presenter remote to navigate
- Press `Esc` to exit presentation mode
-See more details on [using keyboard](https://github.com/shower/shower/wiki/Shortcuts) to control Shower.
+See [Wiki](https://github.com/shower/shower/wiki) for more information how to use Shower.
## Using Shower
-There are two ways of using Shower: you can get full template [ZIP 1.7 MB](http://shwr.me/template.zip) or just an engine [ZIP 915 KB](http://shwr.me/shower.zip). See more details for beginners and advanced techniques in [Quick Start](https://github.com/shower/shower/wiki/Quick-Start) instructions.
+There are two ways of making presentation using Shower: you can just download an archive with all you need or you can install needed Shower modules using [npm](https://www.npmjs.org) or [bower](http://bower.io).
-## Printing to PDF
+## Simple Way
-You can print your presentation to PDF using Google Chrome “Print to PDF” option in print dialog or [wkhtmltopdf](http://code.google.com/p/wkhtmltopdf) or [Prince](http://princexml.com).
-Example of Shower template printed by Prince: [PDF 435 KB](https://github.com/shower/template/blob/master/index.pdf?raw=true). See more details on printing in [documentation](https://github.com/shower/shower/wiki/Print).
+In a simple way you just download the latest Shower version with built-in themes and use it.
+
+1. Download and unarchive [shower.zip](http://shwr.me/shower.zip)
+2. Open `index.html` in any code or text editor, edit your slides in HTML
+3. Use `pictures` folder for pictures used in presentation
+4. Once finished, open `index.html` in a browser, enter full screen and start presenting
+
+## Module Way
+
+Module way allows you to manually install needed Shower packages and requires [Git](http://git-scm.com/) and [Node.js](http://nodejs.org/) installed together with package managment system: `npm` or `bower`.
+
+1. Clone Shower `git clone git@github.com:shower/shower.git` or download [shower-pkg.zip](http://shwr.me/shower-pkg.zip)
+2. Run `npm install` (or `bower install`) command in resulted folder to install script and themes
+3. Open `index.html` in any code or text editor, edit your slides in HTML
+4. Use `pictures` folder for pictures used in presentation
+5. Once finished, open `index.html` in browser, enter full screen and start presenting
## Usage examples
- [Clear and Sharp](http://pepelsbey.net/pres/clear-and-sharp/)
-- [CSS Management](http://pepelsbey.net/pres/css-management/)
+- [CSS Management](http://pepelsbey.net/pres/knife-train/)
- [Push it!](http://pepelsbey.net/pres/push-it/)
- [Pre-fixes](http://pepelsbey.net/pres/pre-fixes/)
- [Web In Curves](http://pepelsbey.net/pres/web-in-curves/)
- [Sense Coding](http://pepelsbey.net/pres/sense-coding/)
-- [Dynamic Graphics](http://pepelsbey.net/pres/dynamic-graphics/)
## Browser support
-Supported desktop browsers: Chrome, Internet Explorer, Firefox, Opera, Safari. Only latest stable versions of mentioned browsers are supported.
+Latest stable versions of Chrome, Internet Explorer, Firefox, Opera and Safari are supported.
## Contributing
-You're always welcome to contibute. Fork project, make changes and send it as pull request. But it's better to file an [issue](https://github.com/shower/shower/issues) with your idea first. Read [contributing rules](https://github.com/shower/shower/blob/master/Contributing.md) for more details.
+You’re always welcome to contibute. Fork project, make changes and send it as pull request. But it’s better to file an [issue](https://github.com/shower/shower/issues) with your idea first. Read [contributing rules](https://github.com/shower/shower/blob/master/Contributing.md) for more details.
-Main contributors: [pepelsbey](https://github.com/pepelsbey), [jahson](https://github.com/jahson), [miripiruni](https://github.com/miripiruni), [kizu](https://github.com/kizu).
+Main contributors: [pepelsbey](https://github.com/pepelsbey), [jahson](https://github.com/jahson), [miripiruni](https://github.com/miripiruni), [kizu](https://github.com/kizu), [artpolikarpov](https://github.com/artpolikarpov), [tonyganch](https://github.com/tonyganch).
---
-Licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License), see [license page](https://github.com/shower/shower/wiki/MIT-License) for details.
+Licensed under [MIT License](http://en.wikipedia.org/wiki/MIT_License), see [license page](https://github.com/shower/shower/wiki/MIT-License) for details.
\ No newline at end of file
diff --git a/bower.json b/bower.json
new file mode 100644
index 0000000..9b0f602
--- /dev/null
+++ b/bower.json
@@ -0,0 +1,24 @@
+{
+ "name": "shower",
+ "version": "1.0.1",
+ "license": "MIT",
+ "main": "index.html",
+ "ignore": [
+ ".editorconfig",
+ ".gitignore",
+ ".npmignore",
+ "Contributing.md",
+ "node_modules",
+ "package.json"
+ ],
+ "keywords": [
+ "shower",
+ "presentation",
+ "template"
+ ],
+ "dependencies": {
+ "shower-core": "^1.0.0",
+ "shower-ribbon": "^1.0.2",
+ "shower-bright": "^1.0.2"
+ }
+}
diff --git a/index.html b/index.html
new file mode 100755
index 0000000..e38c45a
--- /dev/null
+++ b/index.html
@@ -0,0 +1,176 @@
+
+
+
Shower ['ʃəuə] noun. A person or thing that shows.
+
+
+
Plain Text on Your Slides
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in <culpa> qui officia deserunt mollit anim id est laborum.
+
+
+
+
+
\ No newline at end of file
diff --git a/package.json b/package.json
index 70098ca..66d70fc 100644
--- a/package.json
+++ b/package.json
@@ -1,16 +1,33 @@
{
"name": "shower",
"description": "Shower HTML presentation engine",
- "repository": "https://github.com/shower/shower/",
- "version": "1.0.0",
- "private": true,
- "devDependencies": {
- "dalekjs": "0.0.8",
- "dalek-browser-chrome": "0.0.9",
- "grunt": "~0.4.2",
- "grunt-contrib-uglify": "~0.3.2",
- "grunt-dalek": "~0.2.0",
- "grunt-contrib-watch": "~0.5.3",
- "grunt-contrib-connect": "~0.6.0"
+ "version": "1.0.1",
+ "author": {
+ "name": "Vadim Makeev",
+ "url": "http://pepelsbey.com/"
+ },
+ "homepage": "http://shwr.me/",
+ "repository": {
+ "type": "git",
+ "url": "git://github.com/shower/shower.git"
+ },
+ "bugs": {
+ "url": "http://github.com/shower/shower/issues"
+ },
+ "licenses": [
+ {
+ "type": "MIT",
+ "url": "https://github.com/shower/shower/wiki/MIT-License"
+ }
+ ],
+ "keywords": [
+ "shower",
+ "presentation",
+ "template"
+ ],
+ "dependencies": {
+ "shower-core": "^1.0.0",
+ "shower-ribbon": "^1.0.2",
+ "shower-bright": "^1.0.2"
}
}
diff --git a/pictures/cover.jpg b/pictures/cover.jpg
new file mode 100644
index 0000000..75aa5a9
Binary files /dev/null and b/pictures/cover.jpg differ
diff --git a/pictures/logo.svg b/pictures/logo.svg
new file mode 100644
index 0000000..1906a83
--- /dev/null
+++ b/pictures/logo.svg
@@ -0,0 +1,3 @@
+
\ No newline at end of file
diff --git a/pictures/picture.jpg b/pictures/picture.jpg
new file mode 100644
index 0000000..4314090
Binary files /dev/null and b/pictures/picture.jpg differ
diff --git a/shower.js b/shower.js
deleted file mode 100755
index 6d47d6f..0000000
--- a/shower.js
+++ /dev/null
@@ -1,1014 +0,0 @@
-/**
- * Shower HTML presentation engine: github.com/shower/shower
- * @copyright 2010–2013 Vadim Makeev, pepelsbey.net
- * @license MIT license: github.com/shower/shower/wiki/MIT-License
- */
-window.shower = window.shower || (function(window, document, undefined) {
- var shower = {},
- url = window.location,
- body = document.body,
- slides = [],
- progress = [],
- timer,
- isHistoryApiSupported = !!(window.history && window.history.pushState);
-
- /**
- * Slide constructor
- *
- * @param {Object} opts
- * @param {String} opts.id html id attribute or automaticaly assigned order number
- * @param {Number} opts.number slide number
- * @param {Boolean} opts.hasInnerNavigation
- * @param {Number} [opts.timing]
- * @param {Number} [opts.innerLength]
- * @param {Number} [opts.innerComplete = 0]
- * @constructor
- */
- function Slide(opts) {
- for (var prop in opts) {
- if (opts.hasOwnProperty(prop)) {
- this[prop] = opts[prop];
- }
- }
- }
-
- Slide.prototype = {
- /**
- * Get slide number.
- * @returns {Number}
- */
- getSlideNumber : function() {
- return this.number;
- },
-
- isLast : function() {
- return shower.slideList.length === this.number + 1;
- },
-
- /**
- * Check if inner navigation is finished
- * @returns {boolean}
- */
- isFinished : function() {
- return this.innerComplete >= this.innerLength;
- },
-
- /**
- * Start inner navigation by timer or just switch slide after timer.
- * time sets in HTML: .slide[data-timing=MM:SS]
- * @returns {Object} Current slide
- */
- process : function(shower) {
- if (this.timing) {
- this.initTimer(shower);
- return this;
- }
-
- this.next(shower);
- return this;
- },
-
- /**
- * Init timer for inner navigation or for just turn to next slide
- * @param shower
- * @returns {Object|Boolean} Current slide
- */
- initTimer : function(shower) {
- var slide = this;
-
- if ( ! slide.timing) {
- return false;
- }
-
- slide.stopTimer();
-
- if (slide.isFinished()) {
- timer = setInterval(function() {
- slide.stopTimer();
- shower.next();
- },
- slide.timing * (slide.innerLength || 1));
- } else {
- timer = setInterval(function() {
- if (slide.isFinished()) {
- slide.stopTimer();
- shower.next();
- } else {
- slide.next(shower);
- }
- },
- slide.timing);
- }
-
- return this;
- },
-
- /**
- * Stop timer
- */
- stopTimer : function() {
- if (timer) {
- clearInterval(timer);
- timer = false;
- }
-
- return this;
- },
-
- /**
- * Previous step of inner navigation or if current step is step 0 then go to previous slide.
- * @returns {Object|Boolean} Current slide
- */
- prev : function(shower) {
- var prevSteps,
- slide = this;
-
- if ( ! slide.hasInnerNavigation || slide.isFinished() || slide.innerComplete === 0) {
- shower.prev();
- return false;
- }
-
- prevSteps = document.getElementById(slide.id).querySelectorAll('.next.active');
-
- if ( ! prevSteps || prevSteps.length < 1) {
- return false;
- }
-
- if (slide.innerComplete > 0) {
- slide.innerComplete--;
- prevSteps[prevSteps.length - 1].classList.remove('active');
- } else {
- shower.prev();
- }
-
- return this;
- },
-
- /**
- * Next step of inner navigation or if current step is last then go to next slide.
- * @returns {Object|Boolean} Current slide
- */
- next : function(shower) {
- var nextSteps,
- slide = this;
-
- if ( ! slide.hasInnerNavigation || slide.isFinished()) {
- shower.next();
- return false;
- }
-
- if ( ! slide.isFinished()) {
- nextSteps = document.getElementById(slide.id).querySelectorAll('.next:not(.active)');
- nextSteps[0].classList.add('active');
-
- slide.innerComplete++;
- }
-
- return this;
- }
- };
-
- /**
- * Get value at named data store for the DOM element.
- * @private
- * @param {HTMLElement} element
- * @param {String} name
- * @returns {String}
- */
- shower._getData = function(element, name) {
- return element.dataset ? element.dataset[name] : element.getAttribute('data-' + name);
- };
-
- shower.slideList = [];
-
- /**
- * Shower initialization
- * @param {String} [slideSelector]
- * @param {String} [progressSelector]
- * @returns {Object} shower
- */
- shower.init = function(slideSelector, progressSelector) {
- var timing;
-
- slideSelector = slideSelector || '.slide';
- progressSelector = progressSelector || 'div.progress div';
-
- slides = document.querySelectorAll(slideSelector);
- progress = document.querySelector(progressSelector);
-
- for (var i = 0; i < slides.length; i++) {
- // Slide IDs are optional.
- // In case of missing ID we set it to the slide number
- if ( ! slides[i].id) {
- slides[i].id = i + 1;
- }
-
- timing = shower._getData(slides[i], 'timing');
-
- // Parsing timing in [S] or [M:S] format
- // and returning it in milliseconds
- if (timing && /^(\d{1,2}:)?\d{1,3}$/.test(timing)) {
- if (timing.indexOf(':') !== -1) {
- timing = timing.split(':');
- timing = (parseInt(timing[0], 10) * 60 + parseInt(timing[1], 10)) * 1000;
- } else {
- timing = parseInt(timing, 10) * 1000;
- }
- if (timing === 0) {
- timing = false;
- }
- } else {
- timing = false;
- }
-
- shower.slideList.push(new Slide({
- id : slides[i].id,
- number : i,
- hasInnerNavigation : null !== slides[i].querySelector('.next'),
- timing : timing,
- innerLength : slides[i].querySelectorAll('.next').length,
- innerComplete : 0
- }));
- }
-
- return shower;
- };
-
- /**
- * Get slide scale value.
- * @private
- * @returns {String}
- */
- shower._getTransform = function() {
- var denominator = Math.max(
- body.clientWidth / window.innerWidth,
- body.clientHeight / window.innerHeight
- );
-
- return 'scale(' + (1 / denominator) + ')';
- };
-
- /**
- * Set CSS transform with prefixes to body.
- * @private
- * @returns {Boolean}
- */
- shower._applyTransform = function(transform) {
- [
- 'WebkitTransform',
- 'MozTransform',
- 'msTransform',
- 'OTransform',
- 'transform'
- ].forEach(function(prop) {
- body.style[prop] = transform;
- });
-
- return true;
- };
-
- /**
- * Check if arg is number.
- * @private
- * @param {String|Number} arg
- * @returns {Boolean}
- */
- shower._isNumber = function(arg) {
- return ! isNaN(parseFloat(arg)) && isFinite(arg);
- };
-
- /**
- * Normalize slide number.
- * @private
- * @param {Number} slideNumber slide number (sic!)
- * @returns {Number}
- */
- shower._normalizeSlideNumber = function(slideNumber) {
- if ( ! shower._isNumber(slideNumber)) {
- throw new Error('Gimme slide number as Number, baby!');
- }
-
- if (slideNumber < 0) {
- slideNumber = 0;
- }
-
- if (slideNumber >= shower.slideList.length) {
- slideNumber = shower.slideList.length - 1;
- }
-
- return slideNumber;
- };
-
- /**
- * Get slide id from HTML element.
- * @private
- * @param {Node} el
- * @returns {String}
- */
- shower._getSlideIdByEl = function(el) {
- while ('BODY' !== el.nodeName && 'HTML' !== el.nodeName) {
- if (el.classList.contains('slide')) {
- return el.id;
- } else {
- el = el.parentNode;
- }
- }
-
- return '';
- };
-
- /**
- * For touch devices: check if link is clicked.
- *
- * @TODO: add support for textarea/input/etc.
- *
- * @private
- * @param {HTMLElement} e
- * @returns {Boolean}
- */
- shower._checkInteractiveElement = function(e) {
- return 'A' === e.target.nodeName;
- };
-
- /**
- * Get slide number by slideId.
- * @param {String} slideId
- * @returns {Number}
- */
- shower.getSlideNumber = function(slideId) {
- var i = shower.slideList.length - 1,
- slideNumber;
-
- if (slideId === '') {
- slideNumber = 0;
- }
-
- // As fast as you can ;-)
- // http://jsperf.com/for-vs-foreach/46
- for (; i >= 0; --i) {
- if (slideId === shower.slideList[i].id) {
- slideNumber = i;
- break;
- }
- }
-
- return slideNumber;
- };
-
- /**
- * Go to slide number.
- * @param {Number} slideNumber slide number (sic!). Attention: starts from zero.
- * @param {Function} [callback] runs only if you not in List mode.
- * @returns {Number|Boolean}
- */
- shower.go = function(slideNumber, callback) {
- var slide;
-
- if ( ! shower._isNumber(slideNumber)) {
- throw new Error('Gimme slide number as Number, baby!');
- }
-
- if ( ! shower.slideList[slideNumber]) {
- return false;
- }
-
- // Also triggers popstate and invoke shower.enter__Mode()
- url.hash = shower.getSlideHash(slideNumber);
-
- shower.updateProgress(slideNumber);
- shower.updateActiveAndVisitedSlides(slideNumber);
-
- if (shower.isSlideMode()) {
- shower.showPresenterNotes(slideNumber);
- slide = shower.slideList[slideNumber];
- if (slide.timing) {
- slide.initTimer(shower);
- }
- }
-
- if (typeof(callback) === 'function') {
- callback();
- }
-
- return slideNumber;
- };
-
- /**
- * Show next slide or show next Inner navigation item.
- * Returns false on a last slide, otherwise returns shower.
- * @param {Function} [callback] runs only if shower.next() is successfully completed.
- * @returns {Boolean}
- */
- shower.next = function(callback) {
- var currentSlideNumber = shower.getCurrentSlideNumber(),
- nextSlide = shower.slideList[currentSlideNumber + 1];
-
- // If don't exist next slide
- if (! nextSlide) {
- return false;
- }
-
- shower.go(currentSlideNumber + 1);
-
- if (typeof(callback) === 'function') {
- callback();
- }
-
- return this;
- };
-
- /**
- *
- * @param {Function} [callback]
- */
- shower._turnNextSlide = function(callback) {
- var currentSlideNumber = shower.getCurrentSlideNumber(),
- slide = shower.slideList[currentSlideNumber];
-
-
- if (shower.isSlideMode()) {
- slide.stopTimer();
- slide.next(shower);
- } else {
- shower.go(currentSlideNumber + 1);
- }
-
- if (typeof(callback) === 'function') {
- callback();
- }
-
- return;
- };
-
- /**
- * Show previous slide. Returns false on a first slide, otherwise returns shown slide number.
- * @param {Function} [callback] runs only if shower.previous() is successfully completed.
- * @returns {Boolean}
- */
- shower.prev = shower.previous = function(callback) {
- var currentSlideNumber = shower.getCurrentSlideNumber();
-
- // Slides starts from 0
- if (currentSlideNumber < 1) {
- return false;
- }
-
- shower.go(currentSlideNumber - 1);
-
- if (typeof(callback) === 'function') {
- callback();
- }
-
- return true;
- };
-
- /**
- * Show previous slide. Returns false on a first slide, otherwise returns shown slide number.
- * @param {Function} [callback] runs only if shower.previous() is successfully completed.
- * @returns {Boolean}
- */
- shower._turnPreviousSlide = function(callback) {
- var currentSlideNumber = shower.getCurrentSlideNumber(),
- slide = shower.slideList[currentSlideNumber];
-
- slide.stopTimer();
-
- if (shower.isSlideMode()) {
- slide.prev(shower);
- } else {
- shower.go(currentSlideNumber - 1);
- }
-
- if (typeof(callback) === 'function') {
- callback();
- }
-
- return true;
- };
-
- /**
- * Show first slide.
- * @param {Function} [callback]
- */
- shower.first = function(callback) {
- var slide = shower.slideList[shower.getCurrentSlideNumber()];
-
- slide && slide.timing && slide.stopTimer();
- shower.go(0);
-
- if (typeof(callback) === 'function') {
- callback();
- }
- };
-
- /**
- * Show last slide.
- * @param {Function} [callback]
- */
- shower.last = function(callback) {
- var slide = shower.slideList[shower.getCurrentSlideNumber()];
-
- slide && slide.timing && slide.stopTimer();
- shower.go(shower.slideList.length - 1);
-
- if (typeof(callback) === 'function') {
- callback();
- }
- };
-
- /**
- * Switch to slide view.
- * @param {Function} [callback] runs only if shower.enterSlideMode() is successfully completed.
- * @returns {Boolean}
- */
- shower.enterSlideMode = function(callback) {
- var currentSlideNumber = shower.getCurrentSlideNumber();
-
- // Anyway: change body class (@TODO: refactoring)
- body.classList.remove('list');
- body.classList.add('full');
-
- // Preparing URL for shower.go()
- if (shower.isListMode() && isHistoryApiSupported) {
- history.pushState(null, null, url.pathname + '?full' + shower.getSlideHash(currentSlideNumber));
- }
-
- shower._applyTransform(shower._getTransform());
-
- if (typeof(callback) === 'function') {
- callback();
- }
-
- return true;
- };
-
- /**
- * Switch to list view.
- * @param {Function} [callback] runs only if shower.enterListMode() is successfully completed.
- * @returns {Boolean}
- */
- shower.enterListMode = function(callback) {
- var currentSlideNumber;
-
- // Anyway: change body class (@TODO: refactoring)
- body.classList.remove('full');
- body.classList.add('list');
-
- shower.clearPresenterNotes();
- shower._applyTransform('none');
-
- if (shower.isListMode()) {
- return false;
- }
-
- currentSlideNumber = shower.getCurrentSlideNumber();
-
- shower.slideList[currentSlideNumber].stopTimer();
-
- if (shower.isSlideMode() && isHistoryApiSupported) {
- history.pushState(null, null, url.pathname + shower.getSlideHash(currentSlideNumber));
- }
-
- shower.scrollToSlide(currentSlideNumber);
-
- if (typeof(callback) === 'function') {
- callback();
- }
-
- return true;
- };
-
- /**
- * Toggle Mode: Slide and List.
- * @param {Function} [callback]
- */
- shower.toggleMode = function(callback) {
- if (shower.isListMode()) {
- shower.enterSlideMode();
- } else {
- shower.enterListMode();
- }
-
- if (typeof(callback) === 'function') {
- callback();
- }
-
- return true;
- };
-
- /**
- * Get current slide number. Starts from zero. Warning: when you have
- * slide number 1 in URL this method will return 0.
- * If there is no slide number in url, return -1.
- * If there is a slide number in url, but the slide does not exist, return 0.
- * @returns {Number}
- */
- shower.getCurrentSlideNumber = function() {
- var i = shower.slideList.length - 1,
- currentSlideId = url.hash.substr(1);
-
- if (currentSlideId === '') {
- return -1;
- }
-
- // As fast as you can ;-)
- // http://jsperf.com/for-vs-foreach/46
- for (; i >= 0; --i) {
- if (currentSlideId === shower.slideList[i].id) {
- return i;
- }
- }
-
- return 0;
- };
-
- /**
- * Scroll to slide.
- * @param {Number} slideNumber slide number (sic!)
- * @returns {Boolean}
- */
- shower.scrollToSlide = function(slideNumber) {
- var currentSlide,
- ret = false;
-
- if ( ! shower._isNumber(slideNumber)) {
- throw new Error('Gimme slide number as Number, baby!');
- }
-
- if (shower.isSlideMode()) {
- throw new Error('You can\'t scroll to because you in slide mode. Please, switch to list mode.');
- }
-
- // @TODO: WTF?
- if (-1 === slideNumber) {
- return ret;
- }
-
- if (shower.slideList[slideNumber]) {
- currentSlide = document.getElementById(shower.slideList[slideNumber].id);
- window.scrollTo(0, currentSlide.offsetTop);
- ret = true;
- } else {
- throw new Error('There is no slide with number ' + slideNumber);
- }
-
- return ret;
- };
-
- /**
- * Check if it's List mode.
- * @returns {Boolean}
- */
- shower.isListMode = function() {
- return isHistoryApiSupported ? ! /^full.*/.test(url.search.substr(1)) : body.classList.contains('list');
- };
-
- /**
- * Check if it's Slide mode.
- * @returns {Boolean}
- */
- shower.isSlideMode = function() {
- return isHistoryApiSupported ? /^full.*/.test(url.search.substr(1)) : body.classList.contains('full');
- };
-
- /**
- * Update progress bar.
- * @param {Number} slideNumber slide number (sic!)
- * @returns {Boolean}
- */
- shower.updateProgress = function(slideNumber) {
- // if progress bar doesn't exist
- if (null === progress) {
- return false;
- }
-
- if ( ! shower._isNumber(slideNumber)) {
- throw new Error('Gimme slide number as Number, baby!');
- }
-
- progress.style.width = (100 / (shower.slideList.length - 1) * shower._normalizeSlideNumber(slideNumber)).toFixed(2) + '%';
-
- return true;
- };
-
- /**
- * Update active and visited slides.
- * @param {Number} slideNumber slide number (sic!)
- * @returns {Boolean}
- */
- shower.updateActiveAndVisitedSlides = function(slideNumber) {
- var i,
- slide,
- l = shower.slideList.length;
-
- slideNumber = shower._normalizeSlideNumber(slideNumber);
-
- if ( ! shower._isNumber(slideNumber)) {
- throw new Error('Gimme slide number as Number, baby!');
- }
-
- for (i = 0; i < l; ++i) {
- slide = document.getElementById(shower.slideList[i].id);
-
- if (i < slideNumber) {
- slide.classList.remove('active');
- slide.classList.add('visited');
- } else if (i > slideNumber) {
- slide.classList.remove('visited');
- slide.classList.remove('active');
- } else {
- slide.classList.remove('visited');
- slide.classList.add('active');
- }
- }
-
- return true;
- };
-
- /**
- * Clear presenter notes in console (only for Slide Mode).
- */
- shower.clearPresenterNotes = function() {
- if (shower.isSlideMode() && window.console && window.console.clear) {
- console.clear();
- }
- };
-
- /**
- * Show presenter notes in console.
- * @param {Number} slideNumber slide number (sic!). Attention: starts from zero.
- */
- shower.showPresenterNotes = function(slideNumber) {
- shower.clearPresenterNotes();
-
- if (window.console) {
- slideNumber = shower._normalizeSlideNumber(slideNumber);
-
- var slideId = shower.slideList[slideNumber].id,
- nextSlideId = shower.slideList[slideNumber + 1] ? shower.slideList[slideNumber + 1].id : null,
- notes = document.getElementById(slideId).querySelector('footer');
-
- if (notes && notes.innerHTML) {
- console.info(notes.innerHTML.replace(/\n\s+/g,'\n'));
- }
-
- if (nextSlideId) {
-
- var next = document.getElementById(nextSlideId).querySelector('h2');
-
- if (next) {
- next = next.innerHTML.replace(/^\s+|<[^>]+>/g,'');
- console.info('NEXT: ' + next);
- }
- }
- }
- };
-
- /**
- * Get slide hash.
- * @param {Number} slideNumber slide number (sic!). Attention: starts from zero.
- * @returns {String}
- */
- shower.getSlideHash = function(slideNumber) {
- if ( ! shower._isNumber(slideNumber)) {
- throw new Error('Gimme slide number as Number, baby!');
- }
-
- slideNumber = shower._normalizeSlideNumber(slideNumber);
-
- return '#' + shower.slideList[slideNumber].id;
- };
-
- /**
- * Wheel event listener
- * @param e event
- */
- shower.wheel = function (e) {
- var body = document.querySelector('body'),
- wheelDown,
- lockedWheel = body.getAttribute('data-scroll') === 'locked';
-
- if (!lockedWheel && !shower.isListMode()) {
- body.setAttribute('data-scroll', 'locked');
-
- if (e.deltaY === undefined) {
- // Chrome, Opera, Safari
- wheelDown = e.wheelDeltaY < 0;
- } else {
- // Firefox
- wheelDown = e.deltaY > 0;
- }
-
- if (wheelDown) {
- shower._turnNextSlide();
- } else {
- shower._turnPreviousSlide();
- }
-
- setTimeout(function () {
- body.setAttribute('data-scroll', 'unlocked');
- }, 200);
- }
- }
-
- // Event handlers
-
- window.addEventListener('DOMContentLoaded', function() {
- var currentSlideNumber = shower.getCurrentSlideNumber(),
- isSlideMode = body.classList.contains('full') || shower.isSlideMode();
-
- if (currentSlideNumber === -1 && isSlideMode) {
- shower.go(0);
- } else if (currentSlideNumber === 0 || isSlideMode) {
- shower.go(currentSlideNumber);
- }
-
- if (isSlideMode) {
- shower.enterSlideMode();
- }
- }, false);
-
- window.addEventListener('popstate', function() {
- var currentSlideNumber = shower.getCurrentSlideNumber();
-
- if (currentSlideNumber !== -1) {
- shower.go(currentSlideNumber);
- }
-
- if (shower.isListMode()) {
- shower.enterListMode();
- } else {
- shower.enterSlideMode();
- }
- }, false);
-
- window.addEventListener('resize', function() {
- if (shower.isSlideMode()) {
- shower._applyTransform(shower._getTransform());
- }
- }, false);
-
- document.addEventListener('keydown', function(e) {
- var currentSlideNumber = shower.getCurrentSlideNumber(),
- slide = shower.slideList[ currentSlideNumber !== -1 ? currentSlideNumber : 0 ],
- slideNumber;
-
- switch (e.which) {
- case 80: // P Alt Cmd
- if (shower.isListMode() && e.altKey && e.metaKey) {
- e.preventDefault();
-
- slideNumber = slide.number;
-
- shower.go(slideNumber);
- shower.enterSlideMode();
- shower.showPresenterNotes(slideNumber);
-
- slide.timing && slide.initTimer(shower);
- }
- break;
-
- case 116: // F5 (Shift)
- e.preventDefault();
- if (shower.isListMode()) {
- slideNumber = e.shiftKey ? slide.number : 0;
-
- shower.go(slideNumber);
- shower.enterSlideMode();
- shower.showPresenterNotes(slideNumber);
-
- slide.timing && slide.initTimer(shower);
- } else {
- shower.enterListMode();
- }
- break;
-
- case 13: // Enter
- if (shower.isListMode() && -1 !== currentSlideNumber) {
- e.preventDefault();
-
- shower.enterSlideMode();
- shower.showPresenterNotes(currentSlideNumber);
-
- slide.timing && slide.initTimer(shower);
- }
- break;
-
- case 27: // Esc
- if (shower.isSlideMode()) {
- e.preventDefault();
- shower.enterListMode();
- }
- break;
-
- case 33: // PgUp
- case 38: // Up
- case 37: // Left
- case 72: // H
- case 75: // K
- if (e.altKey || e.ctrlKey || e.metaKey) { return; }
- e.preventDefault();
- shower._turnPreviousSlide();
- break;
-
- case 34: // PgDown
- case 40: // Down
- case 39: // Right
- case 76: // L
- case 74: // J
- if (e.altKey || e.ctrlKey || e.metaKey) { return; }
- e.preventDefault();
- shower._turnNextSlide();
- break;
-
- case 36: // Home
- e.preventDefault();
- shower.first();
- break;
-
- case 35: // End
- e.preventDefault();
- shower.last();
- break;
-
- case 9: // Tab (Shift)
- case 32: // Space (Shift)
- e.preventDefault();
- shower[e.shiftKey ? '_turnPreviousSlide' : '_turnNextSlide']();
- break;
-
- default:
- // Behave as usual
- }
- }, false);
-
- shower.init();
-
- document.addEventListener('click', function(e) {
- var slideId = shower._getSlideIdByEl(e.target),
- slideNumber,
- slide;
-
- // Click on slide in List mode
- if (slideId && shower.isListMode()) {
- slideNumber = shower.getSlideNumber(slideId);
- // Warning: go must be before enterSlideMode.
- // Otherwise there is a bug in Chrome
- shower.go(slideNumber);
- shower.enterSlideMode();
- shower.showPresenterNotes(slideNumber);
-
- slide = shower.slideList[slideNumber];
- if (slide.timing) {
- slide.initTimer(shower);
- }
- }
- }, false);
-
- document.addEventListener('touchstart', function(e) {
- var slideId = shower._getSlideIdByEl(e.target),
- slideNumber,
- slide,
- x;
-
- if (slideId) {
- if (shower.isSlideMode() && ! shower._checkInteractiveElement(e)) {
- x = e.touches[0].pageX;
-
- if (x > window.innerWidth / 2) {
- shower._turnNextSlide();
- } else {
- shower._turnPreviousSlide();
- }
- }
-
- if (shower.isListMode()) {
- slideNumber = shower.getSlideNumber(slideId);
- // Warning: go must be before enterSlideMode.
- // Otherwise there is a bug in Chrome
- shower.go(slideNumber);
- shower.enterSlideMode();
- shower.showPresenterNotes(slideNumber);
-
- slide = shower.slideList[slideNumber];
- if (slide.timing) {
- slide.initTimer(shower);
- }
- }
- }
-
- }, false);
-
- document.addEventListener('touchmove', function(e) {
- if (shower.isSlideMode()) {
- e.preventDefault();
- }
- }, false);
-
- document.addEventListener('wheel', shower.wheel, false);
-
- document.addEventListener('mousewheel', shower.wheel, false);
-
- return shower;
-
-})(this, this.document);
diff --git a/shower.min.js b/shower.min.js
deleted file mode 100644
index 0625bdc..0000000
--- a/shower.min.js
+++ /dev/null
@@ -1,6 +0,0 @@
-/**
- * Shower HTML presentation engine: github.com/shower/shower
- * @copyright 2010–2014 Vadim Makeev, pepelsbey.net
- * @license MIT license: github.com/shower/shower/wiki/MIT-License
- */
-window.shower=window.shower||function(a,b,c){function d(a){for(var b in a)a.hasOwnProperty(b)&&(this[b]=a[b])}var e,f={},g=a.location,h=b.body,i=[],j=[],k=!(!a.history||!a.history.pushState);return d.prototype={getSlideNumber:function(){return this.number},isLast:function(){return f.slideList.length===this.number+1},isFinished:function(){return this.innerComplete>=this.innerLength},process:function(a){return this.timing?(this.initTimer(a),this):(this.next(a),this)},initTimer:function(a){var b=this;return b.timing?(b.stopTimer(),e=b.isFinished()?setInterval(function(){b.stopTimer(),a.next()},b.timing*(b.innerLength||1)):setInterval(function(){b.isFinished()?(b.stopTimer(),a.next()):b.next(a)},b.timing),this):!1},stopTimer:function(){return e&&(clearInterval(e),e=!1),this},prev:function(a){var c,d=this;return!d.hasInnerNavigation||d.isFinished()||0===d.innerComplete?(a.prev(),!1):(c=b.getElementById(d.id).querySelectorAll(".next.active"),!c||c.length<1?!1:(d.innerComplete>0?(d.innerComplete--,c[c.length-1].classList.remove("active")):a.prev(),this))},next:function(a){var c,d=this;return!d.hasInnerNavigation||d.isFinished()?(a.next(),!1):(d.isFinished()||(c=b.getElementById(d.id).querySelectorAll(".next:not(.active)"),c[0].classList.add("active"),d.innerComplete++),this)}},f._getData=function(a,b){return a.dataset?a.dataset[b]:a.getAttribute("data-"+b)},f.slideList=[],f.init=function(a,c){var e;a=a||".slide",c=c||"div.progress div",i=b.querySelectorAll(a),j=b.querySelector(c);for(var g=0;ga&&(a=0),a>=f.slideList.length&&(a=f.slideList.length-1),a},f._getSlideIdByEl=function(a){for(;"BODY"!==a.nodeName&&"HTML"!==a.nodeName;){if(a.classList.contains("slide"))return a.id;a=a.parentNode}return""},f._checkInteractiveElement=function(a){return"A"===a.target.nodeName},f.getSlideNumber=function(a){var b,c=f.slideList.length-1;for(""===a&&(b=0);c>=0;--c)if(a===f.slideList[c].id){b=c;break}return b},f.go=function(a,b){var c;if(!f._isNumber(a))throw new Error("Gimme slide number as Number, baby!");return f.slideList[a]?(g.hash=f.getSlideHash(a),f.updateProgress(a),f.updateActiveAndVisitedSlides(a),f.isSlideMode()&&(f.showPresenterNotes(a),c=f.slideList[a],c.timing&&c.initTimer(f)),"function"==typeof b&&b(),a):!1},f.next=function(a){var b=f.getCurrentSlideNumber(),c=f.slideList[b+1];return c?(f.go(b+1),"function"==typeof a&&a(),this):!1},f._turnNextSlide=function(a){var b=f.getCurrentSlideNumber(),c=f.slideList[b];f.isSlideMode()?(c.stopTimer(),c.next(f)):f.go(b+1),"function"==typeof a&&a()},f.prev=f.previous=function(a){var b=f.getCurrentSlideNumber();return 1>b?!1:(f.go(b-1),"function"==typeof a&&a(),!0)},f._turnPreviousSlide=function(a){var b=f.getCurrentSlideNumber(),c=f.slideList[b];return c.stopTimer(),f.isSlideMode()?c.prev(f):f.go(b-1),"function"==typeof a&&a(),!0},f.first=function(a){var b=f.slideList[f.getCurrentSlideNumber()];b&&b.timing&&b.stopTimer(),f.go(0),"function"==typeof a&&a()},f.last=function(a){var b=f.slideList[f.getCurrentSlideNumber()];b&&b.timing&&b.stopTimer(),f.go(f.slideList.length-1),"function"==typeof a&&a()},f.enterSlideMode=function(a){var b=f.getCurrentSlideNumber();return h.classList.remove("list"),h.classList.add("full"),f.isListMode()&&k&&history.pushState(null,null,g.pathname+"?full"+f.getSlideHash(b)),f._applyTransform(f._getTransform()),"function"==typeof a&&a(),!0},f.enterListMode=function(a){var b;return h.classList.remove("full"),h.classList.add("list"),f.clearPresenterNotes(),f._applyTransform("none"),f.isListMode()?!1:(b=f.getCurrentSlideNumber(),f.slideList[b].stopTimer(),f.isSlideMode()&&k&&history.pushState(null,null,g.pathname+f.getSlideHash(b)),f.scrollToSlide(b),"function"==typeof a&&a(),!0)},f.toggleMode=function(a){return f.isListMode()?f.enterSlideMode():f.enterListMode(),"function"==typeof a&&a(),!0},f.getCurrentSlideNumber=function(){var a=f.slideList.length-1,b=g.hash.substr(1);if(""===b)return-1;for(;a>=0;--a)if(b===f.slideList[a].id)return a;return 0},f.scrollToSlide=function(c){var d,e=!1;if(!f._isNumber(c))throw new Error("Gimme slide number as Number, baby!");if(f.isSlideMode())throw new Error("You can't scroll to because you in slide mode. Please, switch to list mode.");if(-1===c)return e;if(!f.slideList[c])throw new Error("There is no slide with number "+c);return d=b.getElementById(f.slideList[c].id),a.scrollTo(0,d.offsetTop),e=!0,e},f.isListMode=function(){return k?!/^full.*/.test(g.search.substr(1)):h.classList.contains("list")},f.isSlideMode=function(){return k?/^full.*/.test(g.search.substr(1)):h.classList.contains("full")},f.updateProgress=function(a){if(null===j)return!1;if(!f._isNumber(a))throw new Error("Gimme slide number as Number, baby!");return j.style.width=(100/(f.slideList.length-1)*f._normalizeSlideNumber(a)).toFixed(2)+"%",!0},f.updateActiveAndVisitedSlides=function(a){var c,d,e=f.slideList.length;if(a=f._normalizeSlideNumber(a),!f._isNumber(a))throw new Error("Gimme slide number as Number, baby!");for(c=0;e>c;++c)d=b.getElementById(f.slideList[c].id),a>c?(d.classList.remove("active"),d.classList.add("visited")):c>a?(d.classList.remove("visited"),d.classList.remove("active")):(d.classList.remove("visited"),d.classList.add("active"));return!0},f.clearPresenterNotes=function(){f.isSlideMode()&&a.console&&a.console.clear&&console.clear()},f.showPresenterNotes=function(c){if(f.clearPresenterNotes(),a.console){c=f._normalizeSlideNumber(c);var d=f.slideList[c].id,e=f.slideList[c+1]?f.slideList[c+1].id:null,g=b.getElementById(d).querySelector("footer");if(g&&g.innerHTML&&console.info(g.innerHTML.replace(/\n\s+/g,"\n")),e){var h=b.getElementById(e).querySelector("h2");h&&(h=h.innerHTML.replace(/^\s+|<[^>]+>/g,""),console.info("NEXT: "+h))}}},f.getSlideHash=function(a){if(!f._isNumber(a))throw new Error("Gimme slide number as Number, baby!");return a=f._normalizeSlideNumber(a),"#"+f.slideList[a].id},f.wheel=function(a){var d,e=b.querySelector("body"),g="locked"===e.getAttribute("data-scroll");g||f.isListMode()||(e.setAttribute("data-scroll","locked"),d=a.deltaY===c?a.wheelDeltaY<0:a.deltaY>0,d?f._turnNextSlide():f._turnPreviousSlide(),setTimeout(function(){e.setAttribute("data-scroll","unlocked")},200))},a.addEventListener("DOMContentLoaded",function(){var a=f.getCurrentSlideNumber(),b=h.classList.contains("full")||f.isSlideMode();-1===a&&b?f.go(0):(0===a||b)&&f.go(a),b&&f.enterSlideMode()},!1),a.addEventListener("popstate",function(){var a=f.getCurrentSlideNumber();-1!==a&&f.go(a),f.isListMode()?f.enterListMode():f.enterSlideMode()},!1),a.addEventListener("resize",function(){f.isSlideMode()&&f._applyTransform(f._getTransform())},!1),b.addEventListener("keydown",function(a){var b,c=f.getCurrentSlideNumber(),d=f.slideList[-1!==c?c:0];switch(a.which){case 80:f.isListMode()&&a.altKey&&a.metaKey&&(a.preventDefault(),b=d.number,f.go(b),f.enterSlideMode(),f.showPresenterNotes(b),d.timing&&d.initTimer(f));break;case 116:a.preventDefault(),f.isListMode()?(b=a.shiftKey?d.number:0,f.go(b),f.enterSlideMode(),f.showPresenterNotes(b),d.timing&&d.initTimer(f)):f.enterListMode();break;case 13:f.isListMode()&&-1!==c&&(a.preventDefault(),f.enterSlideMode(),f.showPresenterNotes(c),d.timing&&d.initTimer(f));break;case 27:f.isSlideMode()&&(a.preventDefault(),f.enterListMode());break;case 33:case 38:case 37:case 72:case 75:if(a.altKey||a.ctrlKey||a.metaKey)return;a.preventDefault(),f._turnPreviousSlide();break;case 34:case 40:case 39:case 76:case 74:if(a.altKey||a.ctrlKey||a.metaKey)return;a.preventDefault(),f._turnNextSlide();break;case 36:a.preventDefault(),f.first();break;case 35:a.preventDefault(),f.last();break;case 9:case 32:a.preventDefault(),f[a.shiftKey?"_turnPreviousSlide":"_turnNextSlide"]()}},!1),f.init(),b.addEventListener("click",function(a){var b,c,d=f._getSlideIdByEl(a.target);d&&f.isListMode()&&(b=f.getSlideNumber(d),f.go(b),f.enterSlideMode(),f.showPresenterNotes(b),c=f.slideList[b],c.timing&&c.initTimer(f))},!1),b.addEventListener("touchstart",function(b){var c,d,e,g=f._getSlideIdByEl(b.target);g&&(f.isSlideMode()&&!f._checkInteractiveElement(b)&&(e=b.touches[0].pageX,e>a.innerWidth/2?f._turnNextSlide():f._turnPreviousSlide()),f.isListMode()&&(c=f.getSlideNumber(g),f.go(c),f.enterSlideMode(),f.showPresenterNotes(c),d=f.slideList[c],d.timing&&d.initTimer(f)))},!1),b.addEventListener("touchmove",function(a){f.isSlideMode()&&a.preventDefault()},!1),b.addEventListener("wheel",f.wheel,!1),b.addEventListener("mousewheel",f.wheel,!1),f}(this,this.document);
\ No newline at end of file
diff --git a/tests/basic.js b/tests/basic.js
deleted file mode 100644
index b7789a1..0000000
--- a/tests/basic.js
+++ /dev/null
@@ -1,84 +0,0 @@
-module.exports = {
- // --------------------------------
- // Click
- // --------------------------------
- 'Click on slide is switching from List to Full': function (test) {
- test
- .open('http://localhost:7497/tests/')
- .click('[id="1"]')
- .assert.attr('body', 'class').to.contain('full', 'Mode is Full')
- .done();
- },
- // --------------------------------
- // Walking
- // --------------------------------
- 'All slides could be switched from first to last in List mode': function (test) {
- test
- .open('http://localhost:7497/tests/#1')
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .assert.attr('[id="6"]', 'class').to.contain('active', 'Last slide is Active')
- .done();
- },
- 'All slides could be switched from last to first in List mode': function (test) {
- test
- .open('http://localhost:7497/tests/#6')
- .sendKeys('body', '\uE012') // Left
- .sendKeys('body', '\uE012') // Left
- .sendKeys('body', '\uE012') // Left
- .sendKeys('body', '\uE012') // Left
- .sendKeys('body', '\uE012') // Left
- .assert.attr('[id="1"]', 'class').to.contain('active', 'First slide is Active')
- .done();
- },
- 'All slides could be switched from first to last in Full mode': function (test) {
- test
- .open('http://localhost:7497/tests/?full#1')
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .assert.attr('[id="6"]', 'class').to.contain('active', 'Last slide is Active')
- .done();
- },
- 'All slides could be switched from last to first in Full mode': function (test) {
- test
- .open('http://localhost:7497/tests/?full#6')
- .sendKeys('body', '\uE012') // Left
- .sendKeys('body', '\uE012') // Left
- .sendKeys('body', '\uE012') // Left
- .sendKeys('body', '\uE012') // Left
- .sendKeys('body', '\uE012') // Left
- .assert.attr('[id="1"]', 'class').to.contain('active', 'First slide is Active')
- .done();
- },
- // --------------------------------
- // Back
- // --------------------------------
- 'Back is switching from Full to List': function (test) {
- test
- .open('http://localhost:7497/tests/')
- .click('[id="1"]')
- .back()
- .assert.attr('body', 'class').to.contain('list', 'Mode is List')
- .done();
- },
- // --------------------------------
- // Zoom
- // --------------------------------
- 'Back from Full to List is restoring scale': function (test) {
- test
- .open('http://localhost:7497/tests/')
- .click('[id="1"]')
- .back()
- .assert.attr('body', 'style').to.contain('none', 'Scale is restored')
- .done();
- }
-};
\ No newline at end of file
diff --git a/tests/index.html b/tests/index.html
deleted file mode 100644
index 19d615a..0000000
--- a/tests/index.html
+++ /dev/null
@@ -1,34 +0,0 @@
-
-
-
- Test page for Shower
-
-
-
-
-
-
-
-
1
-
-
-
2
-
-
-
3
-
-
-
4
-
-
-
5
-
1
-
2
-
3
-
-
-
6
-
-
-
-
\ No newline at end of file
diff --git a/tests/navigation.js b/tests/navigation.js
deleted file mode 100644
index 316707d..0000000
--- a/tests/navigation.js
+++ /dev/null
@@ -1,54 +0,0 @@
-module.exports = {
- 'Navigation doesn’t work in List mode': function (test) {
- test
- .open('http://localhost:7497/tests/#5')
- .sendKeys('body', '\uE014') // Right
- .assert.attr('[id="6"]', 'class').to.contain('active', 'Next slide is Active')
- .done();
- },
- 'Right Arrow key is switching first Next item to Active': function (test) {
- test
- .open('http://localhost:7497/tests/?full#5')
- .sendKeys('body', '\uE014') // Right
- .assert.attr('[id="5"] .next:first-of-type', 'class').to.contain('active', 'First Next item is Active')
- .done();
- },
- 'Left Arrow key is switching Active items back to Next': function (test) {
- test
- .open('http://localhost:7497/tests/?full#5')
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE012') // Left
- .sendKeys('body', '\uE012') // Left
- .assert.numberOfElements('[id="5"] .next.active', 0, 'There are no Active items')
- .done();
- },
- 'Right Arrow key is switching to next slide once all Next items becomes Active': function (test) {
- test
- .open('http://localhost:7497/tests/?full#5')
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .assert.attr('[id="6"]', 'class').to.contain('active', 'Next slide is Active')
- .done();
- },
- 'Left Arrow key is switching to previous slide when all Next items becomes Active': function (test) {
- test
- .open('http://localhost:7497/tests/?full#5')
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE014') // Right
- .sendKeys('body', '\uE012') // Left
- .assert.attr('[id="4"]', 'class').to.contain('active', 'Previous slide is Active')
- .done();
- },
- 'Reload reset navigation': function (test) {
- test
- .open('http://localhost:7497/tests/?full#5')
- .sendKeys('body', '\uE014') // Right
- .reload()
- .assert.numberOfElements('[id="5"] .next.active', 0, 'There are no Active items')
- .done();
- }
-};
\ No newline at end of file
diff --git a/tests/shortcuts.js b/tests/shortcuts.js
deleted file mode 100644
index 3b89155..0000000
--- a/tests/shortcuts.js
+++ /dev/null
@@ -1,250 +0,0 @@
-module.exports = {
- // --------------------------------
- // F5
- // --------------------------------
- 'F5 is switching from List to Full': function (test) {
- test
- .open('http://localhost:7497/tests/')
- .sendKeys('body', '\uE035') // F5
- .assert.attr('body', 'class').to.contain('full', 'Mode is Full')
- .done();
- },
- 'F5 is switching from Full to List': function (test) {
- test
- .open('http://localhost:7497/tests/?full')
- .sendKeys('body', '\uE035') // F5
- .assert.attr('body', 'class').to.contain('list', 'Mode is List')
- .done();
- },
- // --------------------------------
- // Cmd Alt P
- // --------------------------------
- 'Cmd Alt P keys are switching from List to Full': function (test) {
- test
- .open('http://localhost:7497/tests/')
- .sendKeys('body', '\uE03D\uE00A\u0070') // Cmd Alt P
- .assert.attr('body', 'class').to.contain('full', 'Mode is Full')
- .done();
- },
- 'Cmd Alt P keys are not switching from Full to List': function (test) {
- test
- .open('http://localhost:7497/tests/?full#1')
- .sendKeys('body', '\uE03D\uE00A\u0070') // Cmd Alt P
- .assert.attr('body', 'class').to.contain('full', 'Mode is Full')
- .done();
- },
- // --------------------------------
- // Esc
- // --------------------------------
- 'Esc is switching from Full to List': function (test) {
- test
- .open('http://localhost:7497/tests/?full#1')
- .sendKeys('body', '\uE00C') // Esc
- .assert.attr('body', 'class').to.contain('list', 'Mode is List')
- .done();
- },
- // --------------------------------
- // Left
- // --------------------------------
- 'Left Arrow key is switching to the previous slide': function (test) {
- test
- .open('http://localhost:7497/tests/?full#2')
- .sendKeys('body', '\uE012') // Left
- .assert.attr('[id="1"]', 'class').to.contain('active', 'Previous slide is Active')
- .done();
- },
- // --------------------------------
- // Right
- // --------------------------------
- 'Right Arrow key is switching to the next slide': function (test) {
- test
- .open('http://localhost:7497/tests/?full#1')
- .sendKeys('body', '\uE014') // Right
- .assert.attr('[id="2"]', 'class').to.contain('active', 'Next slide is Active')
- .done();
- },
- // --------------------------------
- // Up
- // --------------------------------
- 'Up Arrow key is switching to the previous slide': function (test) {
- test
- .open('http://localhost:7497/tests/?full#2')
- .sendKeys('body', '\uE013') // Up
- .assert.attr('[id="1"]', 'class').to.contain('active', 'Previous slide is Active')
- .done();
- },
- // --------------------------------
- // Down
- // --------------------------------
- 'Down Arrow key is switching to the next slide': function (test) {
- test
- .open('http://localhost:7497/tests/?full#1')
- .sendKeys('body', '\uE015') // Down
- .assert.attr('[id="2"]', 'class').to.contain('active', 'Next slide is Active')
- .done();
- },
- // --------------------------------
- // H
- // --------------------------------
- 'H key is switching to the previous slide': function (test) {
- test
- .open('http://localhost:7497/tests/?full#2')
- .sendKeys('body', '\u0068') // H
- .assert.attr('[id="1"]', 'class').to.contain('active', 'Previous slide is Active')
- .done();
- },
- // --------------------------------
- // K
- // --------------------------------
- 'K key is switching to the previous slide': function (test) {
- test
- .open('http://localhost:7497/tests/?full#2')
- .sendKeys('body', '\u006B') // K
- .assert.attr('[id="1"]', 'class').to.contain('active', 'Previous slide is Active')
- .done();
- },
- // --------------------------------
- // J
- // --------------------------------
- 'J key is switching to the next slide': function (test) {
- test
- .open('http://localhost:7497/tests/?full#1')
- .sendKeys('body', '\u006A') // J
- .assert.attr('[id="2"]', 'class').to.contain('active', 'Next slide is Active')
- .done();
- },
- // --------------------------------
- // L
- // --------------------------------
- 'L key is switching to the next slide': function (test) {
- test
- .open('http://localhost:7497/tests/?full#1')
- .sendKeys('body', '\u006C') // L
- .assert.attr('[id="2"]', 'class').to.contain('active', 'Next slide is Active')
- .done();
- },
- // --------------------------------
- // Space
- // --------------------------------
- 'Space key is switching to the next slide': function (test) {
- test
- .open('http://localhost:7497/tests/?full#1')
- .sendKeys('body', '\uE00D') // Space
- .assert.attr('[id="2"]', 'class').to.contain('active', 'Next slide is Active')
- .done();
- },
- 'Shift Space keys are switching to the previous slide': function (test) {
- test
- .open('http://localhost:7497/tests/?full#2')
- .sendKeys('body', '\uE008\uE00D') // Shift Space
- .assert.attr('[id="1"]', 'class').to.contain('active', 'Previous slide is Active')
- .done();
- },
- // --------------------------------
- // Tab
- // --------------------------------
- 'Tab key is switching to the next slide': function (test) {
- test
- .open('http://localhost:7497/tests/?full#1')
- .sendKeys('body', '\uE004') // Tab
- // Not sure why it’s failing. It works fine manually
- .assert.attr('[id="2"]', 'class').to.contain('active', 'Next slide is Active')
- .done();
- },
- 'Shift Tab keys are switching to the previous slide': function (test) {
- test
- .open('http://localhost:7497/tests/?full#2')
- .sendKeys('body', '\uE008\uE004') // Shift Tab
- // Not sure why it’s failing. It works fine manually
- .assert.attr('[id="1"]', 'class').to.contain('active', 'Previous slide is Active')
- .done();
- },
- // --------------------------------
- // PageUp
- // --------------------------------
- 'PageUp key is switching to the previous slide': function (test) {
- test
- .open('http://localhost:7497/tests/?full#2')
- .sendKeys('body', '\uE00E') // PageUp
- .assert.attr('[id="1"]', 'class').to.contain('active', 'Previous slide is Active')
- .done();
- },
- // --------------------------------
- // PageDown
- // --------------------------------
- 'PageDown key is switching to the next slide': function (test) {
- test
- .open('http://localhost:7497/tests/?full#1')
- .sendKeys('body', '\uE00F') // PageDown
- .assert.attr('[id="2"]', 'class').to.contain('active', 'Next slide is Active')
- .done();
- },
- // --------------------------------
- // Home
- // --------------------------------
- 'Home key select the first slide in List mode': function (test) {
- test
- .open('http://localhost:7497/tests/')
- .sendKeys('body', '\uE011') // Home
- // Failing unlike next one with current slide
- .assert.attr('[id="1"]', 'class').to.contain('active', 'First slide is active')
- .done();
- },
- 'Home key select the first slide in List mode (with current)': function (test) {
- test
- .open('http://localhost:7497/tests/#5')
- .sendKeys('body', '\uE011') // Home
- .assert.attr('[id="1"]', 'class').to.contain('active', 'First slide is active')
- .done();
- },
- 'Home key select the first slide in Full mode': function (test) {
- test
- .open('http://localhost:7497/tests/?full#5')
- .sendKeys('body', '\uE011') // Home
- .assert.attr('[id="1"]', 'class').to.contain('active', 'First slide is active')
- .done();
- },
- // --------------------------------
- // End
- // --------------------------------
- 'End key select the last slide in List mode': function (test) {
- test
- .open('http://localhost:7497/tests/')
- .sendKeys('body', '\uE010') // End
- // Failing unlike next one with current slide
- .assert.attr('[id="6"]', 'class').to.contain('active', 'Last slide is active')
- .done();
- },
- 'End key select the last slide in List mode (with current)': function (test) {
- test
- .open('http://localhost:7497/tests/#1')
- .sendKeys('body', '\uE010') // End
- .assert.attr('[id="6"]', 'class').to.contain('active', 'Last slide is active')
- .done();
- },
- 'End key select the last slide in Full mode': function (test) {
- test
- .open('http://localhost:7497/tests/?full#1')
- .sendKeys('body', '\uE010') // End
- .assert.attr('[id="6"]', 'class').to.contain('active', 'Last slide is active')
- .done();
- },
- // --------------------------------
- // Enter
- // --------------------------------
- 'Enter is opening current slide': function (test) {
- test
- .open('http://localhost:7497/tests/#1')
- .sendKeys('body', '\uE007') // Enter
- .assert.attr('body', 'class', 'full', 'Full mode')
- .assert.attr('[id="1"]', 'class').to.contain('active', 'First slide is active')
- .done();
- },
- 'Enter is not opening any slide if there’s no current': function (test) {
- test
- .open('http://localhost:7497/tests/')
- .sendKeys('body', '\uE007') // Enter
- .assert.attr('body', 'class', 'list', 'Mode is List')
- .done();
- }
-};
\ No newline at end of file
diff --git a/tests/timer.js b/tests/timer.js
deleted file mode 100644
index a6412ab..0000000
--- a/tests/timer.js
+++ /dev/null
@@ -1,31 +0,0 @@
-module.exports = {
- 'Timer is switching to the next slide when finished': function (test) {
- test
- .open('http://localhost:7497/tests/?full#3')
- .wait(5000)
- .assert.attr('[id="4"]', 'class').to.contain('active', 'Next slide is Active')
- .done();
- },
- 'Timer becomes Active and switching to the next slide when finished': function (test) {
- test
- .open('http://localhost:7497/tests/?full#4')
- .sendKeys('body', '\uE012') // Left
- .wait(5000)
- .assert.attr('[id="4"]', 'class').to.contain('active', 'Next slide is Active')
- .done();
- },
- 'Left Arrow key is skipping timer while it’s not finished': function (test) {
- test
- .open('http://localhost:7497/tests/?full#3')
- .sendKeys('body', '\uE012') // Left
- .assert.attr('[id="2"]', 'class').to.contain('active', 'Previous slide is Active')
- .done();
- },
- 'Right Arrow key is skipping timer while it’s not finished': function (test) {
- test
- .open('http://localhost:7497/tests/?full#3')
- .sendKeys('body', '\uE014') // Right
- .assert.attr('[id="4"]', 'class').to.contain('active', 'Next slide is Active')
- .done();
- }
-};
\ No newline at end of file
diff --git a/themes/bright b/themes/bright
deleted file mode 160000
index 2ba8abe..0000000
--- a/themes/bright
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 2ba8abeb2b23b3c202472e02eff4f68adc13bf25
diff --git a/themes/ribbon b/themes/ribbon
deleted file mode 160000
index b79263a..0000000
--- a/themes/ribbon
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit b79263a6bf1b81cf8793077718fcbe0e0f2833db