diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/package.json b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/package.json index 4b1f769870..daff7cbf06 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/package.json +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/package.json @@ -8,6 +8,7 @@ "@abp/tui-editor": "^4.2.2", "@abp/slugify": "^4.2.2", "@abp/uppy": "^4.2.2", + "tui-code-snippet": "1.5.2", // "@abp/aspnetcore.mvc.ui.theme.basic": "^4.2.2" } diff --git a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/wwwroot/libs/tui-code-snippet/tui-code-snippet.js b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/wwwroot/libs/tui-code-snippet/tui-code-snippet.js index 8738e563ef..29e654fdc8 100644 --- a/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/wwwroot/libs/tui-code-snippet/tui-code-snippet.js +++ b/templates/app/aspnet-core/src/MyCompanyName.MyProjectName.Web/wwwroot/libs/tui-code-snippet/tui-code-snippet.js @@ -1,6 +1,6 @@ /*! - * TOAST UI Code Snippet - * @version 2.3.2 + * tui-code-snippet.js + * @version 1.5.2 * @author NHN. FE Development Lab * @license MIT */ @@ -13,5189 +13,4346 @@ exports["util"] = factory(); else root["tui"] = root["tui"] || {}, root["tui"]["util"] = factory(); -})(window, function() { +})(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]) { +/******/ 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: {} +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false /******/ }; -/******/ + /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ + /******/ // Flag the module as loaded -/******/ module.l = true; -/******/ +/******/ module.loaded = 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 = 36); +/******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (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 - */ - - - -/** - * 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; + 'use strict'; + + /** + * @fileoverview + * @author NHN. + * FE Development Lab + * @namespace tui.util + * @example + * // node, commonjs + * var util = require('tui-code-snippet'); + * @example + * // distribution file, script + * + * "; + * var result = util.encodeHTMLEntity(htmlEntityString); + * //"<script> alert('test');</script><a href='test'>" + */ + function encodeHTMLEntity(html) { + var entities = { + '"': 'quot', + '&': 'amp', + '<': 'lt', + '>': 'gt', + '\'': '#39' + }; + + return html.replace(/[<>&"']/g, function(m0) { + return entities[m0] ? '&' + entities[m0] + ';' : m0; + }); + } + + /** + * Return whether the string capable to transform into plain string is in the given string or not. + * @param {String} string - test string + * @memberof tui.util + * @returns {boolean} + */ + function hasEncodableString(string) { + return (/[<>&"']/).test(string); + } + + /** + * Return duplicate charters + * @param {string} operandStr1 The operand string + * @param {string} operandStr2 The operand string + * @private + * @memberof tui.util + * @returns {string} + * @example + * //-- #1. Get Module --// + * var util = require('tui-code-snippet'); // node, commonjs + * var util = tui.util; // distribution file + * + * //-- #2. Use property --// + * util.getDuplicatedChar('fe dev', 'nhn entertainment'); // 'e' + * util.getDuplicatedChar('fdsa', 'asdf'); // 'asdf' + */ + function getDuplicatedChar(operandStr1, operandStr2) { + var i = 0; + var len = operandStr1.length; + var pool = {}; + var dupl, key; + + for (; i < len; i += 1) { + key = operandStr1.charAt(i); + pool[key] = 1; + } + + for (i = 0, len = operandStr2.length; i < len; i += 1) { + key = operandStr2.charAt(i); + if (pool[key]) { + pool[key] += 1; + } + } + + pool = collection.filter(pool, function(item) { + return item > 1; + }); + + pool = object.keys(pool).sort(); + dupl = pool.join(''); + + return dupl; + } + + module.exports = { + decodeHTMLEntity: decodeHTMLEntity, + encodeHTMLEntity: encodeHTMLEntity, + hasEncodableString: hasEncodableString, + getDuplicatedChar: getDuplicatedChar + }; /***/ }), /* 8 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * @fileoverview Check whether the given variable is a string or not. - * @author NHN FE Development Lab - */ - - - -/** - * 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; +/***/ (function(module, exports) { + + /** + * @fileoverview collections of some technic methods. + * @author NHN. + * FE Development Lab + */ + + 'use strict'; + + var tricks = {}; + var aps = Array.prototype.slice; + + /** + * Creates a debounced function that delays invoking fn until after delay milliseconds has elapsed + * since the last time the debouced function was invoked. + * @param {function} fn The function to debounce. + * @param {number} [delay=0] The number of milliseconds to delay + * @memberof tui.util + * @returns {function} debounced function. + * @example + * //-- #1. Get Module --// + * var util = require('tui-code-snippet'); // node, commonjs + * var util = tui.util; // distribution file + * + * //-- #2. Use property --// + * function someMethodToInvokeDebounced() {} + * + * var debounced = util.debounce(someMethodToInvokeDebounced, 300); + * + * // invoke repeatedly + * debounced(); + * debounced(); + * debounced(); + * debounced(); + * debounced(); + * debounced(); // last invoke of debounced() + * + * // invoke someMethodToInvokeDebounced() after 300 milliseconds. + */ + function debounce(fn, delay) { + var timer, args; + + /* istanbul ignore next */ + delay = delay || 0; + + function debounced() { // eslint-disable-line require-jsdoc + args = aps.call(arguments); + + window.clearTimeout(timer); + timer = window.setTimeout(function() { + fn.apply(null, args); + }, delay); + } + + return debounced; + } + + /** + * return timestamp + * @memberof tui.util + * @returns {number} The number of milliseconds from Jan. 1970 00:00:00 (GMT) + */ + function timestamp() { + return Number(new Date()); + } + + /** + * Creates a throttled function that only invokes fn at most once per every interval milliseconds. + * + * You can use this throttle short time repeatedly invoking functions. (e.g MouseMove, Resize ...) + * + * if you need reuse throttled method. you must remove slugs (e.g. flag variable) related with throttling. + * @param {function} fn function to throttle + * @param {number} [interval=0] the number of milliseconds to throttle invocations to. + * @memberof tui.util + * @returns {function} throttled function + * @example + * //-- #1. Get Module --// + * var util = require('tui-code-snippet'); // node, commonjs + * var util = tui.util; // distribution file + * + * //-- #2. Use property --// + * function someMethodToInvokeThrottled() {} + * + * var throttled = util.throttle(someMethodToInvokeThrottled, 300); + * + * // invoke repeatedly + * throttled(); // invoke (leading) + * throttled(); + * throttled(); // invoke (near 300 milliseconds) + * throttled(); + * throttled(); + * throttled(); // invoke (near 600 milliseconds) + * // ... + * // invoke (trailing) + * + * // if you need reuse throttled method. then invoke reset() + * throttled.reset(); + */ + function throttle(fn, interval) { + var base; + var isLeading = true; + var tick = function(_args) { + fn.apply(null, _args); + base = null; + }; + var debounced, stamp, args; + + /* istanbul ignore next */ + interval = interval || 0; + + debounced = tricks.debounce(tick, interval); + + function throttled() { // eslint-disable-line require-jsdoc + args = aps.call(arguments); + + if (isLeading) { + tick(args); + isLeading = false; + + return; + } + + stamp = tricks.timestamp(); + + base = base || stamp; + + // pass array directly because `debounce()`, `tick()` are already use + // `apply()` method to invoke developer's `fn` handler. + // + // also, this `debounced` line invoked every time for implements + // `trailing` features. + debounced(args); + + if ((stamp - base) >= interval) { + tick(args); + } + } + + function reset() { // eslint-disable-line require-jsdoc + isLeading = true; + base = null; + } + + throttled.reset = reset; + + return throttled; + } + + tricks.timestamp = timestamp; + tricks.debounce = debounce; + tricks.throttle = throttle; + + module.exports = tricks; /***/ }), /* 9 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; -/** - * @fileoverview Check whether the given variable is existing or not. - * @author NHN FE Development Lab - */ - - - -var isUndefined = __webpack_require__(2); -var isNull = __webpack_require__(11); - -/** - * Check whether the given variable is existing or not. - * If the given variable is not null and not undefined, returns true. - * @param {*} param - Target for checking - * @returns {boolean} Is existy? - * @memberof module:type - * @example - * var isExisty = require('tui-code-snippet/type/isExisty'); // node, commonjs - * - * isExisty(''); //true - * isExisty(0); //true - * isExisty([]); //true - * isExisty({}); //true - * isExisty(null); //false - * isExisty(undefined); //false -*/ -function isExisty(param) { - return !isUndefined(param) && !isNull(param); -} - -module.exports = isExisty; + /** + * @fileoverview This module has some functions for handling object as collection. + * @author NHN. + * FE Development Lab + */ + 'use strict'; + + var object = __webpack_require__(1); + var collection = __webpack_require__(4); + var type = __webpack_require__(2); + var ms7days = 7 * 24 * 60 * 60 * 1000; + + /** + * Check if the date has passed 7 days + * @param {number} date - milliseconds + * @returns {boolean} + * @ignore + */ + function isExpired(date) { + var now = new Date().getTime(); + + return now - date > ms7days; + } + + /** + * Send hostname on DOMContentLoaded. + * To prevent hostname set tui.usageStatistics to false. + * @param {string} appName - application name + * @param {string} trackingId - GA tracking ID + * @ignore + */ + function sendHostname(appName, trackingId) { + var url = 'https://www.google-analytics.com/collect'; + var hostname = location.hostname; + var hitType = 'event'; + var eventCategory = 'use'; + var applicationKeyForStorage = 'TOAST UI ' + appName + ' for ' + hostname + ': Statistics'; + var date = window.localStorage.getItem(applicationKeyForStorage); + + // skip if the flag is defined and is set to false explicitly + if (!type.isUndefined(window.tui) && window.tui.usageStatistics === false) { + return; + } + + // skip if not pass seven days old + if (date && !isExpired(date)) { + return; + } + + window.localStorage.setItem(applicationKeyForStorage, new Date().getTime()); + + setTimeout(function() { + if (document.readyState === 'interactive' || document.readyState === 'complete') { + imagePing(url, { + v: 1, + t: hitType, + tid: trackingId, + cid: hostname, + dp: hostname, + dh: appName, + el: appName, + ec: eventCategory + }); + } + }, 1000); + } + + /** + * Request image ping. + * @param {String} url url for ping request + * @param {Object} trackingInfo infos for make query string + * @returns {HTMLElement} + * @memberof tui.util + * @example + * //-- #1. Get Module --// + * var util = require('tui-code-snippet'); // node, commonjs + * var util = tui.util; // distribution file + * + * //-- #2. Use property --// + * util.imagePing('https://www.google-analytics.com/collect', { + * v: 1, + * t: 'event', + * tid: 'trackingid', + * cid: 'cid', + * dp: 'dp', + * dh: 'dh' + * }); + */ + function imagePing(url, trackingInfo) { + var queryString = collection.map(object.keys(trackingInfo), function(key, index) { + var startWith = index === 0 ? '' : '&'; + + return startWith + key + '=' + trackingInfo[key]; + }).join(''); + var trackingElement = document.createElement('img'); + + trackingElement.src = url + '?' + queryString; + + trackingElement.style.display = 'none'; + document.body.appendChild(trackingElement); + document.body.removeChild(trackingElement); + + return trackingElement; + } + + module.exports = { + imagePing: imagePing, + sendHostname: sendHostname + }; /***/ }), /* 10 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * @fileoverview Get HTML element's design classes. - * @author NHN FE Development Lab - */ - - - -var isUndefined = __webpack_require__(2); - -/** - * Get HTML element's design classes. - * @param {(HTMLElement|SVGElement)} element target element - * @returns {string} element css class name - * @memberof module:domUtil - */ -function getClass(element) { - if (!element || !element.className) { - return ''; - } - - if (isUndefined(element.className.baseVal)) { - return element.className; - } - - return element.className.baseVal; -} - -module.exports = getClass; +/***/ (function(module, exports) { + + /** + * @fileoverview This module detects the kind of well-known browser and version. + * @author NHN. + * FE Development Lab + */ + + 'use strict'; + + /** + * This object has an information that indicate the kind of browser.
+ * The list below is a detectable browser list. + * - ie8 ~ ie11 + * - chrome + * - firefox + * - safari + * - edge + * @memberof tui.util + * @example + * //-- #1. Get Module --// + * var util = require('tui-code-snippet'); // node, commonjs + * var util = tui.util; // distribution file + * + * //-- #2. Use property --// + * util.browser.chrome === true; // chrome + * util.browser.firefox === true; // firefox + * util.browser.safari === true; // safari + * util.browser.msie === true; // IE + * util.browser.edge === true; // edge + * util.browser.others === true; // other browser + * util.browser.version; // browser version + */ + var browser = { + chrome: false, + firefox: false, + safari: false, + msie: false, + edge: false, + others: false, + version: 0 + }; + + if (window && window.navigator) { + detectBrowser(); + } + + /** + * Detect the browser. + * @private + */ + function detectBrowser() { + var nav = window.navigator; + var appName = nav.appName.replace(/\s/g, '_'); + var userAgent = nav.userAgent; + + var rIE = /MSIE\s([0-9]+[.0-9]*)/; + var rIE11 = /Trident.*rv:11\./; + var rEdge = /Edge\/(\d+)\./; + var versionRegex = { + firefox: /Firefox\/(\d+)\./, + chrome: /Chrome\/(\d+)\./, + safari: /Version\/([\d.]+).*Safari\/(\d+)/ + }; + + var key, tmp; + + var detector = { + Microsoft_Internet_Explorer: function() { // eslint-disable-line camelcase + var detectedVersion = userAgent.match(rIE); + + if (detectedVersion) { // ie8 ~ ie10 + browser.msie = true; + browser.version = parseFloat(detectedVersion[1]); + } else { // no version information + browser.others = true; + } + }, + Netscape: function() { // eslint-disable-line complexity + var detected = false; + + if (rIE11.exec(userAgent)) { + browser.msie = true; + browser.version = 11; + detected = true; + } else if (rEdge.exec(userAgent)) { + browser.edge = true; + browser.version = userAgent.match(rEdge)[1]; + detected = true; + } else { + for (key in versionRegex) { + if (versionRegex.hasOwnProperty(key)) { + tmp = userAgent.match(versionRegex[key]); + if (tmp && tmp.length > 1) { // eslint-disable-line max-depth + browser[key] = detected = true; + browser.version = parseFloat(tmp[1] || 0); + break; + } + } + } + } + if (!detected) { + browser.others = true; + } + } + }; + + var fn = detector[appName]; + + if (fn) { + detector[appName](); + } + } + + module.exports = browser; /***/ }), /* 11 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; -/** - * @fileoverview Check whether the given variable is null or not. - * @author NHN FE Development Lab - */ - - - -/** - * Check whether the given variable is null or not. - * If the given variable(arguments[0]) is null, returns true. - * @param {*} obj - Target for checking - * @returns {boolean} Is null? - * @memberof module:type - */ -function isNull(obj) { - return obj === null; -} - -module.exports = isNull; + /** + * @fileoverview This module has some methods for handling popup-window + * @author NHN. + * FE Development Lab + */ + + 'use strict'; + + var collection = __webpack_require__(4); + var type = __webpack_require__(2); + var func = __webpack_require__(5); + var browser = __webpack_require__(10); + var object = __webpack_require__(1); + + var popupId = 0; + + /** + * Popup management class + * @constructor + * @memberof tui.util + * @example + * // node, commonjs + * var popup = require('tui-code-snippet').popup; + * @example + * // distribution file, script + * + * + * + */ + 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 + * //-- #1. Get Module --// + * var CustomEvents = require('tui-code-snippet').CustomEvents; // node, commonjs + * var CustomEvents = tui.util.CustomEvents; // distribution file + * + * //-- #2. Use property --// + * 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) { + object.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 (!type.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 (!type.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; // node, commonjs + * var CustomEvents = tui.util.CustomEvents; // distribution file + * + * //-- #2. Use property --// + * // # 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 (type.isString(eventName)) { + // [syntax 1, 2] + eventName = eventName.split(R_EVENTNAME_SPLIT); + collection.forEach(eventName, function(name) { + self._bindEvent(name, handler, context); + }); + } else if (type.isObject(eventName)) { + // [syntax 3, 4] + context = handler; + collection.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 (type.isObject(eventName)) { + context = handler; + collection.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 (!type.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 forEach = collection.forEachArray; + var andByHandler = type.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); + + collection.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) { + collection.forEach(obj, function(func, name) { + self.off(name, func); + }); + } else if (type.isString(handler)) { + matchFunc = this._matchContext(obj); + + self._spliceMatches(this._safeEvent(handler), matchFunc); + } else if (type.isFunction(handler)) { + matchFunc = this._matchHandlerAndContext(handler, obj); + + collection.forEach(this._safeEvent(), function(handlerItems) { + self._spliceMatches(handlerItems, matchFunc); + }); + } else { + matchFunc = this._matchContext(obj); + + collection.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; // node, commonjs + * var CustomEvents = tui.util.CustomEvents; // distribution file + * + * //-- #2. Use property --// + * // # 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. 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 (type.isString(eventName)) { + // [syntax 1, 2] + this._offByEventName(eventName, handler); + } else if (!arguments.length) { + // [syntax 8] + this.events = {}; + this.contexts = []; + } else if (type.isFunction(eventName)) { + // [syntax 3] + this._offByHandler(eventName); + } else if (type.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; /***/ }), /* 17 */ /***/ (function(module, exports, __webpack_require__) { -"use strict"; -/** - * @fileoverview Prevent default action - * @author NHN FE Development Lab - */ - - - -/** - * Prevent default action - * @param {Event} e - event object - * @memberof module:domEvent - */ -function preventDefault(e) { - if (e.preventDefault) { - e.preventDefault(); - - return; - } - - e.returnValue = false; -} - -module.exports = preventDefault; + /** + * @fileoverview This module provides a Enum Constructor. + * @author NHN. + * FE Development Lab + * @example + * // node, commonjs + * var Enum = require('tui-code-snippet').Enum; + * @example + * // distribution file, script + * + * + * + *
"; - * var result = encodeHTMLEntity(htmlEntityString); - */ -function encodeHTMLEntity(html) { - var entities = { - '"': 'quot', - '&': 'amp', - '<': 'lt', - '>': 'gt', - '\'': '#39' - }; - - return html.replace(/[<>&"']/g, function(m0) { - return entities[m0] ? '&' + entities[m0] + ';' : m0; - }); -} - -module.exports = encodeHTMLEntity; - - -/***/ }), -/* 63 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * @fileoverview Creates a throttled function that only invokes fn at most once per every interval milliseconds. - * @author NHN FE Development Lab - */ - - - -var debounce = __webpack_require__(34); - -/** - * Creates a throttled function that only invokes fn at most once per every interval milliseconds. - * You can use this throttle short time repeatedly invoking functions. (e.g MouseMove, Resize ...) - * if you need reuse throttled method. you must remove slugs (e.g. flag variable) related with throttling. - * @param {function} fn function to throttle - * @param {number} [interval=0] the number of milliseconds to throttle invocations to. - * @returns {function} throttled function - * @memberof module:tricks - * @example - * var throttle = require('tui-code-snippet/tricks/throttle'); // node, commonjs - * - * function someMethodToInvokeThrottled() {} - * - * var throttled = throttle(someMethodToInvokeThrottled, 300); - * - * // invoke repeatedly - * throttled(); // invoke (leading) - * throttled(); - * throttled(); // invoke (near 300 milliseconds) - * throttled(); - * throttled(); - * throttled(); // invoke (near 600 milliseconds) - * // ... - * // invoke (trailing) - * - * // if you need reuse throttled method. then invoke reset() - * throttled.reset(); - */ -function throttle(fn, interval) { - var base; - var isLeading = true; - var tick = function(_args) { - fn.apply(null, _args); - base = null; - }; - var debounced, stamp, args; - - /* istanbul ignore next */ - interval = interval || 0; - - debounced = debounce(tick, interval); - - function throttled() { // eslint-disable-line require-jsdoc - args = Array.prototype.slice.call(arguments); - - if (isLeading) { - tick(args); - isLeading = false; - - return; - } - - stamp = Number(new Date()); - - base = base || stamp; - - // pass array directly because `debounce()`, `tick()` are already use - // `apply()` method to invoke developer's `fn` handler. - // - // also, this `debounced` line invoked every time for implements - // `trailing` features. - debounced(args); - - if ((stamp - base) >= interval) { - tick(args); - } - } - - function reset() { // eslint-disable-line require-jsdoc - isLeading = true; - base = null; - } - - throttled.reset = reset; - - return throttled; -} - -module.exports = throttle; - - -/***/ }), -/* 64 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * @fileoverview Check whether the given variable is an instance of Array or not. (for multiple frame environments) - * @author NHN FE Development Lab - */ - - - -/** - * Check whether the given variable is an instance of Array or not. - * If the given variable is an instance of Array, return true. - * (It is used for multiple frame environments) - * @param {*} obj - Target for checking - * @returns {boolean} Is an instance of array? - * @memberof module:type - */ -function isArraySafe(obj) { - return Object.prototype.toString.call(obj) === '[object Array]'; -} - -module.exports = isArraySafe; - - -/***/ }), -/* 65 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * @fileoverview Check whether the given variable is a string or not. - * @author NHN FE Development Lab - */ - - - -/** - * Check whether the given variable is a boolean or not. - * If the given variable is a boolean, return true. - * @param {*} obj - Target for checking - * @returns {boolean} Is boolean? - * @memberof module:type - */ -function isBoolean(obj) { - return typeof obj === 'boolean' || obj instanceof Boolean; -} - -module.exports = isBoolean; - - -/***/ }), -/* 66 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * @fileoverview Check whether the given variable is a boolean or not. (for multiple frame environments) - * @author NHN FE Development Lab - */ - - - -/** - * Check whether the given variable is a boolean or not. - * If the given variable is a boolean, return true. - * (It is used for multiple frame environments) - * @param {*} obj - Target for checking - * @returns {boolean} Is a boolean? - * @memberof module:type - */ -function isBooleanSafe(obj) { - return Object.prototype.toString.call(obj) === '[object Boolean]'; -} - -module.exports = isBooleanSafe; - - -/***/ }), -/* 67 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * @fileoverview Check whether the given variable is an instance of Date or not. (for multiple frame environments) - * @author NHN FE Development Lab - */ - - - -/** - * Check whether the given variable is an instance of Date or not. - * If the given variables is an instance of Date, return true. - * (It is used for multiple frame environments) - * @param {*} obj - Target for checking - * @returns {boolean} Is an instance of Date? - * @memberof module:type - */ -function isDateSafe(obj) { - return Object.prototype.toString.call(obj) === '[object Date]'; -} - -module.exports = isDateSafe; - - -/***/ }), -/* 68 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * @fileoverview Check whether the given variable is falsy or not. - * @author NHN FE Development Lab - */ - - - -var isTruthy = __webpack_require__(35); - -/** - * Check whether the given variable is falsy or not. - * If the given variable is null or undefined or false, returns true. - * @param {*} obj - Target for checking - * @returns {boolean} Is falsy? - * @memberof module:type - */ -function isFalsy(obj) { - return !isTruthy(obj); -} - -module.exports = isFalsy; - - -/***/ }), -/* 69 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * @fileoverview Check whether the given variable is a function or not. (for multiple frame environments) - * @author NHN FE Development Lab - */ - - - -/** - * Check whether the given variable is a function or not. - * If the given variable is a function, return true. - * (It is used for multiple frame environments) - * @param {*} obj - Target for checking - * @returns {boolean} Is a function? - * @memberof module:type - */ -function isFunctionSafe(obj) { - return Object.prototype.toString.call(obj) === '[object Function]'; -} - -module.exports = isFunctionSafe; - - -/***/ }), -/* 70 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * @fileoverview Check whether the given variable is a instance of HTMLNode or not. - * @author NHN FE Development Lab - */ - - - -/** - * Check whether the given variable is a instance of HTMLNode or not. - * If the given variables is a instance of HTMLNode, return true. - * @param {*} html - Target for checking - * @returns {boolean} Is HTMLNode ? - * @memberof module:type - */ -function isHTMLNode(html) { - if (typeof HTMLElement === 'object') { - return (html && (html instanceof HTMLElement || !!html.nodeType)); - } - - return !!(html && html.nodeType); -} - -module.exports = isHTMLNode; - - -/***/ }), -/* 71 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * @fileoverview Check whether the given variable is a HTML tag or not. - * @author NHN FE Development Lab - */ - - - -/** - * Check whether the given variable is a HTML tag or not. - * If the given variables is a HTML tag, return true. - * @param {*} html - Target for checking - * @returns {boolean} Is HTML tag? - * @memberof module:type - */ -function isHTMLTag(html) { - if (typeof HTMLElement === 'object') { - return (html && (html instanceof HTMLElement)); - } - - return !!(html && html.nodeType && html.nodeType === 1); -} - -module.exports = isHTMLTag; - - -/***/ }), -/* 72 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * @fileoverview Check whether the given variable is not empty(not null, not undefined, or not empty array, not empty object) or not. - * @author NHN FE Development Lab - */ - - - -var isEmpty = __webpack_require__(13); - -/** - * Check whether the given variable is not empty - * (not null, not undefined, or not empty array, not empty object) or not. - * If the given variables is not empty, return true. - * @param {*} obj - Target for checking - * @returns {boolean} Is not empty? - * @memberof module:type - */ -function isNotEmpty(obj) { - return !isEmpty(obj); -} - -module.exports = isNotEmpty; - - -/***/ }), -/* 73 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * @fileoverview Check whether the given variable is a number or not. (for multiple frame environments) - * @author NHN FE Development Lab - */ - - - -/** - * Check whether the given variable is a number or not. - * If the given variable is a number, return true. - * (It is used for multiple frame environments) - * @param {*} obj - Target for checking - * @returns {boolean} Is a number? - * @memberof module:type - */ -function isNumberSafe(obj) { - return Object.prototype.toString.call(obj) === '[object Number]'; -} - -module.exports = isNumberSafe; - - -/***/ }), -/* 74 */ -/***/ (function(module, exports, __webpack_require__) { - -"use strict"; -/** - * @fileoverview Check whether the given variable is a string or not. (for multiple frame environments) - * @author NHN FE Development Lab - */ - - - -/** - * Check whether the given variable is a string or not. - * If the given variable is a string, return true. - * (It is used for multiple frame environments) - * @param {*} obj - Target for checking - * @returns {boolean} Is a string? - * @memberof module:type - */ -function isStringSafe(obj) { - return Object.prototype.toString.call(obj) === '[object String]'; -} - -module.exports = isStringSafe; + /** + * @fileoverview This module provides the HashMap constructor. + * @author NHN. + * FE Development Lab + */ + + 'use strict'; + + var collection = __webpack_require__(4); + var type = __webpack_require__(2); + /** + * All the data in hashMap begin with _MAPDATAPREFIX; + * @type {string} + * @private + */ + var _MAPDATAPREFIX = 'å'; + + /** + * HashMap can handle the key-value pairs.
+ * Caution:
+ * HashMap instance has a length property but is not an instance of Array. + * @param {Object} [obj] A initial data for creation. + * @constructor + * @memberof tui.util + * @deprecated since version 1.3.0 + * @example + * // node, commonjs + * var HashMap = require('tui-code-snippet').HashMap; + * var hm = new tui.util.HashMap({ + 'mydata': { + 'hello': 'imfine' + }, + 'what': 'time' + }); + * @example + * // distribution file, script + * + *