Performing an AJAX call from JS in asp.net MVC without Jquery - asp.net-mvc

I am developing an app that will be used on an old WInCE devices where IE Embedded doesn't support Jquery, which is why I can use it. So, my question is, what is the way to perform an AJAX call from within a js file.
Code:
html
#using (Html.BeginForm("", "SomeAction", FormMethod.Post, new { id = "myId" }))
{
input field 1: <input type="text" name="somename1"><br>
}
What I need to do is call a validate routine and return a string when the user clicks enter on the somename1 input field.
Normally, this would be done with Jquery, so how do I do it without only utilizing what the MVC asp has to offer (again, the ajax might not work at all on the old browser, but I would like to give it a shot and avoid refreshing the whole page).

Step 1: Get a XMLHttp Object using:
function getXMLHttpRequest() {
var xmlHttpReq = false;
// to create XMLHttpRequest object in non-Microsoft browsers
if (window.XMLHttpRequest) {
xmlHttpReq = new XMLHttpRequest();
} else if (window.ActiveXObject) {
try {
xmlHttpReq = new ActiveXObject("Msxml2.XMLHTTP");
} catch (exp1) {
try {
// to create XMLHttpRequest object in older versions
// of Internet Explorer
xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
} catch (exp2) {
xmlHttpReq = false;
}
}
}
return xmlHttpReq;
}
Then do this (Just an example for downloading a file ajax request)
function myFunction(){
var xmlHttpRequest = getXMLHttpRequest();
xmlHttpRequest.onreadystatechange = getReadyStateHandler_download_file(xmlHttpRequest,file_indicator);
xmlHttpRequest.open("GET", "/wasa-app/DownloadServlet?pmuId="+pmuID+"&dlDate=" + formatted_date+"&check_flag=1"+"&file_indicator="+file_indicator, true);
xmlHttpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xmlHttpRequest.send(null);
}
function getReadyStateHandler_download_file(xmlHttpRequest, fileIndicator) {
return function() {
if (xmlHttpRequest.readyState == 4) {
if (xmlHttpRequest.status == 200) {
populateSchedule();
var resp = xmlHttpRequest.responseText;
if (resp == ""){
document.getElementById("save_" + fileIndicator).disabled = false;
document.getElementById("message").innerHTML = "";
}
else{
document.getElementById("save_" + fileIndicator).disabled = true;
document.getElementById("message").innerHTML = xmlHttpRequest.responseText;
}
} else {
alert("HTTP error -- " + xmlHttpRequest.status + ": " + xmlHttpRequest.statusText);
}
}
};

Related

Scorm files, Ruby on Rails

I have implemented a scorm api in my platform (LMS), for this I have used Ruby on rails, the Scorm gem and the javascript api.
Everything works correctly and the scorm contents are displayed with satisfaction. I do not have much experience in Scorm content, but there is a zip file that they sent me of type scorm, which when it is uploaded to the platform that I am using, it takes a long time to load and execute. when I test this file on Scorm cloud, the content runs normally. The problem is that the platform does not generate any error.
why can this happen?
bugs in my code? or optimization of the Scorm zip file?
The other scorm contents work normally, but this specific one, I have no idea why. I can not think of anything
any ideas? Thank you
this is de api js:
<html>
<head>
<title>VS SCORM - RTE API</title>
<script language="javascript">
function createRequest() {
// this is the object that we're going to (try to) create
var request;
// does the browser have native support for
// the XMLHttpRequest object
try {
request = new XMLHttpRequest();
}
// it failed so it's likely to be Internet Explorer which
// uses a different way to do this
catch (tryIE) {
// try to see if it's a newer version of Internet Explorer
try {
request = new ActiveXObject("Msxml2.XMLHTTP");
}
// that didn't work so ...
catch (tryOlderIE) {
// maybe it's an older version of Internet Explorer
try {
request = new ActiveXObject("Microsoft.XMLHTTP");
}
// even that didn't work (sigh)
catch (failed) {
alert("Error creating XMLHttpRequest");
}
}
}
return request;
}
//var debug = true;
var debug = false;
function sleep(milliseconds) {
var start = new Date().getTime();
for (var i = 0; i < 1e7; i++) {
if ((new Date().getTime() - start) > milliseconds){
break;
}
}
}
// ------------------------------------------
// SCORM RTE Functions - Initialization
// ------------------------------------------
function LMSInitialize(dummyString) {
// create request object
var req = createRequest();
// code to prevent caching
var d = new Date();
// set up request parameters - uses GET method
req.open('GET','/scorm/initializesco?code='+d.getTime(),false);
// submit to the server for processing
req.send(null);
// process returned data - error condition
if (req.status != 200) {
alert('Problem with Request');
return "";
}
// process returned data - OK
else {
return "true";
}
}
// ------------------------------------------
// SCORM RTE Functions - Getting and Setting Values
// ------------------------------------------
//function LMSGetValue(varname) {
// if (debug) {
// alert('*** LMSGetValue varname='+varname
// +' varvalue=value ***');
// }
// return "value";
//}
function LMSGetValue(varname) {
// create request object
var req = createRequest();
// set up request parameters - uses GET method
req.open('GET','/scorm/getValue?varname='+urlencode(varname)
+'&code='+Math.random(),false);
// submit to the server for processing
req.send(null);
//alert('LMSGetValue() - ' + req.responseText);
// process returned data - error condition
if (req.status != 200) {
alert('LMSGetValue() - Problem with Request');
return "";
}
// process returned data - OK
else {
return req.responseText.replace("\n","");
}
}
/*
function LMSSetValue(varname,varvalue) {
if (debug) {
alert('*** LMSSetValue varname='+varname
+' varvalue='+varvalue+' ***');
}
return "true";
}
*/
function LMSSetValue(varname,varvalue) {
// create request object
var req = createRequest();
// set up request parameters - uses combined GET and POST
//req.open('POST','nav/setValue?varname='+urlencode(varname)
// +'&code='+Math.random(),false);
// set up request parameters - uses combined GET and POST
req.open('POST','/scorm/setValue?varname='+urlencode(varname)
+'&code='+Math.random(),false);
// send header information along with the POST data
var params = 'varvalue='+urlencode(varvalue);
req.setRequestHeader("Content-type",
"application/x-www-form-urlencoded");
//req.setRequestHeader("Content-length", params.length);
//req.setRequestHeader("Connection", "close");
// submit to the server for processing
req.send(params);
// process returned data - error condition
if (req.status != 200) {
alert('LMSSetValue() - Problem with Request');
return "false";
}
// process returned data - OK
else {
return "true";
}
}
function LMSCommit(dummyString) {
LMSGetValue('');
if (debug)
{
//alert('*** LMSCommit ***');
}
return "true";
}
function LMSFinish(dummyString) {
// create request object
var req = createRequest();
// code to prevent caching
var d = new Date();
// set up request parameters - uses GET method
req.open('GET','/scorm/finishsco?code='+d.getTime(),false);
// submit to the server for processing
req.send(null);
// process returned data - error condition
if (req.status != 200) {
alert('Problem with Request');
return "";
}
// process returned data - OK
else {
return "true";
}
}
// ------------------------------------------
// SCORM RTE Functions - Error Handling
// ------------------------------------------
function LMSGetLastError() {
if (debug) { alert('*** LMSGetLastError ***'); }
sleep(1000);
return 0;
}
function LMSGetDiagnostic(errorCode) {
if (debug) {
alert('*** LMSGetDiagnostic errorCode='+errorCode+' ***');
}
return "diagnostic string";
}
function LMSGetErrorString(errorCode) {
if (debug) {
alert('*** LMSGetErrorString errorCode='+errorCode+' ***');
}
return "error string";
}
function urlencode( str ) {
//
// Ref: http://kevin.vanzonneveld.net/techblog/article/javascript_equivalent_for_phps_urlencode/
//
var histogram = {}, unicodeStr='', hexEscStr='';
var ret = (str+'').toString();
var replacer = function(search, replace, str) {
var tmp_arr = [];
tmp_arr = str.split(search);
return tmp_arr.join(replace);
};
// The histogram is identical to the one in urldecode.
histogram["'"] = '%27';
histogram['('] = '%28';
histogram[')'] = '%29';
histogram['*'] = '%2A';
histogram['~'] = '%7E';
histogram['!'] = '%21';
histogram['%20'] = '+';
histogram['\u00DC'] = '%DC';
histogram['\u00FC'] = '%FC';
histogram['\u00C4'] = '%D4';
histogram['\u00E4'] = '%E4';
histogram['\u00D6'] = '%D6';
histogram['\u00F6'] = '%F6';
histogram['\u00DF'] = '%DF';
histogram['\u20AC'] = '%80';
histogram['\u0081'] = '%81';
histogram['\u201A'] = '%82';
histogram['\u0192'] = '%83';
histogram['\u201E'] = '%84';
histogram['\u2026'] = '%85';
histogram['\u2020'] = '%86';
histogram['\u2021'] = '%87';
histogram['\u02C6'] = '%88';
histogram['\u2030'] = '%89';
histogram['\u0160'] = '%8A';
histogram['\u2039'] = '%8B';
histogram['\u0152'] = '%8C';
histogram['\u008D'] = '%8D';
histogram['\u017D'] = '%8E';
histogram['\u008F'] = '%8F';
histogram['\u0090'] = '%90';
histogram['\u2018'] = '%91';
histogram['\u2019'] = '%92';
histogram['\u201C'] = '%93';
histogram['\u201D'] = '%94';
histogram['\u2022'] = '%95';
histogram['\u2013'] = '%96';
histogram['\u2014'] = '%97';
histogram['\u02DC'] = '%98';
histogram['\u2122'] = '%99';
histogram['\u0161'] = '%9A';
histogram['\u203A'] = '%9B';
histogram['\u0153'] = '%9C';
histogram['\u009D'] = '%9D';
histogram['\u017E'] = '%9E';
histogram['\u0178'] = '%9F';
// Begin with encodeURIComponent, which most resembles PHP's encoding functions
ret = encodeURIComponent(ret);
for (unicodeStr in histogram) {
hexEscStr = histogram[unicodeStr];
ret = replacer(unicodeStr, hexEscStr, ret); // Custom replace. No regexing
}
// Uppercase for full PHP compatibility
return ret.replace(/(\%([a-z0-9]{2}))/g, function(full, m1, m2) {
return "%"+m2.toUpperCase();
});
}
</script>
</head>
<body>
<p>
</body>
</html>
You're using blocking GET/SET requests (XHR async=false) to your backend for every LMSGetValue call. Some courses are much more aggressive about how many things they get and set at launch/initialization time. Most SCORM implementations do the heavy lifting in JS (all GET value processing never touches a server, most commonly) and only go to the backend for user state storage, often at a commit or some storage frequency. If that's the issue, there's no way to fix it that doesn't involve rewriting your interface to do all the SCORM logic client-side instead of server-side, as you can't switch to using async GET calls since LMSGetValue expects the return to be the value needed.

Ajax calls working in Android but not iOS

I'm developing an app in Nativescript for the first time and running into an issue where AJAX calls work on Android but not iOS. I have a login.js file which requires a user-view-model (user-view-model.js), and when I test the code on Android it takes me to the "home" page but it hits the catch function on iOS.
login.js:
var dialogsModule = require("ui/dialogs");
var UserViewModel = require("../../shared/view-models/user-view-model");
var applicationSettings = require("application-settings");
var user = new UserViewModel({
email: "aaa#aaa.com",
password: "aaa"
});
var frameModule = require("ui/frame");
var page;
exports.loaded = function(args) {
page = args.object;
page.bindingContext = user;
};
exports.login = function () {
user.login().catch(function(error) {
dialogsModule.alert({
message: "Unfortunately we could not find your account.",
okButtonText: "OK"
});
return Promise.reject();
}).then(function(response) {
console.dir(response)
console.log("past response")
applicationSettings.setString("user_id", response.user_id);
applicationSettings.setString("first_name", response.first_name);
applicationSettings.setString("last_name", response.last_name);
applicationSettings.setString("user_type", response.user_type);
var topmost = frameModule.topmost();
topmost.navigate("views/home/home");
});
};
user-view-model.js:
var config = require("../../shared/config");
var fetchModule = require("fetch");
var observableModule = require("data/observable");
var http = require("http");
function User(info) {
info = info || {};
var viewModel = new observableModule.fromObject({
email: info.email || "",
password: info.password || ""
});
viewModel.login = function() {
let loginEmail = JSON.stringify(this.get("email")).replace(/['"]+/g, '');
let loginPassword = JSON.stringify(this.get("password")).replace(/['"]+/g, '');
console.log(loginEmail, loginPassword);
let loginUrl = config.serverPHPServiceUrl + "Login.php?user_id=" + loginEmail + "&password=" + loginPassword;
console.log(loginUrl);
// I tried this way first and wasn't able to login on iOS, which made me try the second method below.
// return fetchModule.fetch(loginUrl, {
// method: "POST",
// headers: {
// "Content-Type": "application/json"
// }
// }).then(handleErrors).then(function(response) {
// return response.json();
// }).then(function(data) {
// console.dir(data);
// console.log(data["results"][0]["user_id"])
// return data["results"][0];
// });
// This method works on Android but not iOS.
return http.getJSON(loginUrl).then(function(response) {
console.dir(response);
return response.results[0];
})
};
return viewModel;
};
function handleErrors(response) {
console.log("in errors")
if (!response.ok) {
console.log(JSON.stringify(response));
throw Error(response.statusText);
}
return response;
}
module.exports = User;
Is there anything fundamentally wrong with my code, or do asynchronous calls work differently on iOS vs Android in Nativescript? I did the Grocery tutorial and didn't run into this issue, so I didn't think this was the case. Does it matter that the backend is using PHP?
I fixed my issue: I started a new project with Angular 2 and ran into the same error, but then it gave me the error message "Error: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection." I solved it by adding "https" to my url call, but this post has another solution.

What should I return from MVC controller in case of an error to make sure DropZone will pick it up

I am using using DropZone JS with MVC. The ActionMethod that saves the images is using a try catch. Now what would I need to return from the ActionMethod in case of an error so the front end will pick that up and show the error mark to the user instead of showing everything went successful.
Is it built in with DropZone or do I need to bind it to event such as complete? If so, how?
An example of the DropZone JS complete event
this.on("complete", function (file, response) {
// If an error has occurred, mark the item as failed
if (response.code != 200){
}
// If it went through successful, show that to the user
if (response.code == 200){
}
});
If this would work, in MVC I could just return HttStatusCodeResult such as
return new HttpStatusCodeResult(HttpStatusCode.BadRequest) and return new HttpStatusCodeResult(HttpStatusCode.Ok)
UPDATED - ActionMethod
[HttpPost]
public ActionResult SaveImages()
{
bool isSavedSuccessfully = true;
string fName = "";
try
{
foreach (string fileName in Request.Files)
{
HttpPostedFileBase file = Request.Files[fileName];
if (HttpPostedFileBaseExtensions.IsImage(file))
{
//Save file content goes here
fName = file.FileName;
if (file != null && file.ContentLength > 0)
{
var originalDirectory = new DirectoryInfo(string.Format("{0}Images\\", Server.MapPath(#"\")));
string pathString = Path.Combine(originalDirectory.ToString(), "Temp");
var fileName1 = Path.GetFileName(file.FileName);
bool isExists = Directory.Exists(pathString);
if (!isExists)
Directory.CreateDirectory(pathString);
var path = string.Format("{0}\\{1}", pathString, file.FileName);
file.SaveAs(path);
_testRepository.EditMainPicture("test", pathString, "imageText", 1);
}
}
}
}
catch (Exception ex)
{
// TODO Add error logging!!
isSavedSuccessfully = false;
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
return new HttpStatusCodeResult(HttpStatusCode.Ok);
}
For some reason if anything else fails within this method, DropZone will not pick it up and it will mark as the file has been successfully uploaded. I want it to show an error if anything fails within the ActionMethod
You'll need to listen for the error event
An error occured. Receives the errorMessage as second parameter and if the error was due to the XMLHttpRequest the xhr object as third.
Example
dropzone.on("error", function(file, errorMesage, xhr) { ... });

breeze observableArray binding - are properties observable?

I have a viewmodel which consists of a list(foreach loop) of DoctorPrices and when clicking on an item in the list it open up a CRUD form on the side. However when i update the values on the CRUD the observableArray that is bound to the foreach is not refreshing? (although the values are updates in the DB correctly)
From my data access module i call the following query.
function getDoctorServices(doctorId) {
var query = breeze.EntityQuery
.from('DoctorPrices')
.where('DoctorID', 'eq', doctorId).orderBy('ListOrder');
return manager.executeQueryLocally(query);
}
In my viewmodel i have the following code:
this.services = ko.computed(function() {
return doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID());
});
services is bound using a foreach loop (not posting here as the code is simple and works)
When i click on a one of the DoctorPrices it gets the data as follows and places it in an observable:
this.selectedPrice = function (data, event) {
self.currentService(data);
self.showEdit(true);
};
I then bind selectPrice to a simple form that has the properties on it to be modified by the user. I then call manager.SaveChanges().
This results in the following problem: the value is being updated correctly but the GUI / Original List that is bound in the foreach is not being updated? Are the properties in breeze not observables? What is the best way to work with something like this.
I thought of a workaround and changing the code with something like this:
doctorList.viewModel.instance.currentDoctorID.subscribe(function() {
self.services([]);
self.services(doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID()));
});
But i feel that clearing the array in that way is sloppy and not the right way of doing things specially with long lists.
Can someone please point me in the right direction on how to bind observableArray properties properly so they are updated?
Additional code my VM Component:
function services() {
var self = this;
this.showForm = ko.observable(false);
this.currentService = ko.observable();
this.services = ko.observableArray(doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID()));
this.title = ko.observable();
doctorList.viewModel.instance.currentDoctorID.subscribe(function() {
self.services([]);
self.services(doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID()));
self.showDetails(false);
});
this.show = function (value) {
self.showForm(value);
};
this.showDetails = ko.observable(false);
this.addNewService = function() {
self.currentService(doctorServices.createService(doctorList.viewModel.instance.currentDoctorID()));
console.log(self.currentService().entityAspect.entityState);
self.showDetails(true);
};
this.showDelete = ko.computed(function() {
if (self.currentService() == null)
return false;
else if (self.currentService().entityAspect.entityState.isDetached()) {
self.title('Add new service');
return false;
} else {
self.title('Edit service');
return true;
}
});
this.deleteService = function() {
self.currentService().entityAspect.setDeleted();
doctorServices.saveChanges();
doctorList.viewModel.instance.currentDoctorID.notifySubscribers();
};
this.closeDetails = function () {
doctorServices.manager.rejectChanges();
doctorList.viewModel.instance.currentDoctorID.notifySubscribers();
self.showDetails(false);
};
this.selectService = function (data, event) {
self.currentService(data);
self.showDetails(true);
};
this.saveChanges = function () {
console.log(self.currentService().entityAspect.entityState);
if (self.currentService().entityAspect.entityState.isDetached()) {
doctorServices.attachEntity(self.currentService());
}
console.log(self.currentService().entityAspect.entityState);
doctorServices.saveChanges();
doctorList.viewModel.instance.currentDoctorID.notifySubscribers();
self.currentService.notifySubscribers();
self.showDetails(true);
};
}
return {
viewModel: {
instance: new services()
},
template: servicesTemplate,
};
Below is my Breeze Data Class:
define('data/doctorServices', ['jquery', 'data/dataManager', 'knockout','mod/medappBase', 'breeze', 'breeze.savequeuing'], function ($, manager, ko,base, breeze, savequeuing) {
var services = ko.observableArray([]);
return {
attachEntity:attachEntity,
getServices: getServices,
services: services,
manager:manager,
getDoctorServices: getDoctorServices,
getServiceById: getServiceById,
createService:createService,
hasChanges: hasChanges,
saveChanges: saveChanges
};
function getServices() {
var query = breeze.EntityQuery.from("DoctorPrices");
return manager.executeQuery(query).then(function (data) {
services(data.results);
}).fail(function (data) {
console.log('fetch failed...');
console.log(data);
});;
}
function getDoctorServices(doctorId) {
var query = breeze.EntityQuery
.from('DoctorPrices')
.where('DoctorID', 'eq', doctorId).orderBy('ListOrder');
var set = manager.executeQueryLocally(query);
return set;
}
function getServiceById(serviceId) {
return manager.createEntity('DoctorPrice', serviceId);
//return manager.getEntityByKey('DoctorPrice', serviceId);
}
function handleSaveValidationError(error) {
var message = "Not saved due to validation error";
try { // fish out the first error
var firstErr = error.innerError.entityErrors[0];
message += ": " + firstErr.errorMessage;
base.addNotify('error', 'Could not save.', message);
} catch (e) { /* eat it for now */ }
return message;
}
function hasChanges() {
return manager.hasChanges();
}
function attachEntity(entity) {
manager.addEntity(entity);
}
function createService(doctorId) {
return manager.createEntity('DoctorPrice', { DoctorPricingID: breeze.core.getUuid(), DoctorID:doctorId }, breeze.EntityState.Detached);
};
function saveChanges() {
return manager.saveChanges()
.then(saveSucceeded)
.fail(saveFailed);
function saveSucceeded(saveResult) {
base.addNotify('success', 'Saved.', 'Your updates have been saved.');
}
function saveFailed(error) {
var reason = error.message;
var detail = error.detail;
if (error.innerError.entityErrors) {
reason = handleSaveValidationError(error);
} else if (detail && detail.ExceptionType &&
detail.ExceptionType.indexOf('OptimisticConcurrencyException') !== -1) {
// Concurrency error
reason =
"Another user, perhaps the server, " +
"may have deleted one or all of the settings." +
" You may have to restart the app.";
} else {
reason = "Failed to save changes: " + reason +
" You may have to restart the app.";
}
console.log(error);
console.log(reason);
}
}
});
Please note this is my frist attempt at both a data class and VM. At the moment i am relying heavily on clearing the array ([]) and using notifySubscribers to make the array refresh :(
I bet you're missing an observable somewhere. I can't tell because you keep hopping from property to property whose definition is not shown.
For example, I don't know how you defined this.currentService.
I'm confused by this:
this.services = ko.computed(function() {
return doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID());
});
Why is it a ko.computed? Why not just make it an observable array.
self.service = ko.observableArray();
// ... later replace the inner array in one step ...
self.service(doctorServices.getDoctorServices(
doctorList.viewModel.instance.currentDoctorID()));
I urge you to follow the observability trail, confident that your Breeze entity properties are indeed observable.
vm.selectedPrice = ko.dependentObservable(function () {
return doctorServices.getDoctorServices(doctorList.viewModel.instance.currentDoctorID());
}, vm);
vm is ur model on which u applied bindings , try this it will work.

Firefox SDK: How to make trigger for certain domain

I need to catch requests on sites with URLs *.net and take some actions (stop request and put HTML code from disk, but this I can do). How do I catch these requests?
I tried to use progress listeners, but something is wrong:
const STATE_START = Ci.nsIWebProgressListener.STATE_START;
var myListener = {
QueryInterface: XPCOMUtils.generateQI(["nsIWebProgressListener",
"nsISupportsWeakReference"]),
onStateChange: function(aWebProgress, aRequest, aFlag, aStatus) {
if (aFlag & STATE_START) {
// actions
}
}
use nsIHTTPChannel and observer service. copy paste it. however .net can be included in resources like javascript things, if you want to test if its specfically a window you have to check for some load flags of LOAD_INITIAL_DOCUMENT_URI, also will want to chec
Cu.import('resource://gre/modules/Services.jsm');
var httpRequestObserver = {
observe: function (subject, topic, data) {
var httpChannel, requestURL;
if (topic == "http-on-modify-request") {
httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
requestURL = httpChannel.URI.spec;
var newRequestURL, i;
if (httpChannel.loadFlags & httpChannel.LOAD_INITIAL_DOCUMENT_URI) {
//ok continue because loadFlags is a document
} else {
//its not a document, probably a resource like a js file image or css or something, but maybe could be ajax call
return;
}
if (requestURL.indexOf('.net')) {
var goodies = loadContextGoodies(httpChannel);
if (goodies) {
httpChannel.cancel(Cr.NS_BINDING_ABORTED);
goodies.contentWindow.location = self.data.url('pages/test.html');
} else {
//dont do anything as there is no contentWindow associated with the httpChannel, liekly a google ad is loading or some ajax call or something, so this is not an error
}
}
return;
}
}
};
Services.obs.addObserver(httpRequestObserver, "http-on-modify-request", false);
//this function gets the contentWindow and other good stuff from loadContext of httpChannel
function loadContextGoodies(httpChannel) {
//httpChannel must be the subject of http-on-modify-request QI'ed to nsiHTTPChannel as is done on line 8 "httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);"
//start loadContext stuff
var loadContext;
try {
var interfaceRequestor = httpChannel.notificationCallbacks.QueryInterface(Ci.nsIInterfaceRequestor);
//var DOMWindow = interfaceRequestor.getInterface(Components.interfaces.nsIDOMWindow); //not to be done anymore because: https://developer.mozilla.org/en-US/docs/Updating_extensions_for_Firefox_3.5#Getting_a_load_context_from_a_request //instead do the loadContext stuff below
try {
loadContext = interfaceRequestor.getInterface(Ci.nsILoadContext);
} catch (ex) {
try {
loadContext = subject.loadGroup.notificationCallbacks.getInterface(Ci.nsILoadContext);
} catch (ex2) {}
}
} catch (ex0) {}
if (!loadContext) {
//no load context so dont do anything although you can run this, which is your old code
//this probably means that its loading an ajax call or like a google ad thing
return null;
} else {
var contentWindow = loadContext.associatedWindow;
if (!contentWindow) {
//this channel does not have a window, its probably loading a resource
//this probably means that its loading an ajax call or like a google ad thing
return null;
} else {
var aDOMWindow = contentWindow.top.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
.rootTreeItem
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindow);
var gBrowser = aDOMWindow.gBrowser;
var aTab = gBrowser._getTabForContentWindow(contentWindow.top); //this is the clickable tab xul element, the one found in the tab strip of the firefox window, aTab.linkedBrowser is same as browser var above //can stylize tab like aTab.style.backgroundColor = 'blue'; //can stylize the tab like aTab.style.fontColor = 'red';
if (aTab == null) {
return null;
}
else {
var browser = aTab.linkedBrowser; //this is the browser within the tab //this is where the example in the previous section ends
return {
aDOMWindow: aDOMWindow,
gBrowser: gBrowser,
aTab: aTab,
browser: browser,
contentWindow: contentWindow
};
}
}
//end loadContext stuff
}

Resources