18
18
style . textContent = `
19
19
#dify-chatbot-bubble-button {
20
20
background-color: #4B39EF !important;
21
+ bottom: 0.25rem !important;
22
+ right: 0.25rem !important;
21
23
}
22
24
` ;
23
25
document . head . appendChild ( style ) ;
26
+
27
+ // Function to force positioning
28
+ function forceChatbotPosition ( ) {
29
+ // Handle all possible widget states
30
+ const allWidgets = document . querySelectorAll ( '.dify-chatbot-widget, [class*="dify"], [id*="dify"]' ) ;
31
+ const allWindows = document . querySelectorAll ( '#dify-chatbot-bubble-window, [class*="chat"], [class*="window"]' ) ;
32
+
33
+ // Position all widget containers
34
+ allWidgets . forEach ( widget => {
35
+ widget . style . position = 'fixed' ;
36
+ widget . style . bottom = '0' ;
37
+ widget . style . right = '0' ;
38
+ widget . style . top = 'auto' ;
39
+ widget . style . left = 'auto' ;
40
+ widget . style . zIndex = '1000' ;
41
+ widget . style . margin = '0' ;
42
+ widget . style . transform = 'none' ;
43
+ } ) ;
44
+
45
+ // Position all window elements
46
+ allWindows . forEach ( window => {
47
+ window . style . position = 'fixed' ;
48
+ window . style . bottom = '0' ;
49
+ window . style . right = '0' ;
50
+ window . style . top = 'auto' ;
51
+ window . style . left = 'auto' ;
52
+ window . style . margin = '0' ;
53
+ window . style . transform = 'none' ;
54
+ } ) ;
55
+
56
+ // Also handle any iframe that might be created
57
+ const iframes = document . querySelectorAll ( 'iframe[src*="dify"], iframe[src*="udify"]' ) ;
58
+ iframes . forEach ( iframe => {
59
+ iframe . style . position = 'fixed' ;
60
+ iframe . style . bottom = '0' ;
61
+ iframe . style . right = '0' ;
62
+ iframe . style . top = 'auto' ;
63
+ iframe . style . left = 'auto' ;
64
+ iframe . style . margin = '0' ;
65
+ iframe . style . transform = 'none' ;
66
+ } ) ;
67
+
68
+ // Special handling for expanded state - target any element that might be the expanded window
69
+ const expandedElements = document . querySelectorAll ( '[data-state="expanded"], [class*="expanded"], [style*="position: fixed"]' ) ;
70
+ expandedElements . forEach ( element => {
71
+ element . style . position = 'fixed' ;
72
+ element . style . bottom = '0' ;
73
+ element . style . right = '0' ;
74
+ element . style . top = 'auto' ;
75
+ element . style . left = 'auto' ;
76
+ element . style . margin = '0' ;
77
+ element . style . transform = 'none' ;
78
+ element . style . zIndex = '1000' ;
79
+ } ) ;
80
+
81
+ // Also force any element with a high z-index to stay at bottom
82
+ const highZIndexElements = document . querySelectorAll ( '[style*="z-index: 999"], [style*="z-index: 1000"], [style*="z-index: 1001"]' ) ;
83
+ highZIndexElements . forEach ( element => {
84
+ if ( element . style . position === 'fixed' ) {
85
+ element . style . bottom = '0' ;
86
+ element . style . right = '0' ;
87
+ element . style . top = 'auto' ;
88
+ element . style . left = 'auto' ;
89
+ }
90
+ } ) ;
91
+ }
92
+
93
+ // Apply positioning after script loads
94
+ setTimeout ( forceChatbotPosition , 1000 ) ;
95
+ setTimeout ( forceChatbotPosition , 2000 ) ;
96
+ setTimeout ( forceChatbotPosition , 3000 ) ;
97
+ setTimeout ( forceChatbotPosition , 4000 ) ;
98
+ setTimeout ( forceChatbotPosition , 5000 ) ;
99
+
100
+ // Also watch for changes
101
+ const observer = new MutationObserver ( ( ) => {
102
+ forceChatbotPosition ( ) ;
103
+ // Run again after a short delay to catch any delayed changes
104
+ setTimeout ( forceChatbotPosition , 100 ) ;
105
+ setTimeout ( forceChatbotPosition , 500 ) ;
106
+ } ) ;
107
+ observer . observe ( document . body , { childList : true , subtree : true , attributes : true } ) ;
108
+
109
+ // Also run continuously for the first 10 seconds
110
+ let runCount = 0 ;
111
+ const continuousInterval = setInterval ( ( ) => {
112
+ forceChatbotPosition ( ) ;
113
+ runCount ++ ;
114
+ if ( runCount > 20 ) { // Stop after 10 seconds (20 * 500ms)
115
+ clearInterval ( continuousInterval ) ;
116
+ }
117
+ } , 500 ) ;
24
118
} ) ( ) ;
0 commit comments