How to add noConflict to a JS module pattern? - module

I use the following pattern in my JS:
var lib =
{
module_one:
{
init: function () {
...
}
},
module_two:
{
init: function () {
...
}
}
};
Question is, whats the best way to add:
(function ($) {
...
})(jQuery);
I tried to put it around the var lib, but that didnt work. To add it inside each function worked, but seems a bit messy..?
Is it possible to add it to the init: function($) somehow?
Quite new on jQuery, so if you have any other suggestions around this pattern, let me know :-)

Basically, you can do this:
(function() {
var global, lib, oldlib;
// We call this anonymous scoping function directly, so we know that
// within it, `this` is the JavaScript global object. Grab a
// local reference to it so we can use it within functions that get
// called via dotted notation and so have different `this` values.
global = this;
// Remember any value that already exists for the `lib` property
// of the global
oldlib = global.lib;
// Define our lib, assigning it to a local variable
lib = {
/* ...your stuff as usual, plus: */
noConflict: function() {
global.lib = oldlib;
return lib;
}
};
// Publish our lib externally on the global object
global.lib = lib;
})();
...which can then be used like this:
var alias = lib.noConflict();
Here's how that works:
We define a scoping function and then immediately call it.
Within the scoping function, we grab the this value as a variable called global. This will be the JavaScript global object because of the way we're calling the scoping function. (The global object on browsers is window, but there's no need to limit this to browsers, hence getting global this way).
The first thing we do is save any old value the lib property of the global object had, in a local variable in our scoping function called oldlib.
We set up our new value for lib.
Our noConflict function restores the earlier value of the lib property, and returns our lib reference so someone can use it as an alias.
BTW, when you use a scoping function, you can also switch over to using named functions rather than anonymous ones, which has several benefits. Here's the above updated to use a named function for noConflict.
(function() {
var global, lib, oldlib;
// We call this anonymous scoping function directly, so we know that
// within it, `this` is the JavaScript global object. Grab a
// local reference to it so we can use it within functions that get
// called via dotted notation and so have different `this` values.
global = this;
// Remember any value that already exists for the `lib` property
// of the global
oldlib = global.lib;
// Define the functions for our lib. Because they're defined
// within our scoping function, they're completely private
function lib_noConflict() {
global.lib = oldlib;
return lib;
}
// Define our lib, publishing the functions we want to be public
lib = {
/* ...your stuff as usual, plus: */
noConflict: lib_noConflict
};
// Publish our lib externally on the global object
global.lib = lib;
})();

Related

Blockly How to create a Variable to the workspace (developer variable)

I want to create a Developer Variable to the workspace in Blockly, but I cannot find the necessary function/method.
I do not want to create the variable over a button. The variable should be included even if there is no block in the workspace.
With these two functions I can get the already created variables:
var variables = workspace.getAllVariables();
var dev_var = Blockly.Variables.allDeveloperVariables(workspace);
But what is the setting function?
Developer variables are variables that will never be visible to the user, but will exist in the generated code. If that's what you're looking for: there's no API for it, but here are some things you can do.
If you want to reserve the name so that users can't accidentally override your variable, call yourGenerator.addReservedWords('var1,var2,...'). You can initialize the variable in your wrapper code.
If you really want Blockly to both reserve and declare the variable for you, you could override the init function on your generator.
On the other hand, if what you want is a user-visible variable that always shows up in the toolbox, without the user creating it, you should call yourWorkspace.createVariable('variable_name').
The unit test blocks all assume that the variable unittestResults exists and can be written to. To indicate this, the block definition includes the function getDeveloperVars, which returns an array of strings. Each string is a variable name.Follow this issue in gtihub
Blockly.Blocks['unittest_fail'] = {
// Always assert an error.
init: function() {
this.setColour(65);
this.setPreviousStatement(true);
this.setNextStatement(true);
this.appendDummyInput()
.appendField(new Blockly.FieldTextInput('test name'), 'MESSAGE')
.appendField('fail');
this.setTooltip('Records an error.');
},
getDeveloperVars: function() {
return ['unittestResults'];
}
};
LINK : https://github.com/google/blockly/issues/1535

Mocha and jsdom - How to set a window variable

