Unexpected '}' On Line 135, but all } needed JavaScript GameEngine - audio

I am making a JavaScript Game Engine called Rage Engine. After about 1.5 hours of working on Version 1.0 Build 1, I had enough features and decided to do a test. Immediately I ran into a problem. The Console was saying Unexpected token } on line 135. I went to line 135 and found where the Console said there was a unexpected } and removed it. The Console next told me that there was an unexpected else on line 135. I use Sublime Text 2 as my IDLE and I made sure of that there were no brackets that were unintended.
Update:
I have identified, thanks in part to +Jason, what I think to be the problem
The Method RageEngine.data.file.requestQuota is too large. I have run into this problem before and I think the javascript compiler cannot handle functions larger than a size without breaking down. I don't know how I could fix that.
Method Error Appeared In:
RageEngine.data.file.requestQuota = function(type,size,success) {
if (RageEngine.data.file.check().FileSystem) {
if(type == 'temp') {
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.TEMPORARY,size,success,function(e) {
var msg = '', c = 0;
switch (e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR';
c = 1
break;
case FileError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR';
c = 2
break;
case FileError.SECURITY_ERR:
msg = 'SECURITY_ERR';
c = 3
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR';
c = 4
break;
case FileError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR';
c = 5
break;
default:
msg = 'Unknown Error';
break;
};
throw new Error('TEMP QUOTA Error: ' +msg+'. Error #3211.'+c+' '+msg)
}
} else if (type == 'perm') {
window.webkitStorageInfo.requestQuota(PERSISTENT, size, function(grantedBytes) {
window.requestFileSystem(PERSISTENT, grantedBytes, success, function(e) {
var msg = '', c = 0;
switch (e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR';
c = 1
break;
case FileError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR';
c = 2
break;
case FileError.SECURITY_ERR:
msg = 'SECURITY_ERR';
c = 3
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR';
c = 4
break;
case FileError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR';
c = 5
break;
default:
msg = 'Unknown Error';
break;
};
throw new Error('PERM QUOTA Error: ' +msg+'. Error #3212.'+c+' '+msg));
}, function(e) {
throw new Error('PERM QUOTA Error: '+e+'. Errror #3213 PERM QUOTA Error (in RageEngine.data.file.requestQuota)')
});
} else {
throw new TypeError("Invalid type "+type+". Error #3214 INVALID_TYPE (in RageEngine.data.file.requestQuota)")
}
} else {
throw new ReferenceError("Invalid User Support for FileSystem. Error #011 NO_SUPPORT (in RageEngine.data.file.requestQuota)")
}
Full Code
var RageEngine = {} // Initalize main object
// Initalize Sub Objects
RageEngine.hardware = {};
RageEngine.canvas = {};
RageEngine.data = {};
// Go Through each one and add methods
//** Sound **\\
RageEngine.hardware.sound.canPlayType = function(file) {
var audioElement = document.createElement( 'audio' );
return !!( audioElement.canPlayType &&
audioElement.canPlayType( 'audio/' + file.split( '.' ).pop().toLowerCase() + ';' ).replace( /no/, '' ) );
}
RageEngine.hardware.sound.preload = function(url) {
if(RageEngine.sound.canPlayType(url.split(".")[url.split(".").length - 1])) { // Test if the computer can play that type of audio
audio = new Audio(url)
return audio
} else {
throw new TypeError("Cannot load "+url+". Error: #111 USER_CANNOT_PLAY (in RageEngine.hardware.sound.preload)")
}
return audio
}
//** Video and Audio**\\
RageEngine.hardware.userMedia = {}
RageEngine.hardware.userMedia.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia
RageEngine.hardware.userMedia.check = function() {
return !!(navigator.getUserMedia || navigator.webkitGetUserMedia ||
navigator.mozGetUserMedia || navigator.msGetUserMedia);
}
RageEngine.hardware.userMedia.get = function(video,audio,stream_options) {
if (!RageEngine.hardware.userMedia.check()) {
throw new Error("Invalid Support for getUserMedia. Error #011 NO_SUPPORT (in RageEngine.hardware.userMedia.get)")
} else {
if(video || audio != (true||false)) throw new TypeError('Invalid Video or Audio type. Expecting Boolean (RageEngine.hardware.userMedia.get)')
if (stream_options.type == "auto") {
RageEngine.hardware.userMedia.getUserMedia({video:video,audio:audio},function(mediastream) {
var video = document.createElement("VIDEO");
video.src = window.URL.createObjectURL(localMediaStream);
stream_options.stream(video)
});
} else if (stream_options.type == "man") {
RageEngine.hardware.userMedia.getUserMedia({video:video,audio:audio},stream_options.stream);
}
}
}
//** Canvas **\\
// Canvas API added to be added in v1.1
RageEngine.canvas.canvas = function() {
console.warn('Canvas API is not implemented yet (in RageEngine.canvas.canvas)')
}
//** Data **\\
RageEngine.data.string = {};
RageEngine.data.string.store = function(type,key,value) {
switch(type.toLowerCase()) {
case "temp":
sessionStorage[key] = value;
break;
case "perm":
localStorage[key] = value;
break;
default:
throw new TypeError("Invalid type "+type+". Error: #2111 INVAILD_STORE_TYPE (in RageEngine.data.string.store)")
}
}
RageEngine.data.string.recall = function(type,key) {
switch(type.toLowerCase()) {
case "temp":
return sessionStorage[key]
break;
case "perm":
return localStorage[key]
break;
default:
throw new TypeError("Invalid type "+type+". Error: #2112 INVAILD_RECALL_TYPE (in RageEngine.data.string.store)")
}
}
RageEngine.data.string.check = function() {
var support = {
'temp': sessionStorage==undefined ? false : true,
'perm': localStorage==undefined ? false : true
};
return support
}
RageEngine.data.file = {};
RageEngine.data.file.check = function() {
var support = {
'File':window.File==undefined ? false : true,
'FileReader':window.FileReader==undefined ? false : true,
'FileList':window.FileList==undefined ? false : true,
'Blob':window.Blob==undefined ? false : true,
'FileSystem':window.FileSystem==undefined ? false : true
}
return support
}
RageEngine.data.file.requestQuota = function(type,size,success) {
if (RageEngine.data.file.check().FileSystem) {
if(type == 'temp') {
window.requestFileSystem = window.requestFileSystem || window.webkitRequestFileSystem;
window.requestFileSystem(window.TEMPORARY,size,success,function(e) {
var msg = '', c = 0;
switch (e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR';
c = 1
break;
case FileError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR';
c = 2
break;
case FileError.SECURITY_ERR:
msg = 'SECURITY_ERR';
c = 3
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR';
c = 4
break;
case FileError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR';
c = 5
break;
default:
msg = 'Unknown Error';
break;
};
throw new Error('TEMP QUOTA Error: ' +msg+'. Error #3211.'+c+' '+msg)
}
} else if (type == 'perm') {
window.webkitStorageInfo.requestQuota(PERSISTENT, size, function(grantedBytes) {
window.requestFileSystem(PERSISTENT, grantedBytes, success, function(e) {
var msg = '', c = 0;
switch (e.code) {
case FileError.QUOTA_EXCEEDED_ERR:
msg = 'QUOTA_EXCEEDED_ERR';
c = 1
break;
case FileError.NOT_FOUND_ERR:
msg = 'NOT_FOUND_ERR';
c = 2
break;
case FileError.SECURITY_ERR:
msg = 'SECURITY_ERR';
c = 3
break;
case FileError.INVALID_MODIFICATION_ERR:
msg = 'INVALID_MODIFICATION_ERR';
c = 4
break;
case FileError.INVALID_STATE_ERR:
msg = 'INVALID_STATE_ERR';
c = 5
break;
default:
msg = 'Unknown Error';
break;
};
throw new Error('PERM QUOTA Error: ' +msg+'. Error #3212.'+c+' '+msg));
}, function(e) {
throw new Error('PERM QUOTA Error: '+e+'. Errror #3213 PERM QUOTA Error (in RageEngine.data.file.requestQuota)')
});
} else {
throw new TypeError("Invalid type "+type+". Error #3214 INVALID_TYPE (in RageEngine.data.file.requestQuota)")
}
} else {
throw new ReferenceError("Invalid User Support for FileSystem. Error #011 NO_SUPPORT (in RageEngine.data.file.requestQuota)")
}
Thank you,
--Vulpus
I know the code is sloppy, but this is Version 1 Build 1.
BTW: The code is live at http://www.vulpusinc.co.nf/RageEngine/J/RageEngine.js or http://www.vulpusinc.co.nf/RageEngine/J/RageEngine.min.js (4Kb of 68% smaller!). Feel Free to use it

Didn't analyze the whole file, but you have an extra end parenthesis which could cause errors on following lines;
throw new Error('PERM QUOTA Error: ' +msg+'. Error #3212.'+c+' '+msg));
// Extra ')' ^

It looks like you have a whole bunch of mismatched braces. For example:
window.requestFileSystem(window.TEMPORARY,size,success,function(e) {
//Stuff
}
} else if (type == 'perm')
You're missing some parentheses to properly complete that function call.
The easiest way to fix a problem like this is to have Sublime fix your indenting for you; if some blocks get misaligned, that's a good clue that you have some parenthesis issues. This article gives you a way to do that

Related

BIP32 derivePath different privatekey in nodejs and dart(flutter) (same mnemonic)

Hello i'm have some problem with BIP32
i use BIP32 library in nodejs and dart(flutter)
in dart(flutter) BIP32 derivePath show different privatekey but not of all mnemonic is just incorrect some mnemonic
in 1000 mnemonic different privatekey 1-2 mnemonic
below is dart derivePath,,
what is inccorect in this code:
Help me pls.
BIP32 derivePath(String path) {
final regex = new RegExp(r"^(m\/)?(\d+'?\/)*\d+'?$");
if (!regex.hasMatch(path)) throw new ArgumentError("Expected BIP32 Path");
List<String> splitPath = path.split("/");
if (splitPath[0] == "m") {
if (parentFingerprint != 0) throw new ArgumentError("Expected master, got child");
splitPath = splitPath.sublist(1);
print("splitPath: "+ splitPath);
}
print("splitPath: "+ splitPath);
return splitPath.fold(this, (BIP32 prevHd,String indexStr) {
int index;
if (indexStr.substring(indexStr.length - 1) == "'") {
index = int.parse(indexStr.substring(0, indexStr.length - 1));
return prevHd.deriveHardened(index);
} else {
index = int.parse(indexStr);
return prevHd.derive(index);
}
});
}
BIP32 derive(int index) {
if (index > UINT32_MAX || index < 0) throw new ArgumentError("Expected UInt32");
final isHardened = index >= HIGHEST_BIT;
Uint8List data = new Uint8List(37);
if (isHardened) {
if (isNeutered()) {
throw new ArgumentError("Missing private key for hardened child key");
}
data[0] = 0x00;
data.setRange(1, 33, privateKey);
data.buffer.asByteData().setUint32(33, index);
} else {
data.setRange(0, 33, publicKey);
data.buffer.asByteData().setUint32(33, index);
}
final I = hmacSHA512(chainCode, data);
final IL = I.sublist(0, 32);
final IR = I.sublist(32);
if (!ecc.isPrivate(IL)) {
return derive(index + 1);
}
BIP32 hd;
if (!isNeutered()) {
final ki = ecc.privateAdd(privateKey, IL);
if (ki == null) return derive(index + 1);
hd = BIP32.fromPrivateKey(ki, IR, network);
} else {
final ki = ecc.pointAddScalar(publicKey, IL, true);
if (ki == null) return derive(index + 1);
hd = BIP32.fromPublicKey(ki, IR, network);
}
hd.depth = depth + 1;
hd.index = index;
hd.parentFingerprint = fingerprint.buffer.asByteData().getUint32(0);
return hd;
}
BIP32 deriveHardened(int index) {
if (index > UINT31_MAX || index < 0) throw new ArgumentError("Expected UInt31");
return this.derive(index + HIGHEST_BIT);
}
OK can solved this problem problem occur in the ecuve function bytes is less than 32 bytes just padding 0 in the left equal 32 bytes just solved it !

Else Statement Does Not Stop Looping NodeJS

I have been working on this code to read through a PDF file and grab the keywords of company names and display them. It all works fine except for one part where the else if statement outputs one line (which is what I want) but the else statement that comes last, which is supposed to output "Not Found" loops 20 times where I only want it to display the output only once instead of 20 times.
I have tried numerous ways by going through the internet to change my code, most recommended that forEach is not a proper way to do things and that I should use for instead but when I do, I just can't seem to get it right.
l.forEach(function(element) {
var j = element['fullTextAnnotation']['text'];
var sd = 'SDN. BHD.';
var bd = 'BHD.';
var et = 'Enterprise';
var inc = 'Incorporated';
var regtoken = new natural.RegexpTokenizer({pattern:/\n/});
var f = regtoken.tokenize(jsondata);
for(o = 0 ; o < f.length; o++){
var arrayline1 = natural.LevenshteinDistance(sd,f[o],{search:true});
var arrayline2 = natural.LevenshteinDistance(bd,f[o],{search:true});
var arrayline3 = natural.LevenshteinDistance(et,f[o],{search:true});
var arrayline4 = natural.LevenshteinDistance(inc,f[o],{search:true});
var arrayline5 = natural.LevenshteinDistance(nf,f[o],{search:false});
var onedata1 = arrayline1['substring'];
var onedata2 = arrayline2['substring'];
var onedata3 = arrayline3['substring'];
var onedata4 = arrayline4['substring'];
var onedata5 = arrayline5['substring'];
if (onedata1 === sd)
{
tokends = f[o];
break;
} else if(onedata3 === et)
{
tokends = f[o];
break;
} else if(onedata2 === bd)
{
tokends = f[o];
console.log(tokends);
break;
} else if(onedata4 === inc)
{
tokends = f[o];
console.log(tokends);
break;
} else{
console.log("Not Found");
return false;
}
}
});
I wish to get only one "Not Found" output for the else statement rather than it looping it for 20 times over. Hopefully I could get some insight to this problem. Thank you.
You are actually using the .forEach Array's method which actually take a function in parameter.
The keywork return breaks actually the loop of the current function executed.
For example :
const data = ['Toto', 'Tata', 'Titi'];
data.forEach(function(element) {
console.log(element);
if (element === 'Tata') {
return false;
}
});
// Will print everything :
// Print Toto
// Print Tata
// Print Titi
for (let element of data) {
console.log(element);
if (element === 'Tata') {
return false;
}
}
// Will print :
// Print Toto
// Print Tata

CSJS addCallback always runs SSJS

Can someone please shed some light on why this CSJS code is always running my SSJS code regardless of the CSJS seeming to return true or false?
CSJS code
message = "Starting Settle ATM Process..."
$(".infoMessage").text(message);
atmID = $("input.atmID").val(); //pull from hidden input
var deferred = atmRPC.closeATMFirstSettle();
deferred.addCallback(function(result){
if (result == "false") {
alert("Close command failed during 1st Settle ATM process. System will retry...");
var insideDeferred = atmMRPC.closeATMSecondSettle();
insideDeferred.addCallback(function(result) {
if (result == "false") {
message = "Close command failed during Settle ATM process. Please try again later."
$(".infoMessage").text(message);
atmRPC.updateInfoMsg(message);
return false;
} else if(result == "true"){
var deferred = atmRPC.settleATMFirst();
deferred.addCallback(function(result){
if (result == "false") {
alert("Settlement failed during 1st attempt. System will retry...");
var insideDeferred = atmMRPC.settleATMSecond();
insideDeferred.addCallback(function(result) {
if (result == "false") {
message = "Settlement failed. Please try again later."
$(".infoMessage").text(message);
atmRPC.updateInfoMsg(message);
return false;
} else if(result == "true"){
message = atmID + " has been successfully Settled."
$(".infoMessage").text(message);
atmRPC.updateInfoMsg(message);
// return true;
}
})
} else if(result == "true"){
message = atmID + " has been successfully Settled."
$(".infoMessage").text(message);
atmRPC.updateInfoMsg(message);
// return true;
}
})
}
})
} else if(result == "true"){
var deferred = atmRPC.settleATMFirst();
deferred.addCallback(function(result){
if (result == "false") {
alert("Settlement failed during 1st attempt. System will retry...");
var insideDeferred = atmMRPC.settleATMSecond();
insideDeferred.addCallback(function(result) {
if (result == "false") {
alert("Settlement failed during 1st attempt. System will retry...");
message = "Settlement failed. Please try again later."
$(".infoMessage").text(message);
atmRPC.updateInfoMsg(message);
return false;
} else if(result == "true"){
message = atmID + " has been successfully Settled."
$(".infoMessage").text(message);
atmRPC.updateInfoMsg(message);
// return true;
}
})
} else if(result == "true"){
message = atmID + " has been successfully Settled."
$(".infoMessage").text(message);
atmRPC.updateInfoMsg(message);
// return true;
}
})
}
})
closeATMFirsSettle and closeATMSecondSettle are identical with exception of the boolean variable
if(atmBean.atmStatus == "OPEN" || atmBean.atmStatus == "WOUNDED") {
var firstTry:boolean = atmBean.closeATM(atmBean.atmID, userBean.userID);
return firstTry.toString();
} else if(atmBean.atmStatus == "CLOSED") {
return "true";
} else {
return "false";
}
settleATMFirst and settleATMSecond are identical with exception of the boolean variable
sessionScope.infoMsg = null;
try {
if(atmBean.atmAmountReceived == null) {
var settleAmt:Integer = Integer.parseInt(atmBean.atmTodaySettlementAmt);
} else {
var settleAmt:Integer = Integer.parseInt(atmBean.atmAmountReceived);
}
} catch(e) {
message:String = "1st Settle ATM Amount Error: " + e;
logInfo(message);
return sessionScope.infoMsg = message;
}
var firstTry:boolean = atmBean.settleATM(atmBean.atmID, userBean.userID, settleAmt);
return firstTry.toString();
atmBean.settleATM
public boolean settleATM(String atmId, String employeeId, Integer settlementAmount, String attempt){
//This method called by RPC control from client JS
AtmOperationSettlementResult result = null;
boolean returnValue = false;
try {
result = AtmTerminalUtil.settleAtm(atmID, employeeId, settlementAmount);
returnValue = result.getSuccess();
if(attempt.equals("Second")) {
System.out.println("ATM Bean - Second Attempt");
if(!returnValue) {
handleATMError(result);
}
}
} catch(Exception e) {
System.out.println(e);
}
//saveATMHistory();
return returnValue; //return status of operation to UI
}
I know the SSJS in the Server tab is always being ran because the log entries show the value of a viewScope that is set if the atmBean.settleATM returns a false.
Sorry, didn't realize until the last comment that everyone may be thinking the SSJS code I'm talking about is in the RPC, but I'm referring to the Server tab.

Exception occurred calling method NotesDatabase.getDocumentByUNID(null) null

I don't understand why I'm getting the above mentioned error with following code :
value1 = sessionScope.get("selectedPicture");
if (value1 != "empty"){
var db:NotesDatabase = session.getDatabase(database.getServer(), "product\\picture.nsf");
if (db != null) {
var IDtoChange = toString("7D59468E241AC271C1257D5000417E46") ;
if (IDtoChange = null){
return
}
try {
doc = db.getDocumentByUNID(IDtoChange);
doc.replaceItemValue( 'picWeb', "true" );
doc.save( true, false );
sessionScope.put("selectedUnid","");
} catch(e) {
sessionScope.put("error",(e.toString()));
context.redirectToPage("errorPage.xsp");
}
}
}
When I replace the line doc = db.getDocumentByUNID(IDtoChange); with doc = db.getDocumentByUNID("7D59468E241AC271C1257D5000417E46"); everything works fine
What is wrong ? (in my real code the id isn't hard coded of course)
Should line six be if (IDtoChange == null){ instead of if (IDtoChange = null){. The single = looks to be assigning the value instead of comparing which is ==

Opening tabs in Chrome news reader extension

I'm trying to create a simple chrome extension using the following google RSS reader sample,
http://code.google.com/chrome/extensions/samples.html#597015d3bcce3da693b02314afd607bec4f55291
I can add links in the pop-up window that open tabs, but not from the feeds themselves.
Looping through the items in the feed, grabbing title tags and link tags, I want the title to link the the appropriate sites
var entries = doc.getElementsByTagName('item');
var count = Math.min(entries.length, maxFeedItems);
for (var i = 0; i < count; i++) {
item = entries.item(i);
// Grab the title for the feed item.
var itemTitle = item.getElementsByTagName('title')[0];
if (itemTitle) {
itemTitle = itemTitle.textContent;
} else {
itemTitle = "Unknown title";
}
// Grab the link for this feed item
var itemLink = item.getElementsByTagName('link')[0];
if (itemLink) {
itemLink = itemLink.textContent;
} else {
itemLink = "Unknown link";
}
var title = document.createElement("a");
title.className = "item_title";
title.innerText = itemTitle; //display title in iframe
title.addEventListener("click", titleLink); // should open link when clicking on title, but does not.
}
// -------------------------------------------------------------------
// Show |url| in a new tab.
function showUrl(url) {
// Only allow http and https URLs.
if (url.indexOf("http:") != 0 && url.indexOf("https:") != 0) {
return;
}
chrome.tabs.create({url: url});
}
function moreStories(event) {
showUrl(moreStoriesUrl);
}
function titleLink(event) {
showUrl(itemLink);
}
Any thoughts on why this is not working.
If I replace title.addEventListener("click", titleLink); with title.addEventListener("click", moreStories); each title will link to moreStories, I cannot get each title to link to itemLink.
Thanks
Its a bit hard to answer your question without the whole code, but Ill give it a shot ;)
First up, titleLink() isnt going to work because itemLink isnt known. When you create title (the link) you should of attached it to that...say title.href=itemLink then in tiltleLinks you could access that href with showUrl(event.currentTarget.href)
Also did you fix the error in that example?...if not then change frameLoaded to....
function frameLoaded() {
var links = document.getElementsByTagName("A");
for (i = 0; i < links.length; i++) {
var clssName = links[i].className;
if (clssName != "item_title" && clssName != "open_box") {
links[i].addEventListener("click", showStory);
}
}
window.addEventListener("message", messageHandler);
}
If you still have probs could you attach the whole code so I can see what your doing and Ill give you a hand.
Thank you very much for your help.
code title.href=itemLink and code showUrl(event.currentTarget.href) was exactly what I needed.
For completeness, here is the full code,
<script id="iframe_script">
function reportHeight() {
var msg = JSON.stringify({type:"size", size:document.body.offsetHeight});
parent.postMessage(msg, "*");
}
function frameLoaded() {
var links = document.getElementsByTagName("A");
for (i = 0; i < links.length; i++) {
var class = links[i].className;
if (class != "item_title" && class != "open_box") {
links[i].addEventListener("click", showStory);
}
}
window.addEventListener("message", messageHandler);
}
function showStory(event) {
var href = event.currentTarget.href;
parent.postMessage(JSON.stringify({type:"show", url:href}), "*");
event.preventDefault();
}
function messageHandler(event) {
reportHeight();
}
</script>
<script>
// Feed URL.
var feedUrl = 'http://localhost/newsfeed.xml';
// The XMLHttpRequest object that tries to load and parse the feed.
var req;
function main() {
req = new XMLHttpRequest();
req.onload = handleResponse;
req.onerror = handleError;
req.open("GET", feedUrl, true);
req.send(null);
}
// Handles feed parsing errors.
function handleFeedParsingFailed(error) {
var feed = document.getElementById("feed");
feed.className = "error";
feed.innerText = "Error: " + error;
}
// Handles errors during the XMLHttpRequest.
function handleError() {
handleFeedParsingFailed('Failed to fetch RSS feed.');
}
// Handles parsing the feed data we got back from XMLHttpRequest.
function handleResponse() {
var doc = req.responseXML;
if (!doc) {
handleFeedParsingFailed("Not a valid feed.");
return;
}
buildPreview(doc);
}
// The maximum number of feed items to show in the preview.
var maxFeedItems = 10;
// Where the more stories link should navigate to.
var moreStoriesUrl;
function buildPreview(doc) {
// Get the link to the feed source.
var link = doc.getElementsByTagName("link");
var parentTag = link[0].parentNode.tagName;
if (parentTag != "item" && parentTag != "entry") {
moreStoriesUrl = link[0].textContent;
}
// Setup the title image.
var images = doc.getElementsByTagName("image");
var titleImg;
if (images.length != 0) {
var urls = images[0].getElementsByTagName("url");
if (urls.length != 0) {
titleImg = urls[0].textContent;
}
}
var img = document.getElementById("title");
// Listen for mouse and key events
if (titleImg) {
img.src = titleImg;
if (moreStoriesUrl) {
document.getElementById("title_a").addEventListener("click",moreStories);
document.getElementById("title_a").addEventListener("keydown",
function(event) {
if (event.keyCode == 13) {
moreStories(event);
}});
}
} else {
img.style.display = "none";
}
// Construct the iframe's HTML.
var iframe_src = "<!doctype html><html><head><script>" +
document.getElementById("iframe_script").textContent + "<" +
"/script></head><body onload='frameLoaded();' " +
"style='padding:0px;margin:0px;'>";
var feed = document.getElementById("feed");
// Set ARIA role indicating the feed element has a tree structure
feed.setAttribute("role", "tree");
var entries = doc.getElementsByTagName('item');
var count = Math.min(entries.length, maxFeedItems);
for (var i = 0; i < count; i++) {
item = entries.item(i);
// Grab the title for the feed item.
var itemTitle = item.getElementsByTagName('title')[0];
if (itemTitle) {
itemTitle = itemTitle.textContent;
} else {
itemTitle = "Unknown title";
}
// Grab the link for the feed item.
var itemLink = item.getElementsByTagName('link')[0];
if (itemLink) {
itemLink = itemLink.textContent;
} else {
itemLink = "Unknown link";
}
var item = document.createElement("div");
var title = document.createElement("a");
title.innerText = itemTitle; //display title in iframe
title.href=itemLink;
title.addEventListener("click", titleLink);
item.appendChild(title);
feed.appendChild(item);
}
if (moreStoriesUrl) {
var more = document.createElement("a");
more.className = "more";
more.innerText = "***Site Main Page*** \u00BB";
more.tabIndex = 0;
more.addEventListener("click", moreStories);
more.addEventListener("keydown", function(event) {
if (event.keyCode == 13) {
moreStories(event);
}});
feed.appendChild(more);
}
}
// -------------------------------------------------------------------
// Show |url| in a new tab.
function showUrl(url) {
// Only allow http and https URLs.
if (url.indexOf("http:") != 0 && url.indexOf("https:") != 0) {
return;
}
chrome.tabs.create({url: url});
}
// -------------------------------------------------------------------
function moreStories(event) {
showUrl(moreStoriesUrl);
}
function titleLink(event) {
showUrl(event.currentTarget.href);
}
function keyHandlerShowDesc(event) {
// Display content under heading when spacebar or right-arrow pressed
// Hide content when spacebar pressed again or left-arrow pressed
// Move to next heading when down-arrow pressed
// Move to previous heading when up-arrow pressed
if (event.keyCode == 32) {
showDesc(event);
} else if ((this.parentNode.className == "item opened") &&
(event.keyCode == 37)) {
showDesc(event);
} else if ((this.parentNode.className == "item") && (event.keyCode == 39)) {
showDesc(event);
} else if (event.keyCode == 40) {
if (this.parentNode.nextSibling) {
this.parentNode.nextSibling.children[1].focus();
}
} else if (event.keyCode == 38) {
if (this.parentNode.previousSibling) {
this.parentNode.previousSibling.children[1].focus();
}
}
}
function showDesc(event) {
var item = event.currentTarget.parentNode;
var items = document.getElementsByClassName("item");
for (var i = 0; i < items.length; i++) {
var iframe = items[i].getElementsByClassName("item_desc")[0];
if (items[i] == item && items[i].className == "item") {
items[i].className = "item opened";
iframe.contentWindow.postMessage("reportHeight", "*");
// Set the ARIA state indicating the tree item is currently expanded.
items[i].getElementsByClassName("item_title")[0].
setAttribute("aria-expanded", "true");
iframe.tabIndex = 0;
} else {
items[i].className = "item";
iframe.style.height = "0px";
// Set the ARIA state indicating the tree item is currently collapsed.
items[i].getElementsByClassName("item_title")[0].
setAttribute("aria-expanded", "false");
iframe.tabIndex = -1;
}
}
}
function iframeMessageHandler(e) {
// Only listen to messages from one of our own iframes.
var iframes = document.getElementsByTagName("IFRAME");
for (var i = 0; i < iframes.length; i++) {
if (iframes[i].contentWindow == e.source) {
var msg = JSON.parse(e.data);
if (msg) {
if (msg.type == "size") {
iframes[i].style.height = msg.size + "px";
}
else if (msg.type == "show") {
var url = msg.url;
if (url.indexOf("http://localhost/index.html") == 0) {
// If the URL is a redirect URL, strip of the destination and go to
// that directly. This is necessary because the Google news
// redirector blocks use of the redirects in this case.
var index = url.indexOf("&url=");
if (index >= 0) {
url = url.substring(index + 5);
index = url.indexOf("&");
if (index >= 0)
url = url.substring(0, index);
}
}
showUrl(url);
}
}
return;
}
}
}
window.addEventListener("message", iframeMessageHandler);
</script>
Thanks again for the help.
-Mike

Resources