Wiki source code of In-place Real-time Editing

Last modified by Vincent Massol on 2024/02/26 17:57

Show last authors
1 {{velocity output="false"}}
2 #macro (video $source)
3 {{html clean="false"}}
4 <video controls muted src="$doc.getAttachmentURL($source)" width="780">
5 Sorry, your browser doesn't support embedded videos.
6 </video>
7 {{/html}}
8 #end
9 {{/velocity}}
10
11 {{toc depth="1"/}}
12
13 = The Problem =
14
15 The users are not motivated to **contribute** to the wiki, particularly because:
16
17 1. there are too many **steps** required to make a change or to add new content (e.g. you need to scroll up, click the Edit button, scroll down, click the Save button)
18 1. it takes too much **time** to make a change or to add new content (e.g. you need to wait a few seconds for the edit mode to load and then another few seconds to get back to the view mode)
19 1. the users don't know:
20 1*. **where** to make the change (e.g. the content you look at is coming from another wiki page)
21 1*. or how to make the change (e.g. you have to know the wiki syntax)
22 1*. or event that they can make the change (e.g. the configuration you need to change is **hidden** somewhere in the administration)
23 1. **collaborating** with other users on the same page can lead to complex merge conflicts that have to be resolved manually
24 1. the content can become outdated without the user being aware of it (e.g. you view a page that someone else is editing)
25 1. there's only very little **reward** for making a change or for adding new content: you don't know if someone noticed your change, or how many people viewed the content you added and if they liked it, or how much you contributed compared to the other users.
26
27 Note that the first 2 items are related but not the same. You can have a single step for which you need to wait 10s. So we need to fix box problems. The last item, about user engagement, deserves a separate investigation so it won't be covered here.
28
29 = The Goals =
30
31 Making changes and adding new content should:
32
33 1. require fewer steps
34 1. take less time
35 1. preserve the context
36 1. be straightforward
37 1. propagate in real-time
38
39 = Use Cases =
40
41 {{toc start="2" scope="local" /}}
42
43 == Plain wiki pages ==
44
45 === UC1: Modify the title of a plain wiki page ===
46
47 You're looking at a wiki page and you decide to modify its title. Currently you have to take the following steps:
48
49 * locate the Edit button, move the mouse over it and click
50 * wait for the edit mode to load (~3s)
51 * move the mouse over the title text input and click on it to have the focus
52 * make the change
53 * locate the Save button at the bottom of the page, move the mouse over it and click
54 * wait for the view mode to load (~2s)
55 * verify that the title was updated
56
57 This requires **7 steps** and takes at least **10 seconds** to complete.
58
59 {{velocity}}#video('UC1-edit-page-title.webm'){{/velocity}}
60
61 The current implementation has the following problems:
62
63 * switching from view mode to edit mode and back takes too much time and is perceived by the user as a context switch because the layout is very different
64 * the title input should be focused automatically, being the first input of the edit form
65
66 === UC2: Modify the content of a plain wiki page ===
67
68 You're looking at a long wiki page (e.g. the Sandbox home page) and you notice a typo somewhere at the end. If you want to fix it then you need to:
69
70 * **Without section editing** (either because there's no section or because you don't notice the section editing icon):
71 ** scroll the page to the top
72 ** locate the Edit button, move the mouse over it and click
73 ** wait for the edit mode to load (~3s)
74 ** move the mouse over the content text area
75 ** scroll down and scan the content until you find the typo
76 ** place the caret over the typo and fix it
77 ** //[optional]// locate the Preview button, move the mouse over it and click
78 ** //[optional]// wait for the preview mode to load (~2s)
79 ** //[optional]// scroll down and scan the content until you find the place you modified, in order to verify the typo is properly fixed
80 ** locate the Save button, move the mouse over it and click
81 ** wait for the view mode to load (~2s)
82 ** scroll down and scan the content until you find the place you modified, in order to verify the typo is indeed fixed
83
84 {{velocity}}#video('UC2a-edit-page-content.webm'){{/velocity}}
85
86 * **With section editing**
87 ** //[optional]// depending on the length of the section, you may have to scroll the page up to locate the section heading
88 ** locate the section edit icon on the right, move the mouse over it and click
89 ** wait for the edit mode to load (~2s)
90 ** //[optional]// depending on the length of the section, you may have to scroll down to find the typo
91 ** place the caret over the typo and fix it
92 ** //[optional]// locate the Preview button, move the mouse over it and click
93 ** //[optional]// wait for the preview mode to load (~2s)
94 ** //[optional]// depending on the length of the section, you may have to scroll down to find the place you modified, in order to verify the typo is properly fixed
95 ** locate the Save button, move the mouse over it and click
96 ** wait for the view mode to load (~2s)
97 ** scroll down and scan the content until you find the place you modified, in order to verify the typo is indeed fixed
98
99 {{velocity}}#video('UC2b-edit-page-content.webm'){{/velocity}}
100
101 This requires **6 to 12 steps** to complete and takes at least **8 to 16 seconds**. The current implementation has the following problems:
102
103 * you need to scroll to the top of the page to find the Edit button
104 * you may need to scroll to find the section editing icon
105 * you loose the context:
106 ** you need to find the place you want to modify after the edit mode is loaded
107 ** if you edit a section, you don't see the other sections anymore
108 * the lack of a real WYSIWYG edit mode (same layout as in view mode) makes the user repeat the Preview - Back To Edit loop which is time consuming
109 * after editing a section the page should be scrolled automatically to that section in view mode in order to verify the changes
110
111 ==== UC2.1: Move around content blocks ====
112
113 You are editing the content of a plain wiki page and you have the need to move around blocks of content (e.g. sections, lists, tables). The current status is this:
114
115 * **paragraphs**, **headings**, **lists** can be moved with drag & drop but:
116 ** you need to select their entire text, which makes this feature hard to discover and use
117 ** there is no visual clue visible while dragging to indicate where the content will be inserted (although there is a visual clue indicating that you are dragging some block of text)
118 ** it's very easy to drop the block in-line (e.g. inside of a paragraph) while you would expect to be allowed to drop only between blocks.
119 * **tables** can't be moved at all
120 * **images** and **macros** have a drag handler
121 ** which makes it easy to discover that they can be dragged, and simplifies the drag operation
122 ** there is a visual clue (dotted horizontal line) visible while dragging, indicating where the block will be inserted
123 ** you can drop the block only between blocks
124
125 FTR, CKEditor5 [[doesn't have support for real content drag & drop>>https://github.com/ckeditor/ckeditor5/issues/2664]] ATM.
126
127 === UC3: Modify the content of an included wiki page ===
128
129 You're reading a wiki page and you notice a typo. You decide it's worth fixing it so you:
130
131 * //[optional]// scroll the page up to the nearest section editing icon or to the top
132 * locate the section edit icon or the Edit button on the right, move the mouse over it and click
133 * wait for the edit mode to load (~3s)
134 * //[optional]// move the mouse over the content text area
135 * //[optional]// scroll down to find the typo
136 * place the caret over the typo to fix it
137 * realize it can't be fixed directly because that is the output of a macro that can't be edited in-line
138 * double click to edit the macro
139 * realize it's the include macro so the typo is in a different page
140 * notice the name of the included page and, hopefully, notice that the same page is listed in the Page Information panel on the right side
141 * close the macro edit modal
142 * move the mouse over the Page Information panel and click on the link to open the included page
143 * wait for the included page to load (2s)
144 * locate the Edit button or the nearest section editing icon, move the mouse over it and click
145 * wait for the edit mode to load (3s)
146 * //[optional]// move the mouse over the content text area
147 * //[optional]// scroll down to find the typo
148 * place the caret over the typo and fix it
149 * locate the Save button, move the mouse over it and click
150 * wait for the view mode to load (~2s)
151 * find a way to get back to the original page
152 ** if you didn't open the included page in a separate tab then you're blocked..
153 ** otherwise you need to get back to the previous tab and:
154 *** cancel the edit mode
155 *** wait for the view mode to load (2s)
156 *** scroll down and scan the content until you find the place you modified, in order to verify the typo is indeed fixed
157
158 This requires **20 to 25 steps** and takes at least **35 seconds** for a knowledgeable user to complete.
159
160 {{velocity}}#video('UC3-edit-included-page.webm'){{/velocity}}
161
162 The current implementation has the following problems:
163
164 * the include macro is not editable in-line with the WYSIWYG editor
165 * it's not easy to open the included page (in a separate tab) in order to edit it (there's no clear link on the Edit Macro dialog)
166 * there's no easy way to get back from the included page to the page that includes it
167
168 === UC4: Translate an existing plain wiki page ===
169
170 You're browsing the wiki with the language set to French and you notice a page that is in English (while the UI is still in French). You decide to translate it to French. Currently you have to do this:
171
172 * locate the Edit button, move the mouse over it and click
173 * wait for the edit mode to load (3s)
174 * notice that the UI language has switched to English; fortunately you know a bit of English, but it could have been worse (Russian)
175 * scan the page and notice the Page Translations panel
176 * understand that you're editing the original English version of the page
177 * move the mouse over the "fr" link and click
178 * wait for the edit mode to load (3s)
179 * do the translation
180 * locate the Save button, move the mouse over it and click
181 * wait for the view mode to load (2s)
182 * review the page
183
184 This requires **11 steps** and takes at least **16 seconds** to complete, without counting the time to do the translation.
185
186 {{velocity}}#video('UC4-translate-page.webm'){{/velocity}}
187
188 The current implementation has the following problems:
189
190 * the UI language is changed when you try to edit a page that doesn't have a translation in your current language
191 * it's easy to miss that you're editing the default translation
192 * the link to create the new translation is also easy to miss
193
194 == Structured wiki pages ==
195
196 === UC5: Modify the value of a field from a structured page ===
197
198 You're looking at a structured page and you notice that the value of a field is wrong. You decide to fix it so you:
199
200 * locate the edit button, move the mouse over it and click
201 * wait for the edit mode to load (3s)
202 * scan the page for the field you want to change
203 * move the mouse over that field and click to change its value
204 * make the change
205 * locate the Save button, move the mouse over it and click
206 * wait for the view mode to load (2s)
207 * scan the page for the field you modified
208 * verify that the value is fixed
209
210 This requires **9 steps** and takes at least **12 seconds** to complete.
211
212 {{velocity}}#video('UC5-edit-page-metadata.webm'){{/velocity}}
213
214 The current implementation has the following problems:
215
216 * the Inline Form edit layout is closer to the view layout but still different; the following items are missing: the author and the creator, the page tags and the page extra tabs. So this is still perceived by the user as a context switch
217 * you need to wait for all the fields to be loaded in edit mode even if you just want to edit a single field
218
219 == Panels ==
220
221 === UC6: Add or remove panels ===
222
223 While looking at a wiki page you realize that one of the panels doesn't make sense in this context and you would prefer to replace it with another panel.
224
225 === UC7: Change panel layout ===
226
227 While looking at a wiki page you realize that the right panels take too much space and don't bring enough value so you decide to change the panel layout to remove the left column.
228
229 === UC8: Configure a panel ===
230
231 ==== UC8.1: Remove an application from the Applications panel ====
232
233 After installing an extension you notice that there's a new entry on the Application panel. You decide to remove it.
234
235 ==== UC8.2: Hide a page from the Navigation panel ====
236
237 You created an application without using AppWithinMinutes and you want to exclude its home page from the Navigation panel because you added an entry to the Applications panel.
238
239 == UC9: Hide page extra tabs ==
240
241 You want to hide the comments tab but you still want to show the list of attachments.
242
243 == UC10: Change the wiki logo ==
244
245 You want to change the wiki logo, either for the entire wiki or just for a specific page and its children.
246
247 = Constraints =
248
249 {{toc start="2" scope="local" /}}
250
251 == Plain wiki pages ==
252
253 Wiki pages have **editable metadata** that is currently not displayed in view mode and thus it cannot be edited in-place as is. We either find a place for this metadata in view mode or we keep a dedicated edit mode for it.
254
255 * **default language**, **syntax**, **hidden**: we have good defaults for these and they are rarely modified by simple users
256 * **comment**, **minor edit**
257 ** the users rarely set them
258 ** they can be hidden from the administration
259 ** setting these while editing in-place is inconvenient so we'll have to drop them; but this means they will become less and less relevant as the users start using the in-place editing more and more
260 ** there is a setting to make the version summary (comment) mandatory; we'll have to disable in-place editing when this is on; we'll also have to keep the classic edit mode because of this
261
262 The edit mode provides **tools** that are obviously not present in view mode and thus would be missing while editing in-place:
263
264 * **auto save**: this is useful mainly when you edit the page content for a long period of time, thus it's probably not needed when editing in-place, but we should keep it for the classic edit mode
265 * link to XWiki **syntax help** (only for Wiki edit mode)
266 * link to configure **more syntaxes**
267 * **included pages**: this information is shown in the "Information" tab but it's going to be easy to miss it while editing in-place because this tab is not active by default
268 * **translations**:
269 ** the current language
270 ** links to existing translations
271 ** link to create a new translation
272
273 == Structured wiki pages ==
274
275 * structured wiki pages have **custom sheets** and often **custom displayers** for their fields
276 ** the way the fields are arranged or grouped in view and edit mode can vary a lot
277 ** the amount of space taken by each field in view and edit mode varies also
278 * structured wiki pages can have custom validation rules and relations between the fields
279 ** this makes in-place single field editing very complicated
280
281 = Solutions =
282
283 {{toc start="2" scope="local" /}}
284
285 == Real WYSIWYG edit mode ==
286
287 There are 2 approaches:
288
289 1. **Modify the WYSIWYG edit mode** to look similar to the view mode (show the same panels, show the page extra tabs, show the page tags, author and creator information). When switching to WYSIWYG edit mode the browser will reload the entire page but since the edit mode will look very similar to the view mode the browser will render the edit mode faster and thus the transition from view to edit will be smoother.
290 1. **Modify the view mode** to support activating the WYSIWYG edit mode without reloading the page.
291
292 For both approaches we'll have to move fields and tools from the edit panels to someplace visible in view mode:
293
294 * Display the default language, syntax and hidden page metadata inside the "Information" page extra tab and make them editable in-place from there. Otherwise we need to keep a dedicated edit mode. Note that all the other page extra tabs have actions that modify the current page (comment, attach, revert), so being able to modify the current page from the "Information" tab shouldn't come as a surprise. At most we may consider changing the title of the tab, but I don't think it's necessary.
295 ** We'll have to move the link to configure more syntaxes also. An idea is to have this as an option in the syntax drop down (i.e. you select from the available syntaxes or you add more syntaxes).
296 * Add a tool bar button for the Wiki editor and for the WYSIWYG editor (when in Source mode) to open the XWiki Syntax help (depending on the page syntax)
297 * Display the language, the list of translations and the link to create a new translation (for the current UI language) inside the "Information". There's no reason to limit this to edit mode. Note that the list of existing translations is availalbe also in the drawer menu, but this has created confusion in the past because the users often ask "why can't I switch to XX language?" and the answer is "Because the current page is not translated in that language". I'd rather keep the drawer for changing the UI language (i.e. list all supported languages) and use the "Information" tab to list available page translations.
298
299 Also, for both approaches we'll have to adjust the title input and the WYSIWYG editor text area:
300
301 * hide the title label (screen reader only) and set the placeholder attribute of the title input
302 * style the title text input so that it appears as in view mode (keep the border but use a bigger font size to match the level 1 heading styles)
303 * since the title can be computed we might have to show the computed title when the title input is not focused, and show the raw value (e.g. the Velocity code) when the title input is focused; one thing to consider is that the rendered title can be influenced by the page content, so in order to preview the title we'll have to submit also the edited page content
304 * run CKEditor in inline mode rather than using an iframe so that there's no scroll bar on the text area; we'll use the page scroll bar and the toolbar will float on top of the edited content; note that the inline CKEditor doesn't support some features:
305 ** Source text area: but there is a Source dialog that can be used instead
306 ** full screen mode: we need to decide if it's still useful and if we think it is then we'll have to find a workaround
307
308 Changes required for the first approach (**modify the WYSIWYG edit mode**):
309
310 * show the author and last modification date (should we update these once the user makes modifications in order to match what the user will see in view mode?)
311 * show the tags, creator and creation date
312 * show the same panels as in view mode and the page extra tabs
313
314 Changes required for the second approach (**activate WYSIWYG edit mode on top of view mode**):
315
316 * load on every view of a plain wiki page (no view sheet applied) the JavaScript code that can activate the WYSIWYG edit mode; this can be a light JavaScript code that:
317 ** catches the click on the WYSIWYG edit menu
318 ** loads more JavaScript code on demand (using RequireJS)
319 * in order to be able to edit we need to have the data (e.g. the raw page title and the annotated XHTML of the page content); we can either:
320 ** modify the view mode to include this data:
321 *** pass the raw page title as an attribute of the title heading
322 *** use the annotated XHTML in view mode to display the page content
323 *** pass some hidden information like the CSRF token, page version and language (to know which page translation we're viewing and editing)
324 ** or fetch the data using JavaScript; the advantage of this is that:
325 *** it could be packaged as an extension more easily
326 *** we can fetch the data as JSON and start a real-time session with it
327 * the JavaScript should also modify the current URL (using the History JavaScript API) so that the real WYSIWYG edit mode can be loaded directly with a dedicated URL
328
329 == In-place section editing ==
330
331 Instead of taking the user to a separate edit mode where they see only the content of that section, we could keep the user in view mode and activate the in-line CKEditor for that section.
332
333 == Quick WYSIWYG edit mode activation ==
334
335 In order to overcome the issue of **scrolling the page** and **moving the mouse** over the page Edit button or the section edit button, we should find a way to activate the edit mode faster. One idea is to show a **balloon** with the invitation to edit when the user selects a piece of text. A similar behavior can be seen in Medium (context toolbar) and Discourse (quote balloon). The flow would be like this:
336
337 * the user selects a piece of text
338 * we show a balloon with the "{{velocity}}$services.icon.render('pencil'){{/velocity}} Edit" action, placed at the start of the text selection
339 * upon clicking on the Edit link we activate the real WYSIWYG edit mode (described in the previous section), preserving the selection
340 * there should be little to no UI flicker, and the user can start editing right away
341
342 There's of course a big issue with this solution: discoverability. But once you learn the behavior it can be very powerful. Moreover, this could eliminate the need to edit a section of a page. Note also that the balloon toolbar could be extended later with actions for annotations and comments.
343
344 == Quick Inline Form activation ==
345
346 Much like in the previous section, we need to find a way to overcome the need to scroll the page and move the mouse over the page Edit button (because it may be far away from the field you're looking at and that you wish to modify). Using the selection is less intuitive in this case and we should avoid interfering with the logic of the sheet. An alternative is to automatically inject an edit icon {{velocity}}$services.icon.render('pencil'){{/velocity}} after each field label (in view mode). Showing the edit icons all the time clutters the UI so we could show them only when the label is hovered. This eliminates the clutter but makes the feature less discoverable and makes it unusable on touch devices. But since we're keeping the Edit page button, there should be no issue.
347
348 The difficulty is in loading the edit mode smoothly and in preserving the target field (label) under the current mouse position. Of course, the target field (that triggered the edit mode) should be focused.

Get Connected