Skip to content

Commit

Permalink
fix: remove deprecated extends method
Browse files Browse the repository at this point in the history
Using classes inheritance instead of the deprecated `.extends` method
will allow users of this library to upgrade VideoJS to version 8.

See silvermine/videojs-chromecast#152
and silvermine/videojs-chromecast#147.

Related to silvermine/videojs-chromecast#152
Related to  silvermine/videojs-chromecast#147
  • Loading branch information
Eric Fortmeyer committed Feb 22, 2023
1 parent af9a000 commit 1347f10
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 131 deletions.
15 changes: 9 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"description": "video.js plugin for casting to airplay",
"main": "src/js/index.js",
"scripts": {
"test": "check-node-version --npm 8.5.5 && nyc mocha -- 'tests/**/*.test.js'",
"test": "check-node-version --npm 8.5.5 && nyc mocha -- -r esm 'tests/**/*.test.js'",
"prepublish": "grunt build",
"commitlint": "commitlint --from 18a346d",
"markdownlint": "markdownlint -c .markdownlint.json -i CHANGELOG.md '{,!(node_modules)/**/}*.md'",
Expand Down Expand Up @@ -35,15 +35,15 @@
},
"homepage": "https://github.com/silvermine/videojs-airplay#readme",
"devDependencies": {
"@babel/core": "^7.21.0",
"@babel/preset-env": "^7.20.2",
"@babel/core": "7.21.0",
"@babel/preset-env": "7.20.2",
"@silvermine/eslint-config": "3.0.1",
"@silvermine/standardization": "2.0.0",
"autoprefixer": "7.1.1",
"babel-eslint": "^10.1.0",
"babelify": "^10.0.0",
"babel-eslint": "10.1.0",
"babelify": "10.0.0",
"check-node-version": "4.0.2",
"core-js": "^3.28.0",
"core-js": "3.28.0",
"coveralls": "3.0.2",
"eslint": "6.8.0",
"expect.js": "0.3.1",
Expand All @@ -70,5 +70,8 @@
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
},
"dependencies": {
"esm": "^3.2.25"
}
}
239 changes: 118 additions & 121 deletions src/js/components/AirPlayButton.js
Original file line number Diff line number Diff line change
@@ -1,119 +1,4 @@
'use strict';

/**
* The AirPlayButton module contains both the AirPlayButton class definition and the
* function used to register the button as a Video.js Component.
*
* @module AirPlayButton
*/

var hasAirPlayAPISupport = require('../lib/hasAirPlayAPISupport'),
AirPlayButton;

/**
* The Video.js Button class is the base class for UI button components.
*
* @external Button
* @see {@link http://docs.videojs.com/Button.html|Button}
*/

/** @lends AirPlayButton.prototype */
AirPlayButton = {

/**
* This class is a button component designed to be displayed in the player UI's control
* bar. It displays an Apple AirPlay selection list when clicked.
*
* @constructs
* @extends external:Button
*/
constructor: function(player, options) {
this.constructor.super_.apply(this, arguments);

if (!hasAirPlayAPISupport()) {
this.hide();
}

this._reactToAirPlayAvailableEvents();

if (options.addAirPlayLabelToButton) {
this.el().classList.add('vjs-airplay-button-lg');

this._labelEl = document.createElement('span');
this._labelEl.classList.add('vjs-airplay-button-label');
this._labelEl.textContent = this.localize('AirPlay');

this.el().appendChild(this._labelEl);
} else {
this.controlText('Start AirPlay');
}
},

/**
* Overrides Button#buildCSSClass to return the classes used on the button element.
*
* @param {DOMElement} el
* @see {@link http://docs.videojs.com/Button.html#buildCSSClass|Button#buildCSSClass}
*/
buildCSSClass: function() {
return 'vjs-airplay-button ' + this.constructor.super_.prototype.buildCSSClass();
},

/**
* Overrides Button#handleClick to handle button click events. AirPlay functionality is
* handled outside of this class, which should be limited to UI related logic. This
* function simply triggers an event on the player.
*
* @fires AirPlayButton#airPlayRequested
* @param {DOMElement} el
* @see {@link http://docs.videojs.com/Button.html#handleClick|Button#handleClick}
*/
handleClick: function() {
this.player().trigger('airPlayRequested');
},

/**
* Gets the underlying DOMElement used by the player.
*
* @private
* @returns {DOMElement} either an <audio> or <video> tag, depending on the type of
* player
*/
_getMediaEl: function() {
var playerEl = this.player().el();

return playerEl.querySelector('video, audio');
},

/**
* Binds a listener to the `webkitplaybacktargetavailabilitychanged` event, if it is
* supported, that will show or hide this button Component based on the availability
* of the AirPlay function.
*
* @private
*/
_reactToAirPlayAvailableEvents: function() {
var mediaEl = this._getMediaEl(),
self = this;

if (!mediaEl || !hasAirPlayAPISupport()) {
return;
}

function onTargetAvailabilityChanged(event) {
if (event.availability === 'available') {
self.show();
} else {
self.hide();
}
}

mediaEl.addEventListener('webkitplaybacktargetavailabilitychanged', onTargetAvailabilityChanged);
this.on('dispose', function() {
mediaEl.removeEventListener('webkitplaybacktargetavailabilitychanged', onTargetAvailabilityChanged);
});
},
};
import hasAirPlayAPISupport from '../lib/hasAirPlayAPISupport';

