Replacing XML DataIsland Files in asp.net - javascript

The app I am working on, currently uses XML dataisland files to retrieve the dropdown data. Below is the code that defines the file.
<xml id="DefaultDataIslands" src="../XMLData/DataIslands-<%=((User.Identity).Database)%>.xml">
</xml>
Below is an example code that uses these XML dataislands.
var oDataIsland = document.getElementById("DefaultDataIslands");
var oXmlNodes = oDataIsland.XMLDocument.selectNodes("XMLDataIslands/DataIsland[#ID='DIMRGroup']/Option");
This oDataIsland line is used about 4k times total in the application. The application itself is intranet, so, I can even ask the users to download the xml files directly. Whole point is to keep the changes required to minimum, while removing all traces of XML tags. I want to make sure that application works on Chrome once this thing is completed.
I checked the link from mozilla regarding the dataislands here. https://developer.mozilla.org/en/docs/Using_XML_Data_Islands_in_Mozilla
Below is the code based on that mozilla link.
var doc = document.getElementById(strDataSource).contentDocument;
var mainNode = doc.getElementsByTagName("DataIsland");
var oXmlNodes;
var strOptions = "";
//finds the selected node based on the id, and gets the options for that id
for (i = 0; i < mainNode.length; i++) {
if (mainNode[i].getAttributeNode("ID").nodeValue == strDataMember) {
oXmlNodes = mainNode[i].getElementsByTagName("Option");
}
}
This code reads the data properly, works perfectly in IE (10 with standards mode, no quirks), was easy enough change to do in the full solution.
Only problem is, document.getElementById(strDataSource).contentDocument; line fails in Chrome. This is the same line as what was mentioned in Mozilla's documentation. But somehow contentDocument property is undefined on chrome.
So, I need some other suggestion on how to get this fixed. I tried other methods, using HTTPRequest (too many request per page), using JSON (requires changing existing methods completely), using backend to process XML instead of doing it client side (requires architectural changes). Till now, all these ideas failed.
Is there any other method that I can use? Or should I fix the contentDocument issue?

To allow contentDocument in Chrome, you will have to use --allow-file-access-from-files. Following are the steps for doing so:
Get the url of your Chrome Installation path to your chrome
installation e.g
C:\Users-your-user-name\AppData\Local\Google\Chrome\Application>
Launch the Google Chrome browser from the command line window with
the additional argument ‘–allow-file-access-from-files’. E.g ‘path
to your chrome installation\chrome.exe
--allow-file-access-from-files’
Temporary method you can use each time you are testing
Copy the existing chrome launcher
Do as above and save it with a new name e.g chrome - testing
Alternatively, you can simply create a new launcher with the above and use it to start chrome.
Source

Related

window.performance.memory is not giving updated data but it should give

