Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk.Razor">

<PropertyGroup>
<Version>10.0.0-beta05</Version>
<Version>10.0.0</Version>
</PropertyGroup>

<PropertyGroup>
Expand Down
31 changes: 28 additions & 3 deletions src/components/BootstrapBlazor.HikVision/wwwroot/hikvision.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { addScript } from '../BootstrapBlazor/modules/utility.js';
import { addScript, registerBootstrapBlazorModule } from '../BootstrapBlazor/modules/utility.js';
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.

Unused import registerBootstrapBlazorModule.

Suggested change
import { addScript, registerBootstrapBlazorModule } from '../BootstrapBlazor/modules/utility.js';
import { addScript } from '../BootstrapBlazor/modules/utility.js';

Copilot uses AI. Check for mistakes.
import Data from '../BootstrapBlazor/modules/data.js';

export async function init(id) {
await addScript('./_content/BootstrapBlazor.HikVision/jsVideoPlugin-1.0.0.min.js');
await addScript('./_content/BootstrapBlazor.HikVision/webVideoCtrl.js');

if (window.$ === void 0) {
Expand All @@ -26,6 +25,29 @@ export async function init(id) {
return true;
}

const hackJSResize = function () {
const originalResize = JSVideoPlugin.prototype.JS_Resize;
JSVideoPlugin.prototype.JS_Resize = function (e, t) {
const { szId } = this.oOptions;
if (document.getElementById(szId)) {
return originalResize.call(this, e, t);
}
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 hacked JS_Resize function doesn't return anything when the element is not found. This could lead to unexpected behavior for callers expecting a return value. Consider returning a default value or explicitly returning undefined.

Suggested change
}
}
return undefined;

Copilot uses AI. Check for mistakes.
}
}
Comment on lines +28 to +36
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.

Consider checking if JSVideoPlugin exists before attempting to hack its prototype. If the script is not loaded, this could throw a ReferenceError.

Copilot uses AI. Check for mistakes.

const hackJSDestroyPlugin = function () {
const originalDestroy = JSVideoPlugin.prototype.JS_DestroyPlugin;
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.

Unused variable originalDestroy.

Suggested change
const originalDestroy = JSVideoPlugin.prototype.JS_DestroyPlugin;

Copilot uses AI. Check for mistakes.
JSVideoPlugin.prototype.JS_DestroyPlugin = function (n) {
const origianlSendRequestProxy = this.oPlugin.oRequest.oRequest.sendRequest;
this.oPlugin.oRequest.oRequest.sendRequest = function (r) {
if (this.oWebSocket && WebSocket.OPEN === this.oWebSocket.readyState) {
return origianlSendRequestProxy.call(this, r);
Comment on lines +41 to +44
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.

Typo in variable name: origianlSendRequestProxy should be originalSendRequestProxy. The letter 'a' and 'l' are swapped.

Suggested change
const origianlSendRequestProxy = this.oPlugin.oRequest.oRequest.sendRequest;
this.oPlugin.oRequest.oRequest.sendRequest = function (r) {
if (this.oWebSocket && WebSocket.OPEN === this.oWebSocket.readyState) {
return origianlSendRequestProxy.call(this, r);
const originalSendRequestProxy = this.oPlugin.oRequest.oRequest.sendRequest;
this.oPlugin.oRequest.oRequest.sendRequest = function (r) {
if (this.oWebSocket && WebSocket.OPEN === this.oWebSocket.readyState) {
return originalSendRequestProxy.call(this, r);

Copilot uses AI. Check for mistakes.
Comment on lines +41 to +44
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.

Typo in variable name: origianlSendRequestProxy should be originalSendRequestProxy. The letter 'a' and 'l' are swapped (same typo as line 41).

Suggested change
const origianlSendRequestProxy = this.oPlugin.oRequest.oRequest.sendRequest;
this.oPlugin.oRequest.oRequest.sendRequest = function (r) {
if (this.oWebSocket && WebSocket.OPEN === this.oWebSocket.readyState) {
return origianlSendRequestProxy.call(this, r);
const originalSendRequestProxy = this.oPlugin.oRequest.oRequest.sendRequest;
this.oPlugin.oRequest.oRequest.sendRequest = function (r) {
if (this.oWebSocket && WebSocket.OPEN === this.oWebSocket.readyState) {
return originalSendRequestProxy.call(this, r);

Copilot uses AI. Check for mistakes.
}
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 hacked sendRequest function doesn't return anything when the WebSocket is not open. This could lead to unexpected behavior for callers expecting a return value. Consider returning a default value or explicitly handling this case.

Suggested change
}
}
// Explicitly return a default value when WebSocket is not open
return null;

Copilot uses AI. Check for mistakes.
}
return this.oPlugin.JS_DestroyPlugin(true);
Comment on lines +38 to +47
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

issue (bug_risk): Overriding JS_DestroyPlugin bypasses the original implementation and ignores its arguments.

This override replaces JSVideoPlugin.prototype.JS_DestroyPlugin without ever calling originalDestroy, and it always invokes this.oPlugin.JS_DestroyPlugin(true) regardless of n. This changes the method’s contract and may break callers or future upstream changes that depend on the argument. Please preserve the original behavior by delegating to originalDestroy with the original arguments (potentially after wrapping sendRequest).

}
}
Comment on lines +38 to +49
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.

Consider checking if JSVideoPlugin exists before attempting to hack its prototype. If the script is not loaded, this could throw a ReferenceError.

Copilot uses AI. Check for mistakes.

const initWindow = id => {
const result = { inited: null, iWndIndex: -1 };
WebVideoCtrl.I_InitPlugin({
Expand Down Expand Up @@ -53,7 +75,9 @@ const initWindow = id => {
return new Promise((resolve, reject) => {
const handler = setInterval(() => {
if (result.inited === false || (result.inited && result.iWndIndex !== -1)) {
clearInterval(handler)
clearInterval(handler);
hackJSResize();
hackJSDestroyPlugin();
Comment on lines +79 to +80
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

suggestion: Prototype hacks are applied every time initWindow resolves, which can repeatedly reassign the same methods.

hackJSResize and hackJSDestroyPlugin patch JSVideoPlugin.prototype, and initWindow can run multiple times, causing the same prototype methods to be reassigned on each successful init. This adds unnecessary repetition and makes it harder to see when the patch is applied. Consider a module-level guard (e.g. let jsPluginPatched = false) so the prototype is patched only once.

Suggested implementation:

}

let jsPluginPatched = false;

const initWindow = id => {
            if (result.inited === false || (result.inited && result.iWndIndex !== -1)) {
                clearInterval(handler);
                if (!jsPluginPatched) {
                    hackJSResize();
                    hackJSDestroyPlugin();
                    jsPluginPatched = true;
                }
                resolve(result);
            }

Comment on lines +79 to +80
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 hack functions are called unconditionally, even when result.inited === false. Consider only applying these hacks when initialization succeeds to avoid potential errors when the plugin is not properly initialized.

Suggested change
hackJSResize();
hackJSDestroyPlugin();
if (result.inited === true) {
hackJSResize();
hackJSDestroyPlugin();
}

Copilot uses AI. Check for mistakes.
resolve(result);
}
}, 16);
Expand Down Expand Up @@ -278,6 +302,7 @@ export function dispose(id) {
if (logined === true) {
logout(id);
}
WebVideoCtrl.I_Stop();
WebVideoCtrl.I_DestroyPlugin();

}
Expand Down