Skip to content

Instantly share code, notes, and snippets.

@LeonardoCiaccio
Last active October 2, 2017 16:40
Show Gist options
  • Save LeonardoCiaccio/f6f89b4d67da704ab6c32cff28195f01 to your computer and use it in GitHub Desktop.
Save LeonardoCiaccio/f6f89b4d67da704ab6c32cff28195f01 to your computer and use it in GitHub Desktop.
Anatomia di una classe
/*
( IT ) -->
Modulo globale, qui vengono aggiunti i nuovi elementi con le regole definite
window[ "Grab Any Media" ].patch( { // manifest
minVersion : "x.x.x.x"
}, function( _ ){ // ( IT ) <-- Modifica gli accessori protetti
// ( IT ) --> 'this' = window[ "Grab Any Media" ], '_' = accessori protetti modificabili
} ).extend( { // manifest
minVersion : "x.x.x.x"
,name : "myname"
,overwrite : true
,parent : null // <-- opzionale
}, function( _ ){ // ( IT ) <-- Estende window[ "Grab Any Media" ]
// ( IT ) --> 'this' = window[ "Grab Any Media" ], '_' = accessori protetti NON modificabili
// cambiano se modificati dalla 'patch'
} ).fn( { // manifest
minVersion : "x.x.x.x"
,name : "myname"
,overwrite : true
,parent : null // <-- opzionale
}, function( _ ){ // ( IT ) <-- Estende le istanze
// ( IT ) --> 'this' = window[ "Grab Any Media" ], '_' = accessori protetti NON modificabili
// cambiano se modificati dalla 'patch'
} );
( EN ) -->
Please fork and translate ...
*/
( function(){
"use strict";
// --> Test Browser
( function(){
try{
var x = JSON.stringify( {} ).trim();
}catch( e ){
throw new Error( "Grab Any Media browser check fail" );
}
} )();
// <-- Test Browser
// --> Polyfill
if( typeof Object.assign != "function" ){
Object.defineProperty( Object, "assign", {
enumerable : false
,configurable : true
,writable : true
,value : function( target, firstSource ){
"use strict";
if( target === undefined || target === null )
throw new TypeError( "_.merge : Cannot convert first argument to object" );
var to = Object( target );
for( var i = 1; i < arguments.length; i++ ){
var nextSource = arguments[ i ];
if( nextSource === undefined || nextSource === null )
continue;
nextSource = Object( nextSource );
var keysArray = Object.keys( Object( nextSource ) );
for( var nextIndex = 0, len = keysArray.length; nextIndex < len; nextIndex++ ){
var nextKey = keysArray[ nextIndex ];
var desc = Object.getOwnPropertyDescriptor( nextSource, nextKey );
if( desc !== undefined && desc.enumerable )to[nextKey] = nextSource[nextKey];
}
}
return to;
}
} );
} // <-- Object.assign
if (typeof Object.create != "function" ){
Object.create = (function() {
var Object = function() {};
return function( prototype ){
if( arguments.length > 1 )
throw Error( "Object.create : Second argument not supported" );
if( typeof prototype != "object" )
throw TypeError( "Object.create : Argument must be an object" );
Object.prototype = prototype;
var result = new Object();
Object.prototype = null;
return result;
};
} )();
} // <-- Object.create
if( typeof Array.isArray != "function" ){
Array.isArray = function( arg ){
return Object.prototype.toString.call( arg ) === "[object Array]";
};
}
if( typeof Object.isObject != "function" ){
Object.isObject = function( arg ){
return Object.prototype.toString.call( arg ) === "[object Object]";
};
}
// <-- Polyfill
var
// ( IT ) --> Protetto
_ = {
v : "1.0.0.0"
,cleanVersion : function( version ){
version = _.cleanString( version );
return ( !version.match( /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/gi ) )
? ""
: version
;
}
,is : function( type, what ){
return ( typeof type === "string" && typeof what === type );
}
,isObj : function( obj ){
return Object.isObject( obj );
}
,isArray : function( arr ){
return Array.isArray( arr );
}
,isNoEmptyString : function( text ){
return ( this.is( "string", text ) && text.trim().length > 0 );
}
,cleanString : function( text ){
return ( this.isNoEmptyString( text ) ) ? text.trim() : "";
}
,cleanMerge : function( newobj, objproto ){
// ( IT ) --> 'objproto' segna le regole dell'oggetto risultante, sia la chiave che il tipo di valore
if( !this.isObj( newobj ) || !this.isObj( objproto ) )return null;
var cleaned = {};
for( var key in newobj ){
if( objproto.hasOwnProperty( key ) )
cleaned[ key ] = ( this.isObj( newobj[ key ] ) )
? this.cleanMerge( newobj[ key ], objproto[ key ] )
: ( this.is( typeof newobj[ key ], objproto[ key ] ) ) ? newobj[ key ] : objproto[ key ]
;
}
return Object.assign( {}, objproto, cleaned );
}
,merge : function( objTarget, objMerge ){
// ( IT ) --> 'objMerge' precedenza su 'objTarget' se trovate key uguali
return Object.assign( objTarget, objMerge );
}
,debug : function( mex, name ){
if( !( mex = _.cleanString( mex ) ) || _debug !== true )return false;
if( name = _.cleanString( name ) ){
name = "'" + name + "'";
mex = " " + mex;
}
mex = " [ " + _session + " ] " + new Date().toLocaleString() + " : " + name + mex;
console.log( mex );
return true;
}
,extend : function( who, bindto, manifest, fn ){
if( !this.is( "function", who ) && !this.isObj( who ) )
throw new Error( "Grab Any Media : '_.extend' require 'objects/function' for 'who'" );
if( !this.is( "function", bindto ) )
throw new Error( "Grab Any Media : '_.extend' require 'function' for 'bindto'" );
if( !this.is( "function", fn ) && !this.isObj( fn ) )
throw new Error( "Grab Any Media : '_.extend' require 'function' or 'object' param" );
if( !this.isObj( manifest ) )
throw new Error( "Grab Any Media : '_.extend' require 'manifest' object param" );
var minversion = this.cleanVersion( manifest.minVersion );
if( !minversion || this.v < minversion )
throw new Error( "Grab Any Media : manifest 'minVersion' current " + this.v );
if( !( manifest.name = this.cleanString( manifest.name ) ) )
throw new Error( "Grab Any Media : manifest 'name' required" );
if( !this.is( "boolean", manifest.overwrite ) )
throw new Error( "Grab Any Media : manifest 'overwrite' required" );
if( !manifest.overwrite && !this.is( "undefined", who[ manifest.name ] ) )return false;
var new_ = Object.create( _ );
if( !manifest.parent ){
who[ manifest.name ] = ( this.isObj( fn ) ) ? fn : fn.bind( bindto, new_ );
}else if( this.is( "function", manifest.parent ) || this.isObj( manifest.parent ) ){
manifest.parent[ manifest.name ] = ( this.isObj( fn ) ) ? fn : fn.bind( bindto, new_ );
}else{
throw new Error( "Grab Any Media : 'extend/fn' require 'function' or 'object' param for manifest 'parent'" );
}
return true;
}
}
,_debug = false
,_session = Date.now()
// ( IT ) --> Pubblico
,_p = function( config ){
if( !( this instanceof _p ) )return new _p( config );
/*
( IT ) --> 'this.config' modificabile dalle nuove istanze come oggetto : .config
dalla classe come funzione : ...().config ovviamente non modificabile
*/
this.config = this.config || {};
if( _.isObj( config ) )this.config = _.merge( this.config, config );
return this;
}
;
// ( IT ) --> Condiviso, non accessibile dalle nuove istanze
_p.debug = function( flag ){
_debug = !!flag;
return _p;
};
_p.patch = function( manifest, fn ){ // ( IT ) <-- Intervento diretto sulle funzioni protette
if( !_.is( "function", fn ) )
throw new Error( "Grab Any Media : 'patch' require 'function' param" );
if( !_.isObj( manifest ) )
throw new Error( "Grab Any Media : 'patch' require 'manifest' object param" );
var minversion = _.cleanVersion( manifest.minVersion );
if( !minversion || _.v < minversion )
throw new Error( "Grab Any Media : manifest 'minVersion' current " + _.v );
var old_ = _.merge( {}, _ );
fn.bind( _p, _ ).call();
var version = _.cleanVersion( _.v );
if( !version || version < old_.v ){
_ = old_;
throw new Error( "Grab Any Media : 'patch' require >= version, current " + _.v );
}
return _p;
};
_p.extend = function( manifest, fn ){
_.extend( _p, _p, manifest, fn );
return _p;
};
_p.fn = function( manifest, fn ){
_.extend( _p.prototype, _p, manifest, fn );
return _p;
};
// ( IT ) --> Visibile solo dalle nuove istanze, prototype
// --> TODO
// ( IT ) --> Disponibile
window[ "Grab Any Media" ] = _p;
// ( IT ) --> Da questo momento le modifiche solo con 'patch' ed estensioni
} )();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment