var path = require('path');12/**3* Intercepts a method by replacing the prototype's implementation4* with a wrapper that invokes the given interceptor instead.5*6* utils.intercept(core.Element, 'inserBefore',7* function(_super, args, newChild, refChild) {8* console.log('insertBefore', newChild, refChild);9* return _super.apply(this, args);10* }11* );12*/13exports.intercept = function(clazz, method, interceptor) {14var proto = clazz.prototype,15_super = proto[method],16unwrapArgs = interceptor.length > 2;1718proto[method] = function() {19if (unwrapArgs) {20var args = Array.prototype.slice.call(arguments);21args.unshift(_super, arguments);22return interceptor.apply(this, args);23}24else {25return interceptor.call(this, _super, arguments);26}27};28};2930exports.toFileUrl = function (fileName) {31// Beyond just the `path.resolve`, this is mostly for the benefit of Windows,32// where we need to convert '\' to '/' and add an extra '/' prefix before the33// drive letter.34var pathname = path.resolve(process.cwd(), fileName).replace(/\\/g, '/');35if (pathname[0] !== '/') {36pathname = '/' + pathname;37}3839return 'file://' + pathname;40};4142/**43* Define a setter on an object44*45* This method replaces any existing setter but leaves getters in place.46*47* - `object` {Object} the object to define the setter on48* - `property` {String} the name of the setter49* - `setterFn` {Function} the setter50*/51exports.defineSetter = function defineSetter(object, property, setterFn) {52var descriptor = Object.getOwnPropertyDescriptor(object, property) || {53configurable: true,54enumerable: true55};5657descriptor.set = setterFn;5859Object.defineProperty(object, property, descriptor);60};6162/**63* Define a getter on an object64*65* This method replaces any existing getter but leaves setters in place.66*67* - `object` {Object} the object to define the getter on68* - `property` {String} the name of the getter69* - `getterFn` {Function} the getter70*/71exports.defineGetter = function defineGetter(object, property, getterFn) {72var descriptor = Object.getOwnPropertyDescriptor(object, property) || {73configurable: true,74enumerable: true75};7677descriptor.get = getterFn;7879Object.defineProperty(object, property, descriptor);80};8182/**83* Create an object with the given prototype84*85* Optionally augment the created object.86*87* - `prototyp` {Object} the created object's prototype88* - `[properties]` {Object} properties to attach to the created object89*/90exports.createFrom = function createFrom(prototype, properties) {91properties = properties || {};9293var descriptors = {};94Object.getOwnPropertyNames(properties).forEach(function (name) {95descriptors[name] = Object.getOwnPropertyDescriptor(properties, name);96});9798return Object.create(prototype, descriptors);99};100101/**102* Create an inheritance relationship between two classes103*104* Optionally augment the inherited prototype.105*106* - `Superclass` {Function} the inherited class107* - `Subclass` {Function} the inheriting class108* - `[properties]` {Object} properties to attach to the inherited prototype109*/110exports.inheritFrom = function inheritFrom(Superclass, Subclass, properties) {111properties = properties || {};112113Object.defineProperty(properties, 'constructor', {114value: Subclass,115writable: true,116configurable: true117});118119Subclass.prototype = exports.createFrom(Superclass.prototype, properties);120};121122123