marko/src/runtime/components/ComponentDef.js
2019-06-05 11:28:58 -07:00

168 lines
4.8 KiB
JavaScript

"use strict";
var complain = "MARKO_DEBUG" && require("complain");
var componentUtil = require("./util");
var attachBubblingEvent = componentUtil.___attachBubblingEvent;
var addDelegatedEventHandler = require("./event-delegation")
.___addDelegatedEventHandler;
var extend = require("raptor-util/extend");
var KeySequence = require("./KeySequence");
var FLAG_WILL_RERENDER_IN_BROWSER = 1;
// var FLAG_HAS_BODY_EL = 2;
// var FLAG_HAS_HEAD_EL = 4;
var FLAG_OLD_HYDRATE_NO_CREATE = 8;
/**
* A ComponentDef is used to hold the metadata collected at runtime for
* a single component and this information is used to instantiate the component
* later (after the rendered HTML has been added to the DOM)
*/
function ComponentDef(component, componentId, globalComponentsContext) {
this.___globalComponentsContext = globalComponentsContext; // The AsyncWriter that this component is associated with
this.___component = component;
this.id = componentId;
this.___domEvents = undefined; // An array of DOM events that need to be added (in sets of three)
this.___isExisting = false;
this.___renderBoundary = false;
this.___flags = 0;
this.___nextIdIndex = 0; // The unique integer to use for the next scoped ID
this.___keySequence = null;
this.___preservedDOMNodes = null;
}
ComponentDef.prototype = {
___nextKey: function(key) {
var keySequence =
this.___keySequence || (this.___keySequence = new KeySequence());
return keySequence.___nextKey(key);
},
___preserveDOMNode: function(key, bodyOnly) {
var lookup =
this.___preservedDOMNodes || (this.___preservedDOMNodes = {});
lookup[key] = bodyOnly ? 2 : 1;
},
/**
* This helper method generates a unique and fully qualified DOM element ID
* that is unique within the scope of the current component.
*/
elId: function(nestedId) {
var id = this.id;
if (nestedId == null) {
return id;
} else {
if (typeof nestedId !== "string") {
// eslint-disable-next-line no-constant-condition
if ("MARKO_DEBUG") {
complain("Using non strings as keys is deprecated.");
}
nestedId = String(nestedId);
}
if (nestedId.indexOf("#") === 0) {
id = "#" + id;
nestedId = nestedId.substring(1);
}
return id + "-" + nestedId;
}
},
/**
* Returns the next auto generated unique ID for a nested DOM element or nested DOM component
*/
___nextComponentId: function() {
return this.id + "-c" + this.___nextIdIndex++;
},
d: function(eventName, handlerMethodName, isOnce, extraArgs) {
addDelegatedEventHandler(eventName);
return attachBubblingEvent(this, handlerMethodName, isOnce, extraArgs);
},
get ___type() {
return this.___component.___type;
}
};
ComponentDef.___deserialize = function(o, types, global, registry) {
var id = o[0];
var typeName = types[o[1]];
var input = o[2];
var extra = o[3];
var isLegacy = extra.l;
var state = extra.s;
var componentProps = extra.w;
var flags = extra.f;
var component =
typeName /* legacy */ &&
registry.___createComponent(typeName, id, isLegacy);
// Prevent newly created component from being queued for update since we area
// just building it from the server info
component.___updateQueued = true;
if (
!isLegacy &&
flags & FLAG_WILL_RERENDER_IN_BROWSER &&
!(flags & FLAG_OLD_HYDRATE_NO_CREATE)
) {
if (component.onCreate) {
component.onCreate(input, { global: global });
}
if (component.onInput) {
input = component.onInput(input, { global: global }) || input;
}
} else {
if (state) {
var undefinedPropNames = extra.u;
if (undefinedPropNames) {
undefinedPropNames.forEach(function(undefinedPropName) {
state[undefinedPropName] = undefined;
});
}
// We go through the setter here so that we convert the state object
// to an instance of `State`
component.state = state;
}
if (componentProps) {
extend(component, componentProps);
}
}
component.___input = input;
if (extra.b) {
component.___bubblingDomEvents = extra.b;
}
var scope = extra.p;
var customEvents = extra.e;
if (customEvents) {
component.___setCustomEvents(customEvents, scope);
}
component.___global = global;
return {
id: id,
___component: component,
___boundary: extra.r,
___domEvents: extra.d,
___flags: extra.f || 0
};
};
module.exports = ComponentDef;