Changes for page Attachments
Last modified by teamwire005 on 2025/05/06 07:37
From version 3.1
edited by teamwire004
on 2024/01/16 09:32
on 2024/01/16 09:32
Change comment:
Install extension [org.xwiki.platform:xwiki-platform-attachment-ui/14.10.13]
To version 1.1
edited by teamwire-admin
on 2020/08/26 13:09
on 2020/08/26 13:09
Change comment:
Install extension [org.xwiki.platform:xwiki-platform-attachment-ui/11.10.8]
Summary
-
Page properties (2 modified, 0 added, 0 removed)
-
Objects (3 modified, 0 added, 0 removed)
Details
- Page properties
-
- Author
-
... ... @@ -1,1 +1,1 @@ 1 -XWiki.teamwire 0041 +XWiki.teamwire-admin - Content
-
... ... @@ -45,7 +45,9 @@ 45 45 #end 46 46 (% class="gallery" %)((( 47 47 ## Only display the upload form if they have edit permission on targetAttachDocument 48 - #attachmentPicker_displayUploadForm($targetDocument, $targetAttachDocument, $options) 48 + #if ($xwiki.hasAccessLevel('edit',$xcontext.user,${targetAttachDocument.fullName})) 49 + #attachmentPicker_displayUploadForm($targetDocument, $targetAttachDocument, $options) 50 + #end 49 49 #attachmentPicker_displayAttachmentGalleryEmptyValue($targetDocument, $targetAttachDocument, $options, $currentValue) 50 50 #set ($sortedAttachments = $sorttool.sort($targetAttachDocument.getAttachmentList(), "${options.sortAttachmentsBy}") ) 51 51 #foreach ($attachment in $sortedAttachments) ... ... @@ -67,46 +67,18 @@ 67 67 * @param $currentValue the currently selected file, used for determining if the box should be highlighted as the current value 68 68 *# 69 69 #macro (attachmentPicker_displayAttachmentBox $attachment $targetDocument $targetAttachDocument, $options $currentValue) 70 - #set ($hasTemporaryAttachment = "$!services.temporaryAttachments" != '') 71 - #set ($canEdit = $xwiki.hasAccessLevel('edit', $xcontext.user, ${targetAttachDocument.fullName})) 72 - #set ($isTemporaryAttachment = false) 73 - #if(!$hasTemporaryAttachment) 74 - #set ($canDeleteAttachment = $canEdit) 72 + #if ($options.displayImage && $attachment.isImage()) 73 + #set ($cssClass = 'gallery_image') 75 75 #else 76 - #set ($isTemporaryAttachment = $services.temporaryAttachments.temporaryAttachmentExists($attachment)) 77 - ## TODO: Update once it is made possible to delete temporary attachments (see XWIKI-20225). 78 - #set ($canDeleteAttachment = !$isTemporaryAttachment && $canEdit) 75 + #set ($cssClass = '') 79 79 #end 80 - #set ($cssClasses = []) 81 - #if ($options.displayImage && $attachment.isImage()) 82 - #set ($discard = $cssClasses.add('gallery_image')) 83 - #end 84 - #if ($isTemporaryAttachment) 85 - #set ($discard = $cssClasses.add('temporary_attachment')) 86 - #end 87 - #attachmentPicker_displayStartFrame({'value' : $attachment.filename, 'text' : $attachment.filename, 'cssClass' : "${stringtool.join($cssClasses, ' ')}"} $currentValue) 77 + #attachmentPicker_displayStartFrame({'value' : $attachment.filename, 'text' : $attachment.filename, 'cssClass' : "$!{cssClass}"} $currentValue) 88 88 #attachmentPicker_displayAttachmentDetails($attachment $options) 89 89 #set ($returnURL = $escapetool.url($doc.getURL('view', $request.queryString))) 90 90 #set ($deleteURL = $targetAttachDocument.getAttachmentURL($attachment.filename, 'delattachment', "xredirect=${returnURL}&form_token=$!{services.csrf.getToken()}") ) 91 91 #set ($viewURL = $targetAttachDocument.getAttachmentURL($attachment.filename) )##{'name' : 'download', 'url' : $viewURL, 'rel' : '__blank'} 92 - #set ($selectURL = $targetDocument.getURL(${options.get('docAction')}, $escapetool.url({ 93 - "${options.get('classname')}_${options.get('object')}_${options.get('property')}": ${attachment.filename}, 94 - 'form_token': $!{services.csrf.getToken()} 95 - }))) 96 - ## Delete action is only proposed for users with the edit right on the document. 97 - ## If the temporary attachment is available, the delete action is only allowed for non-temporary attachments. 98 - #set ($attachmentActions = [{'name' : 'select', 'url' : $selectURL}]) 99 - #if($canDeleteAttachment) 100 - #set ($discard = $attachmentActions.add({'name' : 'delete', 'url' : $deleteURL})) 101 - #end 102 - #define($additionalContent) 103 - #if ($isTemporaryAttachment) 104 - #set ($titleMessage = $services.localization.render('attachment.attachmentSelector.attachmentBox.temporaryAttachmentTitle')) 105 - #set ($titleMessage = $services.rendering.escape($titleMessage, 'xwiki/2.1')) 106 - (% title="$titleMessage" %)$services.icon.render('clock')(%%) 107 - #end 108 - #end 109 - #attachmentPicker_displayEndFrame ($attachmentActions $additionalContent) 82 + #set ($selectURL = $targetDocument.getURL(${options.get('docAction')}, "${options.get('classname')}_${options.get('object')}_${options.get('property')}=${attachment.filename}&form_token=$!{services.csrf.getToken()}")) 83 + #attachmentPicker_displayEndFrame ([{'name' : 'select', 'url' : $selectURL}, {'name' : 'delete', 'url' : $deleteURL}]) 110 110 #end 111 111 112 112 #** ... ... @@ -118,9 +118,7 @@ 118 118 *# 119 119 #macro (attachmentPicker_displayStartFrame $boxOptions $currentValue) 120 120 (% class="gallery_attachmentbox $!{boxOptions.cssClass} #if ("$!{boxOptions.value}" == $currentValue) current#{end}" %)((( 121 - (% class="gallery_attachmenttitle" title="$services.rendering.escape($!{boxOptions.value}, 'xwiki/2.1')" %)((( 122 - $services.rendering.escape($boxOptions.text, 'xwiki/2.1') 123 - ))) 95 + (% class="gallery_attachmenttitle" title="$!{boxOptions.value}" %)((($boxOptions.text))) 124 124 (% class="gallery_attachmentframe" %)((( 125 125 #end 126 126 ... ... @@ -136,13 +136,13 @@ 136 136 ## Compute the attachment reference because there's no getter. 137 137 #set ($attachmentReference = $services.model.createAttachmentReference($attachment.document.documentReference, 138 138 $attachment.filename)) 139 - #set ($attachmentStringReference = $services. rendering.escape($services.model.serialize($attachmentReference, 'default'), 'xwiki/2.1'))111 + #set ($attachmentStringReference = $services.model.serialize($attachmentReference, 'default')) 140 140 #if ($attachment.isImage() && $options.displayImage) 141 141 ## We add the version to the query string in order to invalidate the cache when an image attachment is replaced. 142 142 #set ($queryString = $escapetool.url({'version': $attachment.version})) 143 143 [[[[image:$attachmentStringReference||width=180 queryString="$queryString"]]>>attach:$attachmentStringReference]] 144 144 #else 145 - * (% class="mime" %){{html wiki=false clean=false}}#mimetypeimg($attachment.getMimeType().toLowerCase() $attachment.getFilename().toLowerCase()){{/html}}(%%) (% class="filename" %)$ services.rendering.escape($attachment.getFilename(), 'xwiki/2.1')(% %)117 + * (% class="mime" %){{html wiki=false clean=false}}#mimetypeimg($attachment.getMimeType().toLowerCase() $attachment.getFilename().toLowerCase()){{/html}}(%%) (% class="filename" %)$attachment.getFilename()(% %) 146 146 * v$attachment.getVersion() (#dynamicsize($attachment.longSize)) 147 147 * $services.localization.render('core.viewers.attachments.author', [$!{xwiki.getUserName($attachment.author, false)}]) $services.localization.render('core.viewers.attachments.date', [$!{xwiki.formatDate($attachment.date, 'dd/MM/yyyy hh:mm')}]) 148 148 * (% class="buttonwrapper" %)[[${services.localization.render("${translationPrefix}.actions.download")}>>attach:$attachmentStringReference||title="$services.localization.render("${translationPrefix}.actions.download")" rel="__blank" class="button"]](%%) ... ... @@ -162,9 +162,8 @@ 162 162 * <dt>rel</dt> 163 163 * <dd>an optional parameter to be used in the "rel" HTML attribute; for example "__blank" can be used to open the link in a new tab/window</dd> 164 164 * </dl> 165 - * @param $additionalContent optional additional content that does not follow the structure of the actions 166 166 *# 167 -#macro (attachmentPicker_displayEndFrame $actions $additionalContent)138 +#macro (attachmentPicker_displayEndFrame $actions) 168 168 )))## attachmentframe 169 169 (% class="gallery_actions" %)((( 170 170 #foreach ($action in $actions) ... ... @@ -171,7 +171,6 @@ 171 171 #set( $actionname = $services.localization.render("${translationPrefix}.actions.${action.name}") ) 172 172 [[${actionname}>>path:${action.url}||class="tool ${action.name}" title="${actionname}" #if($action.rel) rel="${action.rel}"#end]]## 173 173 #end 174 - $!additionalContent 175 175 )))## actions 176 176 )))## attachmentbox 177 177 #end ... ... @@ -328,8 +328,6 @@ 328 328 $!targetDocument.use($targetDocument.getObject($options.classname, $options.object))## 329 329 #attachmentPicker_displayAttachmentGallery($targetDocument, $targetAttachDocument, $options) 330 330 331 - #set ($cancelLinkName = $services.rendering.escape($services.rendering.escape($services.localization.render("${translationPrefix}.cancel"), 'xwiki/2.1'), 'xwiki/2.1')) 332 - #set ($cancelLinkTarget = $services.rendering.escape($services.model.serialize($targetDocument), 'xwiki/2.1')) 333 333 (% class="gallery_buttons buttons" %)((( 334 334 (% class="buttonwrapper secondary" %)[[$services.localization.render("${translationPrefix}.cancel")>>$targetDocument||class="button secondary" id="attachment-picker-close"]] 335 335 )))
- XWiki.JavaScriptExtension[0]
-
- Code
-
... ... @@ -1,66 +1,4 @@ 1 1 var XWiki = (function(XWiki) { 2 - function uploadTemporaryAttachment() { 3 - // Require jquery locally until we are able to fully migrate this code away from prototype. 4 - const form = this.property.up('form'); 5 - require(['jquery'], function ($) { 6 - const data = new FormData(); 7 - const uploadedFile = $('#attachfile')[0].files[0]; 8 - const filenameCheckbox = $("#uploadAttachment input[name='filename']"); 9 - 10 - // TODO: Fix replace currently selected checkbox (see XWIKI-20181). 11 - data.append('upload', uploadedFile); 12 - const notification = new XWiki.widgets.Notification( 13 - "$services.localization.render('xe.attachmentSelector.upload.inProgress')", 'inprogress'); 14 - const params = { 15 - 'form_token': $(form).find('[name="form_token"]').val(), 16 - 'sheet': 'CKEditor.FileUploader', 17 - 'outputSyntax': 'plain' 18 - }; 19 - 20 - // Update the name of the file with the name of the currently selected attachment if required. 21 - if (filenameCheckbox.prop('checked')) { 22 - params['filename'] = filenameCheckbox.val() 23 - } 24 - 25 - $.ajax({ 26 - 'url': XWiki.currentDocument.getURL('get', new URLSearchParams(params).toString()), 27 - method: 'POST', 28 - data: data, 29 - processData: false, 30 - contentType: false, // Sets the 'multipart/form-data' automatically 31 - headers: { 32 - 'X-XWiki-Temporary-Attachment-Support': true 33 - } 34 - }).done(function (response) { 35 - #set ($successMessage = $escapetool.javascript($services.localization.render('attachment.attachmentSelector.temporaryUpload.success'))) 36 - notification.replace(new XWiki.widgets.Notification("$successMessage", 'done')); 37 - // Add a field with the name of the uploaded file so that it is moved from the temporary 38 - // attachments to the persisded ones on save. 39 - $(form).append($('<input/>') 40 - .prop('type', 'hidden') 41 - .prop('name', 'uploadedFiles') 42 - .prop('value', response.fileName)) 43 - $(form).find('input[type="hidden"].property-reference').prop('value', response.fileName); 44 - this.updateAttachment(response.fileName, response.url); 45 - this.dialog.closeDialog(); 46 - }.bind(this)).fail(function () { 47 - #set ($errorMessage = $escapetool.javascript($services.localization.render('attachment.attachmentSelector.temporaryUpload.failure')))notification.replace(new XWiki.widgets.Notification("$errorMessage", 'error')); 48 - }); 49 - }.bind(this)); 50 - } 51 - 52 - function directUploadAttachment(uploadForm) { 53 - // FIXME This fails in HTML5, will deal with it later: 54 - // this.property.down('input').value = uploadForm.down('input[type="file"]').value; 55 - // uploadForm.xredirect.value = window.location.pathname; 56 - document.observe('xwiki:document:saved', function () { 57 - new XWiki.widgets.Notification("$services.localization.render('xe.attachmentSelector.upload.inProgress')", 58 - 'inprogress'); 59 - uploadForm.submit(); 60 - }) 61 - document.fire('xwiki:actions:save', {'continue': true, form: this.property.up('form')}); 62 - } 63 - 64 64 /** Handles the gallery buttons directly in the current page without reloading the window. */ 65 65 XWiki.AttachmentPicker = Class.create({ 66 66 /** ... ... @@ -122,23 +122,21 @@ 122 122 new XWiki.widgets.Notification("$services.localization.render('xe.attachmentSelector.upload.error.badExtension')", 'error'); 123 123 hasErrors = true; 124 124 } 125 - const beforeUploadEvent = Event.fire(document, 'xwiki:actions:beforeUpload', { 126 - file: fileInput.files[0] 127 - }); 128 - 129 - if (beforeUploadEvent.defaultPrevented) { 130 - hasErrors = true; 131 - } 132 132 }.bind(this)); 64 + // No form submission by AJAX right now, because file uploads can't be done this way without HTML5, this is future work 65 + // Save the document before submitting, since the current form data will be lost otherwise 133 133 if (!hasErrors) { 134 134 if (this.directSave) { 135 135 uploadForm.submit(); 136 136 } else { 137 - if ("$!services.temporaryAttachments" != '') { 138 - uploadTemporaryAttachment.call(this); 139 - } else { 140 - directUploadAttachment.call(this, uploadForm); 141 - } 70 + // FIXME This fails in HTML5, will deal with it later: 71 + // this.property.down('input').value = uploadForm.down('input[type="file"]').value; 72 + // uploadForm.xredirect.value = window.location.pathname; 73 + document.observe('xwiki:document:saved', function() { 74 + new XWiki.widgets.Notification("$services.localization.render('xe.attachmentSelector.upload.inProgress')", 'inprogress'); 75 + uploadForm.submit(); 76 + }) 77 + document.fire('xwiki:actions:save', {'continue': true, form: this.property.up('form')}); 142 142 } 143 143 } 144 144 }.bindAsEventListener(this)); ... ... @@ -237,7 +237,10 @@ 237 237 this.dialog.closeDialog(); 238 238 }.bindAsEventListener(this), 239 239 onFailure : function(response) { 240 - var failureReason = response.statusText || 'Server not responding'; 176 + var failureReason = response.statusText; 177 + if (response.statusText == '' /* No response */ || response.status == 12031 /* In IE */) { 178 + failureReason = 'Server not responding'; 179 + } 241 241 if (targetElement._x_notif) { 242 242 targetElement._x_notif.replace(new XWiki.widgets.Notification("$services.localization.render('core.widgets.confirmationBox.notification.failed')" + failureReason, "error")); 243 243 } else { ... ... @@ -244,6 +244,9 @@ 244 244 new XWiki.widgets.Notification(this.interactionParameters.failureMessageText + failureReason, "error"); 245 245 } 246 246 }, 186 + on1223 : function(response) { 187 + response.request.options.onSuccess(response); 188 + }, 247 247 on0 : function(response) { 248 248 response.request.options.onFailure(response); 249 249 },
- XWiki.StyleSheetExtension[0]
-
- Code
-
... ... @@ -140,6 +140,9 @@ 140 140 ## Make this box twice as large as the others 141 141 width: ${uploadBoxSize}px; 142 142 } 143 +* html .gallery_upload { 144 + width: ${mathtool.add($uploadBoxSize, 2)}px; 145 +} 143 143 .gallery_upload, .gallery_upload:hover { 144 144 background-color: $theme.backgroundSecondaryColor; 145 145 }
- XWiki.WikiMacroClass[0]
-
- Macro code
-
... ... @@ -34,7 +34,7 @@ 34 34 #set ($property = "$!{xcontext.macro.params.property}") 35 35 #set ($object = $mathtool.toInteger("$!{xcontext.macro.params.object}")) 36 36 #if ("$!{object}" != $!{xcontext.macro.params.object}) 37 - #set ($object = ${ targetdoc.getObject($classname).number})37 + #set ($object = ${doc.getObject($classname).number}) 38 38 #if ("$!{object}" == '') 39 39 #set ($object = 0) 40 40 #end ... ... @@ -46,18 +46,9 @@ 46 46 #set ($displayImage = false) 47 47 #end 48 48 #if ($displayImage) 49 - #set ($alt = '') 50 - #set ($width = '') 51 - #set ($height = '') 52 - #if ($xcontext.macro.params.alternateText) 53 - #set ($alt = "$services.rendering.escape($!{xcontext.macro.params.alternateText}, 'xwiki/2.1')") 54 - #end 55 - #if ($xcontext.macro.params.width) 56 - #set ($width = "$services.rendering.escape($!{xcontext.macro.params.width}, 'xwiki/2.1')") 57 - #end 58 - #if ($xcontext.macro.params.height) 59 - #set ($height = "$services.rendering.escape($!{xcontext.macro.params.height}, 'xwiki/2.1')") 60 - #end 49 + #set ($alt = "$!{xcontext.macro.params.alternateText}") 50 + #set ($width = "$!{xcontext.macro.params.width}") 51 + #set ($height = "$!{xcontext.macro.params.height}") 61 61 #set ($imageParams = '') 62 62 #if ("${width}" != '') 63 63 #set($imageParams = "$!{imageParams} width=${width}") ... ... @@ -95,7 +95,7 @@ 95 95 #set ($savemode = 'form') 96 96 #end 97 97 98 -#set ($propValue = "$!{ targetdoc.getObject($classname, $object).getProperty($property).value}")89 +#set ($propValue = "$!{doc.getObject($classname, $object).getProperty($property).value}") 99 99 ## 100 100 101 101 #macro (attachmentPicker_displayAttachment $name $displayImage $withLink $forceElement) ... ... @@ -122,9 +122,9 @@ 122 122 #set ($attachmentResource = '') 123 123 #end 124 124 #if ($displayImage) 125 - (% class="$!{cssClass}#if (!$attachment) hidden#end" %)(((#if ("$!{attachmentResource}" != '' || $forceElement)#if($withLink)[[#end[[image:$ services.rendering.escape(${attachmentResource}, 'xwiki/2.1')$!{imageParams}]]#if($withLink)>>attach:$services.rendering.escape(${attachmentResource},'xwiki/2.1')||rel=lightbox]]#{end}#end)))##116 + (% class="$!{cssClass}#if (!$attachment) hidden#end" %)(((#if ("$!{attachmentResource}" != '' || $forceElement)#if($withLink)[[#end[[image:${attachmentResource}$!{imageParams}]]#if($withLink)>>attach:${attachmentResource}||rel=lightbox]]#{end}#end)))## 126 126 #else 127 - services.rendering.escape($!{attachmentName}, 'xwiki/2.1')}#{else}Access Denied#{end}(% %)#{end}#end(%%)##118 + (% class="$!{cssClass}" %)#if ("$!{attachmentResource}" != '' || $forceElement)#if ($withLink)[[attach:${attachmentResource}||rel=__blank]]#{else}(% class="displayed" %)#if($targetPermView)$!{attachmentName}#{else}Access Denied#{end}(% %)#{end}#end(%%)## 128 128 #end 129 129 #end 130 130 ... ... @@ -132,7 +132,7 @@ 132 132 ## 1. Edit the current page 133 133 ## 2. View the target attachment page. (can be the same page) 134 134 #macro (attachmentPicker_displayButton) 135 - #if ($targetPermView) 126 + #if ($hasEdit && $targetPermView) 136 136 #set ($queryString = { 137 137 'docname': $doc.fullName, 138 138 'classname': $classname, ... ... @@ -159,7 +159,7 @@ 159 159 #elseif ($xcontext.action == 'inline' || $xcontext.action == 'edit') 160 160 (% class="attachment-picker" %)(((## 161 161 #attachmentPicker_displayAttachment($propValue $displayImage false true) #attachmentPicker_displayButton()## 162 - {{html}}<input type="hidden" name="$ escapetool.xml("${classname}_${object}_${property}")"value="$escapetool.xml("${propValue}")" class="property-reference"/>{{/html}}##153 + {{html}}<input type="hidden" name="${classname}_${object}_${property}" value="${propValue}"/>{{/html}}## 163 163 ))) 164 164 #else 165 165 #attachmentPicker_displayAttachment($propValue $displayImage $link false) - Default category
-
... ... @@ -1,0 +1,1 @@ 1 +Development - Default categories
-
... ... @@ -1,1 +1,0 @@ 1 -Development