'use strict'; var warp10Finalize = require('warp10/finalize'); var eventDelegation = require('./event-delegation'); var win = window; var defaultDocument = document; var events = require('../runtime/events'); var componentsUtil = require('./util'); var componentLookup = componentsUtil.$__componentLookup; var getElementById = componentsUtil.$__getElementById; var ComponentDef = require('./ComponentDef'); // var extend = require('raptor-util/extend'); // var registry = require('./registry'); function invokeComponentEventHandler(component, targetMethodName, args) { var method = component[targetMethodName]; if (!method) { throw Error('Method not found: ' + targetMethodName); } method.apply(component, args); } function addEventListenerHelper(el, eventType, listener) { el.addEventListener(eventType, listener, false); return function remove() { el.removeEventListener(eventType, listener); }; } function addDOMEventListeners(component, el, eventType, targetMethodName, extraArgs, handles) { var removeListener = addEventListenerHelper(el, eventType, function(event) { var args = [event, el]; if (extraArgs) { args = extraArgs.concat(args); } invokeComponentEventHandler(component, targetMethodName, args); }); handles.push(removeListener); } function initComponent(componentDef, doc) { var component = componentDef.$__component; if (!component || !component.$__isComponent) { return; // legacy } var domEvents = componentDef.$__domEvents; component.$__reset(); component.$__document = doc; var isExisting = componentDef.$__isExisting; var id = component.id; var rootIds = componentDef.$__roots; if (rootIds) { var rootComponents; var els = []; rootIds.forEach(function(rootId) { var nestedId = id + '-' + rootId; var rootComponent = componentLookup[nestedId]; if (rootComponent) { rootComponent.$__rootFor = component; if (rootComponents) { rootComponents.push(rootComponent); } else { rootComponents = component.$__rootComponents = [rootComponent]; } } else { var rootEl = getElementById(doc, nestedId); if (rootEl) { rootEl._w = component; els.push(rootEl); } } }); component.el = els[0]; component.els = els; componentLookup[id] = component; } else if (!isExisting) { var el = getElementById(doc, id); el._w = component; component.el = el; component.els = [el]; componentLookup[id] = component; } if (isExisting) { component.$__removeDOMEventListeners(); } if (domEvents) { var eventListenerHandles = []; domEvents.forEach(function(domEventArgs) { // The event mapping is for a direct DOM event (not a custom event and not for bubblign dom events) var eventType = domEventArgs[0]; var targetMethodName = domEventArgs[1]; var eventEl = getElementById(doc, domEventArgs[2]); var extraArgs = domEventArgs[3]; addDOMEventListeners(component, eventEl, eventType, targetMethodName, extraArgs, eventListenerHandles); }); if (eventListenerHandles.length) { component.$__domEventListenerHandles = eventListenerHandles; } } if (isExisting) { component.$__emitLifecycleEvent('update'); } else { events.emit('mountComponent', component); component.$__emitLifecycleEvent('mount'); } } /** * This method is used to initialized components associated with UI components * rendered in the browser. While rendering UI components a "components context" * is added to the rendering context to keep up with which components are rendered. * When ready, the components can then be initialized by walking the component tree * in the components context (nested components are initialized before ancestor components). * @param {Array} componentDefs An array of ComponentDef instances */ function initClientRendered(componentDefs, doc) { // Ensure that event handlers to handle delegating events are // always attached before initializing any components eventDelegation.$__init(doc); doc = doc || defaultDocument; for (var i=0,len=componentDefs.length; i