I am trying to get memory used by a particular tab in the browser using JavaScript code.
I have tried using window.performance.memory in Chrome. It gives me the JS heap size data but the data returned by it everytime is constant. I am creating new objects in my code (hence, memory usage should increase) but still it returns the same data everytime.
I have also used --enable-precise-memory-info argument to open my Chrome. Still same results.
Is there a way to get updated data from window.performance.memory?
Also is there any other way I can get memory usage data of a particular tab opened in the browser? I want this data to be exported in a text file so that I can use it for further analysis.
(I have tried using Chrome's task manager and Memory Manager extension also. But I want data in a text file.)
Try window.performance.memory after opening chrome in administrator mode.

How do I read a JSON file using HTML?

Here is my code:
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js">
</script>
<script>
$(function() {
var thing = [];
var bar = $.getJSON('C:\Users\cccompro\foo.json', function(obj) {
for (i = 0; i < obj.length; i++) {
thing.push(obj[i]);
}
});
});
</script>
I'm not sure why it doesn't work. "foo.json" contains an array of objects.
If you are trying the code at Question at Chrome or Chromium browsers, launch the browser instance with --allow-file-access-from-files flag set. Note that open instances of Chrome or Chromium should be closed when you launch the browser or the instance will be launched with the open browser instances' configuration folder, instead of with the flag set. You can launch Chrome or Chromium with an existing instance open and honoring the flag by using --user-data-dir flag with value set a different directory than open instance of Chrome or Chromium.
Technically, it is also possible to write to user file system without using an extension with window.webkitRequestFileSystem. Though using chrome.fileSystem within an extension provides an API designed to achieve the read/write.
See
Jquery load() only working in firefox?
Read local XML with JS
How to Write in file (user directory) using JavaScript?
How to use webkitRequestFileSystem at file: protocol
JavaScript/Ajax Write to File
Using <input type="file"> element
How to print all the txt files inside a folder using java script
You cannot read files directly from the users hard drive without the browsers permission. This would be a huge security issue if you could even though there are ways to allow this (checkout guests answer).
You could however try to make the user select the file and then read it with Javascript.
This is called the HTML 5 file API.
However, this doesn't work for any browser and you probably have to use a server anyway in this case.
For more information on this checkout this or this post.

CrossRider - is there a way to pass arrays as function parameters without converting them to objects?

We are using CrossRider to develop an extension for Internet Explorer. We have an object which is downloaded from http://jsons.[part_of_link_suppressed].com.s3.amazonaws.com/selectors.json. I found out that when this object is sent to a callback, arrays are converted to objects with integer keys. Why are arrays converted to objects and is there a way to prevent it? I know we can JSON.stringify the object and JSON.parse by the calling function, but is there a way to send arrays without converting them to strings? I checked and even ['a','b','c'] is converted to an object ({"0":"a","1":"b","2":"c"}) when calling a function with it.
I'm using Internet Explorer 11 but this extension should work on all versions of Internet Explorer.
Edit (1): I tested debug mode in Internet Explorer 11 and Google Chrome. I created a new extension - ID 67708. In Chrome it works fine, in Explorer it doesn't. Here is the code:
background.js:
/************************************************************************************
This is your background code.
For more information please visit our wiki site:
http://docs.crossrider.com/#!/guide/scopes_background
*************************************************************************************/
function callme1() {
var r1 = ['a','b','c'];
alert('r1 = ' + JSON.stringify(r1));
return r1;
}
appAPI.ready(function($) {
// Place your code here (ideal for handling browser button, global timers, etc.)
alert('callme1() = ' + JSON.stringify(callme1()));
});
extension.js:
/************************************************************************************
This is your Page Code. The appAPI.ready() code block will be executed on every page load.
For more information please visit our docs site: http://docs.crossrider.com
*************************************************************************************/
function callme2() {
var r2 = ['a','b','c'];
alert('r2 = ' + JSON.stringify(r2));
return r2;
}
appAPI.ready(function($) {
// Place your code here (you can also define new functions above this scope)
// The $ object is the extension's jQuery object
// alert("My new Crossrider extension works! The current page is: " + document.location.href);
alert('callme2() = ' + JSON.stringify(callme2()));
});
In Chrome all the alerts are ["a","b","c"], in Explorer they are {"0":"a","1":"b","2":"c"}, before and after returning the object. But in our extension (ID 43889), if we JSON.stringify the object and then JSON.parse it, then it's still an array (I didn't find how to reproduce it with a simple extension).
By the way, if I type in the console JSON.stringify(['a','b','c']) in Explorer or Chrome, I get the same result - "["a","b","c"]".
I also found another irritating bug - CrossRider converts my staging extensions to production, and I have to switch again to staging manually. It happened at least 5 times with both extensions.
Edit (2): I tried to use appAPI.JSON.stringify instead of JSON.stringify and now I receive the correct results in Explorer in extension.js (["a","b","c"]), but background.js is not loaded at all in debug mode and keeps displaying the old contents. I don't know if that's because I have 2 extensions in debug mode but this is a new bug - background.js is not updated when I click "reload background code".
I had the same problem, with the messaging api. not sure what is your case (when saving to DB?)
Though i don't remember my whole debugging findings i think its like that:
Crossrider api internally serialising the values to JSON in order to send them via postMessage/their own implementation for background communication with the background IE process(for all browser/not natively support pass objects via postMessage eg IE8).
They aren't using native JSON object but rather (broken) JSON implementation (I think only on their IE background process because its not really browser page and there's no built in JSON)
That means that even if you use their appAPI.JSON when no native JSON available you still get the broken arrays.
My solution was to use external json library, think i used JSON3
http://bestiejs.github.io/json3/
http://cdnjs.cloudflare.com/ajax/libs/json3/3.3.2/json3.min.js
It would be less performant but if its not really big object it won't be noticeable.
You can also try to monkey patch their JSON appAPI.JSON with the external library, it might fix their api

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.

How to bypass document.domain limitations when opening local files?

I have a set of HTML files using JavaScript to generate navigation tools, indexing, TOC, etc. These files are only meant to be opened locally (e.g., file://) and not served on a web server. Since Firefox 3.x, we run into the following error when clicking a nav button that would generate a new frame for the TOC:
Error: Permission denied for <file://> to get property Location.href from <file://>.
I understand that this is due to security measures within FF 3.x that were not in 2.x, in that the document.domain does not match, so it's assuming this is cross-site scripting and is denying access.
Is there a way to get around this issue? Perhaps just a switch to turn off/on within Firefox? A bit of JavaScript code to get around it?
In firefox:
In address bar, type about:config,
then type network.automatic-ntlm-auth.trusted-uris in search bar
Enter comma separated list of
servers (i.e.,
intranet,home,company)
Another way is editing the users.js.
In users.js, write:
user_pref("capability.policy.policynames", "localfilelinks");
user_pref("capability.policy.localfilelinks.sites", "http://site1.com http://site2.com");
user_pref("capability.policy.localfilelinks.checkloaduri.enabled", "allAccess");
But if you want to stop all verification, just Write the following line into users.js file:
user_pref("capability.policy.default.checkloaduri.enabled", "allAccess");
You may use this in firefox to read the file.
function readFile(arq) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var file = Components.classes["#mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(arq);
// open an input stream from file
var istream = Components.classes["#mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
istream.init(file, 0x01, 0444, 0);
istream.QueryInterface(Components.interfaces.nsILineInputStream);
var line = {}, lines = [], hasmore;
do {
hasmore = istream.readLine(line);
lines.push(line.value);
} while(hasmore);
istream.close();
return lines;
}
Cleiton's method will work for yourself, or for any users who you expect will go through this manual process (not likely unless this is a tool for you and your coworkers or something).
I'd hope that this type of thing would not be possible, because if it is, that means that any site out there could start opening up documents on my machine and reading their contents.
You can have all files that you want to access in subfolders relative to the page that is doing the request.
You can also use JSONP to load files from anywhere.
Add "file://" to network.automatic-ntlm-auth.trusted-uris in about:config

Categories

Resources