In this weekly series, Martin describes a question that was raised by a Fonto developer, how it was resolved and why Fonto behaved like that in the first place. This week, a partner sees enabled operations for a document they have no rights to edit!
A support question came in: an author loaded a document that was locked by someone else. They right-licked on an image and saw they could replace the image: the operation was enabled. When they did it though, and went through the modal, the replacement was not actually processed. Nothing terrible went wrong and no documents were harmed, but it was still confusing. The partner got this on their plate and they sent us a support ticket.
The operation was straight-forward: a modal opens, accepts the initially selected image and uses the set-attributes operation to write the new selectedImageId
back. We reproduced it on our own editor and we were hit by the first difficulty: locking the document.
The fonto development tools are no replacement for an actual CMS. For instance, locking is not done like a CMS would do it. Running fdt
with the -lL
flag (that’s a lower l and an upper L), all the documents are loaded with the lock neither available or acquired.
The operation looked like this:
{ "contextual-edit-graphic": { "label": "t__Change graphic…", "description": "t__Refer to a different graphic.", "icon": "pencil", "steps": [ { "type": "operation/:_open-image-modal-for-edit", "data": { "selectedImageId": "x__$data?contextNode/@xlink:href" } }, { "type": "operation/set-attributes", "data": { "contextNodeId": "{{contextNodeId}}", "attributes": { "xlink:href": "{{selectedImageId}}" } } } ] } }
This operation does the following:
- Set the
selectedImageId
stepdata property to whatever the currenthref
value is. - Open an image modal; the selectedImageId is picked up there to select the current image.
- Set the
href
attribute to whatever the user selected in the modal
When Fonto is computing state for the operation, it will of course not open a modal: we cannot predict what a user will do, so the modal will just never open. Instead, it will skip the step. Skipping the step will not change the stepdata. Because it is not changed, the set-attributes
will not do anything. Not changing anything can happen on any document, even those that are not editable.
The fix for this is to make sure the operation works differently when running it during the getState flow:
{ "contextual-edit-graphic": { "label": "t__Change graphic…", "description": "t__Refer to a different graphic.", "icon": "pencil", "getStateSteps": [ { "type": "operation/set-attributes", "data": { "contextNodeId": "{{contextNodeId}}", "attributes": { "xlink:href": "dummy-value" } } } ], "steps": [ { "type": "operation/:_open-image-modal-for-edit", "data": { "selectedImageId": "x__$data?contextNode/@xlink:href" } }, { "type": "operation/set-attributes", "data": { "contextNodeId": "{{contextNodeId}}", "attributes": { "xlink:href": "{{selectedImageId}}" } } } ] } }
But why?
This whole flow may not make sense when reading it the first time: why do we not disable any operations on locked documents? The reason is twofold:
We may not always know an edit is targeted at a document that is locked. Some editors load multiple documents at once. For some operations (like opening a sidebar), we do not care if the document is locked: that’s just possible.
But why do we do not disable an operation if we do know it targets a locked document? That should be possible right? Just read from the contextNodeId
property! That’s also not always enough: there are some operations that are targeted to a document that are available if a document is locked. For example the set-selection
operation should always be working. Same as copying content, or cutting content (without the actual delete happening of course).
If you have any other ideas on how we could have prevented this bug, do reach out on Twitter to Martin Middel! We are always looking for feedback and new ideas!
I hope this explained how Fonto works and why it works like that. During the years we built quite the product, and we are aware some parts work in unexpected ways for those who have not been with it from the start. If you have any points of Fonto you would like some focus on, we are always ready and willing to share! Reach out on Twitter to Martin Middel or file a support issue!
Developer advocate / Evangelist. Has been with Fonto since it all began in 2013. He’s currently designing the next steps in Fonto Developer APIs with the input of our valuable partners.
In his spare time, Martin is an avid home brewer.
Receive updates on new Fonto Why & How blog posts by email