JavaScript doOperation() in Doc type action

Post here questions and problems related to oXygen frameworks/document types.
martindholmes
Posts: 139
Joined: Wed Apr 20, 2005 5:43 pm
Location: Victoria, BC, Canada

JavaScript doOperation() in Doc type action

Post by martindholmes » Wed Apr 03, 2019 1:41 am

Hi there,

I'm writing Author actions using the Document Type Author Action configuration, and finding a couple of oddities. First, an extra space is inserted following the closing tag of the element I insert; and secondly, the compound edit functionality seems to be failing (nothing happens when I undo after the action). This is my code:

Code: Select all


function doOperation() {
var selText = authorAccess.getEditorAccess().getSelectedText();
var documentController = authorAccess.getDocumentController();
var workspaceAccess = authorAccess.getWorkspaceAccess();
try {

if (authorAccess.getEditorAccess().hasSelection()) {
var selectionAsAFragment = documentController.createDocumentFragment(
authorAccess.getEditorAccess().getSelectionStart(), authorAccess.getEditorAccess().getSelectionEnd());
var selectionAsXML = documentController.serializeFragmentToXML(selectionAsAFragment);


//Next get a reference to the schema manager.
var schemaManager = documentController.getAuthorSchemaManager();

//Make everything into a single undo item.
documentController.beginCompoundEdit();

//Deletes the selection
authorAccess.getEditorAccess().deleteSelection();

//Process the selectionAsXML fragment, modify it.
//................
selectionAsXML = "<seg xmlns='http://www.tei-c.org/ns/1.0' ana=''>" + selectionAsXML + '</seg>';

//Insert the XML fragment back at caret position.
documentController.insertXMLFragment(selectionAsXML, authorAccess.getEditorAccess().getCaretOffset());

//Now we need to add the attribute value. First find the element we just added.
var newEl = documentController.findNodesByXPath("//*:seg[@ana = ''][1]", true, true, true);

//Now the element is in place, we can interrogate the schema to get the list
//of possible values.
var anaVals = schemaManager.whatPossibleValuesHasAttribute(schemaManager.createWhatPossibleValuesHasAttributeContext(newEl[0], 'ana')).toArray();
//Packages.java.lang.System.err.println("anaVals: " + Array.isArray(anaVals));

//Get the correct selected value from the user.
var selectedValue = Packages.javax.swing.JOptionPane.showInputDialog(
workspaceAccess.getParentFrame(),
null,
'Insert echo figure type value',
Packages.javax.swing.JOptionPane.QUESTION_MESSAGE,
null,
anaVals,
null);

if (selectedValue != null && selectedValue != '') {
documentController.setAttribute("ana", new Packages.ro.sync.ecss.extensions.api.node.AttrValue(selectedValue), newEl[0]);
}

//End of the single Undo action.
documentController.endCompoundEdit();
}
}

catch (e1) {
e1.printStackTrace();
}
}
Can anyone see what I might be doing wrong?

martindholmes
Posts: 139
Joined: Wed Apr 20, 2005 5:43 pm
Location: Victoria, BC, Canada

Re: JavaScript doOperation() in Doc type action

Post by martindholmes » Wed Apr 03, 2019 2:07 am

If I use surroundInFragment I get the same result: an extra space before the closing tag.

Radu
Posts: 6211
Joined: Fri Jul 09, 2004 5:18 pm

Re: JavaScript doOperation() in Doc type action

Post by Radu » Wed Apr 03, 2019 8:06 am

Hi Martin,

That extra space problem appears because the method "getSelectionEnd()" is exclusive:

https://www.oxygenxml.com/InstData/Edit ... ctionEnd--

but the method "createDocumentFragment" receives inclusive offsets:

https://www.oxygenxml.com/InstData/Edit ... t-int-int-

so you need a "-1" extracted from the selection end when creating the document fragment. I'm attaching my changes below.
About the undo not working, I experienced this the first time I run your script, because I run into an unhandled exception as the list of attribute values was null, thus the script called "beginCompoundEdit()" but it never called "endCompoundEdit()" again as the exception was thrown.
So "beginCompoundEdit()" and "endCompoundEdit()" must always be called in pairs, when you can one you are compelled to call the other as well.
You can re-open the file to make this work properly again.
So what can you do about that:

- Move the endCompoundEdit() after the catch() clause so that it's executed even if the code breaks
or even better:
- Remove both the begin and end compound edit calls. They are not necessary, all executed AuthorOperations are automatically surrounded by our own code in such a compound edit.

Code: Select all

function doOperation() {
var selText = authorAccess.getEditorAccess().getSelectedText();
var documentController = authorAccess.getDocumentController();
var workspaceAccess = authorAccess.getWorkspaceAccess();
try {

if (authorAccess.getEditorAccess().hasSelection()) {
var selectionAsAFragment = documentController.createDocumentFragment(
authorAccess.getEditorAccess().getSelectionStart(), authorAccess.getEditorAccess().getSelectionEnd() - 1);
var selectionAsXML = documentController.serializeFragmentToXML(selectionAsAFragment);


//Next get a reference to the schema manager.
var schemaManager = documentController.getAuthorSchemaManager();

//Deletes the selection
authorAccess.getEditorAccess().deleteSelection();

//Process the selectionAsXML fragment, modify it.
//................
selectionAsXML = "<seg xmlns='http://www.tei-c.org/ns/1.0' ana=''>" + selectionAsXML + '</seg>';

//Insert the XML fragment back at caret position.
documentController.insertXMLFragment(selectionAsXML, authorAccess.getEditorAccess().getCaretOffset());

//Now we need to add the attribute value. First find the element we just added.
var newEl = documentController.findNodesByXPath("//*:seg[@ana = ''][1]", true, true, true);

//Now the element is in place, we can interrogate the schema to get the list
//of possible values.
var vals = schemaManager.whatPossibleValuesHasAttribute(schemaManager.createWhatPossibleValuesHasAttributeContext(newEl[0], 'ana'));
if (vals != null) {
var anaVals = vals.toArray();
//Packages.java.lang.System.err.println("anaVals: " + Array.isArray(anaVals));

//Get the correct selected value from the user.
var selectedValue = Packages.javax.swing.JOptionPane.showInputDialog(
workspaceAccess.getParentFrame(),
null,
'Insert echo figure type value',
Packages.javax.swing.JOptionPane.QUESTION_MESSAGE,
null,
anaVals,
null);

if (selectedValue != null && selectedValue != '') {
documentController.setAttribute("ana", new Packages.ro.sync.ecss.extensions.api.node.AttrValue(selectedValue), newEl[0]);
}
}
}
}

catch (e1) {
e1.printStackTrace();
}
}
Regards,
Radu
Radu Coravu
<oXygen/> XML Editor
http://www.oxygenxml.com

martindholmes
Posts: 139
Joined: Wed Apr 20, 2005 5:43 pm
Location: Victoria, BC, Canada

Re: JavaScript doOperation() in Doc type action

Post by martindholmes » Wed Apr 03, 2019 6:53 pm

Works perfectly! Thank you so much.

Cheers,
Martin

Post Reply