Adding xsl-transformation to custom framework

Patrik
Posts: 249
Joined: Thu Nov 28, 2013 9:32 am
Location: Hamburg/Germany
Contact:

Adding xsl-transformation to custom framework

Post by Patrik » Wed Aug 12, 2020 3:55 pm

Hi,

I've created a custom framewirk with xsd and css to edit some configuration files in Web Author (currently 21.1).

Since the format is not exactly what we need, I'd like to create an xslt transformation. For now the result will just need to be displayed or (even better) copied to the clipboard, so we can paste it into the target system.

Could you give me some hints for how to achieve this? Creating a transformation scenario (As I woul din th desktop version), extend my custom framework or do I need to implement a plugin with java?

Thanks and regards,
Patrik

cristi_talau
Posts: 292
Joined: Thu Sep 04, 2014 4:22 pm

Re: Adding xsl-transformation to custom framework

Post by cristi_talau » Wed Aug 12, 2020 6:53 pm

Hello,

You need to implement a plugin for this functionality. You can use as a starting point this sample plugin that runs an XSLT script and prints the result in the browser console.

Best,
Cristian

Patrik
Posts: 249
Joined: Thu Nov 28, 2013 9:32 am
Location: Hamburg/Germany
Contact:

Re: Adding xsl-transformation to custom framework

Post by Patrik » Fri Aug 21, 2020 5:48 pm

Hi Christian,

thanks for the hint. So what I achievd so far is:
  • setting up my local webauthor
  • creating a custom framework with xsd and css
  • compiling my own plugin as java code based on you sample web-author-xslt-report
  • add it as plugin to my web author
So the next step would be to extens my custom framework by adding an action to the toolbar which seems to require javascript.
I created a file web/framework.js in my framework. But actually I don't even know if my code is actually being executed.
I tried to just create some logging output:

Code: Select all

goog.events.listen(workspace, sync.api.Workspace.EventType.EDITOR_LOADED, function(e) {
  console.log('Patrik-Test1');
});
But I could not find the text anywhere in the logs folder.

Could you please give me some advice on how to start some kind of interaction with my source code?

Thanks and regards,
Patrik

Patrik
Posts: 249
Joined: Thu Nov 28, 2013 9:32 am
Location: Hamburg/Germany
Contact:

Re: Adding xsl-transformation to custom framework

Post by Patrik » Mon Aug 24, 2020 12:46 pm

I realized that the javascript code is executed in the browser - not the server. And after opening the browser console I also found my logging output. So for now I have no further questions...

Regards,
Patrik

Patrik
Posts: 249
Joined: Thu Nov 28, 2013 9:32 am
Location: Hamburg/Germany
Contact:

Re: Adding xsl-transformation to custom framework

Post by Patrik » Thu Aug 27, 2020 6:25 pm

Hi again,

I managed to transform the document and display it in a dialog to the user.

Now I'd like to add two checks before the transformation:
  1. Ensure the current document is not modified (i.e. the changes were commited)
    I tried to call editorAccess.isModified() in the java code but this does not work. I get this error:
    Calling isModified() is not supported while a "compound edit" is in progress.
    And I was also surprised that the error text being passed to my callback after completing ActionsManager.invokeOperation() is null when I threw an exception. How can I signal my javascript code that the java operation failed?
  2. Ensure the current document is valid.
    I've added an xsd with embedded schematron checks to the document type and the validations works fine. I just want to check the result.
I both cases I'm open to implement it in either javascript or java.I'd appreciate any hints.

Thanks and regards,
Patrik

cristi_talau
Posts: 292
Joined: Thu Sep 04, 2014 4:22 pm

Re: Adding xsl-transformation to custom framework

Post by cristi_talau » Fri Aug 28, 2020 3:12 pm

Hello,

To check if a document is modified, you can use either the JS API: editor.isDirty [1] or, if you use the Java API inside an AuthorOperation you need to make it implement the AuthorOperationWithCustomUndoBehavior and call the .isModified() method.

