Search code examples
javascripthtmlsafari-extension

Copy window.location.href to clipboard from extension


I am trying to copy 'window.location.href' e.g. the URL of the current page to clipboard from my extension.

My issue is that when I copy the URL to clipboard, it is the extensions URL that is copied and not the page I am visiting.

Extensionbar:

<!DOCTYPE HTML>
<html>
    <head>
        <button onclick="copyFunction();">Copy</button>
        <script type="text/javascript">
          function copyFunction() {
          var inputDump = document.createElement('input'),
              hrefText = window.location.href;
          document.body.appendChild(inputDump);
          inputDump.value = hrefText;
          inputDump.select();
          document.execCommand('copy');
          document.body.removeChild(inputDump);
          }
        </script>
    </head>
</html>

From my understanding the solution should be this, but I fear I am too clueless how to proceed: https://developer.apple.com/documentation/safariservices/safari_app_extensions/passing_messages_between_safari_app_extensions_and_injected_scripts

This is how I (tried to) proceed, by creating a global.html page and an injected script.

Global page:

<!DOCTYPE HTML>
<script>
    safari.application.addEventListener("command", copyFunction, false);

    function copyFunctionEvent(event) {
        if (event.command == "CopyToClipboard") {
            safari.application.activeBrowserWindow.activeTab.page.dispatchMessage("CopyToClipboard", "all");

    }
}
</script>

Injected script:

function myextension_openAll(event){
    if (event.name == 'CopyToClipboard'){         
       function copyFunction() {
       var inputDump = document.createElement('input'),
           hrefText = window.location.href;
       document.body.appendChild(inputDump);
       inputDump.value = hrefText;
       inputDump.select();
       document.execCommand('copy');
       document.body.removeChild(inputDump);
       }

}
safari.self.addEventListener("message", myextension_openAll, true);

Actual: safari-extension://com.myextension-0000000000/abc123/extensionbar.html

Expected: http://www.google.com (e.g. if current tab)


Solution

  • From your code above (Extensionbar html), you seem to write legacy Safari extension (.safariextz), and it has been deprecated. See What’s New in Safari and WebKit" session on WWDC18

    I recommend you rewrite your code into Safari App Extension by following process, which can be written in Swift. I'm not sure why wrong URL is copied to clipboard in your code, but rewriting your code would solve the problem as a result.

    Creating App Extension project

    Create App Extension by following [File] -> [New] -> [Project...] then choose [Safari Extension App] on Xcode. Project template contains example of menubar implementation.

    Copying location.href by clicking menu bar button

    Following code would add functionality to copy location.href when you click menu bar button.

    Just paste this into SafariExtensionHandler.swift.

    class SafariExtensionHandler: SFSafariExtensionHandler {
    
        override func messageReceived(withName messageName: String, from page: SFSafariPage, userInfo: [String : Any]?) {
    
            // WHen injected script calls safari.extension.dispatchMessage, the message will come here
    
            guard let href = userInfo?["href"] as? String else { return }
    
            // Save href to clipboard
            NSPasteboard.general.clearContents()
            NSPasteboard.general.setString(href, forType: .string)
        }
    
        override func toolbarItemClicked(in window: SFSafariWindow) {
            // Request injected script a message to send location.href
            window.getActiveTab { currentTab in
                currentTab!.getActivePage { currentPage in
                    currentPage!.dispatchMessageToScript(withName: "getHref", userInfo: nil)
                }
            }
        }
    }
    
    

    And injected script (script.js) as follows.

    safari.self.addEventListener("message", function(event) {
      console.log("event received");
      safari.extension.dispatchMessage("sendHref", { "href": location.href });
    });
    

    Working Example

    Complete working code here, This may help your work. Good luck :)

    https://github.com/horimislime/safari-extension-menubar-example