'use strict'; /* jshint newcap:false */ var domInsert = require('../runtime/dom-insert'); var marko = require('../'); var componentsUtil = require('./util'); var getComponentForEl = componentsUtil.$__getComponentForEl; var componentLookup = componentsUtil.$__componentLookup; var emitLifecycleEvent = componentsUtil.$__emitLifecycleEvent; var destroyComponentForEl = componentsUtil.$__destroyComponentForEl; var destroyElRecursive = componentsUtil.$__destroyElRecursive; var getElementById = componentsUtil.$__getElementById; var EventEmitter = require('events-light'); var RenderResult = require('../runtime/RenderResult'); var SubscriptionTracker = require('listener-tracker'); var inherit = require('raptor-util/inherit'); var updateManager = require('./update-manager'); var morphAttrs = require('../runtime/vdom/VElement').$__morphAttrs; var morphdomFactory = require('morphdom/factory'); var morphdom = morphdomFactory(morphAttrs); var eventDelegation = require('./event-delegation'); var slice = Array.prototype.slice; var MORPHDOM_SKIP = false; var WIDGET_SUBSCRIBE_TO_OPTIONS; var NON_WIDGET_SUBSCRIBE_TO_OPTIONS = { addDestroyListener: false }; var emit = EventEmitter.prototype.emit; function removeListener(removeEventListenerHandle) { removeEventListenerHandle(); } function hasCompatibleComponent(componentsContext, existingComponent) { var id = existingComponent.id; var newComponentDef = componentsContext.$__componentsById[id]; return newComponentDef && existingComponent.$__type == newComponentDef.$__component.$__type; } function handleCustomEventWithMethodListener(component, targetMethodName, args, extraArgs) { // Remove the "eventType" argument args.push(component); if (extraArgs) { args = extraArgs.concat(args); } var targetComponent = componentLookup[component.$__scope]; var targetMethod = targetComponent[targetMethodName]; if (!targetMethod) { throw Error('Method not found: ' + targetMethodName); } targetMethod.apply(targetComponent, args); } function getElIdHelper(component, componentElId, index) { var id = component.id; var elId = componentElId != null ? id + '-' + componentElId : id; if (index != null) { elId += '[' + index + ']'; } return elId; } /** * This method is used to process "update_" handler functions. * If all of the modified state properties have a user provided update handler * then a rerender will be bypassed and, instead, the DOM will be updated * looping over and invoking the custom update handlers. * @return {boolean} Returns true if if the DOM was updated. False, otherwise. */ function processUpdateHandlers(component, stateChanges, oldState) { var handlerMethod; var handlers; for (var propName in stateChanges) { if (stateChanges.hasOwnProperty(propName)) { var handlerMethodName = 'update_' + propName; handlerMethod = component[handlerMethodName]; if (handlerMethod) { (handlers || (handlers=[])).push([propName, handlerMethod]); } else { // This state change does not have a state handler so return false // to force a rerender return; } } } // If we got here then all of the changed state properties have // an update handler or there are no state properties that actually // changed. if (handlers) { // Otherwise, there are handlers for all of the changed properties // so apply the updates using those handlers for (var i=0, len=handlers.length; i 1) { var fragment = component.$__document.createDocumentFragment(); for (var i=0; i