Skip to content

Commit 2e8096a

Browse files
fix widget and layout issues
1 parent ec7a9d5 commit 2e8096a

File tree

3 files changed

+208
-258
lines changed

3 files changed

+208
-258
lines changed

content/knowrithm-widget.js

Lines changed: 96 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -10,144 +10,130 @@
1010

1111
var WIDGET_STYLE_ID = 'knowrithm-widget-style';
1212
var WIDGET_STYLE_HREF = '/styles/chat-widget-custom.css';
13-
var NAV_ELEMENTS = [
14-
{ id: 'navbar', minWidth: 0, display: 'block', zIndex: 90 },
15-
{ id: 'sidebar', minWidth: 1024, display: 'block', zIndex: 80 },
16-
{ id: 'content-side-layout', minWidth: 1280, display: 'flex', zIndex: 70 },
17-
{ id: 'table-of-contents-layout', minWidth: 1280, display: 'flex', zIndex: 70 },
18-
{ id: 'table-of-contents', minWidth: 1280, display: 'block', zIndex: 70 }
19-
];
20-
var navVisibilityGuardAttached = false;
21-
var navMutationObserver = null;
22-
var navElementObservers = {};
2313

24-
function observeNavElement(ruleId, element) {
25-
if (typeof MutationObserver === 'undefined' || !element) {
14+
function ensureWidgetOverridesLoaded() {
15+
if (typeof document === 'undefined') {
2616
return;
2717
}
28-
29-
var existing = navElementObservers[ruleId];
30-
if (existing && existing.element === element) {
18+
if (document.getElementById(WIDGET_STYLE_ID)) {
3119
return;
3220
}
3321

34-
if (existing && existing.observer) {
35-
existing.observer.disconnect();
36-
}
37-
38-
var observer = new MutationObserver(function () {
39-
applyAllNavigationRules();
40-
});
22+
var link = document.createElement('link');
23+
link.id = WIDGET_STYLE_ID;
24+
link.rel = 'stylesheet';
25+
link.href = WIDGET_STYLE_HREF;
26+
link.type = 'text/css';
27+
link.media = 'all';
28+
link.onerror = function (error) {
29+
console.error('Failed to load Knowrithm widget override styles:', error);
30+
};
4131

42-
observer.observe(element, { attributes: true, attributeFilter: ['class', 'style', 'hidden'] });
43-
navElementObservers[ruleId] = { observer: observer, element: element };
32+
(document.head || document.body).appendChild(link);
4433
}
4534

46-
function applyNavigationRule(rule) {
47-
var element = document.getElementById(rule.id);
48-
if (!element) return;
35+
var NAV_GUARD_TARGETS = [
36+
{ selector: '#navbar', minWidth: 0, display: 'block', zIndex: 120 },
37+
{ selector: '#sidebar', minWidth: 1024, display: 'block', zIndex: 80 },
38+
{ selector: '#content-side-layout', minWidth: 1280, display: 'flex', zIndex: 70 },
39+
{ selector: '#table-of-contents-layout', minWidth: 1280, display: 'flex', zIndex: 70 },
40+
{ selector: '#table-of-contents', minWidth: 1280, display: 'block', zIndex: 70 },
41+
{ selector: '#navbar .relative.hidden.lg\\:flex.items-center.flex-1.justify-center', minWidth: 1024, display: 'flex', zIndex: 110 },
42+
{ selector: '#navbar .flex-1.relative.hidden.lg\\:flex.items-center.ml-auto.justify-end', minWidth: 1024, display: 'flex', zIndex: 110 },
43+
{ selector: '#navbar .hidden.lg\\:flex.px-12.h-12', minWidth: 1024, display: 'flex', zIndex: 110 },
44+
{ selector: '#topbar-cta-button.hidden.lg\\:flex', minWidth: 1024, display: 'flex', zIndex: 110 }
45+
];
46+
var navGuardAttached = false;
47+
var navMutationObserver = null;
48+
var pendingNavFrame = null;
4949

50-
var meetsBreakpoint = true;
51-
if (rule.minWidth) {
52-
if (typeof window.matchMedia === 'function') {
53-
meetsBreakpoint = window.matchMedia('(min-width: ' + rule.minWidth + 'px)').matches;
54-
} else {
55-
meetsBreakpoint = window.innerWidth >= rule.minWidth;
56-
}
50+
function matchesMinWidth(rule) {
51+
if (!rule.minWidth) {
52+
return true;
53+
}
54+
if (typeof window === 'undefined') {
55+
return false;
56+
}
57+
if (typeof window.matchMedia === 'function') {
58+
return window.matchMedia('(min-width: ' + rule.minWidth + 'px)').matches;
5759
}
60+
return window.innerWidth >= rule.minWidth;
61+
}
5862

59-
if (meetsBreakpoint) {
60-
var displayValue = rule.display || 'block';
61-
element.style.setProperty('display', displayValue, 'important');
62-
element.style.setProperty('visibility', 'visible', 'important');
63-
element.style.setProperty('opacity', '1', 'important');
64-
element.style.setProperty('pointer-events', 'auto', 'important');
65-
if (typeof rule.zIndex === 'number') {
66-
element.style.setProperty('z-index', String(rule.zIndex), 'important');
67-
}
68-
if (element.hasAttribute('hidden')) {
69-
element.removeAttribute('hidden');
70-
}
63+
function applyNavGuardRule(rule) {
64+
if (typeof document === 'undefined') {
65+
return;
66+
}
67+
var element = document.querySelector(rule.selector);
68+
if (!element) {
69+
return;
70+
}
7171

72-
// Special handling for navbar removed to ensure layout independence
73-
// and prevent interfering with existing styles (e.g. SVG strokes).
74-
} else {
72+
if (!matchesMinWidth(rule)) {
7573
['display', 'visibility', 'opacity', 'pointer-events', 'z-index'].forEach(function (prop) {
7674
element.style.removeProperty(prop);
7775
});
76+
return;
7877
}
7978

80-
observeNavElement(rule.id, element);
79+
if (rule.display) {
80+
element.style.setProperty('display', rule.display, 'important');
81+
}
82+
element.style.setProperty('visibility', 'visible', 'important');
83+
element.style.setProperty('opacity', '1', 'important');
84+
element.style.setProperty('pointer-events', 'auto', 'important');
85+
if (typeof rule.zIndex === 'number') {
86+
element.style.setProperty('z-index', String(rule.zIndex), 'important');
87+
}
88+
if (element.hasAttribute('hidden')) {
89+
element.removeAttribute('hidden');
90+
}
8191
}
8292

83-
function applyAllNavigationRules() {
84-
NAV_ELEMENTS.forEach(applyNavigationRule);
93+
function enforceNavigationGuards() {
94+
NAV_GUARD_TARGETS.forEach(applyNavGuardRule);
8595
}
8696

87-
function maintainNavigationVisibility() {
88-
if (typeof window === 'undefined' || typeof document === 'undefined') return;
89-
90-
applyAllNavigationRules();
91-
92-
if (navVisibilityGuardAttached) {
97+
function scheduleNavigationGuard() {
98+
if (pendingNavFrame || typeof window === 'undefined') {
9399
return;
94100
}
95-
navVisibilityGuardAttached = true;
96-
97-
var queries = NAV_ELEMENTS
98-
.filter(function (rule) { return rule.minWidth; })
99-
.map(function (rule) { return '(min-width: ' + rule.minWidth + 'px)'; })
100-
.filter(function (query, index, self) { return self.indexOf(query) === index; });
101+
pendingNavFrame = window.requestAnimationFrame(function () {
102+
pendingNavFrame = null;
103+
enforceNavigationGuards();
104+
});
105+
}
101106

102-
function handleViewportChange() {
103-
applyAllNavigationRules();
107+
function attachNavigationGuards() {
108+
if (navGuardAttached || typeof document === 'undefined') {
109+
return;
104110
}
111+
navGuardAttached = true;
112+
enforceNavigationGuards();
105113

106-
if (queries.length && typeof window.matchMedia === 'function') {
107-
queries.forEach(function (query) {
108-
var mediaQuery = window.matchMedia(query);
109-
if (typeof mediaQuery.addEventListener === 'function') {
110-
mediaQuery.addEventListener('change', handleViewportChange);
111-
} else if (typeof mediaQuery.addListener === 'function') {
112-
mediaQuery.addListener(handleViewportChange);
113-
}
114-
});
115-
} else {
116-
window.addEventListener('resize', handleViewportChange, { passive: true });
114+
if (typeof window !== 'undefined') {
115+
window.addEventListener('resize', scheduleNavigationGuard, { passive: true });
117116
}
118117

119-
if (typeof MutationObserver !== 'undefined') {
120-
NAV_ELEMENTS.forEach(function (rule) {
121-
var target = document.getElementById(rule.id);
122-
if (target) {
123-
var observer = new MutationObserver(handleViewportChange);
124-
// For navbar, we need to watch subtree attributes to catch icon style changes
125-
if (rule.id === 'navbar') {
126-
observer.observe(target, {
127-
attributes: true,
128-
attributeFilter: ['class', 'style', 'fill', 'stroke', 'color'],
129-
subtree: true
130-
});
131-
} else {
132-
observer.observe(target, { attributes: true, attributeFilter: ['class', 'style'] });
118+
if (typeof MutationObserver !== 'undefined' && document.body) {
119+
navMutationObserver = new MutationObserver(function (mutations) {
120+
for (var i = 0; i < mutations.length; i++) {
121+
var target = mutations[i].target;
122+
for (var j = 0; j < NAV_GUARD_TARGETS.length; j++) {
123+
var rule = NAV_GUARD_TARGETS[j];
124+
var element = document.querySelector(rule.selector);
125+
if (element && (target === element || element.contains(target))) {
126+
scheduleNavigationGuard();
127+
return;
128+
}
133129
}
134130
}
135131
});
136-
137-
if (!navMutationObserver) {
138-
navMutationObserver = new MutationObserver(function () {
139-
applyAllNavigationRules();
140-
});
141-
142-
if (document.body) {
143-
navMutationObserver.observe(document.body, { childList: true, subtree: true });
144-
} else {
145-
document.addEventListener('DOMContentLoaded', function () {
146-
if (!navMutationObserver) return;
147-
navMutationObserver.observe(document.body, { childList: true, subtree: true });
148-
});
149-
}
150-
}
132+
navMutationObserver.observe(document.body, {
133+
attributes: true,
134+
attributeFilter: ['style', 'hidden', 'class'],
135+
subtree: true
136+
});
151137
}
152138
}
153139

@@ -250,7 +236,8 @@
250236

251237
// Wait for DOM to be ready
252238
function initWidget() {
253-
maintainNavigationVisibility();
239+
ensureWidgetOverridesLoaded();
240+
attachNavigationGuards();
254241

255242
// Fix form autofill issues on initial load
256243
fixFormAutofillIssues();
@@ -306,21 +293,6 @@
306293
}
307294
}
308295

309-
// Ensure the scoped widget stylesheet is loaded once
310-
if (!document.getElementById(WIDGET_STYLE_ID)) {
311-
var link = document.createElement('link');
312-
link.id = WIDGET_STYLE_ID;
313-
link.rel = 'stylesheet';
314-
link.href = WIDGET_STYLE_HREF;
315-
link.type = 'text/css';
316-
link.media = 'all';
317-
link.onerror = function (error) {
318-
console.error('Failed to load Knowrithm widget styles:', error);
319-
};
320-
321-
(document.head || document.body).appendChild(link);
322-
}
323-
324296
// Configure the widget BEFORE loading the script
325297
window.AIChatWidget = {
326298
agentId: "2b041b45-a585-47e9-abaf-ebaad766bce9",
@@ -364,8 +336,10 @@
364336
script.async = true;
365337
script.defer = true; // Defer to avoid blocking page load
366338

339+
script.onload = ensureWidgetOverridesLoaded;
367340
script.onerror = function (error) {
368341
console.error('Failed to load Knowrithm widget script:', error);
342+
ensureWidgetOverridesLoaded();
369343
};
370344

371345
// Append to body instead of head to avoid interfering with page initialization

0 commit comments

Comments
 (0)