Files
config-pacs-docker/nv/html/nv-nopdf/styles/packages/iron_controller.js
2025-02-26 14:49:25 +07:00

469 lines
14 KiB
JavaScript

//////////////////////////////////////////////////////////////////////////
// //
// This is a generated file. You can view the original //
// source in your browser if your browser supports source maps. //
// Source maps are supported by all recent versions of Chrome, Safari, //
// and Firefox, and by Internet Explorer 11. //
// //
//////////////////////////////////////////////////////////////////////////
(function () {
/* Imports */
var Meteor = Package.meteor.Meteor;
var global = Package.meteor.global;
var meteorEnv = Package.meteor.meteorEnv;
var _ = Package.underscore._;
var Tracker = Package.tracker.Tracker;
var Deps = Package.tracker.Deps;
var ReactiveDict = Package['reactive-dict'].ReactiveDict;
var Template = Package['templating-runtime'].Template;
var Iron = Package['iron:core'].Iron;
var Blaze = Package.blaze.Blaze;
var UI = Package.blaze.UI;
var Handlebars = Package.blaze.Handlebars;
var Spacebars = Package.spacebars.Spacebars;
var HTML = Package.htmljs.HTML;
/* Package-scope variables */
var WaitList, Controller;
(function(){
/////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/iron_controller/lib/wait_list.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////
//
/*****************************************************************************/
/* Imports */
/*****************************************************************************/
var assert = Iron.utils.assert;
/*****************************************************************************/
/* Private */
/*****************************************************************************/
/**
* Returns an object of computation ids starting with
* the current computation and including all ancestor
* computations. The data structure is an object
* so we can index by id and do quick checks.
*/
var parentComputations = function () {
var list = {};
var c = Deps.currentComputation;
while (c) {
list[String(c._id)] = true;
c = c._parent;
}
return list;
};
/**
* Check whether the user has called ready() and then called wait(). This
* can cause a condition that can be simplified to this:
*
* dep = new Deps.Dependency;
*
* Deps.autorun(function () {
* dep.depend();
* dep.changed();
* });
*/
var assertNoInvalidationLoop = function (dependency) {
var parentComps = parentComputations();
var depCompIds = _.keys(dependency._dependentsById);
_.each(depCompIds, function (id) {
assert(!parentComps[id], "\n\n\
You called wait() after calling ready() inside the same computation tree.\
\n\n\
You can fix this problem in two possible ways:\n\n\
1) Put all of your wait() calls before any ready() calls.\n\
2) Put your ready() call in its own computation with Deps.autorun."
);
});
};
/*****************************************************************************/
/* WaitList */
/*****************************************************************************/
/**
* A WaitList tracks a list of reactive functions, each in its own computation.
* The list is ready() when all of the functions return true. This list is not
* ready (i.e. this.ready() === false) if at least one function returns false.
*
* You add functions by calling the wait(fn) method. Each function is run its
* own computation. The ready() method is a reactive method but only calls the
* deps changed function if the overall state of the list changes from true to
* false or from false to true.
*/
WaitList = function () {
this._readyDep = new Deps.Dependency;
this._comps = [];
this._notReadyCount = 0;
};
/**
* Pass a function that returns true or false.
*/
WaitList.prototype.wait = function (fn) {
var self = this;
var activeComp = Deps.currentComputation;
assertNoInvalidationLoop(self._readyDep);
// break with parent computation and grab the new comp
Deps.nonreactive(function () {
// store the cached result so we can see if it's different from one run to
// the next.
var cachedResult = null;
// create a computation for this handle
var comp = Deps.autorun(function (c) {
// let's get the new result coerced into a true or false value.
var result = !!fn();
var oldNotReadyCount = self._notReadyCount;
// if it's the first run and we're false then inc
if (c.firstRun && !result)
self._notReadyCount++;
else if (cachedResult !== null && result !== cachedResult && result === true)
self._notReadyCount--;
else if (cachedResult !== null && result !== cachedResult && result === false)
self._notReadyCount++;
cachedResult = result;
if (oldNotReadyCount === 0 && self._notReadyCount > 0)
self._readyDep.changed();
else if (oldNotReadyCount > 0 && self._notReadyCount === 0)
self._readyDep.changed();
});
self._comps.push(comp);
if (activeComp) {
activeComp.onInvalidate(function () {
// keep the old computation and notReadyCount the same for one
// flush cycle so that we don't end up in an intermediate state
// where list.ready() is not correct.
// keep the state the same until the flush cycle is complete
Deps.afterFlush(function () {
// stop the computation
comp.stop();
// remove the computation from the list
self._comps.splice(_.indexOf(self._comps, comp), 1);
if (cachedResult === false) {
self._notReadyCount--;
if (self._notReadyCount === 0)
self._readyDep.changed();
}
});
});
}
});
};
WaitList.prototype.ready = function () {
this._readyDep.depend();
return this._notReadyCount === 0;
};
WaitList.prototype.stop = function () {
_.each(this._comps, function (c) { c.stop(); });
this._comps = [];
};
Iron.WaitList = WaitList;
/////////////////////////////////////////////////////////////////////////////////////////////
}).call(this);
(function(){
/////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/iron_controller/lib/controller.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////
//
/*****************************************************************************/
/* Imports */
/*****************************************************************************/
var debug = Iron.utils.debug('iron:controller');
var Layout = Iron.Layout;
var DynamicTemplate = Iron.DynamicTemplate;
/*****************************************************************************/
/* Private */
/*****************************************************************************/
var bindData = function (value, thisArg) {
return function () {
return (typeof value === 'function') ? value.apply(thisArg, arguments) : value;
};
};
/*****************************************************************************/
/* Controller */
/*****************************************************************************/
Controller = function (options) {
var self = this;
this.options = options || {};
this._layout = this.options.layout || new Layout(this.options);
this._isController = true;
this._layout._setLookupHost(this);
// grab the event map from the Controller constructor which was
// set if the user does MyController.events({...});
var eventMap = Controller._collectEventMaps.call(this.constructor);
this._layout.events(eventMap, this);
this.init(options);
};
/**
* Set or get the layout's template and optionally its data context.
*/
Controller.prototype.layout = function (template, options) {
var self = this;
this._layout.template(template);
// check whether options has a data property
if (options && (_.has(options, 'data')))
this._layout.data(bindData(options.data, this));
return {
data: function (val) {
return self._layout.data(bindData(val, self));
}
};
};
/**
* Render a template into a region of the layout.
*/
Controller.prototype.render = function (template, options) {
var self = this;
if (options && (typeof options.data !== 'undefined'))
options.data = bindData(options.data, this);
var tmpl = this._layout.render(template, options);
// allow caller to do: this.render('MyTemplate').data(function () {...});
return {
data: function (func) {
return tmpl.data(bindData(func, self));
}
};
};
/**
* Begin recording rendered regions.
*/
Controller.prototype.beginRendering = function (onComplete) {
return this._layout.beginRendering(onComplete);
};
/*****************************************************************************/
/* Controller Static Methods */
/*****************************************************************************/
/**
* Inherit from Controller.
*
* Note: The inheritance function in Meteor._inherits is broken. Static
* properties on functions don't get copied.
*/
Controller.extend = function (props) {
return Iron.utils.extend(this, props);
};
Controller.events = function (events) {
this._eventMap = events;
return this;
};
/**
* Returns a single event map merged from super to child.
* Called from the constructor function like this:
*
* this.constructor._collectEventMaps()
*/
var mergeStaticInheritedObjectProperty = function (ctor, prop) {
var merge = {};
if (ctor.__super__)
_.extend(merge, mergeStaticInheritedObjectProperty(ctor.__super__.constructor, prop));
return _.has(ctor, prop) ? _.extend(merge, ctor[prop]) : merge;
};
Controller._collectEventMaps = function () {
return mergeStaticInheritedObjectProperty(this, '_eventMap');
};
// NOTE: helpers are not inherited from one controller to another, for now.
Controller._helpers = {};
Controller.helpers = function (helpers) {
_.extend(this._helpers, helpers);
return this;
};
/*****************************************************************************/
/* Global Helpers */
/*****************************************************************************/
if (typeof Template !== 'undefined') {
/**
* Returns the nearest controller for a template instance. You can call this
* function from inside a template helper.
*
* Example:
* Template.MyPage.helpers({
* greeting: function () {
* var controller = Iron.controller();
* return controller.state.get('greeting');
* }
* });
*/
Iron.controller = function () {
//XXX establishes a reactive dependency which causes helper to run
return DynamicTemplate.findLookupHostWithProperty(Blaze.getView(), '_isController');
};
/**
* Find a lookup host with a state key and return it reactively if we have
* it.
*/
Template.registerHelper('get', function (key) {
var controller = Iron.controller();
if (controller && controller.state)
return controller.state.get(key);
});
}
/*****************************************************************************/
/* Namespacing */
/*****************************************************************************/
Iron.Controller = Controller;
/////////////////////////////////////////////////////////////////////////////////////////////
}).call(this);
(function(){
/////////////////////////////////////////////////////////////////////////////////////////////
// //
// packages/iron_controller/lib/controller_client.js //
// //
/////////////////////////////////////////////////////////////////////////////////////////////
//
/*****************************************************************************/
/* Imports */
/*****************************************************************************/
var Layout = Iron.Layout;
var debug = Iron.utils.debug('iron:controller');
var defaultValue = Iron.utils.defaultValue;
/*****************************************************************************/
/* Private */
/*****************************************************************************/
var bindData = function (value, thisArg) {
return function () {
return (typeof value === 'function') ? value.apply(thisArg, arguments) : value;
};
};
/*****************************************************************************/
/* Controller Client */
/*****************************************************************************/
/**
* Client specific init code.
*/
Controller.prototype.init = function (options) {
this._waitlist = new WaitList;
this.state = new ReactiveDict;
};
/**
* Insert the controller's layout into the DOM.
*/
Controller.prototype.insert = function (options) {
return this._layout.insert.apply(this._layout, arguments);
};
/**
* Add an item to the waitlist.
*/
Controller.prototype.wait = function (fn) {
var self = this;
if (!fn)
// it's possible fn is just undefined but we'll just return instead
// of throwing an error, to make it easier to call this function
// with waitOn which might not return anything.
return;
if (_.isArray(fn)) {
_.each(fn, function eachWait (fnOrHandle) {
self.wait(fnOrHandle);
});
} else if (fn.ready) {
this._waitlist.wait(function () { return fn.ready(); });
} else {
this._waitlist.wait(fn);
}
return this;
};
/**
* Returns true if all items in the waitlist are ready.
*/
Controller.prototype.ready = function () {
return this._waitlist.ready();
};
/**
* Clean up the controller and stop the waitlist.
*/
Controller.prototype.stop = function () {
this._waitlist.stop();
};
/////////////////////////////////////////////////////////////////////////////////////////////
}).call(this);
/* Exports */
Package._define("iron:controller");
})();