0

First of all, for better undestanding, I want to discribe what exactly functionality i need to from my extension:

  1. I open some site [stackoverflow.com || github.com || some else forum] then i need to write text with images as illustrations.
  2. I open some other window from what I need to do screenshot.
  3. I create screenshot with Snipping Tool (which place image data to clipboard after screenshoting)
  4. I`m back to previously opened site
  5. I [open context menu and choose my custom item in it || click on icon of my browser extension and click on button in it || just use ctrl+v hotkeys]
  6. My extension now must go to work and upload image data from clipboard to my own server and paste ready formatted for markdown or bbcode text with url to image.
  7. In options i will can choose what kind of formated text I need to paste.

At this moment, I have this files on my server:
index.html

<button id="pastenupload" type="button" onclick="pastenupload()">SEND FROM CLIPBOARD</button>
<script>
function pastenupload() {
    navigator.permissions.query({ name: "clipboard-read" }).then((result) => {
        if (result.state == "granted" || result.state == "prompt") {
            navigator.clipboard.read().then((data) => {
                for (let i = 0; i < data.length; i++) {
                 if (!data[i].types.includes("image/png")) {
                        alert("Clipboard contains non-image data. Unable to access it.");
                    } else {            
                        data[i].getType("image/png").then((blob) => {
                        fetch(`pastenupload.php`, {method:"POST", body:blob})
                            .then(response => console.log(response.text()))  
                        });
                    }
                }
            });
        }
    });
}
</script>

pastenupload.php

<?php
    header('Access-Control-Allow-Origin: *');
    header('Access-Control-Allow-Methods: GET, POST, DELETE, PUT, PATCH, OPTIONS');
    header("Access-Control-Allow-Headers: X-Requested-With");
    // gets entire POST body
    $data = file_get_contents('php://input');
    // write the data out to the file
    $fp = fopen("/path/to/my/file/myfile.png", "wb");

    fwrite($fp, $data);
    fclose($fp);
    echo 'Good Done!';
?>

This work as expected. If image data in clipboard, after press button image stores in selected folder on my server.

Now I try to create chrome browser extension based on the "Getting Started Example" with this files:

manifest.json

{
  "name": "Paste&Upload",
  "description": "Paste copied image direct into server!",
  "version": "1.0",
  "manifest_version": 3,
  "permissions": ["storage", "activeTab", "scripting", "clipboardRead", "tabs"],
  "host_permissions": ["<all_urls>"],
  "action": {
    "default_popup": "pu_popup.html",
    "default_icon": {
      "16": "/images/get_started16.png",
      "32": "/images/get_started32.png",
      "48": "/images/get_started48.png",
      "128": "/images/get_started128.png"
    }
  },
  "icons": {
    "16": "/images/get_started16.png",
    "32": "/images/get_started32.png",
    "48": "/images/get_started48.png",
    "128": "/images/get_started128.png"
  }
}

pu_popup.html

<!DOCTYPE html>
<html>
  <head>
    <link rel="stylesheet" href="pu_button.css">
  </head>
  <body>
    <button id="changeColor"></button>
    <script src="pu_popup.js"></script>
  </body>
</html>

pu_popup.js

changeColor.onclick = myFunction;

function myFunction() {
  console.log('Is start!');
  navigator.clipboard.read().then((data) => {
    console.log('Is read!')
    for (let i = 0; i < data.length; i++) {
     if (!data[i].types.includes("image/png")) {
        console.log('Is non blob!');
      } else {           
        data[i].getType("image/png").then((blob) => {
        console.log('Is blob!')
        fetch('https://myserver/pasteupload.php', {method:"POST", body:blob}).then(response => console.log(response.text()))  
        });
      }
    }
  });
}

I click on icon of my extension, click on changeColor button, and in dev.tools I see

forms.html:1 Uncaught (in promise) DOMException: Document is not focused.

What I need to change to Document became is focused? Or do I need to look for another approach to solving my problem?

As for the my 6th point, I think I won’t have any problems with it, I indicated it simply for a more accessible understanding of the functionality of the extension that I want to make.

In general, the only thing that interests me is how to properly organize the transfer of image data to my server?

Thanks!


In pu_popup.js I trying change code for click event like this:

changeColor.addEventListener("click", pastenupload());

.

changeColor.addEventListener("click", {
  pastenupload();
});

.

changeColor.addEventListener("click", async () => {
  pastenupload();
});

.

changeColor.addEventListener("click", async () => {
  chrome.scripting.pastenupload();
});

But with no luck. The first three options do not produce errors, but they do nothing. I click and nothing happens.

The last option generates an error

Uncaught (in promise) TypeError: chrome.scripting.pastenupload is not a function

I try to another option - context menus. I add

"background": {"service_worker":"pu_worker.js"}

to the manifest.

Create
pu_worker.js

chrome.contextMenus.create({
    id: "context1",
    title: "Markdown",
    contexts: ["all"]
});



chrome.contextMenus.onClicked.addListener(function(info, tab) {
    console.log(info.menuItemId);
    navigator.permissions.query({ name: "clipboard-read" }).then((result) => {
    if (result.state == "granted" || result.state == "prompt") {
      navigator.clipboard.read().then((data) => {
        for (let i = 0; i < data.length; i++) {
         if (!data[i].types.includes("image/png")) {
            alert("Clipboard contains non-image data. Unable to access it.");
          } else {           
            data[i].getType("image/png").then((blob) => {
            fetch(`https://myserver/pasteupload.php`, {method:"POST", body:blob})
              .then(response => console.log(response.text()))  
            });
          }
        }
      });
    }
  });
});

