var MODE = "CHECK"; var quoteNum; var isIE = (document.all && !window.opera)? true:false; var prelImg = new Image(); prelImg.src = "template/images/loader.gif"; function submitForm() { if(document.getElementById("uploadedfile").value == "") { alert("Please select a file to upload first."); return false; } document.getElementById("uploadform").style.display = "none"; msgBox("Uploading files...", false); //showStatus(); document.getElementById("intro").style.display = "none"; return true; } function showStatus() { msgBox; //document.getElementById("analysestatus").style.display = "block"; } function hideStatus() { hideMsg() ; //document.getElementById("analysestatus").style.display = "none"; } function setStatus(status) { msgBox(status, false); //document.getElementById("statustext").firstChild.nodeValue = status; } var statusCheck; function checkStatus() { statusCheck = setTimeout("requestStatus()", 3000); } // createRO -- creates a cross-browser compatible XMLHttpRequest object for AJAX calls function createRO() {var request=false;if(window.XMLHttpRequest&&!(window.ActiveXObject)){try{request=new XMLHttpRequest()}catch(e){request=false}}else if(window.ActiveXObject){try{request=new ActiveXObject("Msxml2.XMLHTTP")}catch(e){try{request=new ActiveXObject("Microsoft.XMLHTTP")}catch(e){request=false}}}return request}; var http_req = createRO(); var retried; var retryTimer; function requestStatus() { retried = 0; initAjaxRequest("backend/status.php", "?requeststatus=1"eid="+quoteNum, 8000, 5); } // send AJAX request to server function initAjaxRequest(page, dataToSend, timeOut, retries) { //http_req = null; if(isIE)http_req = createRO(); var openCommand = page + dataToSend; http_req.open('get', openCommand); http_req.onreadystatechange = ajaxResponse; retried++; debug("sending data" + dataToSend + "(try " + retried + " of " + retries + ")"); http_req.send(null); if (retried < retries) { retryTimer = setTimeout("initAjaxRequest('" + page + "','" + dataToSend + "'," + timeOut + "," + retries + ")", timeOut); } else { debug("Could not contact server for request to " + page); } } // receive and parse XML response function ajaxResponse() { if(http_req.readyState == 4){ clearTimeout(retryTimer); var xmlDoc = http_req.responseXML; if(xmlDoc) { if(xmlDoc.getElementsByTagName('responsetype')[0]) { var responseType = xmlDoc.getElementsByTagName('responsetype')[0].firstChild.nodeValue; if(responseType=="statusdata"){ statusCode = xmlDoc.getElementsByTagName('code')[0].firstChild.nodeValue; debug("Status received: " + statusCode); if(statusCode=="P") { //showStatus(); //document.getElementById("statustext").firstChild.nodeValue = xmlDoc.getElementsByTagName('text')[0].firstChild.nodeValue; msgBox(xmlDoc.getElementsByTagName('text')[0].firstChild.nodeValue, false); checkStatus(); } else if(statusCode == "F") { //DEPRECATED document.getElementById("statustext").firstChild.nodeValue = xmlDoc.getElementsByTagName('text')[0].firstChild.nodeValue; hideMsg(); document.getElementById("dyncontent").innerHTML = xmlDoc.getElementsByTagName('pagecontent')[0].firstChild.nodeValue; document.getElementById("thisstep").firstChild.nodeValue = "2"; document.getElementById("stepdesc").firstChild.nodeValue = "Identify your files"; } else if (statusCode == "E") { msgBox(xmlDoc.getElementsByTagName('text')[0].firstChild.nodeValue, true); } } else if(responseType=="error"){ msgBox(xmlDoc.getElementsByTagName('details')[0].firstChild.nodeValue, true); } else { msgBox("Unexpected server response received: " + responseType + ".", true); } } else if(xmlDoc.getElementsByTagName('pcb')) { //alert(xmlDoc); processPCB(xmlDoc); } else { msgBox("Invalid server response received.", true); } } else { msgBox("Invalid server response received.", true); } } else { // alert(http_req.readyState); } } function msgBox(details, err) { var docEl = document.getElementById("dyncontent"); var exists = false; if(document.getElementById("msgbox")) { var exists = true; document.getElementById("msgbox").parentNode.removeChild(document.getElementById("msgbox")); } if(document.getElementById("grscrn")) { document.getElementById("grscrn").parentNode.removeChild(document.getElementById("grscrn")); } var errBox = document.createElement('div'); if(!err) { var dimDiv = document.createElement('div'); dimDiv.setAttribute('id', 'grscrn'); errBox.className = "ongrey"; } var errBoxTitle = document.createElement('h2'); var title = (err) ? "An error occurred" : "Status"; errBoxTitle.setAttribute('id', 'msgboxTitle'); errBoxTitle.appendChild(document.createTextNode(title)); errBox.appendChild(errBoxTitle); errBox.setAttribute('id', 'msgbox'); var errDesc = document.createElement('p'); if (err) { var str = document.createElement('strong'); str.appendChild(document.createTextNode("ERROR: ")); str.setAttribute('id', 'errHdg'); errDesc.appendChild(str); } errDesc.appendChild(document.createTextNode(details)); errBox.appendChild(errDesc); if (err) { var errDesc2 = document.createElement('p'); errDesc2.appendChild(document.createTextNode("Please ")); var errLink = document.createElement('a'); errLink.setAttribute('href', 'index.php'); errLink.appendChild(document.createTextNode("click here")); errDesc2.appendChild(errLink); errDesc2.appendChild(document.createTextNode(" to try again.")); errBox.appendChild(errDesc2); } else { var stImg = document.createElement('img'); stImg.setAttribute('alt', 'Working...'); stImg.setAttribute('src', 'template/images/loader.gif'); errBox.appendChild(stImg); } if(!err) { errBox.style.left = ((f_clientWidth()/2) - 220) + "px"; docEl.appendChild(dimDiv); } docEl.appendChild(errBox); if(exists) { if(!err)setOpacity("grscrn", 80); setOpacity("msgbox", 100); } else { if(!err)setOpacity("grscrn", 0); setOpacity("msgbox", 0); if(!err)doAnimation("fade", "grscrn", 0, 80, 500, 20); doAnimation("fade", "msgbox", 0, 100, 500, 20); } //var par = docEl.parentNode; //par.removeChild(docEl); //par.appendChild(errBox); } function hideMsg() { doAnimation("fade", "grscrn", 80, 0, 500, 20); doAnimation("fade", "msgbox", 100, 0, 500, 20); setTimeout("remMsg();", 500); } function remMsg() { if(document.getElementById("msgbox")) { document.getElementById("msgbox").parentNode.removeChild(document.getElementById("msgbox")); } if(document.getElementById("grscrn")) { document.getElementById("grscrn").parentNode.removeChild(document.getElementById("grscrn")); } } function debug(details) { } function print_r(x, max, sep, l) { l = l || 0; max = max || 10; sep = sep || ' '; if (l > max) { return "[WARNING: Too much recursion]\n"; } var i, r = '', t = typeof x, tab = ''; if (x === null) { r += "(null)\n"; } else if (t == 'object') { l++; for (i = 0; i < l; i++) { tab += sep; } if (x && x.length) { t = 'array'; } r += '(' + t + ") :\n"; for (i in x) { try { r += tab + '[' + i + '] : ' + print_r(x[i], max, sep, (l + 1)); } catch(e) { return "[ERROR: " + e + "]\n"; } } } else { if (t == 'string') { if (x == '') { x = '(empty)'; } } r += '(' + t + ') ' + x + "\n"; } return r; }; /* Animation effects ----------------- Effects original John Wells 2008 */ // general handler for animation effects function doAnimation(effect, objID, startVal, endVal, time, steps) { var timeSteps = time/steps; var sizeSteps = (Math.abs(endVal-startVal))/steps; var sign = (endVal > startVal) ? 1 : -1; for(var i=0; Math.abs(i)<=steps;i=i+sign) { if(effect=="leftmarginanim") { // move left or right setTimeout("setLeftMargin(\""+objID+"\","+(startVal+(sizeSteps*i))+")", Math.abs((i*timeSteps))); } else if(effect=="marginanim") { // move up or down setTimeout("setTopMargin(\""+objID+"\","+(startVal+(sizeSteps*i))+")", Math.abs((i*timeSteps))); } else if(effect=="grow") { // grow effect setTimeout("setHeight(\""+objID+"\","+(startVal+(sizeSteps*i))+")", Math.abs((i*timeSteps))); } else { // fade effect setTimeout("setOpacity(\""+objID+"\","+(startVal+(sizeSteps*i))+")", Math.abs((i*timeSteps))); } } } // for height to work, need to set overflow to hidden!! function setHeight(objID, height) { if ((objID=="nav1")||(objID=="nav2")||(objID=="nav3")||(objID=="nav4")) { var obj=document.getElementById(objID).getElementsByTagName("UL")[0].style; } else { var obj=document.getElementById(objID).style; } obj.height = height + "px"; } // animates objects horizontally by altering their left margin function setLeftMargin(objID, width) { if ((objID=="nav1")||(objID=="nav2")||(objID=="nav3")||(objID=="nav4")) { var obj=document.getElementById(objID).getElementsByTagName("UL")[0].style; } else { var obj=document.getElementById(objID).style; } obj.marginLeft = width + "px"; } // animates objects vertically by altering their top margin function setTopMargin(objID, height) { if ((objID=="nav1")||(objID=="nav2")||(objID=="nav3")||(objID=="nav4")) { var obj=document.getElementById(objID).getElementsByTagName("UL")[0].style; } else { var obj=document.getElementById(objID).style; } obj.marginTop = height + "px"; } // sets an element's transparency in a cross-browser compatible way. function setOpacity(element, opac) { if ((element=="nav1")||(element=="nav2")||(element=="nav3")||(element=="nav4")) { var obj=document.getElementById(element).getElementsByTagName("UL")[0].style; } else { var obj=document.getElementById(element).style; } obj.filter="alpha(opacity:"+opac+")"; //for IE obj.opacity=obj.MozOpacity=obj.KhtmlOpacity=(opac/100); //for Gecko & Konq/Safari } function f_clientWidth() { return f_filterResults ( window.innerWidth ? window.innerWidth : 0, document.documentElement ? document.documentElement.clientWidth : 0, document.body ? document.body.clientWidth : 0 ); } function f_clientHeight() { return f_filterResults ( window.innerHeight ? window.innerHeight : 0, document.documentElement ? document.documentElement.clientHeight : 0, document.body ? document.body.clientHeight : 0 ); } function f_filterResults(n_win, n_docel, n_body) { var n_result = n_win ? n_win : 0; if (n_docel && (!n_result || (n_result > n_docel))) n_result = n_docel; return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result; } /* PROCESSQUOTE.JS John Wells Last updated: 16 Sep 2008 Deals with building the user interface from supplied XML QUOTE data */ var numDrills; var numUnknowns; var numGerbers; function processPCB(xml) { /* Extract the data from the PCB schema file into separate layers ready to be placed on a page. TODO: abstractify so we can call generic layers for various purposes. */ layers = xml.getElementsByTagName('layer'); hideMsg(); numDrills = 0; numUnknowns = 0; numGerbers = 0; var gerbers = document.createElement('div'); var drills = document.createElement('div'); var unknowns = document.createElement('ul'); // seems IE doesn't support for..in loops for xml child nodes. FFS, Microsoft. Thanks for the lost day. for(var layer=0;layer 35) { fileName = fileName.substr(0,26) + "…" + fileName.substr(fileName.length-7); } if (layers[layer].getElementsByTagName('type')[0]) { var type = layers[layer].getElementsByTagName('type')[0].firstChild.nodeValue; } else { var type = "Unknown file"; } var layerID = getAttribute("id", layers[layer]); var useDims = getAttribute("usedimensions", layers[layer]); if ( (layerStatus == "gerber") || (layerStatus == "drill") ) { // All valid files if(layers[layer].getElementsByTagName('image')[0]) { var imgName = layers[layer].getElementsByTagName('image')[0].firstChild.nodeValue; } else { imgName = "na"; } layerDiv = document.createElement('div'); layerDiv.className = "layerpreview"; layerDiv.setAttribute('id', 'layer'+layerID); var title = document.createElement('h2'); title.appendChild(document.createTextNode(fileName)); layerDiv.appendChild(title); var details = document.createElement('p'); details.className = "fancysub"; if(layerStatus == "gerber") { // Valid Gerber files only var width = parseFloat(layers[layer].getElementsByTagName('width')[0].firstChild.nodeValue); var height = parseFloat(layers[layer].getElementsByTagName('height')[0].firstChild.nodeValue); var measure = layers[layer].getElementsByTagName('measure')[0].firstChild.nodeValue; var dims = ((width>0.00) && (height>0.00)) ? width + " x " + height + " " + measure : "n/a"; var trackWidth = layers[layer].getElementsByTagName('trackwidth')[0].firstChild.nodeValue; var trackSpacing = layers[layer].getElementsByTagName('trackspacing')[0].firstChild.nodeValue; details.appendChild(document.createTextNode("Dimensions: " + dims)); details.appendChild(document.createElement('br')); details.appendChild(document.createTextNode("Min. track width: " + trackWidth)); details.appendChild(document.createElement('br')); details.appendChild(document.createTextNode("Min. track spacing: " + trackSpacing)); } else { details.appendChild(document.createTextNode("Excellon Drill File")); } layerDiv.appendChild(details); var image = document.createElement('img'); image.setAttribute('alt', fileName); image.setAttribute('src', "image.php?id="+quoteNum+"&img="+imgName); layerDiv.appendChild(image); layerDiv.appendChild(document.createElement('br')); if (layerStatus == "gerber"){ numGerbers++; if(MODE == "QUOTE") { var typeSelectLbl = document.createElement('label'); typeSelectLbl.setAttribute("for", "sel"+layerID); typeSelectLbl.appendChild(document.createTextNode("This layer is: ")); var typeSelect = document.createElement('select'); typeSelect.setAttribute("id" , "sel"+layerID); //TODO: Have this vary depending on number of given layers layerTypes = new Array("unknown", "Top Copper", "Bottom Copper", "Top Soldermask", "Bottom Soldermask", "Top Silkscreen", "Bottom Silkscreen", "Board Outline", "Internal Layer"); for(var i in layerTypes) { typeSelectOpt = document.createElement('option'); typeSelectOpt.setAttribute("value", layerTypes[i]); if(layerTypes[i] == type) { typeSelectOpt.setAttribute("selected", ""); } textNode = (layerTypes[i] == "unknown") ? "---Please select a layer type---" : layerTypes[i]; typeSelectOpt.appendChild(document.createTextNode(textNode)); typeSelect.appendChild(typeSelectOpt); } var dimRad = document.createElement('input'); dimRad.setAttribute("type", "radio"); dimRad.setAttribute("id" , "rad"+layerID); dimRad.setAttribute("name", "dimrad"); if(useDims=="true") { dimRad.setAttribute("checked", "checked"); } var radLbl = document.createElement('label'); radLbl.setAttribute("for", "rad"+layerID); radLbl.appendChild(document.createTextNode(" This layer contains my board outline")); layerDiv.appendChild(typeSelectLbl); layerDiv.appendChild(typeSelect); layerDiv.appendChild(document.createElement('br')); layerDiv.appendChild(dimRad); layerDiv.appendChild(radLbl); } else { var typeP = document.createElement('p'); typeP.appendChild(document.createTextNode("Probable layer type: " + type)); layerDiv.appendChild(typeP); } gerbers.appendChild(layerDiv); } else { numDrills++; layerDiv.appendChild(document.createElement('br')); var caveat = document.createElement('small'); caveat.appendChild(document.createTextNode("Note: drill images do not always correctly represent the actual drill file")); layerDiv.appendChild(caveat); drills.appendChild(layerDiv); } } else { //unknown files numUnknowns++; var li = unknowns.appendChild(document.createElement('li')); var str = unknowns.appendChild(document.createElement('strong')); str.appendChild(document.createTextNode(fileName + ": ")); li.appendChild(str); li.appendChild(document.createTextNode(type)); unknowns.appendChild(li); } } } showStepTwo(gerbers, drills, unknowns); //alert (document.getElementById("dyncontent").innerHTML); } function showStepTwo(gb, dr, unk) { /* Build the page for Step two -- headings and instructions together with the layer blocks generated aboce */ var toDiv = document.getElementById("dyncontent"); var currLoc = toDiv.firstChild; //First, update our step number and description if(MODE == "QUOTE") { document.getElementById("thisstep").firstChild.nodeValue = "2"; document.getElementById("stepdesc").firstChild.nodeValue = "Identify your files"; } //Intro if(MODE == "QUOTE") { var mainIntro = document.createElement('p'); mainIntro.appendChild(document.createTextNode("The files you uploaded are shown below. Please check that all files are shown, and confirm the identity of each layer using the drop-downs.")); toDiv.insertBefore(mainIntro, currLoc); mainIntro = document.createElement('p'); mainIntro.appendChild(document.createTextNode("Then, please select the layer that shows the board outline. This layer will be used to calculate the dimensions of your board, so we can provide a quotation.")); toDiv.insertBefore(mainIntro, currLoc); var mainIntro = document.createElement('p'); mainIntro.appendChild(document.createTextNode("Once you are finished, please click the \"Next\" button to continue.")); } else { var mainIntro = document.createElement('p'); mainIntro.appendChild(document.createTextNode("Here are your uploaded files...")); toDiv.insertBefore(mainIntro, currLoc); mainIntro = document.createElement('p'); strI = document.createElement('strong'); strI.className = "grnheadline"; strI.appendChild(document.createTextNode("Check back in mid-October 2008: you'll be able to order your PCBs and check out online!")); pdfLink = document.createElement('a'); pdfLinkP = document.createElement('p'); pdfLinkP.className = "pdflink"; pdfLink.appendChild(document.createTextNode("Download results in PDF format")); pdfLink.setAttribute("href", "pdf.php?id="+quoteNum); pdfLinkP.appendChild(pdfLink); //pdfLinkP.appendChild(document.createTextNode(" to download these results in PDF format.")); mainIntro.appendChild(strI); mainIntro.appendChild(pdfLinkP); } toDiv.insertBefore(mainIntro, currLoc); toDiv.insertBefore(document.createElement('hr'), currLoc); // Gerber files var intro = document.createElement('h2'); intro.appendChild(document.createTextNode("Gerber files:")); var introp = document.createElement('p'); introp.appendChild(document.createTextNode("These are the valid Gerber files found:")); toDiv.insertBefore(intro, currLoc); toDiv.insertBefore(introp, currLoc); toDiv.insertBefore(gb, currLoc); toDiv.insertBefore(document.createElement('hr'), currLoc); // Drill files var intro2 = document.createElement('h2'); drillFiles = (numDrills == 1) ? "file" : "files"; drillFilesWere = (numDrills == 1) ? "was" : "were"; intro2.appendChild(document.createTextNode("Drill " + drillFiles)); toDiv.insertBefore(intro2, currLoc); var intro2p = document.createElement('p'); if(numDrills == 0) { var strong = document.createElement('strong'); strong.appendChild(document.createTextNode("Error: ")); intro2p.appendChild(strong); intro2p.appendChild(document.createTextNode("No Excellon Drill files were found.")); toDiv.insertBefore(intro2p, currLoc); } else { intro2p.appendChild(document.createTextNode("The following Excellon drill " + drillFiles + " " + drillFilesWere + " found:")); toDiv.insertBefore(intro2p, currLoc); toDiv.insertBefore(dr, currLoc); } toDiv.insertBefore(document.createElement('hr'), currLoc); //Invalid files if(numUnknowns >0) { var intro3 = document.createElement('h2'); unFiles = (numUnknowns == 1) ? "file" : "files"; unFilesDo = (numUnknowns == 1) ? "does not appear to be a" : "do not appear to be"; intro3.appendChild(document.createTextNode("Other " + unFiles)); toDiv.insertBefore(intro3, currLoc); var intro3p = document.createElement('p'); intro3p.appendChild(document.createTextNode("The following " + unFiles + " included in the archive " + unFilesDo + " valid.")); toDiv.insertBefore(intro3p, currLoc); toDiv.insertBefore(unk, currLoc); } //alert(toDiv.innerHTML); } //Returns attribute (e.g. status, id, usedimensions) for the layer function getAttribute(attName, item) { // once again, IE won't support for..in for(var i=0;i