How to disable specific JavaScript object - javascript

HI All,
Is there a way to disable specific JavaScript object, while all other JS objects will be available for execution? Something like a script in the top line which controls the rest of JS code on the page.
For example I want to prevent navigator.userAgent execution and leave navigator.appVersion available.
Or even more advanced way, the execution result must be defined by me. Let's say my browser is FF 3.6.8 but navigator.userAgent would reture IE 8.0
Mostly I'm interested in disabling or superseding objects results that return information about user Browser, Cookie, Resolution and OS
Thanks in Advance.
Jevgenijs

I'm not sure why you would want to do this, but you can override any properties and methods on the window object just by declaring a variable with the same name in the global scope:
var navigator = {
userAgent: "",
appVersion: navigator.appVersion,
// etc...
}
alert(window.navigator.userAgent);
//-> ""

#All: I added following to user.js file ( link text ) and it helped. Now neither my FF browser nor OS type never recognised by any website even by those showed through iframe like adsence.
user_pref("general.useragent.appName", "replacement string for appNameCode");
user_pref("general.appname.override", "replacement string for appName");
user_pref("general.useragent.override", "replacement string for userAgent");
user_pref("general.appversion.override", "replacement string for appVersion");
user_pref("general.platform.override", "replacement string for Platform");
Now it is left to override following screen.width, screen.heigh, screen.colorDepth but these objects seems unable to be overridden via user.js file.
So far only one idea:... most likely FireFox JS engine retrieves these values from OS, hence I need to know which file in Linux (Ubuntu) stores these values and temporary change it when I need. With any WIN OS it would be mush harder to do since it stores everything in damn registries. Am I right ?
Any more ideas ?
Regards

Related

Detect old Internet explorer Javascript functions ( < ES6)

