diff --git a/.editorconfig b/.editorconfig index 0a837c4..9c4332f 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 + +[package.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..11f925d --- /dev/null +++ b/.npmignore @@ -0,0 +1,3 @@ +.editorconfig +.gitignore +Contributing.md \ 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..6b3a351 100644 --- a/Readme.md +++ b/Readme.md @@ -1,44 +1,61 @@ -# 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 -- Press `Esc` to exit presentation mode +- Open [shwr.me](http://shwr.me/). +- Click any slide to enter presentation mode. +- 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 “[Shortcuts](https://github.com/shower/shower/wiki/Shortcuts)” wiki page for more info on how to control your presentation, “[Print](https://github.com/shower/shower/wiki/Print)” on how to print your presentation to PDF and [the rest of the Wiki](https://github.com/shower/shower/wiki) for more information about Shower in English and Russian. ## 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 starting with Shower: simple and advanced. -## 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). +1. Download [shwr.me/shower.zip](http://shwr.me/shower.zip) and unzip it. +2. Open `index.html` in any code or plain text editor, edit your slides in HTML. +3. Use `picture` folder to store pictures used in presentation. +4. Once finished, open `index.html` in browser, enter full screen and start presenting. + +See “[Quick Start](https://github.com/shower/shower/wiki/Quick-Start)” page for more details. + +### Advanced way + +This way requires [Git](http://git-scm.com) and [Node.js](http://nodejs.org) with npm installed. + +1. Clone Shower repository with Git `git clone git@github.com:shower/shower.git`. +2. Run `npm install` inside folder to install script and themes. +3. Open `index.html` in any code or plain text editor, edit your slides in HTML. +4. Use `picture` folder to store pictures used in presentation. +5. Once finished, open `index.html` in browser, enter full screen and start presenting. + +If you prefer bower then clone Shower this way `git clone git@github.com:shower/shower.git -b bower` and run `bower install` on 2nd step. + +See “[Quick Start](https://github.com/shower/shower/wiki/Quick-Start)” page for more details. ## 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/index.html b/index.html new file mode 100755 index 0000000..e38c45a --- /dev/null +++ b/index.html @@ -0,0 +1,176 @@ + + + + Shower Presentation Engine + + + + + + +
+

Shower Presentation Engine

+

Yours Truly, Famous Inc.

+
+
+

Shower Presentation Engine

+

Brought to you by Vadim Makeev

+ + + +
+
+

Shower Key Features

+
    +
  1. Built on HTML, CSS and vanilla JavaScript
  2. +
  3. All modern browsers are supported
  4. +
  5. Slide themes are separated from engine
  6. +
  7. Fully keyboard accessible
  8. +
  9. Printable to PDF
  10. +
+

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.

+
+
+

All Kind of Lists

+
    +
  1. Simple lists are marked with bullets
  2. +
  3. Ordered lists begin with a number
  4. +
  5. You can even nest lists one inside another +
      +
    • Or mix their types
    • +
    • But do not go too far
    • +
    • Otherwise audience will be bored
    • +
    +
  6. +
  7. Look, seven rows exactly!
  8. +
+
+
+

Serious Citations

+
+
+

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.

+
+
Marcus Tullius Cicero
+
+
+
+

Code Samples

+
+			<!DOCTYPE html>
+			<html lang="en">
+			<head> <!--Comment-->
+			    <title>Shower</title>
+			    <meta charset="UTF-8">
+			    <link rel="stylesheet" href="screen.css">
+			</head>
+		
+
+
+

Even Tables

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LocavoreUmamiHelveticaVegan
FingerstacheKaleChipsKeytar
SrirachaGluten-freeEnnuiKeffiyeh
ThundercatsJeanShortsBiodiesel
TerryRichardsonSwagBlog
+

It’s good to have information organized.

+
+
+

Pictures

+ + +
+
+

You can even shout this way

+
+
+

Inner Navigation

+
    +
  1. Lets you reveal list items one by one
  2. + + + + +
+
+
+

 See more on GitHub

+ +
+

Fork me on Github

+ +
+ + + + + \ No newline at end of file diff --git a/package.json b/package.json index 70098ca..692dc9a 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" + "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.0", + "shower-bright": "^1.0.0" } } 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

- - - -
-
-

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