UNPKG

tui-date-picker

Version:
1,933 lines (1,638 loc) 196 kB
/*! * TOAST UI Date Picker * @version 4.3.3 * @author NHN Cloud. FE Development Lab <dl_javascript@nhn.com> * @license MIT */ (function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(require("tui-time-picker")); else if(typeof define === 'function' && define.amd) define(["tui-time-picker"], factory); else if(typeof exports === 'object') exports["DatePicker"] = factory(require("tui-time-picker")); else root["tui"] = root["tui"] || {}, root["tui"]["DatePicker"] = factory(root["tui"]["TimePicker"]); })(window, function(__WEBPACK_EXTERNAL_MODULE__43__) { 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; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // 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 = "dist"; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 34); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * @fileoverview * This module provides a function to make a constructor * that can inherit from the other constructors like the CLASS easily. * @author NHN FE Development Lab <dl_javascript@nhn.com> */ var inherit = __webpack_require__(35); var extend = __webpack_require__(7); /** * @module defineClass */ /** * Help a constructor to be defined and to inherit from the other constructors * @param {*} [parent] Parent constructor * @param {Object} props Members of constructor * @param {Function} props.init Initialization method * @param {Object} [props.static] Static members of constructor * @returns {*} Constructor * @memberof module:defineClass * @example * var defineClass = require('tui-code-snippet/defineClass/defineClass'); // node, commonjs * * //-- #2. Use property --// * var Parent = defineClass({ * init: function() { // constuructor * this.name = 'made by def'; * }, * method: function() { * // ... * }, * static: { * staticMethod: function() { * // ... * } * } * }); * * var Child = defineClass(Parent, { * childMethod: function() {} * }); * * Parent.staticMethod(); * * var parentInstance = new Parent(); * console.log(parentInstance.name); //made by def * parentInstance.staticMethod(); // Error * * var childInstance = new Child(); * childInstance.method(); * childInstance.childMethod(); */ function defineClass(parent, props) { var obj; if (!props) { props = parent; parent = null; } obj = props.init || function() {}; if (parent) { inherit(obj, parent); } if (props.hasOwnProperty('static')) { extend(obj, props['static']); delete props['static']; } extend(obj.prototype, props); return obj; } module.exports = defineClass; /***/ }), /* 1 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * @fileoverview Constants of date-picker */ module.exports = { TYPE_DATE: 'date', TYPE_MONTH: 'month', TYPE_YEAR: 'year', TYPE_HOUR: 'hour', TYPE_MINUTE: 'minute', TYPE_MERIDIEM: 'meridiem', MIN_DATE: new Date(1900, 0, 1), MAX_DATE: new Date(2999, 11, 31), DEFAULT_LANGUAGE_TYPE: 'en', CLASS_NAME_SELECTED: 'tui-is-selected', CLASS_NAME_PREV_MONTH_BTN: 'tui-calendar-btn-prev-month', CLASS_NAME_PREV_YEAR_BTN: 'tui-calendar-btn-prev-year', CLASS_NAME_NEXT_YEAR_BTN: 'tui-calendar-btn-next-year', CLASS_NAME_NEXT_MONTH_BTN: 'tui-calendar-btn-next-month', CLASS_NAME_TITLE_TODAY: 'tui-calendar-title-today', DEFAULT_WEEK_START_DAY: 'Sun', WEEK_START_DAY_MAP: { sun: 0, mon: 1, tue: 2, wed: 3, thu: 4, fri: 5, sat: 6 } }; /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * @fileoverview Execute the provided callback once for each element present in the array(or Array-like object) in ascending order. * @author NHN FE Development Lab <dl_javascript@nhn.com> */ /** * Execute the provided callback once for each element present * in the array(or Array-like object) in ascending order. * If the callback function returns false, the loop will be stopped. * Callback function(iteratee) is invoked with three arguments: * 1) The value of the element * 2) The index of the element * 3) The array(or Array-like object) being traversed * @param {Array|Arguments|NodeList} arr The array(or Array-like object) that will be traversed * @param {function} iteratee Callback function * @param {Object} [context] Context(this) of callback function * @memberof module:collection * @example * var forEachArray = require('tui-code-snippet/collection/forEachArray'); // node, commonjs * * var sum = 0; * * forEachArray([1,2,3], function(value){ * sum += value; * }); * alert(sum); // 6 */ function forEachArray(arr, iteratee, context) { var index = 0; var len = arr.length; context = context || null; for (; index < len; index += 1) { if (iteratee.call(context, arr[index], index, arr) === false) { break; } } } module.exports = forEachArray; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* eslint-disable complexity */ /** * @fileoverview Returns the first index at which a given element can be found in the array. * @author NHN FE Development Lab <dl_javascript@nhn.com> */ var isArray = __webpack_require__(6); /** * @module array */ /** * Returns the first index at which a given element can be found in the array * from start index(default 0), or -1 if it is not present. * It compares searchElement to elements of the Array using strict equality * (the same method used by the ===, or triple-equals, operator). * @param {*} searchElement Element to locate in the array * @param {Array} array Array that will be traversed. * @param {number} startIndex Start index in array for searching (default 0) * @returns {number} the First index at which a given element, or -1 if it is not present * @memberof module:array * @example * var inArray = require('tui-code-snippet/array/inArray'); // node, commonjs * * var arr = ['one', 'two', 'three', 'four']; * var idx1 = inArray('one', arr, 3); // -1 * var idx2 = inArray('one', arr); // 0 */ function inArray(searchElement, array, startIndex) { var i; var length; startIndex = startIndex || 0; if (!isArray(array)) { return -1; } if (Array.prototype.indexOf) { return Array.prototype.indexOf.call(array, searchElement, startIndex); } length = array.length; for (i = startIndex; startIndex >= 0 && i < length; i += 1) { if (array[i] === searchElement) { return i; } } return -1; } module.exports = inArray; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * @fileoverview Utils for Datepicker component */ var forEachArray = __webpack_require__(2); var isHTMLNode = __webpack_require__(46); var sendHostname = __webpack_require__(47); var currentId = 0; var utils = { /** * Get a target element * @param {Event} ev Event object * @returns {HTMLElement} An event target element */ getTarget: function(ev) { return ev.target || ev.srcElement; }, /** * Return the same element with an element or a matched element searched by a selector. * @param {HTMLElement|string} param HTMLElement or selector * @returns {HTMLElement} A matched element */ getElement: function(param) { return isHTMLNode(param) ? param : document.querySelector(param); }, /** * Get a selector of the element. * @param {HTMLElement} elem An element * @returns {string} */ getSelector: function(elem) { var selector = ''; if (elem.id) { selector = '#' + elem.id; } else if (elem.className) { selector = '.' + elem.className.split(' ')[0]; } return selector; }, /** * Create an unique id. * @returns {number} */ generateId: function() { currentId += 1; return currentId; }, /** * Create a new array with all elements that pass the test implemented by the provided function. * @param {Array} arr - Array that will be traversed * @param {function} iteratee - iteratee callback function * @returns {Array} */ filter: function(arr, iteratee) { var result = []; forEachArray(arr, function(item) { if (iteratee(item)) { result.push(item); } }); return result; }, /** * Send hostname for GA * @ignore */ sendHostName: function() { sendHostname('date-picker', 'UA-129987462-1'); } }; module.exports = utils; /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * @fileoverview Utils for DatePicker component */ var isDate = __webpack_require__(28); var isNumber = __webpack_require__(15); var constants = __webpack_require__(1); var TYPE_DATE = constants.TYPE_DATE; var TYPE_MONTH = constants.TYPE_MONTH; var TYPE_YEAR = constants.TYPE_YEAR; /** * Utils of calendar * @namespace dateUtil * @ignore */ var utils = { /** * Get weeks count by paramenter * @param {number} year A year * @param {number} month A month * @returns {number} Weeks count (4~6) **/ getWeeksCount: function(year, month) { var firstDay = utils.getFirstDay(year, month), lastDate = utils.getLastDayInMonth(year, month); return Math.ceil((firstDay + lastDate) / 7); }, /** * @param {Date} date - Date instance * @returns {boolean} */ isValidDate: function(date) { return isDate(date) && !isNaN(date.getTime()); }, /** * Get which day is first by parameters that include year and month information. * @param {number} year A year * @param {number} month A month * @returns {number} (0~6) */ getFirstDay: function(year, month) { return new Date(year, month - 1, 1).getDay(); }, /** * Get timestamp of the first day. * @param {number} year A year * @param {number} month A month * @returns {number} timestamp */ getFirstDayTimestamp: function(year, month) { return new Date(year, month, 1).getTime(); }, /** * Get last date by parameters that include year and month information. * @param {number} year A year * @param {number} month A month * @returns {number} (1~31) */ getLastDayInMonth: function(year, month) { return new Date(year, month, 0).getDate(); }, /** * Chagne number 0~9 to '00~09' * @param {number} number number * @returns {string} * @example * dateUtil.prependLeadingZero(0); // '00' * dateUtil.prependLeadingZero(9); // '09' * dateUtil.prependLeadingZero(12); // '12' */ prependLeadingZero: function(number) { var prefix = ''; if (number < 10) { prefix = '0'; } return prefix + number; }, /** * Get meridiem hour * @param {number} hour - Original hour * @returns {number} Converted meridiem hour */ getMeridiemHour: function(hour) { hour %= 12; if (hour === 0) { hour = 12; } return hour; }, /** * Returns number or default * @param {*} any - Any value * @param {number} defaultNumber - Default number * @throws Will throw an error if the defaultNumber is invalid. * @returns {number} */ getSafeNumber: function(any, defaultNumber) { if (isNaN(defaultNumber) || !isNumber(defaultNumber)) { throw Error('The defaultNumber must be a valid number.'); } if (isNaN(any)) { return defaultNumber; } return Number(any); }, /** * Return date of the week * @param {number} year - Year * @param {number} month - Month * @param {number} weekNumber - Week number (0~5) * @param {number} dayNumber - Day number (0: sunday, 1: monday, ....) * @returns {number} */ getDateOfWeek: function(year, month, weekNumber, dayNumber) { var firstDayOfMonth = new Date(year, month - 1).getDay(); var dateOffset = firstDayOfMonth - dayNumber - 1; return new Date(year, month - 1, weekNumber * 7 - dateOffset); }, /** * Returns range arr * @param {number} start - Start value * @param {number} end - End value * @returns {Array} */ getRangeArr: function(start, end) { var arr = []; var i; if (start > end) { for (i = end; i >= start; i -= 1) { arr.push(i); } } else { for (i = start; i <= end; i += 1) { arr.push(i); } } return arr; }, /** * Returns cloned date with the start of a unit of time * @param {Date|number} date - Original date * @param {string} [type = TYPE_DATE] - Unit type * @throws {Error} * @returns {Date} */ cloneWithStartOf: function(date, type) { type = type || TYPE_DATE; date = new Date(date); // Does not consider time-level yet. date.setHours(0, 0, 0, 0); switch (type) { case TYPE_DATE: break; case TYPE_MONTH: date.setDate(1); break; case TYPE_YEAR: date.setMonth(0, 1); break; default: throw Error('Unsupported type: ' + type); } return date; }, /** * Returns cloned date with the end of a unit of time * @param {Date|number} date - Original date * @param {string} [type = TYPE_DATE] - Unit type * @throws {Error} * @returns {Date} */ cloneWithEndOf: function(date, type) { type = type || TYPE_DATE; date = new Date(date); // Does not consider time-level yet. date.setHours(23, 59, 59, 999); switch (type) { case TYPE_DATE: break; case TYPE_MONTH: date.setMonth(date.getMonth() + 1, 0); break; case TYPE_YEAR: date.setMonth(11, 31); break; default: throw Error('Unsupported type: ' + type); } return date; }, /** * Compare two dates * @param {Date|number} dateA - Date * @param {Date|number} dateB - Date * @param {string} [cmpLevel] - Comparing level * @returns {number} */ compare: function(dateA, dateB, cmpLevel) { var aTimestamp, bTimestamp; if (!(utils.isValidDate(dateA) && utils.isValidDate(dateB))) { return NaN; } if (!cmpLevel) { aTimestamp = dateA.getTime(); bTimestamp = dateB.getTime(); } else { aTimestamp = utils.cloneWithStartOf(dateA, cmpLevel).getTime(); bTimestamp = utils.cloneWithStartOf(dateB, cmpLevel).getTime(); } if (aTimestamp > bTimestamp) { return 1; } return aTimestamp === bTimestamp ? 0 : -1; }, /** * Returns whether two dates are same * @param {Date|number} dateA - Date * @param {Date|number} dateB - Date * @param {string} [cmpLevel] - Comparing level * @returns {boolean} */ isSame: function(dateA, dateB, cmpLevel) { return utils.compare(dateA, dateB, cmpLevel) === 0; }, /** * Returns whether the target is in range * @param {Date|number} start - Range start * @param {Date|number} end - Range end * @param {Date|number} target - Target * @param {string} [cmpLevel = TYPE_DATE] - Comparing level * @returns {boolean} */ inRange: function(start, end, target, cmpLevel) { return utils.compare(start, target, cmpLevel) < 1 && utils.compare(end, target, cmpLevel) > -1; } }; module.exports = utils; /***/ }), /* 6 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * @fileoverview Check whether the given variable is an instance of Array or not. * @author NHN FE Development Lab <dl_javascript@nhn.com> */ /** * Check whether the given variable is an instance of Array or not. * If the given variable is an instance of Array, return true. * @param {*} obj - Target for checking * @returns {boolean} Is array instance? * @memberof module:type */ function isArray(obj) { return obj instanceof Array; } module.exports = isArray; /***/ }), /* 7 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * @fileoverview Extend the target object from other objects. * @author NHN FE Development Lab <dl_javascript@nhn.com> */ /** * @module object */ /** * Extend the target object from other objects. * @param {object} target - Object that will be extended * @param {...object} objects - Objects as sources * @returns {object} Extended object * @memberof module:object */ function extend(target, objects) { // eslint-disable-line no-unused-vars var hasOwnProp = Object.prototype.hasOwnProperty; var source, prop, i, len; for (i = 1, len = arguments.length; i < len; i += 1) { source = arguments[i]; for (prop in source) { if (hasOwnProp.call(source, prop)) { target[prop] = source[prop]; } } } return target; } module.exports = extend; /***/ }), /* 8 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * @fileoverview This module provides some functions for custom events. And it is implemented in the observer design pattern. * @author NHN FE Development Lab <dl_javascript@nhn.com> */ var extend = __webpack_require__(7); var isExisty = __webpack_require__(37); var isString = __webpack_require__(13); var isObject = __webpack_require__(22); var isArray = __webpack_require__(6); var isFunction = __webpack_require__(39); var forEach = __webpack_require__(9); var R_EVENTNAME_SPLIT = /\s+/g; /** * @class * @example * // node, commonjs * var CustomEvents = require('tui-code-snippet/customEvents/customEvents'); */ function CustomEvents() { /** * @type {HandlerItem[]} */ this.events = null; /** * only for checking specific context event was binded * @type {object[]} */ this.contexts = null; } /** * Mixin custom events feature to specific constructor * @param {function} func - constructor * @example * var CustomEvents = require('tui-code-snippet/customEvents/customEvents'); // node, commonjs * * var model; * function Model() { * this.name = ''; * } * CustomEvents.mixin(Model); * * model = new Model(); * model.on('change', function() { this.name = 'model'; }, this); * model.fire('change'); * alert(model.name); // 'model'; */ CustomEvents.mixin = function(func) { extend(func.prototype, CustomEvents.prototype); }; /** * Get HandlerItem object * @param {function} handler - handler function * @param {object} [context] - context for handler * @returns {HandlerItem} HandlerItem object * @private */ CustomEvents.prototype._getHandlerItem = function(handler, context) { var item = {handler: handler}; if (context) { item.context = context; } return item; }; /** * Get event object safely * @param {string} [eventName] - create sub event map if not exist. * @returns {(object|array)} event object. if you supplied `eventName` * parameter then make new array and return it * @private */ CustomEvents.prototype._safeEvent = function(eventName) { var events = this.events; var byName; if (!events) { events = this.events = {}; } if (eventName) { byName = events[eventName]; if (!byName) { byName = []; events[eventName] = byName; } events = byName; } return events; }; /** * Get context array safely * @returns {array} context array * @private */ CustomEvents.prototype._safeContext = function() { var context = this.contexts; if (!context) { context = this.contexts = []; } return context; }; /** * Get index of context * @param {object} ctx - context that used for bind custom event * @returns {number} index of context * @private */ CustomEvents.prototype._indexOfContext = function(ctx) { var context = this._safeContext(); var index = 0; while (context[index]) { if (ctx === context[index][0]) { return index; } index += 1; } return -1; }; /** * Memorize supplied context for recognize supplied object is context or * name: handler pair object when off() * @param {object} ctx - context object to memorize * @private */ CustomEvents.prototype._memorizeContext = function(ctx) { var context, index; if (!isExisty(ctx)) { return; } context = this._safeContext(); index = this._indexOfContext(ctx); if (index > -1) { context[index][1] += 1; } else { context.push([ctx, 1]); } }; /** * Forget supplied context object * @param {object} ctx - context object to forget * @private */ CustomEvents.prototype._forgetContext = function(ctx) { var context, contextIndex; if (!isExisty(ctx)) { return; } context = this._safeContext(); contextIndex = this._indexOfContext(ctx); if (contextIndex > -1) { context[contextIndex][1] -= 1; if (context[contextIndex][1] <= 0) { context.splice(contextIndex, 1); } } }; /** * Bind event handler * @param {(string|{name:string, handler:function})} eventName - custom * event name or an object {eventName: handler} * @param {(function|object)} [handler] - handler function or context * @param {object} [context] - context for binding * @private */ CustomEvents.prototype._bindEvent = function(eventName, handler, context) { var events = this._safeEvent(eventName); this._memorizeContext(context); events.push(this._getHandlerItem(handler, context)); }; /** * Bind event handlers * @param {(string|{name:string, handler:function})} eventName - custom * event name or an object {eventName: handler} * @param {(function|object)} [handler] - handler function or context * @param {object} [context] - context for binding * //-- #1. Get Module --// * var CustomEvents = require('tui-code-snippet/customEvents/customEvents'); // node, commonjs * * //-- #2. Use method --// * // # 2.1 Basic Usage * CustomEvents.on('onload', handler); * * // # 2.2 With context * CustomEvents.on('onload', handler, myObj); * * // # 2.3 Bind by object that name, handler pairs * CustomEvents.on({ * 'play': handler, * 'pause': handler2 * }); * * // # 2.4 Bind by object that name, handler pairs with context object * CustomEvents.on({ * 'play': handler * }, myObj); */ CustomEvents.prototype.on = function(eventName, handler, context) { var self = this; if (isString(eventName)) { // [syntax 1, 2] eventName = eventName.split(R_EVENTNAME_SPLIT); forEach(eventName, function(name) { self._bindEvent(name, handler, context); }); } else if (isObject(eventName)) { // [syntax 3, 4] context = handler; forEach(eventName, function(func, name) { self.on(name, func, context); }); } }; /** * Bind one-shot event handlers * @param {(string|{name:string,handler:function})} eventName - custom * event name or an object {eventName: handler} * @param {function|object} [handler] - handler function or context * @param {object} [context] - context for binding */ CustomEvents.prototype.once = function(eventName, handler, context) { var self = this; if (isObject(eventName)) { context = handler; forEach(eventName, function(func, name) { self.once(name, func, context); }); return; } function onceHandler() { // eslint-disable-line require-jsdoc handler.apply(context, arguments); self.off(eventName, onceHandler, context); } this.on(eventName, onceHandler, context); }; /** * Splice supplied array by callback result * @param {array} arr - array to splice * @param {function} predicate - function return boolean * @private */ CustomEvents.prototype._spliceMatches = function(arr, predicate) { var i = 0; var len; if (!isArray(arr)) { return; } for (len = arr.length; i < len; i += 1) { if (predicate(arr[i]) === true) { arr.splice(i, 1); len -= 1; i -= 1; } } }; /** * Get matcher for unbind specific handler events * @param {function} handler - handler function * @returns {function} handler matcher * @private */ CustomEvents.prototype._matchHandler = function(handler) { var self = this; return function(item) { var needRemove = handler === item.handler; if (needRemove) { self._forgetContext(item.context); } return needRemove; }; }; /** * Get matcher for unbind specific context events * @param {object} context - context * @returns {function} object matcher * @private */ CustomEvents.prototype._matchContext = function(context) { var self = this; return function(item) { var needRemove = context === item.context; if (needRemove) { self._forgetContext(item.context); } return needRemove; }; }; /** * Get matcher for unbind specific hander, context pair events * @param {function} handler - handler function * @param {object} context - context * @returns {function} handler, context matcher * @private */ CustomEvents.prototype._matchHandlerAndContext = function(handler, context) { var self = this; return function(item) { var matchHandler = (handler === item.handler); var matchContext = (context === item.context); var needRemove = (matchHandler && matchContext); if (needRemove) { self._forgetContext(item.context); } return needRemove; }; }; /** * Unbind event by event name * @param {string} eventName - custom event name to unbind * @param {function} [handler] - handler function * @private */ CustomEvents.prototype._offByEventName = function(eventName, handler) { var self = this; var andByHandler = isFunction(handler); var matchHandler = self._matchHandler(handler); eventName = eventName.split(R_EVENTNAME_SPLIT); forEach(eventName, function(name) { var handlerItems = self._safeEvent(name); if (andByHandler) { self._spliceMatches(handlerItems, matchHandler); } else { forEach(handlerItems, function(item) { self._forgetContext(item.context); }); self.events[name] = []; } }); }; /** * Unbind event by handler function * @param {function} handler - handler function * @private */ CustomEvents.prototype._offByHandler = function(handler) { var self = this; var matchHandler = this._matchHandler(handler); forEach(this._safeEvent(), function(handlerItems) { self._spliceMatches(handlerItems, matchHandler); }); }; /** * Unbind event by object(name: handler pair object or context object) * @param {object} obj - context or {name: handler} pair object * @param {function} handler - handler function * @private */ CustomEvents.prototype._offByObject = function(obj, handler) { var self = this; var matchFunc; if (this._indexOfContext(obj) < 0) { forEach(obj, function(func, name) { self.off(name, func); }); } else if (isString(handler)) { matchFunc = this._matchContext(obj); self._spliceMatches(this._safeEvent(handler), matchFunc); } else if (isFunction(handler)) { matchFunc = this._matchHandlerAndContext(handler, obj); forEach(this._safeEvent(), function(handlerItems) { self._spliceMatches(handlerItems, matchFunc); }); } else { matchFunc = this._matchContext(obj); forEach(this._safeEvent(), function(handlerItems) { self._spliceMatches(handlerItems, matchFunc); }); } }; /** * Unbind custom events * @param {(string|object|function)} eventName - event name or context or * {name: handler} pair object or handler function * @param {(function)} handler - handler function * @example * //-- #1. Get Module --// * var CustomEvents = require('tui-code-snippet/customEvents/customEvents'); // node, commonjs * * //-- #2. Use method --// * // # 2.1 off by event name * CustomEvents.off('onload'); * * // # 2.2 off by event name and handler * CustomEvents.off('play', handler); * * // # 2.3 off by handler * CustomEvents.off(handler); * * // # 2.4 off by context * CustomEvents.off(myObj); * * // # 2.5 off by context and handler * CustomEvents.off(myObj, handler); * * // # 2.6 off by context and event name * CustomEvents.off(myObj, 'onload'); * * // # 2.7 off by an Object.<string, function> that is {eventName: handler} * CustomEvents.off({ * 'play': handler, * 'pause': handler2 * }); * * // # 2.8 off the all events * CustomEvents.off(); */ CustomEvents.prototype.off = function(eventName, handler) { if (isString(eventName)) { // [syntax 1, 2] this._offByEventName(eventName, handler); } else if (!arguments.length) { // [syntax 8] this.events = {}; this.contexts = []; } else if (isFunction(eventName)) { // [syntax 3] this._offByHandler(eventName); } else if (isObject(eventName)) { // [syntax 4, 5, 6] this._offByObject(eventName, handler); } }; /** * Fire custom event * @param {string} eventName - name of custom event */ CustomEvents.prototype.fire = function(eventName) { // eslint-disable-line this.invoke.apply(this, arguments); }; /** * Fire a event and returns the result of operation 'boolean AND' with all * listener's results. * * So, It is different from {@link CustomEvents#fire}. * * In service code, use this as a before event in component level usually * for notifying that the event is cancelable. * @param {string} eventName - Custom event name * @param {...*} data - Data for event * @returns {boolean} The result of operation 'boolean AND' * @example * var map = new Map(); * map.on({ * 'beforeZoom': function() { * // It should cancel the 'zoom' event by some conditions. * if (that.disabled && this.getState()) { * return false; * } * return true; * } * }); * * if (this.invoke('beforeZoom')) { // check the result of 'beforeZoom' * // if true, * // doSomething * } */ CustomEvents.prototype.invoke = function(eventName) { var events, args, index, item; if (!this.hasListener(eventName)) { return true; } events = this._safeEvent(eventName); args = Array.prototype.slice.call(arguments, 1); index = 0; while (events[index]) { item = events[index]; if (item.handler.apply(item.context, args) === false) { return false; } index += 1; } return true; }; /** * Return whether at least one of the handlers is registered in the given * event name. * @param {string} eventName - Custom event name * @returns {boolean} Is there at least one handler in event name? */ CustomEvents.prototype.hasListener = function(eventName) { return this.getListenerLength(eventName) > 0; }; /** * Return a count of events registered. * @param {string} eventName - Custom event name * @returns {number} number of event */ CustomEvents.prototype.getListenerLength = function(eventName) { var events = this._safeEvent(eventName); return events.length; }; module.exports = CustomEvents; /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * @fileoverview Execute the provided callback once for each property of object(or element of array) which actually exist. * @author NHN FE Development Lab <dl_javascript@nhn.com> */ var isArray = __webpack_require__(6); var forEachArray = __webpack_require__(2); var forEachOwnProperties = __webpack_require__(23); /** * @module collection */ /** * Execute the provided callback once for each property of object(or element of array) which actually exist. * If the object is Array-like object(ex-arguments object), It needs to transform to Array.(see 'ex2' of example). * If the callback function returns false, the loop will be stopped. * Callback function(iteratee) is invoked with three arguments: * 1) The value of the property(or The value of the element) * 2) The name of the property(or The index of the element) * 3) The object being traversed * @param {Object} obj The object that will be traversed * @param {function} iteratee Callback function * @param {Object} [context] Context(this) of callback function * @memberof module:collection * @example * var forEach = require('tui-code-snippet/collection/forEach'); // node, commonjs * * var sum = 0; * * forEach([1,2,3], function(value){ * sum += value; * }); * alert(sum); // 6 * * // In case of Array-like object * var array = Array.prototype.slice.call(arrayLike); // change to array * forEach(array, function(value){ * sum += value; * }); */ function forEach(obj, iteratee, context) { if (isArray(obj)) { forEachArray(obj, iteratee, context); } else { forEachOwnProperties(obj, iteratee, context); } } module.exports = forEach; /***/ }), /* 10 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * @fileoverview Default locale texts */ module.exports = { en: { titles: { DD: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], D: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'], MMM: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'], MMMM: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] }, titleFormat: 'MMMM yyyy', todayFormat: 'To\\d\\ay: DD, MMMM d, yyyy', time: 'Time', date: 'Date' }, ko: { titles: { DD: ['일요일', '월요일', '화요일', '수요일', '목요일', '금요일', '토요일'], D: ['일', '월', '화', '수', '목', '금', '토'], MMM: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'], MMMM: ['1월', '2월', '3월', '4월', '5월', '6월', '7월', '8월', '9월', '10월', '11월', '12월'] }, titleFormat: 'yyyy.MM', todayFormat: '오늘: yyyy.MM.dd (D)', date: '날짜', time: '시간' } }; /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * @fileoverview Convert text by binding expressions with context. * @author NHN FE Development Lab <dl_javascript@nhn.com> */ var inArray = __webpack_require__(3); var forEach = __webpack_require__(9); var isArray = __webpack_require__(6); var isString = __webpack_require__(13); var extend = __webpack_require__(7); // IE8 does not support capture groups. var EXPRESSION_REGEXP = /{{\s?|\s?}}/g; var BRACKET_NOTATION_REGEXP = /^[a-zA-Z0-9_@]+\[[a-zA-Z0-9_@"']+\]$/; var BRACKET_REGEXP = /\[\s?|\s?\]/; var DOT_NOTATION_REGEXP = /^[a-zA-Z_]+\.[a-zA-Z_]+$/; var DOT_REGEXP = /\./; var STRING_NOTATION_REGEXP = /^["']\w+["']$/; var STRING_REGEXP = /"|'/g; var NUMBER_REGEXP = /^-?\d+\.?\d*$/; var EXPRESSION_INTERVAL = 2; var BLOCK_HELPERS = { 'if': handleIf, 'each': handleEach, 'with': handleWith }; var isValidSplit = 'a'.split(/a/).length === 3; /** * Split by RegExp. (Polyfill for IE8) * @param {string} text - text to be splitted\ * @param {RegExp} regexp - regular expression * @returns {Array.<string>} */ var splitByRegExp = (function() { if (isValidSplit) { return function(text, regexp) { return text.split(regexp); }; } return function(text, regexp) { var result = []; var prevIndex = 0; var match, index; if (!regexp.global) { regexp = new RegExp(regexp, 'g'); } match = regexp.exec(text); while (match !== null) { index = match.index; result.push(text.slice(prevIndex, index)); prevIndex = index + match[0].length; match = regexp.exec(text); } result.push(text.slice(prevIndex)); return result; }; })(); /** * Find value in the context by an expression. * @param {string} exp - an expression * @param {object} context - context * @returns {*} * @private */ // eslint-disable-next-line complexity function getValueFromContext(exp, context) { var splitedExps; var value = context[exp]; if (exp === 'true') { value = true; } else if (exp === 'false') { value = false; } else if (STRING_NOTATION_REGEXP.test(exp)) { value = exp.replace(STRING_REGEXP, ''); } else if (BRACKET_NOTATION_REGEXP.test(exp)) { splitedExps = exp.split(BRACKET_REGEXP); value = getValueFromContext(splitedExps[0], context)[getValueFromContext(splitedExps[1], context)]; } else if (DOT_NOTATION_REGEXP.test(exp)) { splitedExps = exp.split(DOT_REGEXP); value = getValueFromContext(splitedExps[0], context)[splitedExps[1]]; } else if (NUMBER_REGEXP.test(exp)) { value = parseFloat(exp); } return value; } /** * Extract elseif and else expressions. * @param {Array.<string>} ifExps - args of if expression * @param {Array.<string>} sourcesInsideBlock - sources inside if block * @returns {object} - exps: expressions of if, elseif, and else / sourcesInsideIf: sources inside if, elseif, and else block. * @private */ function extractElseif(ifExps, sourcesInsideBlock) { var exps = [ifExps]; var sourcesInsideIf = []; var otherIfCount = 0; var start = 0; // eslint-disable-next-line complexity forEach(sourcesInsideBlock, function(source, index) { if (source.indexOf('if') === 0) { otherIfCount += 1; } else if (source === '/if') { otherIfCount -= 1; } else if (!otherIfCount && (source.indexOf('elseif') === 0 || source === 'else')) { exps.push(source === 'else' ? ['true'] : source.split(' ').slice(1)); sourcesInsideIf.push(sourcesInsideBlock.slice(start, index)); start = index + 1; } }); sourcesInsideIf.push(sourcesInsideBlock.slice(start)); return { exps: exps, sourcesInsideIf: sourcesInsideIf }; } /** * Helper function for "if". * @param {Array.<string>} exps - array of expressions split by spaces * @param {Array.<string>} sourcesInsideBlock - array of sources inside the if block * @param {object} context - context * @returns {string} * @private */ function handleIf(exps, sourcesInsideBlock, context) { var analyzed = extractElseif(exps, sourcesInsideBlock); var result = false; var compiledSource = ''; forEach(analyzed.exps, function(exp, index) { result = handleExpression(exp, context); if (result) { compiledSource = compile(analyzed.sourcesInsideIf[index], context); } return !result; }); return compiledSource; } /** * Helper function for "each". * @param {Array.<string>} exps - array of expressions split by spaces * @param {Array.<string>} sourcesInsideBlock - array of sources inside the each block * @param {object} context - context * @returns {string} * @private */ function handleEach(exps, sourcesInsideBlock, context) { var collection = handleExpression(exps, context); var additionalKey = isArray(collection) ? '@index' : '@key'; var additionalContext = {}; var result = ''; forEach(collection, function(item, key) { additionalContext[additionalKey] = key; additionalContext['@this'] = item; extend(context, additionalContext); result += compile(sourcesInsideBlock.slice(), context); }); return result; } /** * Helper function for "with ... as" * @param {Array.<string>} exps - array of expressions split by spaces * @param {Array.<string>} sourcesInsideBlock - array of sources inside the with block * @param {object} context - context * @returns {string} * @private */ function handleWith(exps, sourcesInsideBlock, context) { var asIndex = inArray('as', exps); var alias = exps[asIndex + 1]; var result = handleExpression(exps.slice(0, asIndex), context); var additionalContext = {}; additionalContext[alias] = result; return compile(sourcesInsideBlock, extend(context, additionalContext)) || ''; } /** * Extract sources inside block in place. * @param {Array.<string>} sources - array of sources * @param {number} start - index of start block * @param {number} end - index of end block * @returns {Array.<string>} * @private */ function extractSourcesInsideBlock(sources, start, end) { var sourcesInsideBlock = sources.splice(start + 1, end - start); sourcesInsideBlock.pop(); return sourcesInsideBlock; } /** * Handle block helper function * @param {string} helperKeyword - helper keyword (ex. if, each, with) * @param {Array.<string>} sourcesToEnd - array of sources after the starting block * @param {object} context - context * @returns {Array.<string>} * @private */ function handleBlockHelper(helperKeyword, sourcesToEnd, context) { var executeBlockHelper = BLOCK_HELPERS[helperKeyword]; var helperCount = 1; var startBlockIndex = 0; var endBlockIndex; var index = startBlockIndex + EXPRESSION_INTERVAL; var expression = sourcesToEnd[index]; while (helperCount && isString(expression)) { if (expression.indexOf(helperKeyword) === 0) { helperCount += 1; } else if (expression.indexOf('/' + helperKeyword) === 0) { helperCount -= 1; endBlockIndex = index; } index += EXPRESSION_INTERVAL; expression = sourcesToEnd[index]; } if (helperCount) { throw Error(helperKeyword + ' needs {{/' + helperKeyword + '}} expression.'); } sourcesToEnd[startBlockIndex] = executeBlockHelper( sourcesToEnd[startBlockIndex].split(' ').slice(1), extractSourcesInsideBlock(sourcesToEnd, startBlockIndex, endBlockIndex), context ); return sourcesToEnd; } /** * Helper function for "custom helper". * If helper is not a function, return helper itself. * @param {Array.<string>} exps - array of expressions split by spaces (first element: helper) * @param {object} context - context * @returns {string} * @private */ function handleExpression(exps, context) { var result = getValueFromContext(exps[0], context); if (result instanceof Function) { return executeFunction(result, exps.slice(1), context); } return result; } /** * Execute a helper function. * @param {Function} helper - helper function * @param {Array.<string>} argExps - expressions of arguments * @param {object} context - context * @returns {string} - result of executing the function with arguments * @private */ function executeFunction(helper, argExps, context) { var args = []; forEach(argExps, function(exp) { args.push(getValueFromContext(exp, context)); }); return helper.apply(null, args); } /** * Get a result of compiling an expression with the context. * @param {Array.<string>} sources - array of sources split by regexp of expression. * @param {object} context - context * @returns {Array.<string>} - array of sources that bind with its context * @private */ function compile(sources, context) { var index = 1; var expression = sources[index]; var exps, firstExp, result; while (isString(expression)) { exps = expression.split(' '); firstExp = exps[0]; if (BLOCK_HELPERS[firstExp]) { result = handleBlockHelper(firstExp, sources.splice(index, sources.length - index), context); sources = sources.concat(result); } else { sources[index] = handleExpression(exps, context); } index += EXPRESSION_INTERVAL; expression = sources[index]; } return sources.join(''); } /** * Convert text by binding expressions with context. * <br> * If expression exists in the context, it will be replaced. * ex) '{{title}}' with context {title: 'Hello!'} is converted to 'Hello!'. * An array or object can be accessed using bracket and dot notation. * ex) '{{odds\[2\]}}' with context {odds: \[1, 3, 5\]} is converted to '5'. * ex) '{{evens\[first\]}}' with context {evens: \[2, 4\], first: 0} is converted to '2'. * ex) '{{project\["name"\]}}' and '{{project.name}}' with context {project: {name: 'CodeSnippet'}} is converted to 'CodeSnippet'. * <br> * If replaced expression is a function, next expressions will be arguments of the function. * ex) '{{add 1 2}}' with context {add: function(a, b) {return a + b;}} is converted to '3'. * <br> * It has 3 predefined block helpers '{{helper ...}} ... {{/helper}}': 'if', 'each', 'with ... as ...'. * 1) 'if' evaluates conditional statements. It can use with 'elseif' and 'else'. * 2) 'each' iterates an array or object. It provides '@index'(array), '@key'(object), and '@this'(current element). * 3) 'with ... as ...' provides an alias. * @param {string} text - text with expressions * @param {object} context - context * @returns {string} - text that bind with its context * @memberof module:domUtil * @example * var template = require('tui-code-snippet/domUtil/template'); * * var source = * '<h1>' * + '{{if isValidNumber title}}' * + '{{title}}th' * + '{{elseif isValidDate title}}' * + 'Date: {{title}}' * + '{{/if}}' * + '</h1>' * + '{{each list}}' * + '{{with addOne @index as idx}}' * + '<p>{{idx}}: {{@this}}</p>' * + '{{/with}}' * + '{{/each}}'; * * var context = { * isValidDate: function(text) { * return /^\d{4}-(0|1)\d-(0|1|2|3)\d$/.test(text); * }, * isValidNumber: function(text) { * return /^\d+$/.test(text); * } * title: '2019-11-25', * list: ['Clean the room', 'Wash the dishes'], * addOne: function(num) { * return num + 1; * } * }; * * var result = template(source, context); * console.log(result); // <h1>Date: 2019-11-25</h1><p>1: Clean the room</p><p>2: Wash the dishes</p> */ function template(text, context) { return compile(splitByRegExp(text, EXPRESSION_REGEXP), context); } module.exports = template; /***/ }), /* 12 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * @fileoverview Check whether the given variable is undefined or not. * @author NHN FE Development Lab <dl_javascript@nhn.com> */ /** * Check whether the given variable is undefined or not. * If the given variable is undefined, returns true. * @param {*} obj - Target for checking * @returns {boolean} Is undefined? * @memberof module:type */ function isUndefined(obj) { return obj === undefined; // eslint-disable-line no-undefined } module.exports = isUndefined; /***/ }), /* 13 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * @fileoverview Check whether the given variable is a string or not. * @author NHN FE Development Lab <dl_javascript@nhn.com> */ /** * Check whether the given variable is a string or not. * If the given variable is a string, return true. * @param {*} obj - Target for checking * @returns {boolean} Is string? * @memberof module:type */ function isString(obj) { return typeof obj === 'string' || obj instanceof String; } module.exports = isString; /***/ }), /* 14 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /** * @fileoverview Remove element from parent node. * @author NHN FE Development Lab <dl_javascript@nhn.com> */ /** * Remove ele