Source: node_modules/@egjs/component/src/component.js

/**
 * Copyright (c) 2015 NAVER Corp.
 * egjs projects are licensed under the MIT license
 */

/**
 * A class used to manage events and options in a component
 * @ko 컴포넌트의 이벤트와 옵션을 관리할 수 있게 하는 클래스
 * @alias eg.Component
 */
class Component {
	/**
	 * @support {"ie": "7+", "ch" : "latest", "ff" : "latest",  "sf" : "latest", "edge" : "latest", "ios" : "7+", "an" : "2.1+ (except 3.x)"}
	 */
	constructor() {
		this._eventHandler = {};
		this.options = {};
	}
	/**
	 * Triggers a custom event.
	 * @ko 커스텀 이벤트를 발생시킨다
	 * @param {String} eventName The name of the custom event to be triggered <ko>발생할 커스텀 이벤트의 이름</ko>
	 * @param {Object} customEvent Event data to be sent when triggering a custom event <ko>커스텀 이벤트가 발생할 때 전달할 데이터</ko>
	 * @return {Boolean} Indicates whether the event has occurred. If the stop() method is called by a custom event handler, it will return false and prevent the event from occurring. <a href="https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F">Ref</a> <ko>이벤트 발생 여부. 커스텀 이벤트 핸들러에서 stop() 메서드를 호출하면 'false'를 반환하고 이벤트 발생을 중단한다. <a href="https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F">참고</a></ko>
	 * @example

class Some extends eg.Component {
  some(){
  	if(this.trigger("beforeHi")){ // When event call to stop return false.
		this.trigger("hi");// fire hi event.
  	}
  }
}

const some = new Some();
some.on("beforeHi", (e) => {
	if(condition){
		e.stop(); // When event call to stop, `hi` event not call.
	}
});
some.on("hi", (e) => {
	// `currentTarget` is component instance.
	console.log(some === e.currentTarget); // true
});
// If you want to more know event design. You can see article.
// https://github.com/naver/egjs-component/wiki/How-to-make-Component-event-design%3F
	 */
	trigger(eventName, customEvent = {}, ...restParam) {
		let handlerList = this._eventHandler[eventName] || [];
		const hasHandlerList = handlerList.length > 0;

		if (!hasHandlerList) {
			return true;
		}

		// If detach method call in handler in first time then handeler list calls.
		handlerList = handlerList.concat();

		customEvent.eventType = eventName;

		let isCanceled = false;
		let arg = [customEvent];
		let i = 0;

		customEvent.stop = () => { isCanceled = true; };
		customEvent.currentTarget = this;

		if (restParam.length >= 1) {
			arg = arg.concat(restParam);
		}

		for (i = 0; handlerList[i]; i++) {
			handlerList[i].apply(this, arg);
		}

		return !isCanceled;
	}
	/**
	 * Executed event just one time.
	 * @ko 이벤트가 한번만 실행된다.
	 * @param {eventName} eventName The name of the event to be attached <ko>등록할 이벤트의 이름</ko>
	 * @param {Function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
	 * @return {eg.Component} An instance of a component itself<ko>컴포넌트 자신의 인스턴스</ko>
	 * @example
class Some extends eg.Component {
  hi() {
    alert("hi");
  }
  thing() {
    this.once("hi", this.hi);
  }
}

var some = new Some();
some.thing();
some.trigger("hi");
// fire alert("hi");
some.trigger("hi");
// Nothing happens
	 */
	once(eventName, handlerToAttach) {
		if (typeof eventName === "object" &&
			typeof handlerToAttach === "undefined") {
			const eventHash = eventName;
			let i;

			for (i in eventHash) {
				this.once(i, eventHash[i]);
			}
			return this;
		} else if (typeof eventName === "string" &&
			typeof handlerToAttach === "function") {
			const self = this;

			this.on(eventName, function listener(...arg) {
				handlerToAttach.apply(self, arg);
				self.off(eventName, listener);
			});
		}

		return this;
	}

	/**
	 * Checks whether an event has been attached to a component.
	 * @ko 컴포넌트에 이벤트가 등록됐는지 확인한다.
	 * @param {String} eventName The name of the event to be attached <ko>등록 여부를 확인할 이벤트의 이름</ko>
	 * @return {Boolean} Indicates whether the event is attached. <ko>이벤트 등록 여부</ko>
	 * @example
class Some extends eg.Component {
  some() {
    this.hasOn("hi");// check hi event.
  }
}
	 */
	hasOn(eventName) {
		return !!this._eventHandler[eventName];
	}

	/**
	 * Attaches an event to a component.
	 * @ko 컴포넌트에 이벤트를 등록한다.
	 * @param {eventName} eventName The name of the event to be attached <ko>등록할 이벤트의 이름</ko>
	 * @param {Function} handlerToAttach The handler function of the event to be attached <ko>등록할 이벤트의 핸들러 함수</ko>
	 * @return {eg.Component} An instance of a component itself<ko>컴포넌트 자신의 인스턴스</ko>
	 * @example
class Some extends eg.Component {
  hi() {
    console.log("hi");
  }
  some() {
    this.on("hi",this.hi); //attach event
  }
}
*/
	on(eventName, handlerToAttach) {
		if (typeof eventName === "object" &&
			typeof handlerToAttach === "undefined") {
			const eventHash = eventName;
			let name;

			for (name in eventHash) {
				this.on(name, eventHash[name]);
			}
			return this;
		} else if (typeof eventName === "string" &&
			typeof handlerToAttach === "function") {
			let handlerList = this._eventHandler[eventName];

			if (typeof handlerList === "undefined") {
				this._eventHandler[eventName] = [];
				handlerList = this._eventHandler[eventName];
			}

			handlerList.push(handlerToAttach);
		}

		return this;
	}
	/**
	 * Detaches an event from the component.
	 * @ko 컴포넌트에 등록된 이벤트를 해제한다
	 * @param {eventName} eventName The name of the event to be detached <ko>해제할 이벤트의 이름</ko>
	 * @param {Function} handlerToDetach The handler function of the event to be detached <ko>해제할 이벤트의 핸들러 함수</ko>
	 * @return {eg.Component} An instance of a component itself <ko>컴포넌트 자신의 인스턴스</ko>
	 * @example
class Some extends eg.Component {
  hi() {
    console.log("hi");
  }
  some() {
    this.off("hi",this.hi); //detach event
  }
}
	 */
	off(eventName, handlerToDetach) {
		// All event detach.
		if (typeof eventName === "undefined") {
			this._eventHandler = {};
			return this;
		}

		// All handler of specific event detach.
		if (typeof handlerToDetach === "undefined") {
			if (typeof eventName === "string") {
				this._eventHandler[eventName] = undefined;
				return this;
			} else {
				const eventHash = eventName;
				let name;

				for (name in eventHash) {
					this.off(name, eventHash[name]);
				}
				return this;
			}
		}

		// The handler of specific event detach.
		let handlerList = this._eventHandler[eventName];

		if (handlerList) {
			let k;
			let handlerFunction;

			for (k = 0; (handlerFunction = handlerList[k]) !== undefined; k++) {
				if (handlerFunction === handlerToDetach) {
					handlerList = handlerList.splice(k, 1);
					break;
				}
			}
		}

		return this;
	}
}

export default Component;
comments powered by Disqus