|
138 | 138 | w.Asc = w.Asc || {}; |
139 | 139 | w.Asc.plugin = w.Asc.plugin || {}; |
140 | 140 |
|
141 | | - function getBaseUrl() { |
142 | | - /* The plugin iframe and Nextcloud share the same nginx origin */ |
| 141 | + /** |
| 142 | + * Get Nextcloud base URL with 3-layer fallback strategy |
| 143 | + * Layer 1: Window config object (most reliable, pre-configured) |
| 144 | + * Layer 2: Query parameter from URL (allows manual override) |
| 145 | + * Layer 3: Auto-detect from origin (fallback when in same iframe context) |
| 146 | + */ |
| 147 | + function getNextcloudUrl() { |
| 148 | + // Layer 1: Pre-configured by Nextcloud app |
| 149 | + if (w.__LIBRESIGN_CONFIG__ && w.__LIBRESIGN_CONFIG__.nextcloudUrl) { |
| 150 | + return w.__LIBRESIGN_CONFIG__.nextcloudUrl; |
| 151 | + } |
| 152 | + |
| 153 | + // Layer 2: Query parameter for manual override |
| 154 | + var params = new URLSearchParams(w.location.search); |
| 155 | + if (params.has('nc_url')) { |
| 156 | + return params.get('nc_url'); |
| 157 | + } |
| 158 | + |
| 159 | + // Layer 3: Auto-detect from current origin (same-origin context) |
143 | 160 | return w.location.origin; |
144 | 161 | } |
145 | 162 |
|
| 163 | + /** |
| 164 | + * Get current document ID and filename from Document Server context |
| 165 | + */ |
| 166 | + function getDocumentContext() { |
| 167 | + var title = document.title || ''; |
| 168 | + var context = { |
| 169 | + fileName: title, |
| 170 | + fileId: null, |
| 171 | + fileUrl: null |
| 172 | + }; |
| 173 | + |
| 174 | + // Try to extract from ONLYOFFICE context if available |
| 175 | + if (w.Asc && w.Asc.documentId) { |
| 176 | + context.fileId = w.Asc.documentId; |
| 177 | + } |
| 178 | + |
| 179 | + // Try to extract from query params if available |
| 180 | + var params = new URLSearchParams(w.location.search); |
| 181 | + if (params.has('filePath')) { |
| 182 | + context.fileUrl = decodeURIComponent(params.get('filePath')); |
| 183 | + context.fileName = context.fileUrl.split('/').pop(); |
| 184 | + } |
| 185 | + |
| 186 | + return context; |
| 187 | + } |
| 188 | + |
| 189 | + /** |
| 190 | + * Open LibreSign in new tab (default behavior) |
| 191 | + * Allows communication back via window.opener after signing |
| 192 | + */ |
| 193 | + function openLibreSignNewTab(nextcloudUrl, documentContext) { |
| 194 | + var url = nextcloudUrl + '/apps/libresign/#/f/filelist/sign'; |
| 195 | + var target = '_blank'; |
| 196 | + |
| 197 | + var child = w.open(url, target); |
| 198 | + |
| 199 | + if (child) { |
| 200 | + // Allow new window to communicate back when signing complete |
| 201 | + child.postMessage({ |
| 202 | + type: 'libresign:documentContext', |
| 203 | + context: documentContext |
| 204 | + }, nextcloudUrl); |
| 205 | + } |
| 206 | + } |
| 207 | + |
| 208 | + /** |
| 209 | + * Handle sign button click |
| 210 | + * Future: Will support modal/sidebar modes via postMessage to Nextcloud |
| 211 | + */ |
| 212 | + function handleSignClick() { |
| 213 | + var nextcloudUrl = getNextcloudUrl(); |
| 214 | + var context = getDocumentContext(); |
| 215 | + |
| 216 | + // Log for debugging configuration |
| 217 | + console.log('[LibreSign Plugin]', { |
| 218 | + nextcloudUrl: nextcloudUrl, |
| 219 | + context: context, |
| 220 | + strategy: 'new-tab' |
| 221 | + }); |
| 222 | + |
| 223 | + openLibreSignNewTab(nextcloudUrl, context); |
| 224 | + } |
| 225 | + |
| 226 | + /** |
| 227 | + * Handle request signatures button click |
| 228 | + * Opens request signature view in new tab |
| 229 | + */ |
| 230 | + function handleRequestClick() { |
| 231 | + var nextcloudUrl = getNextcloudUrl(); |
| 232 | + var url = nextcloudUrl + '/apps/libresign/#/f/request'; |
| 233 | + |
| 234 | + w.open(url, '_blank'); |
| 235 | + } |
| 236 | + |
146 | 237 | function applyTheme(isDark) { |
147 | 238 | document.body.classList.toggle('dark', isDark); |
148 | 239 | document.getElementById('logo').src = isDark |
149 | 240 | ? 'resources/dark/icon.png' |
150 | 241 | : 'resources/light/icon.png'; |
151 | 242 | } |
152 | 243 |
|
| 244 | + /** |
| 245 | + * Plugin initialization |
| 246 | + * Called by ONLYOFFICE plugin system |
| 247 | + */ |
153 | 248 | w.Asc.plugin.init = function () { |
154 | | - var base = getBaseUrl(); |
155 | | - |
156 | | - document.getElementById('btn-sign').addEventListener('click', function () { |
157 | | - w.open(base + '/apps/libresign/#/f/filelist/sign', '_blank'); |
158 | | - }); |
159 | | - |
160 | | - document.getElementById('btn-request').addEventListener('click', function () { |
161 | | - w.open(base + '/apps/libresign/#/f/request', '_blank'); |
162 | | - }); |
| 249 | + document.getElementById('btn-sign').addEventListener('click', handleSignClick); |
| 250 | + document.getElementById('btn-request').addEventListener('click', handleRequestClick); |
163 | 251 |
|
164 | 252 | /* Apply initial theme */ |
165 | 253 | if (w.Asc.plugin.theme) { |
166 | 254 | applyTheme(w.Asc.plugin.theme.type === 'dark'); |
167 | 255 | } |
168 | 256 | }; |
169 | 257 |
|
| 258 | + /** |
| 259 | + * Theme change handler |
| 260 | + * Called by ONLYOFFICE when user changes theme |
| 261 | + */ |
170 | 262 | w.Asc.plugin.onThemeChanged = function (theme) { |
171 | 263 | applyTheme(theme.type === 'dark'); |
172 | 264 | }; |
173 | 265 |
|
| 266 | + /** |
| 267 | + * Button placeholder (ONLYOFFICE API requirement) |
| 268 | + */ |
174 | 269 | w.Asc.plugin.button = function () {}; |
175 | 270 |
|
| 271 | + /** |
| 272 | + * Listen for messages from LibreSign (for future modal/sidebar modes) |
| 273 | + */ |
| 274 | + w.addEventListener('message', function (e) { |
| 275 | + // Verify origin matches Nextcloud |
| 276 | + var nextcloudUrl = getNextcloudUrl(); |
| 277 | + if (!e.origin.startsWith(nextcloudUrl)) { |
| 278 | + return; |
| 279 | + } |
| 280 | + |
| 281 | + if (e.data && e.data.type === 'libresign:signatureComplete') { |
| 282 | + console.log('[LibreSign Plugin] Signature complete:', e.data.result); |
| 283 | + // Future: Annotate document with signature if in sidebar mode |
| 284 | + } |
| 285 | + }); |
| 286 | + |
176 | 287 | }(window)); |
177 | 288 | </script> |
178 | 289 | </body> |
|
0 commit comments