WARNING: THIS SITE IS A MIRROR OF GITHUB.COM / IT CANNOT LOGIN OR REGISTER ACCOUNTS / THE CONTENTS ARE PROVIDED AS-IS / THIS SITE ASSUMES NO RESPONSIBILITY FOR ANY DISPLAYED CONTENT OR LINKS / IF YOU FOUND SOMETHING MAY NOT GOOD FOR EVERYONE, CONTACT ADMIN AT ilovescratch@foxmail.com
Skip to content

Conversation

@ArgoZhang
Copy link
Member

@ArgoZhang ArgoZhang commented Dec 6, 2025

Link issues

fixes #796

Summary By Copilot

Regression?

  • Yes
  • No

Risk

  • High
  • Medium
  • Low

Verification

  • Manual (required)
  • Automated

Packaging changes reviewed?

  • Yes
  • No
  • N/A

☑️ Self Check before Merge

⚠️ Please check all items below before review. ⚠️

  • Doc is updated/provided or not needed
  • Demo is updated/provided or not needed
  • Merge the latest code from the main branch

Summary by Sourcery

Enhancements:

  • Clear global JSVideoPlugin references and remove the HikVision plugin script tag from the document head after plugin destruction to ensure proper cleanup and reinitialization.

Copilot AI review requested due to automatic review settings December 6, 2025 12:31
@bb-auto bb-auto bot added the enhancement New feature or request label Dec 6, 2025
@bb-auto bb-auto bot added this to the v9.2.0 milestone Dec 6, 2025
@sourcery-ai
Copy link

sourcery-ai bot commented Dec 6, 2025

Reviewer's guide (collapsed on small PRs)

Reviewer's Guide

Adds cleanup logic for the HikVision JS video plugin by explicitly destroying the plugin instance, clearing the global reference, and removing the plugin script tag from the document head when the plugin is destroyed.

Sequence diagram for destroying and removing the HikVision JSVideoPlugin

sequenceDiagram
    participant Caller
    participant hackJSDestroyPlugin
    participant JSVideoPluginInstance as oPlugin
    participant Window
    participant DocumentHead as document_head

    Caller->>hackJSDestroyPlugin: invoke()
    hackJSDestroyPlugin->>JSVideoPluginInstance: JS_DestroyPlugin(true)
    JSVideoPluginInstance-->>hackJSDestroyPlugin: plugin_destroyed

    hackJSDestroyPlugin->>Window: set JSVideoPlugin = null
    hackJSDestroyPlugin->>Window: delete JSVideoPlugin

    hackJSDestroyPlugin->>DocumentHead: removePlugin()
    DocumentHead->>DocumentHead: find script jsVideoPlugin_1_0_0
    DocumentHead->>DocumentHead: remove script node(s)
    DocumentHead-->>hackJSDestroyPlugin: scripts_removed

    hackJSDestroyPlugin-->>Caller: destroy_completed
Loading

Flow diagram for removePlugin cleanup logic

flowchart TD
    A["Call removePlugin"] --> B["Query all script elements in document.head"]
    B --> C["Filter scripts by src containing /jsVideoPlugin-1.0.0.min.js"]
    C --> D{"Any matching script nodes?"}
    D -->|Yes| E["Iterate over matching nodes by index"]
    E --> F["Remove current script node from document.head"]
    F --> G{"More nodes to remove?"}
    G -->|Yes| E
    G -->|No| H["Cleanup finished"]
    D -->|No| H
Loading

File-Level Changes

Change Details Files
Ensure HikVision JS video plugin is fully removed from the page when destroyed.
  • Call JS_DestroyPlugin(true) without returning its result to ensure subsequent cleanup code runs
  • Null out the global JSVideoPlugin reference and delete it from the window object after destroy
  • Introduce a removePlugin helper that locates /jsVideoPlugin-1.0.0.min.js script tags in document.head and removes them
  • Invoke the new removePlugin helper from hackJSDestroyPlugin after destroying the plugin
src/components/BootstrapBlazor.HikVision/wwwroot/hikvision.js

Assessment against linked issues

Issue Objective Addressed Explanation
#796 Add a function to remove the HikVision JS video plugin (including cleaning up the plugin instance and removing its script from the document).

Possibly linked issues


Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@ArgoZhang ArgoZhang merged commit 8450879 into master Dec 6, 2025
3 of 4 checks passed
@ArgoZhang ArgoZhang deleted the fix-hik branch December 6, 2025 12:31
Copy link

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey there - I've reviewed your changes - here's some feedback:

  • The hard-coded '/jsVideoPlugin-1.0.0.min.js' substring in removePlugin is brittle; consider matching against a configurable constant or a more flexible pattern (e.g., includes('jsVideoPlugin')) so future version changes don’t silently break the cleanup.
  • In removePlugin, you can simplify and slightly optimize by using a single loop over document.head.querySelectorAll('script[src]') and removing matching nodes in place instead of first creating an intermediate array and filtering.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- The hard-coded `'/jsVideoPlugin-1.0.0.min.js'` substring in `removePlugin` is brittle; consider matching against a configurable constant or a more flexible pattern (e.g., `includes('jsVideoPlugin')`) so future version changes don’t silently break the cleanup.
