0

I have been trying to make a chrome extension that gives the meaning of the selected text using urban dictionary API. I have tried different approaches but unable to connect all the files for proper execution.

manifest.json

{
"manifest_version": 2,
"name": "Urban Dictionary",
"version": "0.1",
"description": "Dictionary based on Urban Dict.",

 "browser_action": {
   "default_popup": "popup.html"
  },
"icons": {
    "16": "images/images.jpg",
    "32": "images/images.jpg",
    "48": "images/images.jpg",
    "128":"images/images.jpg"
   },
  "permissions": [
    "tabs",
    "activeTab"
  ]
 


}

popup.html

<!doctype html>
<html>
  <head>
    <title>meaning</title>
   
  </head>
  <body>
    <h1>meaning</h1>
    <button id="test"></button>
    <script src="popup.js"></script>
    <script src="getword.js"></script>
  </body>
</html>

popup.js

chrome.tabs.executeScript(null, {file: "getword.js"},(results)=>{ console.log(results); } );

getword.js

var something;
var term = window.getSelection().toString()
fetch("https://mashape-community-urban-dictionary.p.rapidapi.com/define?term="+term, {
    "method": "GET",
    "headers": {
        "x-rapidapi-key": "My_API_KEY",
        "x-rapidapi-host": "mashape-community-urban-dictionary.p.rapidapi.com"
    }
})
.then(response => response.json()) 
.then(result => {
    console.log(result)
    something=result.list[0].definition
    
    }
)
.catch(err => {
    console.error(err);
});

console.log(something)
document.getElementById("test").innerHTML = something;

When trying to manipulate HTML using getword.js. The result comes out to be undefined. I would be highly obliged if anyone can help me in any way to refactor this code.

  • Does this answer your question? [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – SuperStormer May 09 '21 at 00:47

2 Answers2

1

In chrome extensions you always define your background scripts in manifest file otherwise it wont work. like this :

"background": {
    "scripts": [
      "back.js"
    ],
    "persistent": true
  },

Secondly Popup.js needs to be included in your pop.html like we normally do <script src="popup.js"></script>

and lastly there is another type of script that is called content script which also needs to be included in manifest to work at all. like this:

    "content_scripts": [
    {
      "js": ["jquery-3.5.0.min.js","content.js"]
    }
  ],

According to your need you should probably study content scripts i think.

  • Sorry for that I had included pop.js but just forgot to write here. The problem is i don't have any background work so no need for back.js and when defining content script the whole structure breaks – BemusedCat May 09 '21 at 01:50
0

There are several problems:

  • Injected code can't make cross-origin network requests.
  • getword.js's purpose is to be injected as a content script so it runs in the web page and thus shouldn't be listed in popup.html as the popup is a separate extension page in a separate window not related to the web page.

The solution is straightforward:

  1. get the selected text from the web page,
  2. transfer it to the popup script,
  3. make the network request and show the result.

manifest.json (MV2) should list the API site in permissions:

  "manifest_version": 2,
  "permissions": [
    "activeTab",
    "https://mashape-community-urban-dictionary.p.rapidapi.com/"
  ]

popup.html: remove getword.js from html and delete getword.js file.

popup.js:

const API_HOST = 'mashape-community-urban-dictionary.p.rapidapi.com';
const API_OPTS = {
  headers: {
    'x-rapidapi-key': 'My_API_KEY',
    'x-rapidapi-host': API_HOST,
  },
};

chrome.tabs.executeScript({
  code: 'getSelection().toString()',
}, async pageData => {
  try {
    const term = pageData[0].trim();
    if (!term) throw new Error('No selection!');
    const apiUrl = `https://${API_HOST}/define?term=${encodeURIComponent(term)}`;
    const apiRes = await (await fetch(apiUrl, API_OPTS)).json();
    const def = apiRes.list[0].definition;
    document.getElementById('test').textContent = def;
  } catch (e) {
    document.getElementById('test').textContent =
      chrome.runtime.lastError ? 'Cannot access this page' : e.message;
  }
});
wOxxOm
  • 65,848
  • 11
  • 132
  • 136