Chrome Extension iframe dom reference disqus - google-chrome-extension

How do I get a reference to the dom of a cross domain iframe/frame?
I want to do some stuff to disqus comments with an extension.
My manifest has the following:
"all_frames": true,
"matches": ["*://*.disqus.com/*","*://disqus.com/*", "http://somesite.com"]
I am not trying to communicate outside of the frame - that is the js will take care of the work without needing to 'tell' me anything.
all_frames should inject the listed js files into every frame, no?
When I do this:
if (window != window.top){
alert('In an IFRAME: ' + window.location.href);
}
...I get the expected disqus URLs.
But when I do this:
var btnCommentBlock = document.getElementsByClassName('dsq-comment-buttons');
alert('btnCommentBlock length: ' + $(btnCommentBlock).length);
...I get 0 for length.

I updated my answer to Javascript to access Disqus comment textbox?
Basically, Disqus changed the selector. They no longer use textarea, they use contenteditable divs.
Something like this should work:
// We just need to check if the IFrame origin is from discus.com
if (location.hostname.indexOf('.disqus.com') != -1) {
// Extract the textarea (there must be exactly one)
var commentBox = document.querySelector('#comment');
if (commentBox) {
// Inject some text!
commentBox.innerText = 'Google Chrome Injected!';
}
}
Source Code:
https://gist.github.com/1034305

Woohoo! I found the answer on github:
https://gist.github.com/471999
The working code is:
$(document).ready(function() {
window.disqus_no_style = true;
$.getScript('http://sitename.disqus.com/embed.js', function() {
var loader = setInterval(function() {
if($('#disqus_thread').html().length) {
clearInterval(loader);
disqusReady();
}
}, 1000);
});
function disqusReady() {
//whatever you can imagine
}
});
I put this in the disqusReady() function:
var aTestHere = document.getElementsByClassName('dsq-comment-body');
alert(aTestHere[0].innerHTML);
...and got back the innerHTML as expected.
Mohamed, I'd really like to thank you for taking the time to interact with my question. If you hadn't posted that link to github there's no telling when if ever I'd have figured it out or found the other code.
edit: After a few minutes of experimenting it looks like it is not necessary to call getScript so you should be able to comment that out.
Also unnecessary is window.disqus_no_style so I commented that out too.
I'll experiment some more and update the answer later. One of those two things prevented me from being able to actually post a comment at the disqus site I use. //them out still allows access to the dom and the ability to post.

Related

How to jBox from JS?