/**
* Registers the AirPlayButton Component with Video.js. Calls
Expand Down Expand Up @@ -141,9 +26,121 @@ AirPlayButton = {
* @param videojs {object} A reference to {@link http://docs.videojs.com/module-videojs.html|Video.js}
* @see http://docs.videojs.com/module-videojs.html#~registerPlugin
*/
module.exports = function(videojs) {
var AirPlayButtonImpl;
export default function createAirPlayButton(videojs) {

/**
* The AirPlayButton module contains both the AirPlayButton class definition and the
* function used to register the button as a Video.js Component.
*
* @module AirPlayButton
*/

const ButtonComponent = videojs.getComponent('Button');

/**
* The Video.js Button class is the base class for UI button components.
*
* @external Button
* @see {@link http://docs.videojs.com/Button.html|Button}
*/

/** @lends AirPlayButton.prototype */
class AirPlayButton extends ButtonComponent {

/**
* This class is a button component designed to be displayed in the
* player UI's control bar. It displays an Apple AirPlay selection
* list when clicked.
*
* @constructs
* @extends external:Button
*/
constructor(player, options) {
super(player, options);

if (!hasAirPlayAPISupport()) {
this.hide();
}

this._reactToAirPlayAvailableEvents();

if (options.addAirPlayLabelToButton) {
this.el().classList.add('vjs-airplay-button-lg');

this._labelEl = document.createElement('span');
this._labelEl.classList.add('vjs-airplay-button-label');
this._labelEl.textContent = this.localize('AirPlay');

this.el().appendChild(this._labelEl);
} else {
this.controlText('Start AirPlay');
}
}

/**
* Overrides Button#buildCSSClass to return the classes used on the button element.
*
* @param {DOMElement} el
* @see {@link http://docs.videojs.com/Button.html#buildCSSClass|Button#buildCSSClass}
*/
buildCSSClass() {
return 'vjs-airplay-button ' + super.buildCSSClass();
}

/**
* Overrides Button#handleClick to handle button click events. AirPlay
* functionality is handled outside of this class, which should be limited
* to UI related logic. This function simply triggers an event on the player.
*
* @fires AirPlayButton#airPlayRequested
* @param {DOMElement} el
* @see {@link http://docs.videojs.com/Button.html#handleClick|Button#handleClick}
*/
handleClick() {
this.player().trigger('airPlayRequested');
}

/**
* Gets the underlying DOMElement used by the player.
*
* @private
* @returns {DOMElement} either an <audio> or <video> tag, depending on the type of
* player
*/
_getMediaEl() {
var playerEl = this.player().el();

return playerEl.querySelector('video, audio');
}

/**
* Binds a listener to the `webkitplaybacktargetavailabilitychanged` event, if it is
* supported, that will show or hide this button Component based on the availability
* of the AirPlay function.
*
* @private
*/
_reactToAirPlayAvailableEvents() {
var mediaEl = this._getMediaEl();

if (!mediaEl || !hasAirPlayAPISupport()) {
return;
}

function onTargetAvailabilityChanged(event) {
if (event.availability === 'available') {
this.show();
} else {
this.hide();
}
}

mediaEl.addEventListener('webkitplaybacktargetavailabilitychanged', onTargetAvailabilityChanged);
this.on('dispose', function() {
mediaEl.removeEventListener('webkitplaybacktargetavailabilitychanged', onTargetAvailabilityChanged);
});
}
}

AirPlayButtonImpl = videojs.extend(videojs.getComponent('Button'), AirPlayButton);
videojs.registerComponent('airPlayButton', AirPlayButtonImpl);
};
videojs.registerComponent('airPlayButton', AirPlayButton);
}
4 changes: 1 addition & 3 deletions src/js/index.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
'use strict';

var createAirPlayButton = require('./components/AirPlayButton'),
var { default: createAirPlayButton } = require('./components/AirPlayButton'),
createAirPlayPlugin = require('./enableAirPlay');

/**
Expand Down
2 changes: 1 addition & 1 deletion tests/AirPlayButton.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

var expect = require('expect.js');

const createAirPlayButton = require('../src/js/components/AirPlayButton');
const { default: createAirPlayButton } = require('../src/js/components/AirPlayButton');

class ButtonComponentStub {}

Expand Down

0 comments on commit 1347f10

Please sign in to comment.