view release on metacpan or search on metacpan
all targets "inherit" from the MFILE.target prototype; now being
much more careful about the order in which I define objects so I
don't refer to objects that don't yet exist; hopefully this change
will streamline the code and facilitate addition of additional targets
- HTML.pm: get names of JavaScript code files from site configuration
parameter, instead of having them hardcoded
- status: login, logout, and simple menus are working again; rest is broken
0.048 2014-08-26 14:49 CEST
- MANIFEST: update JavaScript source files
- 002lib.js: expand MFILE.lib.AJAX to take success and failure callbacks
- js/: change all MFILE.lib.AJAX calls to send success and failure callbacsk
- 011simpleMenu2.js: use anonymous function call to loop over all simple
menus
- status: ready to re-implement simple forms
0.049 2014-08-26 15:52 CEST
- WIP refactoring JavaScript code for the new 'target' prototype
and to use object references wherever possible
0.050 2014-08-27 16:18 CEST
lib/App/MFILE/WWW/Resource.pm view on Meta::CPAN
# baseUrl is where we have all our JavaScript files
$r .= 'baseUrl: "' . $site->MFILE_WWW_REQUIREJS_BASEURL . '",';
# map 'jquery' module to 'jquery-private.js'
# (of course, the real 'jquery.js' must be present in 'js/')
$r .= 'map: {';
$r .= " '*': { 'jquery': 'jquery-private' },";
$r .= " 'jquery-private': { 'jquery': 'jquery' }";
$r .= '},';
# callbacks for showing module loading progress
$r .= 'onNodeCreated: function(node, config, moduleName, url) {';
$r .= " var t = document.getElementById('myLoadProgress'),";
$r .= " m = '';";
$r .= " m = 'module ' + moduleName + ' is about to be loaded';";
$r .= " console.log(m);";
$r .= " t.innerHTML = m;";
$r .= " node.addEventListener('load', function() {";
$r .= " m = 'module ' + moduleName + ' has been loaded';";
$r .= " console.log(m);";
$r .= " t.innerHTML = m;";
share/js/core/ajax.js view on Meta::CPAN
//
// provides a function that sends AJAX requests to the App::MFILE::WWW server
// (which forwards them to the backend server) and takes action based on the
// HTTP response received.
//
// The 'ajax' function takes three arguments:
// - MFILE AJAX Object (an object)
// - success callback
// - failure callback
//
// The success and failure callbacks can be null or undefined, in which case App::MFILE::WWW will
// just display the status text in the #result div (i.e., the line at the bottom of the frame).
// If your AJAX calls needs any other handling than this, you need to provide at least a success
// callback.
//
// In all cases except login/logout, the MFILE AJAX Object looks like this:
// {
// "method": any HTTP method accepted by the backend server
// "path": valid path to backend server resource
// "body": content body to be sent to backend server (can be null)
// }
share/js/core/qunit-2.4.0.js view on Meta::CPAN
if (pairs.every(function (pair) {
return pair.a !== a || pair.b !== b;
})) {
// Not yet started comparing this pair
pairs.push({ a: a, b: b });
}
return true;
}
var callbacks = {
"string": useStrictEquality,
"boolean": useStrictEquality,
"number": useStrictEquality,
"null": useStrictEquality,
"undefined": useStrictEquality,
"symbol": useStrictEquality,
"date": useStrictEquality,
"nan": function nan() {
return true;
share/js/core/qunit-2.4.0.js view on Meta::CPAN
var type = objectType(a);
// Callbacks for containers will append to the pairs queue to achieve breadth-first
// search order. The pairs queue is also used to avoid reprocessing any pair of
// containers that are reference-equal to a previously visited pair (a special case
// this being recursion detection).
//
// Because of this approach, once typeEquiv returns a false value, it should not be
// called again without clearing the pair queue else it may wrongly report a visited
// pair as being equivalent.
return objectType(b) === type && callbacks[type](a, b);
}
function innerEquiv(a, b) {
var i, pair;
// We're done when there's nothing more to compare
if (arguments.length < 2) {
return true;
}
share/js/core/qunit-2.4.0.js view on Meta::CPAN
testsRun: 0,
unskippedTestsRun: 0,
hooks: {
before: [],
beforeEach: [],
afterEach: [],
after: []
}
},
callbacks: {},
// The storage module to use for reordering tests
storage: localSessionStorage
};
// take a predefined QUnit.config and extend the defaults
var globalConfig = window && window.QUnit && window.QUnit.config;
// only extend the global config if there is no QUnit overload
if (window && window.QUnit && !window.QUnit.version) {
share/js/core/qunit-2.4.0.js view on Meta::CPAN
* @method emit
* @param {String} eventName
* @param {Object} data
* @return {Void}
*/
function emit(eventName, data) {
if (objectType(eventName) !== "string") {
throw new TypeError("eventName must be a string when emitting an event");
}
// Clone the callbacks in case one of them registers a new callback
var originalCallbacks = LISTENERS[eventName];
var callbacks = originalCallbacks ? [].concat(toConsumableArray(originalCallbacks)) : [];
for (var i = 0; i < callbacks.length; i++) {
callbacks[i](data);
}
}
/**
* Registers a callback as a listener to the specified event.
*
* @public
* @method on
* @param {String} eventName
* @param {Function} callback
share/js/core/qunit-2.4.0.js view on Meta::CPAN
if (!LISTENERS[eventName]) {
LISTENERS[eventName] = [];
}
// Don't register the same callback more than once
if (!inArray(callback, LISTENERS[eventName])) {
LISTENERS[eventName].push(callback);
}
}
// Register logging callbacks
function registerLoggingCallbacks(obj) {
var i,
l,
key,
callbackNames = ["begin", "done", "log", "testStart", "testDone", "moduleStart", "moduleDone"];
function registerLoggingCallback(key) {
var loggingCallback = function loggingCallback(callback) {
if (objectType(callback) !== "function") {
throw new Error("QUnit logging methods require a callback function as their first parameters.");
}
config.callbacks[key].push(callback);
};
return loggingCallback;
}
for (i = 0, l = callbackNames.length; i < l; i++) {
key = callbackNames[i];
// Initialize key collection of logging callback
if (objectType(config.callbacks[key]) === "undefined") {
config.callbacks[key] = [];
}
obj[key] = registerLoggingCallback(key);
}
}
function runLoggingCallbacks(key, args) {
var i, l, callbacks;
callbacks = config.callbacks[key];
for (i = 0, l = callbacks.length; i < l; i++) {
callbacks[i](args);
}
}
// Doesn't support IE9, it will return undefined on these browsers
// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
var fileName = (sourceFromStacktrace(0) || "").replace(/(:\d+)+\)?/, "").replace(/.+\//, "");
function extractStacktrace(e, offset) {
offset = offset === undefined ? 4 : offset;
share/js/core/qunit-2.4.0.js view on Meta::CPAN
// Store result when possible
if (storage) {
if (bad) {
storage.setItem("qunit-test-" + moduleName + "-" + testName, bad);
} else {
storage.removeItem("qunit-test-" + moduleName + "-" + testName);
}
}
// After emitting the js-reporters event we cleanup the assertion data to
// avoid leaking it. It is not used by the legacy testDone callbacks.
emit("testEnd", this.testReport.end(true));
this.testReport.slimAssertions();
runLoggingCallbacks("testDone", {
name: testName,
module: moduleName,
skipped: skipped,
todo: todo,
failed: bad,
passed: this.assertions.length - bad,
share/js/core/qunit.js view on Meta::CPAN
if (pairs.every(function (pair) {
return pair.a !== a || pair.b !== b;
})) {
// Not yet started comparing this pair
pairs.push({ a: a, b: b });
}
return true;
}
var callbacks = {
"string": useStrictEquality,
"boolean": useStrictEquality,
"number": useStrictEquality,
"null": useStrictEquality,
"undefined": useStrictEquality,
"symbol": useStrictEquality,
"date": useStrictEquality,
"nan": function nan() {
return true;
share/js/core/qunit.js view on Meta::CPAN
var type = objectType(a);
// Callbacks for containers will append to the pairs queue to achieve breadth-first
// search order. The pairs queue is also used to avoid reprocessing any pair of
// containers that are reference-equal to a previously visited pair (a special case
// this being recursion detection).
//
// Because of this approach, once typeEquiv returns a false value, it should not be
// called again without clearing the pair queue else it may wrongly report a visited
// pair as being equivalent.
return objectType(b) === type && callbacks[type](a, b);
}
function innerEquiv(a, b) {
var i, pair;
// We're done when there's nothing more to compare
if (arguments.length < 2) {
return true;
}
share/js/core/qunit.js view on Meta::CPAN
testsRun: 0,
unskippedTestsRun: 0,
hooks: {
before: [],
beforeEach: [],
afterEach: [],
after: []
}
},
callbacks: {},
// The storage module to use for reordering tests
storage: localSessionStorage
};
// take a predefined QUnit.config and extend the defaults
var globalConfig = window && window.QUnit && window.QUnit.config;
// only extend the global config if there is no QUnit overload
if (window && window.QUnit && !window.QUnit.version) {
share/js/core/qunit.js view on Meta::CPAN
* @method emit
* @param {String} eventName
* @param {Object} data
* @return {Void}
*/
function emit(eventName, data) {
if (objectType(eventName) !== "string") {
throw new TypeError("eventName must be a string when emitting an event");
}
// Clone the callbacks in case one of them registers a new callback
var originalCallbacks = LISTENERS[eventName];
var callbacks = originalCallbacks ? [].concat(toConsumableArray(originalCallbacks)) : [];
for (var i = 0; i < callbacks.length; i++) {
callbacks[i](data);
}
}
/**
* Registers a callback as a listener to the specified event.
*
* @public
* @method on
* @param {String} eventName
* @param {Function} callback
share/js/core/qunit.js view on Meta::CPAN
if (!LISTENERS[eventName]) {
LISTENERS[eventName] = [];
}
// Don't register the same callback more than once
if (!inArray(callback, LISTENERS[eventName])) {
LISTENERS[eventName].push(callback);
}
}
// Register logging callbacks
function registerLoggingCallbacks(obj) {
var i,
l,
key,
callbackNames = ["begin", "done", "log", "testStart", "testDone", "moduleStart", "moduleDone"];
function registerLoggingCallback(key) {
var loggingCallback = function loggingCallback(callback) {
if (objectType(callback) !== "function") {
throw new Error("QUnit logging methods require a callback function as their first parameters.");
}
config.callbacks[key].push(callback);
};
return loggingCallback;
}
for (i = 0, l = callbackNames.length; i < l; i++) {
key = callbackNames[i];
// Initialize key collection of logging callback
if (objectType(config.callbacks[key]) === "undefined") {
config.callbacks[key] = [];
}
obj[key] = registerLoggingCallback(key);
}
}
function runLoggingCallbacks(key, args) {
var i, l, callbacks;
callbacks = config.callbacks[key];
for (i = 0, l = callbacks.length; i < l; i++) {
callbacks[i](args);
}
}
// Doesn't support IE9, it will return undefined on these browsers
// See also https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Error/Stack
var fileName = (sourceFromStacktrace(0) || "").replace(/(:\d+)+\)?/, "").replace(/.+\//, "");
function extractStacktrace(e, offset) {
offset = offset === undefined ? 4 : offset;
share/js/core/qunit.js view on Meta::CPAN
// Store result when possible
if (storage) {
if (bad) {
storage.setItem("qunit-test-" + moduleName + "-" + testName, bad);
} else {
storage.removeItem("qunit-test-" + moduleName + "-" + testName);
}
}
// After emitting the js-reporters event we cleanup the assertion data to
// avoid leaking it. It is not used by the legacy testDone callbacks.
emit("testEnd", this.testReport.end(true));
this.testReport.slimAssertions();
runLoggingCallbacks("testDone", {
name: testName,
module: moduleName,
skipped: skipped,
todo: todo,
failed: bad,
passed: this.assertions.length - bad,
share/js/core/require-2.3.5.js view on Meta::CPAN
//define itself again. If already in the process
//of doing that, skip this work.
this.defining = true;
if (this.depCount < 1 && !this.defined) {
if (isFunction(factory)) {
//If there is an error listener, favor passing
//to that instead of throwing an error. However,
//only do it for define()'d modules. require
//errbacks should not be called for failures in
//their callbacks (#699). However if a global
//onError is set, use that.
if ((this.events.error && this.map.isDefine) ||
req.onError !== defaultOnError) {
try {
exports = context.execCb(id, factory, depExports, exports);
} catch (e) {
err = e;
}
} else {
exports = context.execCb(id, factory, depExports, exports);
share/js/core/require-2.3.5.js view on Meta::CPAN
context.enable(pluginMap, this);
this.pluginMaps[pluginMap.id] = pluginMap;
},
enable: function () {
enabledRegistry[this.map.id] = this;
this.enabled = true;
//Set flag mentioning that the module is enabling,
//so that immediate calls to the defined callbacks
//for dependencies do not trigger inadvertent load
//with the depCount still being zero.
this.enabling = true;
//Enable each dependency
each(this.depMaps, bind(this, function (depMap, i) {
var id, mod, handler;
if (typeof depMap === 'string') {
//Dependency needs to be converted to a depMap
share/js/core/require.js view on Meta::CPAN
//define itself again. If already in the process
//of doing that, skip this work.
this.defining = true;
if (this.depCount < 1 && !this.defined) {
if (isFunction(factory)) {
//If there is an error listener, favor passing
//to that instead of throwing an error. However,
//only do it for define()'d modules. require
//errbacks should not be called for failures in
//their callbacks (#699). However if a global
//onError is set, use that.
if ((this.events.error && this.map.isDefine) ||
req.onError !== defaultOnError) {
try {
exports = context.execCb(id, factory, depExports, exports);
} catch (e) {
err = e;
}
} else {
exports = context.execCb(id, factory, depExports, exports);
share/js/core/require.js view on Meta::CPAN
context.enable(pluginMap, this);
this.pluginMaps[pluginMap.id] = pluginMap;
},
enable: function () {
enabledRegistry[this.map.id] = this;
this.enabled = true;
//Set flag mentioning that the module is enabling,
//so that immediate calls to the defined callbacks
//for dependencies do not trigger inadvertent load
//with the depCount still being zero.
this.enabling = true;
//Enable each dependency
each(this.depMaps, bind(this, function (depMap, i) {
var id, mod, handler;
if (typeof depMap === 'string') {
//Dependency needs to be converted to a depMap