UNPKG

@dooboostore/dom-render

Version:
477 lines 24.1 kB
var _a; import { ScriptUtils } from '@dooboostore/core-web/script/ScriptUtils'; import { DomUtils } from '@dooboostore/core-web/dom/DomUtils'; import { Range } from '../iterators/Range'; import { DomRenderFinalProxy } from '../types/Types'; export class EventManager { constructor() { this.eventNames = [ 'click', 'mousedown', 'mouseup', 'dblclick', 'mouseover', 'mouseout', 'mousemove', 'mouseenter', 'mouseleave', 'contextmenu', 'keyup', 'keydown', 'keypress', 'toggle', 'change', 'input', 'submit', 'resize', 'focus', 'blur', 'close', 'cancel' // dialog cancel 이벤트는 close 이벤트의 하위 이벤트로, ESC 키나 취소 버튼으로 닫힐 때만 발생. (close// 추가 로직 (예: 닫힘 후 처리)) /* close 이벤트: <dialog>가 닫힐 때 발생. 사용자가 취소 버튼, 확인 버튼, 또는 dialog.close() 메서드로 닫을 때 모두 트리거됩니다. cancel 이벤트: <dialog>가 ESC 키나 취소 버튼으로 닫힐 때 발생. close 이벤트의 하위 이벤트로 볼 수 있습니다. */ ]; this.bindScript = ` const ${_a.VALUE_VARNAME} = this.__render.value; const ${_a.SCRIPTS_VARNAME} = this.__render.scripts; const ${_a.RANGE_VARNAME} = this.__render.range; const ${_a.ROUTER_VARNAME} = this.__render.router; const ${_a.ATTRIBUTE_VARNAME} = this.__render.attribute; const ${_a.ELEMENT_VARNAME} = this.__render.element; const ${_a.COMPONENT_VARNAME} = this.__render.element.component; const ${_a.TARGET_VARNAME} = this.__render.target; const ${_a.EVENT_VARNAME} = this.__render.event; `; this.eventNames.forEach(it => { _a.attrNames.push(_a.attrPrefix + 'event-' + it); }); _a.attrNames.push(_a.onRenderedInitAttrName); if (typeof window !== 'undefined') { _a.WINDOW_EVENTS.forEach(eventName => { window === null || window === void 0 ? void 0 : window.addEventListener(eventName, (event) => { const targetAttr = `dr-window-event-${eventName}`; document.querySelectorAll(`[${targetAttr}]`).forEach(it => { var _b; const script = it.getAttribute(targetAttr); if (script) { const obj = it.obj; const config = (_b = obj === null || obj === void 0 ? void 0 : obj._DomRender_proxy) === null || _b === void 0 ? void 0 : _b.config; ScriptUtils.eval(`${this.bindScript} ${script} `, Object.assign(obj, { __render: Object.freeze({ target: DomRenderFinalProxy.final(event.target), element: it, event: event, range: Range.range, scripts: _a.setBindProperty(config === null || config === void 0 ? void 0 : config.scripts, obj) // ...EventManager.eventVariables }) })); } }); }); }); } } // // 순환참조때문에 우선 여기에 뺴놓는다. // public DomrenderProxyFinal(obj: any) { // (obj as any)._DomRender_isFinal = true; // return obj; // } // 중요 이벤트에 대상이될 Elements를 찾는다. findAttrElements(fragment, config) { var _b, _c; // const datas: {name: string, value: string | null, element: Element}[] = []; const elements = new Set(); const addAttributes = (_c = (_b = config === null || config === void 0 ? void 0 : config.applyEvents) === null || _b === void 0 ? void 0 : _b.map(it => it.attrName)) !== null && _c !== void 0 ? _c : []; addAttributes.concat([..._a.attrNames]).forEach(attrName => { fragment === null || fragment === void 0 ? void 0 : fragment.querySelectorAll(`[${attrName}]`).forEach(it => { elements.add(it); }); }); return elements; } // 중요 처음 이벤트 처리 // eslint-disable-next-line no-undef applyEvent(obj, childNodes, config) { // console.log('eventManager applyEvent==>', obj, childNodes, config) // Node.ELEMENT_NODE = 1 // event // childNodes.forEach(it => { // if (it instanceof Element) { // it.setAttribute('dr-thieVariableName', 'this') // } // }) // 중요 이벤트 걸어줌 this.eventNames.forEach(it => { this.addDrEvents(obj, it, childNodes, config); }); this.addDrEventPram(obj, _a.eventParam, childNodes, config); // value this.procAttr(childNodes, _a.valueAttrName, (it, attribute) => { const script = attribute; if (script) { const data = ScriptUtils.evalReturn(script, obj); if (it.value !== data) { it.value = data; } } }); // normal-attr-map this.procAttr(childNodes, _a.normalAttrMapAttrName, (it, attribute) => { const map = new Map(JSON.parse(attribute)); map.forEach((v, k) => { const data = ScriptUtils.eval(`const $element = this.element; return ${v} `, Object.assign(obj, { __render: Object.freeze({ element: it, attribute: DomUtils.getAttributeToObject(it) }) })); // console.log('-------normalAttribute---datadatadata',data) if (data === null) { it.removeAttribute(k); } else { it.setAttribute(k, data); } }); }); // window event _a.WINDOW_EVENTS.forEach(it => { this.procAttr(childNodes, _a.attrPrefix + 'window-event-' + it, (it, attribute) => { it.obj = obj; }); }); // value-link event _a.linkAttrs.forEach(linkInfo => { this.procAttr(childNodes, linkInfo.name, (it, varName) => { if (varName) { const ownerVariablePathName = it.getAttribute(_a.ownerVariablePathAttrName); const mapScript = it.getAttribute(`${linkInfo.name}:map`); // const inMapScript = it.getAttribute(`${valueLinkAttrName}:in-map`); let bindObj = obj; if (ownerVariablePathName) { bindObj = ScriptUtils.evalReturn(ownerVariablePathName, obj); } const getValue = this.getValue(obj, varName, bindObj); // TODO: 아래 나중에 리팩토링 필요함 if (typeof getValue === 'function' && getValue) { let setValue = it[linkInfo.property]; if (mapScript) { setValue = ScriptUtils.eval(`${this.getBindScript(config)} return ${mapScript}`, Object.assign(bindObj, { __render: Object.freeze(Object.assign({ element: it, target: bindObj, range: Range.range, value: setValue, scripts: _a.setBindProperty(config === null || config === void 0 ? void 0 : config.scripts, obj) }, config === null || config === void 0 ? void 0 : config.eventVariables)) })); } getValue(setValue); } else if (getValue) { let setValue = getValue; if (mapScript) { setValue = ScriptUtils.eval(`${this.getBindScript(config)} return ${mapScript}`, Object.assign(bindObj, { __render: Object.freeze(Object.assign({ element: it, target: bindObj, range: Range.range, value: setValue, scripts: _a.setBindProperty(config === null || config === void 0 ? void 0 : config.scripts, obj) }, config === null || config === void 0 ? void 0 : config.eventVariables)) })); } // console.log('------->',it.value, setValue) if (setValue === null) { it.removeAttribute(linkInfo.property); } else { // console.log('-----------',it, setValue) it[linkInfo.property] = setValue; } // 여기서 value가 먼저냐 value-link가 먼저냐 선을 정해야되는거네..-> 라고해서 undefined일때에는 element값을 먼저셋팅해준다. } else if (getValue === undefined) { this.setValue(obj, varName, it[linkInfo.property]); } it.addEventListener(linkInfo.event, (event) => { let value = it[linkInfo.property]; if (mapScript) { value = ScriptUtils.eval(`${this.getBindScript(config)} return ${mapScript}`, Object.assign(bindObj, { __render: Object.freeze(Object.assign({ event, element: it, attribute: DomUtils.getAttributeToObject(it), target: event.target, range: Range.range, scripts: _a.setBindProperty(config === null || config === void 0 ? void 0 : config.scripts, obj) }, config === null || config === void 0 ? void 0 : config.eventVariables)) })); } if (typeof this.getValue(obj, varName, bindObj) === 'function') { this.getValue(obj, varName, bindObj)(value, event); } else { this.setValue(obj, varName, value); } }); } }); }); // on-init event this.procAttr(childNodes, _a.onInitAttrName, (it, attribute) => { // it.removeAttribute(EventManager.onInitAttrName); let script = attribute; if (script) { script = 'return ' + script; } if (script) { ScriptUtils.eval(`${this.getBindScript(config)}; ${script} `, Object.assign(obj, { __render: Object.freeze(Object.assign({ element: it, attribute: DomUtils.getAttributeToObject(it) }, config === null || config === void 0 ? void 0 : config.eventVariables)) })); } }); this.onRenderedEvent(obj, childNodes, config); this.changeVar(obj, childNodes, undefined, config); // console.log('eventManager-applyEvent-->', config?.applyEvents) const elements = Array.from(childNodes).filter(it => it.nodeType === 1).map(it => it); elements.forEach(it => { var _b; (_b = config === null || config === void 0 ? void 0 : config.applyEvents) === null || _b === void 0 ? void 0 : _b.filter(ta => it.getAttribute(ta.attrName) !== null).forEach(ta => ta.callBack(it, it.getAttribute(ta.attrName), obj)); }); } // RawSet에서 replaceBody이후에 호출 onRenderedEvent(obj, childNodes, config) { // console.log('--------onRenderedEvent', obj, childNodes); // console.log(document.querySelectorAll(`[${EventManager.onRenderedInitAttrName}]`)) this.procAttr(childNodes, _a.onRenderedInitAttrName, (it, attribute) => { // it.removeAttribute(EventManager.onRenderedInitAttrName); if (!it.isConnected) { return; } let script = attribute; if (script) { script = 'return ' + script; } // console.log('onRendered!!') if (script) { ScriptUtils.eval(`${this.getBindScript(config)}; ${script} `, Object.assign(obj, { __render: Object.freeze(Object.assign({ element: it, attribute: DomUtils.getAttributeToObject(it) }, config === null || config === void 0 ? void 0 : config.eventVariables)) })); } }); } // eslint-disable-next-line no-undef changeVar(obj, elements, varName, config) { // style this.procAttr(elements, _a.styleAttrName, (it, attribute) => { let script = attribute; if (script) { script = 'return ' + script; } if (_a.isUsingThisVar(script, varName) || varName === undefined) { const data = ScriptUtils.eval(`const $element = this.__render.element; ${script} `, Object.assign(obj, { __render: Object.freeze({ element: it, attribute: DomUtils.getAttributeToObject(it) }) })); if (typeof data === 'string') { it.setAttribute('style', data); } else if (Array.isArray(data)) { it.setAttribute('style', data.join(';')); } else { for (const [key, value] of Object.entries(data)) { if (it instanceof HTMLElement) { it.style[key] = String(value); } } } } }); // class this.procAttr(elements, _a.classAttrName, (it, attribute) => { let script = attribute; if (script) { script = 'return ' + script; } if (_a.isUsingThisVar(script, varName) || varName === undefined) { const data = ScriptUtils.eval(`const $element = this.element; ${script} `, Object.assign(obj, { __render: Object.freeze({ element: it, attribute: DomUtils.getAttributeToObject(it) }) })); if (typeof data === 'string') { it.setAttribute('class', data); } else if (Array.isArray(data)) { it.setAttribute('class', data.join(' ')); } else { for (const [key, value] of Object.entries(data)) { if (it instanceof HTMLElement) { if (value) { it.classList.add(key); } else { it.classList.remove(key); } } } } } }); // this.onRenderedEvent(obj,elements, config); } addDrEvents(obj, eventName, elements, config) { // console.log('-------?', config?.router) const attr = _a.attrPrefix + 'event-' + eventName; this.procAttr(elements, attr, (it, attribute) => { const script = attribute; const hasDispatch = it.hasAttribute(`${attr}:dispatch`); // console.log('hasDispatch',hasDispatch, attr, it); it.addEventListener(eventName, (event) => { let filter = true; const filterScript = it.getAttribute(`${attr}:filter`); const thisTarget = Object.assign(obj, { __render: Object.freeze(Object.assign({ event, element: it, target: event.target, range: Range.range, attribute: DomUtils.getAttributeToObject(it), router: config === null || config === void 0 ? void 0 : config.router, scripts: _a.setBindProperty(config === null || config === void 0 ? void 0 : config.scripts, obj) }, config === null || config === void 0 ? void 0 : config.eventVariables)) }); if (filterScript) { filter = ScriptUtils.eval(`${this.getBindScript(config)} return ${filterScript}`, thisTarget); } if (filter) { ScriptUtils.eval(`${this.getBindScript(config)} ${script} `, thisTarget); } }); if (hasDispatch) { it.dispatchEvent(new Event(eventName)); } }); } // eslint-disable-next-line no-undef addDrEventPram(obj, attr, elements, config) { this.procAttr(elements, attr, (it, attribute, attributes) => { const bind = attributes[attr + ':bind']; if (bind) { const script = attribute; const params = {}; const prefix = attr + ':'; Object.entries(attributes).filter(([k, v]) => k.startsWith(prefix)).forEach(([k, v]) => { params[k.slice(prefix.length)] = v; }); bind.split(',').forEach(eventName => { it.addEventListener(eventName.trim(), (event) => { ScriptUtils.eval(`const $params = this.__render.params; ${this.getBindScript(config)} ${script} `, Object.assign(obj, { __render: Object.freeze(Object.assign({ event, element: it, attribute: DomUtils.getAttributeToObject(it), target: event.target, range: Range.range, scripts: _a.setBindProperty(config === null || config === void 0 ? void 0 : config.scripts, obj), params }, config === null || config === void 0 ? void 0 : config.eventVariables)) })); }); }); } }); } // eslint-disable-next-line no-undef procAttr(elements = new Set(), attrName, callBack) { const sets = new Set(); elements.forEach(it => { // console.log('--->type', it, it.nodeType) if (!it) { return; } // Node.ELEMENT_NODE = 1 if (it.nodeType === 1) { const e = it; sets.add(e); e.querySelectorAll(`[${attrName}]`).forEach(it => { sets.add(it); }); } }); // console.log('---setr',sets); sets.forEach(it => { const attr = it.getAttribute(attrName); const attrs = DomUtils.getAttributeToObject(it); if (attr) { callBack(it, attr, attrs); } }); } getValue(obj, name, bindObj) { // let r = obj[name]; let r = ScriptUtils.evalReturn(name, obj); if (typeof r === 'function') { r = r.bind(bindObj !== null && bindObj !== void 0 ? bindObj : obj); } return r; } setValue(obj, name, value) { name = name.replaceAll('this.', 'this.this.'); ScriptUtils.eval(`${name} = this.value;`, { this: obj, value: value }); } static isUsingThisVar(raws, varName) { // console.log('isUsingV', raws) // console.log('isUsingV', raws, varName, ScriptUtils.getVariablePaths(raws ?? '')) if (varName && raws) { if (varName.startsWith('this.')) { varName = varName.replace(/this\./, ''); } _a.VARNAMES.forEach(it => { // raws = raws!.replace(RegExp(it.replace('$', '\\$'), 'g'), `this?.___${it}`); raws = raws.replace(RegExp(it.replace('$', '\\$'), 'g'), `this.___${it}`); }); const variablePaths = ScriptUtils.getVariablePaths(raws !== null && raws !== void 0 ? raws : ''); return variablePaths.has(varName); } return false; } static setBindProperty(scripts, obj) { if (scripts) { // const newScripts = Object.assign({}, scripts) const newScripts = Object.assign({}, scripts); for (const [key, value] of Object.entries(newScripts)) { if (typeof value === 'function') { newScripts[key] = value.bind(obj); } } return newScripts; } } getBindScript(config) { if (config === null || config === void 0 ? void 0 : config.eventVariables) { const bindScript = Object.entries(config.eventVariables).filter(([key, value]) => !this.bindScript.includes(`const ${key}`)).map(([key, value]) => { return `const ${key} = this.__render.${key};`; }).join(';'); return this.bindScript + '' + bindScript; } else { return this.bindScript; } } } _a = EventManager; EventManager.attrPrefix = 'dr-'; EventManager.ownerVariablePathAttrName = _a.attrPrefix + 'owner-variable-path'; EventManager.eventParam = _a.attrPrefix + 'event'; EventManager.onInitAttrName = _a.attrPrefix + 'on-init'; EventManager.valueAttrName = _a.attrPrefix + 'value'; EventManager.linkAttrs = [ { name: _a.attrPrefix + 'value-link', property: 'value', event: 'input' }, { name: _a.attrPrefix + 'hidden-link', property: 'value', event: 'input' }, { name: _a.attrPrefix + 'required-link', property: 'value', event: 'input' }, { name: _a.attrPrefix + 'checked-link', property: 'checked', event: 'change' }, { name: _a.attrPrefix + 'open-link', property: 'open', event: 'toggle' }, ]; EventManager.linkTargetMapAttrName = _a.attrPrefix + 'link-variables'; EventManager.onRenderedInitAttrName = _a.attrPrefix + 'on-rendered-init'; EventManager.attrAttrName = _a.attrPrefix + 'attr'; EventManager.normalAttrMapAttrName = _a.attrPrefix + 'normal-attr-map'; EventManager.styleAttrName = _a.attrPrefix + 'style'; EventManager.classAttrName = _a.attrPrefix + 'class'; EventManager.VALUE_VARNAME = '$value'; EventManager.SCRIPTS_VARNAME = '$scripts'; EventManager.FAG_VARNAME = '$fag'; EventManager.RAWSET_VARNAME = '$rawSet'; EventManager.RENDER_VARNAME = '$render'; EventManager.NEAR_THIS_VARNAME = '$nearThis'; EventManager.PARENT_THIS_VARNAME = '$parentThis'; EventManager.ROOT_OBJECT_VARNAME = '$rootObject'; EventManager.SCRIPT_UTILS_VARNAME = '$scriptUtils'; EventManager.RANGE_VARNAME = '$range'; EventManager.ROUTER_VARNAME = '$router'; EventManager.INNER_HTML_VARNAME = '$innerHTML'; EventManager.ELEMENT_VARNAME = '$element'; EventManager.TARGET_VARNAME = '$target'; EventManager.EVENT_VARNAME = '$event'; EventManager.COMPONENT_VARNAME = '$component'; EventManager.INNERHTML_VARNAME = '$innerHTML'; EventManager.ATTRIBUTE_VARNAME = '$attribute'; EventManager.CREATOR_META_DATA_VARNAME = '$creatorMetaData'; EventManager.PARENT_THIS_PATH_VARNAME = '$parentPath'; EventManager.CURRENT_THIS_VARNAME = '$currentThis'; EventManager.CURRENT_THIS_PATH_VARNAME = '$currentThisPath'; EventManager.NEAR_THIS_PATH_VARNAME = '$nearThisPath'; EventManager.VARNAMES = [_a.SCRIPTS_VARNAME, _a.FAG_VARNAME, _a.RAWSET_VARNAME, _a.RANGE_VARNAME, _a.ROUTER_VARNAME, _a.ELEMENT_VARNAME, _a.TARGET_VARNAME, _a.EVENT_VARNAME, _a.COMPONENT_VARNAME, _a.INNERHTML_VARNAME, _a.ATTRIBUTE_VARNAME, _a.ATTRIBUTE_VARNAME, _a.CREATOR_META_DATA_VARNAME, _a.PARENT_THIS_PATH_VARNAME, _a.PARENT_THIS_VARNAME, _a.attrAttrName]; EventManager.WINDOW_EVENT_POPSTATE = 'popstate'; EventManager.WINDOW_EVENT_RESIZE = 'resize'; EventManager.WINDOW_EVENTS = [_a.WINDOW_EVENT_POPSTATE, _a.WINDOW_EVENT_RESIZE]; EventManager.attrNames = [ _a.valueAttrName, _a.attrAttrName, _a.normalAttrMapAttrName, _a.styleAttrName, _a.classAttrName, _a.attrPrefix + 'window-event-' + _a.WINDOW_EVENT_POPSTATE, _a.attrPrefix + 'window-event-' + _a.WINDOW_EVENT_RESIZE, _a.onInitAttrName, ..._a.linkAttrs.map(it => it.name), _a.eventParam ]; export const eventManager = new EventManager(); //# sourceMappingURL=EventManager.js.map