Changes for page Main

Last modified by Administrator on 2023/03/27 10:53

From version 5.1
edited by Administrator
on 2020/12/29 00:17
Change comment: Install extension [org.xwiki.platform:xwiki-platform-appwithinminutes-ui/12.10.2]
To version 1.1
edited by Administrator
on 2018/07/24 00:25
Change comment: Install extension [org.xwiki.platform:xwiki-platform-appwithinminutes-ui/9.11.7]

Summary

Details

Page properties
Title
... ... @@ -1,1 +1,1 @@
1 -#if ("$!appTitle" != '')$appTitle#else$doc.pageReference.name#end
1 +#if(!$doc.name.endsWith('Sheet'))$services.localization.render('appWithinMinutes.classEditor.title', [$stringtool.removeEnd($doc.title, 'Class').trim()])#{else}$doc.name#end
Syntax
... ... @@ -1,1 +1,1 @@
1 -XWiki 2.1
1 +XWiki 2.0
Content
... ... @@ -1,5 +3,3 @@
1 -{{include reference="AppWithinMinutes.VelocityMacros" /}}
2 -
3 3  {{groovy}}
4 4  import com.xpn.xwiki.XWikiContext;
5 5  import com.xpn.xwiki.api.Context;
... ... @@ -54,101 +54,95 @@
54 54  #**
55 55   * Displays the field palette.
56 56   *#
57 -#macro (displayFieldPalette)
58 - <div id="palette">
59 - <p><strong>$services.localization.render('platform.appwithinminutes.classEditorPaletteTitle')</strong></p>
60 - <p class="xHint">$services.localization.render('platform.appwithinminutes.classEditorPaletteHint')</p>
55 +#macro(displayFieldPalette)
56 + (% id="palette" %)
57 + (((
58 + **$services.localization.render('platform.appwithinminutes.classEditorPaletteTitle')**
59 +
60 + (% class="xHint" %)
61 + $services.localization.render('platform.appwithinminutes.classEditorPaletteHint')
62 +
61 61   ## List all form field types, grouped by category.
62 - #set ($formFieldDocs = [])
63 - #set ($formFieldClassName = 'AppWithinMinutes.FormFieldClass')
64 - #set ($categoryListStatement = 'from doc.object(AppWithinMinutes.FormFieldCategoryClass) as category order by category.priority')
65 - <ul>
66 - #foreach ($category in $services.query.xwql($categoryListStatement).execute())
67 - #set ($categoryDoc = $xwiki.getDocument($category))
68 - <li>
69 - <div class="category">$categoryDoc.plainTitle</div>
70 - #set ($formFieldsForCategoryStatement = "from doc.object($formFieldClassName) as field where field.category = :category order by field.priority")
71 - #set ($formFieldsForCategoryQuery = $services.query.xwql($formFieldsForCategoryStatement).bindValue('category', $category))
72 - <ul>
73 - #foreach ($formField in $formFieldsForCategoryQuery.execute())
74 - #set ($formFieldDoc = $xwiki.getDocument($formField))
75 - #set ($discard = $formFieldDocs.add($formFieldDoc))
76 - #set ($formFieldIcon = $formFieldDoc.getObject($formFieldClassName).getProperty('icon').value)
77 - #set ($formFieldIconRendered = $services.icon.renderHTML($formFieldIcon))
78 - #if ("$!formFieldIconRendered" == "")
79 - #if ($formFieldIcon.contains('/'))
80 - #set ($formFieldIconURL = $xwiki.getSkinFile($formFieldIcon))
81 - #else
82 - #set ($formFieldIconURL = $formFieldDoc.getAttachmentURL($formFieldIcon))
83 - #end
84 - #set ($formFieldIconRendered = "<img src='$formFieldIconURL' alt='$escapetool.xml($formFieldDoc.plainTitle)' class='icon' />")
64 + #set($formFieldDocs = [])
65 + #set($formFieldClassName = 'AppWithinMinutes.FormFieldClass')
66 + #set($categoryListStatement = 'from doc.object(AppWithinMinutes.FormFieldCategoryClass) as category order by category.priority')
67 + #foreach($category in $services.query.xwql($categoryListStatement).execute())
68 + #set($categoryDoc = $xwiki.getDocument($category))
69 + * (% class="category" %)$categoryDoc.plainTitle
70 + #set($formFieldsForCategoryStatement = "from doc.object($formFieldClassName) as field where field.category = :category order by field.priority")
71 + #set($formFieldsForCategoryQuery = $services.query.xwql($formFieldsForCategoryStatement).bindValue('category', $category))
72 + #foreach($formField in $formFieldsForCategoryQuery.execute())
73 + #set($formFieldDoc = $xwiki.getDocument($formField))
74 + #set($discard = $formFieldDocs.add($formFieldDoc))
75 + #set($formFieldIcon = $formFieldDoc.getObject($formFieldClassName).getProperty('icon').value)
76 + #if($formFieldIcon.contains('/'))
77 + #set($formFieldIconURL = $xwiki.getSkinFile($formFieldIcon))
78 + #else
79 + #set($formFieldIconURL = $formFieldDoc.getAttachmentURL($formFieldIcon))
85 85   #end
86 - <li class="field">
87 - $formFieldIconRendered
88 - $escapetool.xml($formFieldDoc.plainTitle)
89 - ## FIXME: We should use the 'get' action instead to prevent the stats module from recording this AJAX request.
90 - ## The 'edit' action is a temporary solution until the sheet module is modified to allow a sheet to be enforced through
91 - ## the query string even if it doesn't match the action (e.g. the 'get' action).
92 - ## The sheet parameter is required when editing a new class because the request will be made to a document that doesn't exist.
93 - ## FIXME2: In the future don't force the text editor type and instead use the default editor. This means
94 - ## that if the WYSIWYG editor is used, we'll need to convert the HTML into the target syntax so that the
95 - ## Template in #updateAndSaveTemplate is saved with target syntax and not HTML.
96 - ## See https://jira.xwiki.org/browse/XWIKI-13789
97 - #set ($fieldURL = $doc.getURL('edit', $escapetool.url({
98 - 'xpage': 'plain',
99 - 'sheet': 'AppWithinMinutes.ClassEditSheet',
100 - 'template': 'AppWithinMinutes.ClassTemplate',
101 - 'field': $formFieldDoc.fullName,
102 - 'xeditmode': 'text'
103 - })))
104 - <input type="hidden" value="$fieldURL" class="data"/>
105 - </li>
81 + ** (% class="field" %){{html}}
82 + <img src="$formFieldIconURL" alt="$escapetool.xml($formFieldDoc.plainTitle)" class="icon" />
83 + $escapetool.xml($formFieldDoc.plainTitle)
84 + ## FIXME: We should use the 'get' action instead to prevent the stats module from recording this AJAX request.
85 + ## The 'edit' action is a temporary solution until the sheet module is modified to allow a sheet to be enforced through
86 + ## the query string even if it doesn't match the action (e.g. the 'get' action).
87 + ## The sheet parameter is required when editing a new class because the request will be made to a document that doesn't exist.
88 + ## FIXME2: In the future don't force the text editor type and instead use the default editor. This means
89 + ## that if the WYSIWYG editor is used, we'll need to convert the HTML into the target syntax so that the
90 + ## Template in #updateAndSaveTemplate is saved with target syntax and not HTML.
91 + ## See https://jira.xwiki.org/browse/XWIKI-13789
92 + <input type="hidden" value="$doc.getURL('edit', "xpage=plain&sheet=AppWithinMinutes.ClassEditSheet&field=$escapetool.url($formFieldDoc.fullName)&xeditmode=text")" class="data"/>
93 + {{/html}}
106 106   #end
107 - </ul>
108 - </li>
109 109   #end
110 - </ul>
111 - </div>
96 + )))
112 112  #end
113 113  
114 114  #**
115 115   * Displays the field canvas.
116 116   *#
117 -#macro (displayFieldCanvas)
118 - #set ($propertyType2FormField = {})
119 - #foreach ($formFieldDoc in $formFieldDocs)
102 +#macro(displayFieldCanvas)
103 + #set($propertyType2FormField = {})
104 + #foreach($formFieldDoc in $formFieldDocs)
120 120   ## Use the type of the field template.
121 - #set ($type = $formFieldDoc.getxWikiClass().properties.get(0).classType)
122 - #set ($discard = $propertyType2FormField.put($type, $formFieldDoc))
106 + #set($type = $formFieldDoc.getxWikiClass().properties.get(0).classType)
107 + #set($discard = $propertyType2FormField.put($type, $formFieldDoc))
123 123   #end
124 - <div id="canvas">
125 - <p class="hint">
126 - $services.localization.render('platform.appwithinminutes.classEditorCanvasHint')
127 - </p>
128 - <ul>
129 - #set ($unknownFields = [])
130 - #foreach ($field in $doc.getxWikiClass().properties)
131 - #set ($formFieldDoc = $propertyType2FormField.get($field.classType))
132 - #if ($formFieldDoc)
133 - <li>#displayField($field $formFieldDoc)</li>
134 - #else
135 - #set($discard = $unknownFields.add($field))
136 - #end
109 + (% id="canvas" %)
110 + (((
111 + (% class="hint" %)
112 + $services.localization.render('platform.appwithinminutes.classEditorCanvasHint')
113 +
114 + #set($unknownFields = [])
115 + #set($empty = true)
116 + #foreach ($field in $doc.getxWikiClass().properties)
117 + #set($formFieldDoc = $propertyType2FormField.get($field.classType))
118 + #if($formFieldDoc)
119 + #set($empty = false)
120 + * (((#displayField($field $formFieldDoc))))
121 + #else
122 + #set($discard = $unknownFields.add($field))
137 137   #end
138 - </ul>
139 - <div class="hidden">
124 + #end
125 + #if(!$empty)
126 + ## Leave an empty line to separate the blocks.
127 +
128 + #end
129 + ##
130 + (% class="hidden" %)
131 + {{html}}
140 140   ## Output the field meta data even if the field is not supported to preserve it when the class is saved.
141 - #foreach ($field in $unknownFields)
133 + #foreach($field in $unknownFields)
142 142   #displayFieldMetaData($field)
143 143   #end
144 - </div>
145 - </div>
136 + {{/html}}
137 + )))
146 146  #end
147 147  
148 148  #**
149 149   * Display the options to create/update the class template, the class sheet and the class translation bundle.
150 150   *#
151 -#macro (displayClassOptions)
143 +#macro(displayClassOptions)
152 152   #set ($className = $stringtool.removeEnd($doc.fullName, 'Class'))
153 153   #set ($templateReference = $services.model.resolveDocument("${className}Template"))
154 154   #set ($translationsReference = $services.model.resolveDocument("${className}Translations"))
... ... @@ -159,6 +159,7 @@
159 159   #elseif ($classSheets.size() == 1)
160 160   #set ($sheetReference = $classSheets.get(0))
161 161   #end
154 + {{html}}
162 162   ## Hide the options if neither the sheet nor the template nor the translation bundle exists. They don't have to be
163 163   ## updated, they have to be created.
164 164   <dl id="options" #if (!$xwiki.exists($sheetReference) && !$xwiki.exists($templateReference)
... ... @@ -207,6 +207,7 @@
207 207   </span>
208 208   </dd>
209 209   </dl>
203 + {{/html}}
210 210  #end
211 211  
212 212  #macro (pageLink $reference)
... ... @@ -218,56 +218,58 @@
218 218   #set ($action = 'create')
219 219   #set ($discard = $params.put('parent', $doc.fullName))
220 220   #end
221 - <span class="$class"><a href="$escapetool.xml($xwiki.getURL($reference, $action, $escapetool.url($params)))"
222 - >$escapetool.xml($reference.name)</a></span>##
215 + <span class="$class">##
216 + <a href="$escapetool.xml($xwiki.getURL($reference, $action, $escapetool.url($params)))">##
217 + $escapetool.xml($reference.name)##
218 + </a>##
219 + </span>##
223 223  #end
224 224  
225 225  #**
226 226   * Display a form field.
227 227   *#
228 -#macro (displayField $field $formFieldDoc)
229 - #if ($formFieldDoc.getObject('XWiki.StyleSheetExtension'))
230 - #set ($discard = $xwiki.ssx.use($formFieldDoc.fullName))
225 +#macro(displayField $field $formFieldDoc)
226 + #if($formFieldDoc.getObject('XWiki.StyleSheetExtension'))
227 + #set($discard = $xwiki.ssx.use($formFieldDoc.fullName))
231 231   #end
232 - #if ($formFieldDoc.getObject('XWiki.JavaScriptExtension'))
233 - #set ($discard = $xwiki.jsx.use($formFieldDoc.fullName))
229 + #if($formFieldDoc.getObject('XWiki.JavaScriptExtension'))
230 + #set($discard = $xwiki.jsx.use($formFieldDoc.fullName))
234 234   #end
235 - <div class="hidden">
232 + (% class="hidden" %)
233 + {{html}}
236 236   #displayFieldMetaData($field)
237 237   ## We need this information to avoid querying and loading all FormField documents twice.
238 238   ## NOTE: We use a different ID format to avoid collisions with the field meta properties.
239 - <input type="hidden" id="template-$field.name" name="template-$field.name"
240 - value="$escapetool.xml($formFieldDoc.fullName)"
241 - data-propertyName="$escapetool.xml($formFieldDoc.getxWikiClass().propertyNames[0])" />
242 - </div>
243 - #set ($className = $stringtool.removeEnd($doc.fullName, 'Class'))
244 - #set ($templateRef = $services.model.resolveDocument("${className}Template"))
245 - #set ($templateDoc = $xwiki.getDocument($templateRef))
237 + <input type="hidden" id="template-$field.name" name="template-$field.name" value="$escapetool.xml($formFieldDoc.fullName)" />
238 + {{/html}}
239 +
240 + #set($className = $stringtool.removeEnd($doc.fullName, 'Class'))
241 + #set($templateRef = $services.model.resolveDocument("${className}Template"))
242 + #set($templateDoc = $xwiki.getDocument($templateRef))
246 246   ## Simulate the editing of the class instance from the template document.
247 247   ## Note that we can't simply call display on the template document because $field could be a new field that hasn't
248 248   ## been added to the class yet (so the object from the template doesn't have this field yet).
249 - <dl class="field-viewer">
250 - #displayFieldProperty($field "${doc.fullName}_0_" $templateDoc.getObject($doc.fullName, true))
251 - </dl>
252 - #set ($propertyNames = ['name', 'prettyName', 'number', 'required', 'hint'])
253 - #set ($formFieldObj = $formFieldDoc.getObject('AppWithinMinutes.FormFieldClass'))
254 - #set ($customPropertyNames = $formFieldObj.getProperty('properties').value.split('\s+'))
255 - #set ($discard = $customPropertyNames.removeAll($propertyNames))
256 - #set ($discard = $propertyNames.addAll($customPropertyNames.subList(0, $customPropertyNames.size())))
257 - <dl class="field-config">
258 - #foreach ($propertyName in $propertyNames)
259 - #set ($propertyDefinition = $field.xWikiClass.get($propertyName))
260 - #if ($propertyDefinition)
261 - #displayFieldProperty($propertyDefinition "field-${field.name}_" $field)
262 - #end
246 + (% class="field-viewer" %)
247 + #displayFieldProperty($field "${doc.fullName}_0_" $templateDoc.getObject($doc.fullName, true))
248 +
249 + #set($propertyNames = ['name', 'prettyName', 'number', 'required', 'hint'])
250 + #set($formFieldObj = $formFieldDoc.getObject('AppWithinMinutes.FormFieldClass'))
251 + #set($customPropertyNames = $formFieldObj.getProperty('properties').value.split('\s+'))
252 + #set($discard = $customPropertyNames.removeAll($propertyNames))
253 + #set($discard = $propertyNames.addAll($customPropertyNames.subList(0, $customPropertyNames.size())))
254 + (% class="field-config" %)
255 + #foreach($propertyName in $propertyNames)
256 + #set($propertyDefinition = $field.xWikiClass.get($propertyName))
257 + #if($propertyDefinition)
258 + #displayFieldProperty($propertyDefinition "field-${field.name}_" $field)
263 263   #end
264 - </dl>
260 + #end
265 265  #end
266 266  
267 267  #**
268 268   * Display the field meta data. This is needed to preserve the field when its type is not supported by the editor.
269 269   *#
270 -#macro (displayFieldMetaData $field)
266 +#macro(displayFieldMetaData $field)
271 271   <input type="hidden" id="type-$field.name" name="type-$field.name" value="$field.classType" />
272 272  #end
273 273  
... ... @@ -274,18 +274,13 @@
274 274  #**
275 275   * Displays a configuration property of a class field. This macro can also be used to display a property of an object.
276 276   *#
277 -#macro (displayFieldProperty $property $prefix $field)
278 - #set ($displayFormType = $property.getProperty('displayFormType'))
279 - #if ($property.classType == 'Boolean' && (!$displayFormType || $displayFormType.value == 'checkbox'))
280 - <dt>
281 - <label for="$!{prefix}$property.name">
282 - #displayPropertyEditInput($property, $prefix, $field)$escapetool.xml($property.prettyName)
283 - </label>
284 - </dt>
285 - <dd></dd>
273 +#macro(displayFieldProperty $property $prefix $field)
274 + #set($displayFormType = $property.getProperty('displayFormType'))
275 + #if($property.classType == 'Boolean' && (!$displayFormType || $displayFormType.value == 'checkbox'))
276 + ; {{html clean="false"}}<label for="$!{prefix}$property.name">#displayPropertyEditInput($property, $prefix, $field)$escapetool.xml($property.prettyName)</label>{{/html}}
286 286   #else
287 - <dt><label for="${prefix}$property.name">$escapetool.xml($property.prettyName)</label></dt>
288 - <dd>#displayPropertyEditInput($property, $prefix, $field)</dd>
278 + ; {{html}}<label for="${prefix}$property.name">$escapetool.xml($property.prettyName)</label>{{/html}}
279 + : {{html clean="false"}}#displayPropertyEditInput($property, $prefix, $field){{/html}}
289 289   #end
290 290  #end
291 291  
... ... @@ -292,18 +292,12 @@
292 292  #**
293 293   * Displays the input used to edit the specified property of the given object. The given object can be either an
294 294   * instance of an XWiki class or a class field. In the first case the property represents an object field and in the
295 - * second case the property represents a field meta property. We currently don't use custom display for metaproperty,
296 - * so in that case we fallback on displayEdit.
286 + * second case the property represents a field meta property.
297 297   *#
298 -#macro (displayPropertyEditInput $property $prefix $object)
299 - #set ($wrappedProperty = $property.propertyClass)
300 - #if ($wrappedProperty.isCustomDisplayed($xcontext.context))
301 - #set ($customDisplayer = $!xcontext.get('propertyCustomDisplayer').display($property, $prefix, $object))
302 - #if ((! $customDisplayer) && ("$!customDisplayer" == ""))
303 - $doc.displayEdit($property, $prefix, $object)
304 - #else
305 - $customDisplayer
306 - #end
288 +#macro(displayPropertyEditInput $property $prefix $object)
289 + #set($wrappedProperty = $property.propertyClass)
290 + #if($wrappedProperty.isCustomDisplayed($xcontext.context))
291 + $xcontext.get('propertyCustomDisplayer').display($property, $prefix, $object)
307 307   #else
308 308   $doc.displayEdit($property, $prefix, $object)
309 309   #end
... ... @@ -312,23 +312,22 @@
312 312  #**
313 313   * Called when a new form field is added via AJAX.
314 314   *#
315 -#macro (displayNewField)
300 +#macro(displayNewField)
316 316   ## Output the SkinExtension hooks to allow field displayers to pull JavaScript/CSS resources.
317 - ## Output also the LinkExtension hook because $xwiki.linkx.use() is used to load CSS files from WebJars.
318 318   ## The class editor moves this resource includes in the HTML page head.
319 - <!-- com.xpn.xwiki.plugin.skinx.LinkExtensionPlugin -->
303 + {{html}}
320 320   #skinExtensionHooks
321 - #set ($formFieldDoc = $xwiki.getDocument($request.field))
322 - #set ($formFieldDocClassFields = $formFieldDoc.getxWikiClass().getXWikiClass().properties)
323 - #if ($formFieldDocClassFields.size() > 0)
305 + {{/html}}
306 +
307 + #set($formFieldDoc = $xwiki.getDocument($request.field))
308 + #set($formFieldDocClassFields = $formFieldDoc.getxWikiClass().getXWikiClass().properties)
309 + #if($formFieldDocClassFields.size() > 0)
324 324   ## Clone the field template.
325 - #set ($field = $formFieldDocClassFields.get(0).clone())
326 - #if ("$!field.prettyName" == '')
327 - #set ($discard = $field.setPrettyName($formFieldDoc.title))
311 + #set($field = $formFieldDocClassFields.get(0).clone())
312 + #if("$!field.prettyName" == '')
313 + #set($discard = $field.setPrettyName($formFieldDoc.title))
328 328   #end
329 - #set ($xclass = $doc.getxWikiClass().getXWikiClass())
330 - #set ($discard = $xclass.addField($field.name, $field))
331 - #set ($discard = $field.setObject($xclass))
315 + #set($discard = $doc.getxWikiClass().getXWikiClass().addField($field.name, $field))
332 332   #displayField($doc.getxWikiClass().get($field.name) $formFieldDoc)
333 333   #else
334 334   Unsupported form field.
... ... @@ -338,92 +338,88 @@
338 338  #**
339 339   * Preview a class field (requires Programming Right).
340 340   *#
341 -#macro (previewField)
325 +#macro(previewField)
342 342   ## Find the request parameter that specifies the field template.
343 - #foreach ($paramName in $request.getParameterMap().keySet())
344 - #if ($paramName.startsWith('template-'))
345 - #set ($fieldName = $paramName.substring(9))
346 - #set ($fieldTemplateDoc = $xwiki.getDocument($request.getParameter($paramName)))
327 + #foreach($paramName in $request.getParameterMap().keySet())
328 + #if($paramName.startsWith('template-'))
329 + #set($fieldName = $paramName.substring(9))
330 + #set($fieldTemplateDoc = $xwiki.getDocument($request.getParameter($paramName)))
347 347   #break
348 348   #end
349 349   #end
350 350   ##
351 351   ## Clone the field template.
352 - #set ($field = $fieldTemplateDoc.getxWikiClass().getXWikiClass().properties.get(0).clone())
336 + #set($field = $fieldTemplateDoc.getxWikiClass().getXWikiClass().properties.get(0).clone())
353 353   ##
354 354   ## Update the field meta properties based on the submitted data.
355 - #set ($valuesFromRequest = $xcontext.context.getForm().getObject("field-$fieldName"))
356 - #set ($discard = $field.getxWikiClass().fromMap($valuesFromRequest, $field))
339 + #set($valuesFromRequest = $xcontext.context.getForm().getObject("field-$fieldName"))
340 + #set($discard = $field.getxWikiClass().fromMap($valuesFromRequest, $field))
357 357   ##
358 358   ## Don't rename the field (ignore the submitted name).
359 - #set ($discard = $field.setName($fieldName))
343 + #set($discard = $field.setName($fieldName))
360 360   ##
361 361   ## We have to add the field to the class before setting its value.
362 362   ## (otherwise the field value from the request is ignored).
363 - #set ($xclass = $doc.getxWikiClass().getXWikiClass())
364 - #set ($discard = $xclass.addField($fieldName, $field))
365 - #set ($discard = $field.setObject($xclass))
347 + #set($xclass = $doc.getxWikiClass().getXWikiClass())
348 + #set($discard = $xclass.addField($fieldName, $field))
366 366   ##
367 367   ## Create an object that has this field and set its value from request.
368 - #set ($object = $fieldTemplateDoc.getObject($doc.fullName, true))
351 + #set($object = $fieldTemplateDoc.getObject($doc.fullName, true))
369 369   ##
370 370   ## Filter empty values from the request, otherwise the update method could try to select an invalid value.
371 - #set ($values = [])
372 - #foreach ($value in $request.getParameterValues("${doc.fullName}_0_$fieldName"))
373 - #if ($value != '')
374 - #set ($discard = $values.add($value))
354 + #set($values = [])
355 + #foreach($value in $request.getParameterValues("${doc.fullName}_0_$fieldName"))
356 + #if($value != '')
357 + #set($discard = $values.add($value))
375 375   #end
376 376   #end
377 - #if ($values.size() > 0)
378 - #set ($stringArray = $request.getParameterValues("template-$fieldName"))
379 - #set ($discard = $xclass.fromMap({$fieldName: $values.toArray($stringArray)}, $object.getXWikiObject()))
360 + #if($values.size() > 0)
361 + #set($stringArray = $request.getParameterValues("template-$fieldName"))
362 + #set($discard = $xclass.fromMap({$fieldName: $values.toArray($stringArray)}, $object.getXWikiObject()))
380 380   #end
381 381   ##
382 - ## Display the field.
383 - #set ($field = $doc.getxWikiClass().get($fieldName))
384 - #displayPropertyEditInput($field, "${doc.fullName}_0_", $object)
365 + ## Display the field (with the rights of the current user).
366 + #set($field = $doc.getxWikiClass().get($fieldName))
367 + ## Note that we don't modify the cached document because the previous line has cloned it.
368 + #set ($discard = $doc.document.setAuthorReference($xcontext.userReference))
369 + {{html clean="false"}}#displayPropertyEditInput($field, "${doc.fullName}_0_", $object){{/html}}
385 385  #end
386 386  
387 387  #**
388 388   * Display the edit class form.
389 389   *#
390 -#macro (displayEditForm)
391 - #set ($discard = $xwiki.jsfx.use('js/scriptaculous/effects.js'))
392 - #set ($discard = $xwiki.jsfx.use('js/scriptaculous/dragdrop.js'))
393 - #set ($discard = $xwiki.jsx.use('AppWithinMinutes.ClassEditSheet'))
394 - #set ($discard = $xwiki.ssx.use('AppWithinMinutes.ClassEditSheet'))
395 - #set ($discard = $xwiki.ssx.use('AppWithinMinutes.ClassSheetGenerator'))
396 - #if ("$!request.wizard" == 'true')
375 +#macro(displayEditForm)
376 + $xwiki.jsfx.use('js/scriptaculous/dragdrop.js')##
377 + $xwiki.jsx.use('AppWithinMinutes.ClassEditSheet')##
378 + $xwiki.ssx.use('AppWithinMinutes.ClassEditSheet')##
379 + $xwiki.ssx.use('AppWithinMinutes.ClassSheetGenerator')##
380 + #if("$!request.wizard" == 'true')
397 397   #appWizardHeader('structure')
382 +
398 398   #end
399 399   #displayFieldPalette()
400 400   #displayFieldCanvas()
401 401   #displayClassOptions()
402 402   #if("$!request.wizard" == 'true')
388 +
403 403   #appWizardFooter('structure')
404 404   #end
405 - <div class="clearfloats"></div>
391 + (% class="clearfloats" %)((()))
406 406  #end
407 407  
408 408  #**
409 409   * Displays either the edit class form or a new form field. The later is used when adding a new form field via AJAX.
410 410   *#
411 -#macro (doEdit)
412 - #if ("$!request.field" != '')
397 +#macro(doEdit)
398 + #if("$!request.field" != '')
413 413   #displayNewField()
414 - #elseif ("$!request.preview" == 'true')
400 + #elseif("$!request.preview" == 'true')
415 415   #previewField()
416 416   #else
417 417   ## Make sure that only the sheet content is rendered when the class is saved using AJAX.
418 - <div class="hidden">
419 - <input type="hidden" name="xpage" value="plain" />
420 - #if ($request.wizard == 'true')
421 - ## Preserve the wizard mode.
422 - <input type="hidden" name="wizard" value="true" />
423 - #end
424 - ## Compute the application title to be used as the wizard step title.
425 - #getAppTitle
426 - </div>
404 + (% class="hidden" %)
405 + {{html}}<input type="hidden" name="xpage" value="plain" />{{/html}}
406 +
427 427   #displayEditForm()
428 428   #end
429 429  #end
... ... @@ -439,7 +439,10 @@
439 439   #try()
440 440   #set ($discard = $copyAsJob.join())
441 441   #set ($copyAsJobStatus = $services.job.getJobStatus($copyAsJob.request.id))
442 - #set ($errorMessage = $copyAsJobStatus.logTail.getFirstLogEvent('ERROR').toString())
422 + #set ($errorLogs = $copyAsJobStatus.log.getLogs('ERROR'))
423 + #if ($errorLogs.size() > 0)
424 + #set ($errorMessage = $errorLogs.get(0).toString())
425 + #end
443 443   #end
444 444   #end
445 445  #end
... ... @@ -578,7 +578,7 @@
578 578   #set($className = $stringtool.removeEnd($doc.fullName, 'Class'))
579 579   #set($templateRef = $services.model.resolveDocument("${className}Template"))
580 580   #set($templateDoc = $xwiki.getDocument($templateRef))
581 - #set($discard = $templateDoc.setParent($doc.documentReference.name))
564 + #set($discard = $templateDoc.setParent($doc.name))
582 582   #if ($request.templateTitle)
583 583   #set($discard = $templateDoc.setTitle($request.templateTitle))
584 584   #end
... ... @@ -616,13 +616,9 @@
616 616   #if($sheetReference)
617 617   #set($sheetDoc = $xwiki.getDocument($sheetReference))
618 618   #set($sheetGeneratorDoc = $xwiki.getDocument('AppWithinMinutes.ClassSheetGenerator'))
619 - #set($discard = $sheetDoc.setParent($doc.documentReference.name))
602 + #set($discard = $sheetDoc.setParent($doc.name))
620 620   #set($discard = $sheetDoc.setContent($doc.getRenderedContent($sheetGeneratorDoc.content,
621 621   $sheetGeneratorDoc.syntax.toIdString(), 'plain/1.0')))
622 - ## We assume for now that the output produced by the sheet generator uses the same syntax as the code of the sheet
623 - ## generator. We have to set the syntax because the default wiki syntax (used when creating new wiki pages) could
624 - ## be different than the one used by the sheet generator.
625 - #set($discard = $sheetDoc.setSyntax($sheetGeneratorDoc.syntax))
626 626   #set($discard = $sheetDoc.setHidden(true))
627 627   #set($discard = $sheetDoc.save($services.localization.render('platform.appwithinminutes.classEditorSheetSaveComment'),
628 628   $minorEdit))
... ... @@ -644,11 +644,10 @@
644 644   #set ($scope = 'WIKI')
645 645   #end
646 646   #set($discard = $translationsObj.set('scope', $scope))
647 - #set($discard = $translationsDoc.setParent($doc.documentReference.name))
626 + #set($discard = $translationsDoc.setParent($doc.name))
648 648   #set($translationsGeneratorDoc = $xwiki.getDocument('AppWithinMinutes.ClassTranslationsGenerator'))
649 649   #set($discard = $translationsDoc.setContent($doc.getRenderedContent($translationsGeneratorDoc.content,
650 650   $translationsGeneratorDoc.syntax.toIdString(), 'plain/1.0')))
651 - #set($discard = $translationsDoc.setSyntaxId('plain/1.0'))
652 652   #set($discard = $translationsDoc.setHidden(true))
653 653   #set($discard = $translationsDoc.save(
654 654   $services.localization.render('platform.appwithinminutes.classEditorTranslationsSaveComment'),
... ... @@ -659,17 +659,17 @@
659 659  #**
660 660   * Updates and saves the class definition, the class sheet and the class template.
661 661   *#
662 -#macro (doSave)
663 - #set ($minorEdit = "$!request.minorEdit" != '')
640 +#macro(doSave)
641 + #set($minorEdit = "$!request.minorEdit" != '')
664 664   #maybeCreateCodeSpace
665 665   #updateAndSaveClass
666 666   #updateAndSaveTemplate
667 667   #updateAndSaveSheet
668 668   #updateAndSaveTranslations
669 - #if ($action == 'save')
670 - #if ($errorMessage)
671 - <div class="box errormessage">$errorMessage</div>
672 - #elseif ("$!request.wizard" == 'true')
647 + #if($action == 'save')
648 + #if($errorMessage)
649 + {{error}}{{html}}$errorMessage{{/html}}{{/error}}
650 + #elseif("$!request.wizard" == 'true')
673 673   ## Redirect to next wizard step.
674 674   #set ($className = $stringtool.removeEnd($doc.fullName, 'Class'))
675 675   #set ($templateProviderReference = $services.model.resolveDocument("${className}TemplateProvider"))
... ... @@ -689,7 +689,7 @@
689 689   $response.sendRedirect($doc.getURL())
690 690   #end
691 691   #else
692 - #if ($errorMessage)
670 + #if($errorMessage)
693 693   $response.sendError(400, $errorMessage)
694 694   #else
695 695   $response.setStatus(204)
... ... @@ -705,23 +705,21 @@
705 705  {{/velocity}}
706 706  
707 707  {{velocity}}
708 -{{html clean="false"}}
709 709  ## Determine the action button that triggered the request
710 -#set ($action = 'edit')
711 -#foreach ($paramName in $request.getParameterMap().keySet())
712 - #if ($paramName.startsWith('xaction_'))
713 - #set ($action = $paramName.substring(8))
687 +#set($action = 'edit')
688 +#foreach($paramName in $request.getParameterMap().keySet())
689 + #if($paramName.startsWith('xaction_'))
690 + #set($action = $paramName.substring(8))
714 714   #break
715 715   #end
716 716  #end
717 -#if ($action == 'edit')
694 +#if($action == 'edit')
718 718   #doEdit()
719 -#elseif ($action == 'save' || $action == 'saveandcontinue')
720 - #if ($services.csrf.isTokenValid($request.form_token))
696 +#elseif($action == 'save' || $action == 'saveandcontinue')
697 + #if($services.csrf.isTokenValid($request.form_token))
721 721   #doSave()
722 722   #else
723 - $response.sendRedirect($services.csrf.getResubmissionURL())
700 + $response.sendRedirect($services.csrf.getResubmissionURL());
724 724   #end
725 725  #end
726 -{{/html}}
727 727  {{/velocity}}
XWiki.JavaScriptExtension[2]
Code
... ... @@ -367,11 +367,7 @@
367 367   hintInput.title = 'Hint';
368 368   }
369 369   // Move the hint input below the pretty name input, in the field viewer.
370 - var dd = hintInput.up('dd');
371 - var dt = dd.previous('dt');
372 372   field.getViewer().down('label').insert({after: hintInput});
373 - dt.remove();
374 - dd.remove();
375 375   // Enhance the hint input.
376 376   new XWiki.InputWithTitle(hintInput);
377 377   new XWiki.AutoResizeInput(hintInput);
... ... @@ -430,7 +430,7 @@
430 430   });
431 431   },
432 432   _onDrop : function(field) {
433 - var fieldContainer = new Element('li', {'data-new': 'true'});
429 + var fieldContainer = new Element('li');
434 434   this.fields.insert(fieldContainer);
435 435   this.container.removeClassName('empty');
436 436   new XWiki.FormField(fieldContainer).enhance(field.down('.data').value);
... ... @@ -520,10 +520,10 @@
520 520   if (!form) {
521 521   return false;
522 522   }
523 - // Let the sheet handle the form submit. The form is submitted by default to the preview action which dispatches the
524 - // request to the save action if the save button is detected on the request parameters. By submitting to the edit
525 - // action the edit sheet is evaluated and thus it can handle the save by itself.
526 - form.action = XWiki.currentDocument.getURL('edit');
519 + // Let the sheet handle the form submit.
520 + // NOTE: The code that handles Save&Continue uses this URL to make the AJAX request and Firefox 3.6 doesn't resolve
521 + // the empty string to the current page URL so we have to explicitly specify it.
522 + form.action = window.location.href;
527 527  
528 528   // Apply the vertical form layout standard.
529 529   form.addClassName('xform');
... ... @@ -562,44 +562,3 @@
562 562   }
563 563   (XWiki.domIsLoaded && init()) || document.observe('xwiki:dom:loaded', init);
564 564  }).call();
565 -
566 -require(['jquery', 'xwiki-events-bridge'], function($) {
567 - $(document).on('xwiki:class:displayField xwiki:class:previewField', function(event, data) {
568 - var container = $(data.field.getContainer());
569 - if (container.attr('data-new') === 'true') {
570 - // We can't suggest property values for properties that don't exist yet (have not been saved) so we provide
571 - // suggestions for the template property that was used to create them. Note that the suggested values depend on
572 - // the saved property meta data so changing the property (field) meta data may not affect the suggestions until
573 - // those changes are saved.
574 - var templateHiddenInput = container.find('#' + 'template-' + data.field.getName());
575 - var propertyValueSuggester = container.find('.field-viewer .suggest-propertyValues').first();
576 - propertyValueSuggester.attr({
577 - 'data-className': templateHiddenInput.val(),
578 - 'data-propertyName': templateHiddenInput.attr('data-propertyName')
579 - });
580 - }
581 - }).on('xwiki:document:saved', function(event) {
582 - // We need to update the property value suggesters because:
583 - // * newly saved properties should have their own suggestions instead of relying on the template property
584 - // * for renamed properties we need to fetch the suggestions from a different location
585 - $('ul#fields > li').each(function() {
586 - var container = $(this);
587 - container.removeAttr('data-new');
588 - var propertyValueSuggester = container.find('.field-viewer .suggest-propertyValues').first();
589 - if (propertyValueSuggester.length > 0) {
590 - // We need to preserve the selected values because they are lost when the suggester is destroyed.
591 - var selectedValues = propertyValueSuggester.children();
592 - propertyValueSuggester[0].selectize.destroy();
593 - // Restore the selected values.
594 - propertyValueSuggester.empty().append(selectedValues);
595 - var className = XWiki.Model.serialize(XWiki.currentDocument.documentReference.relativeTo(
596 - new XWiki.WikiReference(XWiki.currentWiki)));
597 - propertyValueSuggester.attr({
598 - 'data-className': className,
599 - 'data-propertyName': propertyValueSuggester.attr('name').substr((className + '_0_').length)
600 - });
601 - propertyValueSuggester.suggestPropertyValues();
602 - }
603 - });
604 - });
605 -});
XWiki.StyleSheetExtension[1]
Code
... ... @@ -38,9 +38,7 @@
38 38  }
39 39  
40 40  #fields input.xHint {
41 - color: $theme.textSecondaryColor;
42 - font-size: smaller;
43 - font-weight: normal;
41 + border: 0 none;
44 44  }
45 45  
46 46  #fields .labelLine label {