(This is embarrassing, I should not be asking this...but I just don't see the problem...)
As part of a JS-Fn, I would like to give the user immediate feedback by opening a jBox-Tooltip that is attached to the control user is dealing with. But the control tip does not open - what am I doing wrong? I have simpified stepwise by removing params and finally even this does not do.
var x=new jBox('Tooltip',{content:"Press Escape again to clear the input-field!"});
x.open();
I started with
var x = new jBox('Tooltip',{
content:"Press Escape again to clear the input-field!",
attach: "#ipExpr",
onInit: function() { this.open(); }
});
NB: I've chedcked that $("#ipExpr").length==1
It seems that attaching the jBox to an element and opening it when its being initialised seems to be the problem. Can you describe what kind of behavior your looking for in detail? For example, if you like to open the jBox right away on the element with id #idExpr, you could do it like this: jsfiddle.net/pbrrah37
var x = new jBox('Tooltip',{
content:"Press Escape again to clear the input-field!",
onInit: function() { this.open({target: $('#ipExpr')}); }
});

In NodeJS selenium-webdriver, how do you get innerHTML of element

I've gone through: https://code.google.com/p/selenium/wiki/WebDriverJs and it doesn't have any information. So, can someone help.
I have
var element = driver.findElements(webdriver.By.id("something"))
console.log('text='+element.getAttribute("inner‌​HTML"));
But doesn't work. Most of the documentation appears to be for JAVA not nodeJS. If you come across a .getText() function, I'm pretty sure that is JAVA. I actually just want the text part innerText, opposed to innerHTML. But that might be asking too much.
You can check innerHTML like this:
driver.executeScript(function() {
return document.querySelector('#something').innerHTML;
}).then(function(innerHTML) {
//check content here
});
Per the webdriver.js docs:
var myElement = element(by.css('.myclass'));
myElement.getInnerHtml().then(function(html) {
//do stuff with html here
});
Hope that helps! It's working for me using Node.js + Selenium / WebDriver, etc.

Can we get MathML output from MathJax

I was wondering if there are ways to convert MathJax output to MathML.
I read through several articles that saying MathJax supports MathML. I can also see the option 'Show MathML' when I right click the MathJax formulas. My question is, can I get the MathML output to the webpage from MathJax? I am not familiar with MathJax and I am not sure how it works. Any resources or tutorial pages would have been nice!
#Peter, I think the OP may be asking how to get a MathML string from MathJax, rather than how to insert the MathML tags into the page directly. So perhaps the discussion on the MathJax forums that describes how to use toMathML will do the trick.
The basic idea is to get the element jax (using MathJax.Hub.getAllJax) for the math you want to convert, then to call its toMathML method. But you need to use some care for this, as toMathML can operate asynchronously. The link above goes through the details.
EDIT: The MathJax-node project allows you to do this from the command line, so you might want to check that out as well.
I have written some code check it out:
First include "https://code.jquery.com/jquery-1.11.2.min.js" and "http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"
var JaxToML = {
toMathML: function(jax, callback) {
var mml;
try {
mml = jax.root.toMathML("");
} catch (err) {
if (!err.restart) {
throw err
} // an actual error
return MathJax.Callback.After([JaxToML.toMathML, jax, callback], err.restart);
}
MathJax.Callback(callback)(mml);
},
convert: function(AjaxText, callback) {
var tempDiv = $('<div style="width:455px;height:450px:border-width:thick;border-style:double;"></div>').appendTo("body").html(AjaxText)[0];
MathJax.Hub.Queue(["Typeset", MathJax.Hub, tempDiv]); //first place in Q
MathJax.Hub.Queue(function() { //wait for a callback to be fired
var jax = MathJax.Hub.getAllJax(tempDiv);
for (var i = 0; i < jax.length; i++) {
JaxToML.toMathML(jax[i], function(mml) {//alert(jax[i].originalText + "\n\n=>\n\n"+ mml);
AjaxText = AjaxText.replace(jax[i].originalText, mml);
});
}
$(tempDiv).remove();
AjaxText = AjaxText.replace(/\(/g,""); //notice this escape character for ( - i.e it has to be \( , know why it is beacuse JS will treat ) or ( as end/begin of function as there are no quotes here.
AjaxText = AjaxText.replace(/\)/g,""); //notice this escape character for ) - i.e it has to be \)
AjaxText = AjaxText.replace(/\\/g,"");
callback(AjaxText);
});
},
};
Usage :
JaxToML.convert(AjaxText, function(mml) {
alert(mml);
});
The MathJax documentation on configuring MathJax is probably the place to start reading. You can configure the output jax per browser.
A word of caution. There's a reason why MathJax does not use to MathML output on any browser right now: browser support isn't quite there yet. (This will change as browsers catch up and MathJax can start to leverage their native support.) So make sure your content actually renders ok.

Updating an extension button dynamically - inspiration required

I am building an extension where I want to be able to add a signifier to the extension button when the extension in the code has been activated. I was hoping I could add text to the extension button (top right)
Here is a simple scenario. Let's say my extension monitors browsing and gets the tab url, in my extension I have a list of domains to watch for.
Watch for these domains
www.website1.com
www.website2.com
If a user visits a domain in the watched list I want to indicate this somehow, by adding some text somewhere - I was hoping in the top right of the browser where the extensions buttons are. I don't really want to use a notification window as I want something unobtrusive. The text that I want to display would just be a few letters but different for different urls.
Does anyone have any inspiration?
Thanks
You may change the extension icon like this:
chrome.browserAction.setIcon({path: icon});
There is also a 'badge' - small box over the extension icon that shows ie. number of unread messages in gmail extension. You can manipulate it like this:
chrome.browserAction.setBadgeBackgroundColor({color:[190, 190, 190, 230]});
chrome.browserAction.setBadgeText({text:"?"});
It is also possible to generate icon dynamically on a canvas element and then display it like this:
chrome.browserAction.setIcon({imageData:canvasContext.getImageData(0, 0, canvas.width,canvas.height)});
Note that you must call this from your background script, since the content script will not have permission!
tl;dr: Call it from background.js
I googled around this comment because I was trying to call a chrome.browserActions function from my content script
It's only accessible to scripts that are running as part of a chrome extension, since content_scripts are the same as client scripts you'd have to access them through the chrome.* api's
and to fix some addition headaches I had the call for setBadge text needs to look like:
chrome.browserAction.setBadgeText({text: 'ASDF'});
You can put as many characters as you want, but only 4 or so will appear. I got hung up on what the object property needed to be.
You can also set a timeout to check changes on the system every x minutes, and then update de badge.
On my extension, I have an task counter called inside a notification function. Something like :
$.getJSON(
"http://mydomain/notifications?ajax=1&callback=?",
function(data){
var result = data.retorno;
if(result.length > 0){
var totalItens = result[0].total
} else {
var totalItens = 0;
}
chrome.browserAction.setIcon({path: '19.png'});
chrome.browserAction.setBadgeText({text:''+totalItens+''});
for(var i=0; i<result.length; i++){
var imagem = 'http://mydomain/myimage';
var titulo = 'mytitle';
var desciption = 'mydescription';
var urlNot = 'http://mydomain/mypageOnclick';
var not = new Notifier(urlNot);
not.Notify(
imagem, // The image.
titulo, // The title.
desciption // The body.
);
}
}
);
You have to change in 3 files.
manifest.json
Check this code added
"background": { "scripts": ["background.js"], "persistent": false }
script.js
Add the following code:
const msg = 'updateIcon'
chrome.runtime.sendMessage({ message: msg }, function(response) {
});
background.js
Add the following code:
chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
console.log(request);
// Callback for that request
chrome.browserAction.setIcon({path: "/assets/icon.png"});
});

