chrome extension opening browser popup window displays blank screen - javascript

I have a chrome extension which does the following:
When a user copies a word, a popup window opens with a specific url, searching the word in a dictionary. If the popup window already exists, it removes it and recreates it (if you ask why, the answer is: because chrome.windows.update() does not take URL as a parameter so I cannot simply update the window with a new URL).
The problem is: If the user is in another application (like MS Word) and copies a word, when the user clicks on the taskbar icon of the browser (chrome) popup window to bring it on the front, then Chrome does not paint the content of the page, it only displays the title of the page. If the user closes with the X button the popup window though, there is no problem. It happens only if the user just clicks back on MS Word to continue writing and then copies another word, without previously manually closing the popup window. The code is:
g_iIntervalID = setInterval(getClipboardText, 500);
function getClipboardText() {
g_oTA.select();
g_oBG.document.execCommand("Paste");
var clipText = g_oTA.value;
if (g_bOpenWindow) {
clipText = cleanWord(trim(clipText));
if (clipText != "" && clipText.length <= 64 && clipText != g_sPrevClipText && clipText != g_sWord) {
if (g_bClipFirstTime == false) {
g_sWord = clipText;
openLink();
}
g_sPrevClipText = clipText;
}
g_bClipFirstTime = false;
}
}
function openLink() {
chrome.windows.getAll(onWindowsQueryReply);
}
function onWindowsQueryReply(windows) {
var bWindowFound = false;
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError);
} else {
if (g_iCreatedWindowID != 0 && windows.length > 0) {
var wnd;
for (var i = 0; i < windows.length; i++) {
wnd = windows[i];
if (g_iCreatedWindowID == wnd.id) {
bWindowFound = true;
var r = chrome.windows.remove(g_iCreatedWindowID, function() {
CreateWindow();
return;
});
}
}
}
if (bWindowFound === false) CreateWindow();
}
}
function CreateWindow() {
clearInterval(g_iResizeIntervalID);
var createData = {
state: "normal",
url: "https://www.example.com/search.php?word=" + g_sWord,
type: "popup",
top: g_iWinT,
left: g_iWinL,
height: g_iWinH,
width: g_iWinW
};
var creating = chrome.windows.create(createData, onWinCreated);
}
function onWinCreated(win) {
if (chrome.runtime.lastError) {
console.log(chrome.runtime.lastError);
} else {
g_iCreatedWindowID = win.id;
//console.log(g_iWinW + "#" + g_iWinH + "#" + g_iWinT + "#" + g_iWinL + "###The panel has been created"+JSON.stringify(win));
var updateData = {
state: "normal",
top: g_iWinT,
left: g_iWinL,
drawAttention: true,
focused: true
};
var updating = chrome.windows.update(win.id, updateData);
g_iResizeIntervalID = setInterval(getWindowSize, 200);
}
}
Steps:
User is using an app like MS Word
User double clicks a word and ctrl-c or right-click copies it.
When this happens then openLink() runs
The extension removes the current popup window (if it exists) and then creates a new one with a URL
A small icon for the new popup window appears flashing in the taskbar
The first time, the popup window comes automatically in front. The user reads then necessary information
The user clicks back on MS Word to continue work
The user marks another word and copies it
The extension opens another new popup window. This window for some reason does not come on front like the first time, but this is not the main problem. The user has to click its taskbar icon to bring it in front.
The user clicks the icon of the popup window in the taskbar in order to bring it to front.
The popup window comes to front, but it displays a blank page (except for the title).
Comments:
Chrome paints the contents ONLY if I click on the title bar and drag the window a bit OR if I hover the mouse on the icon of the pop up window in the taskbar so that a preview is displayed.
If the user closes the popup window with the X button, then the problem does not arise the next time he copies a word (plus the popup window goes automatically in front/focus, so none of the problems appears).
I have tried many things:
inserting async delays with setTimeout before creating and updating the pop window
repositioning and resizing the popup window in onWinCreated()
repositioning and resizing after the first chrome.windows.update()
But all these efforts in trying to trigger/force Chrome paint the window, have failed. Am I doing something wrong? How can I fix this issue? Also, why the first time when the popup opens, it comes automatically in front (or if I closed the previous popup manually)? But when it gets programmatically removed, it does not? Can this also be solved?
Thank you in advance

Related

EventListener with delay or fire on load of class

