xwiki

Javascript inside a xwiki macro have no effect


I am trying to write a macro, which embed draw.io. when user double click the diagram image I want to open draw.io in aonther window and get image data back as text. but my javascript inside macro not working at all.

It seems my javascript code in macro is not executed at all, can somebody tell me the right way to inject javascrpt code inside a velocity macro?


updates: I have noticed that when editing in CKEditor, my javascript code will not be executed, bu when editing in inline editor it will be executed.

{{velocity}}
$wikimacro.content
#if($wikimacro.content == '')
#set ($wikimacro.content = 'iVBORw0KGgoAAAANSUhEUgAAAIMAAABHCAYAAAAk5PTEAAAC4HRFWHRteGZpbGUAJTNDbXhmaWxlJTIwaG9zdCUzRCUyMjE3Mi4yNS4xNjEuMjExJTIyJTIwbW9kaWZpZWQlM0QlMjIyMDIxLTExLTA4VDA3JTNBNDglM0EzMC4wMzdaJTIyJTIwYWdlbnQlM0QlMjI1LjAlMjAoWDExKSUyMiUyMGV0YWclM0QlMjJ4MTM1OUpQR29sZ21udEFCTFIxSCUyMiUyMHZlcnNpb24lM0QlMjIxNS42LjIlMjIlMjB0eXBlJTNEJTIyZGV2aWNlJTIyJTNFJTNDZGlhZ3JhbSUyMGlkJTNEJTIyNEd0aVp4cWRuemJnanpmMC0zXzElMjIlMjBuYW1lJTNEJTIyUGFnZS0xJTIyJTNFalpKTlQ4UWdFSVolMkZUWThtTFdqdFhsMjdidHg0cXNaNEpHVXNKTFEwTEYxYWY3MVVwbCUyRlpiT0tKNFprUFp0NGhvdnU2ZnpHc0ZXJTJCYWc0cEl6UHVJUGtlRWtEZ2wlMkZoakpFRWlTa0N5UXlraU9iQUdGJTJGQUdFTWRKT2NqaHZBcTNXeXNwMkMwdmRORkRhRFdQR2FMY04lMkI5WnElMkIyckxLcmdDUmNuVU5mMlUzSXBBTSUyRks0OENQSVNrd3ZKJTJCa3VlR28yQmVNa1o4RzRkaXRFODRqdWpkWTJXSFclMkZCeldxTiUyQmtTOGc0M3ZITmpCaHI3bjRRRFl6S1Z1OVBISlQ5JTJCdVpOOUw5enJIVmE1TU5YaHdOaXNIU1lGak80YURtT1JPS0pQVGtnTFJjdkswZXY4MGowVHRsYiUyQmxuZ1R5NEd4ME4lMkZzTTVtbjklMkY4R2RBM1dERDRFRSUyQmpEZlVqQkwwTXpGTkF0JTJCaWVUcUdLbGZZcU00Y3FydWZTaWlqZFFtT202TE9EUHQlMkZySE5QOEYlM0MlMkZkaWFncmFtJTNFJTNDJTJGbXhmaWxlJTNFUXJoXAAAAKNJREFUeJzt0rENACEQwDD2X5rvUoOe6mRL2SBrAQDAA1vjO7aZywzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzEDMQMxAzkegaNDwAA/vkAmk+zV9RvOdkAAAAASUVORK5CYII=')
#end
#if($xcontext.action == 'edit')

{{html}}
<img
  class="drawio"
  style="cursor: default"
  src="data:image/png;base64,$wikimacro.content"
/>
<script>
//<![CDATA[
    document.addEventListener('dblclick', function(evt)
    {
      var url = 'http://172.25.161.211/?embed=1&ui=atlas&spin=1&modified=unsavedChanges&proto=json';
      var source = evt.srcElement || evt.target;

      if (source.nodeName == 'IMG' && source.className == 'drawio'){
        if (source.drawIoWindow == null || source.drawIoWindow.closed) {
        // Implements protocol for loading and exporting with embedded XML
        var receive = function(evt) {
          if (evt.data.length > 0 && evt.source == source.drawIoWindow) {
            var msg = JSON.parse(evt.data);
            // Received if the editor is ready
            if (msg.event == 'init') {
              // Sends the data URI with embedded XML to editor
              source.drawIoWindow.postMessage(JSON.stringify({action: 'load', xmlpng: source.getAttribute('src')}), '*');
              }
            // Received if the user clicks save
            else if (msg.event == 'save')
            {
              // Sends a request to export the diagram as XML with embedded PNG
              source.drawIoWindow.postMessage(JSON.stringify(
                {action: 'export', format: 'xmlpng', spinKey: 'saving'}), '*');
            }
            // Received if the export request was processed
            else if (msg.event == 'export')
            {
              // Updates the data URI of the image
              // TODO save to xwiki server as macro's content 
              source.setAttribute('src', msg.data);
            }

            // Received if the user clicks exit or after export
            if (msg.event == 'exit' || msg.event == 'export')
            {
              // Closes the editor
              window.removeEventListener('message', receive);
              source.drawIoWindow.close();
              source.drawIoWindow = null;
            }
          }
        };

        // Opens the editor
        window.addEventListener('message', receive);
        source.drawIoWindow = window.open(url);
      }
      else
      {
        // Shows existing editor window
        source.drawIoWindow.focus();
      }
    }
  });
// ]]>
</script>
{{/html}}

#else
{{html}}
<img src="data:image/png;base64,$wikimacro.content" />
{{/html}}
#end
{{/velocity}}

Solution

  • In XWiki the insertion of web resources like css and js content is generally done separately through what is called "skin extensions", best is probably to look at the documentation on https://extensions.xwiki.org/xwiki/bin/view/Extension/Skin%20Extension%20Plugin.

    In short, it involves adding an object of type XWiki.JavaScriptExtention in the page holding your macro and reference to it in your macro's code.

    Note that an extension which integrate draw.io already exist on https://extensions.xwiki.org/xwiki/bin/view/Extension/Diagram%20Application, and I guess looking at the source of this extension might be interesting.