From empty
To version 1.1
edited by superadmin
on 2017/11/28 14:52
Change comment: Install extension [org.xwiki.platform:xwiki-platform-attachment-ui/9.9]

Summary

Details

Page properties
Title
... ... @@ -1,0 +1,1 @@
1 +#if ($request.docname)$xwiki.getDocument($request.docname).plainTitle ($request.docname): #end$services.localization.render('xe.attachmentSelector.gallery.title')
Parent
... ... @@ -1,0 +1,1 @@
1 +Main.WebHome
Author
... ... @@ -1,1 +1,1 @@
1 -XWiki.XWikiGuest
1 +xwiki:XWiki.superadmin
Hidden
... ... @@ -1,1 +1,1 @@
1 -false
1 +true
Content
... ... @@ -1,0 +1,302 @@
1 +{{velocity output="false"}}
2 +#if ($request.xaction == 'postUpload')
3 + #set ($targetDocument = $xwiki.getDocument($request.get('docname')))
4 + #set ($targetAttachDocument = $xwiki.getDocument($request.get('targetdocname')))
5 +
6 + #set ($fieldname = $request.get('fieldname'))
7 + #set ($docAction = $request.get('docAction'))
8 + #set ($attachmentList = $targetAttachDocument.getAttachmentList())
9 + #if ($attachmentList && $attachmentList.size() > 0)
10 + #set ($sortedAttachments = $sorttool.sort($attachmentList, 'date:desc'))
11 + #set ($lastAttachment = $sortedAttachments.get(0))
12 + #end
13 + $response.sendRedirect($targetDocument.getURL($docAction, $escapetool.url({
14 + $fieldname: $lastAttachment.filename,
15 + 'form_token': $request.form_token
16 + })))
17 + #stop
18 +#end
19 +{{/velocity}}
20 +
21 +{{velocity output="false"}}
22 +##
23 +## Macros
24 +##
25 +#set ($translationPrefix = 'xe.attachmentSelector')
26 +#set ($attachmentPickerDocName = 'XWiki.AttachmentSelector')
27 +
28 +$xwiki.ssx.use($attachmentPickerDocName)
29 +$xwiki.jsx.use($attachmentPickerDocName)
30 +
31 +#**
32 + * Displays the attachment gallery as a list of attachment boxes, starting with special boxes for uploading a new attachment and for setting a default value.
33 + *
34 + * @param $targetDocument the document to recieve the field value being modified
35 + * @param $targetAttachDocument the document to list/save attachments to
36 + * @param $options generic picker options
37 + *#
38 +#macro (attachmentPicker_displayAttachmentGallery $targetDocument, $targetAttachDocument, $options)
39 + #set ($currentValue = $targetDocument.getValue($options.property))
40 + #if ("$!{targetAttachDocument.getAttachment($currentValue)}" == '')
41 + #set ($currentValue = "$!{options.defaultValue}")
42 + #end
43 + (% class="gallery" %)(((
44 + ## Only display the upload form if they have edit permission on targetAttachDocument
45 + #if ($xwiki.hasAccessLevel('edit',$xcontext.user,${targetAttachDocument.fullName}))
46 + #attachmentPicker_displayUploadForm($targetDocument, $targetAttachDocument, $options)
47 + #end
48 + #attachmentPicker_displayAttachmentGalleryEmptyValue($targetDocument, $targetAttachDocument, $options, $currentValue)
49 + #set ($sortedAttachments = $sorttool.sort($targetAttachDocument.getAttachmentList(), "${options.sortAttachmentsBy}") )
50 + #foreach ($attachment in $sortedAttachments)
51 + #set ($extension = $attachment.getFilename())
52 + #set ($extension = $extension.substring($mathtool.add($extension.lastIndexOf('.'), 1)).toLowerCase())
53 + #if ($options.filter.size() == 0 || $options.filter.contains($extension))
54 + #attachmentPicker_displayAttachmentBox($attachment $targetDocument $targetAttachDocument, $options $currentValue)
55 + #end
56 + #end
57 + )))
58 +#end
59 +
60 +#**
61 + * Displays an attachment box.
62 + *
63 + * @param $attachment the target attachment to display
64 + * @param $targetDocument the document being modified
65 + * @param $options generic picker options
66 + * @param $currentValue the currently selected file, used for determining if the box should be highlighted as the current value
67 + *#
68 +#macro (attachmentPicker_displayAttachmentBox $attachment $targetDocument $targetAttachDocument, $options $currentValue)
69 + #if ($options.displayImage && $attachment.isImage())
70 + #set ($cssClass = 'gallery_image')
71 + #else
72 + #set ($cssClass = '')
73 + #end
74 + #attachmentPicker_displayStartFrame({'value' : $attachment.filename, 'text' : $attachment.filename, 'cssClass' : "$!{cssClass}"} $currentValue)
75 + #attachmentPicker_displayAttachmentDetails($attachment $options)
76 + #set ($returnURL = $escapetool.url($doc.getURL('view', $request.queryString)))
77 + #set ($deleteURL = $targetAttachDocument.getAttachmentURL($attachment.filename, 'delattachment', "xredirect=${returnURL}&form_token=$!{services.csrf.getToken()}") )
78 + #set ($viewURL = $targetAttachDocument.getAttachmentURL($attachment.filename) )##{'name' : 'download', 'url' : $viewURL, 'rel' : '__blank'}
79 + #set ($selectURL = $targetDocument.getURL(${options.get('docAction')}, "${options.get('classname')}_${options.get('object')}_${options.get('property')}=${attachment.filename}&form_token=$!{services.csrf.getToken()}"))
80 + #attachmentPicker_displayEndFrame ([{'name' : 'select', 'url' : $selectURL}, {'name' : 'delete', 'url' : $deleteURL}])
81 +#end
82 +
83 +#**
84 + * Writes the wiki code used at the start of an attachment box. Outputs the attachment title bar, and opens the inner frame div.
85 + *
86 + * @param $boxOptions a map of parameters/options for the current attachment, holding, for example, the attachment name (boxOptions.value),
87 + * the title to display (boxOptions.text), optional extra CSS classnames to put on the box (boxOptions.cssClass)
88 + * @param $currentValue the currently selected file, used for determining if this attachment should be highlighted as the current value
89 + *#
90 +#macro (attachmentPicker_displayStartFrame $boxOptions $currentValue)
91 + (% class="gallery_attachmentbox $!{boxOptions.cssClass} #if ("$!{boxOptions.value}" == $currentValue) current#{end}" %)(((
92 + (% class="gallery_attachmenttitle" title="$!{boxOptions.value}" %)((($boxOptions.text)))
93 + (% class="gallery_attachmentframe" %)(((
94 +#end
95 +
96 +#**
97 + * Displays details about an attachment inside the attachment box. If the attachment is an image and the "displayImage" option is on,
98 + * then the image is displayed. Otherwise, some basic information is displayed: the version, the size, the date and the author.
99 + *
100 + * @param $attachment the target attachment to display
101 + * @param $options generic picker options
102 + *#
103 +#macro (attachmentPicker_displayAttachmentDetails $attachment $options)
104 + #if ($attachment)
105 + ## Compute the attachment reference because there's no getter.
106 + #set ($attachmentReference = $services.model.createAttachmentReference($attachment.document.documentReference,
107 + $attachment.filename))
108 + #set ($attachmentStringReference = $services.model.serialize($attachmentReference, 'default'))
109 + #if ($attachment.isImage() && $options.displayImage)
110 + ## We add the version to the query string in order to invalidate the cache when an image attachment is replaced.
111 + #set ($queryString = $escapetool.url({'version': $attachment.version}))
112 + [[[[image:$attachmentStringReference||width=180 queryString="$queryString"]]>>attach:$attachmentStringReference]]
113 + #else
114 + * (% class="mime" %){{html wiki=false clean=false}}#mimetypeimg($attachment.getMimeType().toLowerCase() $attachment.getFilename().toLowerCase()){{/html}}(%%) (% class="filename" %)$attachment.getFilename()(% %)
115 + * v$attachment.getVersion() (#dynamicsize($attachment.longSize))
116 + * $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')}])
117 + * (% class="buttonwrapper" %)[[${services.localization.render("${translationPrefix}.actions.download")}>>attach:$attachmentStringReference||title="$services.localization.render("${translationPrefix}.actions.download")" rel="__blank" class="button"]](%%)
118 + #end
119 + #end
120 +#end
121 +
122 +#**
123 + * Writes the wiki code used at the end of an attachment box. Closes the inner frame div, and outputs the attachment actions.
124 + *
125 + * @param $actions a list of maps defining action buttons, where each entry contains a subset of the following:
126 + * <dl>
127 + * <dt>name</dt>
128 + * <dd>identifies the action; the name is used as a CSS classname, and in the translation key for the display text, as "xe.attachmentSelector.actions.<name>"</dd>
129 + * <dt>url</dt>
130 + * <dd>the destination of the button</dd>
131 + * <dt>rel</dt>
132 + * <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>
133 + * </dl>
134 + *#
135 +#macro (attachmentPicker_displayEndFrame $actions)
136 + )))## attachmentframe
137 + (% class="gallery_actions" %)(((
138 + #foreach ($action in $actions)
139 + #set( $actionname = $services.localization.render("${translationPrefix}.actions.${action.name}") )
140 + [[${actionname}>>path:${action.url}||class="tool ${action.name}" title="${actionname}" #if($action.rel) rel="${action.rel}"#end]]##
141 + #end
142 + )))## actions
143 + )))## attachmentbox
144 +#end
145 +
146 +#**
147 + * Displays the upload box used for adding and selecting a new attachment.
148 + *
149 + * @param $targetDocument the document with the property being modified
150 + * @param $targetAttachDocument the document to upload the attachment to
151 + * @param $options generic picker options
152 + *#
153 +#macro (attachmentPicker_displayUploadForm $targetDocument, $targetAttachDocument, $options)
154 +#attachmentPicker_displayStartFrame({
155 + 'value' : $services.localization.render("${translationPrefix}.upload.title"),
156 + 'text' : $services.localization.render("${translationPrefix}.upload.title"),
157 + 'cssClass' : 'gallery_upload'
158 + } $NULL)
159 +{{html clean="false"}}
160 +<form action="$targetAttachDocument.getURL('upload')" enctype="multipart/form-data" method="post" id="uploadAttachment" class="uploadAttachment xform">
161 + <div class="gallery_upload_input">
162 + #if (${options.rawfilter} != '')
163 + <span class="xHint">$escapetool.xml($services.localization.render("${translationPrefix}.upload.hint", [${options.rawfilter}]))</span>
164 + #end
165 + <input type="file" name="filepath" id="attachfile" class="noitems" title="$!{escapetool.xml($options.rawfilter)}"/>
166 + <input type="hidden" name="xredirect" value="$xwiki.getDocument($attachmentPickerDocName).getURL('get', "xaction=postUpload&amp;docAction=$!{escapetool.url($options.get('docAction'))}&amp;targetdocname=$!{escapetool.url($targetAttachDocument.fullName)}&amp;docname=$!{escapetool.url($targetDocument.fullName)}&amp;fieldname=$!{escapetool.url($options.get('classname'))}_$!{escapetool.url($options.get('object'))}_$!{escapetool.url($options.get('property'))}&amp;form_token=$!{services.csrf.getToken()}")" />
167 + <input type="hidden" name="docname" value="$!{escapetool.xml($targetDocument.fullName)}" />
168 + <input type="hidden" name="classname" value="$!{escapetool.xml($options.get('classname'))}" />
169 + <input type="hidden" name="object" value="$!{escapetool.xml($options.get('object'))}" />
170 + <input type="hidden" name="property" value="$!{escapetool.xml($options.get('property'))}" />
171 + <input type="hidden" name="form_token" value="$!{services.csrf.getToken()}" />
172 + </div>
173 + #if ("$!currentValue" != '' && $currentValue != $options.defaultValue)
174 + <div>
175 + <label>
176 + <input type="checkbox" name="filename" value="$!escapetool.xml($currentValue)"
177 + />$services.localization.render('attachmentSelector.replace',
178 + ["<strong>$!escapetool.xml($currentValue)</strong>"])
179 + </label>
180 + <span class="xHint">$escapetool.xml($services.localization.render('attachmentSelector.replace.hint'))</span>
181 + </div>
182 + #end
183 + #if ($xwiki.hasEditComment() && $options.versionSummary)
184 + <div>
185 + #if ($xwiki.isEditCommentFieldHidden())
186 + <input type="hidden" name="comment" value="$!escapetool.xml($request.comment)" />
187 + #else
188 + <label for="commentinput">$services.localization.render('core.comment')</label>
189 + <input type="text" name="comment" id="commentinput" value="$!escapetool.xml($request.comment)"
190 + title="$services.localization.render('core.comment.tooltip')" />
191 + #end
192 + </div>
193 + #end
194 + <div class="buttons">
195 + <span class="buttonwrapper">
196 + <input type="submit" name="action_upload" class="button " value='$services.localization.render("${translationPrefix}.upload.submit")' title='$services.localization.render("${translationPrefix}.upload.submit")'/>
197 + </span>
198 + </div>
199 +</form>
200 +{{/html}}
201 +#attachmentPicker_displayEndFrame ([])
202 +#end
203 +
204 +#**
205 + * Displays the "empty value" box, used for unsetting the field value.
206 + *
207 + * @param $targetDocument the document being modified
208 + * @param $targetAttachDocument the document that the attachments will the loaded from/saved to
209 + * @param $options generic picker options
210 + * @param $currentValue the currently selected file, used for determining if the empty box should be highlighted as the current value
211 + *#
212 +#macro (attachmentPicker_displayAttachmentGalleryEmptyValue $targetDocument, $targetAttachDocument, $options, $currentValue)
213 + #if ("$!{options.get('defaultValue')}" != '')
214 + #set ($reference = ${options.get('defaultValue')})
215 + #set ($docNameLimit = $reference.indexOf('@'))
216 + #if ($docNameLimit > 0)
217 + #set ($docName = $reference.substring(0, $docNameLimit))
218 + #else
219 + #set ($docName = $targetAttachDocument.fullName)
220 + #end
221 + #set ($attachmentName = $reference.substring($mathtool.add($docNameLimit, 1)))
222 + #set ($defaultAttachment = $xwiki.getDocument($docName).getAttachment($attachmentName))
223 + #if ($defaultAttachment.isImage())
224 + #set($dcssClass = 'gallery_image')
225 + #end
226 + #end
227 + #attachmentPicker_displayStartFrame({'cssClass' : "gallery_emptyChoice $!{dcssClass}", 'text' : $services.localization.render("${translationPrefix}.default"), 'value' : "${options.defaultValue}"} $currentValue)
228 + #attachmentPicker_displayAttachmentDetails($defaultAttachment $options)
229 + #set ($returnURL = $escapetool.url($doc.getURL('view', $request.queryString)))
230 + #set ($selectURL = $targetDocument.getURL(${options.get('docAction')}, "${options.get('classname')}_${options.get('object')}_${options.get('property')}=&form_token=$!{services.csrf.getToken()}"))
231 + #attachmentPicker_displayEndFrame ([{'name' : 'select', 'url' : $selectURL}])
232 +#end
233 +{{/velocity}}
234 +
235 +{{velocity}}
236 +#if ($request.docname)
237 + #set ($targetDocument = $xwiki.getDocument($request.docname))
238 + #if ($request.targetdocname)
239 + ## Use the target document if it exists.
240 + #set ($targetAttachDocument = $xwiki.getDocument($request.targetdocname))
241 + #else
242 + ## Otherwise, just use the current document as the target to save/load attachments
243 + #set ($targetAttachDocument = $targetDocument)
244 + #end
245 + #if ("$!{request.savemode}" == 'direct')
246 + #set($docAction = 'save')
247 + #else
248 + #set($docAction = $targetAttachDocument.getDefaultEditMode())
249 + #end
250 + #set ($filter = [])
251 + #set ($rawfilter = '')
252 + #if ("$!{request.filter}" != '')
253 + #foreach ($value in $request.filter.trim().split('\s*+[,|; ]\s*+'))
254 + #if ("$!value" != '')
255 + #set ($discard = $filter.add($value.toLowerCase()))
256 + #set ($rawfilter = "${rawfilter}, ${value}")
257 + #end
258 + #end
259 + #if ($rawfilter != '')
260 + #set ($rawfilter = $rawfilter.substring(2))
261 + #end
262 + #end
263 + #if ("$!{request.displayImage}" == 'true')
264 + #set ($displayImage = true)
265 + #else
266 + #set ($displayImage = false)
267 + #end
268 + ### Determine attachment sorting
269 + #set($sortAttachmentsBy = "$!{request.sortAttachmentsBy}")
270 + #set ($validAttachmentProperties = ['filename', 'date', 'filesize', 'author', 'version', 'mimeType'])
271 + #if($sortAttachmentsBy == '' || $validAttachmentProperties.indexOf($sortAttachmentsBy) == -1)
272 + ### Default to sorting by filename, sort not requested.
273 + #set($sortAttachmentsBy = "filename")
274 + #end
275 + ### Set attachment sorting direction
276 + #if($sortAttachmentsBy == 'date')
277 + ### Sort the date descending
278 + #set($sortAttachmentsBy = "date:desc")
279 + #else
280 + ### Sort everything else ascending
281 + #set($sortAttachmentsBy = "${sortAttachmentsBy}:asc")
282 + #end
283 + #set ($options = {
284 + 'classname' : ${request.get('classname')},
285 + 'object' : $!{mathtool.toInteger($request.object)},
286 + 'property' : ${request.property},
287 + 'displayImage' : ${displayImage},
288 + 'docAction' : ${docAction},
289 + 'defaultValue' : "$!{request.defaultValue}",
290 + 'rawfilter': "$!{rawfilter}",
291 + 'filter': ${filter},
292 + 'sortAttachmentsBy': ${sortAttachmentsBy},
293 + 'versionSummary': $request.versionSummary.equals('true')
294 + })
295 + $!targetDocument.use($targetDocument.getObject($options.classname, $options.object))##
296 + #attachmentPicker_displayAttachmentGallery($targetDocument, $targetAttachDocument, $options)
297 +
298 + (% class="gallery_buttons buttons" %)(((
299 + (% class="buttonwrapper secondary" %)[[$services.localization.render("${translationPrefix}.cancel")>>$targetDocument||class="button secondary" id="attachment-picker-close"]]
300 + )))
301 +#end
302 +{{/velocity}}
XWiki.JavaScriptExtension[0]
Caching policy
... ... @@ -1,0 +1,1 @@
1 +long
Code
... ... @@ -1,0 +1,301 @@
1 +var XWiki = (function(XWiki) {
2 + /** Handles the gallery buttons directly in the current page without reloading the window. */
3 + XWiki.AttachmentPicker = Class.create({
4 + /**
5 + * Constructor.
6 + *
7 + * @param property the property being edited, as the containing div with class="attachment-picker"
8 + * @param dialog the modal dialog where the gallery was loaded
9 + */
10 + initialize : function(property, dialog) {
11 + this.property = property;
12 + this.dialog = dialog;
13 + this.gallery = dialog.dialogBox;
14 + if (!this.property.down('input')) {
15 + this.directSave = true;
16 + }
17 + this.defaultValue = '';
18 + var defaultValueElement = this.gallery.down('.gallery_emptyChoice .gallery_attachmenttitle');
19 + if (defaultValueElement) {
20 + this.defaultValue = defaultValueElement.title;
21 + }
22 + this.defaultImageSource = '';
23 + var defaultImage = this.gallery.down('.gallery_emptyChoice.gallery_image img');
24 + if (defaultImage) {
25 + this.defaultImageSource = defaultImage.src.replace(/\?.*$/, '');
26 + }
27 + this.filterFormUpload();
28 + this.addDeleteListeners();
29 + this.addSelectListeners();
30 + this.updateCurrentSelection();
31 + this.addCloseListener();
32 + var img = this.property.down('img');
33 + if (img) {
34 + img.observe('load', function() {img.up('div').removeClassName('hidden');});
35 + img.observe('error', function() {img.up('div').addClassName('hidden');});
36 + }
37 + },
38 + /**
39 + * Catches the upload form submission and stops it if the selected file is not of the accepted types (or not selected at all),
40 + * and saves the underlying form (if any) so that any unsaved changes won't be lost.
41 + */
42 + filterFormUpload : function() {
43 + this.gallery.select('.uploadAttachment input[type="file"]').each(function(fileInput) {
44 + fileInput.__allowedExtensions = fileInput.title.toLowerCase().replace(/\s*[,|; ]\s*/g, " ").strip();
45 + if (fileInput.__allowedExtensions != '') {
46 + fileInput.__allowedExtensions = fileInput.__allowedExtensions.split(" ");
47 + } else {
48 + fileInput.__allowedExtensions = false;
49 + }
50 + });
51 + this.gallery.select(".uploadAttachment").invoke('observe', 'submit', function(event) {
52 + event.stop();
53 + var uploadForm = event.element();
54 + var hasErrors = false;
55 + uploadForm.select('input[type="file"]').each(function(fileInput) {
56 + if (fileInput.value == '') {
57 + new XWiki.widgets.Notification("$services.localization.render('xe.attachmentSelector.upload.error.noFile')", 'error');
58 + hasErrors = true;
59 + } else if (fileInput.__allowedExtensions && fileInput.__allowedExtensions.indexOf(this.getFileExtension(fileInput.value)) == -1) {
60 + new XWiki.widgets.Notification("$services.localization.render('xe.attachmentSelector.upload.error.badExtension')", 'error');
61 + hasErrors = true;
62 + }
63 + }.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
66 + if (!hasErrors) {
67 + if (this.directSave) {
68 + uploadForm.submit();
69 + } else {
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')});
78 + }
79 + }
80 + }.bindAsEventListener(this));
81 + },
82 + getFileExtension : function(filename) {
83 + var fpath = filename.replace('\\', '/');
84 + var pieces = fpath.split('/');
85 + if (pieces.length == 0) {
86 + return null;
87 + }
88 + var basename = pieces[pieces.length-1];
89 + pieces = basename.split('.');
90 + return pieces[pieces.length-1].toLowerCase();
91 + },
92 +
93 + /** Catch attachment delete requests. */
94 + addDeleteListeners : function() {
95 + this.gallery.select('.gallery_actions .tool.delete').invoke('observe', 'click', this.onDelete.bindAsEventListener(this));
96 + },
97 +
98 + /** Catch attachment selection requests. */
99 + addSelectListeners : function() {
100 + this.gallery.select('.gallery_actions .tool.select').invoke('observe', 'click', this.onSelect.bindAsEventListener(this));
101 + },
102 +
103 + /** AJAX deletion of attachments. */
104 + onDelete : function(event) {
105 + event.stop();
106 + deleteTool = event.element();
107 + if (!deleteTool.disabled) {
108 + new XWiki.widgets.ConfirmedAjaxRequest(
109 + deleteTool.readAttribute('href'),
110 + {
111 + onCreate : function() { deleteTool.disabled = true },
112 + onSuccess : function() {
113 + var attachmentBox = deleteTool.up('.gallery_attachmentbox');
114 + if (attachmentBox) {
115 + if (attachmentBox.hasClassName('current')) {
116 + this.updateAttachment(this.defaultValue, this.defaultImageSource);
117 + if (this.gallery.down('.gallery_emptyChoice')) {
118 + this.gallery.down('.gallery_emptyChoice').addClassName('current');
119 + }
120 + // Disable the replace feature because there's no selection.
121 + var fileNameInput = this.gallery.down('input[type="checkbox"][name="filename"]');
122 + fileNameInput.disabled = true;
123 + // Empty the displayed selected file name.
124 + fileNameInput.up('label').down('strong').update('');
125 + if (!this.directSave) {
126 + this.property.down('input').value = this.defaultValue;
127 + }
128 + }
129 + attachmentBox.remove();
130 + }
131 + }.bind(this),
132 + onComplete : function() {
133 + deleteTool.disabled = false;
134 + }
135 + },
136 + {
137 + confirmationText: "$services.localization.render('core.viewers.attachments.delete.confirm')",
138 + progressMessageText : "$services.localization.render('core.viewers.attachments.delete.inProgress')",
139 + successMessageText : "$services.localization.render('core.viewers.attachments.delete.done')",
140 + failureMessageText : "$services.localization.render('core.viewers.attachments.delete.failed')"
141 + }
142 + );
143 + }
144 + },
145 +
146 + /** Update the property with the selected value without reloading the page. */
147 + onSelect : function(event) {
148 + event.stop();
149 + var targetElement = event.element();
150 + var attachmentName = targetElement.up('.gallery_attachmentbox').down('.gallery_attachmenttitle').title;
151 + var imageSource = targetElement.up('.gallery_attachmentbox.gallery_image');
152 + if (imageSource) {
153 + imageSource = imageSource.down('.gallery_attachmentframe img');
154 + if (imageSource) {
155 + imageSource = imageSource.src.replace(/\?.*$/, '');
156 + }
157 + }
158 + if (!imageSource) {
159 + imageSource = '';
160 + }
161 + if (this.directSave) {
162 + // save via ajax
163 + if (!targetElement.disabled) {
164 + new Ajax.Request(event.element().href, {
165 + onCreate : function() {
166 + targetElement.disabled = true;
167 + targetElement._x_notif = new XWiki.widgets.Notification("$services.localization.render('core.widgets.confirmationBox.notification.inProgress')", 'inprogress');
168 + },
169 + onSuccess : function () {
170 + targetElement._x_notif.hide();
171 + // on success, update image
172 + this.updateAttachment(attachmentName, imageSource);
173 + this.dialog.closeDialog();
174 + }.bindAsEventListener(this),
175 + onFailure : function(response) {
176 + var failureReason = response.statusText;
177 + if (response.statusText == '' /* No response */ || response.status == 12031 /* In IE */) {
178 + failureReason = 'Server not responding';
179 + }
180 + if (targetElement._x_notif) {
181 + targetElement._x_notif.replace(new XWiki.widgets.Notification("$services.localization.render('core.widgets.confirmationBox.notification.failed')" + failureReason, "error"));
182 + } else {
183 + new XWiki.widgets.Notification(this.interactionParameters.failureMessageText + failureReason, "error");
184 + }
185 + },
186 + on1223 : function(response) {
187 + response.request.options.onSuccess(response);
188 + },
189 + on0 : function(response) {
190 + response.request.options.onFailure(response);
191 + },
192 + onComplete : function() {
193 + targetElement.disabled = false;
194 + }
195 + });
196 + }
197 + } else {
198 + this.updateAttachment(attachmentName, imageSource);
199 + this.property.down('input').value = attachmentName;
200 + this.dialog.closeDialog();
201 + }
202 + },
203 +
204 + /** Update the property display. */
205 + updateAttachment : function(attachmentName, imageSource) {
206 + var img = this.property.down('img');
207 + if (img) {
208 + img.src = img.src.replace(/^[^\?]+($|\?)/, imageSource + "$1");
209 + var link = img.up('a');
210 + if (link) {
211 + link.href = link.href.replace(/^[^\?]+($|\?)/, imageSource + "$1");
212 + }
213 + } else {
214 + var displayed = this.property.down('.displayed');
215 + if (displayed) {
216 + displayed.update(attachmentName);
217 + var link = displayed.up('a');
218 + if (link) {
219 + link.href = link.href.replace(/^[^\?]+($|\?)/, attachmentName + "$1");
220 + }
221 + }
222 + }
223 + },
224 +
225 + /** Update the gallery to reflect the currently selected value. */
226 + updateCurrentSelection : function() {
227 + if (!this.directSave) {
228 + var selectedName = this.property.down('input').value;
229 + var selectedElement = this.gallery.down('.gallery_attachmenttitle[title="' + selectedName.replace('"', '\\22 ') + '"]');
230 + if (selectedElement) {
231 + selectedElement = selectedElement.up('.gallery_attachmentbox');
232 + } else {
233 + selectedElement = this.gallery.down('.gallery_emptyChoice');
234 + }
235 + if (!selectedElement.hasClassName('current')) {
236 + this.gallery.select('.gallery_attachmentbox.current .tool.select').invoke('removeClassName', 'hidden');
237 + this.gallery.select('.gallery_attachmentbox.current').invoke('removeClassName', 'current');
238 + selectedElement.addClassName('current');
239 + }
240 + selectedElement.down('.tool.select').addClassName('hidden');
241 + } else {
242 + this.gallery.down('.current .tool.select').addClassName('hidden');
243 + }
244 + },
245 + addCloseListener : function () {
246 + var closeButton = $('attachment-picker-close');
247 + if (closeButton) {
248 + closeButton.observe('click', function(event) {
249 + event.stop();
250 + this.dialog.closeDialog();
251 + }.bindAsEventListener(this));
252 + }
253 + }
254 + });
255 +
256 + var loading = new Element('div', {'class' : 'imgcenter'}).update("<img src=\"$xwiki.getSkinFile('icons/xwiki/ajax-loader-large.gif')\"/>");
257 + var dialog;
258 +
259 + /* Hook onto the picker buttons so that the gallery is loaded via AJAX in a modal dialog. */
260 + document.observe('xwiki:dom:loaded', function() {
261 + $$('.attachment-picker-start').invoke('observe', 'click', function(event) {
262 + event.stop();
263 + var targetElement = event.element();
264 + var url = targetElement.href;
265 + if (url.indexOf('?') < 0) {
266 + url += '?';
267 + }
268 + url += "&xpage=plain";
269 + dialog = new XWiki.widgets.ModalPopup(
270 + loading, {}, {
271 + 'verticalPosition' : 'top',
272 + 'removeOnClose' : true,
273 + 'title' : "$services.localization.render('xe.attachmentSelector.gallery.title')"
274 + }
275 + );
276 + dialog.shortcuts.close.keys = [];
277 + dialog.showDialog();
278 + dialog.dialog.down().setStyle({position: "fixed"});
279 + dialog.dialog.setStyle({top: document.viewport.getScrollOffsets().top + "px", position: "absolute"});
280 + dialog.dialogBox.setStyle({overflow: "hidden", width: "80%", margin: "0 10%"});
281 + new Ajax.Updater(loading.up(), url, {
282 + onComplete : function() {
283 + // Play nice with the Lightbox widget
284 + if (window.gallery_lb) {
285 + window.gallery_lb.updateImageList();
286 + }
287 + // Manually convert the special rel values into target attributes for the newly inserted content (rel="_something" => target="something")
288 + if (typeof (XWiki.fixLinksTargetAttribute) == 'function') {
289 + // Trick the function into updating link targets in edit mode; normally the conversion only takes place in view mode
290 + var __tmp = XWiki.contextaction;
291 + XWiki.contextaction = 'view';
292 + XWiki.fixLinksTargetAttribute(dialog.dialog);
293 + XWiki.contextaction = __tmp;
294 + }
295 + new XWiki.AttachmentPicker(targetElement.up('.attachment-picker'), dialog);
296 + }
297 + });
298 + });
299 + });
300 + return XWiki;
301 +}(XWiki || {}));
Name
... ... @@ -1,0 +1,1 @@
1 +Loads the image picker in a modal dialog
Parse content
... ... @@ -1,0 +1,1 @@
1 +Yes
Use this extension
... ... @@ -1,0 +1,1 @@
1 +currentPage
XWiki.JavaScriptExtension[1]
Caching policy
... ... @@ -1,0 +1,1 @@
1 +long
Code
... ... @@ -1,0 +1,33 @@
1 +XWiki.widgets.ModalPopup.prototype.showDialog = function(event) {
2 + if (event) {
3 + Event.stop(event);
4 + }
5 + // Only do this if the dialog is not already active.
6 + if (!this.active) {
7 + this.active = true;
8 + if (!this.dialog) {
9 + // The dialog wasn't loaded, create it.
10 + this.createDialog();
11 + }
12 + // Start listening to keyboard events
13 + this.attachKeyListeners();
14 + // Display the dialog
15 + this.dialog.show();
16 + }
17 +};
18 +XWiki.widgets.ModalPopup.prototype.closeDialog = function(event) {
19 + if (event) {
20 + Event.stop(event);
21 + }
22 + // Call optional callback
23 + this.options.onClose.call(this);
24 + // Hide the dialog, without removing it from the DOM.
25 + this.dialog.hide();
26 + if (this.options.removeOnClose) {
27 + this.dialog.remove();
28 + }
29 + // Stop the UI shortcuts (except the initial Show Dialog one).
30 + this.detachKeyListeners();
31 + // Re-enable the 'show' behavior.
32 + this.active = false;
33 +}
Name
... ... @@ -1,0 +1,1 @@
1 +Patch for modalPopup.js, allowing to display several widgets on the same screen and removing position:fixed in IE
Parse content
... ... @@ -1,0 +1,1 @@
1 +No
Use this extension
... ... @@ -1,0 +1,1 @@
1 +currentPage
XWiki.StyleSheetExtension[0]
Caching policy
... ... @@ -1,0 +1,1 @@
1 +long
Code
... ... @@ -1,0 +1,195 @@
1 +#template("colorThemeInit.vm")
2 +#set ($boxSize = 170)
3 +#set ($boxPadding = 5)
4 +#set ($boxMargin = 5)
5 +## Make the upload box two times as wide, so that the input fits nicely.
6 +## | |
7 +## | | | |
8 +## | 1 width + 1 border + 2 margins + 1 border + 1 width |
9 +#set ($uploadBoxSize = $mathtool.add(2, $mathtool.add($mathtool.mul($boxSize, 2), $mathtool.mul($boxMargin, 2))))
10 +#set ($imgSize = $mathtool.sub($boxSize, $mathtool.mul($boxPadding, 2)))
11 +#set ($actionsHeight = 20)
12 +#set ($actionsWidth = 16)
13 +/*--------------------------------------------------------*/
14 +/* Attachment picker layout fixes */
15 +.attachment-picker p {
16 + margin: 0;
17 + padding : 0;
18 +}
19 +.attachment-picker picture {
20 + max-width: 100%;
21 +}
22 +/*--------------------------------------------------------*/
23 +/* Gallery attachmentboxes */
24 +.gallery p {
25 + margin: 0;
26 +}
27 +.gallery_attachmentbox {
28 + background: $theme.pageContentBackgroundColor;
29 + border: 1px solid $theme.borderColor;
30 + border-radius: 5px;
31 + float: left;
32 + margin: ${boxMargin}px;
33 + overflow: hidden;
34 + position: relative;
35 + width: ${boxSize}px;
36 +}
37 +.gallery .current {
38 + background-color: $theme.highlightColor;
39 + border-width: 3px;
40 + margin: 3px;
41 +}
42 +.gallery .current .gallery_attachmenttitle {
43 + font-weight: bold;
44 +}
45 +.gallery_attachmentbox:hover {
46 + background-color: $theme.highlightColor;
47 +}
48 +
49 +.gallery_attachmenttitle {
50 + background: $theme.backgroundSecondaryColor;
51 + border-bottom: 1px dotted $theme.borderColor;
52 + border-radius: 5px 5px 0px 0px;
53 + font-size: 85%;
54 + padding: 3px ${boxPadding}px;
55 + overflow: hidden;
56 + text-overflow: ellipsis;
57 + white-space: nowrap;
58 +}
59 +.gallery_attachmenttitle p {
60 + text-align: center;
61 + overflow: hidden;
62 +}
63 +
64 +.gallery_attachmentframe {
65 + padding: ${boxPadding}px;
66 + height: ${imgSize}px;
67 + overflow: hidden;
68 + position: relative;
69 +}
70 +
71 +.gallery_attachmentframe a {
72 + display: block;
73 + text-align: center;
74 +}
75 +
76 +.gallery_attachmentbox img {
77 + max-height: ${imgSize}px;
78 + max-width: ${imgSize}px;
79 + width: auto;
80 +}
81 +.gallery_attachmentframe ul {
82 + list-style-type: none;
83 + margin: 0;
84 + padding: 0;
85 +}
86 +.gallery_attachmentframe li {
87 + margin: 0.5em 0 0.5em 20px;
88 + font-size: 0.8em;
89 +}
90 +.gallery_attachmentframe .mime {
91 + margin: 0 2px 0 -20px;
92 +}
93 +.gallery_attachmentframe .mime img {
94 + vertical-align: top;
95 +}
96 +.gallery_attachmentframe li .filename {
97 + display: inline-block;
98 + font-weight: bold;
99 + width: $mathtool.sub($imgSize, 22)px;
100 + word-wrap: break-word;
101 +}
102 +
103 +/* Actions */
104 +.gallery_actions {
105 + width: auto;
106 + position: absolute;
107 + bottom: 0px;
108 + right: ${boxPadding}px;
109 +}
110 +.gallery_actions .tool {
111 + background: none no-repeat 50% transparent;
112 + cursor: pointer;
113 + display: block;
114 + float: left;
115 + height: ${actionsHeight}px;
116 + padding: 0 !important;
117 + overflow: hidden;
118 + text-indent: -1000em;
119 + opacity: 0.6;
120 + width: ${actionsWidth}px;
121 +}
122 +.gallery_actions .tool:hover {
123 + opacity: 1;
124 +}
125 +.gallery_actions .select {
126 + background-image: url("$xwiki.getSkinFile('icons/silk/tick.png')");
127 +}
128 +.gallery_actions .delete {
129 + background-image: url("$xwiki.getSkinFile('icons/silk/cross.png')");
130 +}
131 +.gallery_actions .view {
132 + background-image: url("$xwiki.getSkinFile('icons/silk/link.png')");
133 +}
134 +.gallery_actions .download {
135 + background-image: url("$xwiki.getSkinFile('icons/silk/arrow_down.png')");
136 +}
137 +/*--------------------------------------------------*/
138 +/* Upload form */
139 +.gallery_upload {
140 + ## Make this box twice as large as the others
141 + width: ${uploadBoxSize}px;
142 +}
143 +* html .gallery_upload {
144 + width: ${mathtool.add($uploadBoxSize, 2)}px;
145 +}
146 +.gallery_upload, .gallery_upload:hover {
147 + background-color: $theme.backgroundSecondaryColor;
148 +}
149 +
150 +.gallery_upload .gallery_attachmenttitle {
151 + background-position: 1px center;
152 + background-image: url("$xwiki.getSkinFile('icons/silk/bullet_add.png')");
153 + background-repeat: no-repeat;
154 + padding-left: 16px;
155 +}
156 +.gallery_upload .gallery_attachmentframe {
157 + height: auto;
158 +}
159 +.gallery_upload_input {
160 + margin-bottom: 10px;
161 +}
162 +.gallery_upload input[type="file"] {
163 + font-size: 86%;
164 + width: ${mathtool.sub($uploadBoxSize, $mathtool.mul($boxPadding, 2))}px;
165 +}
166 +.gallery_upload .buttonwrapper {
167 + margin: 0;
168 +}
169 +.gallery_upload .button,
170 +.gallery_upload label {
171 + font-size: 86%;
172 +}
173 +.gallery_upload input[type="checkbox"] {
174 + vertical-align: text-bottom;
175 +}
176 +.gallery_upload label[for="commentinput"] {
177 + margin-top: 10px;
178 +}
179 +
180 +/* ------------------------------------ */
181 +/* Buttons on top: */
182 +.gallery_actions {
183 + top: 1px;
184 + right: 3px;
185 +}
186 +.gallery_attachmenttitle p {
187 + text-align: left;
188 + margin-right: ${mathtool.add($mathtool.mul(2, $actionsWidth), $boxPadding)}px;
189 +}
190 +/* ------------------------------------ */
191 +/* Cancel button */
192 +.gallery_buttons {
193 + clear: both;
194 + margin: ${boxMargin}px;
195 +}
Name
... ... @@ -1,0 +1,1 @@
1 +Attachment galery styling
Parse content
... ... @@ -1,0 +1,1 @@
1 +Yes
Use this extension
... ... @@ -1,0 +1,1 @@
1 +onDemand
XWiki.WikiMacroClass[0]
Macro code
... ... @@ -1,0 +1,158 @@
1 +{{velocity output="false"}}
2 +$xwiki.jsfx.use('js/xwiki/widgets/modalPopup.js', true)##
3 +$xwiki.ssfx.use('js/xwiki/widgets/modalPopup.css', true)##
4 +$xwiki.jsx.use($xcontext.macro.doc.fullName)##
5 +$xwiki.ssx.use($xcontext.macro.doc.fullName)##
6 +$xwiki.jsfx.use('js/scriptaculous/builder.js')##
7 +## Integrates the optional Lightbox widget (from http://extensions.xwiki.org/xwiki/bin/view/Extension/Lightbox+Application )
8 +#if ($xwiki.exists('XWiki.Lightbox'))
9 + $xwiki.jsx.use('XWiki.Lightbox')
10 + $xwiki.ssx.use('XWiki.Lightbox')
11 +#end
12 +
13 +##
14 +## Prepare parameters
15 +##
16 +## Keep track for when we have a target document
17 +#set ($hasTargetDoc = false)
18 +#set ($targetdoc = "$!{xcontext.macro.params.targetdocname}")
19 +###
20 +## Set the targetdoc we want to save to (default to current doc if not set)
21 +#if ("$!{targetdoc}" != '')
22 + ## Check access on targetdocname
23 + #set ($targetPermView = $xwiki.hasAccessLevel('view',$xcontext.user,${targetdoc}))
24 + #set ($targetPermEdit = $xwiki.hasAccessLevel('edit',$xcontext.user,${targetdoc}))
25 + #set ($targetdoc = $xwiki.getDocument($targetdoc) )
26 + #set ($hasTargetDoc = true)
27 +#else
28 + ## The user should have edit and view permissions for the current doc
29 + #set ($targetPermView = true)
30 + #set ($targetPermEdit = true)
31 + #set($targetdoc = $doc)
32 +#end
33 +#set ($classname = "$!{xcontext.macro.params.classname}")
34 +#set ($property = "$!{xcontext.macro.params.property}")
35 +#set ($object = $mathtool.toInteger("$!{xcontext.macro.params.object}"))
36 +#if ("$!{object}" != $!{xcontext.macro.params.object})
37 + #set ($object = ${doc.getObject($classname).number})
38 + #if ("$!{object}" == '')
39 + #set ($object = 0)
40 + #end
41 +#end
42 +
43 +#if ("$!{xcontext.macro.params.displayImage}" == 'true' && $targetPermView)
44 + #set ($displayImage = true)
45 +#else
46 + #set ($displayImage = false)
47 +#end
48 +#if ($displayImage)
49 + #set ($alt = "$!{xcontext.macro.params.alternateText}")
50 + #set ($width = "$!{xcontext.macro.params.width}")
51 + #set ($height = "$!{xcontext.macro.params.height}")
52 + #set ($imageParams = '')
53 + #if ("${width}" != '')
54 + #set($imageParams = "$!{imageParams} width=${width}")
55 + #end
56 + #if ("${height}" != '')
57 + #set ($imageParams = "$!{imageParams} height=${height}")
58 + #end
59 + #set ($imageParams = "$!{imageParams} alt='${alt}'")
60 + #if ("$!{imageParams}" != '')
61 + #set ($imageParams = "||${imageParams.trim()}")
62 + #end
63 +#end
64 +#if ("$!{xcontext.macro.params.link}" == 'true')
65 + #set ($link = true)
66 +#else
67 + #set ($link = false)
68 +#end
69 +
70 +#set ($cssClass = "displayed x-attachment $!{xcontext.macro.params.cssClass}")
71 +#set ($defaultValue = "$!{xcontext.macro.params.defaultValue}")
72 +#if ($defaultValue != '')
73 + #set ($defaultReference = $services.model.resolveAttachment($defaultValue))
74 +#else
75 + #set ($defaultReference = false)
76 +#end
77 +#set ($filter = ${xcontext.macro.params.filter})
78 +
79 +#set ($buttontext = "$!{xcontext.macro.params.buttontext}")
80 +#if ($buttontext == '')
81 + #set ($buttontext = $services.localization.render('xe.attachmentSelector.selectFile'))
82 +#end
83 +
84 +#set ($savemode = "$!{xcontext.macro.params.savemode}")
85 +#if ($savemode != 'direct')
86 + #set ($savemode = 'form')
87 +#end
88 +
89 +#set ($propValue = "$!{doc.getObject($classname, $object).getProperty($property).value}")
90 +##
91 +
92 +#macro (attachmentPicker_displayAttachment $name $displayImage $withLink $forceElement)
93 + #set ($attachment = $targetdoc.getAttachment("$!{name}"))
94 + #if ("$!{name}" != '' && "$!{attachment}" != '')
95 + #set ($attachmentRef = $services.model.createAttachmentReference(${targetdoc.documentReference}, ${name}))
96 + #set ($attachmentName = $name)
97 + #else
98 + #set ($attachmentRef = $defaultReference)
99 + #if ($attachmentRef)
100 + #set ($docReference = $attachmentRef.documentReference)
101 + #else
102 + #set ($docReference = $targetdoc.documentReference)
103 + #end
104 + #set ($attachmentName = $attachmentRef.name)
105 + #set ($attachment = $xwiki.getDocument($docReference).getAttachment($attachmentName))
106 + #if (!$attachment)
107 + #set ($withLink = false)
108 + #end
109 + #end
110 + #if ($attachmentRef)
111 + #set ($attachmentResource = $services.model.serialize($attachmentRef, 'local'))
112 + #else
113 + #set ($attachmentResource = '')
114 + #end
115 + #if ($displayImage)
116 + (% class="$!{cssClass}#if (!$attachment) hidden#end" %)(((#if ("$!{attachmentResource}" != '' || $forceElement)#if($withLink)[[#end[[image:${attachmentResource}$!{imageParams}]]#if($withLink)>>attach:${attachmentResource}||rel=lightbox]]#{end}#end)))##
117 + #else
118 + (% class="$!{cssClass}" %)#if ("$!{attachmentResource}" != '' || $forceElement)#if ($withLink)[[attach:${attachmentResource}||rel=__blank]]#{else}(% class="displayed" %)#if($targetPermView)$!{attachmentName}#{else}Access Denied#{end}(% %)#{end}#end(%%)##
119 + #end
120 +#end
121 +
122 +## Display the "Choose an attachment" button if they can:
123 +## 1. Edit the current page
124 +## 2. View the target attachment page. (can be the same page)
125 +#macro (attachmentPicker_displayButton)
126 + #if ($hasEdit && $targetPermView)
127 + #set ($queryString = {
128 + 'docname': $doc.fullName,
129 + 'classname': $classname,
130 + 'property': $property,
131 + 'object': $object,
132 + 'savemode': $savemode,
133 + 'defaultValue': $defaultValue,
134 + 'filter': $filter,
135 + 'displayImage': $displayImage,
136 + 'versionSummary': $xcontext.macro.params.versionSummary.equals('true')
137 + })
138 + #if ($hasTargetDoc)
139 + #set ($queryString.targetdocname = $targetdoc.fullName)
140 + #end
141 + (% class="buttonwrapper" %)[[$buttontext>>$xcontext.macro.doc.fullName||queryString="$escapetool.url($queryString)"
142 + class="attachment-picker-start button" title="$buttontext"]](%%)##
143 + #end
144 +#end
145 +{{/velocity}}
146 +
147 +{{velocity}}
148 +#if ("${savemode}" == 'direct')
149 + (% class="attachment-picker" %)(((#attachmentPicker_displayAttachment($propValue $displayImage $link true) #attachmentPicker_displayButton())))
150 +#elseif ($xcontext.action == 'inline' || $xcontext.action == 'edit')
151 + (% class="attachment-picker" %)(((##
152 + #attachmentPicker_displayAttachment($propValue $displayImage false true) #attachmentPicker_displayButton()##
153 + {{html}}<input type="hidden" name="${classname}_${object}_${property}" value="${propValue}"/>{{/html}}##
154 + )))
155 +#else
156 + #attachmentPicker_displayAttachment($propValue $displayImage $link false)
157 +#end
158 +{{/velocity}}
Macro content type
... ... @@ -1,0 +1,1 @@
1 +No content
Default category
... ... @@ -1,0 +1,1 @@
1 +Development
Macro description
... ... @@ -1,0 +1,1 @@
1 +A control to be used for object properties of the current document that are supposed to contain the name of an attachment from the current (or target) document. Allows uploading new attachments, and deleting attachments from the target document. If no target document is specified, the current document will be used. Object properties are only saved to the current document.
Macro id
... ... @@ -1,0 +1,1 @@
1 +attachmentSelector
Macro name
... ... @@ -1,0 +1,1 @@
1 +Attachment Selector
Supports inline mode
... ... @@ -1,0 +1,1 @@
1 +Yes
Macro visibility
... ... @@ -1,0 +1,1 @@
1 +Current Wiki
XWiki.WikiMacroParameterClass[0]
Parameter description
... ... @@ -1,0 +1,1 @@
1 +The full name of the document holding the XClass that contains the property associated with this picker.
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +Yes
Parameter name
... ... @@ -1,0 +1,1 @@
1 +classname
XWiki.WikiMacroParameterClass[1]
Parameter description
... ... @@ -1,0 +1,1 @@
1 +The name of the property associated with the picker.
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +Yes
Parameter name
... ... @@ -1,0 +1,1 @@
1 +property
XWiki.WikiMacroParameterClass[2]
Parameter description
... ... @@ -1,0 +1,1 @@
1 +The identifier (number) of the object for which the property is displayed by this picker. If missing, the first instance of the class given by the parameter classname found in the document will be considered.
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +No
Parameter name
... ... @@ -1,0 +1,1 @@
1 +object
XWiki.WikiMacroParameterClass[5]
Parameter description
... ... @@ -1,0 +1,1 @@
1 +A CSS class for the element surrounding the property value.
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +No
Parameter name
... ... @@ -1,0 +1,1 @@
1 +cssClass
XWiki.WikiMacroParameterClass[6]
Parameter default value
... ... @@ -1,0 +1,1 @@
1 +form
Parameter description
... ... @@ -1,0 +1,1 @@
1 +States how the property is updated. Accepted values: "form" (default) meaning that the selected value is stored in an input that will be saved via an external form; "direct" meas that the picker is responsible with updating the property value.
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +No
Parameter name
... ... @@ -1,0 +1,1 @@
1 +savemode
XWiki.WikiMacroParameterClass[7]
Parameter description
... ... @@ -1,0 +1,1 @@
1 +Text of the button that triggers the picker. Defaults to $services.localization.render('xe.attachmentSelector.selectFile').
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +No
Parameter name
... ... @@ -1,0 +1,1 @@
1 +buttontext
XWiki.WikiMacroParameterClass[10]
Parameter description
... ... @@ -1,0 +1,1 @@
1 +What attachment is displayed in view mode if the property is empty. Should either be empty or in the form of a wiki attachment reference (e.g. "attachment.txt", "Another.Document@attachment.txt").
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +No
Parameter name
... ... @@ -1,0 +1,1 @@
1 +defaultValue
XWiki.WikiMacroParameterClass[12]
Parameter description
... ... @@ -1,0 +1,1 @@
1 +Comma separated list of file extensions accepted by the property (to become a comma separated list of mimetypes when XWiki will use HTML5). All files are accepted if this parameter is empty.
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +No
Parameter name
... ... @@ -1,0 +1,1 @@
1 +filter
XWiki.WikiMacroParameterClass[13]
Parameter default value
... ... @@ -1,0 +1,1 @@
1 +false
Parameter description
... ... @@ -1,0 +1,1 @@
1 +States whether images are displayed or just their name is printed like for other attachments. Possible values: true, false (default).
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +No
Parameter name
... ... @@ -1,0 +1,1 @@
1 +displayImage
XWiki.WikiMacroParameterClass[14]
Parameter description
... ... @@ -1,0 +1,1 @@
1 +The width of the displayed image, only taken into account if displayImage=true.
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +No
Parameter name
... ... @@ -1,0 +1,1 @@
1 +width
XWiki.WikiMacroParameterClass[15]
Parameter description
... ... @@ -1,0 +1,1 @@
1 +The height of the displayed image, only taken into account if displayImage=true
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +No
Parameter name
... ... @@ -1,0 +1,1 @@
1 +height
XWiki.WikiMacroParameterClass[16]
Parameter description
... ... @@ -1,0 +1,1 @@
1 +The alternate text of the displayed image, only taken into account if displayImage=true
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +No
Parameter name
... ... @@ -1,0 +1,1 @@
1 +alternateText
XWiki.WikiMacroParameterClass[17]
Parameter default value
... ... @@ -1,0 +1,1 @@
1 +false
Parameter description
... ... @@ -1,0 +1,1 @@
1 +States whether a link to the attachment is associated in view mode with the displayed attachment name/image. Possible values: true, false (default).
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +No
Parameter name
... ... @@ -1,0 +1,1 @@
1 +link
XWiki.WikiMacroParameterClass[18]
Parameter description
... ... @@ -1,0 +1,1 @@
1 +The target document name to save/list attachments from
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +No
Parameter name
... ... @@ -1,0 +1,1 @@
1 +targetdocname
XWiki.WikiMacroParameterClass[19]
Parameter default value
... ... @@ -1,0 +1,1 @@
1 +false
Parameter description
... ... @@ -1,0 +1,1 @@
1 +Whether to allow the user to enter a version summary that will be recorded in the history. An automatic message is used when no version summary is provided or if the version summary input is not displayed.
Parameter mandatory
... ... @@ -1,0 +1,1 @@
1 +No
Parameter name
... ... @@ -1,0 +1,1 @@
1 +versionSummary

Tips

Did you know that you can improve XWiki? Take 5 minutes to fill this survey and help this open source project!

Need help?

If you need help with XWiki you can contact: