You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
131 lines
4.0 KiB
131 lines
4.0 KiB
dojo.provide("dojox.lang.oo.mixin"); |
|
|
|
dojo.experimental("dojox.lang.oo.mixin"); |
|
|
|
dojo.require("dojox.lang.oo.Filter"); |
|
dojo.require("dojox.lang.oo.Decorator"); |
|
|
|
(function(){ |
|
var oo = dojox.lang.oo, Filter = oo.Filter, Decorator = oo.Decorator, empty = {}, |
|
defaultFilter = function(name){ return name; }, |
|
defaultDecorator = function(name, newValue, oldValue){ return newValue; }, |
|
defaultMixer = function(target, name, newValue, oldValue){ target[name] = newValue; }, |
|
defaults = {}, // for the internal use in the mixin() |
|
extraNames = dojo._extraNames, extraLen = extraNames.length, |
|
|
|
applyDecorator = oo.applyDecorator = function(decorator, name, newValue, oldValue){ |
|
// summary: |
|
// applies a decorator unraveling all embedded decorators |
|
// decorator: Function |
|
// top-level decorator to apply |
|
// name: String |
|
// name of the property |
|
// newValue: Object |
|
// new value of the property |
|
// oldValue: Object |
|
// old value of the property |
|
// returns: Object |
|
// returns the final value of the property |
|
if(newValue instanceof Decorator){ |
|
var d = newValue.decorator; |
|
newValue = applyDecorator(decorator, name, newValue.value, oldValue); |
|
return d(name, newValue, oldValue); |
|
} |
|
return decorator(name, newValue, oldValue); |
|
}; |
|
|
|
/*===== |
|
dojox.lang.oo.__MixinDefaults = { |
|
// summary: |
|
// a dict of default parameters for dojox.lang.oo._mixin |
|
// decorator: Function |
|
// a decorator function to be used in absence of other decorators |
|
// filter: Function |
|
// a filter function to be used in absence of other filters |
|
// mixer: Function |
|
// a mixer function to be used to mix in new properties |
|
}; |
|
=====*/ |
|
|
|
oo.__mixin = function(target, source, decorator, filter, mixer){ |
|
// summary: |
|
// mixes in two objects processing decorators and filters |
|
// target: Object |
|
// target to receive new/updated properties |
|
// source: Object |
|
// source of properties |
|
// defaults: dojox.lang.oo.__MixinDefaults? |
|
// default functions for various aspects of mixing |
|
// returns: Object |
|
// target |
|
|
|
var name, targetName, prop, newValue, oldValue, i; |
|
|
|
// start mixing in properties |
|
for(name in source){ |
|
prop = source[name]; |
|
if(!(name in empty) || empty[name] !== prop){ |
|
targetName = filter(name, target, source, prop); |
|
if(targetName && (!(targetName in target) || !(targetName in empty) || empty[targetName] !== prop)){ |
|
// name is accepted |
|
oldValue = target[targetName]; |
|
newValue = applyDecorator(decorator, targetName, prop, oldValue); |
|
if(oldValue !== newValue){ |
|
mixer(target, targetName, newValue, oldValue); |
|
} |
|
} |
|
} |
|
} |
|
if(extraLen){ |
|
for(i = 0; i < extraLen; ++i){ |
|
name = extraNames[i]; |
|
// repeating the body above |
|
prop = source[name]; |
|
if(!(name in empty) || empty[name] !== prop){ |
|
targetName = filter(name, target, source, prop); |
|
if(targetName && (!(targetName in target) || !(targetName in empty) || empty[targetName] !== prop)){ |
|
// name is accepted |
|
oldValue = target[targetName]; |
|
newValue = applyDecorator(decorator, targetName, prop, oldValue); |
|
if(oldValue !== newValue){ |
|
mixer(target, targetName, newValue, oldValue); |
|
} |
|
} |
|
} |
|
} |
|
} |
|
|
|
return target; // Object |
|
}; |
|
|
|
oo.mixin = function(target, source){ |
|
// summary: |
|
// mixes in two or more objects processing decorators and filters |
|
// using defaults as a fallback |
|
// target: Object |
|
// target to receive new/updated properties |
|
// source: Object... |
|
// source of properties, more than one source is allowed |
|
// returns: Object |
|
// target |
|
|
|
var decorator, filter, i = 1, l = arguments.length; |
|
for(; i < l; ++i){ |
|
source = arguments[i]; |
|
if(source instanceof Filter){ |
|
filter = source.filter; |
|
source = source.bag; |
|
}else{ |
|
filter = defaultFilter; |
|
} |
|
if(source instanceof Decorator){ |
|
decorator = source.decorator; |
|
source = source.value; |
|
}else{ |
|
decorator = defaultDecorator; |
|
} |
|
oo.__mixin(target, source, decorator, filter, defaultMixer); |
|
} |
|
return target; // Object |
|
}; |
|
})();
|
|
|