Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use common H5P eslint rules and make linter happy #8

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 19 additions & 7 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
"ecmaVersion": 2020
},
"rules": {
"valid-jsdoc": "off",
// H5P Group rules
"semi": ["error", "always"],
"indent": ["error", 2, { "SwitchCase": 1 }],
// "brace-style": ["error", "stroustrup"],
"brace-style": ["error", "stroustrup"],
"keyword-spacing": ["error", { "after": true }],
"comma-spacing": ["error", { "before": false, "after": true }],
"space-infix-ops": ["error", { "int32Hint": false }],
Expand All @@ -33,11 +33,23 @@
"asyncArrow": "always"
}],
"no-extra-boolean-cast": "off",
"no-console": ["error", { "allow": ["warn", "error", "log"] }],
"quotes": ["error", "double"],
"arrow-parens": ["error", "always"],
"object-curly-spacing": ["error", "always"],
"no-alert": ["error"]
"no-console": ["error", { "allow": ["warn", "error"] }],
"quotes": ["error", "single"],
// SNORDIAN specific rules
"arrow-parens": ["error", "always"],
"object-curly-spacing": ["error", "always"],
"prefer-template": ["error"],
"no-await-in-loop": ["error"],
"no-self-compare": ["error"],
"dot-notation": ["error"],
"no-eval": ["error"],
"no-implied-eval": ["error"],
"no-magic-numbers": ["warn", {
"ignoreArrayIndexes": true,
"ignoreDefaultValues": true,
"enforceConst": true,
"ignore": [-1, 0, 1]
}]
},
"plugins": ["jsdoc"],
"parser": "@babel/eslint-parser",
Expand Down
7 changes: 3 additions & 4 deletions scripts/app.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import React from 'react';
import { createRoot } from 'react-dom/client';
import Main from './components/Main';
import { H5PContext } from './context/H5PContext';

import { sanitizeContentTypeParameters } from './utils/sanitization';

export default class Wrapper extends H5P.EventDispatcher {
Expand Down Expand Up @@ -102,7 +100,8 @@ export default class Wrapper extends H5P.EventDispatcher {
const wrapperSize = this.wrapper.getBoundingClientRect();
if (wrapperSize.width < mobileThreshold) {
this.wrapper.classList.add('mobile');
} else {
}
else {
this.wrapper.classList.remove('mobile');
}
}
Expand Down
18 changes: 6 additions & 12 deletions scripts/components/Dialog/Dialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,12 @@ export default class Dialog extends React.Component {
}
}