There is a web online, library or something to detect old IE functions that are not compatible with Chrome/Firefox or just ES6?
Like: document.all, event.returnValue, etc
JsHint/Jslint are not detecting them as deprecated or incompatibles
It's not quite fair to say JSLint won't tell you about deprecated properties. Let me explain.
Recall first that JavaScript is a dynamic language. You can assign any property to [almost] any object. You could assign all to window in a browser context if you wanted just by saying window.all = "Muahahaha!!! I'm evil!!!". You could add .all to a string with...
var spam = "a string";
spam.all = "I'm still evil!!!"
Or, worse, some piece of code could have changed the prototype for String (or any other object type) somewhere outside of your file. Try this in a browser console:
String.prototype.all = String.prototype.all || "This is beyond evil.";
// 'This is beyond evil.'
var spam = "spam"
// undefined
spam.all
// 'This is beyond evil.'
So JSLint doesn't, by default, check for properties on objects by names. Especially for objects that could live outside of your file's context (because JSLint lints file-by-file), it simply can't know what's happened to an object's properties and identify what's valid and what isn't.
(That's what TypeScript is for, btw.)
Unless you tell JSLint how!! -- the JSLint property directive ftw
Or you can use the JSLint property directive, which does exactly what you want, if you're willing to do some work.
If you put the property directive at the top of your file, JSLint will show errors for any properties that are used by objects on the page that aren't in that list.
For instance, try this on the official JSLint.com page:
/*property
log
*/
/*jslint browser, devel */
function mySpam() {
var spam = document.all;
console.log(spam);
}
See how I'm using document.all but all isn't in the property directive? It's going to error for me.
1. Unregistered property name 'all'.
var spam = document.all;
You might be saying, "But it will take me FOREVER to get all the good properties from my 3000 line file I'm linting into that directive!!"
Not so! Here's a tip: Paste your file, even unlinted, into JSLint.com. It will create a property directive for you in its report.
Here's one I made from AngularJS' [sic] route.js in just a few seconds:
/*property
$$minErr, $evalAsync, $get, angularVersion, caseInsensitiveMatch, create,
defaultPrevented, eagerInstantiationEnabled, extend, info, isArray,
isDefined, isObject, isUndefined, length, module, noop, originalPath,
otherwise, preventDefault, provider, redirectTo, reload, reloadOnSearch,
reloadOnUrl, routes, run, substr, when
*/
Alphabetical, even.
Now just remove the ones you don't want and presto! You'll catch everything you need.
Is this a little tedious, and will it take a little massaging/training on files that use document properly? Yes, but, again, in a dynamic language, this is close to the best you can hope for with file-by-file linters.
NOTE: If this doesn't solve your issue, however imperfectly, that's when we need to see more of your files and hear more precisely what problem you're trying to solve in practice.

IE Object doesn't support this property or method

This is probably the beginning of many questions to come.
I have finished building my site and I was using Firefox to view and test the site. I am now IE fixing and am stuck at the first JavaScript error which only IE seems to be throwing a hissy about.
I run the IE 8 JavaScript debugger and get this:
Object doesn't support this property or method app.js, line 1 character 1
Source of app.js (first 5 lines):
var menu = {};
menu.current = "";
menu.first = true;
menu.titleBase = "";
menu.init = function(){...
I have tested the site in a Webkit browser and it works fine in that.
What can I do to fix this? The site is pretty jQuery intensive so i have given up any hope for getting it to work in IE6 but I would appreciate it working in all the others.
UPDATE: I have upload the latest version of my site to http://www.frankychanyau.com
In IE8, your code is causing jQuery to fail on this line
$("title").text(title);
in the menu.updateTitle() function. Doing a bit of research (i.e. searching with Google), it seems that you might have to use document.title with IE.
Your issue is (probably) here:
menu.updateTitle = function(hash){
var title = menu.titleBase + ": " + $(hash).data("title");
$("title").text(title); // IE fails on setting title property
};
I can't be bothered to track down why jQuery's text() method fails here, but it does. In any case, it's much simpler to not use it. There is a title property of the document object that is the content of the document's title element. It isn't marked readonly, so to set its value you can simply assign a new one:
document.title = title;
and IE is happy with that.
It is a good idea to directly access DOM properties wherever possible and not use jQuery's equivalent methods. Property access is less troublesome and (very much) faster, usually with less code.
Well, your line 1 certainly looks straight forward enough. Assuming the error line and number is not erroneous, it makes me think there is a hidden character in the first spot of your js file that is throwing IE for a fit. Try opening the file in another text editor that may support display of normally hidden characters. Sometimes copying/pasting the source into a super-basic text-editor, like Notepad, can sometimes strip out non-displayable characters and then save it back into place directly from Notepad.

Creating an export function with JavaScript?

I'm trying to set up an export function in JavaScript for a packaged web app that turns a string stored in localStorage into a plain text file for downloading. As JavaScript does not have access to the computer's file-system, I'd like to set it up so that it create a blank text file (or, failing that, a simple HTML page) and open in in the web-browser; as it wouldn't be accessing any file-systems I was hoping this would be possible.
I was thinking of using a Data URI scheme to open the localStorage as plain text, such as the following:
function exportFile() {
window.open("data:text/plain;charset=utf-8," + localStorage.WebAppData);
};
But it's much slower than I expected, which I guess is because it's sticking the whole document in the URL box. Though probably not an issue with the code, some web browsers, like Google Chrome, won't let me save the resulting file. (And for some reason all the line-breaks have turned into spaces....)
Any suggestions to fix these problems or better ways of doing a similar function will be greatly appreciated!
Did you try something like:
window.open("data:text/plain;charset=utf-8," + localStorage.WebAppData);
For the download, I guess you need a round trip to a server, that will set a mime/type that will make the download box to pop up.
EDIT:
If you use localStorage, may be window.postMessage is available in your environment and could help for speed.
In order to retain line-breaks in the data exported with window.open you may wrap up your data with encodeURI:
var data1 = "Line \n break. And \r\n another one";
window.open("data:application/octet-stream, " + encodeURI(data1));
Otherwise you may export your data encoded in base64 with the btoa function:
var data1 = "Line \n break. And \r\n another one";
window.open("data:application/octet-stream;base64, " + btoa(data1));
Not really a solution, rather a work-around, but your question and the answer by #Mic lead me down this route:
Just use data:text/html as then you can put in line breaks using <br />
I tried everything else (all combinations of unicode characters, etc, ) to get line breaks in text/plain but couldn't get them to show up. document.write() and document.body.textContent(), etc also suffer from the same problem. Line breaks just get ignored.
Since Chrome won't let you save the popup window anyway, the only way to get text out of it is copy and paste so there is no benefit of using text/plain over text/html
In web browsers that will let you save the page (Firefox) you can choose to save the page as text, rather than HTML and so you still get the same end result.
EDIT: This approach works in Chrome, but not Firefox
win = window.open("", "win")
win.document.body.innerText = "Line \n breaks?"
Have to use innerText though. InnerHTML or textContent remove the line breaks. This works on both:
win = window.open("", "win")
win.document.body.innerHTML = "<pre>Line \n breaks?</pre>"
So perhaps you could just wrap everything in <pre> tags? Although I guess both of these have the same "problem" as the ` suggestion in that it's actually creating a HTML document rather than a text/plain one.

Webkit Develop Inspektor show long strings

When i debug javascript in webkit browser(f.e. Safari), often i have some string variables and value of these variables are often very long, webkit make it shorter with "..." at the end, but i want to see all value of this variables, how can i do this?
As far as I know all texts are truncated only when being listed as property of an object. If you're logging a text variable directly, it should show the whole text.
var foo = {bar:Array(1000).join('baz')};
console.log(foo); // this will truncate value of foo.bar
console.log(foo.bar); // this should show the whole text
If you still want to change the limit, here is my quick solution.
It may not be the best way to do this, but if you can find a JS file responsible for Dev tools (for my Google Chrome installation the file is DevTools.js, for Safari 5 - InjectedScript.js), open it in a text editor, look for the function InjectedScript._describe. Inside this function you will find
if (obj.length > 100)
return "\"" + obj.substring(0, 100) + "\u2026\"";
increase the limit from 100 to sth else or remove both lines.
I recently discovered that the Chrome dev tools has a copy function which copies to clipboard - without truncation! Handily it also serializes objects to JSON and DOM elements to HTML, straight to the clipboard.
copy(someLongString); // no truncation!
copy({ foo : true }); // JSON
copy(someDOMElement); // HTML
Since I was trying to copy a long string to clipboard for analysis elsewhere, this served my needs perfectly

Cross-window Javascript: is there a right way?

Problem
I'm trying to make a method that passes objects to a similar method in a popup window. I don't have control over the code in the target method, or the object passed in. The target method currently serialises the object, using JSON.stringify where possible, or instanceof Array.
The first problem with this is a bug in IE8 (see below). The second, and more fundamental, is that primitives are not the same across windows:
w = open("http://google.com")
w.Array == Array // returns false
Overriding on the popup any classes that might be passed in, and then restoring them after the call works, but it's really brittle and a maintenance headache.
Serialising the object into JSON and then parsing it in the context of the window hits the Firefox bug below.
I'm also a bit loathe to do a deep copy of the object or parse the JSON using new w.Object, etc. because it doesn't feel like it should be that complicated.
Can anyone suggest a sensible way to deal with this, or should I just accept that objects can't be passed verbatim between windows?
IE bug
JSON.stringify doesn't work across windows in IE8. If I pass an object to the popup, which attempts to serialise it, stringify returns undefined. To see this problem, open the script console in IE8 and try:
w = open("http://google.com")
JSON.stringify(Object()) // returns "{}"
w.JSON.stringify(w.Object()) // returns "{}"
w.JSON.stringify(Object()) // returns "undefined" on IE8
JSON.stringify(w.Object()) // returns "undefined" on IE8
JSON.stringify([1, w.Object()]) // returns "[1,null]" on IE8
I tried working around this by setting w.JSON = JSON, but as the last test shows, that breaks when you have objects from both windows.
Firefox bug
It seems that calling w.Object() to create an object in Firefox in fact calls window.Object(). The same bug is hit when calling w.JSON.parse or w.eval. To see this, open Firebug's console and try:
w = open("http://google.com")
new w.Object instanceof w.Object // returns true
w.Object() instanceof w.Object // returns false on Firefox 3.5
w.Object() instanceof Object // returns true on Firefox 3.5
w.Object.call(w) instanceof Object // returns true on Firefox 3.5
w.JSON.parse("{}") instanceof w.Object // returns false on Firefox 3.5
w.JSON.parse("{}") instanceof Object // returns true on Firefox 3.5
w.eval("[]") instanceof w.Array // returns false on Firefox 3.5
w.eval("[]") instanceof Array // returns true on Firefox 3.5
w.eval.call(w, "[]") instanceof Array // returns true on Firefox 3.5
The only workaround I can see is parsing the JSON string myself.
For what it's worth, this is what I'm doing for now:
Ensure jquery-json is loaded in the popup window
Stringify the object
Call w.$.evalJSON(str), which binds primitives correctly
Pass that result to the method on the popup
Alternatively (if jquery-json is not available), you could inject the following script into the target:
<script type="text/javascript">
function parseJSON(j) {
return JSON.parse(j)
}
</script>
as that will capture the popup's JSON, and not the caller's.
Any better solutions gladly appreciated.
If you are trying to do cross-domain scripting, seems like JSONP might be worth investigating.
I can't say I understand your problem fully, but there's an interesting window.name hack that's worth checking out: http://www.sitepen.com/blog/2008/07/22/windowname-transport/ (the blog post uses dojo but, of course, it can be done with pure JS too). It's safer than JSONP, easy to implement and it seems to work on all browsers.
Basically, it allows you to store any data, of any length in the window.name variable. What's awesome is that this variable doesn't get flushed/cleared on page change/refresh, so with some clever use of iframes you get simple and secure cross-domain transport :)
To see this, open Firebug's console
and try:
Error: Permission denied for <stackoverflow> to get property Window.Object from <google>.
On any line except first one: w = open("http://google.com")
Firefox 3.5.7
Think for a moment: You ar trying to open new window with arbitrary site and send to it data available to js. Seems too insecure to allow this.

Categories

Resources