mirror of
https://github.com/videojs/video.js.git
synced 2025-07-05 00:58:52 +02:00
@heff added and `extends` function for external subclassing. closes #2078
This commit is contained in:
@ -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))
|
* @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))
|
* @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))
|
* @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": {
|
"dependencies": {
|
||||||
"global": "^4.3.0",
|
"global": "^4.3.0",
|
||||||
"safe-json-parse": "^4.0.0",
|
"safe-json-parse": "^4.0.0",
|
||||||
|
"inherits": "^2.0.1",
|
||||||
"videojs-swf": "4.5.4",
|
"videojs-swf": "4.5.4",
|
||||||
"vtt.js": "git+https://github.com/gkatsev/vtt.js.git#shim-build"
|
"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 Component from './component';
|
||||||
import * as Lib from './lib';
|
import * as Lib from './lib';
|
||||||
import * as Util from './util.js';
|
import * as Util from './util.js';
|
||||||
|
import Player from './player';
|
||||||
|
import extendsFn from './extends.js';
|
||||||
|
|
||||||
if (typeof HTMLVideoElement === 'undefined') {
|
if (typeof HTMLVideoElement === 'undefined') {
|
||||||
document.createElement('video');
|
document.createElement('video');
|
||||||
@ -36,9 +37,10 @@ videojs.TOUCH_ENABLED = Lib.TOUCH_ENABLED;
|
|||||||
videojs.util = Util;
|
videojs.util = Util;
|
||||||
|
|
||||||
// Probably want to keep this one for 5.0?
|
// Probably want to keep this one for 5.0?
|
||||||
import Player from './player';
|
|
||||||
videojs.players = Player.players;
|
videojs.players = Player.players;
|
||||||
|
|
||||||
|
videojs.extends = extendsFn;
|
||||||
|
|
||||||
// REMOVING: We probably should not include this in 5.0 thought it would make it
|
// REMOVING: We probably should not include this in 5.0 thought it would make it
|
||||||
// more backwards compatible
|
// more backwards compatible
|
||||||
// // Expose but deprecate the window[componentName] method for accessing components
|
// // 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);
|
// Lib.obj.merge(module.exports[name], component);
|
||||||
// });
|
// });
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export default videojs;
|
export default videojs;
|
||||||
|
@ -255,4 +255,27 @@ function testHelperMakeTag(){
|
|||||||
return videoTag;
|
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');
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
})();
|
||||||
|
Reference in New Issue
Block a user