Changes for page EditSheet

Last modified by teamwire005 on 2025/05/06 08:20

From version 1.1
edited by teamwire001
on 2021/06/11 07:39
Change comment: Install extension [org.xwiki.contrib:application-ckeditor-ui/1.53.2]
To version 4.1
edited by teamwire004
on 2024/07/12 13:08
Change comment: Install extension [org.xwiki.platform:xwiki-platform-ckeditor-ui/15.10.10]

Summary

Details

Page properties
Author
... ... @@ -1,1 +1,1 @@
1 -XWiki.teamwire001
1 +XWiki.teamwire004
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,74 +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 - 'plain/1.0': ';'
115 - };
116 - allowedContentBySyntax['xwiki/2.0'] = allowedContentBySyntax['xwiki/2.1'];
117 - // This is a hack, increasing the technical debt since the CKEditor module should not know about the Markdown
118 - // syntax. Actually it should not know either about the xwiki/2.0 and xwiki/2.1 syntaxes ;)
119 - // This should be fixed by implementing https://jira.xwiki.org/browse/CKEDITOR-319
120 - allowedContentBySyntax['markdown/1.2'] = allowedContentBySyntax['xwiki/2.1'];
121 -
122 - var currentLocale = $('html').attr('lang') || '';
123 -
124 124   // We have to pass the plugin that makes the request (the initiator) because the expected response can be different
125 125   // (e.g. between the filebrowser and filetools plugins).
126 126   var getUploadURL = function(document, initiator) {
... ... @@ -127,8 +127,9 @@
127 127   return document.getURL('get', $.param({
128 128   sheet: 'CKEditor.FileUploader',
129 129   outputSyntax: 'plain',
35 + // The syntax and language are important especially when the upload request creates a new document.
130 130   syntax: document.syntax,
131 - language: currentLocale,
37 + language: XWiki.locale,
132 132   form_token: xwikiMeta.form_token,
133 133   initiator: initiator
134 134   }));
... ... @@ -136,79 +136,38 @@
136 136  
137 137   // Extend the default CKEditor configuration with settings that depend on the source document.
138 138   var getConfig = function(element) {
45 + var sourceSyntax = $(element).attr('data-syntax');
139 139   var sourceDocument = XWiki.currentDocument;
140 - var sourceDocumentReference = $(element).attr('data-sourceDocumentReference');
141 - if (sourceDocumentReference) {
142 - 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;
143 143   }
144 - sourceDocument.syntax = $(element).attr('data-sourceDocumentSyntax');
55 +
56 + var uploadDisabled = element.hasAttribute('data-upload-disabled');
57 +
145 145   var config = {
146 - allowedContent: allowedContentBySyntax[sourceDocument.syntax],
147 - editorplaceholder: $jsontool.serialize($services.localization.render('ckeditor.content.placeholder')),
148 - filebrowserUploadUrl: getUploadURL(sourceDocument, 'filebrowser'),
149 - // This is used in CKEditor.FileUploader so we must keep them in sync.
150 - fileTools_defaultFileName: '__fileCreatedFromDataURI__',
59 + filebrowserUploadUrl: uploadDisabled ? '' : getUploadURL(sourceDocument, 'filebrowser'),
151 151   height: $(element).height(),
152 - // CKEditor uses '-' (dash) as locale separator (between the language code and the country code).
153 - language: currentLocale.toLowerCase().replace('_', '-'),
154 - 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'),
155 155   '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).
156 156   labelGenerator: sourceDocument.getURL('get', $.param({
157 157   sheet: 'CKEditor.LinkLabelGenerator',
158 158   outputSyntax: 'plain',
159 - language: currentLocale
73 + language: XWiki.locale
160 160   }))
161 - },
162 - 'xwiki-resource': {
163 - dispatcher: sourceDocument.getURL('get', $.param({
164 - sheet: 'CKEditor.ResourceDispatcher',
165 - outputSyntax: 'plain',
166 - language: currentLocale
167 - }))
168 - },
169 - 'xwiki-source': {
170 - htmlConverter: sourceDocument.getURL('get', $.param({
171 - sheet: 'CKEditor.HTMLConverter',
172 - outputSyntax: 'plain',
173 - language: currentLocale
174 - }))
175 - },
176 - mentions: [
177 - {
178 - feed: sourceDocument.getURL('get', $.param({
179 - sheet: 'CKEditor.LinkSuggestions',
180 - outputSyntax: 'plain',
181 - language: currentLocale
182 - // Prevent the curly brackets from being URL encoded because they mark a placeholder that will be replaced
183 - // with the text typed by the user (and CKEditor takes care of URL encoding it).
184 - }) + '&input={encodedQuery}'),
185 - itemTemplate: [
186 - '<li data-id="{id}" class="ckeditor-autocomplete-item">',
187 - '<div>',
188 - '<span class="ckeditor-autocomplete-item-icon-wrapper">',
189 - // We have to output both icon types but normally only one is defined and the other is hidden.
190 - '<img src="{iconURL}"/>',
191 - '<span class="{iconClass}"></span>',
192 - '</span>',
193 - '<span class="ckeditor-autocomplete-item-label">{label}</span>',
194 - '</div>',
195 - '<div class="ckeditor-autocomplete-item-hint">{hint}</div>',
196 - '</li>'].join(''),
197 - outputTemplate: '<a href="{url}" data-reference="{typed}|-|{type}|-|{reference}">{label}</a>',
198 - marker: '[',
199 - minChars: 0,
200 - itemsLimit: 6
201 - }
202 - ]
75 + }
203 203   };
204 - if ($(element).attr('data-officeImporterSupported') === 'true') {
205 - config['xwiki-office'] = {
206 - importer: sourceDocument.getURL('get', $.param({
207 - sheet: 'CKEditor.OfficeImporter',
208 - language: currentLocale
209 - }))
210 - };
211 - }
212 212   return config;
213 213   };
214 214  
... ... @@ -262,18 +262,49 @@
262 262   object[key] = newValue;
263 263   };
264 264  
265 - require([
266 - // We cannot add these modules to the list of dependencies because they need the tree module to be configured first.
267 - 'entityResourcePicker', 'entityResourceSuggester', 'entityResourceDisplayer',
268 - // Load the translations for our custom CKEditor plugins. We didn't add this as a dependency to the xwiki-ckeditor
269 - // module because some of our plugins load their dependencies with RequireJS and thus they are loaded with a small
270 - // delay. The plugin needs to be defined before calling CKEDITOR.plugins.setLang().
271 - new XWiki.Document('Translations', 'CKEditor').getURL('jsx', $.param({
272 - language: currentLocale
273 - }))
274 - ], function() {
275 - 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 + }
276 276   });
277 277  
278 - return deferred.promise();
174 + return $.Deferred().resolve(ckeditor).promise();
279 279  });
Parse content
... ... @@ -1,1 +1,1 @@
1 -Yes
1 +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,4 +1,11 @@
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 +
2 2   var createEditors = function(ckeditor, container) {
3 3   container.find('.ckeditor-textarea').each(function() {
4 4   // Wrap in try/catch so that a failure to load one editor doesn't affect the other editors.
... ... @@ -13,9 +13,9 @@
13 13   var createEditor = function(ckeditor, textArea, instanceConfig) {
14 14   var deferred = $.Deferred();
15 15   var editor = ckeditor.replace(textArea, instanceConfig);
16 - editor.once('instanceReady', $.proxy(deferred, 'resolve', editor));
23 + editor.once('instanceReady', deferred.resolve.bind(deferred, editor));
17 17   editor.once('reload', function(event) {
18 - event.data.promise = event.data.promise.then($.proxy(createEditor, null, ckeditor, textArea));
25 + event.data.promise = event.data.promise.then(createEditor.bind(null, ckeditor, textArea));
19 19   });
20 20   return deferred.promise();
21 21   };
Parse content
... ... @@ -1,1 +1,1 @@
1 -Yes
1 +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  
... ... @@ -80,7 +80,7 @@
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  
... ... @@ -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,43 +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: 3px 12px;
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 +}
312 312  /* The image still takes some space in IE11 even if there's no source specified. Let's make sure it's hidden.
313 313   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=""],
314 314  .ckeditor-autocomplete-item-icon-wrapper img[src=""] {
315 315   display: none;
316 316  }
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,
317 317  .ckeditor-autocomplete-item-hint {
318 - color: $theme.textSecondaryColor;
334 + color: @text-muted;
319 319   font-size: smaller;
320 320  }
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 +}
321 321  .ckeditor-autocomplete-item-hint:empty {
322 322   margin-top: 0;
323 323  }
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 -CSS
1 +LESS
Name
... ... @@ -1,1 +1,0 @@
1 -CKEditor Skin Fix
Parse content
... ... @@ -1,1 +1,1 @@
1 -Yes
1 +No
XWiki.StyleSheetExtension[1]
Caching policy
... ... @@ -1,1 +1,0 @@
1 -long
Code
... ... @@ -1,97 +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 - .form-control-focus();
22 -}
23 -
24 -.cke_contents.fake {
25 - /* We need this to have the box shadow visible when the source area is focused. */
26 - overflow: visible;
27 -}
28 -
29 -#xwikicontent + .cke_contents > textarea.cke_source.cke_editable_inline {
30 - /* Don't take the padding and the margin into account when computing the 100% width. */
31 - box-sizing: content-box;
32 - /* Make sure the Source area has the same width as the WYSIWYG area. */
33 - margin-left: -@grid-gutter-width / 2 - 1px;
34 - margin-right: -@grid-gutter-width / 2 - 1px;
35 -}
36 -
37 -/**
38 - * Full-screen styles for the in-line editor
39 - */
40 -body[data-maximized="true"] {
41 - overflow: hidden;
42 -
43 - .cke_maximize_backdrop,
44 - .cke_toolBar_active,
45 - .cke_editable_active,
46 - .cke_actionBar_active {
47 - position: fixed !important;
48 - right: 0 !important;
49 - left: 0 !important;
50 - }
51 -
52 - /*
53 - * The tool bar
54 - */
55 - .cke_toolBar_active {
56 - /* We have to use !important in order to overwrite the in-line styles. */
57 - display: block !important;
58 - top: 0 !important;
59 - }
60 -
61 - /*
62 - * The editing area
63 - */
64 - .cke_maximize_backdrop,
65 - .cke_editable_active {
66 - background-color: @xwiki-page-content-bg;
67 - }
68 - .cke_editable_active {
69 - box-sizing: border-box !important;
70 - margin: 0 !important;
71 - overflow-y: auto !important;
72 - z-index: 9995;
73 -
74 - &:focus {
75 - /* Remove the focus border. */
76 - border-color: transparent !important;
77 - box-shadow: none !important;
78 - }
79 - }
80 - .cke_maximize_backdrop {
81 - top: 0;
82 - bottom: 0;
83 - z-index: 99;
84 - }
85 -
86 - /*
87 - * The action buttons
88 - */
89 - .cke_actionBar_active {
90 - background-color: @xwiki-background-secondary-color;
91 - border: 1px solid @xwiki-border-color;
92 - bottom: 0;
93 - /* Reduce a bit the padding. */
94 - padding: .5em;
95 - z-index: 9995;
96 - }
97 -}
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.contrib:application-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}))
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