Skip to content

Instantly share code, notes, and snippets.

@a1ee9b
Last active January 4, 2016 04:39
Show Gist options
  • Save a1ee9b/8570159 to your computer and use it in GitHub Desktop.
Save a1ee9b/8570159 to your computer and use it in GitHub Desktop.
ValuePlease provides access to an object everywhere.
/*
* ValuePlease
*
* Make objects accessible everywhere. Independently from encapsulation.
*
* Supports all major browsers in the current version.
*
* VERY EARLY STAGE. SHOULD BE TESTED INTENSIVELY.
*
* MIT-License
*/
/*
* Legacy support <IE10
*/
(function () {
function CustomEvent ( event, params ) {
params = params || { bubbles: false, cancelable: false, detail: undefined };
var evt = document.createEvent( 'CustomEvent' );
evt.initCustomEvent( event, params.bubbles, params.cancelable, params.detail );
return evt;
};
CustomEvent.prototype = window.CustomEvent.prototype;
window.CustomEvent = CustomEvent;
})();
/*
* Call this function on any object to provide the object
* for the given event.
*
* @String eventName use a unique name for the event;
* you may want to use namespaces e.g. obj1:var3
*/
Object.prototype.provide = function ( eventName ) {
var handleRequest = function( e ) {
document.dispatchEvent(
new CustomEvent(
eventName + "_answer",
{"detail": { "value": this.valueOf() } }
)
)
};
document.addEventListener( eventName + "_request", handleRequest.bind(this) );
return this;
};
/*
* Request a value that is provided by the given event name
*
* @String eventName the same event name the wanted object used
* when calling "provide"
*/
Object.prototype.request = function ( eventName ) {
this.val = null;
var returnResult = function ( e ) {
this.val = e.detail.value;
};
document.addEventListener( eventName + "_answer", returnResult.bind(this) );
document.dispatchEvent( new CustomEvent( eventName + "_request" ) );
return this.val;
};
/*
* Example:
* We create an standalone object "obj1" holding the variable "val".
* "val" is only reachable from within obj1 but we want a simple way
* to access it without the need to address obj1 directly, e.g. from
* an encapsulated module.
* So we provide access to the variable "val" from everywhere. To
* request "val" just call "Object.request( 'obj1:val' );" anywhere.
*
* BEWARE: Changes within the object are propagated but after reassigning
* a different object to "val" this object has to call "provide" again.
*/
var obj1 = function obj1 () {
var val = {
a: "bar",
b: "foo"
};
val.provide( 'obj1:val' );
return {
setA: function ( v ) {
val.a = v;
},
setB: function( v ) {
val.b = v;
},
get: function () {
return val;
}
}
}();
// not accessable => undefined
console.log( obj1.val );
/*
* Example on how to access "val" from within another object.
* "Object.request( 'obj1:val' )" returns "val". Request
* can be called on any object.
*/
var obj2 = {
getValue: function () {
// create and dispatch the event
var tmp = Object.request( 'obj1:val' );
console.log( tmp ); // just for presentation purpose
return tmp;
}
}
// { a: "bar", b: "foo" };
obj2.getValue();
// set a to "foo"
obj1.setA( "foo" );
// { a: "foo", b: "foo" };
obj2.getValue();
// set b to "bar"
obj1.setB( "bar" );
// { a: "foo", b: "bar" };
obj2.getValue();
// add c to "val"
obj1.get().c = "foo";
// { a: "foo", b: "bar", c: "foo" };
obj2.getValue();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment