Calling Javascript function from XPCOM, C++ - javascript

My goal is to catch pageloads in my component, insert some javascript into the document and then catch onFocus events. On an event i then want to call the javascript function i injected.
Now i managed to solve most issues, i have the script added to all webpages and i can catch onfocus events. What im not able to do is execute a javascript function from my XPCOM component (C++). In my Internet Explorer BHO i use execScript and it works great. Any ideas?
Currently my workaround is to use setattribute and set the onfocus event of each input element to execute the javascript function, but this is intrusive and overwrites existing onFocus handlers in the webpage. Other ideas are welcome.
Thanks.

If you "have the script added to all webpages", the script can take care of both registering a "focus" event listener and taking an appropriate action when the focus event happens.
I'm not sure why you need to call into the content JS from your component.
If you do need to do this, post what you have already tried and in what way it "didn't work".

I believe this used to resolve your issue (pre FF6?), am looking for a newer solution.
FF6 had some change to security of the navigation bar that prevented executing javascript there. https://support.mozilla.org/en-US/questions/876916
Where to execute java script the url might be javascript:alert('hello');
OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, PRUint32 aStateFlags, nsresult aStatus) {
// check for correct state - document load complete...
nsCOMPtr<nsIDOMWindow> domWin;
nsresult rv = aWebProgress->GetDOMWindow(getter_AddRefs(domWin));
nsCOMPtr<nsIWebNavigation> nav = do_GetInterface(domWin);
if (nav)
hr = nav->LoadURI(url, 0, 0, 0, 0);

Related

Determine current DOM element state in chrome

How do I determine the state of a textarea element (:focus, :hover, etc.) in Chrome?
For context, I'm trying to create a web application. After submitting the form on a previous page, the textarea of the new page automatically has the cursor, which I do not want to happen. I've tried to use the jQuery code below, which works in Firefox but not in Chrome:
element = $("#elementID");
if (element.is(":focus")) {
element.blur();
}
In Chrome, the code does not execute the element.blur() in the if statement (meaning the if statement fails). I've checked with a debugger and the element is successfully returned by the id in Chrome. So I think the problem is the state check statement.
I assume the problem is the element state and I want to investigate the element state at that time, preferably using Chrome developer tools. Unfortunately, I can't figure out how to check the current state. I can only figure out how to check if the state is equal to a specific state.
I've searched around but I am only finding answers like set :hover state which discuss how to set a specific state using Chrome dev tools and not how to determine the current state when it could be any state.
I realize that I could check for each possible state at that point in the JavaScript, but it seems like I am missing the correct way to check the state.
Here is a JSFiddle of my specific case. However, I'd be interested to also hear the answer to the general question about determining the current state of a textarea.
Thanks for the help!
It's most likely an order of operations issue - the logic is executed before the input's focus can be detected.
I've reproduced the issue here, and fixed it by putting the code into the window .load() event.
var $el = $('textarea');
// will not execute
if ($el.is(':focus')) {
$el.blur();
console.log('outside of window load');
}
// will execute
$(window).load(function() {
if ($el.is(':focus')) {
$el.blur();
console.log('inside window load');
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea autofocus></textarea>

Overriding VB Code using jquery

I had a problem with a vb.net webpage which I solved by commenting out a .Focus() in the page_load. The customer however, will not receive this amendment until next release.
My question is, is it possible to achieve the same result using jquery through an external js file. ie. I would like to know if I can 'bypass' the '.Focus()' line in the page_load by using some kind of jquery wizardry?
I'm guessing that the answer will be 'no', however I'm still hopeful! :-)
Thank you for your time.
If you have the id of the control (or name) you can set focus to it by calling:
$(document).ready(function(){
$('#elementId').focus();
// or
// $('input[name="elementName"]').focus();
}
This will change WHAT is focused, not un-setting focus
If you know the ID of the focused element you can do:
$(document).ready(function(){
$('#elementId').blur();
// or
// $('input[name="elementName"]').blur();
}
to un-focus it.
you could also do:
$(document).ready(function(){
$('input').blur();
}
if you just wanna unset the focus from all/any input
And in my tests this will override asp.net's attempt to set focus (read: asp.net will focus one thing, your script will afterwards focus another thing, so there might be a race for control here, but at least on my page (asp.net c#) and in chrome this works so that the jquery.focus runs last, thus wins :))
Edit/Update:
Should the problem that the control receives focus rather then having focus, you can overwrite the auto_focus function that asp.net uses when you call .Focus() in your code-behind.
For me this works:
WebForm_AutoFocus = function () { };
However this might cause other things to not work (I do not know if this javascript function is used for other things besides setting the .Focus() from your codebehind, but it might be worth trying.)
You should also set this somewhere "late" in your code, eg: after WebForm_AutoFocus is rendered to your page by the asp.net runtime, and where this is done i do not know.

How can I get two onClick calls to fire?

Firstly I am not a web developer, I'm an Analytics professional, so I apologise if this question seems basic and not using the correct terminology!...
I am trying to get _trackEvent code to fire 'onClick' for some Social buttons - however as the social buttons open in a new window they already run an onClick as follows....
I need to add in the following _trackEvent code:
onClick=_gaq.push(['_trackEvent', 'EN', 'Tower of London', 'Facebook']);
So what I am trying to do is fire an event to Google Analytics on click whilst not disturbing the button functionality. Any help is much appreciated
Just put the tracking command before the window open command in the onClick
like this:
A quick JavaScript/HTML lesson : what the contents of the inline "onclick"-attribute describe is the body of a "callback" function (a method that, in this case, is executed when the element is clicked). In this case it opens the Facebook share URL in a new window/tab when the anchor is clicked.
What you want to do is execute TWO different callbacks for the single click-event. This would lead us to using JavaScript to assign the event callbacks using "addEventListener/attachEvent" as the inline "onclick"-attribute only allows for a single callback handler, while adding listeners gives you the benefit of being able to add multiple callbacks for a single event type. As others have mentioned, if you have jQuery or another library available this can be a doddle to attach.
However, if you want a quick and dirty fix without getting too much JavaScript code going on outside of your HTML document, you can add the _gaq-tracking code inside the "onclick"-attribute by appending after the existing onclick-code like so:
Which will result in tracking the click in Analytics AND the window openeing. Semantically, this is quite fugly as it describes multiple handlers in a single of code, but for the sake of argument we assume you don't mind as the HTML had inline JS handling to begin with and we haven't even touched the subject of window opens being blocked when they are delegated through multiple functions instead of on a direct-click handler! ;)
Instead of using onclick, attach the events using jquery if you have it:
<script type="text/javascript">
$('.facebook').on('click', function () {
window.open('http://www.facebook.com/share.php?u=http://www.londonpass.com/infographic/hampton-court.html&title=Hampton Court - History and Stories Infographic from the London Pass/','newWin','width=400,height=200')
_gaq.push(['_trackEvent', 'EN', 'Tower of London', 'Facebook']);
//other code you like
});
</script>
For attaching the event using pure javascript:
var socials = document.getElementByClass("facebook");
socials.addEventListener('click', myFunction, false);
And define your function:
<script type="text/javascript">
function myFunction () {
window.open('http://www.facebook.com/share.php?u=http://www.londonpass.com/infographic/hampton-court.html&title=Hampton Court - History and Stories Infographic from the London Pass/','newWin','width=400,height=200')
_gaq.push(['_trackEvent', 'EN', 'Tower of London', 'Facebook']);
//other code you like
}
</script>

Check if the webpage has been modified

I am working on chrome extension for facebook. If you use facebook, you know that when you scroll down to the bottom of the news feed/timeline/profile it shows more posts. The extension actually adds a button beside the "like" button. So I need to check if there are more posts to add that button to.
Right now to check if the page has been modified, I use setInterval(function(){},2000).
I want to run a function when the user clicks the button. But this function doesn't work if I put it outside (or even inside) setInterval() – The Koder just now edit
How can I check if the webpage has been modified WITHOUT using a loop?
Example:
$(document).ready(function(){
window.setInterval(function(){
$(".UIActionLinks").find(".dot").css('display','none');
$(".UIActionLinks").find(".taheles_link").css('display','none');
$(".miniActionList").find(".dot").css('display','none');
$(".miniActionList").find(".taheles_link").css('display','none');
//only this function doesn't work:
$(".taheles_link").click(function(){
$(".taheles_default_message").hide();
$(".taheles_saving_message").show();
});
//end
$(".like_link").after('<span class="dot"> · </span><button class="taheles_link stat_elem as_link" title="תגיד תכל´ס" type="submit" name="taheles" onclick="apply_taheles()" data-ft="{"tn":">","type":22}"><span class="taheles_default_message">תכל´ס</span><span class="taheles_saving_message">לא תכלס</span></button>');
$(".taheles_saving_message").hide();
}, 2000);
});
In the future, this extension will use AJAX, so setInterval() can make even more problems for me.
If I understand correctly you want to get a notification when the page's DOM changes. And you want to do this without using the setInterval() function.
As your problem lies within the attaching event handlers to elements that are created after the page has loaded, you might be interested in checking out the jquery.live event attachment technique. I think it will solve your issue.
In general you want the page to throw a mutation event. There is a mutation event spec that might be what you're looking for. Here are some links that might be useful.
http://tobiasz123.wordpress.com/2009/01/19/utilizing-mutation-events-for-automatic-and-persistent-event-attaching/
Detect element content changes with jQuery
$(document).ready(function(){
setInterval('fun()',5000);
fun();
});
function fun()
{
alert(11)
}

How do I discover which function is called when I press a button?

I'm stuck modifying someone else's source code, and unfortunately it's very strongly NOT documented.
I'm trying to figure out which function is called when I press a button as part of an effort to trace the current bug to it's source, and I"m having no luck. From what I can tell, the function is dynamically added to the button after it's generated. As a result, there's no onlick="" for me to examine, and I can't find anything else in my debug panel that helps.
While I prefer Chrome, I'm more than willing to boot up in a different browser if I have to.
In Chrome, type the following in your URL bar after the page has been fully loaded (don't forget to change the button class):
var b = document.getElementsByClassName("ButtonClass"); alert(b[0].onclick);
or you can try (make the appropriate changes for the correct button id):
var b = document.getElementById("ButtonID"); alert(b.onclick);
This should alert the function name/code snippet in a message box.
After having the function name or the code snippet you just gotta perform a seach through the .js files for the snippet/function name.
Hope it helps!
Open page with your browser's JavaScript debugger open
Click "Break all" or equivalent
Click button you wish to investigate (may require some finesse if mouseovering page elements causes events to be fired. If timeouts or intervals occur in the page, they may get in the way, too.)
Inspect the buttons markup and look at its class / id. Use that class or id and search the JavaScript, it's quite likely that the previous developer has done something like
document.getElementById('someId').onclick = someFunction...;
or
document.getElementById('someId').addEventListener("click", doSomething, false);
You can add a trace variable to each function. Use console.log() to view the trace results.
Like so:
function blah(trace) {
console.log('blah called from: '+trace);
}
(to view the results, you have to open the developer console)

Categories