Check webkit version with javascript embedded pywebkitgtk? - javascript

Apparently the best way to check the version of webkit is
/AppleWebKit\/([\d.]+)/.exec(navigator.userAgent)
(as seen here and a few other places). What is this /AppleWebKit/, a hidden variable, a constant, a regex?
I noticed it worked fine in the browser, but would not work in an embedded pywebkitgtk, it returns null. Is there something missing in the embedded webkit?

/AppleWebKit/([\d.]+)/ is a regular expression which navigator.userAgent is checked against.
The navigator object returns information about the browser you use (name, version, etc). So I guess this does not exist in pywebkitgtk, as it's only a framework for WebKitGtk, not a browser by itself.

Related

Weird 'ChildNodes of undefined' error in IE8 with an AngularJS application

TypeError: Unable to get value of the property 'childNodes': object is null or undefinedundefined
After making a long list of modifications to my application in order to support IE8, including:
running all of the views in their compiled form through W3C validator, setting up xdomain.js proxy to support CORS API calls, making some general restructures, etc.
I was very disappointed to find out that IE8 still throws this weird error at me, while IE9 works perfectly fine.
Making changes to the Angular-seo package to prevent it from running when the client is an IE browser.
Any ideas on what can it be?.
Make sure that all your tags are closed properly. I just spent hours trying to figure out what the problem was, until I noticed this in my code:
<span>some text<span>
I finally realized I didn't close the <span> tag properly. After that everything just worked.
Without the code you are running it is a bit difficult. However there is a command to use for debugging. First you need to identify which variable might not contain an object [i.e.
"object is null or undefined"].
For example, parent, then you can use
//next look to see if parent is something
if('undefined'==(typeof parent)) alert("variable empty:parent");
Once you find something that is empty that you are expecting to be an object then you can go trace back from there. Also use a browser debugged tool, to identify the line number of the error.
Often if using the child nodes, you may not have the right level or you need to access as an array i.e. you need something like.
parent.childNodes[0].childNodes[0].value
In IE you are also dealing with unsupported functions. So getElementById will work but some other similar ones do not. Again typeof can be useful.
//next ensure function supported
if( 'undefined'==(typeof document.getElementsByClassName) ){
alert("Not Supported"); // notice ^ no () required here
//...add code to handle differently when not supported
}
This may reveal if you can use a function
IE8 is so old and non-standards compliant it doesn't support childNodes[]. http://quirksmode.org/dom/core/#t70

JSON.stringify and JSON.parse not working in IE9?

I'm using JSON.Stringify and JSON.parse everywhere and it works fine with Firefox. It's working no more with IE9 nor does it work in IE8. What can I do?
JSON.stringify starts with a lower-case s. Both stringify and parse are available in IE8+, but only in standards mode.
Prepend your document with <!DOCTYPE html> if you're currently using quirks mode. Also, watch the capitalization of the JavaScript methods you call - all built-in ones start with a lower-case character.
why do you want to depend on the browser having the object instead just include the script file by Douglas Crockford.. You can find the minifed file here: http://www.json.org/js.html
Once imported you dont have to worry abt the method existing in a browser.
For an alternative, in a scenario where you might need to run in strict mode for whatever reason (I have another library that includes "use strict"), you can look here: https://github.com/douglascrockford/JSON-js. I modified this to check first if JSON is undefined, and only generate the function JSON.parse if it is:
if (typeof JSON === "undefined") {
var JSON = {
parse: <insert value of json_parse from library here>
};
}
My issue was application code not working in IE9 (strict mode being used by a participating library, I believe). That solved the problem for me.
the mere issue is, that sending UTF-8 headers will invalidate the JSON (IE doesn't/didn't like that). as the issue is described, that might still apply for IE9... once wrote a how to, a few years ago. adding JSON support to a browser which can parse native JSON is probably not the optimal solution, since it produces useless overhead - only because failing to deliver the JSON in the expected format.

IE8 / JavaScript: Override native implementation of document.all.item?

