KyleMit
KyleMit

Reputation: 29909

Copy hyperlink to clipboard - generated string won't copy but new one will

I often want to save a whole group of links at a time with the url and title formatted into a single hyperlink I'm working on a chrome extension that will copy the formatted url and title

manifest.json

{
  "name": "Copy Tabs",
  "version": "0.1",
  "description": "Creates a keyboard shortcut (Ctrl + Shift + C) which copies links for selected tabs",
  "permissions": [
    "tabs",
    "clipboardWrite",
    "clipboardRead"
  ],
  "background": {
    "persistent": false,
    "scripts": ["jquery.js","background.js"]
  },
  "commands": {
    "copy-tabs": {
      "suggested_key": { "default": "Ctrl+Shift+C" },
      "description": "Copy Selected Tab Links"
    }
  },
  "manifest_version": 2
}

background.js

chrome.commands.onCommand.addListener(function(command) {
  if (command == "copy-tabs") {
    // declare text element
    var text = "";

    // only look for highlighted tabs in the current window
    queryInfo = new Object();
    queryInfo.highlighted  = true;
    queryInfo.currentWindow  = true;

    // get tabs
    chrome.tabs.query(queryInfo, function(tabs) {
        // loop through tab results
        for (var i = 0; i < tabs.length; i++) {
            //add hyperlink to text
            text += "<a href='" + tabs[i].url + "'>" + tabs[i].title + "</a>";
        }
    });

    //copy text to clipboard
    copyTextToClipboard(text);
  }
});

copyTextToClipboard

// Copy provided text to the clipboard.
function copyTextToClipboard(text) {
    var copyFrom = $('<textarea/>');
    copyFrom.text(text);
    $('body').append(copyFrom);
    copyFrom.select();
    document.execCommand('copy');
    copyFrom.remove();
}

Issues:

I have two problems: When I construct the link from the tab properties, the copy won't actually work, but if I manually specify that text = "<a href='www.google.com'>Google</a>"; everything works fine. In the developer tools, the inline tool tip looks like the text is properly formed, but the local variable window looks like the text variable is still set as "".

Inline Watch Scope Variables

Secondly, when it does paste, i don't get nice formatting.

It just looks like this:

But what I want is this:

Upvotes: 2

Views: 1266

Answers (1)

Rob W
Rob W

Reputation: 348992

Regarding the two issues:

  1. chrome.tabs.query is asynchronous. If you don't understand this, read this similar question. The solution is to move copyTextToClipboard(text); inside the callback of chrome.tabs.query.
  2. You're running execCommand('copy') on a textarea. The result is that only plain text is copied to the clipboard.
    Assuming that the HTML input comes from a trusted, you can use the following code to copy custom rich text to the clipboard:

    function copyTextToClipboard(html) {
        var tmpNode = document.createElement('div');
        tmpNode.innerHTML = html;
        document.body.appendChild(tmpNode);
    
        // Back up previous selection
        var selection = window.getSelection();
        var backupRange;
        if (selection.rangeCount) {
            backupRange = selection.getRangeAt(0).cloneRange();
        }
    
        // Copy the contents
        var copyFrom = document.createRange();
        copyFrom.selectNodeContents(tmpNode)
        selection.removeAllRanges();
        selection.addRange(copyFrom);
        document.execCommand('copy');
    
        // Clean-up
        tmpNode.parentNode.removeChild(tmpNode);
    
        // Restore selection
        selection = window.getSelection();
        selection.removeAllRanges();
        if (backupRange) {
            selection.addRange(backupRange);
        }
    }
    

Upvotes: 2

Related Questions