Skip to content

Commit

Permalink
feat: refactor theme change functionality to use abstract class and s…
Browse files Browse the repository at this point in the history
…ubclasses for different chess sites
  • Loading branch information
pruizlezcano committed Feb 25, 2024
1 parent 8697022 commit bfaf267
Show file tree
Hide file tree
Showing 4 changed files with 161 additions and 104 deletions.
120 changes: 16 additions & 104 deletions src/chessThemer.ts
Original file line number Diff line number Diff line change
@@ -1,111 +1,23 @@
import browser from 'webextension-polyfill';
import { getBoardURL, getPieceURL } from './utils';
import Lichessorg from './sites/Lichessorg';
import ChessCom from './sites/Chesscom';

/**
* Change the board in Lichess.
* @param theme Theme name
*/
const lichessBoard = (theme: string): void => {
const boards: NodeListOf<HTMLElement> = document.querySelectorAll('cg-board');
for (const board of boards) {
board.style.backgroundImage = `url('${getBoardURL(theme)}')`;
}
};

/**
* Change the pieces in Lichess.
* @param theme Theme name
*/
const lichessPieces = (theme: string): void => {
const pieces: NodeListOf<HTMLElement> = document.querySelectorAll('piece');
for (const piece of pieces) {
const classList = piece.classList;
if (
!classList.contains('ghost') &&
(classList.contains('white') || classList.contains('black'))
) {
const nameRelation: { [key: string]: string } = {
black: 'b',
white: 'w',
pawn: 'p',
knight: 'n',
bishop: 'b',
rook: 'r',
queen: 'q',
king: 'k',
};
const pieceName = [...classList]
.sort(
(a, b) =>
Object.keys(nameRelation).indexOf(a) -
Object.keys(nameRelation).indexOf(b),
)
.map((c: string) => nameRelation[c])
.join('');
piece.style.backgroundImage = `url('${getPieceURL(theme, pieceName)}')`;
}
}
// TODO: change ghost pieces
};

/**
* Change the board in Chess.com.
* @param theme Theme name
*/
const chessComBoard = (theme: string): void => {
const board: HTMLElement | null = document.querySelector('wc-chess-board');
if (board != null)
board.style.backgroundImage = `url('${getBoardURL(theme)}')`;
const root: HTMLElement = document.querySelector(':root')!;
root.style.setProperty(
'--theme-board-style-image',
`url('${getBoardURL(theme)}')`,
);
};

/**
* Change the pieces in Chess.com.
* @param theme Theme name
*/
const chessComPieces = (theme: string): void => {
const pieces: NodeListOf<HTMLElement> = document.querySelectorAll('.piece');
const pieceNames = [
'wp',
'wr',
'wn',
'wb',
'wq',
'wk',
'bp',
'br',
'bn',
'bb',
'bq',
'bk',
];
for (const piece of pieces) {
const classList = piece.classList;
const name = pieceNames.find((name) => classList.contains(name));
if (name != null) {
piece.style.backgroundImage = `url('${getPieceURL(theme, name)}')`;
}
}
const root: HTMLElement = document.querySelector(':root')!;
for (const piece of pieceNames) {
root.style.setProperty(
`--theme-piece-set-${piece}`,
`url('${getPieceURL(theme, piece)}')`,
);
}
};
const lichess = new Lichessorg();
const chessCom = new ChessCom();

const changeTheme = (board: string, pieces: string, site: string) => {
if (site === 'lichess.org') {
lichessBoard(board);
lichessPieces(pieces);
console.log('Changing theme for lichess.org');

lichess.changeBoard(board);
lichess.changePieces(pieces);
lichess.startObserver();
} else if (site === 'www.chess.com') {
chessComBoard(board);
chessComPieces(pieces);
console.log('Changing theme for chess.com');
// FIXME: not working in https://www.chess.com/analysis?tab=analysis
chessCom.changeBoard(board);
chessCom.changePieces(pieces);
chessCom.startObserver();
}
};

