JS: Can not convert to object, childNodes related - javascript

Ok, feeling stupid here, but wondering what the problem is here exactly.
Although the function works as it should, I get this JS Error in Opera. Not sure about other browsers...
Uncaught exception: TypeError: Cannot
convert
'document.getElementById("shoutbox_area"
+ moduleId)' to object
oElement = document.getElementById("shoutbox_area"
+ moduleId).childNodes;
Here is the relevant code:
function appendShout(XMLDoc)
{
var shoutData = XMLDoc.getElementsByTagName("item");
var oElement = [];
if (shoutData.length > 0)
{
var moduleId = shoutData[0].getAttribute("moduleid");
if (shoutData[shoutData.length - 1].getAttribute("lastshout") != "undefined")
{
for (var i = 0; i < shoutData.length; i++)
if (shoutData[i].firstChild.nodeValue != 0)
document.getElementById("shoutbox_area" + moduleId).innerHTML += shoutData[i].firstChild.nodeValue;
oElement = document.getElementById("shoutbox_area" + moduleId).childNodes;
var i = oElement.length;
while (i--)
{
if (i % 2 == 0)
oElement[i].className = "windowbg2";
else
oElement[i].className = "windowbg";
}
oElement[oElement.length - 2].style.borderBottom = "1px black dashed";
}
}
}
Can someone please help me to understand why it is giving me an error here:
oElement = document.getElementById("shoutbox_area" + moduleId).childNodes;
Can I not assign an array to the childNodes?
EDIT:
This JS Error occurs when I try and delete a shout. The JS function for deleting a shout is this:
function removeShout(shout, moduleID)
{
var shoutContainer = shout.parentNode.parentNode;
var send_data = "id_shout=" + shout.id;
var url = smf_prepareScriptUrl(smf_scripturl) + "action=dream;sa=shoutbox;xml;" + "delete_shout;" + "canmod=" + canMod[moduleID] + ";" + sessVar + "=" + sessId;
sendXMLDocument(url, send_data);
var shoutID = 0;
while (shoutID !== null)
{
var shoutID = document.getElementById(shout.parentNode.id);
var moduleID = shoutID.parentNode.getAttribute("moduleid");
if (shoutID.parentNode.lastChild)
{
var url = smf_prepareScriptUrl(smf_scripturl) + "action=dream;sa=shoutbox;xml;get_shouts=" + (shoutID.parentNode.lastChild.id.replace("shout_", "") - 1) + ";membercolor=" + memberColor[moduleID] + ";maxcount=" + maxCount[moduleID] + ";shoutboxid=" + shoutboxID[moduleID] + ";textsize=" + textSize[moduleID] + ";parsebbc=" + parseBBC[moduleID] + ";moduleid=" + moduleID + ";maxcount=" + maxCount[moduleID] + ";canmod=" + canMod[moduleID] + ";" + sessVar + "=" + sessId;
getXMLDocument(url, appendShout);
}
element = shoutID.parentNode.childNodes;
var i = element.length;
while (i--)
{
if (i % 2 == 0)
element[i].className = "windowbg2";
else
element[i].className = "windowbg";
}
shoutID.parentNode.removeChild(shoutID);
}
}
Am using the following functions for the sending and getting the XMLHttpRequest as you may have noticed already in the removeShout function above:
// Load an XML document using XMLHttpRequest.
function getXMLDocument(sUrl, funcCallback)
{
if (!window.XMLHttpRequest)
return null;
var oMyDoc = new XMLHttpRequest();
var bAsync = typeof(funcCallback) != 'undefined';
var oCaller = this;
if (bAsync)
{
oMyDoc.onreadystatechange = function () {
if (oMyDoc.readyState != 4)
return;
if (oMyDoc.responseXML != null && oMyDoc.status == 200)
{
if (funcCallback.call)
{
funcCallback.call(oCaller, oMyDoc.responseXML);
}
// A primitive substitute for the call method to support IE 5.0.
else
{
oCaller.tmpMethod = funcCallback;
oCaller.tmpMethod(oMyDoc.responseXML);
delete oCaller.tmpMethod;
}
}
};
}
oMyDoc.open('GET', sUrl, bAsync);
oMyDoc.send(null);
return oMyDoc;
}
// Send a post form to the server using XMLHttpRequest.
function sendXMLDocument(sUrl, sContent, funcCallback)
{
if (!window.XMLHttpRequest)
return false;
var oSendDoc = new window.XMLHttpRequest();
var oCaller = this;
if (typeof(funcCallback) != 'undefined')
{
oSendDoc.onreadystatechange = function () {
if (oSendDoc.readyState != 4)
return;
if (oSendDoc.responseXML != null && oSendDoc.status == 200)
funcCallback.call(oCaller, oSendDoc.responseXML);
else
funcCallback.call(oCaller, false);
};
}
oSendDoc.open('POST', sUrl, true);
if ('setRequestHeader' in oSendDoc)
oSendDoc.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
oSendDoc.send(sContent);
return true;
}
Hopefully this is good enough, you can do a view source on it to see the actual HTML, but there are attributes that get added to the Shoutbox tags at runtime so as to be XHTML compliant, etc..
Please let me know if there is anything else you need?
Thanks :)

