0

I was trying to create a chrome extension that graps the text you highlighted in your page , replace some of its letters , then output it to text Field in the popup . my Main.js :

var letters = [
    'q','ض',
    'w','ص',
    'e','ث',
    'r','ق',
    't','ف',
    'y','غ',
    'u','ع',
    'i','ه',
    'o','خ',
    'p','ح',
    'a','ش',
    's','س',
    'd','ي',
    'f','ب',
    'g','ل',
    'h','ا',
    'j','ت',
    'k','ن',
    'l','م',
    'z','ئ',
    'x','ء',
    'c','ؤ',
    'v','ر',
    'b','لا',
    'n','ى',
    'm','ة',
    '[','ج',
    ']','د',
    ';','ك',
    ',','و',
    '.','ز',
    '/','ظ',
    "'",'ط',
    ' ',' ',
    '1','1',
    '2','2',
    '3','3',
    '4','4',
    '5','5',
    '6','6',
    '7','7',
    '8','8',
    '9','9',
    '0','0'
     ];//all the used charchters
var lastSelect = null;
var outBox = document.getElementById('copy_box');
outBox.value = null;
function con(english) {//convert from english to arabic
    var aoutput = new Array;
    var chars = english.split(''); 
    for(var i = 0; i < chars.length; i++){
        aoutput.push(letters[letters.indexOf(chars[i])+1]);
    }
    var ar = aoutput.join();
    var res = ar.replace(/,/g,'');
    return res;
}
let getText = new Promise(function(resolve, reject){
  chrome.tabs.executeScript({
      code: "window.getSelection().toString();"
  }, function(results){ 
    lastSelect = results;
  });
  if(lastSelect == undefined){
      reject("You Didn't Select Text!");
  }else{
      resolve(lastSelect);
  }
});

getText.then(function(Resolve){
  outBox.value = con(Resolve);
}).catch(function(reject){
  outBox.value = reject;
});
body{
 background-color:#f39c12;
 font-family:'Roboto Mono', monospace;
 font-size:13px;
 margin:20px;
 padding:0px;
    min-height: 300px;
    width: 300px;
}
h1{
  color:#2ecc71;
  text-shadow:
   -1px -1px 0 #000,
  1px -1px 0 #000,
  -1px 1px 0 #000,
  1px 1px 0 #000;
}
#copy_box{
    outline:none;
 height:20px;
 width:290px;
 border:none;
 border-radius:10px;
padding: 10px;
}
#arabic
{
 outline:none;
 background-color:#e67e22;
 border:none;
 width:100px;
 height:30px;
 margin: 0px;
  padding:0px;
  }
 #english
{
 outline:none;
 background-color:#e67e22;
 border:none;
 width:100px;
 height:30px;
 margin:0px;
 padding:0px;
 }
hr {
    background-color: #d35400;
    color: #d35400;
    height: 2px;
}
#cpy-btn {
    padding-top: 10px;
    padding-bottom: 10px;
    outline: none;
    width: 100%;
    background-color: #f39c12;
    color: #d35400;
    border: solid #d35400 3px;
    font-size: 20px;
    letter-spacing: 3px;
    transition: all 0.5s ease;
    cursor: pointer;
}
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>English to Arabic Converter</title>
    <link href="https://fonts.googleapis.com/css?family=Roboto+Mono&display=swap" rel="stylesheet"><!--google Fonts cdn-->
    <link href="popup.css" rel="stylesheet" type="text/css"><!--my Css File-->
</head>
<body>
    <img src="Icon.png">
    <h1>key shifter</h1>
    <hr></hr>
    <p>selcet text press ctrl + shift + language letter to shift text to it</p>
    <input type ="text" id ='copy_box' placeholder="your converted text will apear here"><br><br />
    <button id="cpy-btn">Copy This!</button>
    <br />
    <hr></hr>
    <p>languages Supported :</p>
    <input type ="button" value = "Arabic" id = "arabic">
    <input type ="button" value = "English" id = "english">
    <script src ="main.js"></script><!--my Main Js Script-->
</body>
</html>

problem is : the chrome.tabs.executeScript() is asynchronous so the response from the page comes after executing the outBox.value = con(lastSelect); (lastSelect is undefined) , So i tried to use a promise but it's always Rejected but still the return from chrome.tabs.executeScript() is undefined so its Rejected ,

Why chrome.tabs.executeScript() returns undefined even inside the promise ?

some debugging details : when i enter the chrome console and type lastSelect and the execute the return is the expected, so i run con(lastSelect); and the output is the expected.

EDIT: I think there wouldn't be a problem if the script waited for the response from the page to come back , it will be a matter of milliseconds

tehhowch
  • 9,645
  • 4
  • 24
  • 42
White Death
  • 408
  • 5
  • 12
  • Possible duplicate of [Why is my variable unaltered after I modify it inside of a function? - Asynchronous code reference](https://stackoverflow.com/questions/23667086/why-is-my-variable-unaltered-after-i-modify-it-inside-of-a-function-asynchron) – Ivar Sep 14 '19 at 12:18
  • As you said `chrome.tabs.executeScript()` is asynchronous. So `lastSelect == undefined` will be executed _before_ the `lastSelect = results` in your callback. – Ivar Sep 14 '19 at 12:20
  • 1
    Simply move the entire if(lastSelect == undefined){....} else {...} block right after lastSelect = results; – wOxxOm Sep 14 '19 at 12:39
  • tried what wOxxOm said but ended having this error `Uncaught (in promise) TypeError: english.split is not a function` – White Death Sep 14 '19 at 12:58
  • 1
    @WhiteDeath According to [the documentation](https://developer.chrome.com/extensions/tabs#method-executeScript), the parameter of the callback of `executeScript()` is an array of results, not a string. So you probably need to use something like `var chars = english[0].split(''); `. (Or alternatively instead of `resolve(lastSelect);` you can use `resolve(lastSelect[0]);`.) – Ivar Sep 14 '19 at 13:20

0 Answers0