Javascript: Onload event in Firefox not firing - firefox

I am making a dynamic script call to load some extenal JS before window's onload event. Here is the sample code.
var temp = document.createElement('script');
temp.type = 'text/javascript';
temp.async = temp.defer= true;
temp.src = "http://stevesouders.com/efws/iframe-empty.php?t==";
window.setTimeout(function(){document.getElementsByTagName('head')[0].appendChild(temp)},0);
This code is perfectly working on IE (Window onload event is not waiting for dynamic script resource download). However it's not working on Firefox. Window onload event is waiting for the dynamic script resource download.
Are there any workarounds for this issue. You can use http://nidhisekhar.com/samples/async_script_call_settimeout.html link to see the behavior on IE and Firefox. I appreciate your help.
Thanks,
Raja

try this JavaScript function:
// Adds script tag to head of the page
function addScriptToHead(source, code, type) {
var script = document.createElement('script');
if (type === 'js') {
script.setAttribute('type', 'text/javascript');
}
if (source !== '') {
script.setAttribute('src', source);
}
if (code !== '') {
if (document.all && !window.opera) {
script.text = code;
} else {
script.innerHTML = code;
}
}
document.getElementsByTagName('head')[0].appendChild(script);
}
call example:
addScriptToHead(path, '', 'js');

Related

code highlighting apex (Firefox 31)