I know you're not supposed to do this, but I'm trying to write some tests with legacy code still using requirejs that have a few window variables floating around.
Basically I'm trying to write a mocha test and include some predefined global variables that a different file would use later. I'm trying to do the following, but it seems the global variable "container" isn't populated when accessing it later.
global.document = require('jsdom').jsdom('<html></html>');
global.window = document.defaultView;
global.$ = require('jquery')(window);
// this should be available everywhere as far as I can tell...
global.container= {};
global.window.container= global.container;
// legacy scripts still using requirejs, so we need to load the require config here
var requirejs = require('testing-setup').requirejs;
// chai is nice
require('chai').should();
describe('model tests', function () {
var model;
// before we begin the tests, we need to require in all the necessary modules
before(function (done) {
window.container= {
dateFormat: false
};
requirejs(['Model', 'common', 'date'], function (Model) {
// load some dummy data out of a file
model= new Model(require('./test-data.js').item);
done();
});
});
// run some more tests down here, I'll spare you those
});
The script being loaded called "common" above has a reference to the global "container" object that lives on the window. Apparently what I have is not correct. Is there no way to set up a shared global variable in jsdom? I know it's not the standard way of doing things, so please spare the lectures. Refactoring all that legacy code right now is not really a feasible option.
Ah, it turns out this is the correct way of doing it. It appears the jsdom/nodejs differentiate the difference between window and global. If you want something to be available everywhere in every file in that session, it needs to be on the global namespace. The window is explicitly window.

How to address internal module when a name conflict exists in TypeScript