- In `removePlugin`, you can simplify and slightly optimize by using a single loop over `document.head.querySelectorAll('script[src]')` and removing matching nodes in place instead of first creating an intermediate array and filtering.

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a plugin cleanup function to the HikVision component to properly remove plugin resources when destroying the video player instance. The changes address issue #796 by implementing proper cleanup of the JSVideoPlugin global object and removing the dynamically loaded script from the DOM. The version is also updated from beta to stable release (10.0.0).

Key Changes

  • Added removePlugin() function to remove the jsVideoPlugin-1.0.0.min.js script from the DOM
  • Enhanced hackJSDestroyPlugin() to nullify the global JSVideoPlugin object and call the new cleanup function
  • Updated package version from 10.0.0-beta06 to 10.0.0 (stable release)

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
src/components/BootstrapBlazor.HikVision/wwwroot/hikvision.js Implements plugin cleanup logic to remove script tags and nullify global objects when destroying the video plugin
src/components/BootstrapBlazor.HikVision/BootstrapBlazor.HikVision.csproj Updates package version to stable release 10.0.0
Comments suppressed due to low confidence (3)

src/components/BootstrapBlazor.HikVision/wwwroot/hikvision.js:1

  • Unused import registerBootstrapBlazorModule.
import { addScript, registerBootstrapBlazorModule } from '../BootstrapBlazor/modules/utility.js';

src/components/BootstrapBlazor.HikVision/wwwroot/hikvision.js:39

  • Unused variable originalDestroy.
    const originalDestroy = JSVideoPlugin.prototype.JS_DestroyPlugin;

src/components/BootstrapBlazor.HikVision/wwwroot/hikvision.js:148

  • Unused variable logined.
    const { szDeviceIdentify, logined } = vision;

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

return this.oPlugin.JS_DestroyPlugin(true);
this.oPlugin.JS_DestroyPlugin(true);

JSVideoPlugin = null;
Copy link

Copilot AI Dec 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Attempting to set JSVideoPlugin = null in local scope has no effect on the global JSVideoPlugin. Since JSVideoPlugin is a global constructor, you should use window.JSVideoPlugin = null instead for proper cleanup.

Suggested change
JSVideoPlugin = null;
window.JSVideoPlugin = null;

Copilot uses AI. Check for mistakes.
const removePlugin = () => {
const scripts = [...document.head.querySelectorAll('script')]
const nodes = scripts.filter(function (link) {
return link.src.indexOf('/jsVideoPlugin-1.0.0.min.js') > -1
Copy link

Copilot AI Dec 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardcoded filename '/jsVideoPlugin-1.0.0.min.js' makes this function fragile. If the plugin version changes, this cleanup won't work. Consider extracting this as a constant or making it more flexible (e.g., using a pattern like /jsVideoPlugin.*\.js).

Suggested change
return link.src.indexOf('/jsVideoPlugin-1.0.0.min.js') > -1
return /\/jsVideoPlugin.*\.js$/.test(link.src);

Copilot uses AI. Check for mistakes.
Comment on lines +57 to +58
const nodes = scripts.filter(function (link) {
return link.src.indexOf('/jsVideoPlugin-1.0.0.min.js') > -1
Copy link

Copilot AI Dec 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The variable name link in the filter callback is misleading since the elements being filtered are <script> elements, not <link> elements. Consider renaming to script for clarity.

Suggested change
const nodes = scripts.filter(function (link) {
return link.src.indexOf('/jsVideoPlugin-1.0.0.min.js') > -1
const nodes = scripts.filter(function (script) {
return script.src.indexOf('/jsVideoPlugin-1.0.0.min.js') > -1

Copilot uses AI. Check for mistakes.
Comment on lines +56 to +59
const scripts = [...document.head.querySelectorAll('script')]
const nodes = scripts.filter(function (link) {
return link.src.indexOf('/jsVideoPlugin-1.0.0.min.js') > -1
})
Copy link

Copilot AI Dec 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolons after statements on lines 56 and 57. Consider adding semicolons for consistency with the rest of the codebase (lines 47, 49, 50, 51, etc.).

Suggested change
const scripts = [...document.head.querySelectorAll('script')]
const nodes = scripts.filter(function (link) {
return link.src.indexOf('/jsVideoPlugin-1.0.0.min.js') > -1
})
const scripts = [...document.head.querySelectorAll('script')];
const nodes = scripts.filter(function (link) {
return link.src.indexOf('/jsVideoPlugin-1.0.0.min.js') > -1
});

Copilot uses AI. Check for mistakes.
const scripts = [...document.head.querySelectorAll('script')]
const nodes = scripts.filter(function (link) {
return link.src.indexOf('/jsVideoPlugin-1.0.0.min.js') > -1
})
Copy link

Copilot AI Dec 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing semicolon after the closing brace. Consider adding a semicolon for consistency with the rest of the codebase.

Suggested change
})
});

Copilot uses AI. Check for mistakes.
Comment on lines +60 to +61
for (let index = 0; index < nodes.length; index++) {
document.head.removeChild(nodes[index])
Copy link

Copilot AI Dec 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A standard for-of loop would be more idiomatic and readable here: for (const node of nodes) { document.head.removeChild(node) }.

Suggested change
for (let index = 0; index < nodes.length; index++) {
document.head.removeChild(nodes[index])
for (const node of nodes) {
document.head.removeChild(node);

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(HikVision): add remove plugin function

2 participants