VulpesOS/gaia/apps/calendar/js/views/factory.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

78 lines
2.1 KiB
JavaScript
Executable file

define(function(require, exports, module) {
'use strict';
var asyncRequire = require('common/async_require');
var debug = require('common/debug')('viewFactory');
var nextTick = require('common/next_tick');
var snakeCase = require('snake_case');
exports._instances = Object.create(null);
/**
* Initializes a view and stores
* a internal reference so when
* view is called a second
* time the same view is used.
*
* Makes an asynchronous call to
* load the script if we do not
* have the view cached.
*
* // for example if you have
* // a calendar view Foo
*
* viewFactory.get('Foo', function(view) {
* (view instanceof require('views/foo')) === true
* });
*
* @param {String} name view name.
* @param {Function} view loaded callback.
*/
exports.get = function(name, cb) {
if (this._registered(name)) {
debug(`Found view named ${name}`);
this._get(name, cb);
return;
}
var path = `views/${snakeCase(name)}`;
try {
// we try sync require first since it should be faster (skip an extra
// "tick"); our modules are bundled into few files during build time, so
// sync require should work in almost all the calls (will only fail if
// module was not defined/loaded before)
var Ctor = require(path);
debug(`Initializing view ${name} registered as ${path}`);
this._initView(name, Ctor, cb);
} catch(e) {
debug(`Will try to load view ${name} at ${path}`);
asyncRequire(path).then(Ctor => {
debug(`Loaded view ${name}`);
this._initView(name, Ctor, cb);
});
}
},
exports._registered = function(name) {
return name in this._instances;
};
exports._get = function(name, cb) {
var view = this._instances[name];
cb && nextTick(() => cb.call(null, view));
};
exports._initView = function(name, Ctor, cb) {
if (this._registered(name)) {
// need to safeguard in case async load is triggered multiple times before
// we can save a reference to the Constructor and/or view instance (would
// trigger the window.require callback multiple times)
return;
}
var view = new Ctor();
this._instances[name] = view;
this._get(name, cb);
};
});