The code is breaking because shoutID is null in the second of these two lines, the second time through the loop:
var shoutID = document.getElementById(shout.parentNode.id);
var moduleID = shoutID.parentNode.getAttribute("moduleid");
The first of those lines is strange. Why not just use var shoutID = shout.parentNode;?
Also, the moduleId attribute seems to be nowhere around.
What are you trying to achieve with the while loop?

Related

Uncaught TypeError: Cannot read properties of undefined (reading '1'); looping through arrays

I am attaching the URL to the issue I am talking about. If inspected, you can see the error.
I have program that is taking in data in a form and comparing it against json data and then outputting json data. I used an xmlhttprequest to grab the json and convert it to javascript array. I keep getting an error specifically about the following line of code. I will past the entire js file underneath.
Now the code is actually working at this time, but earlier it was not, and obviously I should find and fix the errors no matter what. I have been researching for hours, and can't fix the problem. Help would be so appreciated.
URL: https://oacaa.org/self-sufficiency-calculator/
if (arrBirds[i][1] === userAdultInt && arrBirds[i][2] === userInfantInt && arrBirds[i][3] === userPreschoolInt && arrBirds[i][4] === userSchoolageInt && arrBirds[i][5] === userTeenageInt && arrBirds[i][9] === userCounty)
function overIt() {
// Create XMLHttpRequest object.
var oXHR = new XMLHttpRequest();
// Initiate request.
oXHR.onreadystatechange = reportStatus;
oXHR.open("GET","/oacaa.json", true); // get json file.
oXHR.send();
function reportStatus() {
if (oXHR.readyState == 4) { // Check if request is complete.
// Create an HTML table using response from server.
createTableFromJSON(this.responseText);
}
}
// Create an HTML table using the JSON data.
function createTableFromJSON(jsonData) {
const userAdult = document.getElementById("adult").value;
const userAdultInt = parseInt(userAdult,10);
const userInfant = document.getElementById("infant").value;
const userInfantInt = parseInt(userInfant,10);
const userPreschool = document.getElementById("preschool").value;
const userPreschoolInt = parseInt(userPreschool,10);
const userSchoolage = document.getElementById("schoolage").value;
const userSchoolageInt = parseInt(userSchoolage,10);
const userTeenage = document.getElementById("teenage").value;
const userTeenageInt = parseInt(userTeenage,10);
const userCounty = document.getElementById("county").value;
const userChildren = Number(userInfantInt) + Number(userPreschoolInt) + Number(userSchoolageInt) + Number(userTeenageInt);
var arrBirds = [];
arrBirds = JSON.parse(jsonData); // Convert JSON to array.
for (i = 0; i < 63274; i++){
if (arrBirds[i][1] === userAdultInt && arrBirds[i][2] === userInfantInt && arrBirds[i][3] === userPreschoolInt && arrBirds[i][4] === userSchoolageInt && arrBirds[i][5] === userTeenageInt && arrBirds[i][9] === userCounty) {
// EXPENSES
document.getElementById("housing").innerHTML = arrBirds[i][10];
document.getElementById("childcare").innerHTML = arrBirds[i][11];
document.getElementById("food").innerHTML = arrBirds[i][12];
document.getElementById("transportation").innerHTML = arrBirds[i][13];
document.getElementById("healthcare").innerHTML = arrBirds[i][14];
document.getElementById("misc").innerHTML = arrBirds[i][15];
document.getElementById("taxes").innerHTML = arrBirds[i][16];
// TAX CREDITS
document.getElementById("EITC").innerHTML = arrBirds[i][17];
document.getElementById("CCTC").innerHTML = arrBirds[i][18];
document.getElementById("CTC").innerHTML = arrBirds[i][19];
// SELF SUFFICIENCY WAGE
document.getElementById("hourly").innerHTML = arrBirds[i][20];
document.getElementById("monthly").innerHTML = arrBirds[i][21];
document.getElementById("annual").innerHTML = arrBirds[i][22];
document.getElementById("emergency").innerHTML = arrBirds[i][23];
const userName = document.getElementById("name").value;
const userCounty = document.getElementById("county").value;
//PERSONAL INFO
document.getElementById("personal-info").innerHTML = "Self Sufficiency Report for" + " " + userName + "'s" + " " + "household living in " + " " + userCounty + "." + " " + "The residents in this household include" + " " + userAdultInt + " " + "adult(s)" + " " + "and" + " " + userChildren + " " + "child(ren)" + ".";
var x = document.getElementById("form-user-input");
if (x.style.display === "none") {
x.style.display = "block";
} else {
x.style.display = "none";
}
var j = document.getElementById("income-form");
if (j.style.display === "block") {
j.style.display = "none";
} else {
j.style.display = "block";
}
} else {
document.getElementById('error').innerHTML = "We do not currently have information for this family type. We apologize in advance." }
}
}
}

