Javascript acting differently in inappbrowser vs Chrome - Undefined global variables - javascript

My problem is that when I use inappbrowser to open my web page, the main javascript file seems to be ignored, even though it is referenced in the Head of the file that I am opening using ref = cordova.InAppBrowser.open('https://MYURLHERE:8484/home/login', '_self', 'location=yes');
I am using chrome://inspect/#devices to inspect the console and I get errors when hitting buttons.. Anything referenced in the main.js file is undefined.. whereas the actual code for the autocomplete and button seems to be executing.
Please note The url is working fine when viewed in the chrome browser. The javascript files seem to load correctly, and all variables are defined correctly. - It is only when I use inappbrowser that I see issues with undefined variables.
My code (cordova app):
ref = cordova.InAppBrowser.open('https://MYURLHERE:8484/home/login', '_self', 'location=yes');
var myInAppBrowserCallback = function(event) {
console.log(event.url, 'LOADED');
};
ref.addEventListener('loadstart', myInAppBrowserCallback);
//Works fine.
My code (from the actual website I'm trying to view in Inappbrowser):
<script src="/Scripts/commonFunctions.js"></script>
var p = 'Hello';
<script src="/Scripts/loginPage.js"></script>
$('#btnLogin').on('click', function() {
alert(p);
});
Returns an alert with undefined.
What I have tried:
Extensive googling! (all the answers seem to be related to javascript not being enabled.. or 404 errors or things like that.. Not with global variables from one js file being undefined in another js file.)
Removing inappbrowser, using window.open.. Won't work as the app needs to execute scripts to inspect localstorage of the site.
Re-installing the android platform using cordova.
Re-installing the plugin.
Checking chrome in the inspector to ensure the files are in sources tab (they are).
Checking that the functions in main.js also exist (they do).
Thanks, JFIT

Summary:
The problem was that a javascript file was trying to load 'SpeechSynthesis' which was undefined only in the inappbrowser.
Details:
The problem with this was confusing but here are the steps I found to debug / solve:
Set up Remote Debugging on the phone so that you can view the console of the phone using chrome://inspect/#devices
View the console of the inappbrowser site (which will show as a seperate page to the inappbrowser instance.
Identify which files are being loaded and remove files until 'undefined' errors disappear.
Add back in the most recent file and start to strip out various functions (especially functions/variables before document.ready (global variables also)
Find the line/variable that way. It was handy for me this way as the actual undefined variable showed up after I removed most of the files.
The actual cause of my error was the speechSynthesis functionality.
The speechsynthesis lines were removed, and I readded all remaining files and everything works. This function works fine in chrome on desktop/android but not in the inappbrowser.

Related

Exception in defer callback prevents iron-router from rendering when in an iframe on FireFox

I'm working on Meteor app that mostly expects to exist within an <iframe>.
Steps to reproduce
meteor create iframe-test
cd iframe-test
meteor add iron:router
meteor
Create a test page using jsbin.com or some other tool that loads http://localhost:3000 in an iframe.
Load the page in Firefox and take a look at the console. You'll see something like this (note you might need to hard-refresh with Ctrl/Cmd+Shift+R).
I've added links to an example jsbin and git repo below.
18:26:56.356 Exception in defer callback: onLocationChange#http://localhost:3000/packages/iron_router.js?7b16fe70bccff9182aca02afb2ccd7708ac57c64:2227:55
Tracker.Computation.prototype._compute#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:323:41
Tracker.Computation#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:207:41
Tracker.autorun#http://localhost:3000/packages/tracker.js?6d0890939291d9780f7e2607ee3af3e7f98a3d9c:564:48
Router.prototype.start#http://localhost:3000/packages/iron_router.js?7b16fe70bccff9182aca02afb2ccd7708ac57c64:2223:68
Router/ eval:23:19959
1 meteor.js:944:47
The exception stops iron-router from rendering any template (the page just appears blank).
Exception only occurs on first load - if you refresh the page using a soft refresh (Ctrl/Cmd+R) then templates get rendered correctly.
The issue can be reliably reproduced with a hard refresh (Command/Ctrl+Shift+R)
Exception only happens on FireFox (running 40.0a2) - fine in other browsers.
Appears to be coming from the Meteor.defer call on line 44 of iron-router/lib/router.js (in the iron-router repository)
Repro repos
https://github.com/joeapearson/iframe-test (meteor app)
http://jsbin.com/qucuberupi/edit?html,output (jsbin with an iframe)
Any ideas about what could be going on?
Thanks for any help!
For reference, I've reported this as a potential issue here although I'm not necessarily convinced the issue lies in iron-router itself at all. I have a suspicion that this is somehow related to the HTML5 History API implementation in FireFox itself, which behaves differently in an <iframe> for some reason.
Workaround
Looks like it's possible to workaround this issue by dynamically creating the <iframe> before setting its location like this:
var body = document.getElementsByTagName('body')[0];
var iframe = document.createElement('iframe');
body.appendChild(iframe);
iframe.src = 'http://localhost:3000';
Still think this is something related to how FireFox is setting up the HTML5 history in the <iframe>. If you query history.state in the two differing iframes you get these results:
Dynamically created <iframe>
history.state // Object { initial: true }
Statically created <iframe>
history.state // null

How can I access Safari extension settings from outside of the global scope?

I am trying to allow the user to configure my safari extension through a HTML preference page (as many Safari extensions do). I open this page from a javascript call inside my global html file:
var newTab = safari.application.activeBrowserWindow.openTab();
newTab.url = safari.extension.baseURI + "settings/settings.html";
What I can NOT manage to do is write anything from this settings.html into the actual Safari extension settings or access the global page.
safari.extension.settings.MY_SETTINGS = settingsData;
safari.extension.globalPage
Both of these calls result in exceptions and the objects appear undefined.
I then also tried to send messages, but never seem to receive them in the global space, where I thought I could then again access the settings.
safari.self.tab.dispatchMessage("store_settings", settingsData); //settings javascript
These message are not received by my event listener.
safari.self.addEventListener("message", process_messages, false); //GLOBAL javascript
Any idea why I can not access the extension settings? Do I need to initialise something for my settings.html to be able to access the extension settings?
PS: I have seen a similar approach working inside the ClickToPlugin Safari extension - so it should be possible, but I can't get it to work :(
In the global script, try safari.application.addEventListener.
If your html page is part of your extension then your settings.js script file will have access to safari.extension.globalPage. This object points to the window of your global.html.
From there you can call any object in that context. Debugging this however is a pain to say the least. Good luck :-)

Debugging Firefox extension - How to see all JS and XUL files contained in the XPI?

I'm trying to debug a Firefox extension, using Firefox 28.0.
I have set up the dev environment as suggested in https://developer.mozilla.org/en-US/Add-ons/Setting_up_extension_development_environment (actually I just took the lazy way out and installed the DevPrefs extension to set all the necessary about:configs)
I then open Firefox and go into the debugging environment (Tools > Web Developer > Browser Toolbox).
I then go to the Debugger tab.
However, under the Sources pane, under my extension (e.g. chrome://myextension), I only see some of the JS and XUL files that are contained in my extension XPI.
How can I manually "load files" in the debugger, so that I can set a breakpoint and trace the runtime of my extension?
The debugger doesn't have any functionality that would allow loading files "manually", instead it will show you every file that is currently loaded by the JavaScript engine. If you dig into details, this means that whenever the JavaScript engine compiles a new script the debugger is notified and adds the corresponding file to its list. So normally all you need to do is open a page or dialog that uses that script and it will become visible in the debugger. I say "normally" because in my tests this didn't seem to work reliably - there appears to be some bug which makes the debugger miss out some scripts, maybe that's what prompted your question.
Now of course you can consider faking the notification to force the debugger to load a particular file - e.g. if you want to set breakpoints before the file actually loads. I tried it and it is indeed possible, but it requires you to mess with Firefox internals and it relies on a number of implementation details that might change in future Firefox versions. In particular, you need to get the DebuggerServer instance used to communicate with the debugger. While the in-process debugger always uses the same instance which is trivial to get, a new instance is created for each remote debugger. From what I can tell, getting to that instance is only possible with the changes implemented in bug 993029 which means that it will only work with Firefox 32 (currently available from the Firefox Aurora channel) and above.
The problem is that the DebuggerServer instance is being created by the BrowserToolboxProcess class declared in ToolboxProcess.jsm. Before the changes introduced by bug 993029 a BrowserToolboxProcess object would be created and no reference to it kept - meaning that it would be impossible to access it and the corresponding connection after the fact. Starting with Firefox 32 all created BrowserToolboxProcess objects are stored in the processes set and can be enumerated.
This code can be used to fake a Debugger.onNewScript() call that will be forwarded to the remote debugger:
(function()
{
// Iterate over existing processes
const {processes} = Cu.import("resource:///modules/devtools/ToolboxProcess.jsm", null);
for (var process of processes)
{
// Iterate over connections associated with each process
var debuggerServer = process.debuggerServer;
for (var connID in debuggerServer._connections)
{
if (!debuggerServer._connections.hasOwnProperty(connID))
continue;
var conn = debuggerServer._connections[connID];
// Get ChromeDebuggerActor instance for the connection
var chromeDebugger = conn._getOrCreateActor(conn.rootActor._extraActors.chromeDebugger.actorID);
// Fake new script call
chromeDebugger.onNewScript({
url: "chrome://myextension/content/script.js", // CHANGE THAT LINE
source: {text:""},
getChildScripts: () => []
});
}
}
})();
As mentioned above, this code should only work starting with Firefox 32, I tested it on Firefox 33.0a1. You can run it from Scratchpad, make sure to switch environment to "Browser". There is no guarantee whatsoever that it will continue working in future Firefox versions, there are several implementation details used here that can change at any time.

Javascript in asp.net MVC... Beginner issue

I created an Asp.Net MVC Internet Aplication and in my Index view of the Home Controller I have this
This is the first line, before the script results.
<script type="text/javascript" src="~/Script/Teste.js"></script>
<br />
This line comes after the script.
In my Teste.js I have this:
document.write("Yes! I am now a JavaScript coder!");
But nothing happens. If I change the src attribute and put some random name src="aaaa", despite the fact "aaaa" doesnt exist, I get no error in runtime.
EDIT
Also, check your path again. The default MVC templates in VS create a folder called Scripts, not Script. ("~/Scripts/teste.js")
Per the comment below, this was not the root cause of the issue, but in other cases can easily bite new JavaScript developers.
Most likely, your document.write function is firing before the document is ready, leading to the appearance that nothing is happening. Try the following in your Teste.js file
window.onload = function ()
{
document.write("Yes! I am now a JavaScript coder!");
//or even better as a test
alert("This alert was called");
}
Check the source of your page as well, it could be the document is being written to, you just can't see it due to markup/page styling.
As for you second issue, there will be no 'Runtime Exception' thrown if you reference a non-existent file. If you are using tools like Firebug or Chrome's developer tools, you should see a request to http://siteDomain/Scripts/aaaa.js with a response of 404, not found.
You generally should avoid using document.write() unless you absolutely have to use it for some reason... I don't think I've ever come across such a situation, and write a lot of Javascript.
Try this:
1) Put this in your HTML:
<script src="/scripts/teste.js"></script>
2) Put this in your JS:
alert('Yes! I am now a JavaScript coder!');
3) Open Chrome since it makes it easy to look for external resources loading and open the Network tab in Developer Tools (click the menu button at top-right, Tools > Developer Tools, Network tab).
4) Run your project and copy/paste the URL in the browser that comes up into this Chrome window, and hit enter.
When your page loads one of 2 things will happen:
A) You'll get the alert box you wanted or
B) You'll find out why it isn't loading because the Network tab will show the browser attempting to fetch teste.js and failing in some fashion, for example a 404, which would indicate you've got a typo in the path, or the script isn't where you thought it was, etc.
Put the following line at the very end of your document. There should not be anything after. Then try to load the page.
<script type="text/javascript" src="~/Script/Teste.js"></script>
Also, try pressing F12 once the page loads to see the source. Check if you script is there.
In MVC, the tilde is used to refer to the root URL of your application. However, it cannot normally parse this information. If you write:
<script src="~/Script/Teste.js"></script>
The lookup will fail, because the ~ means nothing special in HTML. If you're using Razor as your view engine (not ASPX), you need to wrap that call in Url.Content like so:
<script src="#Url.Content(~/Script/Teste.js)"></script>
Doing this will ensure a valid URL is provided to the browser.
With that in mind, you need to check that you have the file name and folder name both correct. You also need to ensure that the file is being deployed with your application. You can do this my opening the properties panel while the file is selected in the Solution Explorer and pressing F4.