Expand All @@ -129,8 +41,8 @@ browser.runtime.onMessage.addListener(
* Load the extension.
*/
(async () => {
console.info('Chess Themer v', chrome.runtime.getManifest().version);
const { pieces, board } = await chrome.storage.sync.get({
console.info('Chess Themer v', browser.runtime.getManifest().version);
const { pieces, board } = await browser.storage.sync.get({
pieces: 'neo',
board: 'green',
});
Expand Down
54 changes: 54 additions & 0 deletions src/sites/Chesscom.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import Site from './Site';
import { getBoardURL, getPieceURL } from '../utils';

/** Class for chess.com */
class ChessCom extends Site {
constructor() {
super();
}

changeBoard(theme: string): void {
const board: HTMLElement | null = document.querySelector('wc-chess-board');
if (board != null)
board.style.backgroundImage = `url('${getBoardURL(theme)}')`;
const root: HTMLElement = document.querySelector(':root')!;
root.style.setProperty(
'--theme-board-style-image',
`url('${getBoardURL(theme)}')`,
);
}

changePieces(theme: string): void {
const pieces: NodeListOf<HTMLElement> = document.querySelectorAll('.piece');
const pieceNames = [
'wp',
'wr',
'wn',
'wb',
'wq',
'wk',
'bp',
'br',
'bn',
'bb',
'bq',
'bk',
];
const root: HTMLElement = document.querySelector(':root')!;
for (const piece of pieceNames) {
root.style.setProperty(
`--theme-piece-set-${piece}`,
`url('${getPieceURL(theme, piece)}')`,
);
}
for (const piece of pieces) {
const classList = piece.classList;
const name = pieceNames.find((name) => classList.contains(name));
if (name != null) {
piece.style.backgroundImage = `var(--theme-piece-set-${name})`;
}
}
}
}

export default ChessCom;
49 changes: 49 additions & 0 deletions src/sites/Lichessorg.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import Site from './Site';
import { getBoardURL, getPieceURL } from '../utils';

/** Class for lichess.org */
class Lichessorg extends Site {
constructor() {
super();
}

changeBoard(theme: string): void {
const boards: NodeListOf<HTMLElement> =
document.querySelectorAll('cg-board');
for (const board of boards) {
board.style.backgroundImage = `url('${getBoardURL(theme)}')`;
}
this.boardTheme = theme;
}

changePieces(theme: string): void {
const pieces: NodeListOf<HTMLElement> = document.querySelectorAll('piece');
for (const piece of pieces) {
const classList = piece.classList;
if (classList.contains('white') || classList.contains('black')) {
const nameRelation: { [key: string]: string } = {
black: 'b',
white: 'w',
pawn: 'p',
knight: 'n',
bishop: 'b',
rook: 'r',
queen: 'q',
king: 'k',
};
const pieceName = [...classList]
.sort(
(a, b) =>
Object.keys(nameRelation).indexOf(a) -
Object.keys(nameRelation).indexOf(b),
)
.map((c: string) => nameRelation[c])
.join('');
piece.style.backgroundImage = `url('${getPieceURL(theme, pieceName)}')`;
}
}
this.piecesTheme = theme;
}
}

export default Lichessorg;
42 changes: 42 additions & 0 deletions src/sites/Site.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/** Abstract class for chess sites */
abstract class Site {
// Properties for the theme of the board and pieces
boardTheme: string;
piecesTheme: string;
constructor() {
this.boardTheme = '';
this.piecesTheme = '';
}

/** Abstract method to change the board theme, to be implemented by subclasses
* @param board - The theme of the board
*/
abstract changeBoard(board: string): void;

/** Abstract method to change the pieces theme, to be implemented by subclasses
* @param pieces - The theme of the pieces
*/
abstract changePieces(pieces: string): void;

/** Method to start observing changes in the DOM */
startObserver(): void {
const observer = new MutationObserver((mutations) => {
if (this.boardTheme === '' || this.piecesTheme === '') {
return;
}
mutations.forEach((mutation) => {
if (mutation.type === 'childList') {
this.changeBoard(this.boardTheme);
this.changePieces(this.piecesTheme);
}
});
});

observer.observe(document.body, {
childList: true,
subtree: true,
});
}
}

export default Site;

0 comments on commit bfaf267

Please sign in to comment.