handleResize(isNarrow) {
handleResize() {
if (this.el) {
// Reset to allow size growth
this.el.style.width = '';
this.el.style.height = '';
this.el.style.height = this.el.getBoundingClientRect().height + 'px';
//if (isNarrow) {
// This make IE11 not show the image. It seems to be the combination of
// flexbox and width:auto that is causing this
// Shrink dialog width for narrow images
// this.el.style.width = 'auto';
//}
this.el.style.height = `${this.el.getBoundingClientRect().height }px`;
}
}

Expand All @@ -43,10 +37,10 @@ export default class Dialog extends React.Component {
this.props.children.type === 'div'
? this.props.children
: React.Children.map(this.props.children, (child) =>
React.cloneElement(child, {
onResize: this.handleResize,
})
);
React.cloneElement(child, {
onResize: this.handleResize,
})
);

return (
<div className='h5p-text-overlay' role='dialog' aria-label={this.props.title}>
Expand Down
2 changes: 1 addition & 1 deletion scripts/components/Dialog/InteractionContent.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ export default class InteractionContent extends React.Component {
if (library.library.split(' ')[0] === 'H5P.Video') {
this.instance.on('stateChange', (e) => {
if (e.data === H5P.Video.PLAYING) {
this.props.onAudioIsPlaying('video-' + this.props.hotspot);
this.props.onAudioIsPlaying(`video-${ this.props.hotspot}`);
}
});
}
Expand Down
55 changes: 26 additions & 29 deletions scripts/components/HUD/Buttons/AudioButton.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';

import { H5PContext } from '../../../context/H5PContext';
import Button from './Button/Button';

export default class AudioButton extends React.Component {
constructor(props) {
Expand All @@ -13,13 +12,12 @@ export default class AudioButton extends React.Component {

/**
* Determine player ID from given props
*
* @param {Object} props
* @return {string}
* @param {object} props React props.
* @returns {string|undefined} Player ID.
*/
getPlayerId(props) {
if (props.sceneId !== undefined && props.sceneAudioTrack && props.sceneAudioTrack.length) {
return 'scene-' + props.sceneId;
return `scene-${ props.sceneId}`;
}
if (this.context.behavior.audio && this.context.behavior.audio.length) {
return 'global';
Expand All @@ -28,19 +26,17 @@ export default class AudioButton extends React.Component {

/**
* Get track from given player ID
*
* @param {string} props
* @return {Array}
* @param {string} id Player ID.
* @returns {object} Audio track.
*/
getTrack(id) {
return id === 'global' ? this.context.behavior.audio : this.props.sceneAudioTrack;
}

/**
* Get the audio player for the current track.
*
* @param {string} id
* @return {AudioElement} or 'null' if track isn't playable.
* @param {string} id Audio player id.
* @returns {HTMLAudioElement} or 'null' if track isn't playable.
*/
getPlayer(id) {
if (!id) {
Expand Down Expand Up @@ -76,7 +72,8 @@ export default class AudioButton extends React.Component {
if (id === this.props.isPlaying) {
// Pause and reset the player
player.pause();
} else {
}
else {
// Start the playback!
player.play();
}
Expand All @@ -103,6 +100,7 @@ export default class AudioButton extends React.Component {

/**
* React - runs after render.
* @param {object} prevProps Previous props.
*/
componentDidUpdate(prevProps) {
if (this.props.isPlaying && this.props.isPlaying !== prevProps.isPlaying) {
Expand Down Expand Up @@ -143,14 +141,15 @@ export default class AudioButton extends React.Component {

/**
* React - adds dom elements.
* @returns {HTMLElement} React element
*/
render() {
const id = this.getPlayerId(this.props);
if (!id) {
return null;
}

const type = 'audio-track' + (this.props.isPlaying === id ? ' active' : '');
const type = `audio-track${ this.props.isPlaying === id ? ' active' : ''}`;
return (
<Button
type={type}
Expand All @@ -167,42 +166,39 @@ export default class AudioButton extends React.Component {

/**
* Determine if the ID of the player belongs to a scene audio track.
*
* @param {string} id
* @return {boolean}
* @param {string} id Audio player id.
* @returns {boolean} True if the ID belongs to a scene audio.
*/
static isSceneAudio(id) {
return id && (id === 'global' || id.substr(0, 6) === 'scene-');
return id && (id === 'global' || id.startsWith('scene-'));
}

/**
* Determine if the ID of the player belongs to a scene audio track.
*
* @param {string} id
* @return {boolean}
* @param {string} id Audio player id.
* @returns {boolean} True if the ID belongs to an interaction audio.
*/
static isInteractionAudio(id) {
return id && id.substr(0, 12) === 'interaction-';
return id?.startsWith('interaction-');
}

/**
* Determine if the ID of the player belongs to a video interaction.
*
* @param {string} id
* @return {boolean}
* @param {string} id Audio player id.
* @returns {boolean} True if the ID belongs to a video interaction.
*/
static isVideoAudio(id) {
return id && id.substr(0, 6) === 'video-';
return id?.startsWith('video-');
}

/**
* Help create the audio player and find the approperiate source.
*
* @param {number} id Content ID
* @param {Array} sources
* @param {object} sources Source elements.
* @param {function} onPlay Callback
* @param {function} onStop Callback
* @param {boolean} loop
* @param {boolean} loop True if the audio should loop.
* @returns {null|HTMLAudioElement} Audio or 'null' if track isn't playable
*/
static createAudioPlayer(id, sources, onPlay, onStop, loop) {
// Check if browser supports audio.
Expand All @@ -221,7 +217,8 @@ export default class AudioButton extends React.Component {

if (!player.children.length) {
player = null; // Not supported
} else {
}
else {
player.controls = false;
player.preload = 'auto';
player.loop = loop;
Expand Down
11 changes: 6 additions & 5 deletions scripts/components/HUD/Buttons/Button/Button.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,29 +8,30 @@ export default class Button extends React.Component {

handleClick() {
if (!this.props.disabled) {
console.log(this.props);
this.props.onClick();
this.props.onClick();
}
}

/**
* React - after render
* @param {object} prevProps Previous props.
*/
componentDidUpdate(prevProps, prevState) {
componentDidUpdate(prevProps) {
if (prevProps.nextFocus !== this.props.nextFocus && this.props.type === this.props.nextFocus) {
this.element.focus();
}
}

/**
* React - create DOM elements
* React - create DOM elements.
* @returns {HTMLElement} React element.
*/
render() {
return (
<div className='btn-wrap'>
<button
ref={(el) => (this.element = el)}
className={'hud-btn ' + this.props.type}
className={`hud-btn ${ this.props.type}`}
onClick={this.handleClick.bind(this)}
aria-label={this.props.label}
disabled={!!this.props.disabled}
Expand Down
7 changes: 3 additions & 4 deletions scripts/components/HUD/HUD.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import React from 'react';
import './HUD.scss';

import { H5PContext } from '../../context/H5PContext';
import Button from './Buttons/Button/Button';

export default class HUD extends React.Component {
constructor(props) {
Expand All @@ -13,9 +12,8 @@ export default class HUD extends React.Component {

/**
* Help pick the audio track for the given scene.
*
* @param {Object} scene
* @return {Object}
* @param {object} scene Scene object.
* @returns {object} Props for the audio track.
*/
getSceneAudioTrack(scene) {
const props = {
Expand All @@ -39,6 +37,7 @@ export default class HUD extends React.Component {

/**
* React - create DOM elements
* @returns {HTMLElement} React element.
*/
render() {
return (
Expand Down
3 changes: 1 addition & 2 deletions scripts/components/LoadingSpinner/LoadingSpinner.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React from 'react';
import './LoadingSpinner.scss';

const LoadingSpinner = (props) => {
const LoadingSpinner = () => {
return (
<div id='outer'>
<div id='middle'>
Expand Down
Loading
Loading