Changes for page EditSheet
Last modified by teamwire005 on 2025/05/06 08:20
From version 2.1
edited by teamwire004
on 2024/01/16 09:21
on 2024/01/16 09:21
Change comment:
Install extension [org.xwiki.contrib:application-ckeditor-ui/1.48]
To version 4.1
edited by teamwire004
on 2024/07/12 13:08
on 2024/07/12 13:08
Change comment:
Install extension [org.xwiki.platform:xwiki-platform-ckeditor-ui/15.10.10]
Summary
-
Objects (4 modified, 5 added, 2 removed)
- XWiki.JavaScriptExtension[0]
- XWiki.JavaScriptExtension[1]
- XWiki.JavaScriptExtension[2]
- XWiki.StyleSheetExtension[0]
- XWiki.StyleSheetExtension[1]
- XWiki.UIExtensionClass[0]
- XWiki.UIExtensionClass[1]
- XWiki.UIExtensionClass[2]
- XWiki.UIExtensionClass[3]
- XWiki.UIExtensionClass[4]
- XWiki.UIExtensionClass[5]
Details
- XWiki.JavaScriptExtension[0]
-
- Code
-
... ... @@ -1,51 +1,6 @@ 1 -/* 2 -#set ($ckeditorPath = $services.webjars.url('org.xwiki.contrib:application-ckeditor-webjar', 'ckeditor')) 3 -#set ($bootstrap3typeaheadPath = $services.webjars.url('org.webjars.npm:bootstrap-3-typeahead', 'bootstrap3-typeahead.min')) 4 -#set ($fastDiffPath = $services.webjars.url('org.webjars.npm:fast-diff', 'diff')) 5 -#if ($ckeditorPath.indexOf('?') >= 0) 6 - ## Before XWiki 7.1M1 the WebJar resource path was included in the query string which means we have to specify the 7 - ## '.js' extension (Require.js doesn't add it in this case). 8 - #set ($ckeditorPath = "${ckeditorPath}.js") 9 - #set ($bootstrap3typeaheadPath = "${bootstrap3typeaheadPath}.js") 10 - #set ($fastDiffPath = "${$fastDiffPath}.js") 11 -#end 12 -#set ($ckeditorBasePath = $stringtool.removeEnd($stringtool.removeEnd($ckeditorPath, '.js'), 'ckeditor')) 13 -#set ($resourcePickerBundlePath = "${ckeditorBasePath}plugins/xwiki-resource/resourcePicker.bundle.min") 14 -#set ($macroWizardBundlePath = "${ckeditorBasePath}plugins/xwiki-macro/macroWizard.bundle.min") 15 -#set ($modalPath = "${ckeditorBasePath}plugins/xwiki-dialog/modal.min") 16 -#set ($l10nPath = "${ckeditorBasePath}plugins/xwiki-localization/l10n.min") 17 -#if ($resourcePickerBundlePath.indexOf('?') >= 0) 18 - ## Before XWiki 7.1M1 the WebJar resource path was included in the query string which means we have to specify the 19 - ## '.js' extension (Require.js doesn't add it in this case). 20 - #set ($resourcePickerBundlePath = "${resourcePickerBundlePath}.js") 21 - #set ($macroWizardBundlePath = "${macroWizardBundlePath}.js") 22 - #set ($modalPath = "${modalPath}.js") 23 - #set ($l10nPath = "${l10nPath}.js") 24 -#end 25 -*/ 1 +XWiki.locale = document.documentElement.getAttribute('lang') || ''; 2 + 26 26 require.config({ 27 - paths: { 28 - ckeditor: '$!ckeditorPath', 29 - resource: '$!resourcePickerBundlePath', 30 - resourcePicker: '$!resourcePickerBundlePath', 31 - entityResourcePicker: '$!resourcePickerBundlePath', 32 - entityResourceSuggester: '$!resourcePickerBundlePath', 33 - entityResourceDisplayer: '$!resourcePickerBundlePath', 34 - modal: '$!modalPath', 35 - l10n: '$!l10nPath', 36 - macroWizard: '$!macroWizardBundlePath', 37 - // This is used by the resource suggest picker on the link modal. 38 - 'bootstrap3-typeahead': '$!bootstrap3typeaheadPath', 39 - // This is used to preserve the selection when switching between WYSIWYG and Source modes. 40 - 'fast-diff': '$!fastDiffPath' 41 - }, 42 - shim: { 43 - ckeditor: { 44 - exports: 'CKEDITOR', 45 - // This includes dependencies of the plugins bundled with the CKEditor code. 46 - deps: ['jquery', 'resource', 'resourcePicker', 'macroWizard'] 47 - } 48 - }, 49 49 config: { 50 50 l10n: { 51 51 // We need to specify the language because this URL can be used after the page is loaded and thus after the ... ... @@ -53,73 +53,24 @@ 53 53 // a different language specified). We take the current language from the page HTML, rather than using Velocity, 54 54 // in order to avoid having the current language cached. 55 55 url: new XWiki.Document('Translator', 'CKEditor').getURL('get', 'outputSyntax=plain&language=' + 56 - encodeURIComponent( document.documentElement.getAttribute('lang')|| ''))11 + encodeURIComponent(XWiki.locale)) 57 57 } 58 58 } 59 59 }); 60 60 61 -window.CKEDITOR_BASEPATH = "$!ckeditorBasePath"; 62 - 63 63 define('xwiki-ckeditor', [ 64 64 'jquery', 18 + // The CKEditor standard API. 65 65 'ckeditor', 66 66 // Used to access the form token required by the upload URL. 67 67 'xwiki-meta', 22 + // CKEditor plugins specific to XWiki. 23 + 'xwiki-ckeditor-plugins', 68 68 // Used to catch form action events fired from Prototype.js code (actionButtons.js). 69 69 'xwiki-events-bridge', 70 - // Configures the path to the tree widget module and its dependencies which are used by the page and attachment 71 - // pickers on the link, image and macro dialogs to select pages and attachments. 72 - "$!services.webjars.url('org.xwiki.platform:xwiki-platform-tree-webjar', 'require-config.min.js', {'evaluate': true})" 26 + // Load the translations for our custom CKEditor plugins. 27 + new XWiki.Document('Translations', 'CKEditor').getURL('jsx', 'language=' + encodeURIComponent(XWiki.locale)) 73 73 ], function($, ckeditor, xwikiMeta) { 74 - var deferred = $.Deferred(); 75 - 76 - var loadJavaScriptSkinExtensions = $jsontool.serialize($xwiki.getDocument('CKEditor.Config' 77 - ).getValue('loadJavaScriptSkinExtensions')) === 1; 78 - 79 - // See http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules 80 - var allowedContentBySyntax = { 81 - 'xwiki/2.1': { 82 - '$1': { 83 - elements: { 84 - // Elements required because the editor input is a full HTML page. 85 - html: true, head: true, link: true, script: loadJavaScriptSkinExtensions, body: true, 86 - // Headings 87 - h1: true, h2: true, h3: true, h4: true, h5: true, h6: true, 88 - // Lists 89 - dl: true, ol: true, ul: true, 90 - // Tables 91 - table: true, tr: true, th: true, td: true, 92 - // Formatting 93 - span: true, strong: true, em: true, ins: true, del: true, sub: true, sup: true, tt: true, pre: true, 94 - // Others 95 - div: true, hr: true, p: true, a: true, img: true, blockquote: true 96 - }, 97 - // The elements above can have any attribute, through the parameter (%%) syntax. 98 - attributes: '*', 99 - styles: '*', 100 - classes: '*' 101 - }, 102 - '$2': { 103 - // The XWiki syntax doesn't support parameters for the following elements. 104 - elements: {br: true, dd: true, dt: true, li: true, tbody: true} 105 - }, 106 - '$3': { 107 - // Wiki syntax macros can output any HTML. 108 - match: CKEDITOR.plugins.xwikiMacro.isMacroOutput, 109 - attributes: '*', 110 - styles: '*', 111 - classes: '*' 112 - } 113 - } 114 - }; 115 - allowedContentBySyntax['xwiki/2.0'] = allowedContentBySyntax['xwiki/2.1']; 116 - // This is a hack, increasing the technical debt since the CKEditor module should not know about the Markdown 117 - // syntax. Actually it should not know either about the xwiki/2.0 and xwiki/2.1 syntaxes ;) 118 - // This should be fixed by implementing https://jira.xwiki.org/browse/CKEDITOR-319 119 - allowedContentBySyntax['markdown/1.2'] = allowedContentBySyntax['xwiki/2.1']; 120 - 121 - var currentLocale = $('html').attr('lang') || ''; 122 - 123 123 // We have to pass the plugin that makes the request (the initiator) because the expected response can be different 124 124 // (e.g. between the filebrowser and filetools plugins). 125 125 var getUploadURL = function(document, initiator) { ... ... @@ -126,8 +126,9 @@ 126 126 return document.getURL('get', $.param({ 127 127 sheet: 'CKEditor.FileUploader', 128 128 outputSyntax: 'plain', 35 + // The syntax and language are important especially when the upload request creates a new document. 129 129 syntax: document.syntax, 130 - language: currentLocale,37 + language: XWiki.locale, 131 131 form_token: xwikiMeta.form_token, 132 132 initiator: initiator 133 133 })); ... ... @@ -135,82 +135,38 @@ 135 135 136 136 // Extend the default CKEditor configuration with settings that depend on the source document. 137 137 var getConfig = function(element) { 45 + var sourceSyntax = $(element).attr('data-syntax'); 138 138 var sourceDocument = XWiki.currentDocument; 139 - var sourceDocumentReference = $(element).attr('data-sourceDocumentReference'); 140 - if (sourceDocumentReference) { 141 - sourceDocument = new XWiki.Document(XWiki.Model.resolve(sourceDocumentReference, XWiki.EntityType.DOCUMENT)); 47 + sourceDocument.syntax = XWiki.docsyntax; 48 + var sourceDocumentReference = XWiki.Model.resolve($(element).attr('data-sourceDocumentReference'), 49 + XWiki.EntityType.DOCUMENT, XWiki.currentDocument.documentReference); 50 + if (!XWiki.currentDocument.documentReference.equals(sourceDocumentReference)) { 51 + sourceDocument = new XWiki.Document(sourceDocumentReference); 52 + // We assume the syntax of the source document is the same as the syntax of the edited content. 53 + sourceDocument.syntax = sourceSyntax; 142 142 } 143 - sourceDocument.syntax = $(element).attr('data-sourceDocumentSyntax'); 55 + 56 + var uploadDisabled = element.hasAttribute('data-upload-disabled'); 57 + 144 144 var config = { 145 - allowedContent: allowedContentBySyntax[sourceDocument.syntax], 146 - filebrowserUploadUrl: getUploadURL(sourceDocument, 'filebrowser'), 147 - // This is used in CKEditor.FileUploader so we must keep them in sync. 148 - fileTools_defaultFileName: '__fileCreatedFromDataURI__', 59 + filebrowserUploadUrl: uploadDisabled ? '' : getUploadURL(sourceDocument, 'filebrowser'), 149 149 height: $(element).height(), 150 - // CKEditor uses '-' (dash) as locale separator (between the language code and the country code). 151 - language: currentLocale.toLowerCase().replace('_', '-'), 152 - uploadUrl: getUploadURL(sourceDocument, 'filetools'), 61 + // Used to resolve and serialize relative references. Also used to make HTTP requests with the right context. 62 + sourceDocument: sourceDocument, 63 + // The syntax of the edited content is not always the same as the syntax of the source document (which applies to 64 + // the source document content, but we might be editing something else, like an object property). 65 + sourceSyntax: sourceSyntax, 66 + uploadUrl: uploadDisabled ? '' : getUploadURL(sourceDocument, 'filetools'), 153 153 'xwiki-link': { 68 + // We use the source document to compute the link label generator URL because we want the link references to be 69 + // resolved relative to the edited document (as they were inserted). 154 154 labelGenerator: sourceDocument.getURL('get', $.param({ 155 155 sheet: 'CKEditor.LinkLabelGenerator', 156 156 outputSyntax: 'plain', 157 - language: currentLocale73 + language: XWiki.locale 158 158 })) 159 - }, 160 - 'xwiki-resource': { 161 - dispatcher: sourceDocument.getURL('get', $.param({ 162 - sheet: 'CKEditor.ResourceDispatcher', 163 - outputSyntax: 'plain', 164 - language: currentLocale 165 - })) 166 - }, 167 - 'xwiki-source': { 168 - htmlConverter: sourceDocument.getURL('get', $.param({ 169 - sheet: 'CKEditor.HTMLConverter', 170 - outputSyntax: 'plain', 171 - // Make sure we use the syntax specified when the editor was loaded. This is especially important when the 172 - // edited document is new (unsaved) because we want the converter to use the syntax specified by the template 173 - // rather than the default wiki syntax. 174 - sourceSyntax: sourceDocument.syntax, 175 - language: currentLocale 176 - })) 177 - }, 178 - mentions: [ 179 - { 180 - feed: sourceDocument.getURL('get', $.param({ 181 - sheet: 'CKEditor.LinkSuggestions', 182 - outputSyntax: 'plain', 183 - language: currentLocale 184 - // Prevent the curly brackets from being URL encoded because they mark a placeholder that will be replaced 185 - // with the text typed by the user (and CKEditor takes care of URL encoding it). 186 - }) + '&input={encodedQuery}'), 187 - itemTemplate: [ 188 - '<li data-id="{id}" class="ckeditor-autocomplete-item">', 189 - '<div>', 190 - '<span class="ckeditor-autocomplete-item-icon-wrapper">', 191 - // We have to output both icon types but normally only one is defined and the other is hidden. 192 - '<img src="{iconURL}"/>', 193 - '<span class="{iconClass}"></span>', 194 - '</span>', 195 - '<span class="ckeditor-autocomplete-item-label">{label}</span>', 196 - '</div>', 197 - '<div class="ckeditor-autocomplete-item-hint">{hint}</div>', 198 - '</li>'].join(''), 199 - outputTemplate: '<a href="{url}" data-reference="{typed}|-|{type}|-|{reference}">{label}</a>', 200 - marker: '[', 201 - minChars: 0, 202 - itemsLimit: 6 203 - } 204 - ] 75 + } 205 205 }; 206 - if ($(element).attr('data-officeImporterSupported') === 'true') { 207 - config['xwiki-office'] = { 208 - importer: sourceDocument.getURL('get', $.param({ 209 - sheet: 'CKEditor.OfficeImporter', 210 - language: currentLocale 211 - })) 212 - }; 213 - } 214 214 return config; 215 215 }; 216 216 ... ... @@ -264,18 +264,49 @@ 264 264 object[key] = newValue; 265 265 }; 266 266 267 - require([ 268 - // We cannot add these modules to the list of dependencies because they need the tree module to be configured first. 269 - 'entityResourcePicker', 'entityResourceSuggester', 'entityResourceDisplayer', 270 - // Load the translations for our custom CKEditor plugins. We didn't add this as a dependency to the xwiki-ckeditor 271 - // module because some of our plugins load their dependencies with RequireJS and thus they are loaded with a small 272 - // delay. The plugin needs to be defined before calling CKEDITOR.plugins.setLang(). 273 - new XWiki.Document('Translations', 'CKEditor').getURL('jsx', $.param({ 274 - language: currentLocale 275 - })) 276 - ], function() { 277 - deferred.resolve(ckeditor); 130 + // See XWIKI-21351: Macros using RequireJS are not properly displayed by the standalone WYSIWYG editor even when 131 + // JavaScript is enabled. 132 + // 133 + // For each CKEditor instance that uses a separate DOM document for the edited content (i.e. classical iframe-based 134 + // editor) we overwrite the appendChild and insertBefore functions of the initial HEAD element in order to make sure 135 + // that RequireJS appends the script tags to the current HEAD element (because the HEAD element is overwritten each 136 + // time the edited content is reloaded, like when inserting a macro or switching between Source and WYSIWYG modes). 137 + // 138 + // We have to overwrite both appendChild and insertBefore because depending on the presence of the BASE element 139 + // RequireJS uses one or the other. 140 + ckeditor.on('instanceReady', ({editor}) => { 141 + if (editor.document.$ !== document) { 142 + // This editor instance is using a separate DOM document for editing which means it's a standalone editor. 143 + const initialHead = editor.document.$.head; 144 + const originalAppendChild = initialHead.appendChild; 145 + initialHead.appendChild = function() { 146 + const currentHead = editor.document.$.head; 147 + if (currentHead !== initialHead) { 148 + // The edited content has been reloaded. Append to the current HEAD. 149 + return currentHead.appendChild.apply(currentHead, arguments); 150 + } else { 151 + // Still using the initial HEAD so preserve the default behavior. 152 + originalAppendChild.apply(initialHead, arguments); 153 + } 154 + }; 155 + const originalInsertBefore = initialHead.insertBefore; 156 + initialHead.insertBefore = function(newChild, existingChild) { 157 + const currentHead = editor.document.$.head; 158 + if (currentHead !== initialHead) { 159 + // The edited content has been reloaded. Normally the given existingChild should be a child of the initial 160 + // HEAD element (not the current one), but better check to be sure. 161 + if (existingChild.parentNode === currentHead) { 162 + return currentHead.insertBefore(newChild, existingChild); 163 + } else { 164 + return currentHead.appendChild.apply(newChild); 165 + } 166 + } else { 167 + // Still using the initial HEAD so preserve the default behavior. 168 + return originalInsertBefore.apply(initialHead, arguments); 169 + } 170 + }; 171 + } 278 278 }); 279 279 280 - return deferred.promise();174 + return $.Deferred().resolve(ckeditor).promise(); 281 281 }); - Parse content
-
... ... @@ -1,1 +1,1 @@ 1 - Yes1 +No
- XWiki.JavaScriptExtension[1]
-
- Caching policy
-
... ... @@ -1,1 +1,0 @@ 1 -long - Code
-
... ... @@ -1,178 +1,0 @@ 1 -// Fix CKEDITOR.tools.escapeCss() for browsers that don't support CSS.escape() 2 -// See https://github.com/ckeditor/ckeditor4/issues/681 3 -require(['jquery', 'ckeditor'], function($, ckeditor) { 4 - // Test if CKEDITOR.tools.escapeCss() works as expected. 5 - if (ckeditor.tools.escapeCss('.') === '.') { 6 - // Special CSS characters were not escaped so we need to fix this. 7 - // Use jQuery's escapeSelector() if available (only since jQuery 3.0), otherwise use some naive implementation. 8 - ckeditor.tools.escapeCss = $.escapeSelector || function(selector) { 9 - if (typeof selector === 'string') { 10 - // Simple implementation. 11 - // 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/ 12 - return selector.replace(/(:|\.|\[|\]|,|=|@)/g, '\\$1'); 13 - } else { 14 - return selector; 15 - } 16 - }; 17 - } 18 -}); 19 - 20 -// Fix the path to the arrow icon that indicates the presence of a sub-menu in the context menu. 21 -if (CKEDITOR_BASEPATH.indexOf('?') >= 0) { 22 - // The WebJar resource path was specified in the query string before 7.1M1 which prevented the browser from resolving 23 - // relative paths. See XWIKI-10880 (A CSS file inside a webjar cannot use a resource from that webjar). 24 - require(['ckeditor'], function(ckeditor) { 25 - ckeditor.on('instanceReady', function(event) { 26 - if (event.editor.contextMenu) { 27 - event.editor.contextMenu._.panelDefinition.css.push( 28 - '.cke_menuarrow {' + 29 - 'background-image: url("' + CKEDITOR_BASEPATH + 'skins/moono-lisa/images/arrow.png") !important;' + 30 - '}' 31 - ); 32 - } 33 - }); 34 - }); 35 -} 36 - 37 -// Polyfill for the xwiki:actions:beforeSave and xwiki:actions:beforePreview events (available since 7.4.1) 38 -// We have to use Prototype.js because it is loaded before jQuery and we need to register our save and preview listeners 39 -// before the actionButtons.js does it, as otherwise the CKEditor doesn't get the chance to update the text area before 40 -// the form is submitted. 41 -(function() { 42 - var submitActions = ['save', 'preview']; 43 - var beforeSubmitWasTriggered = false; 44 - var onBeforeSubmit = function(event) { 45 - beforeSubmitWasTriggered = true; 46 - if (!(event.memo || {}).polyfill) { 47 - removeListeners(); 48 - } 49 - }; 50 - var onSubmit = function(event) { 51 - if (!beforeSubmitWasTriggered && jQuery) { 52 - // Our CKEditor plugins use jQuery to listen to events. 53 - var parts = event.eventName.split(':'); 54 - var data = event.memo || {}; 55 - data.polyfill = true; 56 - jQuery(document).triggerHandler(getBeforeEventName(parts[parts.length - 1]), data); 57 - } 58 - beforeSubmitWasTriggered = false; 59 - }; 60 - var getBeforeEventName = function(action) { 61 - return 'xwiki:actions:before' + action.substr(0, 1).toUpperCase() + action.substr(1); 62 - }; 63 - var removeListeners = function() { 64 - submitActions.forEach(function(action) { 65 - document.stopObserving(getBeforeEventName(action), onBeforeSubmit); 66 - document.stopObserving('xwiki:actions:' + action, onSubmit); 67 - }); 68 - }; 69 - if (typeof document.observe == 'function') { 70 - submitActions.forEach(function(action) { 71 - document.observe(getBeforeEventName(action), onBeforeSubmit); 72 - document.observe('xwiki:actions:' + action, onSubmit); 73 - }); 74 - } 75 -})(); 76 - 77 -// Make sure the "Back To Edit" button from the Preview mode works as expected on XWiki versions older than 8.2 (where 78 -// CKEditor is not the default editor). 79 -require(['jquery'], function($) { 80 - if (/&sheet=CKEditor.EditSheet\b/.test(window.location.href)) { 81 - // Make sure the CKEditor.EditSheet is preserved when coming back from Preview mode. 82 - $('form#inline').find('input[name="xcontinue"]').val(function(index, oldValue) { 83 - return oldValue + '&sheet=CKEditor.EditSheet'; 84 - }); 85 - } 86 -}); 87 - 88 -// Polyfill for entityReference.js 89 -require(['jquery'], function($) { 90 - if (typeof XWiki.EntityType.byName !== 'function') { 91 - // Before 6.4.1 92 - var entityTypeByName = { 93 - wiki: XWiki.EntityType.WIKI, 94 - space: XWiki.EntityType.SPACE, 95 - document: XWiki.EntityType.DOCUMENT, 96 - attachment: XWiki.EntityType.ATTACHMENT 97 - }; 98 - XWiki.EntityType.byName = function(name) { 99 - return entityTypeByName[name]; 100 - }; 101 - } 102 - 103 - if (typeof XWiki.EntityType.getName !== 'function') { 104 - // Before 6.4.1 105 - var entityTypes = ['wiki', 'space', 'document', 'attachment']; 106 - XWiki.EntityType.getName = function(entityType) { 107 - return entityTypes[entityType]; 108 - } 109 - } 110 - 111 - if (typeof XWiki.EntityReference.prototype.getReversedReferenceChain !== 'function') { 112 - // Before 7.2M2 113 - XWiki.EntityReference.prototype.getReversedReferenceChain = function() { 114 - return this._extractComponents().reverse(); 115 - }; 116 - } 117 - 118 - if (typeof XWiki.currentDocument.getDocumentReference !== 'function') { 119 - // Before 7.2M3 120 - // Take the current document full name. 121 - var currentDocumentReference = $('meta[name="document"]').attr('content'); 122 - // Resolve the local reference. 123 - currentDocumentReference = XWiki.Model.resolve(currentDocumentReference, XWiki.EntityType.DOCUMENT); 124 - // Add the wiki component. 125 - currentDocumentReference.getReversedReferenceChain()[0].parent = new XWiki.WikiReference(XWiki.currentWiki); 126 - XWiki.currentDocument.getDocumentReference = function() { 127 - return currentDocumentReference; 128 - }; 129 - } 130 - 131 - var reference = XWiki.Model.resolve('S', XWiki.EntityType.SPACE, new XWiki.WikiReference('W')); 132 - if (!reference.parent) { 133 - // The resolve method did not support a default value provider before 7.2M1. 134 - var oldResolve = XWiki.Model.resolve; 135 - XWiki.Model.resolve = function(representation, entityType, defaultValueProvider) { 136 - var reference = oldResolve.apply(this, arguments); 137 - if (reference && defaultValueProvider && typeof defaultValueProvider.extractReference === 'function') { 138 - // The given default value provider is an entity reference (normally a document reference). 139 - var root = reference.getReversedReferenceChain()[0]; 140 - // We cover the document and attachment references mainly, 141 - var defaultRoot = defaultValueProvider.extractReference(root.type) || {parent: defaultValueProvider}; 142 - // Nested spaces were introduced in 7.2M1 so we can safely assume that the given default value provider has only 143 - // one space reference component. 144 - root.parent = defaultRoot.parent; 145 - } 146 - return reference; 147 - }; 148 - } 149 -}); 150 - 151 -// Fix the layout to be consistent with the Wiki edit mode (tested with the Flamingo Skin). 152 -require(['jquery'], function($) { 153 - var ckeEditMeta = $('.cke-editMeta'); 154 - if (ckeEditMeta.length != 1) { 155 - // Fix the layout only when the CKEditor.EditSheet is applied. 156 - return; 157 - } 158 - // Hide the page title because the edit form has an input field to edit the title. This is consistent with the Wiki 159 - // edit mode. Remove the 'editMeta' id because the edit sheet adds an element with the same id. 160 - // NOTE: In order to rely on Chrome's Back-Forward cache we must not remove or move form elements. We can only hide. 161 - $('#document-title').parent('#editMeta').removeAttr('id').parent('.row').hide(); 162 - // Move the content menu before the editMeta element so that they are displayed on the same row. 163 - ckeEditMeta.attr('id', 'editMeta').addClass('col-md-pull-5') 164 - .before($('#contentmenu').parent('.col-md-5').addClass('col-md-push-7')); 165 -}); 166 - 167 -// Activate the auto-save feature on XWiki versions older than 8.2RC1 (XE-1562), where CKEditor is not the default 168 -// WYSIWYG editor and thus it is loaded with a sheet (CKEditor.EditSheet). Note that for XWiki 8.2RC1 and 8.2 (where 169 -// CKEditor is the default WYSIWYG editor) the auto-save feature is not activated because the WYSIWYG edit mode doesn't 170 -// active it. This has been fixed in 8.2.1 and 8.3M1 (XWIKI-8614). 171 -// Note that we can't enable auto-save by loading autosave.js from the editing sheet (CKEditor.EditSheet) because on 172 -// older versions of XWiki (XWIKI-8614) autosave.js needs to be loaded after actionbuttons.js, which is loaded after the 173 -// editing sheet is rendered. 174 -require(['jquery'], function($) { 175 - if ($('#xwikieditcontent').data('autosave')) { 176 - require(["$xwiki.getSkinFile('js/xwiki/editors/autosave.js', true)"]); 177 - } 178 -}); - Name
-
... ... @@ -1,1 +1,0 @@ 1 -Various fixes and polyfills - Parse content
-
... ... @@ -1,1 +1,0 @@ 1 -Yes - Use this extension
-
... ... @@ -1,1 +1,0 @@ 1 -onDemand
- XWiki.JavaScriptExtension[2]
-
- Code
-
... ... @@ -1,19 +1,37 @@ 1 1 require(['jquery', 'xwiki-ckeditor', 'xwiki-events-bridge'], function($, ckeditorPromise) { 2 + // Make sure we don't create the editors twice because this file can be loaded twice (by RequireJS, for in-place 3 + // editing, and as a JSX resource, for standalone editing). 4 + if (ckeditorPromise.__editSheetLoaded) { 5 + return; 6 + } 7 + ckeditorPromise.__editSheetLoaded = true; 8 + 9 + var createEditors = function(ckeditor, container) { 10 + container.find('.ckeditor-textarea').each(function() { 11 + // Wrap in try/catch so that a failure to load one editor doesn't affect the other editors. 12 + try { 13 + createEditor(ckeditor, this); 14 + } catch(e) { 15 + console.log(e); 16 + } 17 + }); 18 + }; 19 + 20 + var createEditor = function(ckeditor, textArea, instanceConfig) { 21 + var deferred = $.Deferred(); 22 + var editor = ckeditor.replace(textArea, instanceConfig); 23 + editor.once('instanceReady', deferred.resolve.bind(deferred, editor)); 24 + editor.once('reload', function(event) { 25 + event.data.promise = event.data.promise.then(createEditor.bind(null, ckeditor, textArea)); 26 + }); 27 + return deferred.promise(); 28 + }; 29 + 2 2 ckeditorPromise.done(function(ckeditor) { 3 - var createEditors = function(container) { 4 - container.find('.ckeditor-textarea').each(function() { 5 - // Wrap in try/catch so that a failure to load one editor doesn't affect the other editors. 6 - try { 7 - ckeditor.replace(this); 8 - } catch(e) { 9 - console.log(e); 10 - } 11 - }); 12 - }; 13 - createEditors($(body)); 31 + createEditors(ckeditor, $(body)); 14 14 // Make sure we don't register the event listener multiple times (in case this code is loaded multiple times). 15 15 $(document).off('xwiki:dom:updated.ckeditor').on('xwiki:dom:updated.ckeditor', function(event, data) { 16 - createEditors($(data.elements)); 34 + createEditors(ckeditor, $(data.elements)); 17 17 }); 18 18 }); 19 19 }); - Parse content
-
... ... @@ -1,1 +1,1 @@ 1 - Yes1 +No
- XWiki.StyleSheetExtension[0]
-
- Code
-
... ... @@ -1,50 +46,5 @@ 1 -#template('colorThemeInit.vm') 2 - 3 -/* 4 -#set ($ckeditorSkinPath = $services.webjars.url('org.xwiki.contrib:application-ckeditor-webjar', 'skins/moono-lisa')) 5 -#if ($ckeditorSkinPath.indexOf('?') >= 0) 6 - ## The WebJar resource path was specified in the query string before 7.1M1 which prevented the browser from resolving 7 - ## relative paths. See XWIKI-10880 (A CSS file inside a webjar cannot use a resource from that webjar). 8 - */ 9 - a.cke_button > span.cke_button_icon { 10 - background-image: url("$ckeditorSkinPath/icons.png") !important; 11 - } 12 - .cke_hidpi a.cke_button > span.cke_button_icon { 13 - background-image: url("$ckeditorSkinPath/icons_hidpi.png") !important; 14 - } 15 - .cke_notification_close, a.cke_dialog_close_button { 16 - background-image: url("$ckeditorSkinPath/images/close.png") !important; 17 - } 18 - .cke_hidpi .cke_dialog_close_button { 19 - background-image: url("$ckeditorSkinPath/images/hidpi/close.png") !important; 20 - } 21 - .cke_dialog a.cke_btn_reset { 22 - background-image: url("$ckeditorSkinPath/images/refresh.png") !important; 23 - } 24 - .cke_hidpi .cke_dialog a.cke_btn_reset { 25 - background-image: url("$ckeditorSkinPath/images/hidpi/refresh.png") !important; 26 - } 27 - .cke_dialog a.cke_btn_locked { 28 - background-image: url("$ckeditorSkinPath/images/lock.png") !important; 29 - } 30 - .cke_hidpi .cke_dialog a.cke_btn_locked { 31 - background-image: url("$ckeditorSkinPath/images/hidpi/lock.png") !important; 32 - } 33 - .cke_dialog a.cke_btn_unlocked { 34 - background-image: url("$ckeditorSkinPath/images/lock-open.png") !important; 35 - } 36 - .cke_hidpi .cke_dialog a.cke_btn_unlocked { 37 - background-image: url("$ckeditorSkinPath/images/hidpi/lock-open.png") !important; 38 - } 39 - .cke_menuarrow { 40 - background-image: url("$ckeditorSkinPath/images/arrow.png") !important; 41 - } 42 - /* 43 -#end 44 -*/ 45 - 46 46 a.cke_button_disabled > span.cke_button_icon.loading { 47 - background-image: url( "$xwiki.getSkinFile('icons/xwiki/spinner.gif')")!important;2 + background-image: url(@xwiki-icon-spinner) !important; 48 48 background-position: 0 0 !important; 49 49 } 50 50 ... ... @@ -71,7 +71,7 @@ 71 71 } 72 72 73 73 /** 74 - * Full-screen styles. 29 + * Full-screen styles (for the standalone / classic editor). 75 75 */ 76 76 77 77 .fullScreenEditLinkContainer { ... ... @@ -80,11 +80,11 @@ 80 80 } 81 81 82 82 .cke_maximized .buttons { 83 - background-color: $theme.backgroundSecondaryColor;38 + background-color: @well-bg; 84 84 padding: .5em; 85 85 } 86 86 87 -/* The 'skin-flamingo' class name is removed from the body element in full-screen mode so we need to fix the auto-save 42 +/* The 'skin-flamingo' class name is removed from the body element in full-screen mode so we need to fix the auto-save 88 88 styles. */ 89 89 .cke_maximized #autosaveControl input.autosave-frequency { 90 90 width: 3em; ... ... @@ -188,7 +188,7 @@ 188 188 box-sizing: border-box; 189 189 } 190 190 .resourcePicker .resourceDisplay.loading { 191 - background-image: url( "$xwiki.getSkinFile('icons/xwiki/spinner.gif')");146 + background-image: url(@xwiki-icon-spinner); 192 192 background-repeat: no-repeat; 193 193 } 194 194 ... ... @@ -212,7 +212,7 @@ 212 212 * tree finder = 48px 213 213 * footer = 69px 214 214 */ 215 - max-height: calc(100vh - 268px); 170 + max-height: calc(~"100vh - 268px"); 216 216 overflow-y: auto; 217 217 } 218 218 ... ... @@ -281,38 +281,215 @@ 281 281 */ 282 282 ul.cke_autocomplete_panel { 283 283 border: 1px solid rgba(0, 0, 0, 0.15); 284 - border-radius: 4px;239 + border-radius: @border-radius-base; 285 285 box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175); 286 286 font: inherit; 287 287 padding: 5px 0; 288 288 width: auto; 289 - max-width: 100%;244 + max-width: 324px; 290 290 min-width: 200px; 291 291 } 247 +.cke_autocomplete_panel > li.ckeditor-autocomplete-group, 292 292 .cke_autocomplete_panel > li.ckeditor-autocomplete-item { 293 - padding: 3px12px;249 + padding: 5px 20px; 294 294 } 295 -.cke_autocomplete_panel > li.ckeditor-autocomplete-item > div { 251 +.cke_autocomplete_panel > li.ckeditor-autocomplete-group { 252 + border-top: 1px solid @xwiki-border-color; 253 + color: @text-muted; 254 + font-size: smaller; 255 + margin-top: 9px; 256 + padding-top: 14px; 257 +} 258 +.cke_autocomplete_panel > li.ckeditor-autocomplete-group h6 { 259 + font-size: inherit; 260 + margin: 0; 261 +} 262 +.cke_autocomplete_panel > li.ckeditor-autocomplete-group:first-child { 263 + border-top: 0 none; 264 + margin-top: 0; 265 + padding-top: 5px; 266 +} 267 +.cke_autocomplete_panel > li.ckeditor-autocomplete-group:hover { 268 + background-color: transparent; 269 + cursor: inherit; 270 +} 271 +.ckeditor-autocomplete-group h6, 272 +.ckeditor-autocomplete-item-label, 273 +.ckeditor-autocomplete-item-shortcut { 274 + overflow: hidden; 275 + text-overflow: ellipsis; 296 296 white-space: nowrap; 297 297 } 278 +.ckeditor-autocomplete-item-head { 279 + display: flex; 280 + align-items: center; 281 +} 298 298 .ckeditor-autocomplete-item-icon-wrapper { 299 299 display: inline-block; 300 300 height: 14px; 301 301 line-height: 14px; 302 - margin-right: . 3em;286 + margin-right: .5em; 303 303 text-align: center; 304 304 width: 14px; 305 305 } 306 306 .ckeditor-autocomplete-item-icon-wrapper img { 307 - border-radius: 3px;291 + border-radius: @border-radius-small; 308 308 max-height: 14px; 309 309 max-width: 14px; 310 310 vertical-align: text-top; 311 311 } 296 +.ckeditor-autocomplete-item-preview-wrapper { 297 + display: flex; 298 + align-items: center; 299 + justify-content: space-around; 300 + height: 64px; 301 + margin-right: .5em; 302 + text-align: center; 303 + vertical-align: middle; 304 + width: 64px; 305 +} 306 +.ckeditor-autocomplete-centered { 307 + justify-content: center; 308 +} 309 +.ckeditor-autocomplete-item-preview-wrapper img { 310 + border-radius: @border-radius-small; 311 + max-height: 64px; 312 + max-width: 64px; 313 + vertical-align: text-top; 314 +} 315 +/* The image still takes some space in IE11 even if there's no source specified. Let's make sure it's hidden. 316 + See CKEDITOR-389: Missing space in the suggestions that appear while using the autocomplete function on IE 11 */ 317 +.ckeditor-autocomplete-item-preview-wrapper img[src=""], 318 +.ckeditor-autocomplete-item-icon-wrapper img[src=""] { 319 + display: none; 320 +} 321 +.ckeditor-autocomplete-item-label { 322 + /* Push the shortcut to the right edge of the item. */ 323 + flex-grow: 1; 324 +} 325 +.ckeditor-autocomplete-item-shortcut:not(:empty) { 326 + background-color: @xwiki-border-color; 327 + border-radius: @border-radius-base; 328 + padding: 2px 5px; 329 + margin-left: .5em; 330 +} 331 +.ckeditor-autocomplete-item-shortcut, 332 +.ckeditor-autocomplete-item-badge, 312 312 .ckeditor-autocomplete-item-hint { 313 - color: $theme.textSecondaryColor;334 + color: @text-muted; 314 314 font-size: smaller; 315 315 } 337 +.ckeditor-autocomplete-item-badge { 338 + background-color: @xwiki-border-color; 339 + font-weight: normal; 340 +} 341 +.ckeditor-autocomplete-item-hint { 342 + /* Limit to 3 lines of text (based on line height). */ 343 + max-height: calc(3 * 20em / 14); 344 + overflow: hidden; 345 + /* Put the ellipsis at the end of the last line when the text is cut. */ 346 + display: -webkit-box; 347 + -webkit-box-orient: vertical; 348 + -webkit-line-clamp: 3; 349 +} 316 316 .ckeditor-autocomplete-item-hint:empty { 317 317 margin-top: 0; 318 318 } 353 + 354 +/** 355 + * Source mode 356 + */ 357 + 358 +.cke_contents > textarea.cke_source { 359 + box-sizing: border-box; 360 + color: @text-color; 361 + font-family: @font-family-monospace; 362 + font-size: inherit; 363 + /* Same padding as on the page content. */ 364 + padding: @grid-gutter-width / 2; 365 +} 366 + 367 +.cke_contents > textarea.cke_source.cke_editable_inline { 368 + border: 1px solid transparent; 369 + border-radius: 0; 370 + box-shadow: none; 371 + margin-top: -1px; 372 + margin-left: -1px; 373 + 374 + .form-control-focus(); 375 +} 376 + 377 +.cke_contents.fake { 378 + /* We need this to have the box shadow visible when the source area is focused. */ 379 + overflow: visible; 380 +} 381 + 382 +#xwikicontent + .cke_contents > textarea.cke_source.cke_editable_inline { 383 + /* Don't take the padding and the margin into account when computing the 100% width. */ 384 + box-sizing: content-box; 385 + /* Make sure the Source area has the same width as the WYSIWYG area. */ 386 + margin-left: -@grid-gutter-width / 2 - 1px; 387 + margin-right: -@grid-gutter-width / 2 - 1px; 388 +} 389 + 390 +/** 391 + * Full-screen styles for the in-line editor 392 + */ 393 +body[data-maximized="true"] { 394 + overflow: hidden; 395 + 396 + .cke_maximize_backdrop, 397 + .cke_toolBar_active, 398 + .cke_editable_active, 399 + .cke_actionBar_active { 400 + position: fixed !important; 401 + right: 0 !important; 402 + left: 0 !important; 403 + } 404 + 405 + /* 406 + * The tool bar 407 + */ 408 + .cke_toolBar_active { 409 + /* We have to use !important in order to overwrite the in-line styles. */ 410 + display: block !important; 411 + top: 0 !important; 412 + } 413 + 414 + /* 415 + * The editing area 416 + */ 417 + .cke_maximize_backdrop, 418 + .cke_editable_active { 419 + background-color: @xwiki-page-content-bg; 420 + } 421 + .cke_editable_active { 422 + box-sizing: border-box !important; 423 + margin: 0 !important; 424 + overflow-y: auto !important; 425 + z-index: 9995; 426 + 427 + &:focus { 428 + /* Remove the focus border. */ 429 + border-color: transparent !important; 430 + box-shadow: none !important; 431 + } 432 + } 433 + .cke_maximize_backdrop { 434 + top: 0; 435 + bottom: 0; 436 + z-index: 99; 437 + } 438 + 439 + /* 440 + * The action buttons 441 + */ 442 + .cke_actionBar_active { 443 + background-color: @xwiki-background-secondary-color; 444 + border: 1px solid @xwiki-border-color; 445 + bottom: 0; 446 + /* Reduce a bit the padding. */ 447 + padding: .5em; 448 + z-index: 9995; 449 + } 450 +} - Content Type
-
... ... @@ -1,1 +1,1 @@ 1 - CSS1 +LESS - Name
-
... ... @@ -1,1 +1,0 @@ 1 -CKEditor Skin Fix - Parse content
-
... ... @@ -1,1 +1,1 @@ 1 - Yes1 +No
- XWiki.StyleSheetExtension[1]
-
- Caching policy
-
... ... @@ -1,1 +1,0 @@ 1 -long - Code
-
... ... @@ -1,37 +1,0 @@ 1 -/** 2 - * Source mode 3 - */ 4 - 5 -.cke_contents > textarea.cke_source { 6 - box-sizing: border-box; 7 - color: @text-color; 8 - font-family: @font-family-monospace; 9 - font-size: inherit; 10 - /* Same padding as on the page content. */ 11 - padding: @grid-gutter-width / 2; 12 -} 13 - 14 -.cke_contents > textarea.cke_source.cke_editable_inline { 15 - border: 1px solid transparent; 16 - border-radius: 0; 17 - box-shadow: none; 18 - margin-top: -1px; 19 - margin-left: -1px; 20 - 21 - &:focus { 22 - .form-control-focus(); 23 - } 24 -} 25 - 26 -.cke_contents.fake { 27 - /* We need this to have the box shadow visible when the source area is focused. */ 28 - overflow: visible; 29 -} 30 - 31 -#xwikicontent + .cke_contents > textarea.cke_source.cke_editable_inline { 32 - /* Don't take the padding and the margin into account when computing the 100% width. */ 33 - box-sizing: content-box; 34 - /* Make sure the Source area has the same width as the WYSIWYG area. */ 35 - margin-left: -@grid-gutter-width / 2 - 1px; 36 - margin-right: -@grid-gutter-width / 2 - 1px; 37 -} - Content Type
-
... ... @@ -1,1 +1,0 @@ 1 -LESS - Name
-
... ... @@ -1,1 +1,0 @@ 1 -LESS - Parse content
-
... ... @@ -1,1 +1,0 @@ 1 -No - Use this extension
-
... ... @@ -1,1 +1,0 @@ 1 -onDemand
- XWiki.UIExtensionClass[0]
-
- Extension ID
-
... ... @@ -1,1 +1,1 @@ 1 -org.xwiki.platform.requirejs.module.ckeditor 1 +org.xwiki.platform.requirejs.module.xwiki-ckeditor - Extension Parameters
-
... ... @@ -1,2 +1,2 @@ 1 1 id=xwiki-ckeditor 2 -path=$xwiki.getURL('CKEditor.EditSheet', 'jsx', $escapetool.url({'v': $services.extension.installed.getInstalledExtension('org.xwiki.contri b:application-ckeditor-ui', "wiki:$xcontext.database").version.value}))2 +path=$xwiki.getURL('CKEditor.EditSheet', 'jsx', $escapetool.url({'v': $services.extension.installed.getInstalledExtension('org.xwiki.platform:xwiki-platform-ckeditor-ui', "wiki:$xcontext.database").version.value, 'xwiki-version': $services.extension.core.getCoreExtension('org.xwiki.platform:xwiki-platform-tree-webjar').version.value, 'fast-diff-version': $services.extension.installed.getInstalledExtension('org.webjars.npm:fast-diff', "wiki:$xcontext.database").version.value, 'bs3typeahead-version': $services.extension.installed.getInstalledExtension('org.webjars.npm:bootstrap-3-typeahead', "wiki:$xcontext.database").version.value}))
- XWiki.UIExtensionClass[1]
-
- Cached
-
... ... @@ -1,0 +1,1 @@ 1 +No - Asynchronous rendering
-
... ... @@ -1,0 +1,1 @@ 1 +No - Extension Point ID
-
... ... @@ -1,0 +1,1 @@ 1 +org.xwiki.platform.requirejs.module - Extension ID
-
... ... @@ -1,0 +1,1 @@ 1 +org.xwiki.platform.requirejs.module.fusejs - Extension Parameters
-
... ... @@ -1,0 +1,2 @@ 1 +id=fuse 2 +path=$services.webjars.url('org.webjars.npm:fuse.js', 'dist/fuse.basic.min.js') - Extension Scope
-
... ... @@ -1,0 +1,1 @@ 1 +wiki
- XWiki.UIExtensionClass[2]
-
- Cached
-
... ... @@ -1,0 +1,1 @@ 1 +No - Asynchronous rendering
-
... ... @@ -1,0 +1,1 @@ 1 +No - Extension Point ID
-
... ... @@ -1,0 +1,1 @@ 1 +org.xwiki.platform.requirejs.module - Extension ID
-
... ... @@ -1,0 +1,1 @@ 1 +org.xwiki.platform.requirejs.module.bootstrap3-typeahead - Extension Parameters
-
... ... @@ -1,0 +1,2 @@ 1 +id=bootstrap3-typeahead 2 +path=$services.webjars.url('org.webjars.npm:bootstrap-3-typeahead', 'bootstrap3-typeahead.min') - Extension Scope
-
... ... @@ -1,0 +1,1 @@ 1 +wiki
- XWiki.UIExtensionClass[3]
-
- Cached
-
... ... @@ -1,0 +1,1 @@ 1 +No - Asynchronous rendering
-
... ... @@ -1,0 +1,1 @@ 1 +No - Extension Point ID
-
... ... @@ -1,0 +1,1 @@ 1 +org.xwiki.platform.requirejs.module - Extension ID
-
... ... @@ -1,0 +1,1 @@ 1 +org.xwiki.platform.requirejs.module.fast-diff - Extension Parameters
-
... ... @@ -1,0 +1,2 @@ 1 +id=fast-diff 2 +path=$services.webjars.url('org.webjars.npm:fast-diff', 'diff') - Extension Scope
-
... ... @@ -1,0 +1,1 @@ 1 +wiki
- XWiki.UIExtensionClass[4]
-
- Cached
-
... ... @@ -1,0 +1,1 @@ 1 +No - Asynchronous rendering
-
... ... @@ -1,0 +1,1 @@ 1 +No - Extension Point ID
-
... ... @@ -1,0 +1,1 @@ 1 +org.xwiki.platform.requirejs.module - Extension ID
-
... ... @@ -1,0 +1,1 @@ 1 +org.xwiki.platform.requirejs.module.ckeditor - Extension Parameters
-
... ... @@ -1,0 +1,3 @@ 1 +id=ckeditor 2 +path=$services.webjars.url('org.xwiki.platform:xwiki-platform-ckeditor-webjar', 'ckeditor') 3 +exports=CKEDITOR - Extension Scope
-
... ... @@ -1,0 +1,1 @@ 1 +wiki
- XWiki.UIExtensionClass[5]
-
- Cached
-
... ... @@ -1,0 +1,1 @@ 1 +No - Asynchronous rendering
-
... ... @@ -1,0 +1,1 @@ 1 +No - Extension Point ID
-
... ... @@ -1,0 +1,1 @@ 1 +org.xwiki.platform.requirejs.module - Extension ID
-
... ... @@ -1,0 +1,1 @@ 1 +org.xwiki.platform.requirejs.module.xwiki-ckeditor-plugins - Extension Parameters
-
... ... @@ -1,0 +1,4 @@ 1 +id=xwiki-ckeditor-plugins 2 +path=$services.webjars.url('org.xwiki.platform:xwiki-platform-ckeditor-plugins', 'webjar.bundle.min') 3 +bundles=resource, resourcePicker, entityResourcePicker, entityResourceSuggester, entityResourceDisplayer, modal, l10n, macroWizard, imageWizard 4 +deps=jquery, ckeditor - Extension Scope
-
... ... @@ -1,0 +1,1 @@ 1 +wiki