Changes for page InplaceEditing
From version 4.1
edited by Nazzareno Pompei
on 28/10/2022 08:43
on 28/10/2022 08:43
Change comment:
Install extension [org.xwiki.platform:xwiki-platform-edit-ui/14.9]
To version 3.1
edited by Nazzareno Pompei
on 22/12/2021 09:31
on 22/12/2021 09:31
Change comment:
Install extension [org.xwiki.platform:xwiki-platform-edit-ui/13.10.1]
Summary
-
Objects (2 modified, 0 added, 0 removed)
Details
- XWiki.JavaScriptExtension[0]
-
- Code
-
... ... @@ -87,24 +87,26 @@ 87 87 timestamp: new Date().getTime() 88 88 }; 89 89 if (!forView) { 90 - // We need the annotated HTML when editing in order to be able to protect the rendering transformations and to 90 + // We need the annotated XHTML when editing in order to be able to protect the rendering transformations and to 91 91 // be able to recreate the wiki syntax. 92 - queryString.outputSyntax = 'annotatedhtml'; 93 - queryString.outputSyntaxVersion = '5.0' 92 + queryString.outputSyntax = 'annotatedxhtml'; 94 94 // Currently, only the macro transformations are protected and thus can be edited. 95 95 // See XRENDERING-78: Add markers to modified XDOM by Transformations/Macros 96 96 queryString.transformations = 'macro'; 97 97 } 98 - return Promise.resolve($.get(this.getURL('view'), queryString)).then(html => { 97 + var thisXWikiDocument = this; 98 + return $.get(this.getURL('view'), queryString).fail(function() { 99 + new XWiki.widgets.Notification(l10n['edit.inplace.page.renderFailed'], 'error'); 100 + }).then(function(html) { 99 99 // Render succeeded. 100 100 var container = $('<div/>').html(html); 101 - return $.extend(this, { 103 + return $.extend(thisXWikiDocument, { 102 102 renderedTitle: container.find('#document-title h1').html(), 103 103 renderedContent: container.find('#xwikicontent').html() 104 104 }); 105 - } ).catch(()=>{106 - newXWiki.widgets.Notification(l10n['edit.inplace.page.renderFailed'], 'error');107 - return Promise.reject(this);107 + }, function() { 108 + // Render failed. 109 + return thisXWikiDocument; 108 108 }); 109 109 }, 110 110 ... ... @@ -114,19 +114,20 @@ 114 114 * @return a promise that resolves to this document instance if the reload request succeeds 115 115 */ 116 116 reload: function() { 117 - return Promise.resolve($.getJSON(this.getRestURL(), { 119 + var thisXWikiDocument = this; 120 + return $.getJSON(this.getRestURL(), { 118 118 // Make sure the response is not retrieved from cache (IE11 doesn't obey the caching HTTP headers). 119 119 timestamp: new Date().getTime() 120 - }) ).then(newXWikiDocument=>{123 + }).then(function(newXWikiDocument) { 121 121 // Reload succeeded. 122 122 // Resolve the document reference. 123 - this.documentReference = XWiki.Model.resolve(newXWikiDocument.id, XWiki.EntityType.DOCUMENT); 126 + thisXWikiDocument.documentReference = XWiki.Model.resolve(newXWikiDocument.id, XWiki.EntityType.DOCUMENT); 124 124 // We were able to load the document so it's not new. 125 - this.isNew = false; 126 - return $.extend(this, newXWikiDocument); 127 - } ).catch(()=>{128 + thisXWikiDocument.isNew = false; 129 + return $.extend(thisXWikiDocument, newXWikiDocument); 130 + }, function() { 128 128 // Reload failed. 129 - return Promise.reject(this);132 + return thisXWikiDocument; 130 130 }); 131 131 }, 132 132 ... ... @@ -137,8 +137,9 @@ 137 137 * @return a promise that resolves to this document instance if the lock request succeeds 138 138 */ 139 139 lock: function(action, force) { 143 + var thisXWikiDocument = this; 140 140 action = action || 'edit'; 141 - return Promise.resolve($.getJSON(this.getURL('get'), {145 + return $.getJSON(this.getURL('get'), { 142 142 sheet: 'XWiki.InplaceEditing', 143 143 action: 'lock', 144 144 lockAction: action, ... ... @@ -147,20 +147,20 @@ 147 147 outputSyntax: 'plain', 148 148 // Make sure the response is not retrieved from cache (IE11 doesn't obey the caching HTTP headers). 149 149 timestamp: new Date().getTime() 150 - }) ).then(()=>{154 + }).then(function() { 151 151 // Lock succeeded. 152 - this.locked = action; 153 - return this; 154 - } ).catch(response=>{156 + thisXWikiDocument.locked = action; 157 + return thisXWikiDocument; 158 + }, function(response) { 155 155 // Lock failed. 156 - delete this.locked; 160 + delete thisXWikiDocument.locked; 157 157 // Check if the user can force the lock. 158 158 var lockConfirmation = response.responseJSON; 159 159 if (response.status === 423 && lockConfirmation) { 160 160 // The user can force the lock, but needs confirmation. 161 - this.lockConfirmation = lockConfirmation; 165 + thisXWikiDocument.lockConfirmation = lockConfirmation; 162 162 } 163 - return Promise.reject(this);167 + return thisXWikiDocument; 164 164 }); 165 165 }, 166 166 ... ... @@ -255,7 +255,7 @@ 255 255 $('#xwikicontent').removeAttr('tabindex'); 256 256 if (sectionId) { 257 257 // Select the heading of the specified section. 258 - $('#xwikicontent > #' + $.escapeSelector(sectionId)).each(function() {262 + $('#xwikicontent > #' + escapeSelector(sectionId)).each(function() { 259 259 selectText(this); 260 260 }); 261 261 } ... ... @@ -263,6 +263,22 @@ 263 263 }); 264 264 }; 265 265 270 + var escapeSelector = function(selector) { 271 + if (window.CSS && typeof CSS.escape === 'function') { 272 + // Not supported by Internet Explorer. 273 + return CSS.escape(selector); 274 + } else if (typeof $.escapeSelector === 'function') { 275 + // Added in jQuery 3.0 276 + return $.escapeSelector(selector); 277 + } else if (typeof selector === 'string') { 278 + // Simple implementation. 279 + // See https://learn.jquery.com/using-jquery-core/faq/how-do-i-select-an-element-by-an-id-that-has-characters-used-in-css-notation/ 280 + return selector.replace(/(:|\.|\[|\]|,|=|@)/g, '\\$1'); 281 + } else { 282 + return selector; 283 + } 284 + }; 285 + 266 266 // We preserve the document data between edits in order to be able to know which document translation should be edited 267 267 // (e.g. when the document translation is missing and we create it, the next edit session should target the created 268 268 // translation). ... ... @@ -270,11 +270,6 @@ 270 270 language: xcontext.locale 271 271 }, xwikiDocumentAPI); 272 272 273 - var setCurrentXWikiDocument = function(xwikiDocument) { 274 - currentXWikiDocument = xwikiDocument; 275 - return Promise.resolve(xwikiDocument); 276 - }; 277 - 278 278 var editInPlace = function(options) { 279 279 options = $.extend({ 280 280 afterEdit: function() {}, ... ... @@ -282,16 +282,11 @@ 282 282 }, options); 283 283 $('#xwikicontent').addClass('loading'); 284 284 // Lock the document first. 285 - return lock(currentXWikiDocument) 300 + return lock(currentXWikiDocument).fail(options.lockFailed) 286 286 // Then load the document only if we managed to lock it. 287 - .then(load, xwikiDocument => { 288 - options.lockFailed(xwikiDocument); 289 - return Promise.reject(xwikiDocument); 302 + .then(load) 290 290 // Then load the editors only if we managed to load the document. 291 - }).then(edit).then(xwikiDocument => { 292 - options.afterEdit(xwikiDocument); 293 - return xwikiDocument; 294 - }).finally(() => { 304 + .then(edit).done(options.afterEdit).always(function() { 295 295 $('#xwikicontent').removeClass('loading'); 296 296 // Then wait for an action (save, cancel, reload) only if the editors were loaded successfuly. 297 297 }).then(maybeSave) ... ... @@ -299,39 +299,34 @@ 299 299 .then(unlock, unlock) 300 300 // Finally view the document both when the edit ended with success and with a failure. 301 301 .then(view, view) 302 - // Update the current document for the next edit session. 303 - .then(setCurrentXWikiDocument, setCurrentXWikiDocument); 312 + .always(function(xwikiDocument) { 313 + // Update the current document for the next edit session. 314 + currentXWikiDocument = xwikiDocument; 315 + }); 304 304 }; 305 305 306 306 var lock = function(xwikiDocument) { 307 - return xwikiDocument.lock(). catch(function(xwikiDocument) {319 + return xwikiDocument.lock().then(null, function(xwikiDocument) { 308 308 // If the document was already locked then we need to ask the user if they want to force the lock. 309 309 if (xwikiDocument.lockConfirmation) { 310 310 var confirmation = xwikiDocument.lockConfirmation; 311 311 delete xwikiDocument.lockConfirmation; 312 - return maybeForceLock(confirmation).then(xwikiDocument .lock.bind(xwikiDocument, 'edit', true), function() {324 + return maybeForceLock(confirmation).then($.proxy(xwikiDocument, 'lock', 'edit', true), function() { 313 313 // Cancel the edit action. 314 - return Promise.reject(xwikiDocument);326 + return xwikiDocument; 315 315 }); 316 316 } else { 317 317 new XWiki.widgets.Notification(l10n['edit.inplace.page.lockFailed'], 'error'); 318 - return Promise.reject(xwikiDocument);330 + return xwikiDocument; 319 319 } 320 320 }); 321 321 }; 322 322 323 323 var maybeForceLock = function(confirmation) { 324 - var deferred, promise = new Promise((resolve, reject) => { 325 - deferred = {resolve, reject}; 326 - }); 327 - // We need the catch() to prevent the "Uncaught (in promise)" error log in the console. 328 - promise.catch(() => {}).finally(() => { 329 - // This flag is used by the Force Lock modal to know whether the promise is settled when the modal is closing. 330 - deferred.settled = true; 331 - }); 336 + var deferred = $.Deferred(); 332 332 // Reuse the confirmation modal once it is created. 333 333 var modal = $('.force-edit-lock-modal'); 334 - if ( !modal.length) {339 + if (modal.length === 0) { 335 335 modal = createForceLockModal(); 336 336 } 337 337 // Update the deferred that needs to be resolved or rejected. ... ... @@ -347,7 +347,7 @@ 347 347 } 348 348 // Show the confirmation modal. 349 349 modal.modal('show'); 350 - return promise; 355 + return deferred.promise(); 351 351 }; 352 352 353 353 var createForceLockModal = function() { ... ... @@ -371,16 +371,16 @@ 371 371 '</div>' 372 372 ].join('')); 373 373 modal.find('.close').attr('aria-label', l10n['edit.inplace.close']); 374 - modal.find('.modal-footer .btn-warning'). on('click',function() {379 + modal.find('.modal-footer .btn-warning').click(function() { 375 375 // The user has confirmed they want to force the lock. 376 376 modal.data('deferred').resolve(); 377 377 modal.modal('hide'); 378 378 }); 379 379 modal.on('hide.bs.modal', function() { 380 - // If the lock promise is not yet settled when the modal is closing then it means the modal was canceled,385 + // If the lock promise is not yet resolved when the modal is closing then it means the modal was canceled, 381 381 // i.e. the user doesn't want to force the lock. 382 382 var deferred = modal.data('deferred'); 383 - if ( !deferred.settled) {388 + if (deferred.state() === 'pending') { 384 384 deferred.reject(); 385 385 } 386 386 }); ... ... @@ -388,19 +388,17 @@ 388 388 }; 389 389 390 390 var load = function(xwikiDocument) { 391 - return xwikiDocument.reload(). then(xwikiDocument=>{396 + return xwikiDocument.reload().done(function(xwikiDocument) { 392 392 // Clone the current document version and keep a reference to it in order to be able to restore it on cancel. 393 393 xwikiDocument.originalDocument = $.extend(true, { 394 394 renderedTitle: $('#document-title h1').html(), 395 395 renderedContent: $('#xwikicontent').html() 396 396 }, xwikiDocument); 397 - return xwikiDocument; 398 - }).catch(xwikiDocument => { 402 + }).fail(function() { 399 399 new XWiki.widgets.Notification(l10n['edit.inplace.page.loadFailed'], 'error'); 400 - return Promise.reject(xwikiDocument); 401 401 // Render the document for edit, in order to have the annotated content HTML. The annotations are used to protect 402 402 // the rendering transformations (e.g. macros) when editing the content. 403 - }).then(render .bind(null, false));406 + }).then($.proxy(render, null, false)); 404 404 }; 405 405 406 406 /** ... ... @@ -413,7 +413,7 @@ 413 413 }; 414 414 415 415 var maybeSave = function(xwikiDocument) { 416 - return waitForAction(xwikiDocument).then(action =>{419 + return waitForAction(xwikiDocument).then(function(action) { 417 417 switch(action.name) { 418 418 case 'save': return save({ 419 419 document: action.document, ... ... @@ -426,29 +426,29 @@ 426 426 }; 427 427 428 428 var waitForAction = function(xwikiDocument) { 429 - return new Promise((resolve, reject) => { 430 - // We wait for the first save, reload or cancel event, whichever is triggered first. Note that the event listeners 431 - // that are not executed first will remain registered but that doesn't cause any problems because the state of a 432 - // deferred object (promise) cannot change once it was resolved. So the first event that fires will resolve the 433 - // promise and the remaining events won't be able to change that. The remaining event listeners could be called 434 - // later but they won't have any effect on the deferred object. 435 - $(document).one([ 436 - 'xwiki:actions:save', 437 - 'xwiki:actions:reload', 438 - 'xwiki:actions:cancel', 439 - ].join(' '), '.xcontent.form', function(event, data) { 440 - resolve({ 441 - name: event.type.substring('xwiki:actions:'.length), 442 - document: xwikiDocument, 443 - data: data 444 - }); 432 + var deferred = $.Deferred(); 433 + // We wait for the first save, reload or cancel event, whichever is triggered first. Note that the event listeners 434 + // that are not executed first will remain registered but that doesn't cause any problems because the state of a 435 + // deferred object (promise) cannot change once it was resolved. So the first event that fires will resolve the 436 + // promise and the remaining events won't be able to change that. The remaining event listeners could be called 437 + // later but they won't have any effect on the deferred object. 438 + $(document).one([ 439 + 'xwiki:actions:save', 440 + 'xwiki:actions:reload', 441 + 'xwiki:actions:cancel', 442 + ].join(' '), '.xcontent.form', function(event, data) { 443 + deferred.resolve({ 444 + name: event.type.substring('xwiki:actions:'.length), 445 + document: xwikiDocument, 446 + data: data 445 445 }); 446 446 }); 449 + return deferred.promise(); 447 447 }; 448 448 449 449 var save = function(data) { 450 450 // Push the changes to the server. 451 - return push(data.document).then(xwikiDocument =>{454 + return push(data.document).then(function(xwikiDocument) { 452 452 // Save succeeded. 453 453 return shouldReload(xwikiDocument).then( 454 454 // The document was saved with merge and thus if we want to continue eding we need to reload the editor (because ... ... @@ -455,7 +455,7 @@ 455 455 // its content doesn't match the saved content). 456 456 reload, 457 457 // No need to reload the editor because either the action was Save & View or there was no merge on save. 458 - maybeContinueEditing .bind(null, data['continue'])461 + $.proxy(maybeContinueEditing, null, data['continue']) 459 459 ); 460 460 // Save failed. Continue editing because we may have unsaved content. 461 461 }, maybeSave); ... ... @@ -463,15 +463,15 @@ 463 463 464 464 var push = function(xwikiDocument) { 465 465 // Let actionButtons.js do the push. We just catch the result. 466 - r eturnnew Promise((resolve,reject)=>{467 - 468 - 469 - 470 - remaining event won't be able to change that. The remaining event listener could be called later but it won't471 - haveany effect.472 - .bind(null, xwikiDocument));473 - .bind(null, xwikiDocument));474 - });469 + var deferred = $.Deferred(); 470 + // We wait for the save request to either succeed or fail. Note that one of the event listeners will remain 471 + // registered but that doesn't cause any problems because the state of a deferred object (promise) cannot change 472 + // once it was resolved or rejected. So the first event that fires will resolve/reject the promise and the remaining 473 + // event won't be able to change that. The remaining event listener could be called later but it won't have any 474 + // effect. 475 + $(document).one('xwiki:document:saved', '.xcontent.form', $.proxy(deferred, 'resolve', xwikiDocument)); 476 + $(document).one('xwiki:document:saveFailed', '.xcontent.form', $.proxy(deferred, 'reject', xwikiDocument)); 477 + return deferred.promise(); 475 475 }; 476 476 477 477 var maybeContinueEditing = function(continueEditing, xwikiDocument) { ... ... @@ -492,9 +492,9 @@ 492 492 493 493 // Reload the document JSON data (to have the new version) and render the document for view. We need the view HTML 494 494 // both if we stop editing now and if we continue but cancel the edit later. 495 - return xwikiDocument.reload().then(render .bind(null, true)).then(496 - afterReloadAndRender .bind(null, /* success: */ true),497 - afterReloadAndRender .bind(null, /* success: */ false)498 + return xwikiDocument.reload().then($.proxy(render, null, true)).then( 499 + $.proxy(afterReloadAndRender, null, /* success: */ true), 500 + $.proxy(afterReloadAndRender, null, /* success: */ false) 498 498 ); 499 499 }; 500 500 ... ... @@ -513,7 +513,7 @@ 513 513 }; 514 514 515 515 // Make sure we unlock the document when the user navigates to another page. 516 - $(window).on('unload pagehide', unlock .bind(null, currentXWikiDocument));519 + $(window).on('unload pagehide', $.proxy(unlock, null, currentXWikiDocument)); 517 517 518 518 var shouldReload = function(xwikiDocument) { 519 519 var reloadEventFired = false; ... ... @@ -520,18 +520,18 @@ 520 520 $(document).one('xwiki:actions:reload.maybe', '.xcontent.form', function() { 521 521 reloadEventFired = true; 522 522 }); 523 - r eturnnew Promise((resolve,reject)=>{524 - 525 - 526 - 527 - 528 - 529 - 530 - 531 - 532 - 533 - 534 - });526 + var deferred = $.Deferred(); 527 + // Wait a bit to see if the reload event is fired. 528 + setTimeout(function() { 529 + // Remove the listener in case the reload event wasn't fired. 530 + $(document).off('xwiki:actions:reload.maybe'); 531 + if (reloadEventFired) { 532 + deferred.resolve(xwikiDocument); 533 + } else { 534 + deferred.reject(xwikiDocument); 535 + } 536 + }, 0); 537 + return deferred.promise(); 535 535 }; 536 536 537 537 var reload = function(xwikiDocument) { ... ... @@ -558,7 +558,7 @@ 558 558 if (window.location.hash === '#edit' || window.location.hash === '#translate') { 559 559 history.replaceState(null, null, '#'); 560 560 } 561 - return Promise.resolve(xwikiDocument);564 + return $.Deferred().resolve(xwikiDocument).promise(); 562 562 }; 563 563 564 564 var edit = function(xwikiDocument) { ... ... @@ -603,7 +603,7 @@ 603 603 // action buttons so we need to re-enable them each time we enter the edit mode. 604 604 fakeForm.enable(); 605 605 } 606 - return Promise.resolve(xwikiDocument);609 + return $.Deferred().resolve(xwikiDocument).promise(); 607 607 } 608 608 }; 609 609 ... ... @@ -664,9 +664,9 @@ 664 664 .parent().removeClass('hidden'); 665 665 } 666 666 }); 667 - return Promise.resolve($.get(XWiki.currentDocument.getURL('get'), {670 + return $.get(XWiki.currentDocument.getURL('get'), { 668 668 xpage: 'editactions' 669 - }) ).then(html=>{672 + }).then(function(html) { 670 670 actionButtons.html(html); 671 671 // Fix the name of the Save & View action. 672 672 actionButtons.find('.btn-primary').first().attr('name', 'action_save'); ... ... @@ -676,21 +676,21 @@ 676 676 actionButtons.append('<div class="hidden extra"/>'); 677 677 // Let the others know that the DOM has been updated, in order to enhance it. 678 678 $(document).trigger('xwiki:dom:updated', {'elements': actionButtons.toArray()}); 679 - return new Promise((resolve, reject) => { 680 - require(['xwiki-actionButtons', 'xwiki-diff', 'xwiki-autoSave'], function() { 681 - overrideEditActions(); 682 - overrideAjaxSaveAndContinue(); 683 - // Activate the auto-save feature passing our fake edit form. Note that autosave.js also creates an instance of 684 - // AutoSave but it doesn't do anything because it doesn't find a real edit form in the page. This is why we have 685 - // to create our own instance of AutoSave passing the right (fake) form. 686 - new XWiki.editors.AutoSave({form: fakeForm}); 687 - var xwikiDocument = actionButtons.data('xwikiDocument'); 688 - // Enable the action buttons (and their shortcut keys) only if we're editing a document. 689 - actionButtons.find(':input').prop('disabled', !xwikiDocument); 690 - resolve(xwikiDocument); 691 - }); 682 + var deferred = $.Deferred(); 683 + require(['xwiki-actionButtons', 'xwiki-diff', 'xwiki-autoSave'], function() { 684 + overrideEditActions(); 685 + overrideAjaxSaveAndContinue(); 686 + // Activate the auto-save feature passing our fake edit form. Note that autosave.js also creates an instance of 687 + // AutoSave but it doesn't do anything because it doesn't find a real edit form in the page. This is why we have 688 + // to create our own instance of AutoSave passing the right (fake) form. 689 + new XWiki.editors.AutoSave({form: fakeForm}); 690 + var xwikiDocument = actionButtons.data('xwikiDocument'); 691 + // Enable the action buttons (and their shortcut keys) only if we're editing a document. 692 + actionButtons.find(':input').prop('disabled', !xwikiDocument); 693 + deferred.resolve(xwikiDocument); 692 692 }); 693 - }).catch(() => { 695 + return deferred.promise(); 696 + }, function() { 694 694 new XWiki.widgets.Notification(l10n['edit.inplace.actionButtons.loadFailed'], 'error'); 695 695 }); 696 696 }; ... ... @@ -731,13 +731,6 @@ 731 731 extra[entry.name] = value; 732 732 return extra; 733 733 }, {}); 734 - // retrieve all input fields listing the temporary uploaded files. 735 - var uploadedFiles = $('#xwikicontent').nextAll('input[name="uploadedFiles"]').serializeArray().reduce(function(extra, entry) { 736 - var value = extra[entry.name] || []; 737 - value.push(entry.value); 738 - extra[entry.name] = value; 739 - return extra; 740 - }, {}); 741 741 var xwikiDocument = this._getActionButtons().data('xwikiDocument'); 742 742 var formData = { 743 743 title: xwikiDocument.rawTitle, ... ... @@ -755,8 +755,6 @@ 755 755 content_syntax: xwikiDocument.syntax 756 756 }); 757 757 } 758 - // Add the temporary uploaded files to the form. 759 - $.extend(formData, uploadedFiles); 760 760 // Check for merge conflicts only if the document is not new and we know the current version. 761 761 if (!xwikiDocument.isNew && xwikiDocument.version) { 762 762 formData.previousVersion = xwikiDocument.version; ... ... @@ -845,7 +845,7 @@ 845 845 deferred: $.Deferred() 846 846 }); 847 847 editContent.trigger('xwiki:actions:edit', data); 848 - return data.deferred. promise().then(()=>{842 + return data.deferred.done(function() { 849 849 editContent.show(); 850 850 viewContent.remove(); 851 851 if (withFocus) { ... ... @@ -856,8 +856,7 @@ 856 856 editContent[0].focus({preventScroll: true}); 857 857 }, 0); 858 858 } 859 - return xwikiDocument; 860 - }); 853 + }).promise(); 861 861 }; 862 862 863 863 var startRealTimeEditingSession = function(xwikiDocument) { ... ... @@ -922,7 +922,7 @@ 922 922 require(['editInPlace', wysiwygEditorModule], function(editInPlace) { 923 923 // Re-enable the translate button because it can be used while editing to create the missing translation. 924 924 translateButton.removeClass('disabled'); 925 - handler.edit(editInPlace, data). finally(function() {918 + handler.edit(editInPlace, data).always(function() { 926 926 // Restore only the edit button at the end because: 927 927 // * the translate button is restored (if needed) by the editInPlace module 928 928 // * the section edit links are restored when the document is rendered for view ... ... @@ -929,7 +929,7 @@ 929 929 editButton.removeClass('disabled'); 930 930 }); 931 931 // Fallback on the standalone edit mode if we fail to load the required modules. 932 - }, disableInPlaceEditing .bind(event.target));925 + }, $.proxy(disableInPlaceEditing, event.target)); 933 933 }; 934 934 935 935 var disableInPlaceEditing = function() {
- XWiki.UIExtensionClass[0]
-
- Executed Content
-
... ... @@ -48,6 +48,7 @@ 48 48 'editButtonSelector': '#tmEdit > a', 49 49 'translateButtonSelector': '#tmTranslate > a', 50 50 'enableSourceMode': true, 51 + 'enableOfficeImport': $services.officemanager.isConnected(), 51 51 'paths': { 52 52 'js': { 53 53 'xwiki-actionButtons': "#getSkinFileWithParams('js/xwiki/actionbuttons/actionButtons.js' $jsParams)",