Modifications pour le document EditSheet

Modifié par Florent Charton le 2026/03/13 11:04

Depuis la version 5.1
modifié par Florent Charton
sur 2026/01/08 10:59
Commentaire de modification : Install extension [org.xwiki.platform:xwiki-platform-ckeditor-ui/17.4.8]
À la version 1.1
modifié par superadmin
sur 2022/06/20 08:49
Commentaire de modification : Install extension [org.xwiki.contrib:application-ckeditor-ui/1.63.1]

Résumé

Détails

Propriétés de la Page
Auteur du document
... ... @@ -1,1 +1,1 @@
1 -xwiki:XWiki.fcharton
1 +XWiki.superadmin
Contenu
... ... @@ -1,0 +1,38 @@
1 +{{include reference="CKEditor.VelocityMacros"/}}
2 +
3 +{{velocity}}
4 +#if ($doc.fullName == 'CKEditor.EditSheet')
5 + This is a sheet for editing the document content using [[CKEditor>>http://ckeditor.com/]].
6 +#else
7 + {{html clean="false"}}
8 + ## Include the auto-save styles.
9 + #set ($discard = $xwiki.ssfx.use('js/xwiki/editors/autosave.css', true))
10 + #if ("$!request.section" != '')
11 + <div class="hidden">
12 + <input type="hidden" name="section" value="$!escapetool.xml($request.section)"/>
13 + </div>
14 + #end
15 + <div class="row">
16 + <div class="cke-editMeta col-xs-12 col-md-7">
17 + ## Add support for editing the page title (which is not available by default in Inline Form edit mode).
18 + #set ($editor = 'wiki')
19 + #template('editmeta.vm')
20 + #set ($editor = 'inline')
21 + </div>
22 + </div>
23 + ## The xwikieditcontent id is needed for the auto-save feature.
24 + <div id="xwikieditcontent" data-autosave="true">
25 + #set ($parameters = {
26 + 'content': $tdoc.content,
27 + 'attributes': {
28 + 'id': 'content',
29 + 'name': 'content',
30 + 'rows': 25,
31 + 'cols': 80
32 + }
33 + })
34 + #ckeditor($parameters)
35 + </div>
36 + {{/html}}
37 +#end
38 +{{/velocity}}
XWiki.JavaScriptExtension[0]
Code
... ... @@ -1,6 +1,37 @@
1 -XWiki.locale = document.documentElement.getAttribute('lang') || '';
2 -
1 +/*
2 +#set ($ckeditorPath = $services.webjars.url('org.xwiki.contrib:application-ckeditor-webjar', 'ckeditor'))
3 +#set ($ckeditorBasePath = $stringtool.removeEnd($stringtool.removeEnd($ckeditorPath, '.js'), 'ckeditor'))
4 +#set ($resourcePickerBundlePath = "${ckeditorBasePath}plugins/xwiki-resource/resourcePicker.bundle.min")
5 +#set ($macroWizardBundlePath = "${ckeditorBasePath}plugins/xwiki-macro/macroWizard.bundle.min")
6 +#set ($imageWizardBundlePath = "${ckeditorBasePath}plugins/xwiki-image/imageWizard.bundle.min")
7 +#set ($modalPath = "${ckeditorBasePath}plugins/xwiki-dialog/modal.min")
8 +#set ($l10nPath = "${ckeditorBasePath}plugins/xwiki-localization/l10n.min")
9 +*/
3 3  require.config({
11 + paths: {
12 + ckeditor: '$!ckeditorPath',
13 + resourcePickerBundle: '$!resourcePickerBundlePath',
14 + modal: '$!modalPath',
15 + l10n: '$!l10nPath',
16 + macroWizard: '$!macroWizardBundlePath',
17 + imageWizard: '$!imageWizardBundlePath',
18 + // This is used by the resource suggest picker on the link modal.
19 + 'bootstrap3-typeahead': $jsontool.serialize($services.webjars.url('org.webjars.npm:bootstrap-3-typeahead',
20 + 'bootstrap3-typeahead.min')),
21 + // This is used to preserve the selection when switching between WYSIWYG and Source modes.
22 + 'fast-diff': $jsontool.serialize($services.webjars.url('org.webjars.npm:fast-diff', 'diff'))
23 + },
24 + bundles: {
25 + 'resourcePickerBundle': ['resource', 'resourcePicker', 'entityResourcePicker', 'entityResourceSuggester',
26 + 'entityResourceDisplayer']
27 + },
28 + shim: {
29 + ckeditor: {
30 + exports: 'CKEDITOR',
31 + // This includes dependencies of the plugins bundled with the CKEditor code.
32 + deps: ['jquery', 'resource', 'resourcePicker', 'macroWizard', 'imageWizard']
33 + }
34 + },
4 4   config: {
5 5   l10n: {
6 6   // We need to specify the language because this URL can be used after the page is loaded and thus after the
... ... @@ -8,24 +8,27 @@
8 8   // a different language specified). We take the current language from the page HTML, rather than using Velocity,
9 9   // in order to avoid having the current language cached.
10 10   url: new XWiki.Document('Translator', 'CKEditor').getURL('get', 'outputSyntax=plain&language=' +
11 - encodeURIComponent(XWiki.locale))
42 + encodeURIComponent(document.documentElement.getAttribute('lang') || ''))
12 12   }
13 13   }
14 14  });
15 15  
47 +window.CKEDITOR_BASEPATH = "$!ckeditorBasePath";
48 +
16 16  define('xwiki-ckeditor', [
17 17   'jquery',
18 - // The CKEditor standard API.
19 19   'ckeditor',
20 20   // Used to access the form token required by the upload URL.
21 21   'xwiki-meta',
22 - // CKEditor plugins specific to XWiki.
23 - 'xwiki-ckeditor-plugins',
24 24   // Used to catch form action events fired from Prototype.js code (actionButtons.js).
25 25   'xwiki-events-bridge',
26 - // Load the translations for our custom CKEditor plugins.
27 - new XWiki.Document('Translations', 'CKEditor').getURL('jsx', 'language=' + encodeURIComponent(XWiki.locale))
56 + // Configures the path to the tree widget module and its dependencies which are used by the page and attachment
57 + // pickers on the link, image and macro dialogs to select pages and attachments.
58 + "$!services.webjars.url('org.xwiki.platform:xwiki-platform-tree-webjar', 'require-config.min.js', {'evaluate': true})"
28 28  ], function($, ckeditor, xwikiMeta) {
60 + var deferred = $.Deferred();
61 + var currentLocale = $('html').attr('lang') || '';
62 +
29 29   // We have to pass the plugin that makes the request (the initiator) because the expected response can be different
30 30   // (e.g. between the filebrowser and filetools plugins).
31 31   var getUploadURL = function(document, initiator) {
... ... @@ -34,7 +34,7 @@
34 34   outputSyntax: 'plain',
35 35   // The syntax and language are important especially when the upload request creates a new document.
36 36   syntax: document.syntax,
37 - language: XWiki.locale,
71 + language: currentLocale,
38 38   form_token: xwikiMeta.form_token,
39 39   initiator: initiator
40 40   }));
... ... @@ -42,30 +42,47 @@
42 42  
43 43   // Extend the default CKEditor configuration with settings that depend on the source document.
44 44   var getConfig = function(element) {
45 - var sourceSyntax = $(element).attr('data-syntax');
46 46   var sourceDocument = XWiki.currentDocument;
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;
80 + var sourceDocumentReference = $(element).attr('data-sourceDocumentReference');
81 + if (sourceDocumentReference) {
82 + sourceDocument = new XWiki.Document(XWiki.Model.resolve(sourceDocumentReference, XWiki.EntityType.DOCUMENT));
54 54   }
84 + sourceDocument.syntax = $(element).attr('data-sourceDocumentSyntax');
55 55  
56 - var uploadDisabled = element.hasAttribute('data-upload-disabled');
57 - var startupFocus = element.hasAttribute('data-startup-focus');
58 -
59 59   var config = {
60 - filebrowserUploadUrl: uploadDisabled ? '' : getUploadURL(sourceDocument, 'filebrowser'),
61 - startupFocus,
87 + filebrowserUploadUrl: getUploadURL(sourceDocument, 'filebrowser'),
62 62   height: $(element).height(),
63 - // Used to resolve and serialize relative references. Also used to make HTTP requests with the right context.
89 + mentions: [
90 + {
91 + // We use the source document to compute the feed URL because we want the suggested link references to be
92 + // relative to the edited document (we want the editor to output relative references as much as possible).
93 + feed: sourceDocument.getURL('get', $.param({
94 + sheet: 'CKEditor.LinkSuggestions',
95 + outputSyntax: 'plain',
96 + language: currentLocale
97 + // Prevent the curly brackets from being URL encoded because they mark a placeholder that will be replaced
98 + // with the text typed by the user (and CKEditor takes care of URL encoding it).
99 + }) + '&input={encodedQuery}'),
100 + itemTemplate: [
101 + '<li data-id="{id}" class="ckeditor-autocomplete-item">',
102 + '<div>',
103 + '<span class="ckeditor-autocomplete-item-icon-wrapper">',
104 + // We have to output both icon types but normally only one is defined and the other is hidden.
105 + '<img src="{iconURL}"/>',
106 + '<span class="{iconClass}"></span>',
107 + '</span>',
108 + '<span class="ckeditor-autocomplete-item-label">{label}</span>',
109 + '</div>',
110 + '<div class="ckeditor-autocomplete-item-hint">{hint}</div>',
111 + '</li>'].join(''),
112 + outputTemplate: '<a href="{url}" data-reference="{typed}|-|{type}|-|{reference}">{label}</a><span>&nbsp;</span>',
113 + marker: '[',
114 + minChars: 0,
115 + itemsLimit: 6
116 + }
117 + ],
64 64   sourceDocument: sourceDocument,
65 - // The syntax of the edited content is not always the same as the syntax of the source document (which applies to
66 - // the source document content, but we might be editing something else, like an object property).
67 - sourceSyntax: sourceSyntax,
68 - uploadUrl: uploadDisabled ? '' : getUploadURL(sourceDocument, 'filetools'),
119 + uploadUrl: getUploadURL(sourceDocument, 'filetools'),
69 69   'xwiki-link': {
70 70   // We use the source document to compute the link label generator URL because we want the link references to be
71 71   // resolved relative to the edited document (as they were inserted).
... ... @@ -72,7 +72,7 @@
72 72   labelGenerator: sourceDocument.getURL('get', $.param({
73 73   sheet: 'CKEditor.LinkLabelGenerator',
74 74   outputSyntax: 'plain',
75 - language: XWiki.locale
126 + language: currentLocale
76 76   }))
77 77   }
78 78   };
... ... @@ -129,49 +129,18 @@
129 129   object[key] = newValue;
130 130   };
131 131  
132 - // See XWIKI-21351: Macros using RequireJS are not properly displayed by the standalone WYSIWYG editor even when
133 - // JavaScript is enabled.
134 - //
135 - // For each CKEditor instance that uses a separate DOM document for the edited content (i.e. classical iframe-based
136 - // editor) we overwrite the appendChild and insertBefore functions of the initial HEAD element in order to make sure
137 - // that RequireJS appends the script tags to the current HEAD element (because the HEAD element is overwritten each
138 - // time the edited content is reloaded, like when inserting a macro or switching between Source and WYSIWYG modes).
139 - //
140 - // We have to overwrite both appendChild and insertBefore because depending on the presence of the BASE element
141 - // RequireJS uses one or the other.
142 - ckeditor.on('instanceReady', ({editor}) => {
143 - if (editor.document.$ !== document) {
144 - // This editor instance is using a separate DOM document for editing which means it's a standalone editor.
145 - const initialHead = editor.document.$.head;
146 - const originalAppendChild = initialHead.appendChild;
147 - initialHead.appendChild = function() {
148 - const currentHead = editor.document.$.head;
149 - if (currentHead !== initialHead) {
150 - // The edited content has been reloaded. Append to the current HEAD.
151 - return currentHead.appendChild.apply(currentHead, arguments);
152 - } else {
153 - // Still using the initial HEAD so preserve the default behavior.
154 - originalAppendChild.apply(initialHead, arguments);
155 - }
156 - };
157 - const originalInsertBefore = initialHead.insertBefore;
158 - initialHead.insertBefore = function(newChild, existingChild) {
159 - const currentHead = editor.document.$.head;
160 - if (currentHead !== initialHead) {
161 - // The edited content has been reloaded. Normally the given existingChild should be a child of the initial
162 - // HEAD element (not the current one), but better check to be sure.
163 - if (existingChild.parentNode === currentHead) {
164 - return currentHead.insertBefore(newChild, existingChild);
165 - } else {
166 - return currentHead.appendChild.apply(newChild);
167 - }
168 - } else {
169 - // Still using the initial HEAD so preserve the default behavior.
170 - return originalInsertBefore.apply(initialHead, arguments);
171 - }
172 - };
173 - }
183 + require([
184 + // We cannot add these modules to the list of dependencies because they need the tree module to be configured first.
185 + 'entityResourcePicker', 'entityResourceSuggester', 'entityResourceDisplayer',
186 + // Load the translations for our custom CKEditor plugins. We didn't add this as a dependency to the xwiki-ckeditor
187 + // module because some of our plugins load their dependencies with RequireJS and thus they are loaded with a small
188 + // delay. The plugin needs to be defined before calling CKEDITOR.plugins.setLang().
189 + new XWiki.Document('Translations', 'CKEditor').getURL('jsx', $.param({
190 + language: currentLocale
191 + }))
192 + ], function() {
193 + deferred.resolve(ckeditor);
174 174   });
175 175  
176 - return $.Deferred().resolve(ckeditor).promise();
196 + return deferred.promise();
177 177  });
Parser le contenu
... ... @@ -1,1 +1,1 @@
1 -Non
1 +Oui
XWiki.JavaScriptExtension[2]
Code
... ... @@ -10,9 +10,7 @@
10 10   container.find('.ckeditor-textarea').each(function() {
11 11   // Wrap in try/catch so that a failure to load one editor doesn't affect the other editors.
12 12   try {
13 - createEditor(ckeditor, this).then(() => {
14 - this.classList.remove('loading');
15 - });
13 + createEditor(ckeditor, this);
16 16   } catch(e) {
17 17   console.log(e);
18 18   }
Parser le contenu
... ... @@ -1,1 +1,1 @@
1 -Non
1 +Oui
XWiki.StyleSheetExtension[0]
Code
... ... @@ -1,5 +1,50 @@
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 +
1 1  a.cke_button_disabled > span.cke_button_icon.loading {
2 - background-image: url(@xwiki-icon-spinner) !important;
47 + background-image: url("$xwiki.getSkinFile('icons/xwiki/spinner.gif')") !important;
3 3   background-position: 0 0 !important;
4 4  }
5 5  
... ... @@ -12,13 +12,6 @@
12 12   resize: none;
13 13  }
14 14  
15 -/* Hide the form action bar while the editor is loading in order to avoid UI flickering (because the editor may enhance
16 - or replace the form action bar). */
17 -main > div:has(.ckeditor-textarea.loading) ~ .bottom-editor,
18 -#xwikicontent.loading ~ form#inplace-editing {
19 - visibility: hidden;
20 -}
21 -
22 22  /* Show the modal above the CKEditor dialogs */
23 23  body > .modal-backdrop {
24 24   z-index: 10040;
... ... @@ -42,7 +42,7 @@
42 42  }
43 43  
44 44  .cke_maximized .buttons {
45 - background-color: @well-bg;
83 + background-color: $theme.backgroundSecondaryColor;
46 46   padding: .5em;
47 47  }
48 48  
... ... @@ -150,7 +150,7 @@
150 150   box-sizing: border-box;
151 151  }
152 152  .resourcePicker .resourceDisplay.loading {
153 - background-image: url(@xwiki-icon-spinner);
191 + background-image: url("$xwiki.getSkinFile('icons/xwiki/spinner.gif')");
154 154   background-repeat: no-repeat;
155 155  }
156 156  
... ... @@ -174,7 +174,7 @@
174 174   * tree finder = 48px
175 175   * footer = 69px
176 176   */
177 - max-height: calc(~"100vh - 268px");
215 + max-height: calc(100vh - 268px);
178 178   overflow-y: auto;
179 179  }
180 180  
... ... @@ -211,6 +211,8 @@
211 211  a.cke_button.cke_button__xwiki-macro-edit > span.cke_button_icon.cke_button__xwiki-macro-edit_icon,
212 212  a.cke_button.cke_button__xwiki-link-open > span.cke_button_icon.cke_button__xwiki-link-open_icon,
213 213  a.cke_button.cke_button__insert > span.cke_button_icon.cke_button__insert_icon {
252 + /* This is needed for XWiki versions older than 7.1M1 where we overwrite the icons path (see above). */
253 + background-image: none !important;
214 214   font-family: 'Glyphicons Halflings';
215 215   position: relative;
216 216   top: 1px;
... ... @@ -241,303 +241,43 @@
241 241   */
242 242  ul.cke_autocomplete_panel {
243 243   border: 1px solid rgba(0, 0, 0, 0.15);
244 - border-radius: @border-radius-base;
284 + border-radius: 4px;
245 245   box-shadow: 0 6px 12px rgba(0, 0, 0, 0.175);
246 246   font: inherit;
247 247   padding: 5px 0;
248 248   width: auto;
249 - max-width: 324px;
289 + max-width: 100%;
250 250   min-width: 200px;
251 251  }
252 -.cke_autocomplete_panel > li.ckeditor-autocomplete-group,
253 253  .cke_autocomplete_panel > li.ckeditor-autocomplete-item {
254 - padding: 5px 20px;
293 + padding: 3px 12px;
255 255  }
256 -.cke_autocomplete_panel > li.ckeditor-autocomplete-group {
257 - border-top: 1px solid @xwiki-border-color;
258 - color: @text-muted;
259 - font-size: smaller;
260 - margin-top: 9px;
261 - padding-top: 14px;
262 -}
263 -.cke_autocomplete_panel > li.ckeditor-autocomplete-group h6 {
264 - font-size: inherit;
265 - margin: 0;
266 -}
267 -.cke_autocomplete_panel > li.ckeditor-autocomplete-group:first-child {
268 - border-top: 0 none;
269 - margin-top: 0;
270 - padding-top: 5px;
271 -}
272 -.cke_autocomplete_panel > li.ckeditor-autocomplete-group:hover {
273 - background-color: transparent;
274 - cursor: inherit;
275 -}
276 -.ckeditor-autocomplete-group h6,
277 -.ckeditor-autocomplete-item-label,
278 -.ckeditor-autocomplete-item-shortcut {
279 - overflow: hidden;
280 - text-overflow: ellipsis;
295 +.cke_autocomplete_panel > li.ckeditor-autocomplete-item > div {
281 281   white-space: nowrap;
282 282  }
283 -.ckeditor-autocomplete-item-head {
284 - display: flex;
285 - align-items: center;
286 -}
287 287  .ckeditor-autocomplete-item-icon-wrapper {
288 288   display: inline-block;
289 289   height: 14px;
290 290   line-height: 14px;
291 - margin-right: .5em;
302 + margin-right: .3em;
292 292   text-align: center;
293 293   width: 14px;
294 294  }
295 295  .ckeditor-autocomplete-item-icon-wrapper img {
296 - border-radius: @border-radius-small;
307 + border-radius: 3px;
297 297   max-height: 14px;
298 298   max-width: 14px;
299 299   vertical-align: text-top;
300 300  }
301 -.ckeditor-autocomplete-item-preview-wrapper {
302 - display: flex;
303 - align-items: center;
304 - justify-content: space-around;
305 - height: 64px;
306 - margin-right: .5em;
307 - text-align: center;
308 - vertical-align: middle;
309 - width: 64px;
310 -}
311 -.ckeditor-autocomplete-centered {
312 - justify-content: center;
313 -}
314 -.ckeditor-autocomplete-item-preview-wrapper img {
315 - border-radius: @border-radius-small;
316 - max-height: 64px;
317 - max-width: 64px;
318 - vertical-align: text-top;
319 -}
320 -/* The image still takes some space in all browsers even if there's no source specified. Let's make sure it's hidden.
312 +/* The image still takes some space in IE11 even if there's no source specified. Let's make sure it's hidden.
321 321   See CKEDITOR-389: Missing space in the suggestions that appear while using the autocomplete function on IE 11 */
322 -.ckeditor-autocomplete-item-preview-wrapper img[src=""],
323 323  .ckeditor-autocomplete-item-icon-wrapper img[src=""] {
324 324   display: none;
325 325  }
326 -.ckeditor-autocomplete-item-label {
327 - /* Push the shortcut to the right edge of the item. */
328 - flex-grow: 1;
329 -}
330 -.ckeditor-autocomplete-item-shortcut:not(:empty) {
331 - background-color: @xwiki-border-color;
332 - border-radius: @border-radius-base;
333 - padding: 2px 5px;
334 - margin-left: .5em;
335 -}
336 -.ckeditor-autocomplete-item-shortcut,
337 -.ckeditor-autocomplete-item-badge,
338 338  .ckeditor-autocomplete-item-hint {
339 - color: @text-muted;
318 + color: $theme.textSecondaryColor;
340 340   font-size: smaller;
341 341  }
342 -.ckeditor-autocomplete-item-badge {
343 - background-color: @xwiki-border-color;
344 - font-weight: normal;
345 -}
346 -.ckeditor-autocomplete-item-hint {
347 - /* Limit to 3 lines of text (based on line height). */
348 - max-height: calc(3 * 20em / 14);
349 - overflow: hidden;
350 - /* Put the ellipsis at the end of the last line when the text is cut. */
351 - display: -webkit-box;
352 - -webkit-box-orient: vertical;
353 - -webkit-line-clamp: 3;
354 -}
355 355  .ckeditor-autocomplete-item-hint:empty {
356 356   margin-top: 0;
357 357  }
358 -
359 -/**
360 - * Source mode
361 - */
362 -
363 -.cke_contents > textarea.cke_source {
364 - box-sizing: border-box;
365 - color: @text-color;
366 - font-family: @font-family-monospace;
367 - font-size: inherit;
368 - /* Same padding as on the page content. */
369 - padding: @grid-gutter-width / 2;
370 -}
371 -
372 -.cke_contents > textarea.cke_source.cke_editable_inline {
373 - box-shadow: none;
374 -}
375 -
376 -#xwikicontent + .cke_contents > textarea.cke_source.cke_editable_inline {
377 - /* Don't take the padding and the margin into account when computing the 100% width. */
378 - box-sizing: content-box;
379 - /* Make sure the Source area has the same width as the WYSIWYG area. */
380 - margin-left: -@grid-gutter-width / 2;
381 - margin-right: -@grid-gutter-width / 2;
382 -}
383 -
384 -/**
385 - * Custom styles to match XWiki's Look & Feel
386 - */
387 -.cke_chrome,
388 -.cke_chrome > .cke_inner {
389 - border-radius: @border-radius-base;
390 -}
391 -
392 -.cke_chrome > .cke_inner > .cke_top {
393 - border-top-right-radius: @border-radius-base;
394 - border-top-left-radius: @border-radius-base;
395 -}
396 -
397 -.cke_chrome > .cke_inner > .cke_bottom {
398 - border-bottom-right-radius: @border-radius-base;
399 - border-bottom-left-radius: @border-radius-base;
400 -}
401 -
402 -/* The standalone WYSIWYG edit mode shows the form action toolbar right below the CKEditor instance used to edit the
403 - document content. We make the bottom border rounded on the form action toolbar instead. */
404 -#xwikieditcontent > .cke_chrome,
405 -#xwikieditcontent > .cke_chrome > .cke_inner,
406 -#xwikieditcontent > .cke_chrome > .cke_inner > .cke_bottom {
407 - border-bottom-right-radius: 0;
408 - border-bottom-left-radius: 0;
409 -}
410 -
411 -a.cke_button,
412 -a.cke_combo_button {
413 - border-radius: @border-radius-small;
414 -}
415 -
416 -.cke_panel,
417 -.cke_dialog_body,
418 -.cke_dialog a.cke_dialog_ui_button,
419 -.cke_dialog input.cke_dialog_ui_input_text,
420 -.cke_dialog select.cke_dialog_ui_input_select,
421 -.cke_dialog fieldset.cke_dialog_ui_fieldset,
422 -.cke_notification {
423 - border-radius: @border-radius-base;
424 -}
425 -
426 -.cke_panel.cke_menu_panel,
427 -.cke_panel.cke_combopanel {
428 - margin: 2px 0;
429 -}
430 -
431 -.cke_dialog_title,
432 -.cke_dialog a.cke_dialog_tab {
433 - border-top-right-radius: @border-radius-base;
434 - border-top-left-radius: @border-radius-base;
435 -}
436 -
437 -.cke_dialog_contents,
438 -.cke_dialog_footer {
439 - border-bottom-right-radius: @border-radius-base;
440 - border-bottom-left-radius: @border-radius-base;
441 -}
442 -
443 -/**
444 - * Custom styles for the in-line editor
445 - */
446 -.viewbody > .cke_float {
447 - /* Shift the floating toolbar in order to match the content padding. */
448 - margin-right: floor((@grid-gutter-width / 2));
449 - margin-left: ceil((@grid-gutter-width / 2));
450 -}
451 -.cke_float .cke_top {
452 - border-radius: @border-radius-base;
453 -}
454 -
455 -/**
456 - * Full-screen styles for the in-line editor
457 - */
458 -body[data-maximized="true"] {
459 - overflow: hidden;
460 -
461 - .cke_maximize_backdrop,
462 - .cke_toolBar_active,
463 - .cke_editable_active,
464 - .cke_actionBar_active {
465 - position: fixed !important;
466 - right: 0 !important;
467 - left: 0 !important;
468 - }
469 -
470 - /*
471 - * The tool bar
472 - */
473 - .cke_toolBar_active {
474 - /* We have to use !important in order to overwrite the in-line styles. */
475 - display: block !important;
476 - top: 0 !important;
477 - }
478 -
479 - /*
480 - * The editing area
481 - */
482 - .cke_maximize_backdrop,
483 - .cke_editable_active {
484 - background-color: @xwiki-page-content-bg;
485 - }
486 - .cke_editable_active {
487 - box-sizing: border-box !important;
488 - margin: 0 !important;
489 - overflow-y: auto !important;
490 - z-index: 9995;
491 - }
492 - .cke_maximize_backdrop {
493 - top: 0;
494 - bottom: 0;
495 - z-index: 99;
496 - }
497 -
498 - /*
499 - * The action buttons
500 - */
501 - .cke_actionBar_active {
502 - background-color: @xwiki-background-secondary-color;
503 - border: 1px solid @xwiki-border-color;
504 - bottom: 0;
505 - /* Reduce a bit the padding. */
506 - padding: .5em;
507 - z-index: 9995;
508 - }
509 -}
510 -
511 -/*
512 - * Override the CKEditor reset for the table border color.
513 - * The default border color from CKEditor is quite lacking on contrast.
514 - */
515 -.cke_editable.cke_show_borders table.cke_show_border,
516 -.cke_editable.cke_show_borders table.cke_show_border > tr > th,
517 -.cke_editable.cke_show_borders table.cke_show_border > tr > td,
518 -.cke_editable.cke_show_borders table.cke_show_border > thead > tr > th,
519 -.cke_editable.cke_show_borders table.cke_show_border > thead > tr > td,
520 -.cke_editable.cke_show_borders table.cke_show_border > tbody > tr > th,
521 -.cke_editable.cke_show_borders table.cke_show_border > tbody > tr > td,
522 -.cke_editable.cke_show_borders table.cke_show_border > tfoot > tr > th,
523 -.cke_editable.cke_show_borders table.cke_show_border > tfoot > tr > td {
524 - border-color: @table-border-color;
525 - border-style: solid;
526 -}
527 -
528 -/* CKEditor contains a CSS reset. It works with its own style sheets and does not use the ones in XWiki.
529 -However, we want `.sr-only` from XWiki to still be usable in our CKEditor environment.
530 -We need to redefine the XWiki styles of this class to have better priority than the CKEditor CSS reset.
531 -Without this, the elements with this class are still shown which would be different from the behaviour
532 -of `.sr-only` anywhere else in XWiki (as described in our doc).
533 -This redefinition allows for a more consistent behaviour of the `.sr-only` class. */
534 -.cke_reset_all .sr-only {
535 - position: absolute;
536 - width: 1px;
537 - height: 1px;
538 - padding: 0;
539 - margin: -1px;
540 - overflow: hidden;
541 - clip: rect(0, 0, 0, 0);
542 - border: 0;
543 -}
Content Type
... ... @@ -1,1 +1,1 @@
1 -LESS
1 +CSS
Nom
... ... @@ -1,0 +1,1 @@
1 +CKEditor Skin Fix
Parser le contenu
... ... @@ -1,1 +1,1 @@
1 -Non
1 +Oui
XWiki.UIExtensionClass[0]
Extension ID
... ... @@ -1,1 +1,1 @@
1 -org.xwiki.platform.requirejs.module.xwiki-ckeditor
1 +org.xwiki.platform.requirejs.module.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.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}))
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}))
XWiki.UIExtensionClass[1]
Cached
... ... @@ -1,1 +1,0 @@
1 -Non
Asynchronous rendering
... ... @@ -1,1 +1,0 @@
1 -Non
Extension Point ID
... ... @@ -1,1 +1,0 @@
1 -org.xwiki.platform.requirejs.module
Extension ID
... ... @@ -1,1 +1,0 @@
1 -org.xwiki.platform.requirejs.module.fusejs
Extension Parameters
... ... @@ -1,2 +1,0 @@
1 -id=fuse
2 -path=$services.webjars.url('org.webjars.npm:fuse.js', 'dist/fuse.basic.min.js')
Extension Scope
... ... @@ -1,1 +1,0 @@
1 -wiki
XWiki.UIExtensionClass[2]
Cached
... ... @@ -1,1 +1,0 @@
1 -Non
Asynchronous rendering
... ... @@ -1,1 +1,0 @@
1 -Non
Extension Point ID
... ... @@ -1,1 +1,0 @@
1 -org.xwiki.platform.requirejs.module
Extension ID
... ... @@ -1,1 +1,0 @@
1 -org.xwiki.platform.requirejs.module.bootstrap3-typeahead
Extension Parameters
... ... @@ -1,2 +1,0 @@
1 -id=bootstrap3-typeahead
2 -path=$services.webjars.url('org.webjars.npm:bootstrap-3-typeahead', 'bootstrap3-typeahead.min')
Extension Scope
... ... @@ -1,1 +1,0 @@
1 -wiki
XWiki.UIExtensionClass[3]
Cached
... ... @@ -1,1 +1,0 @@
1 -Non
Asynchronous rendering
... ... @@ -1,1 +1,0 @@
1 -Non
Extension Point ID
... ... @@ -1,1 +1,0 @@
1 -org.xwiki.platform.requirejs.module
Extension ID
... ... @@ -1,1 +1,0 @@
1 -org.xwiki.platform.requirejs.module.fast-diff
Extension Parameters
... ... @@ -1,2 +1,0 @@
1 -id=fast-diff
2 -path=$services.webjars.url('org.webjars.npm:fast-diff', 'diff')
Extension Scope
... ... @@ -1,1 +1,0 @@
1 -wiki
XWiki.UIExtensionClass[4]
Cached
... ... @@ -1,1 +1,0 @@
1 -Non
Asynchronous rendering
... ... @@ -1,1 +1,0 @@
1 -Non
Extension Point ID
... ... @@ -1,1 +1,0 @@
1 -org.xwiki.platform.requirejs.module
Extension ID
... ... @@ -1,1 +1,0 @@
1 -org.xwiki.platform.requirejs.module.ckeditor
Extension Parameters
... ... @@ -1,3 +1,0 @@
1 -id=ckeditor
2 -path=$services.webjars.url('org.xwiki.platform:xwiki-platform-ckeditor-webjar', 'ckeditor')
3 -exports=CKEDITOR
Extension Scope
... ... @@ -1,1 +1,0 @@
1 -wiki
XWiki.UIExtensionClass[5]
Cached
... ... @@ -1,1 +1,0 @@
1 -Non
Asynchronous rendering
... ... @@ -1,1 +1,0 @@
1 -Non
Extension Point ID
... ... @@ -1,1 +1,0 @@
1 -org.xwiki.platform.requirejs.module
Extension ID
... ... @@ -1,1 +1,0 @@
1 -org.xwiki.platform.requirejs.module.xwiki-ckeditor-plugins
Extension Parameters
... ... @@ -1,4 +1,0 @@
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,1 +1,0 @@
1 -wiki
XWiki.JavaScriptExtension[1]
Mode de mise en cache
... ... @@ -1,0 +1,1 @@
1 +long
Code
... ... @@ -1,0 +1,165 @@
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 +});
Nom
... ... @@ -1,0 +1,1 @@
1 +Various fixes and polyfills
Parser le contenu
... ... @@ -1,0 +1,1 @@
1 +Oui
Utiliser cette extension
... ... @@ -1,0 +1,1 @@
1 +onDemand
XWiki.StyleSheetExtension[1]
Mode de mise en cache
... ... @@ -1,0 +1,1 @@
1 +long
Code
... ... @@ -1,0 +1,97 @@
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,0 +1,1 @@
1 +LESS
Nom
... ... @@ -1,0 +1,1 @@
1 +LESS
Parser le contenu
... ... @@ -1,0 +1,1 @@
1 +Non
Utiliser cette extension
... ... @@ -1,0 +1,1 @@
1 +onDemand