mirror of
https://github.com/videojs/video.js.git
synced 2025-03-29 22:07:10 +02:00
@heff added and `extends` function for external subclassing. closes #2078
This commit is contained in:
parent
94f33c8d43
commit
f19d13b9bb
@ -14,6 +14,7 @@ CHANGELOG
|
||||
* @dconnolly replaced JSON.parse with a safe non-eval JSON parse ([view](https://github.com/videojs/video.js/pull/2077))
|
||||
* @mmcc added a new default skin, switched to SASS, modified the html ([view](https://github.com/videojs/video.js/pull/1999))
|
||||
* @gkatsev removed event.isDefaultPrevented in favor of event.defaultPrevented ([view](https://github.com/videojs/video.js/pull/2081))
|
||||
* @heff added and `extends` function for external subclassing ([view](https://github.com/videojs/video.js/pull/2078))
|
||||
|
||||
--------------------
|
||||
|
||||
|
@ -24,6 +24,7 @@
|
||||
"dependencies": {
|
||||
"global": "^4.3.0",
|
||||
"safe-json-parse": "^4.0.0",
|
||||
"inherits": "^2.0.1",
|
||||
"videojs-swf": "4.5.4",
|
||||
"vtt.js": "git+https://github.com/gkatsev/vtt.js.git#shim-build"
|
||||
},
|
||||
|
71
src/js/extends.js
Normal file
71
src/js/extends.js
Normal file
@ -0,0 +1,71 @@
|
||||
import * as Lib from './lib';
|
||||
|
||||
/**
|
||||
* A combination of node inherits and babel's inherits (after transpile).
|
||||
* Both work the same but node adds `super_` to the subClass
|
||||
* and Bable adds the superClass as __proto__. Both seem useful.
|
||||
*/
|
||||
const _inherits = function (subClass, superClass) {
|
||||
if (typeof superClass !== 'function' && superClass !== null) {
|
||||
throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass);
|
||||
}
|
||||
|
||||
subClass.prototype = Object.create(superClass && superClass.prototype, {
|
||||
constructor: {
|
||||
value: subClass,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true
|
||||
}
|
||||
});
|
||||
|
||||
if (superClass) {
|
||||
// node
|
||||
subClass.super_ = superClass;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Function for subclassing using the same inheritance that
|
||||
* videojs uses internally
|
||||
*
|
||||
* ```
|
||||
* var Button = videojs.getComponent('Button');
|
||||
*
|
||||
* var MyButton = videojs.extends(Button, {
|
||||
* constructor: function(player, options) {
|
||||
* Button.call(this, player, options);
|
||||
* },
|
||||
*
|
||||
* onClick: function() {
|
||||
* // doSomething
|
||||
* }
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
const extendsFn = function(superClass, subClassMethods={}) {
|
||||
let subClass = function() {
|
||||
superClass.apply(this, arguments);
|
||||
};
|
||||
let methods = {};
|
||||
|
||||
if (subClassMethods.constructor !== Object.prototype.constructor) {
|
||||
subClass = subClassMethods.constructor;
|
||||
methods = subClassMethods;
|
||||
} else if (typeof subClassMethods === 'function') {
|
||||
subClass = subClassMethods;
|
||||
}
|
||||
|
||||
_inherits(subClass, superClass);
|
||||
|
||||
// Extend subObj's prototype with functions and other properties from props
|
||||
for (var name in methods) {
|
||||
if (methods.hasOwnProperty(name)) {
|
||||
subClass.prototype[name] = methods[name];
|
||||
}
|
||||
}
|
||||
|
||||
return subClass;
|
||||
};
|
||||
|
||||
export default extendsFn;
|
@ -15,7 +15,8 @@ import * as setup from './setup';
|
||||
import Component from './component';
|
||||
import * as Lib from './lib';
|
||||
import * as Util from './util.js';
|
||||
|
||||
import Player from './player';
|
||||
import extendsFn from './extends.js';
|
||||
|
||||
if (typeof HTMLVideoElement === 'undefined') {
|
||||
document.createElement('video');
|
||||
@ -36,9 +37,10 @@ videojs.TOUCH_ENABLED = Lib.TOUCH_ENABLED;
|
||||
videojs.util = Util;
|
||||
|
||||
// Probably want to keep this one for 5.0?
|
||||
import Player from './player';
|
||||
videojs.players = Player.players;
|
||||
|
||||
videojs.extends = extendsFn;
|
||||
|
||||
// REMOVING: We probably should not include this in 5.0 thought it would make it
|
||||
// more backwards compatible
|
||||
// // Expose but deprecate the window[componentName] method for accessing components
|
||||
@ -55,6 +57,4 @@ videojs.players = Player.players;
|
||||
// Lib.obj.merge(module.exports[name], component);
|
||||
// });
|
||||
|
||||
|
||||
|
||||
export default videojs;
|
||||
|
@ -255,4 +255,27 @@ function testHelperMakeTag(){
|
||||
return videoTag;
|
||||
}
|
||||
|
||||
})();
|
||||
test('should extend Component', function(){
|
||||
var Component = videojs.getComponent('Component');
|
||||
var MyComponent = videojs.extends(Component, {
|
||||
constructor: function() {
|
||||
this.bar = true;
|
||||
},
|
||||
foo: function() {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
var myComponent = new MyComponent();
|
||||
ok(myComponent instanceof Component, 'creates an instance of Component');
|
||||
ok(myComponent instanceof MyComponent, 'creates an instance of MyComponent');
|
||||
ok(myComponent.bar, 'the constructor function is used');
|
||||
ok(myComponent.foo(), 'instance methods are applied');
|
||||
|
||||
var NoMethods = videojs.extends(Component);
|
||||
var noMethods = new NoMethods({});
|
||||
ok(noMethods.on, 'should extend component with no methods or constructor');
|
||||
});
|
||||
|
||||
|
||||
})();
|
||||
|
Loading…
x
Reference in New Issue
Block a user