mirror of
https://github.com/webslides/WebSlides.git
synced 2025-09-15 15:32:05 +02:00
Compare commits
14 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
b8b7211f4f | ||
|
9dc223912e | ||
|
587590a8e8 | ||
|
fb5208218f | ||
|
87db22523c | ||
|
d9c2cb44f8 | ||
|
9a2dfe0e52 | ||
|
26716804cb | ||
|
ea0f2cb833 | ||
|
5dd1b9c649 | ||
|
ed93fd8df9 | ||
|
43105bd180 | ||
|
bee1e87c7f | ||
|
e9fa8d2e3a |
1
.npmignore
Normal file
1
.npmignore
Normal file
@@ -0,0 +1 @@
|
||||
.babelrc
|
@@ -1,4 +1,3 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "6"
|
||||
- "7"
|
||||
- "10"
|
||||
|
@@ -92,7 +92,7 @@ You can add:
|
||||
### Dive In!
|
||||
|
||||
- Do not miss [our demos](https://webslides.tv/).
|
||||
- Want to get techie? Read [our wiki](wiki):
|
||||
- Want to get techie? Read [our wiki](https://github.com/webslides/WebSlides/wiki):
|
||||
- [FAQ](https://github.com/webslides/WebSlides/wiki)
|
||||
- [Core API](https://github.com/webslides/WebSlides/wiki/Core-API)
|
||||
- [Plugin Docs](https://github.com/webslides/WebSlides/wiki/Plugin-docs)
|
||||
|
10
index.html
10
index.html
@@ -294,11 +294,11 @@
|
||||
</svg>
|
||||
<strong>Guides</strong>
|
||||
</h4>
|
||||
<p>If you need help, here's just three tutorials. Just a basic knowledge of HTML is required:</p>
|
||||
<p>If you need help, here's just some tutorials. Just a basic knowledge of HTML is required:</p>
|
||||
<ul class="description">
|
||||
<li><a href="demos/components.html" title="WebSlides Components">WebSlides Components</a>.</li>
|
||||
<li><a href="demos/classes.html" title="WebSlides Classes">WebSlides Classes</a>.</li>
|
||||
<li><a href="demos/media.html" title="WebSlides Media">WebSlides Media: images, videos...</a></li>
|
||||
<li><a href="/demos/components.html" title="WebSlides Components">Components</a> · <a href="/demos/classes.html" title="WebSlides Classes">Classes</a>.</li>
|
||||
<li><a href="https://codepen.io/webslides" title="WebSlides on Codepen">WebSlides on Codepen</a>.</li>
|
||||
<li><a href="/demos/media.html" title="WebSlides Media">WebSlides Media: images, videos...</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="column">
|
||||
@@ -357,7 +357,7 @@
|
||||
</svg>
|
||||
</a>
|
||||
</h2>
|
||||
<p>People share content that makes them feel inspired. WebSlides is a very effective way to engage young audiences, customers, and teams.</p>
|
||||
<p>People share content that makes them feel inspired. WebSlides is a very effective way to engage young audiences, customers, and teams.</p>
|
||||
<p>Best,<br> <a href="https://twitter.com/jlantunez">@jlantunez</a>, <a href="https://twitter.com/belelros">@belelros</a>, and <a href="https://twitter.com/luissacristan">@luissacristan</a>.</p>
|
||||
</div>
|
||||
<!-- .end .content-right -->
|
||||
|
15192
package-lock.json
generated
15192
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
26
package.json
26
package.json
@@ -19,7 +19,7 @@
|
||||
},
|
||||
{
|
||||
"name": "Antonio Laguna",
|
||||
"email": "a.laguna@funcion13.com"
|
||||
"email": "anlagmat@gmail.com"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
@@ -32,18 +32,18 @@
|
||||
"autoprefixer": "^7.1.4",
|
||||
"babel-cli": "^6.26.0",
|
||||
"babel-core": "^6.26.0",
|
||||
"babel-jest": "^21.0.2",
|
||||
"babel-jest": "^22.0.4",
|
||||
"babel-loader": "^7.1.2",
|
||||
"babel-preset-env": "^1.6.0",
|
||||
"babel-preset-es2015": "^6.24.1",
|
||||
"codecov": "^2.3.0",
|
||||
"codecov": "^3.0.0",
|
||||
"css-loader": "^0.28.7",
|
||||
"eslint": "^4.7.0",
|
||||
"eslint-loader": "^1.9.0",
|
||||
"eslint-plugin-jest": "^21.1.0",
|
||||
"extract-text-webpack-plugin": "^3.0.0",
|
||||
"jest": "^21.1.0",
|
||||
"node-sass": "^4.5.3",
|
||||
"jest": "^22.0.4",
|
||||
"node-sass": "4.9.4",
|
||||
"npm-run-all": "^4.1.1",
|
||||
"postcss-loader": "^2.0.6",
|
||||
"pre-commit": "^1.2.2",
|
||||
@@ -52,7 +52,7 @@
|
||||
"sass-loader": "^6.0.6",
|
||||
"simulant": "^0.2.2",
|
||||
"smart-banner-webpack-plugin": "^3.0.1",
|
||||
"style-loader": "^0.18.2",
|
||||
"style-loader": "^0.19.1",
|
||||
"webpack": "^3.6.0",
|
||||
"webpack-dev-server": "^2.8.2"
|
||||
},
|
||||
@@ -80,19 +80,13 @@
|
||||
]
|
||||
},
|
||||
"jest": {
|
||||
"collectCoverage": true
|
||||
"collectCoverage": true,
|
||||
"testURL": "http://localhost/"
|
||||
},
|
||||
"pre-commit": [
|
||||
"lint"
|
||||
],
|
||||
"babel": {
|
||||
"presets": [
|
||||
[
|
||||
"es2015",
|
||||
{
|
||||
"modules": false
|
||||
}
|
||||
]
|
||||
]
|
||||
"dependencies": {
|
||||
"request": "^2.83.0"
|
||||
}
|
||||
}
|
||||
|
@@ -8,8 +8,9 @@ const CLASSES = {
|
||||
const Events = {
|
||||
ENTER: 'dom:enter',
|
||||
LEAVE: 'dom:leave',
|
||||
DISABLE: 'slide:disable',
|
||||
ENABLE: 'slide:enable',
|
||||
DISABLE: 'slide:disable'
|
||||
SHOW: 'slide:show'
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -36,7 +37,7 @@ class Slide {
|
||||
*/
|
||||
this.i = i;
|
||||
|
||||
this.el.id = `section-${(i + 1)}`;
|
||||
this.el.id = this.el.id ? this.el.id : `section-${(i + 1)}`;
|
||||
this.el.classList.add(CLASSES.SLIDE);
|
||||
|
||||
// Hide slides by default
|
||||
@@ -57,6 +58,7 @@ class Slide {
|
||||
show() {
|
||||
DOM.show(this.el);
|
||||
this.el.classList.add(CLASSES.CURRENT);
|
||||
this.fire_(Events.SHOW);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -19,7 +19,7 @@ const PLUGINS = {
|
||||
'nav': Plugins.Navigation,
|
||||
'scroll': Plugins.Scroll,
|
||||
'touch': Plugins.Touch,
|
||||
'video': Plugins.Video,
|
||||
'media': Plugins.Media,
|
||||
'youtube': Plugins.YouTube,
|
||||
'zoom': Plugins.Zoom
|
||||
};
|
||||
@@ -315,6 +315,7 @@ export default class WebSlides {
|
||||
|
||||
DOM.fireEvent(this.el, 'ws:slide-change', {
|
||||
slides: this.maxSlide_,
|
||||
slideEl: slide.el,
|
||||
currentSlide0: this.currentSlideI_,
|
||||
currentSlide: this.currentSlideI_ + 1
|
||||
});
|
||||
|
@@ -5,7 +5,7 @@ import {default as Slide, Events as SlideEvents} from '../modules/slide';
|
||||
* Video plugin. Video plugin that allows to autoplay videos once the slide gets
|
||||
* active.
|
||||
*/
|
||||
export default class Video {
|
||||
export default class Media {
|
||||
/**
|
||||
* @param {WebSlides} wsInstance The WebSlides instance.
|
||||
* @constructor
|
||||
@@ -17,24 +17,24 @@ export default class Video {
|
||||
*/
|
||||
this.ws_ = wsInstance;
|
||||
|
||||
const videos = DOM.toArray(this.ws_.el.querySelectorAll('video'));
|
||||
const medias = DOM.toArray(this.ws_.el.querySelectorAll('video,audio'));
|
||||
|
||||
if (videos.length) {
|
||||
videos.forEach(video => {
|
||||
if (!video.hasAttribute('autoplay')) {
|
||||
if (medias.length) {
|
||||
medias.forEach(media => {
|
||||
if (!media.hasAttribute('autoplay')) {
|
||||
return;
|
||||
}
|
||||
|
||||
video.removeAttribute('autoplay');
|
||||
video.pause();
|
||||
video.currentTime = 0;
|
||||
const {i} = Slide.getSectionFromEl(video);
|
||||
media.removeAttribute('autoplay');
|
||||
media.pause();
|
||||
media.currentTime = 0;
|
||||
const {i} = Slide.getSectionFromEl(media);
|
||||
const slide = wsInstance.slides[i - 1];
|
||||
|
||||
slide.video = video;
|
||||
slide.media = media;
|
||||
|
||||
slide.el.addEventListener(SlideEvents.ENABLE, Video.onSectionEnabled);
|
||||
slide.el.addEventListener(SlideEvents.DISABLE, Video.onSectionDisabled);
|
||||
slide.el.addEventListener(SlideEvents.ENABLE, Media.onSectionEnabled);
|
||||
slide.el.addEventListener(SlideEvents.DISABLE, Media.onSectionDisabled);
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -44,7 +44,7 @@ export default class Video {
|
||||
* @param {CustomEvent} event
|
||||
*/
|
||||
static onSectionEnabled(event) {
|
||||
event.detail.slide.video.play();
|
||||
event.detail.slide.media.play();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -52,6 +52,6 @@ export default class Video {
|
||||
* @param {CustomEvent} event
|
||||
*/
|
||||
static onSectionDisabled(event) {
|
||||
event.detail.slide.video.pause();
|
||||
event.detail.slide.media.pause();
|
||||
}
|
||||
}
|
@@ -60,6 +60,9 @@ export default class Navigation {
|
||||
this.el.appendChild(this.counter);
|
||||
|
||||
this.ws_.el.appendChild(this.el);
|
||||
this.slides = Array.prototype.slice.call(
|
||||
document.querySelectorAll('#webslides section')).map(s => s.id);
|
||||
|
||||
this.bindEvents_();
|
||||
}
|
||||
|
||||
@@ -73,6 +76,29 @@ export default class Navigation {
|
||||
this.next.addEventListener('click', this.onButtonClicked_.bind(this));
|
||||
this.prev.addEventListener('click', this.onButtonClicked_.bind(this));
|
||||
this.counter.addEventListener('click', this.onButtonClicked_.bind(this));
|
||||
document.body.addEventListener('click', this.onBodyClicked_.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Whenever the body is clicked, check if the element has [data-slide] attr
|
||||
* and if so, navigate to it.
|
||||
* @param {MouseEvent} event Click event
|
||||
*/
|
||||
onBodyClicked_(event) {
|
||||
const matches = document.body.matches || document.body.msMatchesSelector;
|
||||
let el;
|
||||
|
||||
if (matches.call(event.target, '[data-slide]')) {
|
||||
el = event.target;
|
||||
} else if (matches.call(event.target, '[data-slide] *')) {
|
||||
el = event.target.querySelector('[data-slide]');
|
||||
}
|
||||
|
||||
if (el) {
|
||||
event.preventDefault();
|
||||
const i = this.slides.indexOf(el.dataset.slide);
|
||||
this.ws_.goToSlide(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -6,7 +6,7 @@ import Keyboard from './keyboard';
|
||||
import Navigation from './navigation';
|
||||
import Scroll from './scroll';
|
||||
import Touch from './touch';
|
||||
import Video from './video';
|
||||
import Media from './media';
|
||||
import YouTube from './youtube';
|
||||
import Zoom from './zoom';
|
||||
|
||||
@@ -19,7 +19,7 @@ export default {
|
||||
Navigation,
|
||||
Scroll,
|
||||
Touch,
|
||||
Video,
|
||||
Media,
|
||||
YouTube,
|
||||
Zoom
|
||||
};
|
||||
|
@@ -148,7 +148,8 @@ export default class DOM {
|
||||
*/
|
||||
static fireEvent(target, eventType, eventInfo = {}) {
|
||||
const event = new WSCustomEvent(eventType, {
|
||||
detail: eventInfo
|
||||
detail: eventInfo,
|
||||
bubbles: true
|
||||
});
|
||||
|
||||
target.dispatchEvent(event);
|
||||
|
@@ -30,6 +30,7 @@ webslides.js will add .ws-ready automatically. Don't worry :) -- */
|
||||
height: 100vh;
|
||||
overflow-x: hidden;
|
||||
overflow-y: scroll;
|
||||
scrollbar-width: none; // sass-lint:disable-line no-misspelled-properties
|
||||
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*!
|
||||
* Name: WebSlides
|
||||
* Version: 1.5.0
|
||||
* Date: 2017-09-16
|
||||
* Date: 2018-01-01
|
||||
* Description: Making HTML presentations easy
|
||||
* URL: https://github.com/webslides/webslides#readme
|
||||
* Credits: @jlantunez, @LuisSacristan, @Belelros
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/*!
|
||||
* Name: WebSlides
|
||||
* Version: 1.5.0
|
||||
* Date: 2017-09-16
|
||||
* Date: 2018-01-01
|
||||
* Description: Making HTML presentations easy
|
||||
* URL: https://github.com/webslides/webslides#readme
|
||||
* Credits: @jlantunez, @LuisSacristan, @Belelros
|
||||
@@ -263,7 +263,8 @@ var DOM = function () {
|
||||
var eventInfo = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
|
||||
|
||||
var event = new __WEBPACK_IMPORTED_MODULE_0__custom_event__["a" /* default */](eventType, {
|
||||
detail: eventInfo
|
||||
detail: eventInfo,
|
||||
bubbles: true
|
||||
});
|
||||
|
||||
target.dispatchEvent(event);
|
||||
@@ -377,8 +378,9 @@ var CLASSES = {
|
||||
var Events = {
|
||||
ENTER: 'dom:enter',
|
||||
LEAVE: 'dom:leave',
|
||||
DISABLE: 'slide:disable',
|
||||
ENABLE: 'slide:enable',
|
||||
DISABLE: 'slide:disable'
|
||||
SHOW: 'slide:show'
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -408,7 +410,7 @@ var Slide = function () {
|
||||
*/
|
||||
this.i = i;
|
||||
|
||||
this.el.id = 'section-' + (i + 1);
|
||||
this.el.id = this.el.id ? this.el.id : 'section-' + (i + 1);
|
||||
this.el.classList.add(CLASSES.SLIDE);
|
||||
|
||||
// Hide slides by default
|
||||
@@ -436,6 +438,7 @@ var Slide = function () {
|
||||
value: function show() {
|
||||
__WEBPACK_IMPORTED_MODULE_0__utils_dom__["a" /* default */].show(this.el);
|
||||
this.el.classList.add(CLASSES.CURRENT);
|
||||
this.fire_(Events.SHOW);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1906,6 +1909,10 @@ var Navigation = function () {
|
||||
this.el.appendChild(this.counter);
|
||||
|
||||
this.ws_.el.appendChild(this.el);
|
||||
this.slides = Array.prototype.slice.call(document.querySelectorAll('#webslides section')).map(function (s) {
|
||||
return s.id;
|
||||
});
|
||||
|
||||
this.bindEvents_();
|
||||
}
|
||||
|
||||
@@ -1922,6 +1929,32 @@ var Navigation = function () {
|
||||
this.next.addEventListener('click', this.onButtonClicked_.bind(this));
|
||||
this.prev.addEventListener('click', this.onButtonClicked_.bind(this));
|
||||
this.counter.addEventListener('click', this.onButtonClicked_.bind(this));
|
||||
document.body.addEventListener('click', this.onBodyClicked_.bind(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* Whenever the body is clicked, check if the element has [data-slide] attr
|
||||
* and if so, navigate to it.
|
||||
* @param {MouseEvent} event Click event
|
||||
*/
|
||||
|
||||
}, {
|
||||
key: 'onBodyClicked_',
|
||||
value: function onBodyClicked_(event) {
|
||||
var matches = document.body.matches || document.body.msMatchesSelector;
|
||||
var el = void 0;
|
||||
|
||||
if (matches.call(event.target, '[data-slide]')) {
|
||||
el = event.target;
|
||||
} else if (matches.call(event.target, '[data-slide] *')) {
|
||||
el = event.target.querySelector('[data-slide]');
|
||||
}
|
||||
|
||||
if (el) {
|
||||
event.preventDefault();
|
||||
var i = this.slides.indexOf(el.dataset.slide);
|
||||
this.ws_.goToSlide(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
4
static/js/webslides.min.js
vendored
4
static/js/webslides.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -71,22 +71,26 @@ describe('Slide module', () => {
|
||||
const enter = jest.fn();
|
||||
const enable = jest.fn();
|
||||
const disable = jest.fn();
|
||||
const show = jest.fn();
|
||||
|
||||
slide.el.addEventListener('dom:leave', leave);
|
||||
slide.el.addEventListener('dom:enter', enter);
|
||||
slide.el.addEventListener('slide:enable', enable);
|
||||
slide.el.addEventListener('slide:disable', disable);
|
||||
slide.el.addEventListener('slide:show', show);
|
||||
|
||||
expect(enter).not.toHaveBeenCalled();
|
||||
expect(leave).not.toHaveBeenCalled();
|
||||
expect(enable).not.toHaveBeenCalled();
|
||||
expect(disable).not.toHaveBeenCalled();
|
||||
expect(show).not.toHaveBeenCalled();
|
||||
|
||||
slide.enable();
|
||||
expect(enter).not.toHaveBeenCalled();
|
||||
expect(leave).not.toHaveBeenCalled();
|
||||
expect(enable).toHaveBeenCalledTimes(1);
|
||||
expect(disable).not.toHaveBeenCalled();
|
||||
expect(show).not.toHaveBeenCalled();
|
||||
enable.mockClear();
|
||||
|
||||
slide.disable();
|
||||
@@ -94,6 +98,7 @@ describe('Slide module', () => {
|
||||
expect(leave).not.toHaveBeenCalled();
|
||||
expect(enable).not.toHaveBeenCalled();
|
||||
expect(disable).toHaveBeenCalledTimes(1);
|
||||
expect(show).not.toHaveBeenCalled();
|
||||
disable.mockClear();
|
||||
|
||||
slide.moveAfterLast();
|
||||
@@ -101,6 +106,7 @@ describe('Slide module', () => {
|
||||
expect(leave).toHaveBeenCalledTimes(1);
|
||||
expect(enable).not.toHaveBeenCalled();
|
||||
expect(disable).not.toHaveBeenCalled();
|
||||
expect(show).not.toHaveBeenCalled();
|
||||
enter.mockClear();
|
||||
leave.mockClear();
|
||||
|
||||
@@ -109,8 +115,12 @@ describe('Slide module', () => {
|
||||
expect(leave).toHaveBeenCalledTimes(1);
|
||||
expect(enable).not.toHaveBeenCalled();
|
||||
expect(disable).not.toHaveBeenCalled();
|
||||
expect(show).not.toHaveBeenCalled();
|
||||
enter.mockClear();
|
||||
leave.mockClear();
|
||||
|
||||
slide.show();
|
||||
expect(show).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
test('Move', () => {
|
||||
|
@@ -51,7 +51,7 @@ test('Should have correct properties', () => {
|
||||
expect(webslides.plugins.nav).toBeDefined();
|
||||
expect(webslides.plugins.scroll).toBeDefined();
|
||||
expect(webslides.plugins.touch).toBeDefined();
|
||||
expect(webslides.plugins.video).toBeDefined();
|
||||
expect(webslides.plugins.media).toBeDefined();
|
||||
expect(webslides.plugins.youtube).toBeDefined();
|
||||
expect(webslides.plugins.zoom).toBeDefined();
|
||||
|
||||
|
@@ -9,8 +9,7 @@ beforeAll(() => {
|
||||
test('Click nav plugin', () => {
|
||||
const next = jest.fn();
|
||||
const ws = document.getElementById('webslides');
|
||||
// Simulates dataset
|
||||
ws.dataset = {};
|
||||
|
||||
const webslides = {
|
||||
options: {
|
||||
changeOnClick: true
|
||||
|
@@ -1,4 +1,4 @@
|
||||
import Video from '../../src/js/plugins/video';
|
||||
import Video from '../../src/js/plugins/media';
|
||||
import DOM from '../../src/js/utils/dom';
|
||||
|
||||
beforeAll(() => {
|
@@ -29,7 +29,7 @@ test('Navigation plugin', () => {
|
||||
expect(fakeCounter.tagName).toBe('SPAN');
|
||||
expect(fakeCounter.childNodes.length).toBe(1);
|
||||
expect(fakeCounter.childNodes[0].tagName).toBe('A');
|
||||
expect(fakeCounter.childNodes[0].href).toBe('about:blank#');
|
||||
expect(fakeCounter.childNodes[0].href).toBe('http://localhost/#');
|
||||
expect(fakeCounter.childNodes[0].title).toBe('View all slides');
|
||||
|
||||
new Navigation(webslides);
|
||||
|
@@ -44,10 +44,10 @@ test('YouTube utility', () => {
|
||||
new YouTube(webslides);
|
||||
|
||||
expect(typeof window.onYouTubeIframeAPIReady).toBe('function');
|
||||
webslides.el.querySelector('[data-youtube]').dataset = {
|
||||
autoplay: true,
|
||||
youtubeId: 'CQY3KUR3VzM'
|
||||
};
|
||||
const el = webslides.el.querySelector('[data-youtube]');
|
||||
|
||||
el.dataset.autoplay = true;
|
||||
el.dataset.youtubeId = 'CQY3KUR3VzM';
|
||||
|
||||
window.onYouTubeIframeAPIReady();
|
||||
|
||||
|
@@ -8,8 +8,8 @@ describe('Hash utility', () => {
|
||||
document.location.hash = '#slide=1';
|
||||
const goto = jest.fn();
|
||||
const ws = document.getElementById('webslides');
|
||||
// Simulates dataset
|
||||
ws.dataset = {};
|
||||
|
||||
|
||||
const webslides = {
|
||||
options: {
|
||||
changeOnClick: true
|
||||
|
Reference in New Issue
Block a user