youtube-chapters
Version:
A chapters markers generator plugin for a YouTube video, built using JavaScript.
1,290 lines (1,101 loc) • 36.3 kB
JavaScript
/*!
* youtube-chapters
* A YouTube chapter generator
* https://github.com/VD39/youtube-chapters
* @author Vijay Dubb
* @version 3.1.0
* Copyright 2013. MIT licensed.
*/
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory();
else if(typeof define === 'function' && define.amd)
define("YTC", [], factory);
else if(typeof exports === 'object')
exports["YTC"] = factory();
else
root["YTC"] = factory();
})(this, function() {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 3);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.YouTubeChapters = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _helperFunctions = __webpack_require__(2);
var _query = __webpack_require__(4);
var _query2 = _interopRequireDefault(_query);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var _elements = []; // Elements array to store the elements
var _players = []; // Players array to store the current players
/**
* Main YouTubeChapters class
*
* @class YouTubeChapters
* @example
* YouTubeChapters('elementID', options);
*
* or
*
* let player = new YouTubeChapters('elementID', options);
*/
var YouTubeChapters = exports.YouTubeChapters = function () {
/**
* Main constructor for YouTubeChapters class
* @constructor
* @param {string} element - A DOM element to wrap in a YouTubeChapters object.
* @param {object} options - The options for the YouTube video
* @param {string} options.youtubeId - Sets the YouTube video based on the ID.
* @param {string} [options.id=A random number] - The random ID of the element.
* @param {string} [options.loader=Default loader] - Loader for the YouTube chapter frame.
* @param {bool} [options.fluid=false] - Sets if the YouTube video should be fluid/responsive.
* @param {array} [options.width=500px] - Sets the video and wrapper width.
* @param {array} [options.height=350px] - Sets the video height.
* @param {object} [options.playerVars=[]] - Sets the YouTube playerVars.
* @param {bool} [options.showTime=false] - Sets if the times should appear in the chapter frame.
* @param {array} options.chapters -Sets the chapters of the YouTube video.
*/
function YouTubeChapters(element, options) {
_classCallCheck(this, YouTubeChapters);
this.options = (0, _helperFunctions.defaultOption)(options, {});
for (var i = 0; i < _elements.length; i += 1) {
if (_elements[i] === element) {
throw new Error('An instance of YouTubeChapters with element ' + element + ' already exists.');
}
}
if (!element || typeof element !== 'string') {
throw new Error('Element has not been set, please set an element.');
}
if ((0, _query2.default)(element).length < 1) {
throw new Error('Element ' + this.element + ' does not exsit.');
}
this._interval = null;
this._playerReadyFunction = [];
this._readyFunction = [];
this.element = element;
this.ytc = {};
this.ytc.id = (0, _helperFunctions.defaultOption)(this.options.id, Math.floor(Math.random() * 99999));
this.ytc.element = 'youtube-iframe-' + this.ytc.id;
this.ytc.player = null;
this.ytc.options = {
youtubeId: (0, _helperFunctions.defaultOption)(this.options.youtubeId, 'bHQqvYy5KYo'),
loader: (0, _helperFunctions.defaultOption)(this.options.loader, (0, _helperFunctions.loader)()),
fluid: (0, _helperFunctions.defaultOption)(this.options.fluid, false),
playerVars: (0, _helperFunctions.defaultOption)(this.options.playerVars, {}),
width: (0, _helperFunctions.defaultOption)(this.options.width, '500px'),
height: (0, _helperFunctions.defaultOption)(this.options.height, '350px'),
showTime: (0, _helperFunctions.defaultOption)(this.options.showTime, false),
chapters: (0, _helperFunctions.sort)((0, _helperFunctions.defaultOption)(this.options.chapters, []))
};
if ((0, _helperFunctions.checkIds)(this.options.chapters)) {
throw new Error('All ID\'s must be unqiue');
}
this._init();
}
/**
* Begin the initialisation of the library.
* @private
* @returns {YouTubeChapters} YouTubeChapters
*/
_createClass(YouTubeChapters, [{
key: '_init',
value: function _init() {
_elements.push(this.element);
this._buildStruture()._addChapterPoints()._addTextPoints()._addYouTubeVideo();
}
/**
* Builds the main structure of YouTube frame.
* @private
* @returns {YouTubeChapters} YouTubeChapters
*/
}, {
key: '_buildStruture',
value: function _buildStruture() {
var mainElement = (0, _query2.default)(this.element);
mainElement.addElement('div', {
class: 'loading'
}, this.ytc.options.loader).addElement('div', {
class: 'youtube-chapter-wrapper'
});
mainElement.find('.loading').width(mainElement.parent().width());
mainElement.find('.youtube-chapter-wrapper').addElement('div', {
class: 'youtube-wrapper',
style: 'max-width: ' + this.ytc.options.width
}).addElement('div', {
class: 'chapters-wrapper'
}).addElement('div', {
class: 'text-wrapper'
}).find('.youtube-wrapper').addElement('div', {
class: 'youtube-video ' + (this.ytc.options.fluid ? 'fluid-wrapper' : ''),
id: 'youtube-video-' + this.ytc.id
}).find('.youtube-video').addElement('div', {
class: 'youtube-iframe',
id: this.ytc.element
});
mainElement.find('.chapters-wrapper').addElement('ul', {
id: 'chapters-wrapper-' + this.ytc.id
});
mainElement.find('.text-wrapper').addElement('ul', {
id: 'text-wrapper-' + this.ytc.id
});
return this;
}
/**
* Add the chapter points to the YouTube player frame.
* @private
* @returns {YouTubeChapters} YouTubeChapters
*/
}, {
key: '_addChapterPoints',
value: function _addChapterPoints() {
var _this = this;
/**
* Sets the click event to each chapter point.
* @private
* @param {event} event
*/
var goToChatper = function goToChatper(event) {
event.preventDefault();
_this.seekTo(event.currentTarget.getAttribute('data-time'));
};
var chaptersWrapper = (0, _query2.default)('#chapters-wrapper-' + this.ytc.id);
(0, _query2.default)(this.ytc.options.chapters).each(function (index, current) {
chaptersWrapper.addElement('li', {
class: 'chapter-point-wrapper',
id: 'chapter-' + current.id + '-' + _this.ytc.id,
dataTime: (0, _helperFunctions.convertTime)(current.time)
}).find('li.chapter-point-wrapper').addElement('div', {
class: 'chapter-point',
id: 'chapter-point-' + current.id + '-' + _this.ytc.id
}, current.title).find('.chapter-point').addElement('span', {
class: 'time'
}, _this.ytc.options.showTime ? current.time : '');
});
chaptersWrapper.find('li.chapter-point-wrapper').addEvent('click', goToChatper);
return this;
}
/**
* Adds the chapter’s optional text.
* @private
* @returns {YouTubeChapters} YouTubeChapters
*/
}, {
key: '_addTextPoints',
value: function _addTextPoints() {
var _this2 = this;
var textWrapper = (0, _query2.default)('#text-wrapper-' + this.ytc.id);
(0, _query2.default)(this.ytc.options.chapters).each(function (index, current) {
textWrapper.addElement('li', {
class: 'text-point',
id: 'text-point-' + current.id + '-' + _this2.ytc.id
}, current.text);
});
return this;
}
/**
* Adds the YouTube video script and sets up the YouTube video.
* @private
* @returns {YouTubeChapters} YouTubeChapters
*/
}, {
key: '_addYouTubeVideo',
value: function _addYouTubeVideo() {
var _this3 = this;
if (window.YT && window.YT.Player) {
this._playerSetup(this.ytc);
} else {
_players.push(function () {
_this3._playerSetup(_this3.ytc);
});
}
if (!window.onYouTubeIframeAPIReady) {
var tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
var firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
window.onYouTubePlayerAPIReady = function () {
(0, _query2.default)(_players).each(function (index, player) {
player();
});
};
}
return this;
}
/**
* Sets up the player height and displays the YouTube player has
* finished loading.
* @private
* @returns {YouTubeChapters} YouTubeChapters
*/
}, {
key: '_complete',
value: function _complete() {
var element = (0, _query2.default)(this.element);
var iframeHeight = this.ytc.options.fluid ? element.find('#youtube-video-' + this.ytc.id).height() : this.ytc.options.height.replace('px', '');
element.find('.chapters-wrapper').height(iframeHeight);
element.find('.youtube-chapter-wrapper').addClass('complete');
element.find('.loading').remove();
return this;
}
/**
* Calls the chaining methods such as play, pause, goToChatperId if there
* are any within the this._playerReadyFunction array.
* @private
* @returns {YouTubeChapters} YouTubeChapters
*/
}, {
key: '_callPlayerReady',
value: function _callPlayerReady() {
(0, _query2.default)(this._playerReadyFunction).each(function (index, playerReady) {
playerReady();
});
this._playerReadyFunction.length = 0;
return this;
}
/**
* Calls the ready method once the YouTube video has loaded.
* @private
* @returns {YouTubeChapters} YouTubeChapters
*/
}, {
key: '_callReady',
value: function _callReady() {
if (this._readyFunction.length) {
this._readyFunction[0]();
}
return this;
}
/**
* Sets up the player.
* @param {object} params
* @param {string} params.id - The random ID of the element.
* @param {string} params.element - The element.
* @param {object} params.player - The YouTube video player.
* @param {object} params.options - The original options.
* @private
*/
}, {
key: '_playerSetup',
value: function _playerSetup(params) {
var _this4 = this;
/**
* On ready method that is called once the video has finished playing.
* @private
*/
var onReady = function onReady() {
_this4._complete()._callReady()._callPlayerReady();
};
/**
* The method that runs while the YouTube video is being played.
* @param {event} event
* @private
*/
var onStateChange = function onStateChange(event) {
var chapters = (0, _query2.default)(_this4.element + ' .chapter-point-wrapper');
var player = _this4.ytc.player;
/**
* The playing method that add the active class and shows the chapter text
* to the current chapter.
* @private
*/
var playing = function playing() {
chapters.each(function (index, element) {
var current = (0, _query2.default)(element);
var textPoint = (0, _query2.default)('#' + element.getAttribute('id').replace('chapter', 'text-point'));
var time = parseFloat(current.attr('data-time'));
var next = void 0;
if (current.next().length > 0) {
next = parseFloat(current.next().attr('data-time'));
} else {
next = player.getDuration();
}
current.removeClass('current');
textPoint.removeClass('current');
if (player.getCurrentTime() > time && player.getCurrentTime() < next) {
current.addClass('current');
if (!textPoint.isEmpty()) {
textPoint.addClass('current');
}
}
});
};
switch (event.data) {
case YT.PlayerState.PLAYING:
_this4._interval = setInterval(playing, 250);
break;
case YT.PlayerState.UNSTARTED:
case YT.PlayerState.BUFFERING:
case YT.PlayerState.CUED:
break;
case YT.PlayerState.PAUSED:
case YT.PlayerState.ENDED:
clearInterval(_this4._interval);
break;
default:
clearInterval(_this4._interval);
throw new Error('Something went wrong.');
}
};
/**
* The on error method if an error occurs while the video is being played.
* @param {event} event
* @private
*/
var onError = function onError(event) {
var errormsg = event.data;
if (errormsg === 150 || errormsg === 101) {
throw new Error('Error: An error has occurred while the video was loading.');
}
event.target.stopVideo();
};
params.player = new YT.Player(params.element, {
height: params.options.height,
width: params.options.width,
videoId: params.options.youtubeId,
playerVars: params.options.playerVars,
events: {
onReady: onReady,
onStateChange: onStateChange,
onError: onError
}
});
}
/**
* Function seek to and play video.
* @param {number} time - The time the video should seek to.
* @private
* @todo Add play and pause option
*/
}, {
key: '_seek',
value: function _seek(time) {
this.ytc.player.seekTo(time);
this.ytc.player.playVideo();
}
/**
* Ready function to call once the video has loaded.
* @param {function} callback - Function callback after player is finished loading.
* @param {YT} [callback.player] - The video player.
* @example
* YouTubeChapters(element, options)
* .ready(function(player) {
* ....
* });
*
* or
*
* let player = new YouTubeChapters();
* player.ready(function(player) {
* ....
* });
*
* @returns {YouTubeChapters} YouTubeChapters
*/
}, {
key: 'ready',
value: function ready(callback) {
var _this5 = this;
if (typeof callback !== 'function') {
throw new Error('ready method must include a function.');
}
if (window.YT && window.YT.Player) {
callback.call(this);
} else {
this._readyFunction.push(function () {
callback.call(_this5, _this5);
});
}
return this;
}
/**
* Goes to the position of the YouTube video.
* @param {number|string} seekToTime - The time to seek to.
* @example
* YouTubeChapters(element, options)
* .seekTo('03:43'); or
* .seekTo('2m 0s'); or
* .seekTo(67);
*
* or
*
* let player = new YouTubeChapters(element, options);
* player.seekTo('03:43'); or
* player.seekTo('2m 0s'); or
* player.seekTo(67);
*
* @returns {YouTubeChapters} YouTubeChapters
*/
}, {
key: 'seekTo',
value: function seekTo(seekToTime) {
var _this6 = this;
var sTT = parseFloat((0, _helperFunctions.convertTime)(seekToTime));
if (window.YT && window.YT.Player && this._playerReadyFunction.length === 0) {
this._seek(sTT);
} else {
this._playerReadyFunction.push(function () {
_this6._seek(sTT);
});
}
return this;
}
/**
* Goes to the video position of the chapter ID.
* @param {string} id - ID of the chapter.
* @example
* YouTubeChapters(element, options)
* .goToChatperId('id1');
*
* or
*
* let player = new YouTubeChapters(element, options);
* player.goToChatperId('id1');
*
* @returns {YouTubeChapters} YouTubeChapters
*/
}, {
key: 'goToChatperId',
value: function goToChatperId(id) {
var _this7 = this;
var time = (0, _helperFunctions.getTime)(this.ytc.options.chapters, id);
if (!time) {
throw new Error('No id with ' + id + ' found.');
}
var seekToTime = parseFloat(time);
if (window.YT && window.YT.Player && this._playerReadyFunction.length === 0) {
this._seek(seekToTime);
} else {
this._playerReadyFunction.push(function () {
_this7._seek(seekToTime);
});
}
return this;
}
/**
* Pauses the YouTube video.
* @example
* YouTubeChapters(element, options)
* .pause();
*
* or
*
* let player = new YouTubeChapters(element, options);
* player.pause();
*
* @returns {YouTubeChapters} YouTubeChapters
*/
}, {
key: 'pause',
value: function pause() {
var _this8 = this;
if (window.YT && window.YT.Player && this._playerReadyFunction.length === 0) {
this.ytc.player.pauseVideo();
} else {
this._playerReadyFunction.push(function () {
_this8.ytc.player.pauseVideo();
});
}
return this;
}
/**
* Plays the YouTube video.
* @example
* YouTubeChapters(element, options)
* .play();
*
* or
*
* let player = new YouTubeChapters(element, options);
* player.play();
*
* @returns {YouTubeChapters} YouTubeChapters
*/
}, {
key: 'play',
value: function play() {
var _this9 = this;
if (window.YT && window.YT.Player && this._playerReadyFunction.length === 0) {
this.ytc.player.playVideo();
} else {
this._playerReadyFunction.push(function () {
_this9.ytc.player.playVideo();
});
}
return this;
}
/**
* Static method so class doesn't have to be called with new.
* @param {string} element - A DOM element to wrap in a YouTubeChapters object.
* @param {object} options - The options for the YouTube video.
* @private
* @returns {YouTubeChapters} YouTubeChapters
*/
}], [{
key: 'setup',
value: function setup(element, options) {
return new YouTubeChapters(element, options);
}
}]);
return YouTubeChapters;
}();
/***/ }),
/* 1 */
/***/ (function(module, exports) {
// removed by extract-text-webpack-plugin
/***/ }),
/* 2 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
/**
* Sets the default option of the input option if option is not set.
* @param {any} option - Any option to check.
* @param {any} def - What the default of the option should be if option is undefined.
* @private
* @returns {any} Either the orginal option or default option.
*/
function defaultOption(option, def) {
if (!option || typeof option === 'undefined') {
return def;
}
return option;
}
/**
* Checks duplicate ids within an array.
* @param {array} chapters - Array of chapters.
* @private
* @returns {bool} If ID is duplicate.
*/
function checkIds(chapters) {
if (!chapters) {
return false;
}
var ids = chapters.map(function (item) {
return item.id;
});
return ids.some(function (item, idx) {
return ids.indexOf(item) !== idx;
});
}
/**
* Returns the time from the chapter array.
* @param {array} chapters - Array of chapters.
* @param {string} id - Id to check within the chapters array.
* @private
* @returns {number} The time of the current chapter.
*/
function getTime(chapters, id) {
if (!chapters) {
return false;
}
for (var i = 0; i < chapters.length; i += 1) {
if (chapters[i].id === id) {
return convertTime(chapters[i].time);
}
}
return null;
}
/**
* Check if input is a number.
* @param {string} value - Value to test.
* @private
* @returns {bool} If value is number or not.
*/
function _isNumber(value) {
return (/^\d+$/.test(value)
);
}
/**
* Returns the duration into seconds.
* @param {string} duration - Duration to convert.
* @private
* @returns {number} The duration.
*/
function convertTime(duration) {
if (_isNumber(duration)) {
return duration;
}
var match = duration.replace(/ /g, '').match(/(\d+h)?(\d+m)?(\d+s)?/);
if (match[0]) {
return (parseInt(match[1], 10) || 0) * 3600 + (parseInt(match[2], 10) || 0) * 60 + (parseInt(match[3], 10) || 0);
}
match = duration.split(':');
if (match.length > 2) {
return parseInt(match[0], 10) * 3600 + parseInt(match[1], 10) * 60 + parseInt(match[2], 10) * 1;
}
return parseInt(match[0], 10) * 60 + parseInt(match[1], 10) * 1;
}
/**
* Sorts the array by time.
* @param {array} array - The array to sort by time.
* @private
* @returns {array} The orginal array sorted.
*/
function sort(array) {
return array.sort(function (a, b) {
return convertTime(a.time) - convertTime(b.time);
});
}
/**
* Returns the default loading HTML.
* @private
* @returns {string} The default HTML for the loading.
*/
function loader() {
return '<div class="loading-wrapper">' + '<p class="loading-text">Loading YouTube Video</p>' + '</div>';
}
exports.defaultOption = defaultOption;
exports.checkIds = checkIds;
exports.getTime = getTime;
exports.convertTime = convertTime;
exports.sort = sort;
exports.loader = loader;
/***/ }),
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _youtubeChapters = __webpack_require__(0);
__webpack_require__(1);
/**
* Add YTC to window
* @private
*/
/* YouTube Chapters */
window.YTC = _youtubeChapters.YouTubeChapters.setup;
/**
* Export as YTC for shorter code.
* @private
*/
/* Stylesheets */
exports.default = _youtubeChapters.YouTubeChapters.setup;
module.exports = exports['default'];
/***/ }),
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
/**
* Main Q class
*
* @class Q
* @example
* let query = Q('elementID');
*/
var Q = function () {
/**
* Main constructor for Q class
* @constructor
* @param {string} element - A DOM element to wrap in a Q object.
*/
function Q(element) {
_classCallCheck(this, Q);
if (!element) {
this.length = 0;
return;
}
if (Array.isArray(element)) {
this.element = element;
} else if (element.nodeType) {
this.element = [];
this.element[0] = element;
} else {
this.element = [];
if (typeof element === 'string') {
var nodes = document.querySelectorAll(element);
for (var i = 0; i < nodes.length; i += 1) {
this.element[i] = nodes[i];
}
}
}
this.length = this.element.length;
}
/**
*Adds an element to the current queried element.
* @param {string} tag - What tag the element is to be.
* @param {object} object - Object of attributes.
* @param {string} text - the inner text of the element.
* @example
* Q(element)
* .addElement('div', {
* class: 'elementClass,
* id: 'elementID',
* style: 'height: 100px',
* });
*/
_createClass(Q, [{
key: 'addElement',
value: function addElement(tag, object, text) {
var crEl = document.createElement(tag);
if (object) {
new Q(crEl).attr(object);
}
if (text) {
crEl.innerHTML = text;
}
if (this.element.length) {
for (var i = 0; i < this.element.length; i += 1) {
this.element[i].appendChild(crEl);
}
} else {
this.element.appendChild(crEl);
}
return this;
}
/**
* Gets all element of that are found from the current element.
* @param {string} element - A DOM element to wrap in a Q object.
* @example
* Q(element)
* .find('element');
*
* @returns {Q} Q
*/
}, {
key: 'find',
value: function find(element) {
var results = [];
for (var i = 0; i < this.length; i += 1) {
var current = this.element[i].querySelectorAll(element);
if (current) {
for (var j = 0; j < current.length; j += 1) {
results.push(current[j]);
}
}
}
return new Q(results);
}
/**
* Attachs an event handler function to the selected elements.
* @param {string} eventName - What the event should be.
* @param {function} eventHandler - The function to attach to the event.
* @example
* Q(element)
* .addEvent('click', function () {
* ....
* });
*
*/
}, {
key: 'addEvent',
value: function addEvent(eventName, eventHandler) {
for (var i = 0; i < this.length; i += 1) {
this.element[i].addEventListener(eventName, eventHandler, false);
}
return this;
}
/**
* Iterate over an array, executing a function for each matched element.
* @param {function} callback - The function that will be executed on every object.
* @param {number} [callback.index] - The current index of the current element.
* @param {element} [callback.element] - The single element in the elements list.
* @example
* Q(element)
* .each(function (index, element) {
* ....
* });
*
* @returns {Q} Q
*/
}, {
key: 'each',
value: function each(callback) {
var end = void 0;
for (var i = 0; i < this.length; i += 1) {
end = callback.call(this.element[i], i, this.element[i]);
if (end === false) {
break;
}
}
return this;
}
/**
* Adds the class name from all current elements.
* @param {string} className - class to remove.
* @example
* Q(element)
* .addClass('className');
*
* @returns {Q} Q
*/
}, {
key: 'addClass',
value: function addClass(className) {
if (this.element.length > 0) {
for (var i = 0; i < this.element.length; i += 1) {
this.element[i].classList.add(className);
}
}
return this;
}
/**
* Remove the class name from all current elements.
* @param {string} className - class to remove.
* @example
* Q(element)
* .removeClass('className');
*
* @returns {Q} Q
*/
}, {
key: 'removeClass',
value: function removeClass(className) {
if (this.element.length > 0) {
for (var i = 0; i < this.element.length; i += 1) {
this.element[i].classList.remove(className);
}
}
return this;
}
/**
* Either sets or gets the height of the current element.
* @param {string} [height] - optional set height value.
* @example
*
* Get:
* Q(element)
* .height();
*
* or
*
* Set:
* Q(element)
* .height(200);
*
* @returns {number|Q} Height value or Q
*/
}, {
key: 'height',
value: function height(_height) {
if (_height) {
for (var i = 0; i < this.element.length; i += 1) {
this.element[i].style.height = _height + 'px';
}
} else {
return this.element[0].clientHeight;
}
return this;
}
/**
* Either sets or gets the width of the current element.
* @param {string} [width] - optional set width value.
* @example
*
* Get:
* Q(element)
* .width();
*
* or
*
* Set:
* Q(element)
* .width(200);
*
* @returns {number|Q} Width value or Q.
*/
}, {
key: 'width',
value: function width(_width) {
if (_width) {
for (var i = 0; i < this.element.length; i += 1) {
this.element[i].style.width = _width + 'px';
}
} else {
return this.element[0].clientWidth;
}
return this;
}
/**
* Either adds the attribute if object of attributes to add or
* returns the attrbutes if string input.
* @param {string|object} attr - attrribute.
* @example
* Get
* Q(element)
* .attr('class');
*
* or
*
* Set:
* Q(element)
* .attr({
* class: 'elementClass,
* id: 'elementID',
* style: 'height: 100px',
* });
*
* @returns {string|Q} Attribute value or Q.
*/
}, {
key: 'attr',
value: function attr(_attr) {
var _this = this;
if (typeof _attr === 'string') {
return this.element[0].getAttribute(_attr);
}
Object.keys(_attr).forEach(function (key) {
for (var i = 0; i < _this.element.length; i += 1) {
if (key.indexOf('data') > -1) {
_this.element[i].dataset[key.toLowerCase().replace('data', '')] = _attr[key];
} else {
_this.element[i].setAttribute(key, _attr[key]);
}
}
});
return this;
}
/**
* Removes the current element.
* @example
* Q(element)
* .remove()
*
* @returns {Q} Q
*/
}, {
key: 'remove',
value: function remove() {
for (var i = 0; i < this.element.length; i += 1) {
this.element[i].parentNode.removeChild(this.element[i]);
}
this.length = this.element.length;
return this;
}
/**
* Return the next element of the current element.
* @example
* Q(element)
* .next();
*
* @returns {Q} New query of the next element.
*/
}, {
key: 'next',
value: function next() {
return new Q(this.element[0].nextElementSibling);
}
/**
* Return is current element is empty of not.
* @example
* Q(element)
* .isEmpty();
*
* @returns {bool} If is empty or not.
*/
}, {
key: 'isEmpty',
value: function isEmpty() {
return this.element[0].innerHTML.trim() === '';
}
/**
* Returns parent node of the current element.
* @example
* Q(element)
* .parent();
*
* @returns {Q} New query of the parent element.
*/
}, {
key: 'parent',
value: function parent() {
return new Q(this.element[0].parentNode);
}
/**
* Returns new Q.
* @param {string} element - A DOM element to wrap in a Q object.
* @private
* @returns {Q} New Q class.
*/
}], [{
key: 'findSelector',
value: function findSelector(element) {
return new Q(element);
}
}]);
return Q;
}();
exports.default = Q.findSelector;
module.exports = exports['default'];
/***/ })
/******/ ]);
});