Regarding the validation status, I created a small plugin that blocks saving a document if not valid. Maybe it can give you some inspiration: https://github.com/oxygenxml/web-author ... if-invalid .

Best,
Cristian

[1] https://www.oxygenxml.com/maven/com/oxy ... ml#isDirty

Patrik
Posts: 249
Joined: Thu Nov 28, 2013 9:32 am
Location: Hamburg/Germany
Contact:

Re: Adding xsl-transformation to custom framework

Post by Patrik » Thu Sep 24, 2020 7:03 pm

Hi Christian,

thanks for the hints. Adding a check for isDirty() was indeed very simple.

But I still struggle with the validation status:

Using the plugin you suggested seemed to have no effect when commiting the file to an on-premise git repository. I'd assume that the commit would trigger the same listeners as saving a file, right?

I'm sure the file is read because I get error messages when writing bad code. But I could not get any output:

Code: Select all

editorAboutToBeSavedVeto: function () {
  console.log("editorAboutToBeSavedVeto");
  workspaceAccess.showErrorMessage("editorAboutToBeSavedVeto");
}
I also failed to check for the validation status within my javascript for the custom action. I'm aware of having access to sync.api.Editor and sync.api.Workspace. But in the documentation I could not find any way to access the AuthorDocumentModel from there.

I'd appreciate some more guidance.

Thanks and regards,
Patrik

cristi_talau
Posts: 292
Joined: Thu Sep 04, 2014 4:22 pm

Re: Adding xsl-transformation to custom framework

Post by cristi_talau » Thu Sep 24, 2020 11:56 pm

Hello,

The Commit action for Git is different from the "Save". To add some code before it you can use the following JS code:

Code: Select all

 goog.events.listenOnce(workspace, sync.api.Workspace.EventType.EDITOR_LOADED, function(e) {
    var editor = e.editor;
    goog.events.listenOnce(e.editor, sync.api.Editor.EventTypes.ACTIONS_LOADED, function(e) {
      var commitAction = editor.getActionsManager().getActionById('Git/Commit');
      var oldActionPerformed = commitAction.actionPerformed;
      commitAction.actionPefrormed = function(callback) {
        // ... YOUR CODE HERE
        oldActionPerformed.call(commitAction, callback);
      };
    });
 });
Best,
Cristian

Patrik
Posts: 249
Joined: Thu Nov 28, 2013 9:32 am
Location: Hamburg/Germany
Contact:

Re: Adding xsl-transformation to custom framework

Post by Patrik » Fri Sep 25, 2020 2:07 pm

Hi Christian,

thanks, but it still doesn't work. I added this code to my framework.js:

Code: Select all

goog.events.listenOnce(workspace, sync.api.Workspace.EventType.EDITOR_LOADED, function(e) {
	console.log("sync.api.Workspace.EventType.EDITOR_LOADED");
	var editor = e.editor;
	goog.events.listenOnce(e.editor, sync.api.Editor.EventTypes.ACTIONS_LOADED, function(e) {
		console.log("sync.api.Workspace.EventType.ACTIONS_LOADED");
		var commitAction = editor.getActionsManager().getActionById('Git/Commit');
		console.log("commitAction: " + commitAction);
		var oldActionPerformed = commitAction.actionPerformed;
		commitAction.actionPefrormed = function(callback) {
			console.log("before Git/Commit");
			oldActionPerformed.call(commitAction, callback);
			console.log("after Git/Commit");
		};
	});
});
In the console I ensured that sync.api.Workspace.EventType.EDITOR_LOADED and sync.api.Workspace.EventType.ACTIONS_LOADED were triggered.

But on commit I get no additional output on the console - so my code wasn't executed.

And even if it was executed I still don't know how to access the AuthorDocumentModel .

Regards,
Patrik

cristi_talau
Posts: 292
Joined: Thu Sep 04, 2014 4:22 pm

