功能不适用于新创建的菜单

functionality is not working for newly created menu

我正在 Oxygen Web-Author 上创建 Link 菜单,已经有两个名为 "ulink" 和 "uri" 的菜单。当我包含名为外部参照的第三个菜单时,外部参照的功能无法正常工作,它在氧气 framework.js.

中使用 "ulink" 功能
var insertWebLinkActionId =
      sync.docbook.DocbookExtension.prototype.version == 5 ? "insert.web.link" : "insert.web.ulink";
    var originalInsertWebLinkAction = actionsManager.getActionById(insertWebLinkActionId);
    if(originalInsertWebLinkAction) {
      var webLinkOperationClass = sync.docbook.DocbookExtension.prototype.version == 5 ?
        "ro.sync.ecss.extensions.docbook.link.InsertExternalLinkOperation" :
        "ro.sync.ecss.extensions.docbook.link.InsertULink";
      var insertWebLinkAction = new sync.actions.InsertWebLink(
        originalInsertWebLinkAction,
        webLinkOperationClass,
        editor,
        'url_value');
      actionsManager.registerAction(insertWebLinkActionId, insertWebLinkAction);
    }

这里已经用上面的代码插入了菜单,其中insert.web.linkinsert.web.ulink代表translation.xml

中的相应菜单
<key type="action" value="insert.web.ulink">
        <comment>Insert Link action name.</comment>
        <val lang="en_US">Web Link (ulink)...</val>
 </key>
...
<key type="action" value="insert.cross.reference.xref">
        <comment>Insert Link action name.</comment>
        <val lang="en_US">Cross reference (xref)...</val>
</key>

所以我想插入外部参照菜单到javascript,外部参照菜单和class路径代表insert.cross.reference.xrefro.sync.ecss.extensions.docbook.link.InsertXrefOperation对应。

您可以在 DocBook 框架扩展中实现您自己的 "Insert Cross Reference (xref)" 操作版本。为此,您需要:

  1. 创建一个自定义操作,提示用户选择目标文件和目标元素的 ID。此操作的代码需要添加到框架的 "web" 文件夹中的新 JS 文件中。您可以在下面找到一个最小的工作示例:
var DocBookCrossRefXrefAction = function (editor) {
  sync.actions.AbstractAction.call(this);
  this.editor = editor;
  this.xrefTargetsDialog = null;
};
DocBookCrossRefXrefAction.prototype = 
  Object.create(sync.actions.AbstractAction.prototype);
DocBookCrossRefXrefAction.prototype.constructor = DocBookCrossRefXrefAction;

DocBookCrossRefXrefAction.prototype.getDisplayName = function () {
  return 'Insert cross reference (xref)';
};

DocBookCrossRefXrefAction.prototype.actionPerformed = function (callback) {
  // This callback might have to be called at a later point, so save it until then.
  this.callback = callback || function () {};

  var chooser = workspace.getUrlChooser();
  var context = new sync.api.UrlChooser.Context(sync.api.UrlChooser.Type.EXTERNAL_REF);
  chooser.chooseUrl(context, this.showXrefTargetChooser.bind(this), 
    sync.api.UrlChooser.Purpose.CHOOSE);
};

DocBookCrossRefXrefAction.prototype.showXrefTargetChooser = function (url) {
  if (url) {
    // Create a dialog to display all targets, so the user can select one to insert 
    // cross reference.
    this.xrefTargetsDialog = this.createXrefTargetsDialog();
    this.populateXrefTargetsDialog(url);

    this.xrefTargetsDialog.onSelect(function (key, e) {
      if (key === 'ok') {
        e.preventDefault();
        this.xrefTargetChosen();
      } else {
        this.callback();
      }
    }.bind(this));
    this.xrefTargetsDialog.show();
  } else {
    this.callback();
  }
};

DocBookCrossRefXrefAction.prototype.createXrefTargetsDialog = function () {
  var dialog = workspace.createDialog();
  dialog.setTitle('Choose cross reference');
  dialog.setButtonConfiguration(sync.api.Dialog.ButtonConfiguration.OK_CANCEL);
  dialog.setPreferredSize(700, 500);
  dialog.setResizable(true);
  return dialog;
};

DocBookCrossRefXrefAction.prototype.populateXrefTargetsDialog = function (url) {
  this.editor.getActionsManager()
    .invokeOperation('ro.sync.servlet.operation.FindXrefTargetsOperation', {url: url})
    .then(function(str) { return JSON.parse(str);})
    .then(this.xrefTargetsReceived.bind(this))
};