And again with no luck :/ At this time, error is:

Uncaught (in promise) TypeError: Cannot read properties of undefined (reading 'read')

Looks like last error is the because of this two year old bug... Bad luck...

  • Remove executeScript and call pastenupload() directly. Note that the popup is a separate window so it has its own separate devtools console: right-click inside the popup and select "inspect" in the menu. – wOxxOm Apr 13 '22 at 10:54
  • Thanks! I was trying this (i edit my question and indicated the options that I tried). Unfortunately none of them work.. (( – taravasya_github Apr 13 '22 at 11:17
  • 1
    You need to do it in the popup e.g. changeColor.onclick=pastenupload; Note that the popup is a separate window so it has its own separate devtools console: right-click inside the popup and select "inspect" in the menu. – wOxxOm Apr 13 '22 at 14:22
  • In pu_popup.js ? Thanks, I try this.. And I understood, what for popup i must use separate dev.tool window. But.. nothig changes. And I try **changeColor.onclick = pastenupload;** With it, looks like no DOMExceptions, and other errors. But after some debug, I see what after **navigator.clipboard.read().then(...** nothing to happens in script. No errors and no callback. – taravasya_github Apr 13 '22 at 16:12
  • I've edit my question to match the current state of the code. When debugging the **pu_popup.js** file, the line **console.log('Is read!')** never appears in the console... So looks like **navigator.clipboard.read()** not working here.. – taravasya_github Apr 13 '22 at 16:21
  • Looks like a bug in Chrome. Use the [classic method via execCommand](https://stackoverflow.com/questions/6969403/why-is-document-execcommandpaste-not-working-in-google-chrome). – wOxxOm Apr 13 '22 at 16:33
  • Unfortunately, I don’t quite understand how this can help me, because I don’t need to paste from the buffer, I need to programmatically extract and transfer the contents of the clipboard to the server. I'm afraid I have to admit defeat here ... I'll just make a pinned tab, switching to which I just need to press the button and get the formatted text back to the clipboard. Anyway, thank you for trying to help me! – taravasya_github Apr 13 '22 at 16:41
  • I guess it won't help with images. – wOxxOm Apr 13 '22 at 17:36
  • Dang I'm over here wanting an extension that does this :P – CTS_AE Jun 10 '22 at 21:51

0 Answers0