aframe
Version:
A web framework for building virtual reality experiences.
115 lines (102 loc) • 3.23 kB
JavaScript
var ANode = require('./a-node');
var registerElement = require('./a-register-element').registerElement;
var components = require('./component').components;
var utils = require('../utils');
var MULTIPLE_COMPONENT_DELIMITER = '__';
/**
* @member {object} componentCache - Cache of pre-parsed values. An object where the keys
* are component names and the values are already parsed by the component.
*/
module.exports = registerElement('a-mixin', {
prototype: Object.create(ANode.prototype, {
createdCallback: {
value: function () {
this.componentCache = {};
this.id = this.getAttribute('id');
this.isMixin = true;
}
},
attributeChangedCallback: {
value: function (attr, oldVal, newVal) {
this.cacheAttribute(attr, newVal);
this.updateEntities();
}
},
attachedCallback: {
value: function () {
this.sceneEl = this.closestScene();
this.cacheAttributes();
this.updateEntities();
this.load();
}
},
/**
* setAttribute that parses and caches component values.
*/
setAttribute: {
value: function (attr, value) {
window.HTMLElement.prototype.setAttribute.call(this, attr, value);
this.cacheAttribute(attr, value);
}
},
/**
* If `attr` is a component, then parse the value using the schema and store it.
*/
cacheAttribute: {
value: function (attr, value) {
var component;
var componentName;
// Get component data.
componentName = utils.split(attr, MULTIPLE_COMPONENT_DELIMITER)[0];
component = components[componentName];
if (!component) { return; }
if (value === undefined) {
value = window.HTMLElement.prototype.getAttribute.call(this, attr);
}
this.componentCache[attr] = component.parseAttrValueForCache(value);
}
},
/**
* If `attr` is a component, then grab pre-parsed value from the cache.
* Else do a normal getAttribute.
*/
getAttribute: {
value: function (attr) {
return this.componentCache[attr] ||
window.HTMLElement.prototype.getAttribute.call(this, attr);
}
},
/**
* Parse and cache every component defined on the mixin.
*/
cacheAttributes: {
value: function () {
var attributes = this.attributes;
var attrName;
var i;
for (i = 0; i < attributes.length; i++) {
attrName = attributes[i].name;
this.cacheAttribute(attrName);
}
}
},
/**
* For entities that already have been loaded by the time the mixin was attached, tell
* those entities to register the mixin and refresh their component data.
*/
updateEntities: {
value: function () {
var entity;
var entities;
var i;
if (!this.sceneEl) { return; }
entities = this.sceneEl.querySelectorAll('[mixin~=' + this.id + ']');
for (i = 0; i < entities.length; i++) {
entity = entities[i];
if (!entity.hasLoaded || entity.isMixin) { continue; }
entity.mixinUpdate(this.id);
}
}
}
})
});