Re: Adding xsl-transformation to custom framework

Post by cristi_talau » Fri Sep 25, 2020 2:58 pm

Hello,

The code was intended to be used in a plugin. In a framework you can use the "editorCreated" callback in your extension implementation [1]. There you get a handle on an editor. With that you can listen for ACTIONS_LOADED event and patch the "Commit" action.

Also, note that the Commit action is asynchronous - to write a console.log after its execution you should use its callback argument.

Best,
Cristian

[1] https://www.oxygenxml.com/maven/com/oxy ... nsion.html

Patrik
Posts: 249
Joined: Thu Nov 28, 2013 9:32 am
Location: Hamburg/Germany
Contact:

Re: Adding xsl-transformation to custom framework

Post by Patrik » Fri Sep 25, 2020 4:02 pm

Hi again,

I found and fixed a typo in your code: commitAction.actionPefrormed = function(callback)

Now I get the colsole output - by placing the code in a plugin and also by placing the code in a framework.

However, I still don't now, how to get access to the DocumentValidator. Your sample plugin uses the authorDocumentModel which is passed as parameter to the callback function - so I can't use this method!?

Regards,
Patrik

cristi_talau
Posts: 292
Joined: Thu Sep 04, 2014 4:22 pm

Re: Adding xsl-transformation to custom framework

Post by cristi_talau » Fri Sep 25, 2020 4:43 pm

Hello,

The sample plugin runs the JS code on the server. The simplest way to query the validation status is to use an AuthorOperationWithResult. We have a tutorial on how to use one here [1].

Best,
Cristian

[1] https://www.oxygenxml.com/maven/com/oxy ... esult.html

Patrik
Posts: 249
Joined: Thu Nov 28, 2013 9:32 am
Location: Hamburg/Germany
Contact:

Re: Adding xsl-transformation to custom framework

Post by Patrik » Tue Sep 29, 2020 12:39 pm

Hi again,

thanks, now I could make it work.

Java class in my plugin:

Code: Select all

@WebappCompatible
@WebappRestSafe
public class IsDocumentValid extends AuthorOperationWithResult {
	
	private final static Logger logger = Logger.getLogger(IsDocumentValid.class.getName());
	
	@Override
	public String doOperation(AuthorDocumentModel model, ArgumentsMap args) throws AuthorOperationException {
		try {
			final List<DocumentPositionedInfo> errors = model.getDocumentValidator().getValidationTask().call();
			return String.valueOf((errors == null) || (errors.isEmpty()));
		} catch (Exception e) {
			logger.error(e, e);
			throw new AuthorOperationException(e.getMessage(), e);
		}
	}
}
javascript code in my framework:

Code: Select all

goog.events.listenOnce(workspace, sync.api.Workspace.EventType.EDITOR_LOADED, function(e) {
	var editor = e.editor;
	
	goog.events.listenOnce(e.editor, sync.api.Editor.EventTypes.ACTIONS_LOADED, function(e) {
		var commitAction = editor.getActionsManager().getActionById('Git/Commit');
		var oldActionPerformed = commitAction.actionPerformed;
		
		commitAction.actionPerformed = function(callback) {
			editor.getActionsManager().invokeOperation(
				'com.gdvdl.webauth.IsDocumentValid', 
				{}, // no parameters
				function (err, result) {
					console.log('Git/Commit - isValid: ' + result);
					if (result == 'true') {
						console.log('Git/Commit - valid');
						oldActionPerformed.call(commitAction, callback);
					} else {
						console.log('Git/Commit - invalid');
						dialog = workspace.createDialog();
						dialog.setButtonConfiguration(sync.api.Dialog.ButtonConfiguration.OK);
						dialog.setTitle('Error');
						dialog.getElement().innerHTML = 'Commit with validation errors is not allowed.';
						dialog.show();		
					}
				},
				null,
				true // This is a background operation - it does not update the document
			);
			
		};
	});
});
Regards,
Patrik

Post Reply