modified innerHTML does not show on page

I am writing a Google extension. Here my content script modifies a page based on a list of keywords requested from background. But the new innerHTML does not show up on the screen. I've kluged it with an alert so I can see the keywords before deciding to actually send a message, but it is not how the routine should work. Here's the code:
// MESSAGE.JS //
//alert("Message Page");
var keyWordList= new Array();
var firstMessage="Hello!";
var contentMessage=document.getElementById("message");
contentMessage.value=firstMessage;
var msgComments=document.getElementsByClassName("comment");
msgComments[1].value="Hello Worlds!";//marker to see what happens
chrome.extension.sendRequest({cmd: "sendKeyWords"}, function(response) {
keyWordList=response.keyWordsFound;
//alert(keyWordList.length+" key words.");//did we get any keywords back?
var keyWords="";
for (var i = 0; i<keyWordList.length; ++i)
{
keyWords=keyWords+" "+keyWordList[i];
}
//alert (keyWords);//let's see what we got
document.getElementsByClassName("comment")[1].firstChild.innerHTML=keyWords;
alert (document.getElementsByClassName("comment")[1].firstChild.innerHTML);// this is a band aid - keyWords does not show up in tab
});
document.onclick= function(event) {
//only one button to click in page
document.onload=self.close();
};
What do I have to do so that the text area that is modified actually appears in the tab?
(Answering my own question) This problem really has two parts. The simplest part is that I was trying to modify a text node by setting its value like this:
msgComments1.value="Hello Worlds!"; //marker to see what happens
To make it work, simply set the innerHTML to a string value like this:
msgComment1.innerHTML="Hello Worlds!"; //now it works.
The second part of the problem is that the asynchronous call to chrome.extension.sendRequest requires a callback to update the innerHTML when the reply is received. I posted a question in this regard earlier and have answered it myself after finding a solution in an previous post by #serg.

Resources