Trying to change parameters in JQuery plugin file

I have a JQuery plugin i am using as part of my project. The file is located in the root of my solution folder under a file called "jquery.tablePagination.js" I want to alter some of the parameters inside of the file without hard coding the data.
The script is as follows..
(function ($) {
$.fn.tablePagination = function (settings) {
var defaults = {
firstArrow: (new Image()).src = "./images/first.gif",
prevArrow: (new Image()).src = "./images/prev.gif",
lastArrow: (new Image()).src = "./images/last.gif",
nextArrow: (new Image()).src = "./images/next.gif",
rowsPerPage: 5,
currPage: 1,
optionsForRows: [5, 10],
ignoreRows: []
};
settings = $.extend(defaults, settings);
return this.each(function () {
var table = $(this)[0];
var totalPagesId = '#' + table.id + '+#tablePagination #tablePagination_totalPages';
var currPageId = '#' + table.id + '+#tablePagination #tablePagination_currPage';
var rowsPerPageId = '#' + table.id + '+#tablePagination #tablePagination_rowsPerPage';
var firstPageId = '#' + table.id + '+#tablePagination #tablePagination_firstPage';
var prevPageId = '#' + table.id + '+#tablePagination #tablePagination_prevPage';
var nextPageId = '#' + table.id + '+#tablePagination #tablePagination_nextPage';
var lastPageId = '#' + table.id + '+#tablePagination #tablePagination_lastPage';
var possibleTableRows = $.makeArray($('tbody tr', table));
var tableRows = $.grep(possibleTableRows, function (value, index) {
return ($.inArray(value, defaults.ignoreRows) == -1);
}, false)
var numRows = tableRows.length
var totalPages = resetTotalPages();
var currPageNumber = (defaults.currPage > totalPages) ? 1 : defaults.currPage;
if ($.inArray(defaults.rowsPerPage, defaults.optionsForRows) == -1)
defaults.optionsForRows.push(defaults.rowsPerPage);
function hideOtherPages(pageNum) {
if (pageNum == 0 || pageNum > totalPages)
return;
var startIndex = (pageNum - 1) * defaults.rowsPerPage;
var endIndex = (startIndex + defaults.rowsPerPage - 1);
$(tableRows).show();
for (var i = 0; i < tableRows.length; i++) {
if (i < startIndex || i > endIndex) {
$(tableRows[i]).hide()
}
}
}
function resetTotalPages() {
var preTotalPages = Math.round(numRows / defaults.rowsPerPage);
var totalPages = (preTotalPages * defaults.rowsPerPage < numRows) ? preTotalPages + 1 : preTotalPages;
if ($(totalPagesId).length > 0)
$(totalPagesId).html(totalPages);
return totalPages;
}
function resetCurrentPage(currPageNum) {
if (currPageNum < 1 || currPageNum > totalPages)
return;
currPageNumber = currPageNum;
hideOtherPages(currPageNumber);
$(currPageId).val(currPageNumber)
}
function resetPerPageValues() {
var isRowsPerPageMatched = false;
var optsPerPage = defaults.optionsForRows;
optsPerPage.sort();
var perPageDropdown = $(rowsPerPageId)[0];
perPageDropdown.length = 0;
for (var i = 0; i < optsPerPage.length; i++) {
if (optsPerPage[i] == defaults.rowsPerPage) {
perPageDropdown.options[i] = new Option(optsPerPage[i], optsPerPage[i], true, true);
isRowsPerPageMatched = true;
}
else {
perPageDropdown.options[i] = new Option(optsPerPage[i], optsPerPage[i]);
}
}
if (!isRowsPerPageMatched) {
defaults.optionsForRows == optsPerPage[0];
}
}
function createPaginationElements() {
var htmlBuffer = [];
htmlBuffer.push("<div id='tablePagination'>");
htmlBuffer.push("<span id='tablePagination_perPage'>");
htmlBuffer.push("<select id='tablePagination_rowsPerPage'><option value='5'>5</option></select>");
htmlBuffer.push("per page");
htmlBuffer.push("</span>");
htmlBuffer.push("<span id='tablePagination_paginater'>");
htmlBuffer.push("<img id='tablePagination_firstPage' src='" + defaults.firstArrow + "'>");
htmlBuffer.push("<img id='tablePagination_prevPage' src='" + defaults.prevArrow + "'>");
htmlBuffer.push("Page");
htmlBuffer.push("<input id='tablePagination_currPage' type='input' value='" + currPageNumber + "' size='1'>");
htmlBuffer.push("of <span id='tablePagination_totalPages'>" + totalPages + "</span>");
htmlBuffer.push("<img id='tablePagination_nextPage' src='" + defaults.nextArrow + "'>");
htmlBuffer.push("<img id='tablePagination_lastPage' src='" + defaults.lastArrow + "'>");
htmlBuffer.push("</span>");
htmlBuffer.push("</div>");
return htmlBuffer.join("").toString();
}
if ($(totalPagesId).length == 0) {
$(this).after(createPaginationElements());
}
else {
$('#tablePagination_currPage').val(currPageNumber);
}
resetPerPageValues();
hideOtherPages(currPageNumber);
$(firstPageId).bind('click', function (e) {
resetCurrentPage(1)
});
$(prevPageId).bind('click', function (e) {
resetCurrentPage(currPageNumber - 1)
});
$(nextPageId).bind('click', function (e) {
resetCurrentPage(currPageNumber + 1)
});
$(lastPageId).bind('click', function (e) {
resetCurrentPage(totalPages)
});
$(currPageId).bind('change', function (e) {
resetCurrentPage(this.value)
});
$(rowsPerPageId).bind('change', function (e) {
defaults.rowsPerPage = parseInt(this.value, 10);
totalPages = resetTotalPages();
resetCurrentPage(1)
});
})
};
})(jQuery);
I want to be able to alter the following settings: RowsPerPage and OptionforRows.
I have tried to copy and paste the code from the script directly into my .aspx file next to some other Jquery/JavaScript I already have however the plugin doesn't run when I do this.
Could it be possible to write to the settings part of the file from the code behind? It would also work if the file could read the settings from a certain hidden field but I can't get it to run on my .aspx to do this. I'm not sure how to go about solving this issue.
I have ended up solving this issue by first copying the script and pasting in my .aspx file. I was originally copying the code inside of the document ready function:
$(document).ready(function)
Once I have had this done It was quite easy to pass through a variable from the code behind to be used as the required setting.
rowsPerPage: <%=PageRowAmount%>,
For the code behind I have added the following:
Public PageRowAmount As Integer = 10
and in the page_load I have added
Page.DataBind()
Solved!

