Skip to content
Merged
Changes from 3 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
78 changes: 75 additions & 3 deletions src/components/BootstrapBlazor.HikVision/wwwroot/hikvision.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,49 @@ export async function init(id) {
vision.iWndIndex = result.iWndIndex;
vision.inited = true;

const observer = new IntersectionObserver(() => {
if (checkVisibility(el)) {
Comment on lines +25 to +26
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

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

The IntersectionObserver callback doesn't use the entries parameter to check intersection state. The observer fires for both entering and leaving viewport, but the current implementation only checks visibility without considering the intersection state. This could cause unnecessary resize calls. Consider checking entries[0].isIntersecting to only resize when the element is actually intersecting the viewport.

Suggested change
const observer = new IntersectionObserver(() => {
if (checkVisibility(el)) {
const observer = new IntersectionObserver((entries) => {
if (entries[0].isIntersecting && checkVisibility(el)) {

Copilot uses AI. Check for mistakes.
WebVideoCtrl.I_Resize(el.offsetWidth, el.offsetHeight);
}
});
observer.observe(el);
vision.observer = observer;

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);
const el = document.getElementById(szId);
if (el) {
const visible = checkVisibility(el);
if (visible) {
return originalResize.call(this, e, t);
}
else {
WebVideoCtrl.I_HidPlugin();
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

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

There's a spelling error in the function name. The function is called I_HidPlugin() but it should likely be I_HidePlugin() based on the PR title and standard English conventions. Please verify the correct API method name from the WebVideoCtrl documentation.

Suggested change
WebVideoCtrl.I_HidPlugin();
WebVideoCtrl.I_HidePlugin();

Copilot uses AI. Check for mistakes.
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

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

The JS_Resize function should return a value when the element is not visible. Currently, when visible is false and I_HidPlugin() is called, the function doesn't return anything (implicit undefined). This could break calling code that expects a return value. Consider adding an explicit return statement.

Suggested change
WebVideoCtrl.I_HidPlugin();
WebVideoCtrl.I_HidPlugin();
return false;

Copilot uses AI. Check for mistakes.
}
}
}
}

const hackJSShowWnd = function () {
const originalShowWnd = JSVideoPlugin.prototype.JS_ShowWnd;
JSVideoPlugin.prototype.JS_ShowWnd = function () {
const { szId } = this.oOptions;
const el = document.getElementById(szId);
if (el) {
const visible = checkVisibility(el);
if (visible) {
return originalShowWnd.call(this);
}
else {
return new Promise((resolve, reject) => {
resolve();
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

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

The reject parameter is declared but never used. When returning an empty resolved promise for a non-visible element, this could mask errors. Consider whether this is the intended behavior or if the promise should be rejected instead to signal that the window cannot be shown.

Suggested change
resolve();
reject(new Error("Element is not visible, cannot show window."));

Copilot uses AI. Check for mistakes.
});
Comment on lines +64 to +66
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

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

This empty promise can be simplified using Promise.resolve() instead of constructing a new Promise with an executor function. This is more concise and clearer in intent.

Suggested change
return new Promise((resolve, reject) => {
resolve();
});
return Promise.resolve();

Copilot uses AI. Check for mistakes.
}
}
}
}
Expand Down Expand Up @@ -91,6 +125,7 @@ const initWindow = id => {
if (result.inited === false || (result.inited && result.iWndIndex !== -1)) {
clearInterval(handler);
hackJSResize();
hackJSShowWnd();
hackJSDestroyPlugin();
resolve(result);
}
Expand Down Expand Up @@ -309,7 +344,10 @@ export function dispose(id) {
const vision = Data.get(id);
Data.remove(id);

const { realPlaying, logined } = vision;
const { realPlaying, logined, observer } = vision;
if (observer) {
observer.disconnect();
}
if (realPlaying === true) {
stopRealPlay(id);
}
Expand All @@ -330,3 +368,37 @@ const getTagNameFirstValue = (xmlDoc, tagName, defaultValue = '0') => {
const getTagNameValues = (xmlDoc, tagName) => {
return xmlDoc.getElementsByTagName(tagName);
}

const checkVisibility = el => {
if (el.checkVisibility) {
return el.checkVisibility();
}
else {
return isVisible(el);
}
}

const isVisible = (element) => {
if (!element) return false;

const style = window.getComputedStyle(element);
if (style.display === 'none' || style.visibility === 'hidden' || parseFloat(style.opacity) < 0.01) {
Copy link

Copilot AI Dec 7, 2025

Choose a reason for hiding this comment

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

Using a magic number 0.01 without explanation makes the code harder to understand. Consider adding a comment explaining why this specific threshold is chosen for opacity checks, or define it as a named constant like MIN_VISIBLE_OPACITY.

Copilot uses AI. Check for mistakes.
return false;
}

const rect = element.getBoundingClientRect();
if (rect.width === 0 || rect.height === 0) {
return false;
}

let parent = element.parentElement;
while (parent) {
const parentStyle = window.getComputedStyle(parent);
if (parentStyle.display === 'none' || parentStyle.visibility === 'hidden') {
return false;
}
parent = parent.parentElement;
}

return true;
}