I know this is crazy, but IE can drive one to do crazy things.
Here's the deal: we have a SharePoint 2007 site with Content Editor Web Parts. We have a contingent of users with Internet Explorer 8. We want to keep the site in IE8/IE8 Standards modes for better rendering of content. However, this configuration breaks the ability to open the Rich Text Editor window from the C.E. web part.
If we force IE8 into IE7 document mode or quirks mode, it works. Indeed, other sources online have suggested doing just that to fix the problem. But we'd really rather have everything run in standards mode.
Through some debugging, we found the source of the problem to be the use of document.all.index("<web_part_id>") JavaScript when retrieving a web part object on the page. In IE8 standards, this returns an object with most of the properties either empty, null or undefined; most notably, the id property is not set. If you were to use document.getElementById to retrieve the same ID, you get back a fully populated object. Likewise if IE8 is not in standards mode, you get back a mostly (but not completely) populated object -- but populated enough to avoid the script error, anyway.
All this code looks like it is injected dynamically into the SharePoint page, so that rules out simply replacing references to document.all. However, we got the crazy idea of redefining the document.all.item method to actually invoke document.getElementById. Our attempts so far to do this don't work, so perhaps someone might shed some light on what we're doing wrong (okay, there's lots wrong about this, but it's IE and SharePoint, right?).
Our initial attempt at an override looks like this:
<script type="text/javascript">
document.all.item = function(id) { return document.getElementById(id); }
</script>
This code is in the document HEAD, above any other script references (SharePoint or otherwise), but it does not appear to supersede the native code.
Thoughts, ideas, suggestions and criticisms welcome!
document.all is a HTMLCollection, so you may use HTMLCollection.prototype to change the behaviour:
if(document.all
&& !window.opera
&& typeof HTMLDocument=='object'
&& typeof HTMLCollection=='object')//filter IE8
{
HTMLCollection.prototype.item=
function(id)
{
return((this==document.all)
? document.getElementById(id)//document.all
: this[id]//maintain native behaviour for other collections
);
}
}
So you're saying you can't change the references to document.all.item because SP directly injects it to the html? So couldn't you use the DOM to replace it?
BTW, I feel your SharePoint pain. I've built SP workflows, and those are enough of a pain for me!

alternative when an older browser does not accept jquery