Extracting image from API

Trying to output an image from an API but I keep getting an error "Empty JSON string"
function getIcon2(id)
{
var api = "http://services.runescape.com/m=itemdb_rs/api/catalogue/detail.json?item=";
var data2 = JSON.parse(UrlFetchApp.fetch(api + id));
return data2.item.icon_large;
}
function iconTest(){
var icon = getIcon2(itemsheet.getRange("C2").getValue());
itemsheet.getRange("D18").setValue(data2);
}
I figured it out.
function getIcon() {
for(var i = 2; i < 500; i++) {
id = itemsheet.getRange("C" + i).getValue()
if(id == "")
return; //If the cell is empty, ignore it.
try {
target = itemsheet.getRange("B" + i);
var api = "http://services.runescape.com/m=itemdb_rs/api/catalogue/detail.json?item=";
var raw = UrlFetchApp.fetch(api + id);
var data = JSON.parse(raw);
formula = "=image(\"" + data.item.icon_large + "\",1)";
target.setFormula(formula);
} catch(err) {
Logger.log("getIcon...." + err)
return;
}
}
}

Does this iframe buster script look safe?

We're being asked to host a number of iframe buster scripts on our site - they allow ads which are served from external domains into iframes to expand outside of them into the host page. Our hosting provider's warned us to watch out for security holes in these scripts. Specifically, they say some of them create cross-site scripting holes by allowing a piece of Javascript to be loaded into our site from any URL.
To implement the script, you host an HTML page on your site. I'm looking at an example from the ad provider Atlas. In this case the URL is like http://domain.com/atlas/atlas_rm.htm. That page contains a script tag with src at an external URL, and here's the JS it includes:
var ARMIfbLib = function () {
function documentWrite(htmlString) {
document.write(htmlString);
}
function writeIframeBustingScript() {
var imgSrvPath = getTlDirectoryFromQueryString(getParameterString());
if (imgSrvPath != "") {
var scriptURL = imgSrvPath + getScriptFileName();
ARMIfbLib.DocumentWrite("<script language='javascript' type='text/javascript' src='" + scriptURL + "'></scr" + "ipt>");
}
}
return {
WriteIframeBustingScript: writeIframeBustingScript,
DocumentWrite: documentWrite
}
}();
function getValueFromDelimitedString(paramKey, delimiter, queryString) {
if (paramKey == "imgSrv")
return getValueFromProperties();
var re = new RegExp(paramKey + "=" + "(.*?)" + "(" + delimiter + "|$)");
var matchArray = queryString.match(re);
if (matchArray == null)
return "";
else
return matchArray[1];
}
function getValueFromProperties() {
var iframename = unescape(self.name);
if (iframename.indexOf("<form") >= 0) {
var params = iframename.split("<input ");
for (var i = 1; i < params.length; i++) {
var parts = params[i].split(" ");
for (var j = 0; j < parts.length; j++) {
var param = parts[j].split("=");
if (param[0].indexOf("name") >= 0 && param[1].indexOf("TL_files_path") >= 0) {
param = parts[j + 1].split("=");
if (param[0].indexOf("value") >= 0) {
var value = param[1].substr(1, param[1].indexOf(">"));
value = value.substr(value, value.lastIndexOf("/"));
value = value.substr(value, value.lastIndexOf("/") + 1);
return unescape(value);
}
}
}
}
}
else if (iframename.indexOf("adparamdelim") >= 0) {
var params = iframename.split("adparamdelim");
for (var i = 0; i < params.length; i++) {
var param = params[i].split("=");
if (param[0].indexOf("TL_files_path") >= 0) {
var value = param[1];
value = value.substr(value, value.lastIndexOf("/"));
value = value.substr(value, value.lastIndexOf("/") + 1);
return value;
}
}
}
else if (/^\{.*\}$/.test(iframename)) {
try {
eval('var results = ' + iframename);
var value = results.TL_files_path;
value = value.substr(value, value.lastIndexOf("/"));
value = value.substr(value, value.lastIndexOf("/") + 1);
return value;
} catch (e) {
return "";
}
} else {
var params = iframename.split("&");
for (var i = 0; i < params.length; i++) {
var param = params[i].split("=");
if (param[0].indexOf("TL_files_path") >= 0) {
var value = unescape(param[1]);
value = value.substr(value, value.lastIndexOf("/"));
value = value.substr(value, value.lastIndexOf("/") + 1);
return value;
}
}
}
return "";
}
function getTlDirectoryFromQueryString(sLocation) {
var queryVar = getValueFromDelimitedString("imgSrv", "a4edelim", sLocation);
var temp = queryVar.substr(0, queryVar.lastIndexOf("/"));
var tlDir = temp.substr(0, temp.lastIndexOf("/") + 1);
return tlDir;
}
function getDocumentQueryString() {
return window.location.search;
}
function getIframeParameterString() {
var ret = "";
var qs = getDocumentQueryString();
if (qs.length > 0)
ret = qs.substring(1);
return ret;
}
function getScriptParameterString() {
var ret = "";
var scripts = document.getElementsByTagName('script');
for (var i = 0; i < scripts.length; i++) {
var scriptSrc = scripts[i].src;
if (scriptSrc.toLowerCase().indexOf("newiframescript") != -1 && scriptSrc.indexOf("?") != -1) {
ret = scriptSrc.substr(scriptSrc.indexOf("?") + 1);
break;
}
}
return ret;
}
function getParameterString() {
var qs = getIframeParameterString();
if (qs.length > 0 && qs.indexOf("a4edelim") > 0)
return qs;
return getScriptParameterString();
}
function getScriptFileName() {
var armdelim = ",";
var fileName = "ifb.0";
var queryString = getParameterString();
var parmValue = "";
if (queryString.length > 0) {
parmValue = getValueFromDelimitedString("armver", "a4edelim", queryString);
}
if (parmValue.length > 0) {
var fileNames = parmValue.split(armdelim);
for (var i = 0; i < fileNames.length; i++) {
if (fileNames[i].toLowerCase().indexOf("ifb") != -1) {
fileName = fileNames[i];
break;
}
}
}
return fileName + ".js";
}
if (typeof(armTestMode) == "undefined") {
ARMIfbLib.WriteIframeBustingScript();
}
I've spent a couple of hours studying this to try and work out what it's doing, but I've got bogged down in the different function calls. It seems to be grabbing a query string parameter or else a value from the name of an iframe, presumably the iframe the contains the ad.
Can anyone understand what this JS is doing? Does it look fairly safe from a XSS point of view?
=========================================
EDIT
In case useful to anybody else, we mentioned this concern to the providers, and their response was:
The iframe buster page will only work if it is in an iframe
The code in the ftlocal.html file will only work if the domain of the iframe is already the same as the domain of the parent page – So any code would already have access to the parent page anyway
The the JS script creates a dynamically generated script tag in your page.
ARMIfbLib.DocumentWrite("<script language='javascript' type='text/javascript' src='" + scriptURL + "'></scr" + "ipt>");
If you dig into where scriptURL comes from, it appears to be a parameter passed to window.location.search (the query string).
From what I can see this effectively allows any script to be passed to your page on the query string rendering it vulnerable to DOM XSS, unless it is effectively secured to allow the domain to be set by the frame name in your page. I'd do some testing using your own domains and passing the query string variables that are searched for (the string literals in the JS).

