Skip to content

Commit 7041d53

Browse files
committed
feat: implement 3-layer Nextcloud URL configuration strategy
- Add window.__LIBRESIGN_CONFIG__ support for pre-configured URL (Layer 1) - Add ?nc_url= query parameter support for manual override (Layer 2) - Keep window.location.origin fallback for auto-detection (Layer 3) - Refactor button handlers with proper error handling - Extract document context from query params and ONLYOFFICE context - Add message listeners for future modal/sidebar mode support - Improve logging for debugging configuration issues - Document URL resolution strategy in code comments Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent afc379d commit 7041d53

1 file changed

Lines changed: 122 additions & 11 deletions

File tree

index.html

Lines changed: 122 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -138,41 +138,152 @@
138138
w.Asc = w.Asc || {};
139139
w.Asc.plugin = w.Asc.plugin || {};
140140

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)
143160
return w.location.origin;
144161
}
145162

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+
146237
function applyTheme(isDark) {
147238
document.body.classList.toggle('dark', isDark);
148239
document.getElementById('logo').src = isDark
149240
? 'resources/dark/icon.png'
150241
: 'resources/light/icon.png';
151242
}
152243

244+
/**
245+
* Plugin initialization
246+
* Called by ONLYOFFICE plugin system
247+
*/
153248
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);
163251

164252
/* Apply initial theme */
165253
if (w.Asc.plugin.theme) {
166254
applyTheme(w.Asc.plugin.theme.type === 'dark');
167255
}
168256
};
169257

258+
/**
259+
* Theme change handler
260+
* Called by ONLYOFFICE when user changes theme
261+
*/
170262
w.Asc.plugin.onThemeChanged = function (theme) {
171263
applyTheme(theme.type === 'dark');
172264
};
173265

266+
/**
267+
* Button placeholder (ONLYOFFICE API requirement)
268+
*/
174269
w.Asc.plugin.button = function () {};
175270

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+
176287
}(window));
177288
</script>
178289
</body>

0 commit comments

Comments
 (0)