I am tweaking the code of a chrome extension to display the content of a page element in the tab title and scroll it fir navigating open ticket tabs easer. As below
// Need to change this, mousemove listener is super harsh on resource
document.addEventListener("mousemove", function() {
// call the banner element
let bannerTextElements = document.getElementsByClassName("cw_BannerView");
// console.log(bannerTextElements);
// console.log(bannerTextElements[0]);
if (bannerTextElements[0]) {
// console.log("ok");
// console.log(bannerTextElements[0].innerHTML);
// Find and get ticket detail
let bannerTextLine = bannerTextElements[0].getElementsByClassName("detailLabel");
// console.log(bannerTextLine);
if (bannerTextLine[0]) {
// console.log(bannerTextLine[0].innerHTML);
// Trim "Service Ticket for cleanness Need to do this for 'Manage' too"
let tickettext = bannerTextLine[0].innerHTML.split("Manage ");
let tickettext1 = bannerTextLine[0].innerHTML.split("Service Ticket ");
// console.log(tickettext[0]);
// console.log(tickettext[1]);
// Set the title equal to everything after "Service Ticket"
if (tickettext1[1]) {
document.title = tickettext1[1];
// now works!! bit clunky though
var documentTitle = tickettext1 + " - ";
(function titleMarquee() {
document.title = documentTitle = documentTitle.substring(1) +
documentTitle.substring(0,1);
setTimeout(titleMarquee, 160);
})();
} else {
// For everything else, just display what's already there
document.title = tickettext1[0];
}
}
}
}, false);
(ignore the appalling indents i promise thats just on this post! )
However, due to the slow page load the only eventlistener i can get to pick the content of the banner text is 'mousemove' which naturally has the negative side effects of A. Firing infinite times as you view the page and also resetting the scroll to the start as you mouse over.
document.OnLoad and window.onload just stops this working and it loads the default tab title
Is there a way to get onLoad to run after an arbitrary delay, say 10s or to check to make sure that the classname cw_bannerview is loaded up and populate with the ticket title?

Window.open() not working + how to close a tab

I am trying to make it so when someone goes onto my codepen --> https://codepen.io/Mike-was-here123/pen/gXMrJO , the window opens itself. Basically a infinite loops opening and closing itself, this is my JS/ jQuery code:
I added comments in the code on the codepen.
$(document).ready(function() {
if (document.URL !== "https://codepen.io/Mike-was-here123/full/ooLxmQ/") {
window.open("https://codepen.io/Mike-was-here123/full/ooLxmQ/");
}
var one = 1;
if (1 === 1) {
window.open("https://codepen.io/Mike-was-here123/full/ooLxmQ/");
one += 1;
}
if (one !== 1) {
window.close();
}
});
Why doesn't the window open?
Also if i wanted to close the current tab because i just opened a new one, would i just use window.close()?
If you want to open an infinite number of web pages, just do this:
while (true) {
window.open("insert web page");
}

How to access content of a tab from firefox addon