The Oracle Application Express code editor is just plain back text on white background. No Code highlighting. Also I can't press "tab" without the textfield loosing focus.
I am using firefox 31 (can't upgrade, rescricted by Admin at work here) Also I can't install plugins. I know you can change css on specific sites using a special folder in firefox ("chrome"-folder / userContent.css). I already used this to change die default size of the textfield, because it was frickin small everytime I opened the edit page.
So do you know any framework or script I can use in Apex ? (I could copy that shit to jsfiddle.net every time but that sucks
(I also found the scratchpad in Firefox, which can run js and jquery. Does that help ?)
[SOLVED]
since you can't use
<script src = "">
etc. in plain js, I had to use loadScript. For css files it was even more complicated, but I got it all working.
This is my code, I run it in scratchpad (firefox). It uses ACE to change a div to an editor with highlighting. When clicking apply I revert the editor-changes in the DOM but keep the text/code.
// Load Ace js
loadScript("http://cdnjs.cloudflare.com/ajax/libs/ace/1.1.01/ace.js", function(){
//initialization code
});
// Load Ace css
var cssId = 'myCss'; // you could encode the css path itself to generate id..
if (!document.getElementById(cssId)){
var head = document.getElementsByTagName('head')[0];
var link = document.createElement('link');
link.id = cssId;
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = 'http://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/3.0.0/css/bootstrap.min.css';
link.media = 'all';
head.appendChild(link);
}
// change textarea to div
var editorRegion = document.getElementById('F4000_P4651_PLUG_SOURCE_fieldset');
editorRegion.innerHTML = editorRegion.innerHTML.replace("textarea","div");
// run ACE
highlight();
// Modify the apply Button in Apex to first revert ACE-Editor to normal, then do the usual apply.
var applyChanges = document.getElementById('B3456326662');
applyChanges.setAttribute("onclick","modifiedApply()");
function modifiedApply(){
close();
setTimeout(normalApply, 500);
}
function normalApply(){
javascript:apex.submit('Apply_Changes');
}
// Revert ACE-Changes, but keep changed text/code.
function close(){
var value = editor.getValue();
editor.destroy();
var oldDiv = editor.container;
var newDiv = oldDiv.cloneNode(false);
newDiv.textContent = value;
oldDiv.parentNode.replaceChild(newDiv, oldDiv);
newDiv.outerHTML = newDiv.outerHTML.replace("div","textarea");
var old_new_old = document.getElementById('F4000_P4651_PLUG_SOURCE');
old_new_old.textContent = old_new_old.textContent.substring(0, old_new_old.textContent.length - 6);
}
var editor;
function highlight() {
editor = ace.edit("F4000_P4651_PLUG_SOURCE");
editor.setTheme("ace/theme/monokai");
editor.getSession().setUseWorker(false);
editor.getSession().setMode("ace/mode/javascript");
document.getElementsByClassName('ace_print-margin')[0].setAttribute("style","left:1000px");
}
function loadScript(url, callback){
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState){ //IE
script.onreadystatechange = function(){
if (script.readyState == "loaded" ||
script.readyState == "complete"){
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function(){
callback();
};
}
script.src = url;
document.getElementsByTagName("head")[0].appendChild(script);
}

Fiiling the compose message at opening

I'm desesperatly seeking for a way to fill in the compose message when it opens, in a boostraped (restartless) TB add-on.
This is something that I did in my non-bootstraped add-on RemindIt
Thanks to Superjos I was able to manage the different listeners, and get the compose message filled with my custom message when it opened.
But... this works only for new (non recycled) windows. If I close a compose window, then click on "new message", it is recycled (I guess) and the "load" event is not fired.
I tried different tricks (see for example onComposeInit2), but at the end, I'm not able to alter compose message for non new windows, even if it looks like my addon is calling the editing method (this is what one can see in the log).
Any ideas ?
See my test/bootstrap.js code :
function log(s){
Components.classes["#mozilla.org/consoleservice;1"]
.getService(Components.interfaces.nsIConsoleService).logStringMessage("test: "+s);
}
// Thanks (a lot ! ) to Superjos :
// https://stackoverflow.com/questions/25989864/get-sender-and-recipients-in-thunderbird-extension-upon-sending-message
var winListener={
onOpenWindow: function(win){
compose=win.docShell.
QueryInterface(Components.interfaces.nsIInterfaceRequestor).
getInterface(Components.interfaces.nsIDOMWindow);
compose.addEventListener('compose-window-init', winListener.onComposeInit, true);
},
onComposeInit: function(event){
var document=event.currentTarget.document;
var edit=document.getElementById("content-frame");
edit.addEventListener("load",winListener.onComposeLoad,true);
log("compose init "+event.currentTarget);
event.currentTarget.removeEventListener(event.type,winListener.onComposeInit , true);
},
onComposeLoad: function(event){
var edit=event.currentTarget;
var editor=edit.getHTMLEditor(edit.contentWindow);
log("compose load");
winListener.alterMessage(editor);
},
alterMessage: function(editor){
var msg="Hello<br>";
editor.insertHTML(msg);
log("alter message "+editor);
},
onComposeInit2: function(event){
var document=event.currentTarget.document;
var edit=document.getElementById("content-frame");
edit.addEventListener("load",winListener.onComposeLoad,true);
log("compose init "+event.currentTarget);
var editor=edit.getHTMLEditor(edit.contentWindow);
if( editor!=null ){
// the editor is ready, remove load event listener
edit.removeEventListener("load",winListener.onComposeLoad,true);
// and call the method to alter message
winListener.alterMessage(editor);
}
//edit.addEventListener("focus",winListener.onFocus,true);
event.currentTarget.removeEventListener(event.type,winListener.onComposeInit2 , true);
},
/*
onFocus: function(event){
event.currentTarget.removeEventListener("focus",winListener.onFocus,true);
var edit=event.currentTarget;
var editor=edit.getHTMLEditor(edit.contentWindow);
winListener.alterMessage(editor);
log("focus");
},
onComposeClose: function(event){
var document=event.currentTarget.document;
var edit=document.getElementById("content-frame");
edit.addEventListener("focus",winListener.onFocus,true);
log("close");
}
*/
}
function startup(aData, aReason) {
log("startup");
var windowMediator = Components.classes['#mozilla.org/appshell/window-mediator;1'].
getService(Components.interfaces.nsIWindowMediator);
windowMediator.addListener(winListener);
}
function shutdown(aData, aReason) {
log("shutdown");
var windowMediator = Components.classes['#mozilla.org/appshell/window-mediator;1'].getService(Components.interfaces.nsIWindowMediator);
windowMediator.removeListener(winListener);
}
function install(aData, aReason) {
log("install");
}
function uninstall(aData, aReason) {
log("uninstall");
}
I found the solution from this http://forums.mozillazine.org/viewtopic.php?f=19&t=450474
There is a compose-window-reopen event that is fired when the window is reopen.

dragover event is no not firing in firefox

I'm working to simulate files and directories structure ,using drag and drop,
my code is working fine in IE, Chrome but not working in Firefox ,
while i'm searching i found this fiddle .
> http://jsfiddle.net/G9mJw/20/
same problem works on IE,Chrome but not Firefox !
http://jsfiddle.net/G9mJw/140/
var dropzone = document.getElementById('dropzone');
var draggable = document.getElementById('draggable');
draggable.addEventListener('dragstart', onDragStart, false);
dropzone.ondragover = function(e){e.preventDefault(); }
dropzone.ondrop = function(e){ onDragOver(e); }
function onDragStart(event) {
event.dataTransfer.setData('text/html', null); //cannot be empty string
}
function onDragOver(event) {
var counter = document.getElementById('counter');
counter.innerHTML = parseInt(counter.innerHTML) + 1;
}

IE8 hangs when more than 4 async XmlHttpRequests are triggered concurrently

for (var i = 0; i < 5; ++i) {
var xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else if (window.ActiveXObject) {
xhr = new ActiveXObject("Msxml2.XMLHTTP");
}
xhr.open('GET', '/Test/LongOperation?p=' + new Date());
xhr.send('');
}
This is only a demo (not live code) but it illustrates the core problem.
LongOperation is a method that returns a result after 10 seconds.
Questions:
Why does IE8 (and maybe other IEs) hang when the user tries to navigate away from page right after the above code snippet has been executed? FireFox/Safari cancel these requests and allow navigation to another page. If you replace 'i < 5' with 'i < 4' then IE would not hang.
How to work around this ugly IE behavior? Users are very upset when their browser suddenly hangs.
Most browsers have an inbuilt limit of 4 connections to any given server. One way to work around this "problem" might be to use a different hostname for out of band XML requests - your user requests will go to the main hosts, while the AJAX requests can go to the second server.
My answer to my question. I abort all not completed xhr objects in window.onbeforeunload. At least this solution works for me. I slightly override $.ajax() method behavior:
;(function($) {
var rq = [];
var ajax = $.ajax;
$.ajax = function(settings) {
// override complete() operation
var complete = settings.complete;
settings.complete = function(xhr) {
if (xhr) {
// xhr may be undefined, for example when downloading JavaScript
for (var i = 0, len = rq.length; i < len; ++i) {
if (rq[i] == xhr) {
// drop completed xhr from list
rq.splice(i, 1);
break;
}
}
}
// execute base
if (complete) {
complete.apply(this, arguments)
}
}
var r = ajax.apply(this, arguments);
if (r) {
// r may be undefined, for example when downloading JavaScript
rq.push(r);
}
return r;
};
// 'kill' all pending xhrs
$(window).bind('beforeunload', function() {
$.each(rq, function(i, xhr) {
try {
xhr.abort();
} catch(e) {
$debug.fail('failed to abort xhr');
}
});
rq = [];
});
})(jQuery);
$debug - my utility class
Try running them asynchronously and then triggering the next http request when the each completes. I suspect that the xmlhttp request is blocking the UI thread of IE whereas the implementations of that on other browsers is a little more graceful.
Hopefully that will give you a work-around for question 2 but I can only guess at the true reason for question 1, it could just be a bug.

How can I disable a hotkey in GreaseMonkey while editing?

I'm using Ctrl+Left / Ctrl+Right in a GreaseMonkey script as a hotkey to turn back / forward pages. It seems to works fine, but I want to disable this behavior if I'm in a text edit area. I'm trying to use document.activeElement to get the page active element and test if it's an editable area, but it always returns "undefined".
document.activeElement works for me in FF3 but the following also works
(function() {
var myActiveElement;
document.onkeypress = function(event) {
if ((myActiveElement || document.activeElement || {}).tagName != 'INPUT')
// do your magic
};
if (!document.activeElement) {
var elements = document.getElementsByTagName('input');
for(var i=0; i<elements.length; i++) {
elements[i].addEventListener('focus',function() {
myActiveElement = this;
},false);
elements[i].addEventListener('blur',function() {
myActiveElement = null;
},false);
}
}
})();
element.activeElement is part of HTML5 spec but is not supported by most browsers. It was first introduced by IE.

Resources