how can I force IE9 to "see" the most current javascript when using the debugger?

I'm using IE9 to debug a web app. I made some changes to the javascript after loading the page. I'm not able to get IE9 to stop on the new code. The message is "The code in the document is not loaded". I can set breakpoints when I'm not debugging, but they won't be valid when I start debugging. I'm using IE7 Browswer Mode, IE7 Document Mode.
Things I've tried:
close dev tools window, re-open
stop debugging, start debugging
Ctrl R in dev tools window (same as Clear Browser Cache button)
Ctrl R on the IE9 web page
Ctrl F5 on the Ie9 web page
Clear browser cache for this domain
Check (set) Always refresh cache from server
Next thing to try (I guess) would be closing IE completely. Is that the fix for this? If so, yuck. It takes me a couple of minutes to set the page up so doing that after every JS change really stinks. I can use FF4 to develop the JS, but the JS issue I'm seeing is specific to IE7 so I have to do it this way.
>> How can I get IE9 (running in IE7 mode) to reliably debug the most current JS from the server?
This issue wasn't related to caching etc. IE9 was hitting a script error (missing closing paren) in the new code and not allowing breakpoints anywhere in the script. IE seemed very quiet about the script error though. Anyway, fixing the script error fixed the issues with breakpoints / caching.
If you have access to the code:
In you javascript file reference add a query string, something like this:
<script src="Scripts/main.js?v=1" type="text/javascript"></script>
And every time you change in the js file change the v value to something else, like that the browser will feel that this is a new file and will get it.
Add this:
window.applicationCache.addEventListener('updateready', function (e)
{
if (window.applicationCache.status == window.applicationCache.UPDATEREADY)
{
window.applicationCache.swapCache();
if (confirm('A new version of this site is available. Load it?'))
window.location.reload();
}
}, false);
I found this solution somwhere in the Net. Sorry, but I don't remember the author. It works for me when I debug Web App with JavaScript in Visual Studio and use IE.
I found this question based on the "the code in the document is not loaded" error message. I'm not using IE7 document mode or any of that, just IE9.
Like jcollum, my issue wasn't related to caching.
I'm using MVC.Net, and someone had set up a piece of javascript to rely on a string in the ViewBag. I changed a couple things, and that ViewBag string disappeared, so the resulting javascript looked something like this:
if(!()) {
// Some code
}
Javascript died right here, and wouldn't process the rest of the code in the block. This was confusing, as it was still trying to execute javascript in a different set of script tags, but which relied on a variable set in the other block it wouldn't load.
So, basically, a syntax error was introduced via strange means, and the debugger refused to load some of the code which came after it. Another lesson on the dangers of ViewBag.

Categories

Resources