I have just been altered to the fact that a user of my website is using a very old browser which does not run jquery (in this case Safari 1.x) and as a result can not access the login panel which uses jquery's slideToggle function.
Can anyone think of a fix which detects whether a browser is able to use jquery - and if not make that link go to a different page rather than showing the login panel?
You could a little conditional check like
if(!'jQuery' in window) {
// jQuery is not available
}
or, if Safari 1.x doesn't know about the IN operator (I'm not sure) use
if(!window.jQuery) {
}
I think there are alternative answers to this, but for me, I would have to weigh up the time it will take you to support his obsolete browser (I'm sure there may be other things inside the site), versus the payback to you...
In the plain HTML source code for the the href= of the login link, set that to a plain HTML login page.
Using jQuery, attach the click handler to the link, if this part fails, thats ok, the browser will just follow the href in the link to the plain login page, allowing your old-browser-user to login still.
$(document).ready(function(){
$('#login_link_id').click(function(){
// Your code here
});
});
If you use javascript/jQuery you should ALWAYS ensure your site works perfectly without it. In this case if you have a login popup box; you probably assign a click event assigned after the DOM has loaded.
What you should do is ensure that if jQuery isn't present the link loads a "normal" login webpage as opposed to the popupbox. I use something similar to this:
Log in
<script>
if(!'jQuery' in window) {
$(document).ready(function(){
//assign on click event to loginlink
});
}
</script>
If jQuery doesn't exist then login.html will be opened normally.
Wow, seriously?! Safari 1.x?? Anyhow, try this...
var isJQSupported = false;
$(function() { //shorthand for document.ready
isJQSupported = true;
//your usual code
});
if (!isJQSupported) {
window.location = "http://www.apple.com/safari/download/";
}
To me it sounds like safari 1.X has problems with jQuery internally. Which means simple checks like whether $ exists in the global space or whether $(function) does anything are not going to help.
The most likely root cause will be that javascript throws an error in loading of jQuery itself which will then stop the rest of your javascript code from execution.
There are four viable options here.
Either make the website work with noscript. Replace your login control with pure HTML and postbacks and ask the user to turn javascript off. This option is useful since you won't be fixing the issue for safari 1.x problems specifically.
You can make javascript check for safari 1.X and other non-supported browsers and only load jQuery through script tag injection or ajax if your user is using a supported browser. If the user is using a browser not compatible with jQuery then you can instead use plain javascript.
Get a copy of safari 1.x and see why jQuery breaks. Then fix it and ask for it to pulled into the release of jQuery 1.5. This relies on the fix being something that does can be done without hacking and that the jQuery team agrees is worth adding in.
Ask the user to use a compliant browser.
There might be some more options. I would personally lean towards asking the user to use a compliant browser because supporting Safari 1.x is ridiculous.
This seems like a case where progressive enhancement is needed.
You have to do multiple checks
see if $ exists
see if $.fn exists
[not sure if needed] check if $.support is a function
check for feature support as needed with $.support() http://api.jquery.com/jQuery.support/
At the end of the check, when jQuery reports that features you need are present - the rest of the script can run.
If you're not sure which features mentioned in the support you use, then this might need a single test on Safari 1.x to see what are the values returned by $.support(), but that is what your nasty old-browser-user can do for you (if you prepare code and publish) and report the resulting text. Then you compare the list with other [old] browsers that are accessible and determine features that are required.
The easy way would be to require everything and cancel all scripts if suport for any feature is missing. This will also rule out IE6 and IE7 and opera below 9.something and firefox below 2.0 or including - I'm not sure.
Use a server side language to detect if it's the old safari based on user-agent and load a different javascript file

jQuery.data() works in Mac OS WebKit, but not on iPhone OS?

I'm playing around with jQTouch for an iPhone OS app that I've been toying with off and on for a while. I wanted to try my hand building it as a web app so I started playing with jQTouch. For reference, here is the page+source (all my code is currently in index.html so you can just "View Source" to see it all):
http://rpj.me/doughapp.com/wd/
Essentially, I'm trying to save pertinent JSON objects retrieved from Google Local into DOM objects using the data() method (in this example, obj is the Google Local object):
$('#locPane').data('selected', obj);
then later (in a different "pane"), retrieving that object to be used:
$('#locPane').bind('pageAnimationEnd', function(e, inf) {
var selobj = $(this).data('selected');
// use 'selobj' here ...
}
In Chromium and Safari on the desktop OS (Snow Leopard in my case), this works perfectly (try it out).
However, the same code returns undefined for the call to $(this).data('selected') in the second snippet above. I've also tried $('#' + e.target.id).data('selected') and even the naive $('#locPane').data('selected'). All variants return undefined in the iPhone OS version of WebKit, but not on the desktop.
Interestingly, the running this on Mobile Safari in the iPhone Simulator fails as well.
If you look at the full source, you'll see that I even try to save this object into my global jQTouch object (named jqt in my code). This, too, fails on the mobile platform.
Has anyone else ever ran into this? I'll admit to not being a web/javascript programmer by trade, so if I'm making an idiot's error please call me out on it.
Thank you in advance for the help!
-RPJ
Update: I didn't make it clear in the original post, but I'm open to any workaround if it works consistently. Since I'm having trouble storing these objects in general, anything that allows me to keep them around is good enough for now. Thanks!
Have you tried using HTML5 data-ref attributes? The data has to be stringified, but you can just do
$('#locPane').attr('data-selected', "somestring");
and still have valid HTML5 markup.
As far as I can tell there seems to be a bug in Mobile Safari storing objects like this. So what I did was to simply store the components of the object in the documents data store.
$(document).data( "lessonCode" , lesson.lessonCode);
$(document).data( "question" , lesson.question);
$(document).data( "answer" , lesson.answer);

Categories