Javascript error after upgrade to Drupal 7

I posted a similar question at the Drupal Forum, but I haven't had much luck.
I'm upgrading a site from D6 to D7. So far it's gone well, but I'm getting a Javascript error that I just can't pin down a solution for.
This is a cut down version of the whole script:
(function($) {
function sign(secret, message) {
var messageBytes = str2binb(message);
var secretBytes = str2binb(secret);
if (secretBytes.length > 16) {
secretBytes = core_sha256(secretBytes, secret.length * chrsz);
}
var ipad = Array(16), opad = Array(16);
for (var i = 0; i < 16; i++) {
ipad[i] = secretBytes[i] ^ 0x36363636;
opad[i] = secretBytes[i] ^ 0x5C5C5C5C;
}
var imsg = ipad.concat(messageBytes);
var ihash = core_sha256(imsg, 512 + message.length * chrsz);
var omsg = opad.concat(ihash);
var ohash = core_sha256(omsg, 512 + 256);
var b64hash = binb2b64(ohash);
var urlhash = encodeURIComponent(b64hash);
return urlhash;
}
function addZero(n) {
return ( n < 0 || n > 9 ? "" : "0" ) + n;
}
Date.prototype.toISODate =
new Function("with (this)\nreturn " +
"getFullYear()+'-'+addZero(getMonth()+1)+'-'" +
"+addZero(getDate())+'T'+addZero(getHours())+':'" +
"+addZero(getMinutes())+':'+addZero(getSeconds())+'.000Z'");
function getNowTimeStamp() {
var time = new Date();
var gmtTime = new Date(time.getTime() + (time.getTimezoneOffset() * 60000));
return gmtTime.toISODate() ;
}
}(jQuery));
The part that keeps throwing an error I'm seeing in Firebug is at:
Date.prototype.toISODate =
new Function("with (this)\n return " +
"getFullYear()+'-'+addZero(getMonth()+1)+'-'" +
"+addZero(getDate())+'T'+addZero(getHours())+':'" +
"+addZero(getMinutes())+':'+addZero(getSeconds())+'.000Z'");
Firebug keeps stopping at "addZero is not defined". JS has never been my strong point, and I know some changes have been made in D7. I've already wrapped the entire script in "(function($) { }(jQuery));", but I must be missing something else. The same script works perfectly on the D6 site.
Here is the "fixed" version of the whole code with #Pointy suggestion added. All I left out is the part of the script for making the hash that goes to Amazon, and some of my declared variables.
(function($) {
var typedText;
var strSearch = /asin:/;
var srchASIN;
$(document).ready(function() {
$("#edit-field-game-title-und-0-asin").change(function() {
typedText = $("#edit-field-game-title-und-0-asin").val();
$.ajax({
type: 'POST',
data: {typedText: typedText},
dataType: 'text',
url: '/asin/autocomplete/',
success:function(){
document.getElementById('asin-lookup').style.display='none';
x = typedText.search(strSearch);
y = (x+5);
srchASIN = typedText.substr(y,10)
amazonSearch();
}
});
});
$("#search_asin").click(function() {
$("#edit-field-game-title-und-0-asin").val('');
document.getElementById('name-lookup').style.display='none';
$("#edit-field-game-title-und-0-asin").val('');
$("#edit-title").val('');
$("#edit-field-subtitle-und-0-value").val('');
$("#edit-field-game-edition-und-0-value").val('');
$("#edit-field-release-date-und-0-value-date").val('');
$("#edit-field-asin-und-0-asin").val('');
$("#edit-field-ean-und-0-value").val('');
$("#edit-field-amazon-results-und-0-value").val('');
$("#edit-body").val('');
srchASIN = $("#field-asin-enter").val();
amazonSearch();
});
$("#clear_search").click(function() {
$("#field-asin-enter").val('');
$("#edit-field-game-title-und-0-asin").val('');
$("#edit-title").val('');
$("#edit-field-subtitle-und-0-value").val('');
$("#edit-field-game-edition-und-0-value").val('');
$("#edit-field-release-date-und-0-value-date").val('');
$("#edit-field-release-dt2-und-0-value-date").val('');
$("#edit-field-asin-und-0-asin").val('');
$("#edit-field-ean-und-0-value").val('');
$("#edit-field-amazon-results-und-0-value").val('');
$("#field-amazon-platform").val('');
$("#field-amazon-esrb").val('');
$("#edit-body-und-0-value").val('');
document.getElementById('asin-lookup').style.display='';
document.getElementById('name-lookup').style.display='';
});
function amazonSearch(){
var ASIN = srchASIN;
var azScr = cel("script");
azScr.setAttribute("type", "text/javascript");
var requestUrl = invokeRequest(ASIN);
azScr.setAttribute("src", requestUrl);
document.getElementsByTagName("head").item(0).appendChild(azScr);
}
});
var amzJSONCallback = function(tmpData){
if(tmpData.Item){
var tmpItem = tmpData.Item;
}
$("#edit-title").val(tmpItem.title);
$("#edit-field-game-edition-und-0-value").val(tmpItem.edition);
$("#edit-field-release-date-und-0-value-date").val(tmpItem.relesdate);
$("#edit-field-release-dt2-und-0-value-date").val(tmpItem.relesdate);
$("#edit-field-asin-und-0-asin").val(tmpItem.asin);
$("#edit-field-ean-und-0-value").val(tmpItem.ean);
$("#field-amazon-platform").val(tmpItem.platform);
$("#field-amazon-publisher").val(tmpItem.publisher);
$("#field-amazon-esrb").val(tmpItem.esrb);
};
function ctn(x){ return document.createTextNode(x); }
function cel(x){ return document.createElement(x); }
function addEvent(obj,type,fn){
if (obj.addEventListener){obj.addEventListener(type,fn,false);}
else if (obj.attachEvent){obj["e"+type+fn]=fn; obj.attachEvent("on"+type,function(){obj["e"+type+fn]();});}
}
var styleXSL = "http://www.tlthost.net/sites/vglAmazonAsin.xsl";
function invokeRequest(ASIN) {
cleanASIN = ASIN.replace(/[-' ']/g,'');
var unsignedUrl = "http://xml-us.amznxslt.com/onca/xml?Service=AWSECommerceService&AssociateTag=theliterarytimes&IdType=ASIN&ItemId="+cleanASIN+"&Operation=ItemLookup&ResponseGroup=Medium,ItemAttributes,OfferFull&Style="+styleXSL+"&ContentType=text/javascript&CallBack=amzJSONCallback";
var lines = unsignedUrl.split("\n");
unsignedUrl = "";
for (var i in lines) { unsignedUrl += lines[i]; }
// find host and query portions
var urlregex = new RegExp("^http:\\/\\/(.*)\\/onca\\/xml\\?(.*)$");
var matches = urlregex.exec(unsignedUrl);
var host = matches[1].toLowerCase();
var query = matches[2];
// split the query into its constituent parts
var pairs = query.split("&");
// remove signature if already there
// remove access key id if already present
// and replace with the one user provided above
// add timestamp if not already present
pairs = cleanupRequest(pairs);
// encode the name and value in each pair
pairs = encodeNameValuePairs(pairs);
// sort them and put them back together to get the canonical query string
pairs.sort();
var canonicalQuery = pairs.join("&");
var stringToSign = "GET\n" + host + "\n/onca/xml\n" + canonicalQuery;
// calculate the signature
//var secret = getSecretAccessKey();
var signature = sign(secret, stringToSign);
// assemble the signed url
var signedUrl = "http://" + host + "/onca/xml?" + canonicalQuery + "&Signature=" + signature;
//document.write ("<html><body><pre>REQUEST: "+signedUrl+"</pre></body></html>");
return signedUrl;
}
function encodeNameValuePairs(pairs) {
for (var i = 0; i < pairs.length; i++) {
var name = "";
var value = "";
var pair = pairs[i];
var index = pair.indexOf("=");
// take care of special cases like "&foo&", "&foo=&" and "&=foo&"
if (index == -1) {
name = pair;
} else if (index == 0) {
value = pair;
} else {
name = pair.substring(0, index);
if (index < pair.length - 1) {
value = pair.substring(index + 1);
}
}
// decode and encode to make sure we undo any incorrect encoding
name = encodeURIComponent(decodeURIComponent(name));
value = value.replace(/\+/g, "%20");
value = encodeURIComponent(decodeURIComponent(value));
pairs[i] = name + "=" + value;
}
return pairs;
}
function cleanupRequest(pairs) {
var haveTimestamp = false;
var haveAwsId = false;
var nPairs = pairs.length;
var i = 0;
while (i < nPairs) {
var p = pairs[i];
if (p.search(/^Timestamp=/) != -1) {
haveTimestamp = true;
} else if (p.search(/^(AWSAccessKeyId|SubscriptionId)=/) != -1) {
pairs.splice(i, 1, "AWSAccessKeyId=" + accessKeyId);
haveAwsId = true;
} else if (p.search(/^Signature=/) != -1) {
pairs.splice(i, 1);
i--;
nPairs--;
}
i++;
}
if (!haveTimestamp) {
pairs.push("Timestamp=" + getNowTimeStamp());
}
if (!haveAwsId) {
pairs.push("AWSAccessKeyId=" + accessKeyId);
}
return pairs;
}
function sign(secret, message) {
var messageBytes = str2binb(message);
var secretBytes = str2binb(secret);
if (secretBytes.length > 16) {
secretBytes = core_sha256(secretBytes, secret.length * chrsz);
}
var ipad = Array(16), opad = Array(16);
for (var i = 0; i < 16; i++) {
ipad[i] = secretBytes[i] ^ 0x36363636;
opad[i] = secretBytes[i] ^ 0x5C5C5C5C;
}
var imsg = ipad.concat(messageBytes);
var ihash = core_sha256(imsg, 512 + message.length * chrsz);
var omsg = opad.concat(ihash);
var ohash = core_sha256(omsg, 512 + 256);
var b64hash = binb2b64(ohash);
var urlhash = encodeURIComponent(b64hash);
return urlhash;
}
Date.prototype.toISODate = function() {
function addZero(n) {
return ( n < 0 || n > 9 ? "" : "0" ) + n;
}
var d = this;
return d.getFullYear() + '-' +
addZero(d.getMonth() + 1) + '-' +
addZero(d.getDate()) + 'T' +
addZero(d.getHours()) + ':' +
addZero(d.getMinutes()) + ':' +
addZero(d.getSeconds()) + '.000Z';
};
function getNowTimeStamp() {
var time = new Date();
var gmtTime = new Date(time.getTime() + (time.getTimezoneOffset() * 60000));
return gmtTime.toISODate() ;
}
}(jQuery));
Here's a better version of your code:
Date.prototype.toISODate = function() {
function addZero(n) {
return ( n < 0 || n > 9 ? "" : "0" ) + n;
}
var d = this;
return d.getFullYear() + '-' +
addZero(d.getMonth() + 1) + '-' +
addZero(d.getDate()) + 'T' +
addZero(d.getHours()) + ':' +
addZero(d.getMinutes()) + ':' +
addZero(d.getSeconds()) + '.000Z';
};
That moves "addDate" inside the extension function, and it avoids the horrid with statement.

Categories