I've been trying to figure this out for a while now, but I'm at my wit's end and have given up all hope.
Here is my unpacked chrome extension: nexrem.com/test/extension-test2 - Copy.zip
Exhibit A:
Navigate into the template folder
run test.html in Chrome
Click on the "Footer link"
Observe it scroll correctly to the footer
Exhibit B: Currently, the extension basically replaces the entirety of html on the page.
Install the unpacked extension
Go to some website (for the sake of testing, one that isn't filled with all sorts of scripts. or just make a local blank html file)
Click the extension icon in chrome
You will see the exact same page as when you ran just the test.html ;however, the jquery scrolling no longer works. I fail to understand why.
If someone can explain this to me, assist in a solution or at least point in the right direction, I'd greatly appreciate it!
According to load
jQuery uses the browser's .innerHTML property to parse the retrieved document and insert it into the current document. During this process, browsers often filter elements from the document such as <html>, <title>, or <head> elements. As a result, the elements retrieved by .load() may not be exactly the same as if the document were retrieved directly by the browser.
And after digging into your html code after you click the browser action, it seems the body tag is not included.
You can use the following code instead load
var template = chrome.extension.getURL('template/test.html');
console.log(template);
$.get(template, function(data) {
document.open();
document.write(data);
document.close();
$.cache = {};
}, "text");
Related
I'm working on a WebExtension that scrapes some data from a web page. The page in question dynamically loads stuff into an iframe, and the iframe contains the stuff I need. The data I need never gets written to the iframe document, it only exists in the JS objects.
From inside of my WebExtension, I'm trying to do the following:
var result = $("iframe")[0].contentWindow.eval("(function() { return $('#grid').jqxGrid('getrows'); }())");
This works flawlessly when using the extension in Firefox. No issues whatsoever.
Unfortunately, trying to do the same thing in Chrome results in the error $ is not defined on the eval.
I've been trying for the last couple of hours to figure out why and I'm at a complete loss. Would really appreciate if someone could point me in the right direction.
I'm still not sure why the eval() works in Firefox but not in Chrome, but here's what I ended up doing to get what I needed:
1) Add an event listener in my extension for a custom event.
window.addEventListener("myCustomEvent", function(e) { HandleResult(e.detail); });
2) Inject a script block with the code to fire the event, including the data I need, into the body of the iframe document.
$("body", $("iframe").contents()).append("<script>top.dispatchEvent(new CustomEvent('myCustomEvent', {detail: $('#grid').jqxGrid('getrows') }));</script>")
Shout-out to wOxxOm for pointing my brain in the right direction.
This answer https://stackoverflow.com/a/10929430/749227
to this question Is possible to debug dynamic loading JavaScript by some debugger like WebKit, FireBug or IE8 Developer Tool? is spot on for debugging dynamic scripts.
The issue I am facing is that I have a page that has a script on it, and after it loads an ajax request fires which returns with some HTML and a script that get put into the page. With the //# sourceURL=myDynamicDocumentFragment.html bit added, I can debug the dynamic script just fine.
But once it's loaded, then the other script that is part of the outer page that initially loaded goes off the rails. I can set breakpoints on blank lines and can't set them on legitimate lines. The debugger will stop on them but it won't be at the place in the code where I'd expect.
What it appears to be is that the dev tools window is showing the original script, and the debugger itself is running on something else - some updated version of code that includes both the outer page's script and the dynamic script that was added later. Or maybe it just hiccups with respect to line numbers it's displaying and what those map to in the code it's actually running.
I wish I had a good simple code snippet to demonstrate the issue, but I don't. Has anyone seen this, and does anyone know of a way to have Chrome 'refresh' the dev tools scripts/debugger without refreshing the page? (it has to be w/o refreshing the page since things work fine when the page loads - it's only after the dynamic script is dropped in that the wheels come off)
Note: I've tagged with Chrome since that's what I'm using (v 38). I don't know how other browsers fare.
You can find scripts injected into head or evaluated, here is a break point added on youtube evaluated (another js file).
You can find this in chrome as well, adding console.log (click on message shown), and voila you have source code you can add break points.
Here mozila print debugging/breakpoint over evaluated script on utube page:
Update
Sorry, I understand chrome was out of the scope, my engrish :)
How I did debugging on chrome over injected scripts, but there are cases when you cannot attach to execution if script is active (page load plus few milliseconds), you need to search for workarounds.
Added this at the begin of the script injected:
//# sourceURL=jseinjectedsource.js
console.log("evaluated");
and voila console:
Better check this way better than my explanation chrome developer
Check to see if your script is using a source map (if you're using TypeScript this is typically on by default for VS projects).
I've found Chrome to be really bad with source maps, often refusing to update them, or stop displaying them after the source map line is removed from the code.
Precondition:
I have an aspx-page with iframe inside. This iframe points to the url handled by MVC on the same site (it's hybrid site, both standard ASP.NET and ASP.NET MVC). The resulting page rendered by MVC contains a lot of scripts references.
Problem:
IE9 throws an exception on every single script it load in iframe. These exceptions are similar to this one:
Error: 'Function' is undefined
That is, it says that the most basic things every window has is somehow absent. Once you clicked through all of these popups, the page just works as designed!
If I load a URL from <iframe /> src attribute in the browser directly, everything works as expected.
If I open the page in another browser (I tried Opera, Firefox), everything works as expected -- no errors.
So, what IE9 wants?
There is this msdn page about this bug (or feature).
You get these kinds of errors when you move the iframe element around in DOM. In such cases, IE 9 garbage collects the iframe (causing your undefined bug) and reloads it at another position.
In general, you should create the element, set its src attribute only once and then put it somewhere in the DOM tree once. It has nothing to do with the code which runs in the iframe itself.
I have encountered this same situation in the wild. Basic symptoms:
You load script code in an iframe
The script code runs early (from the head section or top of body)
IE complains about some missing native object
I found that it can often be prevented by delaying the execution of the script code until onload or DOMContentLoaded... Not much help I know but this is one of the most difficult IE scripting bugs I have ever encountered. I upped the score of your question, hope it will be found by others as well and we can get a more detailed answer.
Also see this question:
Error in Internet Explorer 9 (not earlier versions or other browsers) when including jQuery in an iframe
Placing the following script block at the very top of the iFrame html <head> seems to resolve the issue in my case. Basically, it forces the iframe to reload, which as some have pointed out, solves the issue. It seems relatively safe, because, without things like 'Object' and 'Date', javascript is essentially useless.
<script type="text/javascript">
if(typeof(Object)==="undefined"){
window.location.reload();
}
</script>
Try loading the javascript at the end after complete web page is loaded. I feel the script is executing even before the iframe is completely loaded.
for some suggestion of scripting in IE9 view the given link below
http://blogs.msdn.com/b/ie/archive/2010/06/25/enhanced-scripting-in-ie9-ecmascript-5-support-and-more.aspx
Further investigation revealed that the solution is to add the offending iframe to it's dom location BEFORE setting the 'src' attribute.
Once the 'src' has been set, changing location of the iframe within the DOM stack forces IE9 to garbage collect it.
Once 'src' has been set, iframe can be resized and changed via css positioning, but cannot change the relative location in the DOM stack.
Often times, plugins like dialogs and lightboxes will stuff an iframe with src already set into the dom, then append / prepend or whatever, triggering the GC to take place.
function waitForjQuery(){
if(typeof jQuery!='undefined'){
//Do yor stuff!
}
else{
setTimeout(function(){
waitForjQuery();
},500);
}
}
waitForjQuery();
I have a bookmarklet that launches a window.open javascript function to open a small window with my bookmarklet -- an external feature used to communicate between any visted site and my server. I'd like for a favicon to show up when the bookmarklet is added to the bookmark toolbar. I realize that the bookmarklet is javascript, there is no domain tied to it so it's going to be either difficult or impossible to achieve this goal.
My understanding of the problem:
Favicons are easy to understand, a link within the head of an HTML doc. The browser can pull this when bookmarking an actual site by reference. However, as you see my bookmarklet is ran off a javascript launch code where there exists no HTML, therefor no link to a favicon. I'm not ready to give up yet though, I feel that there's some injection that can be made...
As of now, the bookmarklet launch code looks like this:
Current Script -- bookmarklet, no favicon (note all code is formated with line breaks -- won't work in all browsers, normally its one line)
javascript:void(window.open(
'http://mydomain.com/bookmarklet/form?u='
+encodeURIComponent(location.href)+
't='+encodeURIComponent(document.title),
'test','status=0,toolbar=0,location=0,menubar=0,
resizable=false,scrollbars=false,height=379,width=379'
));
The closest thing I've found to a solution is as follows, but it doesn't open a new window -- just creates a new tab with the html as the page:
Working favicon, no bookmarklet window
javascript:'<!DOCTYPE html>
<html><head>
<title>Hello World</title>
<link rel="icon" type="image/png" href="http://www.tapper-ware.net/devel/js/JS.Bookmarklets/icons/next.png" />
</head>
<body>Hello World</body>
</html>';
I have tried a combination of the two but it didn't seem to use the icon. I'd be curious to know if anyone can see a type of workaround.. I think it could be possible, I just don't think it's set up correctly as I've been trying.
My hybrid of the two -- bookmarklet but no favicon
javascript:'<!DOCTYPE html>
<html><head>
<title>Hello World</title>
<link rel="icon" type="image/png" href="http://www.tapper-ware.net/devel/js/JS.Bookmarklets/icons/next.png" />
</head><body>Hello World</body></html>';
window.open('http://mydomain.com/bookmarklet/form?u='
+encodeURIComponent(location.href)+
'&t='+encodeURIComponent(document.title),
'test',
'status=0,toolbar=0,location=0,menubar=0,resizable=false,
scrollbars=false,height=379,width=379').void(0);
What I did was use the html structure before firing window.open(), this successfully opened my bookmarklet in a new window, but no favicon showed up for the bookmark icon.
Logical Solution:
My thoughts on this would be to have the bookmarklet point to a page that is simply an HTML file with a favicon link and the launch script in the <head>. However, I don't want this opening in a new tab with a blank HTML file that then launches a popup.. Workaround..?
There exists a similar question but I did not seem to find the answer I'm looking for:
How to have favicon / icon set when bookmarklet dragged to toolbar?
Source for the working javascript favicon (no bookmarklet however):
http://www.tapper-ware.net/blog/?p=97
I'd be interested in what your current knowledge/thoughts on this would be
I tried and retried, and my first conclusion was: "It can't be done (at least not in FF4 on Ubuntu 11.04)". You need (I guess) a simple solution for your site visitors (drag&drop, add bookmark with 1 click ...).
I have found a workaround, it does it's job, but it is a little buggy (maybe someone can help fix it).
PROS:
add a icon to the bookmarklet
it uses windows.open
doesn't leave empty pages behind
CONS:
it reloads the current page (instead of leave a page behind)
Can't make Firefox POP-ul blocker allow "javascript:" generated HTML page to load POP-ups, so you need to hit allow every time
This is the code:
Bookmarklet
This is a link that you put on your page, the user needs to drag&drop this link to the bookmark bar (you can use something like Add Bookmark Script for adding it as a bookmark with 1 click), The bookmark has no icon until the user click's it at least once.
So how it supose to work:
1. redirect the user to the generated HTML page from the bookmarklet (that makes the ICON posible)
2. onLoad open the window you need using "windows.open"
3. redirect the page back using "history.back(-1)"
In theory everithing happens so fast, that the user does't see the new page, just that the current page is reloading, and a new windows appear.
The problem:
1. I use setTimeout for history.back beacause window.open is blocked by Firefox, so I need to click allow every single time (if somebody can fix this ... we have a chance of using this, develop it further :) )
I know THIS is not a reliable solution, but this is the only solution I've got so far.
Hope this helps a little. :)
Some of the things that I've tried that might possibly get you going a bit more:
Append a new link element to the current document:
javascript: var newLink = document.createElement('link');
newLink.setAttribute('rel','icon');
newLink.setAttribute('type','image/png');
newLink.setAttribute('href','http://www.tapper-ware.net/devel/js/JS.Bookmarklets/icons/next.png');
document.querySelector('head').appendChild(newLink);
void(0);
Note that I was using the querySelector due to IE testing (though works in modern browsers as well). With Chrome and FF, I kept getting invalid character when trying to create the element, so I had to do piecewise attribute setting.
Tried using base64 encoded image string using the "data:image/png;base64,iVBORw0KGgoAAAA..." URI schema, but that didn't help anything due to the fact that I still had to set it to the current HTML text (which I could do, but ran into the same problem as you above of no bookmarklet).
Maybe this can't be done due to cross site scripting concerns? Not sure... Either way, really curious to see what you come up with (if you manage to come up with anything).
"I don't want this opening in a new tab with a blank HTML file that then launches a popup.. Workaround..?"
If what you after really is the visual effect, you can try launch the blank HTML in hidden iframe, then launch the javascript.
Hope that helps
When I open Developer Tools in Google Chrome, I see all kinds of features like Profiles, Timelines, and Audits, but basic functionality like being able to set breakpoints both in js files and within html and javascript code is missing! I tried to use the javascript console, which itself is buggy - for example, once it encounters a JS error, I cannot get out of it unless I refresh the whole page. Can someone help?
Are you talking about code within <script> tags, or in the HTML tag attributes, like this?
Click
Either way, the debugger keyword like this will work:
Click
N.B. Chrome won't pause at debuggers if the dev tools are not open.
You can also set property breakpoints in JS files and <script> tags:
Click the Sources tab
Click the Show Navigator icon and select the a file
Double-click the a line number in the left-hand margin. A corresponding row is added to the Breakpoints panel (4).
Use the sources tab, you can set breakpoints in JavaScript there. In the directory tree underneath it (with the up and down arrow in it), you can select the file you want to debug. You can get out of an error by pressing resume on the right-hand side of the same tab.
You also can give a name to your script:
<script>
... (your code here)
//# sourceURL=somename.js
</script>
ofcourse replace "somename" by some name ;) and then you will see it in the chrome debugger at "Sources > top > (no domain) > somename.js" as a normal script and you will be able to debug it like other scripts
Refresh the page containing the script whilst the developer tools are open on the scripts tab. This will add a (program) entry in the file list which shows the html of the page including the script. From here you can add breakpoints.
Another intuitive simple trick to debug especially script inside html returned by ajax, is to temporary put console.log("test") inside the script.
Once you have fired the event, open up the console tab inside the developer tools.
you will see the source file link shown up at the right side of the "test" debug print statement. just click on the source (something like VM4xxx) and you can now set the break point.
P.S.: besides, you can consider to put "debugger" statement if you are using chrome, like what is being suggested by #Matt Ball
My situation and what I did to fix it:
I have a javascript file included on an HTML page as follows:
Page Name: test.html
<!DOCTYPE html>
<html>
<head>
<script src="scripts/common.js"></script>
<title>Test debugging JS in Chrome</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
</head>
<body>
<div>
<script type="text/javascript">
document.write("something");
</script>
</div>
</body>
</html>
Now entering the Javascript Debugger in Chrome, I click the Scripts Tab, and drop down the list as shown above. I can clearly see scripts/common.js however I could NOT see the current html page test.html in the drop down, therefore I could not debug the embedded javascript:
<script type="text/javascript">
document.write("something");
</script>
That was perplexing. However, when I removed the obsolete type="text/javascript" from the embedded script:
<script>
document.write("something");
</script>
..and refreshed / reloaded the page, voila, it appeared in the drop down list, and all was well again.
I hope this is helpful to anyone who is having issues debugging embedded javascript on an html page.
I was having the same problem too, how to debug JavaScript that is inside <script> tags. But then I found it under the Sources tab, called "(index)", with parenthesis. Click the line number to set breakpoints.
This is Chrome 71.
Adding debugger; on top at my script worked for me.
I know the Q is not about Firefox but I did not want to add a copy of this question to just answer it myself.
For Firefox you need to add debugger; to be able to do what #matt-ball suggested for the script tag.
So on your code, you add debugger above the line you want to debug and then you can add breakpoints. If you just set the breakpoints on the browser it won't stop.
If this is not the place to add a Firefox answer given that the question is about Chrome. Don't :( minus the answer just let me know where I should post it and I'll happily move the post. :)
If you cannot see the "Scripts" tab, make sure you are launching Chrome with the right arguments. I had this problem when I launched Chrome for debugging server-side JavaScript with the argument --remote-shell-port=9222. I have no problem if I launch Chrome with no argument.
I came across this issue, however my inline function was withing an angularJS view. Therefore on the load i could not access the inline script to add the debug, as only the index.html was available in the sources tab of the debugger.
This meant that when i was opening the particular view with my inline (had no choice on this) it was not accessible.
The onlly way i was able to hit it was to put an erroneous function or call inside the inline JS function.
My solution included :
function doMyInline(data) {
//Throw my undefined error here.
$("select.Sel").debug();
//This is the real onclick i was passing to
angular.element(document.getElementById(data.id)).scope().doblablabla(data.id);
}
This mean when i clicked on my button, i was then prompted in the chrome consolse.
Uncaught TypeError: undefined is not a function
The important thing here was the source of this : VM5658:6 clicking on this allowed me to step through the inline and hold the break point there for later..
Extremely convoluted way of reaching it.. But it worked and might prove useful for when dealing with Single page apps which dynamically load your views.
The VM[n] has no significant value, and the n on equates to the script ID. This info can be found here : Chrome "[VM]"
Using Visual Studio (2012) I had the same issue and switching to IIS Express solved the problem!
The script tag's type attribute did not factor into it.
For some reason the Visual Studio Development Server does not provide everything Chrome needs to enable the breakpoints.
This is an extension of Rian Schmits' answer above. In my case, I had HTML code embedded in my JavaScript code and I couldn't see anything other than the HTML code. Maybe Chrome Debugging has changed over the years but right-clicking the Sources/Sources tab presented me with Add folder to workspace. I was able to add my entire project, which gave me access to all of my JavaScripts. You can find more detail in this link. I hope this helps somebody.
You have to add type="text/javascript" to the script blocks for them to be picked up as script. For example:
<script type="text/javascript"> ...your code here... </script>
for someone like me: just want to
(add breakpoint to) debug normal js code
<script> ... </script> inside/embedded html
Steps:
Sources -> Page -> Top -> find your html -> click -> right side show html and js script -> add breakpoint -> debug