... |
... |
@@ -1,9 +1,8 @@ |
1 |
1 |
require.config({ |
2 |
2 |
paths: { |
3 |
3 |
'actionButtons': $jsontool.serialize($xwiki.getSkinFile('js/xwiki/actionbuttons/actionButtons.js', true)), |
4 |
|
- 'autoSave': $jsontool.serialize($xwiki.getSkinFile('js/xwiki/editors/autosave.js', true)), |
5 |
5 |
// Required in case the user needs to resolve merge conflicts on save. |
6 |
|
- 'xwiki-diff': $jsontool.serialize($xwiki.getSkinFile('uicomponents/viewers/diff.js')) |
|
5 |
+ 'diff': $jsontool.serialize($xwiki.getSkinFile('uicomponents/viewers/diff.js')) |
7 |
7 |
} |
8 |
8 |
}); |
9 |
9 |
|
... |
... |
@@ -18,17 +18,7 @@ |
18 |
18 |
* @return this document's real locale |
19 |
19 |
*/ |
20 |
20 |
getRealLocale: function() { |
21 |
|
- var realLocale = this.language; |
22 |
|
- if (typeof realLocale === 'string' && realLocale !== '') { |
23 |
|
- // This document is a translation. |
24 |
|
- } else if (this.translations && typeof this.translations['default'] === 'string') { |
25 |
|
- // This is the original document. |
26 |
|
- realLocale = this.translations['default']; |
27 |
|
- } else { |
28 |
|
- // The document locale is not specified. Use the UI locale. |
29 |
|
- realLocale = $('html').attr('lang'); |
30 |
|
- } |
31 |
|
- return realLocale; |
|
20 |
+ return this.language || (this.translations && this.translations['default']) || $('html').attr('lang'); |
32 |
32 |
}, |
33 |
33 |
|
34 |
34 |
/** |
... |
... |
@@ -66,7 +66,7 @@ |
66 |
66 |
*/ |
67 |
67 |
render: function(forView) { |
68 |
68 |
var queryString = { |
69 |
|
- xpage: 'get', |
|
58 |
+ xpage: 'rendercontent', |
70 |
70 |
outputTitle: true, |
71 |
71 |
outputSyntax: forView ? null : 'annotatedxhtml', |
72 |
72 |
language: this.getRealLocale(), |
... |
... |
@@ -80,15 +80,11 @@ |
80 |
80 |
'error' |
81 |
81 |
); |
82 |
82 |
}).then(function(html) { |
83 |
|
- // Render succeeded. |
84 |
84 |
var container = $('<div/>').html(html); |
85 |
85 |
return $.extend(thisXWikiDocument, { |
86 |
86 |
renderedTitle: container.find('#document-title h1').html(), |
87 |
87 |
renderedContent: container.find('#xwikicontent').html() |
88 |
88 |
}); |
89 |
|
- }, function() { |
90 |
|
- // Render failed. |
91 |
|
- return thisXWikiDocument; |
92 |
92 |
}); |
93 |
93 |
}, |
94 |
94 |
|
... |
... |
@@ -103,15 +103,11 @@ |
103 |
103 |
// Make sure the response is not retrieved from cache (IE11 doesn't obey the caching HTTP headers). |
104 |
104 |
timestamp: new Date().getTime() |
105 |
105 |
}).then(function(newXWikiDocument) { |
106 |
|
- // Reload succeeded. |
107 |
107 |
// Resolve the document reference. |
108 |
108 |
thisXWikiDocument.documentReference = XWiki.Model.resolve(newXWikiDocument.id, XWiki.EntityType.DOCUMENT); |
109 |
109 |
// We were able to load the document so it's not new. |
110 |
110 |
thisXWikiDocument.isNew = false; |
111 |
111 |
return $.extend(thisXWikiDocument, newXWikiDocument); |
112 |
|
- }, function() { |
113 |
|
- // Reload failed. |
114 |
|
- return thisXWikiDocument; |
115 |
115 |
}); |
116 |
116 |
}, |
117 |
117 |
|
... |
... |
@@ -134,19 +134,8 @@ |
134 |
134 |
// Make sure the response is not retrieved from cache (IE11 doesn't obey the caching HTTP headers). |
135 |
135 |
timestamp: new Date().getTime() |
136 |
136 |
}).then(function() { |
137 |
|
- // Lock succeeded. |
138 |
138 |
thisXWikiDocument.locked = action; |
139 |
139 |
return thisXWikiDocument; |
140 |
|
- }, function(response) { |
141 |
|
- // Lock failed. |
142 |
|
- delete thisXWikiDocument.locked; |
143 |
|
- // Check if the user can force the lock. |
144 |
|
- var lockConfirmation = response.responseJSON; |
145 |
|
- if (response.status === 423 && lockConfirmation) { |
146 |
|
- // The user can force the lock, but needs confirmation. |
147 |
|
- thisXWikiDocument.lockConfirmation = lockConfirmation; |
148 |
|
- } |
149 |
|
- return thisXWikiDocument; |
150 |
150 |
}); |
151 |
151 |
}, |
152 |
152 |
|
... |
... |
@@ -186,7 +186,6 @@ |
186 |
186 |
], function($, xcontext, xwikiDocumentAPI) { |
187 |
187 |
var preload = function() { |
188 |
188 |
loadCSS($jsontool.serialize($xwiki.getSkinFile('js/xwiki/actionbuttons/actionButtons.css', true))); |
189 |
|
- loadCSS($jsontool.serialize($xwiki.getSkinFile('js/xwiki/editors/autosave.css', true))); |
190 |
190 |
// Required in case the user needs to resolve merge conflicts on save. |
191 |
191 |
loadCSS($jsontool.serialize($xwiki.getSkinFile('uicomponents/viewers/diff.css', true))); |
192 |
192 |
return initActionButtons(); |
... |
... |
@@ -256,27 +256,20 @@ |
256 |
256 |
lockFailed: function() {} |
257 |
257 |
}, options); |
258 |
258 |
$('#xwikicontent').addClass('loading'); |
259 |
|
- // Lock the document first. |
260 |
260 |
return lock(currentXWikiDocument).fail(options.lockFailed) |
261 |
|
- // Then load the document only if we managed to lock it. |
262 |
262 |
.then(load) |
263 |
|
- // Then load the editors only if we managed to load the document. |
264 |
264 |
.then(edit).done(options.afterEdit).always(function() { |
265 |
265 |
$('#xwikicontent').removeClass('loading'); |
266 |
|
- // Then wait for an action (save, cancel, reload) only if the editors were loaded successfuly. |
267 |
267 |
}).then(maybeSave) |
268 |
|
- // Then unlock the document both when the edit ended with success and with a failure. |
269 |
|
- .then(unlock, unlock) |
270 |
|
- // Finally view the document both when the edit ended with success and with a failure. |
271 |
|
- .then(view, view); |
|
233 |
+ .then(unlock) |
|
234 |
+ .then(view); |
272 |
272 |
}; |
273 |
273 |
|
274 |
274 |
var lock = function(xwikiDocument) { |
275 |
|
- return xwikiDocument.lock().then(null, function(xwikiDocument) { |
|
238 |
+ return xwikiDocument.lock().then(null, function(response) { |
|
239 |
+ var confirmation = response.responseJSON; |
276 |
276 |
// If the document was already locked then we need to ask the user if they want to force the lock. |
277 |
|
- if (xwikiDocument.lockConfirmation) { |
278 |
|
- var confirmation = xwikiDocument.lockConfirmation; |
279 |
|
- delete xwikiDocument.lockConfirmation; |
|
241 |
+ if (response.status === 423 && confirmation) { |
280 |
280 |
return maybeForceLock(confirmation).then($.proxy(xwikiDocument, 'lock', 'edit', true)); |
281 |
281 |
} else { |
282 |
282 |
new XWiki.widgets.Notification( |
... |
... |
@@ -283,7 +283,6 @@ |
283 |
283 |
$jsontool.serialize($services.localization.render('edit.inplace.page.lockFailed')), |
284 |
284 |
'error' |
285 |
285 |
); |
286 |
|
- return xwikiDocument; |
287 |
287 |
} |
288 |
288 |
}); |
289 |
289 |
}; |
... |
... |
@@ -407,18 +407,24 @@ |
407 |
407 |
}; |
408 |
408 |
|
409 |
409 |
var save = function(data) { |
410 |
|
- // Push the changes to the server. |
411 |
|
- return push(data.document).then(function(xwikiDocument) { |
|
371 |
+ // Push the changes to the server then render the document for view. We need the view HTML both if we stop editing |
|
372 |
+ // now and if we continue but cancel the edit later. |
|
373 |
+ return push(data.document).then($.proxy(render, null, true)).then(function(xwikiDocument) { |
412 |
412 |
// Save succeeded. |
413 |
|
- return shouldReload(xwikiDocument).then( |
414 |
|
- // The document was saved with merge and thus if we want to continue eding we need to reload the editor (because |
415 |
|
- // its content doesn't match the saved content). |
416 |
|
- reload, |
417 |
|
- // No need to reload the editor because either the action was Save & View or there was no merge on save. |
418 |
|
- $.proxy(maybeContinueEditing, null, data['continue']) |
419 |
|
- ); |
420 |
|
- // Save failed. Continue editing because we may have unsaved content. |
421 |
|
- }, maybeSave); |
|
375 |
+ if (data['continue']) { |
|
376 |
+ // Update the original version in order to be able to restore it on cancel. |
|
377 |
+ delete xwikiDocument.originalDocument; |
|
378 |
+ xwikiDocument.originalDocument = $.extend(true, {}, xwikiDocument); |
|
379 |
+ // Continue editing. |
|
380 |
+ return maybeSave(xwikiDocument); |
|
381 |
+ } else { |
|
382 |
+ // This is the final version. |
|
383 |
+ return xwikiDocument; |
|
384 |
+ } |
|
385 |
+ }, function(xwikiDocument) { |
|
386 |
+ // Save failed. Continue editing. |
|
387 |
+ return maybeSave(xwikiDocument); |
|
388 |
+ }); |
422 |
422 |
}; |
423 |
423 |
|
424 |
424 |
var push = function(xwikiDocument) { |
... |
... |
@@ -431,33 +431,9 @@ |
431 |
431 |
// effect. |
432 |
432 |
$(document).one('xwiki:document:saved', $.proxy(deferred, 'resolve', xwikiDocument)); |
433 |
433 |
$(document).one('xwiki:document:saveFailed', $.proxy(deferred, 'reject', xwikiDocument)); |
434 |
|
- return deferred.promise(); |
|
401 |
+ return deferred.promise().then($.proxy(xwikiDocument, 'reload')); |
435 |
435 |
}; |
436 |
436 |
|
437 |
|
- var maybeContinueEditing = function(continueEditing, xwikiDocument) { |
438 |
|
- var afterReloadAndRender = function(success, xwikiDocument) { |
439 |
|
- if (continueEditing) { |
440 |
|
- if (success) { |
441 |
|
- // Update the original version in order to be able to restore it on cancel. |
442 |
|
- delete xwikiDocument.originalDocument; |
443 |
|
- xwikiDocument.originalDocument = $.extend(true, {}, xwikiDocument); |
444 |
|
- } |
445 |
|
- // Continue editing. |
446 |
|
- return maybeSave(xwikiDocument); |
447 |
|
- } else { |
448 |
|
- // This is the final version. We stop editing even if the reload / render failed. |
449 |
|
- return xwikiDocument; |
450 |
|
- } |
451 |
|
- }; |
452 |
|
- |
453 |
|
- // Reload the document JSON data (to have the new version) and render the document for view. We need the view HTML |
454 |
|
- // both if we stop editing now and if we continue but cancel the edit later. |
455 |
|
- return xwikiDocument.reload().then($.proxy(render, null, true)).then( |
456 |
|
- $.proxy(afterReloadAndRender, null, /* success: */ true), |
457 |
|
- $.proxy(afterReloadAndRender, null, /* success: */ false) |
458 |
|
- ); |
459 |
|
- }; |
460 |
|
- |
461 |
461 |
var cancel = function(xwikiDocument) { |
462 |
462 |
// Simply return the original version to be restored. |
463 |
463 |
return xwikiDocument.originalDocument; |
... |
... |
@@ -475,25 +475,6 @@ |
475 |
475 |
// Make sure we unlock the document when the user navigates to another page. |
476 |
476 |
$(window).on('unload pagehide', $.proxy(unlock, null, currentXWikiDocument)); |
477 |
477 |
|
478 |
|
- var shouldReload = function(xwikiDocument) { |
479 |
|
- var reloadEventFired = false; |
480 |
|
- $(document).one('xwiki:actions:reload.maybe', function() { |
481 |
|
- reloadEventFired = true; |
482 |
|
- }); |
483 |
|
- var deferred = $.Deferred(); |
484 |
|
- // Wait a bit to see if the reload event is fired. |
485 |
|
- setTimeout(function() { |
486 |
|
- // Remove the listener in case the reload event wasn't fired. |
487 |
|
- $(document).off('xwiki:actions:reload.maybe'); |
488 |
|
- if (reloadEventFired) { |
489 |
|
- deferred.resolve(xwikiDocument); |
490 |
|
- } else { |
491 |
|
- deferred.reject(xwikiDocument); |
492 |
|
- } |
493 |
|
- }, 0); |
494 |
|
- return deferred.promise(); |
495 |
|
- }; |
496 |
|
- |
497 |
497 |
var reload = function(xwikiDocument) { |
498 |
498 |
// Leave the edit mode and then re-enter. |
499 |
499 |
return view(xwikiDocument, true).then(editInPlace); |
... |
... |
@@ -580,12 +580,8 @@ |
580 |
580 |
|
581 |
581 |
var loadActionButtons = function(actionButtons) { |
582 |
582 |
$(document).on('xwiki:actions:view', function() { |
583 |
|
- // Blur the action buttons first to re-enable the "disabled in inputs" shortcut keys (e.g. the page edit |
584 |
|
- // shortcut), then disable the action buttons in order to disable their shortcut keys while we're not editing |
585 |
|
- // in-place (e.g. prevent the Save shortcut while the user is only viewing the page). Finally hide the action |
586 |
|
- // buttons to have them ready for the next editing session (the user can save or cancel and then edit again |
587 |
|
- // without reloading the page). |
588 |
|
- actionButtons.find(':input').blur().prop('disabled', true).end().hide(); |
|
507 |
+ // Hide the action buttons and disable the shortcut keys (by disabling the buttons). |
|
508 |
+ actionButtons.hide().find(':input').prop('disabled', true); |
589 |
589 |
// Hide the translate button because it can be used only in edit mode for the moment. |
590 |
590 |
$('#tmTranslate').addClass('hidden'); |
591 |
591 |
}); |
... |
... |
@@ -600,13 +600,9 @@ |
600 |
600 |
// We need a place where actionButtons.js can add more hidden inputs. |
601 |
601 |
actionButtons.append('<div class="hidden extra"/>'); |
602 |
602 |
var deferred = $.Deferred(); |
603 |
|
- require(['actionButtons', 'xwiki-diff', 'autoSave'], function() { |
|
523 |
+ require(['actionButtons'], function() { |
604 |
604 |
overrideEditActions(); |
605 |
605 |
overrideAjaxSaveAndContinue(); |
606 |
|
- // Activate the auto-save feature passing our fake edit form. Note that autosave.js also creates an instance of |
607 |
|
- // AutoSave but it doesn't do anything because it doesn't find a real edit form in the page. This is why we have |
608 |
|
- // to create our own instance of AutoSave passing the right (fake) form. |
609 |
|
- new XWiki.editors.AutoSave({form: fakeForm}); |
610 |
610 |
var xwikiDocument = actionButtons.data('xwikiDocument'); |
611 |
611 |
// Enable the action buttons (and their shortcut keys) only if we're editing a document. |
612 |
612 |
actionButtons.find(':input').prop('disabled', !xwikiDocument); |
... |
... |
@@ -643,9 +643,6 @@ |
643 |
643 |
insert: function(element) { |
644 |
644 |
this._getActionButtons().find('.hidden.extra').append(element); |
645 |
645 |
}, |
646 |
|
- down: function(selector) { |
647 |
|
- return this._getActionButtons().find(selector)[0]; |
648 |
|
- }, |
649 |
649 |
serialize: function() { |
650 |
650 |
var extra = this._getActionButtons().find(':input').serializeArray().reduce(function(extra, entry) { |
651 |
651 |
var value = extra[entry.name] || []; |
... |
... |
@@ -655,21 +655,13 @@ |
655 |
655 |
}, {}); |
656 |
656 |
var xwikiDocument = this._getActionButtons().data('xwikiDocument'); |
657 |
657 |
var formData = { |
658 |
|
- title: xwikiDocument.rawTitle, |
|
571 |
+ title: xwikiDocument.title, |
|
572 |
+ content: xwikiDocument.renderedContent, |
|
573 |
+ RequiresHTMLConversion: 'content', |
|
574 |
+ content_syntax: xwikiDocument.syntax, |
659 |
659 |
language: xwikiDocument.getRealLocale(), |
660 |
660 |
isNew: xwikiDocument.isNew |
661 |
661 |
}; |
662 |
|
- if (xwikiDocument.content != xwikiDocument.originalDocument.content) { |
663 |
|
- // Submit the raw (source) content. No syntax conversion is needed in this case. |
664 |
|
- formData.content = xwikiDocument.content; |
665 |
|
- } else { |
666 |
|
- // Submit the rendered content (HTML), but make sure it is converted to the document syntax on the server. |
667 |
|
- $.extend(formData, { |
668 |
|
- content: xwikiDocument.renderedContent, |
669 |
|
- RequiresHTMLConversion: 'content', |
670 |
|
- content_syntax: xwikiDocument.syntax |
671 |
|
- }); |
672 |
|
- } |
673 |
673 |
// Check for merge conflicts only if the document is not new and we know the current version. |
674 |
674 |
if (!xwikiDocument.isNew && xwikiDocument.version) { |
675 |
675 |
formData.previousVersion = xwikiDocument.version; |
... |
... |
@@ -704,14 +704,11 @@ |
704 |
704 |
return originalAjaxSaveAndContinue.reloadEditor.apply(this, arguments); |
705 |
705 |
} |
706 |
706 |
}, |
707 |
|
- maybeRedirect: function(continueEditing) { |
|
612 |
+ maybeRedirect: function() { |
708 |
708 |
if ($('.inplace-editing-buttons').is(':visible')) { |
709 |
|
- // Overwrite the default behavior so that we don't redirect when leaving the edit mode because we're already |
710 |
|
- // in view mode. We still need to report a redirect (return true) if we don't continue editing, so that |
711 |
|
- // actionButtons.js behaves as if a redirect was done. |
712 |
|
- return !continueEditing; |
|
614 |
+ // Never redirect when leaving the edit mode because we're already in view mode. |
|
615 |
+ return false; |
713 |
713 |
} else { |
714 |
|
- // Fallback on the default behavior if the in-place editing buttons are hidden. |
715 |
715 |
return originalAjaxSaveAndContinue.maybeRedirect.apply(this, arguments); |
716 |
716 |
} |
717 |
717 |
} |
... |
... |
@@ -721,7 +721,7 @@ |
721 |
721 |
var initTitleEditor = function(xwikiDocument) { |
722 |
722 |
var label = $('<label for="document-title-input" class="sr-only"/>') |
723 |
723 |
.text($jsontool.serialize($services.localization.render('core.editors.content.titleField.label'))); |
724 |
|
- var input = $('<input type="text" id="document-title-input"/>').val(xwikiDocument.rawTitle); |
|
626 |
+ var input = $('<input type="text" id="document-title-input"/>').val(xwikiDocument.title); |
725 |
725 |
var placeholder = xwikiDocument.documentReference.name; |
726 |
726 |
if (placeholder === 'WebHome') { |
727 |
727 |
placeholder = xwikiDocument.documentReference.parent.name; |
... |
... |
@@ -729,12 +729,12 @@ |
729 |
729 |
input.attr('placeholder', placeholder); |
730 |
730 |
$('#document-title h1').addClass('editable').empty().append([label, input]); |
731 |
731 |
$(document).on('xwiki:actions:beforeSave.titleEditor', function(event) { |
732 |
|
- xwikiDocument.rawTitle = input.val(); |
|
634 |
+ xwikiDocument.title = input.val(); |
733 |
733 |
}); |
734 |
734 |
$(document).one('xwiki:actions:view', function(event, data) { |
735 |
735 |
// Destroy the title editor. |
736 |
736 |
$(document).off('xwiki:actions:beforeSave.titleEditor'); |
737 |
|
- $('#document-title h1').removeClass('editable').text(xwikiDocument.rawTitle); |
|
639 |
+ $('#document-title h1').removeClass('editable').text(xwikiDocument.title); |
738 |
738 |
}); |
739 |
739 |
return xwikiDocument; |
740 |
740 |
}; |
... |
... |
@@ -756,11 +756,7 @@ |
756 |
756 |
editMode: 'wysiwyg', |
757 |
757 |
document: xwikiDocument, |
758 |
758 |
// The content editor is loaded on demand, asynchronously. |
759 |
|
- deferred: $.Deferred(), |
760 |
|
- // We have to explicitly enable the source mode for in-line edit because the latest version of the content editor |
761 |
|
- // could be installed on an older version of XWiki where the in-place editor didn't support the source mode (so |
762 |
|
- // the content editor cannot enable the source mode by default). |
763 |
|
- enableSourceMode: true |
|
661 |
+ deferred: $.Deferred() |
764 |
764 |
}; |
765 |
765 |
var editContentPromise = data.deferred.promise(); |
766 |
766 |
editContentPromise.done(function() { |
... |
... |
@@ -798,11 +798,6 @@ |
798 |
798 |
}); |
799 |
799 |
|
800 |
800 |
require(['jquery'], function($) { |
801 |
|
- // We can edit in-place only if the #xwikicontent element is present. |
802 |
|
- if (!$('#xwikicontent').length) { |
803 |
|
- return; |
804 |
|
- } |
805 |
|
- |
806 |
806 |
var inplaceEditingConfig = $('div[data-inplace-editing-config]').data('inplaceEditingConfig') || {}; |
807 |
807 |
var wysiwygEditorModule = 'xwiki-' + inplaceEditingConfig.wysiwygEditor + '-inline'; |
808 |
808 |
|