0

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)

Joe Berg
  • 381
  • 3
  • 16
  • 1
    Maybe [`safari.application.activeBrowserWindow.activeTab.url`](https://stackoverflow.com/questions/14822404/safari-extension-to-obtain-url-from-address-bar) ? I know nothing about Safari extensions and that answer has 0 upvote so just in case it helps. – Jeto Dec 30 '18 at 08:52
  • Thanks Jeto, I have also tried with this but the issue for me is mainly that I am not sure how to communicate between my extensionbar.html, the global.html and the injected script correctly. I'm afraid I'm lost. :) – Joe Berg Dec 30 '18 at 13:57

1 Answers1

1

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

horimislime
  • 106
  • 2
  • 6
  • Thanks a lot! This will surely get me in the right direction. I just need to read up on some swift now it seems. :) Marking this as answer. – Joe Berg Feb 10 '19 at 07:48