In my addon I find the tab I want to operate and then try to access the elements of it.
Currently I am finding the tab I need by
var b = this.wm.getMostRecentWindow("navigator:browser");
// qqDPSWD This allows for correct window targeting.
var foundW = null;
var en = this.wm.getEnumerator("navigator:browser");
while (en.hasMoreElements()) {
var w = en.getNext();
if ((w.title && w.title.indexOf(parameters['title_identifier']) != -1) ||
(w.document && w.document.title.indexOf(parameters['title_identifier']) != -1))
{
var doc = w.document;
var temp2 = doc.getElementById("myframe");
foundW = temp2.contentWindow;
}
}
temp2 is null though the tab does have an iframe with id myframe.
I get the object doc as an XUL object but doc.getElementById("myframe") is null. Currently I have an html file opened in the desired tab with the desired iframe residing inside the html page loaded in the main tab. I am able to identify the tab properly but couldn't return the iframe window. How do I do it?
I tried looking at the documentation for browsing between the tabs but couldn't find right answer in https://developer.mozilla.org/en/docs/Working_with_windows_in_chrome_code
Node I am working on https://github.com/sebuilder/se-builder/blob/master/seleniumbuilder/components/command_processor.js#L10103 and want to replace
foundW = w;
with
foundW = w.document.getElementById("myframe").contentWindow
as unlike the open source project where he wants to return the tab window I want to return the iframe window present inside the tab he returns.
You aren't actually going through all tabs, you are just going through the FIREFOX windows (called CHROME windows) (not the browser and its window inside each tab).
In your code. var doc = w.document is the CHROME document of the FIREFOX window (not the browser inside the tab). So w.title of the FIREFOX window will be the title of the currently selected tab (probably followed by ' - Mozilla Fireox' can you verify this for me? im guessing here)
temp2 is null because your frame is in the BROWSER IN TAB window which is the HTML document. So if your tab is currently selected you would get it like this w.gBrowser.selectedTab.linkedBrowser.contentwindow this will be the html window. w.selectedTab is the actual tab element that you click at top, it has a property called linkedBrowser which holds the "HTML" browser which is inside this tab. (i put html
so to fix your code below:
var b = this.wm.getMostRecentWindow("navigator:browser");
// qqDPSWD This allows for correct window targeting.
var foundW = null;
var en = this.wm.getEnumerator("navigator:browser");
while (en.hasMoreElements()) {
var w = en.getNext();
if ((w.title && w.title.indexOf(parameters['title_identifier']) != -1) ||
(w.document && w.document.title.indexOf(parameters['title_identifier']) != -1))
{
var doc = w.gBrowser.selectedTab.linkedBrowser.contentDocument;
var temp2 = doc.getElementById("myframe");
foundW = doc.defaultView; //im not sure what you want foundW to be, the chrome window? or the tab html window? if you want html window or you can do doc.defaultView OR w.gBrowser.selectedTab.linkedBrowser.contentWindow BUT if you want the chrome window it would be w
}
}
HOWEVER your code has a problem, its not going through all tabs in each window, its only going through the currently selected tab.
This is how you would do it for each tab in each window, read the comments carefully, also i took out your ugly if statement lol it was making things sloppy. Just put it back i replaced with /*your if statement*/ for easyiness for me to make example below
var b = this.wm.getMostRecentWindow("navigator:browser");
// qqDPSWD This allows for correct window targeting.
var foundW = null;
var en = this.wm.getEnumerator("navigator:browser");
while (en.hasMoreElements()) {
var w = en.getNext();
//we know for sure that all your windows have gBrowser element because you are getting enumerator for 'navigator:browser', but its not necessary for it to have tabContainer, for example a pop up window with no tabs in it
if (w.gBrowser.tabContainer) {
for (var i = 0; i < w.gBrowser.tabContainer.childNodes.length; i++) { //this itereates through each tab element in the tab bar (so the thingies you click)
var tab = w.gBrowser.tabContainer.childNodes[i];
var tabBrowser = tab.linkedBrowser;
var tabDoc = tabBrowser.contentDocument;
var tabWin = tabDoc.defaultView; //OR you can do tabBrowser.contentWindow
if ( /*if statement here*/ ) {
var temp2 = tabDoc.getElementById("myframe");
foundW = tabWin; //im not sure what you want here so i set it to the html window
w.focus(); //if you want to focus this FIREFOX window which is chrome window do this:
w.gBrowser.selectedTab = tab[i]; //if you want to select this tab then do this
}
}
} else {
//it has no tabContainer so its like a popup window with no tabs so our browser elment is just gBrowser, ill use same var names as above to keep things straight for you
var tabBrowser = w.gBrowser;
var tabDoc = tabBrowser.contentDocument;
var tabWin = tabDoc.defaultView; //OR you can do tabBrowser.contentWindow
if ( /*if statement here*/ ) {
var temp2 = tabDoc.getElementById("myframe");
foundW = tabWin; //im not sure what you want here so i set it to the html window
w.focus(); //if you want to focus this FIREFOX window which is chrome window do this:
//w.gBrowser.selectedTab = tab[i]; //no tabs in this window so if you do w.focus() on line above it will focus this properly
}
}
}

Frame location change bug

I have successfully changed the location of frames on my page using commands like:
parent.bottomframe.location = 'interstitial.html';.
This one particular call, however, isn't working. I am calling a js function from the 'onclick' of a button in html. This function does most of its work successfully, and also successfully changes the text of my top frame using
parent.topframe.document.getElementById("tutorial").innerHTML = text;
But the bottom frame doesn't change. Could it be that I'm losing permission to change this property? If I put an alert() after the location-change line, I get back the old location, not the new one.
Any ideas?
(Here's the code for this function:)
function GetInterstitial(found_target)
{
parent.topframe.current_trial++;
if (found_target)
{
parent.topframe.correct++;
}
if (parent.topframe.current_trial==parent.topframe.total_trials)
{
UpdateData(parent.topframe.output);
setTimeout(function()
{SendAllData();}, 0
);
parent.topframe.document.getElementById("tutorial").innerHTML = thank_you_text[0]+parent.topframe.correct.toString()+'/'+parent.topframe.total_trials.toString()+thank_you_text[1];
parent.bottomframe.location.href = 'http://urlname..../js/thankyou.html?c='+parent.topframe.userID;
}
else
{
if (found_target)
text = "<p>Great job; you found the hidden number! Now click 'next' to play the next round.</p>";
else
text = "<p>Hmm... it seems you didn't find the hidden number. Click 'next' to play the next round.</p>";
}
setTimeout(function()
{
UpdateData(parent.topframe.output);
},600);
parent.topframe.document.getElementById("tutorial").innerHTML = text; //interstitial_text;
parent.bottomframe.location = 'interstitial.html';
parent.topframe.trial++;
parent.topframe.document.getElementById("nextbutton").style.display="block";
}

Javascript: open & close new window on image's onMouseOver & onMouseOut, but only if new window onMouseOver = true

thank you all for helping me previously with my Javascripting problems. My current problem is that I need to open & close a new window on an image's onMouseOver & onMouseOut, respectively, but if the new window onMouseOver == true then I don't want the new window to close.
I am sure there is a simple solution, but I can't seem to figure out a way to cancel the image's onMouseOut="closeDetails();" if the user hovers over the New Window. Below is most of the code I am dealing with. Thanks in advance for your help.
<body>
<img name="img1" id="img1" onMouseOver="windowDelay(this);"
onMouseOut="closeDetails();" src="images/127.jpg" height="240" width="166"/>
</body>
<script language="JavaScript" type="text/javascript">
// This opens the movie details pop-up after an
// half second interval.
function windowDelay(thatImg)
{
winOpenTimer = window.setTimeout(function() {openDetails(thatImg);}, 2000);
}
// This is the function that will open the
// new window when the mouse is moved over the image
function openDetails(thatImg)
{
// This creates a new window and uses the hovered image name as the window
// name so that it can be used in the that window's javascript
newWindow = open("", thatImg.name,"width=400,height=500,left=410,top=210");
// open new document
newWindow.document.open();
// Text of the new document
// Replace your " with ' or \" or your document.write statements will fail
newWindow.document.write("<html><head><title>Movies</title>");
newWindow.document.write("<script src='myDetails.js' type='text/javascript'>");
newWindow.document.write("</script></head>");
newWindow.document.write("<body bgcolor='white' onload='popUpDetails();'>");
newWindow.document.write("... SOME OTHER HTML....");
newWindow.document.write("</body></html>");
// close the document
newWindow.document.close();
}
// This is the function that will call the
// closeWindow() after 2 seconds
// when the mouse is moved off the image.
function closeDetails()
{
winCloseTimer = window.setTimeout("closeWindow();", 2000);
}
// This function closes the pop-up window
// and turns off the Window Timers
function closeWindow()
{
// If popUpHover == true then I do not want
// the window to close
if(popUpHover == false)
{
clearInterval(winOpenTimer);
clearInterval(winCloseTimer);
newWindow.close();
}
}
function popUpDetails()
{
// This will be used to prevent the Details Window from closing
popUpHover = true;
// Below is some other javascript code...
}
</script>
I would recommend against using a new browser window for this task. Try something like this:
var popup = {
open = function () {
if (this.element == null) {
// create new div element to be our popup and store it in the popup object
this.element = document.createElement('div');
this.element.id = "myPopup";
// you don't need a full html document here. Just the stuff you were putting in the <body> tag before
this.element.innerHTML = "<your>html</here>";
// Some bare minimum styles to make this work as a popup. Would be better in a stylesheet
this.element.style = "position: absolute; top: 50px; right: 50px; width: 300px; height: 300px; background-color: #fff;";
}
// Add it to your <body> tag
document.body.appendChild(this.element);
// call whatever setup functions you were calling before
popUpDetails();
},
close = function () {
// get rid of the popup
document.body.removeChild(this.element);
// any other code you want
}
};
// The element you want to trigger the popup
var hoverOverMe = document.getElementById("hoverOverMe");
// set our popup open and close methods to the proper events
hoverOverMe.onmouseover = popup.open;
hoverOverMe.onmouseout = popup.close;
That should do it. It's much easier to control than a new browser window. You will want to tweak the CSS yourself.
EDIT:
Here are instructions to do this with an actual window. To reiterate, using an actual window is not the best way to accomplish this task. A stylized div tag to look like a window is better because it offers more control, as well as standardized functionality across browsers. However, if you must use a window, here it is:
// You can use many principles from the example above, but I'll give the quick version
var popup;
var hoverOverMe = document.getElementById("hoverOverMe");
hoverOverMe.onmouseover = function () {
popup = window.open("path_to_content", "popup");
};
hoverOverMe.onmouseout = function () {
popup.close();
};
It works, but not very well (IMHO). If the user has their settings such that new windows open in new tabs (as I do), then a tab will open up. Javascript has no control over that. In Firefox, the new tab will open and gain focus, at which point it immediately closes because hoverOverMe had its onmouseout event fired (which obviously closes the window). I imagine you'd have this same problem with an actual window, too.

Categories