mirror of
https://github.com/flynx/pWiki.git
synced 2025-10-29 10:00:08 +00:00
updated local deps...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
6655d985ec
commit
113084652f
1706
lib/actions.js
1706
lib/actions.js
File diff suppressed because it is too large
Load Diff
1276
lib/features.js
1276
lib/features.js
File diff suppressed because it is too large
Load Diff
627
lib/object.js
627
lib/object.js
@ -1,50 +1,403 @@
|
||||
/**********************************************************************
|
||||
*
|
||||
* object.js
|
||||
*
|
||||
* Repo and docs:
|
||||
* https://github.com/flynx/object.js
|
||||
*
|
||||
*
|
||||
* XXX should this extend Object???
|
||||
* ...if yes then it would also be logical to move Object.run(..)
|
||||
* here...
|
||||
*
|
||||
**********************************************************************/
|
||||
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)(
|
||||
function(require){ var module={} // makes module AMD/node compatible...
|
||||
((typeof define)[0]=='u'?function(f){module.exports=f(require)}:define)
|
||||
(function(require){ var module={} // make module AMD/node compatible...
|
||||
/*********************************************************************/
|
||||
// Helpers...
|
||||
|
||||
var TAB_SIZE =
|
||||
module.TAB_SIZE = 4
|
||||
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
|
||||
// Make a JavaScrip object constructor...
|
||||
// Normalize indent...
|
||||
//
|
||||
// normalizeIndent(text)
|
||||
// -> text
|
||||
//
|
||||
//
|
||||
// This will remove common indent from each like of text, this is useful
|
||||
// for printing function code of functions that were defined at deep
|
||||
// levels of indent.
|
||||
//
|
||||
// NOTE: this will trim out both leading and trailing white-space.
|
||||
//
|
||||
// XXX is this the right place for this???
|
||||
// ...when moving take care that ImageGrid's core.doc uses this...
|
||||
var normalizeIndent =
|
||||
module.normalizeIndent =
|
||||
function(text, tab_size){
|
||||
tab_size = tab_size || TAB_SIZE
|
||||
text = tab_size > 0 ?
|
||||
text.replace(/\t/g, ' '.repeat(tab_size))
|
||||
: text
|
||||
var lines = text.split(/\n/)
|
||||
var l = lines
|
||||
.reduce(function(l, e, i){
|
||||
var indent = e.length - e.trimLeft().length
|
||||
return e.trim().length == 0
|
||||
// ignore 0 indent of first line...
|
||||
|| (i == 0 && indent == 0) ? l
|
||||
: l < 0 ?
|
||||
indent
|
||||
: Math.min(l, indent)
|
||||
}, -1)
|
||||
return lines
|
||||
.map(function(line, i){
|
||||
return i == 0 ?
|
||||
line
|
||||
: line.slice(l) })
|
||||
.join('\n')
|
||||
.trim() }
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Prototype chain content access...
|
||||
|
||||
// Get a list of source objects for a prop/attr name...
|
||||
//
|
||||
// sources(obj, name)
|
||||
// sources(obj, name, callback)
|
||||
// -> list
|
||||
// -> []
|
||||
//
|
||||
// callback(obj)
|
||||
// -> true | 'stop'
|
||||
// -> ..
|
||||
//
|
||||
//
|
||||
// The callback(..) is called with each matching object.
|
||||
//
|
||||
// The callback(..) can be used to break/stop the search, returning
|
||||
// a partial list og matcges up untill and including the object
|
||||
// triggering the stop.
|
||||
//
|
||||
//
|
||||
// NOTE: this go up the prototype chain, not caring about any role (
|
||||
// instance/class or instance/prototype) bounderies and depends
|
||||
// only on the object given as the starting point.
|
||||
// It is possible to start the search from this, thus checking
|
||||
// for any overloading in the instance, though this approach is
|
||||
// not very reusable....
|
||||
// NOTE: this will not trigger any props...
|
||||
var sources =
|
||||
module.sources =
|
||||
function(obj, name, callback){
|
||||
var stop
|
||||
var res = []
|
||||
do {
|
||||
if(obj.hasOwnProperty(name)){
|
||||
res.push(obj)
|
||||
// handle callback...
|
||||
stop = callback
|
||||
&& callback(obj)
|
||||
// stop requested by callback...
|
||||
if(stop === true || stop == 'stop'){
|
||||
return res }
|
||||
}
|
||||
obj = obj.__proto__
|
||||
} while(obj !== null)
|
||||
return res }
|
||||
|
||||
|
||||
// Find the next parent attribute in the prototype chain.
|
||||
//
|
||||
// Get parent attribute value...
|
||||
// parent(proto, name)
|
||||
// -> value
|
||||
// -> undefined
|
||||
//
|
||||
// Get parent method...
|
||||
// parent(method, this)
|
||||
// -> meth
|
||||
// -> undefined
|
||||
//
|
||||
//
|
||||
// The two forms differ in:
|
||||
// - in parent(method, ..) a method's .name attr is used for name.
|
||||
// - in parent(method, ..) the containing prototype is inferred.
|
||||
//
|
||||
// NOTE: there are cases where method.name is not set (e.g. anonymous
|
||||
// function), so there a name should be passed explicitly...
|
||||
// NOTE: when passing a method it is recommended to pass an explicit
|
||||
// reference to it relative to the constructor, i.e.:
|
||||
// Constructor.prototype.method
|
||||
// this will avoid relative resolution loops, for example:
|
||||
// this.method
|
||||
// deep in a chain will resolve to the first .method value visible
|
||||
// from 'this', i.e. the top most value and not the value visible
|
||||
// from that particular level...
|
||||
//
|
||||
//
|
||||
// Example:
|
||||
// var X = object.Constructor('X', {
|
||||
// __proto__: Y.prototype,
|
||||
//
|
||||
// attr: 123,
|
||||
//
|
||||
// method: function(){
|
||||
// // get attribute...
|
||||
// var a = object.parent(X.prototype, 'attr')
|
||||
//
|
||||
// // get method...
|
||||
// var ret = object.parent(X.prototype.method, this)
|
||||
// .call(this, ...arguments)
|
||||
//
|
||||
// // ...
|
||||
// }
|
||||
// })
|
||||
//
|
||||
//
|
||||
// NOTE: in the general case this will get the value of the returned
|
||||
// property/attribute, the rest of the way passive to props.
|
||||
// The method case will get the value of every method from 'this'
|
||||
// and to the method after the match.
|
||||
// NOTE: this is super(..) replacement, usable in any context without
|
||||
// restriction -- super(..) is restricted to class methods only...
|
||||
var parent =
|
||||
module.parent =
|
||||
function(proto, name){
|
||||
// special case: method...
|
||||
if(typeof(name) != typeof('str')){
|
||||
that = name
|
||||
name = proto.name
|
||||
// get first matching source...
|
||||
proto = sources(that, name,
|
||||
function(obj){ return obj[name] === proto })
|
||||
.pop() }
|
||||
// get first source...
|
||||
var res = sources(proto, name,
|
||||
function(obj){ return 'stop' })
|
||||
.pop()
|
||||
return res ?
|
||||
// get next value...
|
||||
res.__proto__[name]
|
||||
: undefined }
|
||||
|
||||
|
||||
// Find the next parent property descriptor in the prototype chain...
|
||||
//
|
||||
// parentProperty(proto, name)
|
||||
// -> prop-descriptor
|
||||
//
|
||||
//
|
||||
// This is like parent(..) but will get a property descriptor...
|
||||
//
|
||||
var parentProperty =
|
||||
module.parentProperty =
|
||||
function(proto, name){
|
||||
// get second source...
|
||||
var c = 0
|
||||
var res = sources(proto, name,
|
||||
function(obj){ return c++ == 1 })
|
||||
.pop()
|
||||
return res ?
|
||||
// get next value...
|
||||
Object.getOwnPropertyDescriptor(res, name)
|
||||
: undefined }
|
||||
|
||||
|
||||
// Find the next parent method and call it...
|
||||
//
|
||||
// parentCall(proto, name, this, ...)
|
||||
// parentCall(meth, this, ...)
|
||||
// -> res
|
||||
// -> undefined
|
||||
//
|
||||
//
|
||||
// This also gracefully handles the case when no higher level definition
|
||||
// is found, i.e. the corresponding parent(..) call will return undefined
|
||||
// or a non-callable.
|
||||
//
|
||||
// NOTE: this is just like parent(..) but will call the retrieved method,
|
||||
// essentially this is a shorthand to:
|
||||
// parent(proto, name).call(this, ...)
|
||||
// or:
|
||||
// parent(method, this).call(this, ...)
|
||||
// NOTE: for more docs see parent(..)
|
||||
var parentCall =
|
||||
module.parentCall =
|
||||
function(proto, name, that, ...args){
|
||||
var meth = parent(proto, name)
|
||||
return meth instanceof Function ?
|
||||
meth.call(...( typeof(name) == typeof('str') ?
|
||||
[...arguments].slice(2)
|
||||
: [...arguments].slice(1) ))
|
||||
: undefined }
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Mixin utils...
|
||||
// XXX should we add mixout(..) and friends ???
|
||||
|
||||
// Mix a set of methods/props/attrs into an object...
|
||||
//
|
||||
// mixinFlat(root, object, ...)
|
||||
// -> root
|
||||
//
|
||||
//
|
||||
// NOTE: essentially this is just like Object.assign(..) but copies
|
||||
// properties directly rather than copying property values...
|
||||
var mixinFlat =
|
||||
module.mixinFlat =
|
||||
function(root, ...objects){
|
||||
return objects
|
||||
.reduce(function(root, cur){
|
||||
Object.keys(cur)
|
||||
.map(function(k){
|
||||
Object.defineProperty(root, k,
|
||||
Object.getOwnPropertyDescriptor(cur, k)) })
|
||||
return root }, root) }
|
||||
|
||||
|
||||
// Mix sets of methods/props/attrs into an object as prototypes...
|
||||
//
|
||||
// mixin(root, object, ...)
|
||||
// -> root
|
||||
//
|
||||
//
|
||||
// This will create a new object per set of methods given and
|
||||
// mixinFlat(..) the method set into this object leaving the
|
||||
// original objects intact.
|
||||
//
|
||||
// root <-- object1_copy <-- .. <-- objectN_copy
|
||||
//
|
||||
var mixin =
|
||||
module.mixin =
|
||||
function(root, ...objects){
|
||||
return objects
|
||||
.reduce(function(res, cur){
|
||||
return module.mixinFlat(Object.create(res), cur) }, root) }
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------
|
||||
// Constructor...
|
||||
|
||||
// Make an uninitialized instance object...
|
||||
//
|
||||
// makeRawInstance(context, constructor, ...)
|
||||
// -> instance
|
||||
//
|
||||
//
|
||||
// This will:
|
||||
// - construct an object
|
||||
// - if .__new__(..) is defined
|
||||
// -> call and use its return value
|
||||
// - if prototype is a function or if .__call__(..) is defined
|
||||
// -> use a wrapper function
|
||||
// - else
|
||||
// -> use {}
|
||||
// - link the object into the prototype chain
|
||||
//
|
||||
//
|
||||
// This will not call .__init__(..)
|
||||
//
|
||||
//
|
||||
// NOTE: context is only used when passeding to .__new__(..) if defined,
|
||||
// and is ignored otherwise...
|
||||
// NOTE: as this is simply an extension to the base JavaScript protocol this
|
||||
// can be used to construct any object...
|
||||
// Example:
|
||||
// var O = function(){}
|
||||
// // new is optional...
|
||||
// var o = new makeRawInstance(null, O)
|
||||
// NOTE: .__new__(..) is intentionaly an instance method (contary to
|
||||
// Python) this is done because there are no classes in JS and
|
||||
// adding and instance constructor as a class method would create
|
||||
// unneccessary restrictions both on the "class" object and on the
|
||||
// instance...
|
||||
//
|
||||
// XXX Q: should the context (this) in .__new__(..) be _constructor or
|
||||
// .prototype???
|
||||
// ... .prototype seems to be needed more often but through it we
|
||||
// can't reach the actual constructor... but on the other hand we
|
||||
// can (should?) always explicitly use it -- .__new__(..) is usually
|
||||
// in the same scope + this makes it more reusable for chaining
|
||||
// .__new__(..) calls...
|
||||
// ...currently it's .prototype...
|
||||
var makeRawInstance =
|
||||
module.makeRawInstance =
|
||||
function(context, constructor, ...args){
|
||||
var _mirror_doc = function(func, target){
|
||||
Object.defineProperty(func, 'toString', {
|
||||
value: function(...args){
|
||||
return target.toString(...args) },
|
||||
enumerable: false,
|
||||
})
|
||||
return func }
|
||||
|
||||
var obj =
|
||||
// prototype defines .__new__(..)...
|
||||
constructor.prototype.__new__ instanceof Function ?
|
||||
constructor.prototype.__new__(context, ...args)
|
||||
// callable instance -- prototype is a function...
|
||||
// NOTE: we need to isolate the .prototype from instances...
|
||||
: constructor.prototype instanceof Function ?
|
||||
_mirror_doc(
|
||||
function(){
|
||||
return constructor.prototype
|
||||
.call(obj, this, ...arguments) },
|
||||
constructor.prototype)
|
||||
// callable instance -- prototype defines .__call__(..)...
|
||||
// NOTE: we need to isolate the .__call__ from instances...
|
||||
: constructor.prototype.__call__ instanceof Function ?
|
||||
_mirror_doc(
|
||||
function(){
|
||||
return constructor.prototype.__call__
|
||||
.call(obj, this, ...arguments) },
|
||||
constructor.prototype.__call__)
|
||||
// default object base...
|
||||
: {}
|
||||
|
||||
// link to prototype chain...
|
||||
obj.__proto__ = constructor.prototype
|
||||
Object.defineProperty(obj, 'constructor', {
|
||||
value: constructor,
|
||||
enumerable: false,
|
||||
})
|
||||
|
||||
return obj }
|
||||
|
||||
|
||||
// Make an object constructor function...
|
||||
//
|
||||
// Make a constructor with an object prototype...
|
||||
// makeConstructor(<name>, <proto>)
|
||||
// -> constructor
|
||||
//
|
||||
// Make a constructor with an init function prototype...
|
||||
// makeConstructor(<name>, <init-func>)
|
||||
// Constructor(name, proto)
|
||||
// -> constructor
|
||||
//
|
||||
// Make a constructor with a prototype (object/function) and a class
|
||||
// prototype...
|
||||
// makeConstructor(<name>, <proto>, <class-proto>)
|
||||
// makeConstructor(<name>, <init-func>, <class-proto>)
|
||||
// Constructor(name, class-proto, proto)
|
||||
// -> constructor
|
||||
// NOTE: the <class-proto> defines a set of class methods and
|
||||
// attributes.
|
||||
//
|
||||
//
|
||||
//
|
||||
// The resulting constructor can produce objects in one of these ways:
|
||||
//
|
||||
// Basic constructor use...
|
||||
// constructor()
|
||||
// Create instance...
|
||||
// constructor(..)
|
||||
// new constructor
|
||||
// new constructor()
|
||||
// new constructor(..)
|
||||
// -> instance
|
||||
//
|
||||
// Pass arguments to the constructor...
|
||||
// constructor(<arg>[, ...])
|
||||
// new constructor(<arg>[, ...])
|
||||
// -> instance
|
||||
// Create raw/uninitialized instance...
|
||||
// constructor.__rawinstance__(..)
|
||||
// makeRawInstance(null, constructor, ..)
|
||||
// -> raw-instance
|
||||
//
|
||||
//
|
||||
// All produced objects are instances of the constructor
|
||||
@ -53,28 +406,65 @@ function(require){ var module={} // makes module AMD/node compatible...
|
||||
//
|
||||
//
|
||||
//
|
||||
// Init protocol:
|
||||
// 1) the base instance object is prepared (.__proto__ is set)
|
||||
// 2) if <init-func> is present, then it is called with instance as
|
||||
// context and passed the constructor arguments
|
||||
// 3) if <proto>.__init__(..) is present, it is called with the instance
|
||||
// as context and passed the constructor arguments.
|
||||
// Create and initialization protocol:
|
||||
// 1) raw instance is created:
|
||||
// a) constructor.__rawinstance__(..) / makeRawInstance(..) called:
|
||||
// - call .__new__(..) if defined and get return value as
|
||||
// instance, or
|
||||
// - if .__call__(..) defined or prototype is a function, wrap
|
||||
// it and use the wrapper function as instance, or
|
||||
// - create an empty object
|
||||
// b) instance linked to prototype chain
|
||||
// set .__proto__ to constructor.prototype
|
||||
// 2) instance is initialized:
|
||||
// call .__init__(..) if defined
|
||||
//
|
||||
//
|
||||
//
|
||||
// Special methods (constructor):
|
||||
//
|
||||
// Handle uninitialized instance construction
|
||||
// .__rawinstance__(context, ...)
|
||||
// -> instance
|
||||
// NOTE: This is a shorthand to makeRawInstance(..) see it for
|
||||
// details.
|
||||
//
|
||||
//
|
||||
// Special methods (.prototype):
|
||||
//
|
||||
// Create new instance object...
|
||||
// .__new__(context, ..)
|
||||
// -> object
|
||||
//
|
||||
// Handle instance call...
|
||||
// .__call__(context, ..)
|
||||
// -> ..
|
||||
//
|
||||
// Initialize instance object...
|
||||
// .__init__(..)
|
||||
// -> ..
|
||||
//
|
||||
//
|
||||
// NOTE: raw instance creation is defined by makeRawInstance(..) so see
|
||||
// it for more info.
|
||||
// NOTE: raw instance creation can be completely overloaded by defining
|
||||
// .__rawinstance__(..) on the constructor.
|
||||
//
|
||||
//
|
||||
//
|
||||
// Inheritance:
|
||||
// A simple way to build C -> B -> A chain would be:
|
||||
//
|
||||
// var A = makeConstructor('A', {})
|
||||
// // NOTE: new is optional...
|
||||
// var A = new Constructor('A')
|
||||
//
|
||||
// // NOTE: the prototype is an instance and not a constructor,
|
||||
// // this is obvious if one considers that in JS there are
|
||||
// // no classes and inheritance is done via object prototypes
|
||||
// // but this might be a gotcha to people coming from the
|
||||
// // class-object world.
|
||||
// var B = makeConstructor('B', A())
|
||||
// // NOTE: in a prototype chain the prototypes are "inherited"
|
||||
// // NOTE: JS has no classes and the prototype is just another
|
||||
// // object, the only difference is that it's used by the
|
||||
// // constructor to link other objects i.e. "instances" to...
|
||||
// var B = Constructor('B', {__proto__: A.prototype})
|
||||
//
|
||||
// var C = makeConstructor('C', B())
|
||||
// var C = Constructor('C', Objec.create(B.prototype))
|
||||
//
|
||||
// var c = C()
|
||||
//
|
||||
@ -89,12 +479,12 @@ function(require){ var module={} // makes module AMD/node compatible...
|
||||
//
|
||||
//
|
||||
// Motivation:
|
||||
// The general motivation here is to standardise the constructor protocol
|
||||
// and make a single simple way to go with minimal variation. This is due
|
||||
// to the JavaScript base protocol though quite simple, being too flexible
|
||||
// making it very involved to produce objects in a consistent manner by
|
||||
// hand, especially in long running projects, in turn spreading all the
|
||||
// refactoring over multiple sites and styles.
|
||||
// The general motivation here is to standardise the constructor
|
||||
// protocol and make a single simple way to go with minimal variation.
|
||||
// This is due to the JavaScript base protocol though quite simple,
|
||||
// being too flexible making it very involved to produce objects in a
|
||||
// consistent manner by hand, especially in long running projects,
|
||||
// in turn spreading all the refactoring over multiple sites and styles.
|
||||
//
|
||||
// This removes part of the flexibility and in return gives us:
|
||||
// - single, well defined protocol
|
||||
@ -103,111 +493,74 @@ function(require){ var module={} // makes module AMD/node compatible...
|
||||
// - easy refactoring without touching the client code
|
||||
//
|
||||
//
|
||||
// NOTE: this sets the proto's .constructor attribute, this rendering it
|
||||
// not reusable, to use the same prototype for multiple objects clone
|
||||
// it via. Object.create(..) or copy it...
|
||||
//
|
||||
// XXX might be a good idea to be able to make an instance without
|
||||
// initializing it...
|
||||
// ...mainly for inheritance.
|
||||
// ...would also be helpful in this case to call all the
|
||||
// constructors in the chain
|
||||
var makeConstructor =
|
||||
module.makeConstructor =
|
||||
function makeConstructor(name, a, b){
|
||||
// NOTE: this sets the proto's .constructor attribute, thus rendering it
|
||||
// not reusable, to use the same prototype for multiple objects
|
||||
// clone it via. Object.create(..) or copy it...
|
||||
// NOTE: to disable .__rawinstance__(..) handling set it to false in the
|
||||
// class prototype...
|
||||
var Constructor =
|
||||
module.Constructor =
|
||||
// shorthand...
|
||||
module.C =
|
||||
function Constructor(name, a, b){
|
||||
var proto = b == null ? a : b
|
||||
var cls_proto = b == null ? b : a
|
||||
proto = proto || {}
|
||||
|
||||
// the actual constructor...
|
||||
var _constructor = function Constructor(){
|
||||
/*
|
||||
// XXX BUG: if the constructor is called from it's instance this will
|
||||
// return the instance and not a new object...
|
||||
// in case this is called as a function (without new)...
|
||||
if(this.constructor !== _constructor){
|
||||
// NOTE: the following does the job of the 'new' operator but
|
||||
// with one advantage, we can now pass arbitrary args
|
||||
// in...
|
||||
// This is equivalent to:
|
||||
// return new _constructor(json)
|
||||
var obj = {}
|
||||
obj.__proto__ = _constructor.prototype
|
||||
// XXX for some reason this does not resolve from .__proto__
|
||||
obj.constructor = _constructor
|
||||
//obj.__proto__.constructor = _constructor
|
||||
// create raw instance...
|
||||
var obj = _constructor.__rawinstance__ ?
|
||||
_constructor.__rawinstance__(this, ...arguments)
|
||||
: makeRawInstance(this, _constructor, ...arguments)
|
||||
// initialize...
|
||||
obj.__init__ instanceof Function
|
||||
&& obj.__init__(...arguments)
|
||||
return obj }
|
||||
|
||||
} else {
|
||||
var obj = this
|
||||
}
|
||||
*/
|
||||
_constructor.name = name
|
||||
// just in case the browser refuses to change the name, we'll make
|
||||
// it a different offer ;)
|
||||
_constructor.name == 'Constructor'
|
||||
// NOTE: this eval(..) should not be a risk as its inputs are
|
||||
// static and never infuenced by external inputs...
|
||||
&& eval('_constructor = '+ _constructor
|
||||
.toString()
|
||||
.replace(/Constructor/g, name))
|
||||
// set .toString(..)...
|
||||
// NOTE: do this only if .toString(..) is not defined by user...
|
||||
;((cls_proto || {}).toString() == ({}).toString())
|
||||
&& Object.defineProperty(_constructor, 'toString', {
|
||||
value: function(){
|
||||
var args = proto.__init__ ?
|
||||
proto.__init__
|
||||
.toString()
|
||||
.split(/\n/)[0]
|
||||
.replace(/function\(([^)]*)\){.*/, '$1')
|
||||
: ''
|
||||
var code = proto.__init__ ?
|
||||
proto.__init__
|
||||
.toString()
|
||||
.replace(/[^{]*{/, '{')
|
||||
: '{ .. }'
|
||||
return `${this.name}(${args})${normalizeIndent(code)}` },
|
||||
enumerable: false,
|
||||
})
|
||||
_constructor.__proto__ = cls_proto
|
||||
_constructor.prototype = proto
|
||||
// generic raw instance constructor...
|
||||
_constructor.__rawinstance__ instanceof Function
|
||||
|| (_constructor.__rawinstance__ =
|
||||
function(context, ...args){
|
||||
return makeRawInstance(context, this, ...args) })
|
||||
|
||||
// NOTE: the following does the job of the 'new' operator but
|
||||
// with one advantage, we can now pass arbitrary args
|
||||
// in...
|
||||
// This is equivalent to:
|
||||
// return new _constructor(json)
|
||||
var obj = {}
|
||||
obj.__proto__ = _constructor.prototype
|
||||
// XXX for some reason this does not resolve from .__proto__
|
||||
// XXX this also is a regular attr and not a prop...
|
||||
//obj.constructor = _constructor
|
||||
Object.defineProperty(obj, 'constructor', {
|
||||
// set .prototype.constructor
|
||||
Object.defineProperty(_constructor.prototype, 'constructor', {
|
||||
value: _constructor,
|
||||
enumerable: false,
|
||||
})
|
||||
//obj.__proto__.constructor = _constructor
|
||||
|
||||
// explicit init...
|
||||
if(proto instanceof Function){
|
||||
proto.apply(obj, arguments)
|
||||
}
|
||||
|
||||
// load initial state...
|
||||
if(obj.__init__ != null){
|
||||
obj.__init__.apply(obj, arguments)
|
||||
}
|
||||
|
||||
return obj
|
||||
}
|
||||
|
||||
/* XXX for some reason this works for the _constructor but all
|
||||
* instances get the wrong name resolved...
|
||||
Object.defineProperty(_constructor, 'name', {
|
||||
value: name,
|
||||
})
|
||||
*/
|
||||
|
||||
// just in case the browser refuses to change the name, we'll make it
|
||||
// a different offer ;)
|
||||
if(_constructor.name == 'Constructor'){
|
||||
// skip for chrome app...
|
||||
//&& !(window.chrome && chrome.runtime && chrome.runtime.id)){
|
||||
eval('_constructor = '+ _constructor
|
||||
.toString()
|
||||
.replace(/Constructor/g, name))
|
||||
}
|
||||
|
||||
_constructor.__proto__ = cls_proto
|
||||
_constructor.prototype = proto
|
||||
_constructor.prototype.constructor = _constructor
|
||||
|
||||
return _constructor
|
||||
}
|
||||
|
||||
|
||||
// super equivalent...
|
||||
//
|
||||
// superMethod(<class>, <method-name>).call(this, ...)
|
||||
// -> <result>
|
||||
//
|
||||
// This will return a next method in inheritance chain after <class> by
|
||||
// its name (<method-name>).
|
||||
// In the normal use-case <class> is the current class and <method-name>
|
||||
// is the name of the current method.
|
||||
var superMethod =
|
||||
module.superMethod =
|
||||
function superMethod(cls, meth){
|
||||
return cls.prototype.__proto__[meth]
|
||||
}
|
||||
return _constructor }
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user