1
0
mirror of https://github.com/videojs/video.js.git synced 2025-01-02 06:32:07 +02:00

feat(svg-icons): handle custom svg icons

Replace the player's default icons with custom icons.

The `experimentalSvgIcons` option accepts a `boolean` or a `string`.
If the string represents a valid svg, it will replace the default icons.

**Usage**

```javascript
import playerIcons from './asset/vjs-sprite-icons.svg';

const player = videojs('my-player', {
  experimentalSvgIcons: playerIcons,
  // ...
});
```

Or:

```javascript
const player = videojs('my-player', {
  experimentalSvgIcons: `
  <svg>
  ...
  </svg>
  `,
  // ...
});
```

- extract a `initSvgIcons_` function to activate svg icons
- add test cases
This commit is contained in:
amtins 2023-11-12 15:50:27 +01:00
parent d535e163da
commit 0c9ae3c400
2 changed files with 67 additions and 19 deletions

View File

@ -518,25 +518,7 @@ class Player extends Component {
this.playbackRates(options.playbackRates); this.playbackRates(options.playbackRates);
if (options.experimentalSvgIcons) { this.initSvgIcons_(options.experimentalSvgIcons);
// Add SVG Sprite to the DOM
const parser = new window.DOMParser();
const parsedSVG = parser.parseFromString(icons, 'image/svg+xml');
const errorNode = parsedSVG.querySelector('parsererror');
if (errorNode) {
log.warn('Failed to load SVG Icons. Falling back to Font Icons.');
this.options_.experimentalSvgIcons = null;
} else {
const sprite = parsedSVG.documentElement;
sprite.style.display = 'none';
this.el_.appendChild(sprite);
this.addClass('vjs-svg-icons-enabled');
}
}
this.initChildren(); this.initChildren();
// Set isAudio based on whether or not an audio tag was used // Set isAudio based on whether or not an audio tag was used
@ -5093,6 +5075,39 @@ class Player extends Component {
return baseOptions; return baseOptions;
} }
/**
* Initialize SVG icons.
*
* @param {boolean|string} svgIconsOption
* Takes a Boolean or a string as parameter, if true will activate
* the default icons, if the string represents an svg it will replace
* the default icons.
*/
initSvgIcons_(svgIconsOption) {
if (!svgIconsOption) {
return;
}
const hasCustomSvgIcons = typeof svgIconsOption === 'string';
const svgIcons = hasCustomSvgIcons ? svgIconsOption : icons;
// Add SVG Sprite to the DOM
const parser = new window.DOMParser();
const parsedSVG = parser.parseFromString(svgIcons, 'image/svg+xml');
const errorNode = parsedSVG.querySelector('parsererror');
if (errorNode) {
log.warn('Failed to load SVG Icons. Falling back to Font Icons.');
this.options_.experimentalSvgIcons = null;
} else {
const sprite = parsedSVG.documentElement;
sprite.style.display = 'none';
this.el_.appendChild(sprite);
this.addClass('vjs-svg-icons-enabled');
}
}
/** /**
* Set debug mode to enable/disable logs at info level. * Set debug mode to enable/disable logs at info level.
* *

View File

@ -1000,6 +1000,39 @@ QUnit.test('should revert to font icons if the SVG sprite cannot be loaded', fun
player.dispose(); player.dispose();
}); });
QUnit.test('should add a svg-icons-enabled classname when svg icons string is valid', function(assert) {
// Stub a successful parsing of the SVG sprite.
sinon.stub(window.DOMParser.prototype, 'parseFromString').returns({
querySelector: () => false,
documentElement: document.createElement('span')
});
assert.expect(1);
const player = TestHelpers.makePlayer({experimentalSvgIcons: '<svg></svg>'});
assert.ok(player.hasClass('vjs-svg-icons-enabled'), 'svg-icons-enabled classname added');
window.DOMParser.prototype.parseFromString.restore();
player.dispose();
});
QUnit.test('should revert to font icons if the SVG sprite string is not valid', function(assert) {
// Stub an unsuccessful parsing of the SVG sprite.
sinon.stub(window.DOMParser.prototype, 'parseFromString').returns({
querySelector: () => true
});
assert.expect(1);
const player = TestHelpers.makePlayer({experimentalSvgIcons: ''});
assert.ok(!player.hasClass('vjs-svg-icons-enabled'), 'svg-icons-enabled classname was not added');
window.DOMParser.prototype.parseFromString.restore();
player.dispose();
});
QUnit.test('should not add a touch-enabled classname when touch is not supported', function(assert) { QUnit.test('should not add a touch-enabled classname when touch is not supported', function(assert) {
assert.expect(1); assert.expect(1);