| // ========================================== |
| // Copyright 2013 Twitter, Inc |
| // Licensed under The MIT License |
| // http://opensource.org/licenses/MIT |
| // ========================================== |
| |
| "use strict"; |
| |
| define( |
| |
| [ |
| './utils', |
| '../tools/debug/debug' |
| ], |
| |
| function(util, debug) { |
| |
| //enumerables are shims - getOwnPropertyDescriptor shim doesn't work |
| var canWriteProtect = debug.enabled && !util.isEnumerable(Object, 'getOwnPropertyDescriptor'); |
| //whitelist of unlockable property names |
| var dontLock = ['mixedIn']; |
| |
| if (canWriteProtect) { |
| //IE8 getOwnPropertyDescriptor is built-in but throws exeption on non DOM objects |
| try { |
| Object.getOwnPropertyDescriptor(Object, 'keys'); |
| } catch(e) { |
| canWriteProtect = false; |
| } |
| } |
| |
| function setPropertyWritability(obj, isWritable) { |
| if (!canWriteProtect) { |
| return; |
| } |
| |
| var props = Object.create(null); |
| |
| Object.keys(obj).forEach( |
| function (key) { |
| if (dontLock.indexOf(key) < 0) { |
| var desc = Object.getOwnPropertyDescriptor(obj, key); |
| desc.writable = isWritable; |
| props[key] = desc; |
| } |
| } |
| ); |
| |
| Object.defineProperties(obj, props); |
| } |
| |
| function unlockProperty(obj, prop, op) { |
| var writable; |
| |
| if (!canWriteProtect || !obj.hasOwnProperty(prop)) { |
| op.call(obj); |
| return; |
| } |
| |
| writable = Object.getOwnPropertyDescriptor(obj, prop).writable; |
| Object.defineProperty(obj, prop, { writable: true }); |
| op.call(obj); |
| Object.defineProperty(obj, prop, { writable: writable }); |
| } |
| |
| function mixin(base, mixins) { |
| base.mixedIn = base.hasOwnProperty('mixedIn') ? base.mixedIn : []; |
| |
| mixins.forEach(function(mixin) { |
| if (base.mixedIn.indexOf(mixin) == -1) { |
| setPropertyWritability(base, false); |
| mixin.call(base); |
| base.mixedIn.push(mixin); |
| } |
| }); |
| |
| setPropertyWritability(base, true); |
| } |
| |
| return { |
| mixin: mixin, |
| unlockProperty: unlockProperty |
| }; |
| |
| } |
| ); |