In my TypeScript project (using only internal modules), I want to include polyfills/extension for an existing library. For this example, I will use the RxJS library but the question/problem is not specific to this library.
The following code is what I came up with:
module MyModule.Rx {
Rx.Observable.prototype.myExtension = function() { /* ... */ };
}
The RxJS definitions (.d.ts files) are used and compiled together with the code. This leads to the following compiler error: 2339 Property 'Observable' does not exist on type 'typeof Rx'
As far as I can tell this happens because I used the same Rx identifier in MyModule.Rx. When switching the namespace in the first line to module MyModule.NotRx { everything works fine - the Observable type is correctly looked up from the RxJS .d.ts file.
So it seems that the names MyModule.Rx and the RxJS declared Rx namespaces are in conflict. I know that I could simply rename my namespace to MyModule.SomethingElse but that seems somewhat of a hack.
Having all polyfills/extensions for Rx in the MyModue.Rx namespace seems a natural choice for me - how can this be done in a clean way?
You can't do that.
Take this code in TypeScript:
var B = 'test';
module A.B {
// Declare a function
export function fn() {
}
// Tests
console.log(B); // Object { }
A.B.fn(); // valid
B.fn(); // valid
fn(); // valid
}
The message displayed in the console is: Object { } and not test. Look at the transpiled code:
var B = 'test'; // root scope
var A;
(function (A) {
var B; // same name, hide the root scope one
(function (B) {
// Declare a function
function fn() {
}
B.fn = fn;
// Tests
console.log(B); // Object { }
A.B.fn(); // valid
B.fn(); // valid
fn(); // valid
})(B = A.B || (A.B = {}));
})(A || (A = {}));
The module A.B is transpiled to two JavaScript variables A and B. We can use them in order to access to the exported members of the module: the function fn is accessible from A.B.fn, B.fn and fn. In the module, the variable B from the root scope is hidden by the variable B of the module.
You can't access to a global variable Rx from a module named Rx.
As mentioned by Tarh you cannot refer to an outer module if its been shadowed by a local variable. I've +1ed his answer and that should be the accepted answer. I'll just leave a few workarounds:
One workaround which you already know is to rename MyModule.Rx to something that doesn't have Rx. An alternative is to capture Rx with some other name:
import OrigRx = Rx;
module MyModule.Rx {
OrigRx.Observable.prototype.myExtension = function() { /* ... */ };
}
This is very similar to https://stackoverflow.com/a/29021964/390330

How to override dojo's domReady

I want to override dijit._CssStateMixin's domReady() method.
Is there any way to override that instead of changing the listener mechanism in Dojo.
I tried overriding _cssMouseEvent() method in simple javascript, but it still does invoke dijit's _cssMouseEvent() from domReady().
I have tried following approach:
dojoConfig = {
map: {
'dijit/_CssStateMixin': {
'dojo/domReady': 'app/noop'
}
}
};
I have added 'app' folder and then 'noop.js' inside that.
noop.js has nothing in it:
define([], function () {
return function () {};
});
Even after this I can see that dijit.js's _CssStateMaxin domReady() getting called from listener.apply (code snippet pasted below)
var addStopImmediate = function(listener){
return function(event){
if(!event.immediatelyStopped){// check to make sure it hasn't been stopped immediately
event.stopImmediatePropagation = stopImmediatePropagation;
return listener.apply(this, arguments);
}
};
}
If your ultimate goal is to prevent the domReady callback in dijit/_CssStateMixin from running, your simplest bet is likely to re-map dojo/domReady to a different module that doesn't call the callback at all, when loaded via dijit/_CssStateMixin.
NOTE: Stripping out these handlers might have adverse visual effects on Dijit widgets which inherit _CssStateMixin, since it may hinder the application of Dijit CSS classes related to hover and focus. But if your concern is that _CssStateMixin is hampering performance, it may at least be worth a try to confirm or deny your suspicion.
First we have to create a simple module that returns a function that does nothing, which we will later substitute for dojo/domReady when loaded by dijit/_CssStateMixin, so that it can still call domReady but it won't execute the callback it passes.
For simplicity's sake I'll assume you already have a custom package that you can easily add a module to; for this example I'll assume it's called app. Let's create app/noop:
define([], function () {
return function () {};
});
Now let's configure the loader to map app/noop in place of dojo/domReady specifically when loaded by dijit/_CssStateMixin:
var dojoConfig = {
...,
map: {
'dijit/_CssStateMixin': {
'dojo/domReady': 'app/noop'
}
},
...
};
Now the offending domReady callback should no longer be run.
If you're curious about map, you can read more about it in this SitePen FAQ.

Dojo 1.7 how to use dojo components outside of require()

I have created Dojo widget like below using AMD loader in Dojo 1.7.2
var myCpane;
require([
"dijit/layout/ContentPane"
], function(ContentPane) {
myCpane = new ContentPane();
});
myCpane.startup(); // It gives 'myCpane' as undefined
In the above example, in the last statment, the variable 'myCpane' is coming as 'undefined', if I use the 'myCpane.startup()' inside the 'require()' callback function then, it will work fine.
But I want to use that 'myCpane' variable on outside of the 'require' function (for many reasons). I know the 'require()' callback function execution delayed due to the component loading process by Dojo.
My question is,
How to block the 'require()' function until it completes to execute it's callback function.
So the variable 'myCpane' will not be 'undefined' when the control come out from the 'require()' function
===========================================================
To overcome this issue, I have written a small function to load the modules and wait until the module load complete
LoadModule: function(modulePath) { // modulePath = "dijit/layout/ContentPane"
var moduleObject = undefined;
require({async: false}, [modulePath], function(getModuleObject) {
moduleObject = getModuleObject;
});
// Wait until the module loads completes
while(moduleObject === undefined);
// Return the loaded module.
return moduleObject;
}
The output of the function is always executing the while loop, the control never comes inside of 'require()'s callback function to set the value to the variable "moduleObject".
When the 'require()' function will call it's callback function? I have verified using the browser debugger window the file 'ContentPane.js' is loaded properly, but the callback function is not called, If I comment the while loop then, the callback is called properly.
When the control will come inside of the callback function in my case ?
I'm not sure what are you about to achieve, but it looks for me like a programming anti-pattern. Anyway you can achieve this via dojo/_base/Deferred:
require(["dojo/_base/Deferred"], function(Deferred) {
var deferred = new Deferred();
require(["dijit/layout/ContentPane"], function(ContentPane) {
var myCpane = new ContentPane();
deferred.resolve(myCpane); //resolve, i.e. call `then` callback
});
deferred.then(function(myCpane) {
console.log(myCpane);
myCpane.startup();
});
});​
Mess with it at jsFiddle: http://jsfiddle.net/phusick/HYQEd/
I would also suggest you consider one of these two strategies to achieve the same:
Give the ContentPane an id and obtain its reference via dijit's registry.byId().
Create ContentPane instance in a separate module and expose it as a return value of that module:
// file: myCpane.js
define(["dijit/layout/ContentPane"], function(ContentPane) {
var myCpane = new ContentPane();
return myCpane;
});
// file: main.js
require(["./myCpane"], function(myCpane) {
myCpane.startup();
});
I think this goes more to scope issue then amd loader question; consider
var x;
function foo() {
x = { bar : 1 };
}
// you wouldn't expect to have reference to x variable here
if(typeof x.bar == "undefined") console.log(x);
// foo() is called at a random time - or in dojo loader case, when modules are present
foo();
console.log(x.bar); // oohh now its there ^^
x in this case translates to your myCpane, which is declared as variable (var $$) inside a function, the function that is callback for when loader is done requireing modules.
The Deferred is a nice handler for this as stated below. A slight overhead though, if youre allready in a detached (async) function flow. For full control, look into require() you could do this as well:
var myCpane;
require({ async: false }, [
"dijit/layout/ContentPane"
], function(ContentPane) {
myCpane = new ContentPane();
});
// require does not return until module loading is done and callback executed
myCpane.startup();