如何在XULRunner中向浏览器元素添加复制/粘贴上下文菜单?

时间:2011-04-08 16:57:17

标签: contextmenu xulrunner

我想允许基于XULRunner的应用程序的用户能够通过上下文菜单进行复制/粘贴。 键盘快捷键Ctrl-C和Ctrl-V已经正常工作

3 个答案:

答案 0 :(得分:1)

使用以下代码创建菜单。

<popupset>
<menupopup id="clipmenu">

      <menuitem label="Copy" oncommand="copy();"/>
     <menuseparator/>
     <menuitem label="paste" oncommand="paste();"/>
</menupopup>
</popupset>

 <browser type="content" src="chrome://myapp/content/theme1/index.html" flex="1" context="clipmenu"/>

将它连接到你想要的任何东西,这里通过在浏览器元素的context属性中给出menu的id来使它成为浏览器元素的上下文菜单。

然后,对于每个菜单,您可以命令在oncommand事件中执行。我们已经给出了复制和粘贴功能。

然后编写代码以从您想要的任何元素复制文本,或者只想复制所选数据。

请参阅以下链接以获取复制命令。

http://www.deluxeblogtips.com/2010/06/javascript-copy-to-clipboard.html

答案 1 :(得分:1)

这里没有闪光灯。 getInputSelection函数来自:Is there an Internet Explorer approved substitute for selectionStart and selectionEnd?

<?xml version="1.0"?>

<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>

<window id="mywin" title="my app" 
    width="800" height="600" persist="screenX screenY width height sizemode" 
    xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">

    <popupset>
        <menupopup id="clipmenu">
      <menuitem label="Copy" oncommand="copy()"/>
      <menuitem label="Paste" oncommand="paste();"/>
        </menupopup>
    </popupset>

    <browser
          type="content-primary"
      src="http://127.0.0.1/"
      flex="1"
      disablehistory="true"
      id="browserId"
      context="clipmenu"
      />
<script>
<![CDATA[

    function copy()
{
    var tabBrowser = document.getElementById("browserId");
    var selectedTagName = tabBrowser.contentWindow.document.activeElement.tagName;
    var windowObj;
    if(selectedTagName == "IFRAME")
{
  windowObj = tabBrowser.contentWindow.frames[tabBrowser.contentWindow.document.activeElement.name]; 
}
else
{
    windowObj = document.getElementById("browserId").contentWindow;
}

var selectedText = windowObj.getSelection();

if(!selectedText || selectedText == "")
{
    var focused = windowObj.document.activeElement;
    if(focused && focused.value)
    {
        selectedText = getSelectionFromInput(focused);
    }
}

//alert(selectedText + "---");

const clipHelper = Components.classes["@mozilla.org/widget/clipboardhelper;1"].getService(Components.interfaces.nsIClipboardHelper);
    clipHelper.copyString(selectedText);
}

function getSelectionFromInput(focused)
{
var focusedValue = focused.value;
var sel = getInputSelection(focused);
var selectedText = "";
if(focusedValue.length == (sel.end))
{
    selectedText = focusedValue.substring(sel.start);
}
else
{
    selectedText = focusedValue.substring(sel.start, (sel.end));
}

return selectedText;
}

  function paste()
  {
        var clip = Components.classes["@mozilla.org/widget/clipboard;1"].getService(Components.interfaces.nsIClipboard); 
    var trans = Components.classes["@mozilla.org/widget/transferable;1"].createInstance(Components.interfaces.nsITransferable); 
        trans.addDataFlavor("text/unicode"); 
        clip.getData(trans, clip.kGlobalClipboard); 
        var str = new Object(); 
        var len = new Object(); 
        trans.getTransferData("text/unicode",str,len); 
        str = str.value.QueryInterface(Components.interfaces.nsISupportsString); 
        str = str.data.substring(0, len.value / 2);

        var focused = document.commandDispatcher.focusedElement;
var focusedValue = focused.value; 
var sel = getInputSelection(focused);
focused.value = focusedValue.substring(0,sel.start) + str + focusedValue.substring(sel.end);
 }

function getInputSelection(el) {
var start = 0, end = 0, normalizedValue, range,
    textInputRange, len, endRange;

if (typeof el.selectionStart == "number" && typeof el.selectionEnd == "number") {
    start = el.selectionStart;
    end = el.selectionEnd;
} else {
    range = document.selection.createRange();

    if (range && range.parentElement() == el) {
        len = el.value.length;
        normalizedValue = el.value.replace(/\r\n/g, "\n");

        // Create a working TextRange that lives only in the input
        textInputRange = el.createTextRange();
        textInputRange.moveToBookmark(range.getBookmark());

        // Check if the start and end of the selection are at the very end
        // of the input, since moveStart/moveEnd doesn't return what we want
        // in those cases
        endRange = el.createTextRange();
        endRange.collapse(false);

        if (textInputRange.compareEndPoints("StartToEnd", endRange) > -1) {
            start = end = len;
        } else {
            start = -textInputRange.moveStart("character", -len);
            start += normalizedValue.slice(0, start).split("\n").length - 1;

            if (textInputRange.compareEndPoints("EndToEnd", endRange) > -1) {
                end = len;
            } else {
                end = -textInputRange.moveEnd("character", -len);
                end += normalizedValue.slice(0, end).split("\n").length - 1;
            }
        }
    }
}

return {
    start: start,
    end: end
};
}
]]>
</script>   
</window>

已更新以支持iframe。

答案 2 :(得分:1)

SWT浏览器下XULRunner中“复制”上下文菜单的另一个示例(代码是为Eclipse v3.5.1,XULRunner v1.8.1.3实现的):

Browser browser = new Browser(parent, style | SWT.MOZILLA);

Menu menu = new Menu(browser);
MenuItem item = new MenuItem(menu, SWT.NONE);
item.setText("Copy");
item.addSelectionListener(new SelectionListener() {
   @Override
   public void widgetSelected(SelectionEvent e) {
      nsIWebBrowser webBrowser = (nsIWebBrowser) browser.getWebBrowser();
      nsIInterfaceRequestor req = (nsIInterfaceRequestor) webBrowser.queryInterface(nsIInterfaceRequestor.NS_IINTERFACEREQUESTOR_IID);
      nsIDocShell docShell = (nsIDocShell) req.getInterface(nsIDocShell.NS_IDOCSHELL_IID);
      nsIClipboardCommands cmds = (nsIClipboardCommands) docShell.queryInterface(nsIClipboardCommands.NS_ICLIPBOARDCOMMANDS_IID);
      cmds.copySelection();
   }

   @Override
   public void widgetDefaultSelected(SelectionEvent e) {
   }
});
browser.setMenu(menu);