diff --git a/.github/workflows/verify-pull-request.yml b/.github/workflows/verify-pull-request.yml index e80d566..1d4278d 100644 --- a/.github/workflows/verify-pull-request.yml +++ b/.github/workflows/verify-pull-request.yml @@ -1,6 +1,7 @@ name: Verify Pull Request on: + workflow_dispatch: pull_request: branches: - develop diff --git a/CHANGELOG.md b/CHANGELOG.md index 3185fa4..a7aa4fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,16 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.1.2] - 2025-11-12 + +### Fixed + +- CSS selectors for `Members Only` videos + +### Added + +- Github Actions CI and security scan workflow + ## [1.1.1] - 2025-10-22 ### Fixed diff --git a/README.md b/README.md index a759de5..7b0b8b4 100644 --- a/README.md +++ b/README.md @@ -22,10 +22,11 @@ A browser extension that filters out watched and members-only YouTube videos, ke ## Development - git clone this repository. -- run `npm i` -- run `npm start` or `./ddstart` for docker-desktop on Linux +- Run `npm i` +- Run `npm start` or `./ddstart` for docker-desktop on Linux - Load the extension in your browser: - Firefox: Go to `about:debugging#/runtime/this-firefox` and select "Load Temporary Add-on." +- Create a `feature/`, `bugfix/`, etc. branch, where you'll commit your code ## Build and Package (for Mozilla code reviewers) @@ -33,14 +34,15 @@ A browser extension that filters out watched and members-only YouTube videos, ke ## Manual Build Pipeline (for extension developers) -- Create a pull request to merge your `feature` branch into `develop` branch +- Create a pull request to merge your `feature/`, `bugfix/`, etc. branch into the `develop` branch - Create `release/v` off `develop` branch - Update `version` in `package.json`, `manifest.json`, `CHANGELOG.md` - Run `npm install` to update the version in `package-lock.json` +- Commit the changes on the `release/v` branch - To build for production, and package into `artifacts/youtube_magic-.zip`: run: `npm run build` or `./ddbuild` for docker-desktop on Linux - Submit zip file from `artifacts/` to https://addons.mozilla.org - Once the extension is live, merge `release/v` into `develop` and `main` -- `git tag -a v -m "Release : - Published to Firefox Add-ons"` +- Tag the latest commit: `git tag -a v -m "Release : - Published to Firefox Add-ons"` ## Zip Source Code diff --git a/package-lock.json b/package-lock.json index 7a2fdd4..9446b5f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "youtube-magic", - "version": "1.1.1", + "version": "1.1.2", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "youtube-magic", - "version": "1.1.1", + "version": "1.1.2", "license": "MIT", "dependencies": { "react": "^19.2.0", diff --git a/package.json b/package.json index 70c04ae..0327598 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "youtube-magic", - "version": "1.1.1", + "version": "1.1.2", "main": "index.ts", "type": "module", "scripts": { diff --git a/src/code/content/dom.ts b/src/code/content/dom.ts index 3a592c4..9e02d19 100644 --- a/src/code/content/dom.ts +++ b/src/code/content/dom.ts @@ -44,7 +44,7 @@ export default class Dom { /** * returns all HTML elements for a given selector (`selector` parameter), including the matching parent (`element` parameter) and its children */ - public static findAll(element: HTMLElement, selector: string) { + public static _findAll(element: HTMLElement, selector: string) { const elements: HTMLElement[] = []; if (element.matches(selector)) { @@ -59,22 +59,6 @@ export default class Dom { return elements; } - /** - * checks if any elements returned by the `findAll` method have text content - */ - public static anySelectedElementHasText( - element: HTMLElement, - selector: string, - ) { - const elements = this.findAll(element, selector); - - if (elements) { - return elements.some((element) => element.textContent); - } else { - return false; - } - } - /** * returns the descendant's ancestor HTML element selected by `ancestorSelector`, if found, or null */ diff --git a/src/code/content/element.ts b/src/code/content/element.ts index 4d9d584..a0648fb 100644 --- a/src/code/content/element.ts +++ b/src/code/content/element.ts @@ -27,6 +27,9 @@ export default class Element { return this.youTubePageType; } + /** + * returns the outermost `contents` element that is visible on the page + */ public get newContents() { /* may include invisible elements */ const contentsElements = Array.from( @@ -89,6 +92,10 @@ export default class Element { return this.visibleVideos.length; } + public isVideo(element: HTMLElement) { + return element.matches(selectors.video[this.pageType]); + } + public waitForAndGetAndSetContents(): Promise { return new Promise((resolve) => { this.contents = this.newContents; @@ -136,7 +143,24 @@ export default class Element { } public hasMembersOnlyBadge(element: HTMLElement) { - return Dom.anySelectedElementHasText(element, selectors.membersOnlyBadge); + if (this.isVideo(element)) { + const membersOnlyElements = element.querySelectorAll( + selectors.membersOnlyBadge, + ); + + return [...membersOnlyElements].some((element) => element.textContent); + } + + if (element.textContent) { + const membersOnlyElement = Dom.getAncestor( + selectors.membersOnlyBadge, + element, + ); + + return !!membersOnlyElement; + } + + return false; } public hasChipBeenClicked(event: Event) { diff --git a/src/code/content/filter.ts b/src/code/content/filter.ts index 793b604..b2106ec 100644 --- a/src/code/content/filter.ts +++ b/src/code/content/filter.ts @@ -182,7 +182,7 @@ export default class Filter { } /** - * @param element - can be a video element or an element inside a video. The element and its children are checked recursively for the presence of elements that indicate the video should get hidden, based on the enabled filters + * @param element - can be a video element, or an element inside a video if detected by Mutation Observer. The element and its children are checked recursively for the presence of elements that indicate the video should get hidden, based on the enabled filters */ private shouldHideVideo(element: HTMLElement) { if (this.watchedFilterEnabled && this.element.hasProgressBar(element)) { diff --git a/src/code/content/observer.ts b/src/code/content/observer.ts index 7ec7bbb..dcb161a 100644 --- a/src/code/content/observer.ts +++ b/src/code/content/observer.ts @@ -17,7 +17,7 @@ export default class Observer { public constructor( private observedElement: HTMLElement, private eventBus: EventTarget, - private exclusionSelectors?: string[], + private exclusionSelectors?: string[] /* identifies elements that should not be acted on */, ) { this.mutationObserver = this.create(); } diff --git a/src/manifest.json b/src/manifest.json index f666c5f..f224f87 100644 --- a/src/manifest.json +++ b/src/manifest.json @@ -1,7 +1,7 @@ { "manifest_version": 2, "name": "YouTube Magic", - "version": "1.1.1", + "version": "1.1.2", "description": "Filters out YouTube videos using UI indicators.", "permissions": ["management", "tabs", "activeTab", "storage"], "background": {