DocBookCrossRefXrefAction.prototype.xrefTargetsReceived = function (targets) {
  var container = this.xrefTargetsDialog.getElement();
  if (!targets || !targets.length) {
    container.textContent = 'No cross reference targets found in the chosen file';
  } else {
    for (var i = 0; i < targets.length; i++) {
      var radio = document.createElement('input');
      radio.name = 'docbook-ref-table-radio';
      radio.type = 'radio';
      radio.dataset.id = targets[i].id;

      var label = document.createElement('label');
      label.style = 'display: block';
      label.appendChild(radio);
      label.appendChild(document.createTextNode(targets[i].nodeName + ' (#' + 
        targets[i].id  + ') - ' + targets[i].content.substring(0, 50)));

      container.appendChild(label);
    }
  }
};

DocBookCrossRefXrefAction.prototype.xrefTargetChosen = function() {
  var targetRadio = this.xrefTargetsDialog.getElement().querySelector(
    'input[name="docbook-ref-table-radio"]:checked');
  if (targetRadio) {
    this.editor.getActionsManager().invokeOperation('InsertFragmentOperation',
      {fragment: '<xref linkend="' + targetRadio.dataset.id + '"/>'})
      .then(this.xrefInserted.bind(this));
  }
};

DocBookCrossRefXrefAction.prototype.xrefInserted = function () {
  this.xrefTargetsDialog && this.xrefTargetsDialog.dispose();
  this.callback();
};

DocBookCrossRefXrefAction.prototype.dispose = function() {
  this.xrefTargetsDialog && this.xrefTargetsDialog.dispose();
};

goog.events.listen(workspace, sync.api.Workspace.EventType.EDITOR_LOADED, function(e) {
  var editor = e.editor;
  goog.events.listen(editor, sync.api.Editor.EventTypes.ACTIONS_LOADED, function(e) {
    editor.getActionsManager().registerAction('insert.cross.reference.xref', 
      new DocBookCrossRefXrefAction(editor));
  });
});
  1. 此操作使用服务器端 AuthorOperationWithResult 从用户选择的文件中收集外部参照目标。您可以在下面找到此 Java 操作的代码:
package ro.sync.servlet.operation;

import java.net.URL;
import java.util.ArrayList;

import javax.xml.parsers.DocumentBuilder;

import org.codehaus.jackson.map.ObjectMapper;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import ro.sync.basic.util.URLUtil;
import ro.sync.ecss.extensions.api.ArgumentsMap;
import ro.sync.ecss.extensions.api.AuthorOperationException;
import ro.sync.ecss.extensions.api.webapp.AuthorDocumentModel;
import ro.sync.ecss.extensions.api.webapp.AuthorOperationWithResult;
import ro.sync.ecss.extensions.api.webapp.WebappRestSafe;
import ro.sync.xml.parser.ParserCreator;

@WebappRestSafe
public class FindXrefTargetsOperation extends AuthorOperationWithResult {

  @Override
  public String doOperation(AuthorDocumentModel model, ArgumentsMap args) 
      throws AuthorOperationException {
    String urlString = (String) args.getArgumentValue("url");
    try {
      URL url = URLUtil.addAuthenticationInfo(
        model.getAuthorAccess().getEditorAccess().getEditorLocation(), 
        new URL(urlString));
      InputSource is = new InputSource(url.toString());
      DocumentBuilder docBuilder = ParserCreator.newSchemaAwareDocumentBuilder();
      Document document = docBuilder.parse(is);

      ArrayList<XrefTarget> xrefTargets = new ArrayList<>();
      gatherXrefTargets(document, xrefTargets);
      return new ObjectMapper().writeValueAsString(xrefTargets);
    } catch (Exception e) {
      throw new AuthorOperationException(e.getMessage(), e);
    }
  }

  public static class XrefTarget {
    public final String id;
    public final String nodeName;
    public final String content;

    public XrefTarget(Element elem) {
      this.id = getIDValue(elem);
      this.nodeName = elem.getTagName();
      this.content = elem.getTextContent();
    }
  }


  private static void gatherXrefTargets(Node node, ArrayList<XrefTarget> xrefTargets) {
    if (node.getNodeType() == Node.ELEMENT_NODE) {
      Element elem = (Element) node;
      if (getIDValue(elem) != null) {
        xrefTargets.add(new XrefTarget(elem));
      }
    }
    NodeList childNodes = node.getChildNodes();
    for (int i = 0; i < childNodes.getLength(); i++) { 
      gatherXrefTargets(childNodes.item(i), xrefTargets);
    }
  }

  public static String getIDValue(Element elem) {
    NamedNodeMap attributes = elem.getAttributes();
    for (int i = 0; i < attributes.getLength(); i++) {
      Attr attribute = (Attr)attributes.item(i);
      // There are some ID attributes defined as such in the schema file.
      if (attribute.isId() || "xml:id".equals(attribute.getName()) || 
        "id".equals(attribute.getName())) {
        return attribute.getValue();
      }
    }
    return null;
  }
}

您需要编译此 Java class 并将其作为 JAR 文件添加到框架的 class 路径中。更多详情 here .