'use strict'; /* jshint newcap:false */ var domInsert = require('../runtime/dom-insert'); var marko = require('../'); var widgetsUtil = require('./util'); var getWidgetForEl = widgetsUtil.$__getWidgetForEl; var widgetLookup = widgetsUtil.$__widgetLookup; var emitLifecycleEvent = widgetsUtil.$__emitLifecycleEvent; var destroyWidgetForEl = widgetsUtil.$__destroyWidgetForEl; var destroyElRecursive = widgetsUtil.$__destroyElRecursive; var getElementById = widgetsUtil.$__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/HTMLElement').$__morphAttrs; var morphdomFactory = require('morphdom/factory'); var morphdom = morphdomFactory(morphAttrs); 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 hasCompatibleWidget(widgetsContext, existingWidget) { var id = existingWidget.id; var newWidgetDef = widgetsContext.$__widgetsById[id]; return newWidgetDef && existingWidget.$__type == newWidgetDef.$__type; } function handleCustomEventWithMethodListener(widget, targetMethodName, args, extraArgs) { // Remove the "eventType" argument args.push(widget); if (extraArgs) { args = extraArgs.concat(args); } var targetWidget = widgetLookup[widget.$__scope]; var targetMethod = targetWidget[targetMethodName]; if (!targetMethod) { throw Error('Method not found: ' + targetMethodName); } targetMethod.apply(targetWidget, args); } function getElIdHelper(widget, widgetElId, index) { var id = widget.id; var elId = widgetElId != null ? id + '-' + widgetElId : 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(widget, stateChanges, oldState) { var handlerMethod; var handlers; for (var propName in stateChanges) { if (stateChanges.hasOwnProperty(propName)) { var handlerMethodName = 'update_' + propName; handlerMethod = widget[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 emitLifecycleEvent(widget, 'beforeUpdate'); for (var i=0, len=handlers.length; i 1) { var fragment = widget.$__document.createDocumentFragment(); for (var i=0; i