function FDCPBridge(initParams) { // number of attempts at polling iframe content this.count = 0; // the iframe used to hold the cleanprint response this.ifc = null; // form inside the iframe, used to post data to cleanprint this.oform; // timer id this.tid = 0; // grab a copy of FDCP this.fdcp = initParams.fdcp; // callback function to call when printing is either done or aborted this.pcallback = null; // the DIV where Ajax-based CP content goes this.fd_div_id = "fd_page_main"; // the list of onscreen elements that were removed this.rmEl = new Array(); // the list of stylesheets that were removed this.st = new Array(); this.nonescnames = [ 'd','p','r','q','bn','bv' ]; this.doesc = function(robj) { oloop: for(var x in robj) { for(var n = 0; n < this.nonescnames.length; n++) { if(x == this.nonescnames[n]) { continue oloop; } } robj[x] = escape(robj[x]); } } /** * Attempts to make the cleanprint happen. * * cpData: an object containing all request parameters * timeoutInterval: a time in milliseconds, after which the cleanprint should fail * callbackFunction: a function that takes a single boolean parameter. A true indicates * that the cleanprint happened successfully (use this to reset state). * A false indicates that the cleanprint did not happen, and the * callback can take appropriate action, possibly different based on the * activation mechanism (link-based vs. File->Print...) */ this.cleanPrint = function(cpData, timeoutInterval, callbackFunction) { if (this.fdcp.clt.getFDDebug()) { alert('DocDomain : [' + document.domain + ']'); } this.pcallback = callbackFunction; if(this.fdcp.clt.mode == this.fdcp.clt.modes.printerFriendlyViewer || cpData.action != 'print'){ cpData.pfv = 'y'; try{ var pfvId = this.fdcp.clt.getCPViewerId(); if(typeof pfvId != 'undefined'){ cpData.pfvId = pfvId; } }catch(e){ } cpData.pfUrl = this.fdcp.pfLink; } // for IE, use the Ajax call, which is tied to the print event if (FDCPLoader.browserDetect.browser == 'Explorer' && !fdcp.clt.cpc.templateTest && this.fdcp.clt.mode == this.fdcp.clt.modes.filePrint) { if (this.fdcp.clt.getFDDebug()) { alert('IE Printing'); } FDCPLoader.fdPrintWrapper(); this.pcallback(true); return; } // Remove existing iframe and form before printing if(typeof this.ifc != 'undefined' && this.ifc != null) { document.body.removeChild(this.ifc); document.body.removeChild(this.oform); } // get the url var newUrl = this.fdcp.getCpUrl(); var frameName = "fDContentFrame"; // create the Iframe this.ifc=document.createElement("iframe"); this.ifc.setAttribute('src', 'about:blank'); this.ifc.setAttribute('id', frameName); this.ifc.setAttribute('NAME', frameName); this.ifc.setAttribute('loaded', false); this.ifc.onload = function() { loaded = true; }; this.ifc.style.width = '0px'; this.ifc.style.height = '0px'; this.ifc.style.border = '0px'; document.body.appendChild(this.ifc); if(FDCPLoader.browserDetect.browser != "Explorer" || (FDCPLoader.browserDetect.browser == "Explorer" && FDCPLoader.browserDetect.version >= 7)){ if(self.frames[frameName].name != frameName) { self.frames[frameName].name = frameName; } } // create the form this.oform=document.createElement("form"); document.body.appendChild(this.oform); this.oform.action = newUrl; this.oform.name = 'FDForm'; this.oform.method = 'post'; if(this.fdcp.clt.mode == this.fdcp.clt.modes.printerFriendlyViewer || cpData.action != 'print'){ var wind = window.open("about:blank", "test", "copyhistory=yes,width=1024,height=768,left=50, top=50,screenX=50,screenY=50"); this.oform.target = "test"; wind.focus(); } else{ this.oform.target = frameName; } // Add the params for(var k in cpData) { var pc = document.createElement("input"); pc.type = "hidden"; pc.name = k; pc.value = cpData[k]; this.oform.appendChild(pc); } this.count = 0; if (this.fdcp.clt.getFDDebug()) { alert('CP Submit'); } // Submit the form this.oform.submit(); if(this.fdcp.clt.mode == this.fdcp.clt.modes.printerFriendlyViewer){ this.pcallback(true); this.fdcp.clt.resetMode(); this.fdcp.getCpPostDataValue = null; return; } // check for content every second if(this.fdcp.clt.mode != this.fdcp.clt.modes.printerFriendlyViewer && this.fdcp.clt.action == "print" && this.fdcp.clt.outputFormat == "text/html"){ this.tid = setInterval(function() { this.fdcp.bridge.checkcontent(); },1000); } } this.clientlog = function(log_code,log_message) { var params = this.fdcp.clt.getRequestObject(); params.bn = FDCPLoader.browserDetect.browser; params.bv = FDCPLoader.browserDetect.version; // client failure logging url var url = this.fdcp.clt.logUrl + "/f"; var pstr = "LOG_CODE=" + log_code; if(typeof log_message != "undefined" && log_message != null){ pstr += '&' + "LOG_MSG=" + escape(log_message); } if(typeof params != 'undefined' && params != null) { for(var p in params) { pstr += '&' + p + '=' + params[p]; } } url = url + "?" + pstr ; var log_image = new Image(); log_image.src = url; } /** * Sends a log message to the cleanprint logging servlet. * * level: a log4j log level (debug, warn, error, etc.) * description: the error message */ this.log = function(level, description, url, additionalParams) { if(url == null) return; try { var params = "rtype=log&"; params += "LOG_LEVEL=" + level + "&"; params += "LOG_MSG=" + description + "&"; if(typeof additionalParams != 'undefined' && additionalParams != null) { for(var p in additionalParams) { params += '&' + p + '=' + additionalParams[p]; } } var myFdAjax = fdGetAjaxObj(); if(typeof myFdAjax == 'undefined' || myFdAjax == null){ return; } myFdAjax.open("POST", url, true); myFdAjax.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); myFdAjax.send(params); } catch(e) { // don't let an error kill the cleanprint } } /** * callback function used to see if content has been returned into the iframe. When it has, * the content is printed. */ this.checkcontent = function() { try { if(this.count < 10) { // Test for the End of Content if(this.ifc != null) { var contentElement = FDCPLoader.browserDetect.browser == "Explorer" ? this.ifc.contentWindow : this.ifc.contentDocument; if(contentElement != 'undefined'){ var contentForms = FDCPLoader.browserDetect.browser == "Explorer" ? contentElement.document.forms : contentElement.forms; if (typeof contentForms['EOC'] != 'undefined') { // clear the timer clearInterval(this.tid); // switch off PrintTracker this.fdcp.enPt(false); if (this.fdcp.clt.getFDDebug()) { alert('CP Content Pass - Print'); } var printElement = FDCPLoader.browserDetect.browser == "Explorer" ? contentElement : this.ifc.contentWindow; // print the iframe FDCPLoader.fdPrintWrapper(printElement); // turn PrintTracker back on this.fdcp.enPt(true); // re-enable the link this.pcallback(true); return true; } else this.count = this.count + 1; } } else this.count = this.count + 1; } else { clearInterval(this.tid); this.pcallback(false); return false; } } catch(e) { if (this.fdcp.clt.getFDDebug()) { alert('CP Content Fail : [' + e.message + ']'); } this.count = 10; clearInterval(this.tid); this.pcallback(false); } } /** * removes all non-CP visual elements from the page */ this.removeelements = function () { var pathsValid = this.validateAjaxPaths(); if(!pathsValid){ return false; } var cpdata = this.fdcp.getCpPostData(); if(cpdata == null) { if (this.fdcp.clt.getFDDebug()) { alert('CP Content Fail'); } return false; } else { if (this.fdcp.clt.getFDDebug()) { alert('CP Content Pass'); } } var result = fdcp.clt.onPrint(cpdata); if(typeof result != 'undefined' && result != null && result==false){ return false; } var cpoutput = this.getOutputDocument(cpdata); if(cpoutput.indexOf('
') != -1) { var fd_div = document.getElementById(this.fd_div_id); if (fd_div != null) { // Don't add print content if the toggle failed. // try the togEl twice. IE has a bug that will cause it to fail the first // time in some cases and work on the second if(this.togEl(true) || this.togEl(true)){ if(typeof this.fdcp.clt.onBeforeCleanPrint != "undefined"){ cpoutput = this.fdcp.clt.onBeforeCleanPrint(cpoutput); } fd_div.style.display = 'block'; fd_div.innerHTML = cpoutput; } } } } this.validateAjaxPaths = function(){ // Test for the same domain var url_re = new RegExp("^(?:(http[s]?):\/\/([^/:]+)(:[0-9]+)?)?(.*)"); var cpurl = this.fdcp.getCpUrl(); var cp_match = url_re.exec(cpurl); // if cp_match is null, we got garbage back from getCpUrl if(cp_match == null) return false; // if cp_match came back with a domain, make sure it's the same as the host page's if(cp_match[2] != '') { var d = url_re.exec(window.location); // if http is present, need everything up to the path if(cp_match[1] != undefined && cp_match[1] + cp_match[2] != d[1] + d[2]) return false; if(cp_match[3] != d[3]) return false; } return true; } /* * Makes ajax call to cleanprint and returns the output document */ this.getOutputDocument = function(cpdata){ var postBodyStr = ""; for(var x in cpdata) { var n; for(n = 0; n < this.nonescnames.length; n++) { if(x == this.nonescnames[n]) { break; } } if(n == this.nonescnames.length){ postBodyStr += x + '=' + escape(cpdata[x]) + '&'; } else{ postBodyStr += x + '=' + cpdata[x] + '&'; } } var myFdAjax = fdGetAjaxObj(); if(typeof myFdAjax == 'undefined' || myFdAjax == null){ return ""; } myFdAjax.open("POST", this.fdcp.getCpUrl(), false); myFdAjax.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); myFdAjax.send(postBodyStr); if (myFdAjax.status == 200) { return myFdAjax.responseText; } return ""; } /** * Replaces visible elements after the print completes */ this.revertback = function() { var fd_div = document.getElementById(this.fd_div_id); if (fd_div != null) { fd_div.innerHTML = ""; fd_div.style.display = 'none'; } this.togEl(false); // let fdcp know that the print is done this.fdcp.CPFailover(true); } /** * turns page elements on or off. This includes all block elements and stylesheets. * If bp is true, elements are removed. If false, they are shown. * * Returns false if it fails, true otherwise. */ this.togEl = function(bp) { var d = document; var body = d.body; var removed = new Array(); if(bp) { var i = 0; this.st = []; // push body elements onto the rmEl array, disable STYLE and LINK elements for( i = 0; i < body.childNodes.length; i++ ) { if(typeof body.childNodes[i].id != 'undefined' && body.childNodes[i].id == this.fd_div_id) { continue; } else if(body.childNodes[i].nodeName=='STYLE' || body.childNodes[i].nodeName=='LINK'){ if(body.childNodes[i].disabled){ continue; } else{ body.childNodes[i].disabled=true; this.st.push(body.childNodes[i]); } } else{ this.rmEl.push(body.childNodes[i]); } } // Remove all non-fd elements from the body. // Replace removed elements if there was an error. try{ for( i = 0; i < this.rmEl.length; i++ ) { body.removeChild(this.rmEl[i]); removed.push(this.rmEl[i]); } } catch(err){ // Avoid changing ordering of elements in the body by inserting // all removed elements before the first existing element if(body.childNodes.length > 0){ var e = body.childNodes[0]; for(i=0; i=4 && navigator.userAgent.indexOf("Windows") != -1) { if (document.body != null) { var div = document.createElement('div'); div.setAttribute("id", this.fd_div_id); div.style["display"] = "none"; document.body.appendChild(div); div.innerHTML = "FD HIDDEN DIV"; } if (localFdcp.clt.cpc != null && localFdcp.clt.getcpStat() == 'y') { window.attachEvent("onbeforeprint", this.handleOnBeforePrint ); window.attachEvent("onafterprint", function() { localFdcp.bridge.revertback();localFdcp.clt.resetMode(); } ); } } if(typeof Ajax == 'undefined'){ var jsloc = this.fdcp.clt.getCfg('ajaxlib'); if(typeof jsloc == 'undefined' || jsloc == null) return; var e = document.createElement('script'); e.src = jsloc; e.type = 'text/javascript'; document.getElementsByTagName("head")[0].appendChild(e); } } this.handleOnBeforePrint = function() { if(fdcp.clt.mode == fdcp.clt.modes.unset){ fdcp.clt.mode = fdcp.clt.modes.filePrint; } fdcp.bridge.removeelements(); } } /** * FDCP * * The main CleanPrint class. */ function FDCP() { this.clt = FDCPLoader.FDCPClient; this.bridge = new FDCPBridge( { fdcp : this }); this.fdser = new FDSerializer(this.clt); this.tstr = this.clt.getTPath(); this.pfLink = null; this.linkClicked = false; if (this.clt.getFDDebug()) { alert('TPath : [' + this.clt.getTPath() + '] Tmpl : [' + this.clt.getTmpl() + '] Div : [' + this.clt.getDiv() + ']'); } /** * returns true if CP is enabled */ this.cpEn = function() { return fdcp.clt.cpc != null && fdcp.clt.getcpStat() == 'y'; } /** * returns true if cleanprint can run on the user's browser/os combo */ this.browserSupported = function() { if (FDCPLoader.browserDetect.browser == "Opera") { return false; } else if ((FDCPLoader.browserDetect.browser == "Safari") && (FDCPLoader.browserDetect.OS == "Windows")) { return false; } else return true; } /** * returns the base URL for CleanPrint, with a single cache-busting * parameter */ this.getCpUrl = function() { return this.tstr + '?' + (new Date()).getTime(); } /** * marshals the cleanprint request data, timeout value, failover function * and hands the print over to the helper class */ this.linkPrintHandler = function(pfLink) { // make a copy of the printer friendly link if (pfLink != undefined) this.pfLink = pfLink; // if cleanprint is disabled or the browser isn't supported, log it and fail over if (this.cpEn() == false || !this.browserSupported()) { if(!this.browserSupported()){ this.bridge.clientlog("BROWSER_NOT_SUPPORTED"); } this.CPFailover(false); return true; } try { // only go into this block if there isn't a pending link print if (fdcp.linkClicked != true) { // set the link flag, so we can't double-print fdcp.linkClicked = true; // get the request data var cpdata = this.getCpPostData(); if(!cpdata){ this.CPFailover(false); return false; } // add cp viewer params to the post data if(this.clt.mode == this.clt.modes.printerFriendlyViewer) { cpdata.pfv = 'y'; try { // see if a speicific viewer instance is needed var pfvId = this.clt.getCPViewerId(); if(typeof pfvId != 'undefined') cpdata.pfvId = pfvId; } catch(e){ } cpdata.pfUrl = this.pfLink; } // TODO: should we break out the call to getPCXPath? // This is set so the client functions can decide to make a template change based on content width this.clt.blkwidth = this.fdser.getWidestBlkWidth(); // fire the onprint event var result = this.clt.onPrint(cpdata); // if onprint returned an invalid result, abort the cleanprint if (typeof result != 'undefined' && result != null && result == false) { if (this.clt.getFDDebug()) { alert('onPrint() returned ' + result + ', failing over'); } this.CPFailover(false); return false; } // make sure we got a request object. if (cpdata != null) { if (this.clt.getFDDebug()) { alert('CPPostData - Pass'); } if((cpdata.pfv == 'y' || cpdata.action == 'email') && this.clt.cpc.rpOk == true) { this.printToViewer(cpdata); // this.pcallback(true); this.clt.resetMode(); this.getCpPostDataValue = null; } else { if(cpdata.pfv == 'y' || cpdata.action != 'print'){ this.bridge.printToScreen = true; } if(FDCPLoader.browserDetect.browser == "Safari" && ((typeof this.bridge.printElement == "undefined" || this.bridge.printElement == null || this.bridge.printElement.closed) && ((cpdata.pfv && cpdata.pfv=='y') || cpdata.action != 'print') || cpdata.tt == true)){ //this.bridge.printElement = window.open(); this.bridge.printElement = null; this.bridge.printElement = window.open("about:blank", "pfvWindow", "toolbar=0,location=0,directories=0,status=0,menubar=0,resizable=0,scrollbars=no,copyhistory=yes,width=1024,height=768,left=50, top=50,screenX=50,screenY=50"); } // call the bridge's cleanprint method this.bridge.cleanPrint(cpdata, this.clt.getTO(), function( status) { fdcp.CPFailover(status); }); } } else { if (this.clt.getFDDebug()) { alert('CPPostData - Fail (cpdata is null)'); } this.CPFailover(false); } } } catch (e) { // caught an error - assume the print failed and do a failover print. if (this.clt.getFDDebug()) { alert('CPPostData - Fail (error): ' + e.message); } this.bridge.clientlog("LINK_PRINT_EXCEPTION", e.message); fdcp.CPFailover(false); } return true; } /** * printToViewer(): open a chomeless viewer window and send cleanprint output to it */ this.printToViewer = function(cpData) { // create the form var oform = document.createElement("form"); document.body.appendChild(oform); oform.action = fdcp.getCpUrl(); oform.name = 'FDForm'; oform.method = 'post'; if(typeof cpData.action != 'undefined' && (cpData.pfv && cpData.pfv != 'y')){ cpData.pfv = 'n'; } // Open the viewer window here, so we can create it with as little chrome as possible var wind = window.open("about:blank", "pfvWindow", "toolbar=0,location=0,directories=0,status=0,menubar=0,resizable=0,scrollbars=no,copyhistory=yes,width=1024,height=768,left=50, top=50,screenX=50,screenY=50"); wind.focus(); oform.target = "pfvWindow"; // Add the params for(var k in cpData) { var pc = document.createElement("input"); pc.type = "hidden"; pc.name = k; pc.value = cpData[k]; oform.appendChild(pc); } if (this.clt.getFDDebug()) { alert('CP Submit'); } // Submit the form oform.submit(); } // Keep a copy of the request data, in case it's needed again this.getCpPostDataValue; /** * Returns an object that contains all of the cleanprint request data, * including primary content. It returns null and logs an error if anything * critical wasn't available. */ this.getCpPostData = function() { if (typeof this.getCpPostDataValue != "undefined" && this.getCpPostDataValue != null) { return this.getCpPostDataValue; } if (typeof this.clt.getDiv() == 'undefined' || this.clt.getDiv() == null || this.clt.getDiv().length == 0) { this.bridge.log("ERROR", "No division defined", this.clt.logUrl); this.bridge.clientlog("NO_DIVISION_DEFINED"); return null; } if (typeof this.clt.getSegment() == 'undefined' || this.clt.getSegment() == null) { this.bridge.log("ERROR", "No segment defined", this.clt.logUrl); this.bridge.clientlog("NO_SEGMENT_DEFINED"); return null; } var pc = null; if (typeof fdcp.clt.onBeforeContentSerialization == "function") { fdcp.clt.onBeforeContentSerialization(); } try { pc = this.getPCXPath(); } catch (e) { this.bridge.log("ERROR", "Error generating primary content.", this.clt.logUrl); this.bridge.clientlog("PC_GEN_ERROR",e.message); return null; } finally { if (typeof fdcp.clt.onAfterContentSerialization == "function") { fdcp.clt.onAfterContentSerialization(); } } if (pc == null || pc.length == 0) { return null; } // TODO: i think this is unsupported on the server side as of 3.1.3 var imgs = null; try { imgs = this.getImages(); } catch (e) { this.bridge.log("ERROR", "Error parsing for image data.", this.clt.logUrl); this.bridge.clientlog("IMAGE_PARSE_ERROR",e.message); return null; } var tmpl = this.clt.getTmpl(); // TODO: this error handling seems odd if (typeof tmpl == 'undefined' || tmpl == null || tmpl.length == 0) { pc = ""; this.tmpl = ""; this.bridge.clientlog("TEMPLATE_UNDEFINED"); } var act = "Unknown"; if (fdcp.clt.mode == fdcp.clt.modes.filePrint) { act = "Chrome"; } else if (fdcp.clt.mode == fdcp.clt.modes.printLink || fdcp.clt.mode == fdcp.clt.modes.printerFriendlyViewer) { act = "Link"; } var robj = { d : this.clt.getDiv(), a : navigator.appName + " " + navigator.userAgent, s : this.clt.getSegment(), u : window.location.href, p : this.clt.getPFF(), r : this.clt.getRfmt(), q : "1.0", bn : FDCPLoader.browserDetect.browser, bv : FDCPLoader.browserDetect.version, template : tmpl, ci : imgs, mt: this.clt.getOutputFormat(), action: this.clt.action, args: this.clt.args, act : act, title: document.title, rp: this.clt.cpc.rpOk }; // TODO: just set it, don't check for null? if (pc != null) robj.pc = pc; // add in targeting variables var qp = this.clt.getVR(); // TODO: these should really all be packaged inside a single param. if (typeof qp != 'undefined' && qp != null) { for ( var ki in qp) { robj[ki] = qp[ki]; } } // add the template test if true if (this.clt.getTemplateTest()) robj.tt = this.clt.getTemplateTest(); this.getCpPostDataValue = robj; return robj; } this.getPCXPath = function() { // var xpathDefs = [{selection:"include", include:"inner", // occurrence:"once", target:"default", inlineDiv:false, // location:"domOrder", query:'//div[@id="myDiv"]'}]; // this.xpathDefs = this.sortXPathDefs(this.xpathDefs); var excludes = new Array(); for ( var i = 0; i < this.xpathDefs.length; i++) { var xpathDef = this.xpathDefs[i]; if (xpathDef.selection == "exclude") { var xpathXcludes = this.getXPathNodes(xpathDef); if (xpathXcludes == null) { return null; } for ( var j = 0; j < xpathXcludes.length; j++) { excludes.push(xpathXcludes[j]); } } } this.fdser.setExcludes(excludes); var pc = new Object(); var mode = new Object(); var lastChildName = ""; // loop over the xpath defs for ( var i = 0; i < this.xpathDefs.length; i++) { var xpathDef = this.xpathDefs[i]; // only process the includes if (xpathDef.selection == "include") { // use the default content group if one isn't defined if (typeof xpathDef.target == "undefined" || xpathDef.target == null || xpathDef.target == "") { xpathDef.target = "default"; } // get the set of nodes for this query var xpathNodes = this.getXPathNodes(xpathDef); // a null means that required content wasn't found. bail out. if (xpathNodes == null) { return null; } // create a content array for this target if one doesn't already // exist if ((typeof pc[xpathDef.target] == 'undefined' || pc[xpathDef.target] == null) && xpathNodes.length > 0) { pc[xpathDef.target] = new Array(); mode[xpathDef.target] = xpathDef.mode; } // loop over the returned nodes for ( var j = 0; j < xpathNodes.length; j++) { if ((lastChildName == "P" && xpathNodes[j].nodeType == 3) || (i != 0 && j == 0)) { this.fdser.newpg(pc[xpathDef.target]); } this.fdser.serializeNode(xpathNodes[j], pc[xpathDef.target], null, xpathDef.inlineDiv ? "false" : "true", xpathDef.mode); // TODO: the serializer needs to do this. call fdser.addPagebreak(array) if (xpathDef.pagebreak == 'all') pc[xpathDef.target].push(""); // TODO: the serializer needs to do this. call fdser.addLinebreak(array) if (xpathDef.linebreak == 'all') pc[xpathDef.target] .push("
"); lastChildName = xpathNodes[j].nodeName; } // TODO: the serializer needs to do this. call fdser.addPagebreak(array) if (xpathDef.pagebreak == 'last') { if (pc[xpathDef.target] != null) { pc[xpathDef.target].push(""); } } // TODO: the serializer needs to do this. call fdser.addLinebreak(array) if (xpathDef.linebreak == 'last') { if (pc[xpathDef.target] != null) { pc[xpathDef.target] .push("
"); } } } } var contentCount = 0; var finalContent = new String(""); // TODO: this needs to happen inside the serializer // wrap each node in a subcontent/paragraph pair for ( var key in pc) { finalContent += ""; for ( var i = 0; i < pc[key].length; i++) { finalContent += pc[key][i]; contentCount++; } finalContent += ""; } if (contentCount == 0) { this.bridge.clientlog("CONTENT_COUNT_IS_ZERO"); return null; } else { if (this.clt.getFDDebug()) { alert('ContentCount : [' + contentCount + ']'); } } // TODO: move this up. and then into the serializer. return "" + finalContent + ""; } this.getXPathNodes = function(xpathDef) { var context = document; var queryBase = document; if (typeof this.contextXpath != "undefined") { if (FDCPLoader.browserDetect.browser == 'Explorer') { context = document; queryBase = frames['contextFrame'].document; } else {// firefox context = this.contextXpath; queryBase = context.documentElement; } } var rv = new Array(); try { var iterator = context.evaluate(xpathDef.query, queryBase, null, XPathResult.UNORDERED_NODE_ITERATOR_TYPE, null); var thisNode = iterator.iterateNext(); if (xpathDef.occurrence == "once") { if (thisNode) { if (xpathDef.include == "outer") { rv.push(thisNode); } else if (xpathDef.include == "inner") { var children = thisNode.childNodes; var lastChildName = ""; for ( var j = 0; j < children.length; j++) { rv.push(children[j]); } } } else { // No node found for this xpath query } } else if (xpathDef.occurrence == "all") { while (thisNode) { if (xpathDef.include == "outer") { rv.push(thisNode); } else if (xpathDef.include == "inner") { var children = thisNode.childNodes; var lastChildName = ""; for ( var j = 0; j < children.length; j++) { rv.push(children[j]); } } thisNode = iterator.iterateNext(); } } } catch (e) { this.bridge.clientlog("XPATH_EXCEPTION" ,"exception message :" + e.message); return null; } if (rv.length < xpathDef.required) { if (this.clt.getFDDebug()) { alert('No content found for required xpath: ' + xpathDef.query); } this.bridge.clientlog("NO_CONTENT_FOUND_FOR_REQUIRED_XPATH" ,"xpath query: " + xpathDef.query ); return null; } return rv; } // dwilson this is not used, but kept in just in case we find out we need // location again this.sortXPathDefs = function(xpathDefs) { // add excludes, then fronts, domOrders, and backs var excludes = new Array(); var fronts = new Array(); var domOrders = new Array(); var backs = new Array(); for ( var i = 0; i < xpathDefs.length; i++) { var xpathDef = xpathDefs[i]; if (xpathDef.selection == "exclude") { excludes.push(xpathDef); } else { if (xpathDef.location == "front") { fronts.push(xpathDef); } else if (xpathDef.location == "domOrder") { domOrders.push(xpathDef); } else if (xpathDef.location == "back") { backs.push(xpathDef); } } } return excludes.concat(fronts.concat(domOrders.concat(backs))); } this.replacePrintLinks = function() { this.xpathDefs = FDCPLoader.cpDef.xpathDefs; var printLinkReplaces = new Array(); var iframeContextFound = false; for ( var i = 0; i < this.xpathDefs.length; i++) { var xpathDef = this.xpathDefs[i]; if (typeof xpathDef.context != "undefined" && xpathDef.context != "self") { iframeContextFound = true; } if (xpathDef.selection == "printlink") { var printLinkReplace = this.getXPathNodes(xpathDef); if (printLinkReplace == null) { // returning null means something unexpected happened, not // an empty this.bridge.clientlog("OTHER_UNCLASSIFIED"); return null; } for ( var j = 0; j < printLinkReplace.length; j++) { printLinkReplaces.push(printLinkReplace[j]); } } } if (!iframeContextFound && FDCPLoader.FDCPClient.cpc.preloadPF) { FDCPLoader.FDCPClient.cpc.preloadPF = false; } var iframeUrls = typeof FDCPLoader.FDCPClient.getIframeUrls == "undefined" || typeof FDCPLoader.FDCPClient.getIframeUrls() == "undefined" ? [] : FDCPLoader.FDCPClient.getIframeUrls(); if (iframeContextFound && iframeUrls.length == 1 && iframeUrls[0] == window.location.href) { // we are already at the printer friendly, so override the xpathDefs for ( var i = 0; i < this.xpathDefs.length; i++) { var xpathDef = this.xpathDefs[i]; iframeContextFound.context = "self"; } } else if (iframeContextFound && iframeUrls.length == 1 && FDCPLoader.FDCPClient.cpc.preloadPF) { // create the hidden iframe this.createContextFrame(iframeUrls[0]); } // TODO:Implement multiple iframe contexts here, by looping and naming // accordingly for ( var i = 0; i < printLinkReplaces.length; i++) { var printLinkReplaceNode = printLinkReplaces[i]; if (printLinkReplaceNode.nodeName == "A") { printLinkReplaceNode.href = "#"; printLinkReplaceNode.onclick = function() { FDCPUrl(); return false; }; } else if (printLinkReplaceNode.nodeName == "BUTTON") { printLinkReplaceNode.onclick = function() { FDCPUrl(); return false; }; } // any other node types added and handled according should go here } // run through defs and look for a context that is not self } this.contextFrameLoaded = false; this.contextFrame; this.contextXpath; this.createContextFrame = function(url) { this.contextFrame = document.createElement("iframe"); this.contextFrame.setAttribute('src', url); this.contextFrame.setAttribute('id', "contextFrame"); this.contextFrame.setAttribute('NAME', "contextFrame"); if (FDCPLoader.browserDetect.browser == "Explorer") { this.contextFrame.onreadystatechange = function() { if (fdcp.contextFrame.readyState == "complete") { fdcp.contextFrameLoaded = true; fdcp.contextXpath = frames[fdcp.contextFrame.name].document; } }; } else { this.contextFrame.onload = function() { fdcp.contextFrameLoaded = true; if (FDCPLoader.browserDetect.browser == "Firefox" && FDCPLoader.browserDetect.version == 3) { fdcp.contextXpath = fdcp.contextFrame.contentDocument; } else { fdcp.contextXpath = frames[fdcp.contextFrame.name].document; } }; } this.contextFrame.style.width = '1px'; this.contextFrame.style.height = '1px'; this.contextFrame.style.position = 'absolute'; this.contextFrame.style.top = '-3000px'; this.contextFrame.style.border = '0px'; document.body.appendChild(this.contextFrame); } this.printerFriendlyViewerTemplateLoadStart = 0; this.printerFriendlyViewerTemplatePolledOnce = false; this.printerFriendlyViewerTemplateLoadTimeout = 3 * 1000; this.printerFriendlyVieweriFrameTag = ""; this.loadPrinterFriendlyViewer = function() { if (typeof _fdCpOutput == "undefined" || _fdCpOutput == "") { // see if we keep polling, otherwise failover if (this.printerFriendlyViewerTemplatePolledOnce == false) { // if we haven't polled once yet, irregardless of timeout, give // a 1ms thread jump to see if the script has downloaded // to give it time to eval and move on this.printerFriendlyViewerTemplatePolledOnce = true; setTimeout("fdcp.loadPrinterFriendlyViewer()", 1); return; } if ((new Date()).getTime() > this.printerFriendlyViewerTemplateLoadStart + this.printerFriendlyViewerTemplateLoadTimeout) { // failover this.bridge.clientlog("VIEWER_TIME_OUT"); this.CPFailover(false); } else { // keep polling setTimeout("fdcp.loadPrinterFriendlyViewer()", 100); return; } } else { this.printerFriendlyViewerTemplatePolledOnce = false; var fdUniqueId = (new Date()).getTime() + "" + Math.floor((Math.random() * 1000000)); _fdCpOutput = _fdCpOutput.replace("\"0\";/*fdUniqueIdReplace*/", "\"" + fdUniqueId + "\";/*replaced*/"); // var printPreviewWindow = window.open("", "printPreviewWindow", // "toolbar=0,location=0,directories=0,status=0,menubar=0,resizable=0,scrollbars=no,copyhistory=yes,width=1024,height=768,left=50, // top=50,screenX=50,screenY=50"); // printPreviewWindow.document.open(); // wrap innerHTML clearing in try catch to appease webkit gods on // first open try { FDCPLoader.printPreviewWindow.document.body.innerHTML = ""; } catch (err) {/* squelch */ } if (typeof this.outputDocument == "undefined" || this.outputDocument == "") { FDCPLoader.printPreviewWindow.document.write(_fdCpOutput .replace("", this.printerFriendlyVieweriFrameTag.replace( "xxx", this.pfLink))); } else { var outputDocumentCopy = this.outputDocument; while (outputDocumentCopy.indexOf("$pageId$") != -1) { outputDocumentCopy = outputDocumentCopy.replace("$pageId$", fdUniqueId); } FDCPLoader.printPreviewWindow.document.write(_fdCpOutput .replace("", outputDocumentCopy)); } FDCPLoader.printPreviewWindow.document.close(); } } this.loadPrinterFriendlyViewerTemplateScript = function() { var advars = this.clt.getVR(); var adstr = ""; if (typeof advars != 'undefined' && advars != null) { for ( var ki in advars) { adstr += "&" + ki + "=" + advars[ki]; } } this.printerFriendlyViewerTemplateLoadStart = (new Date()).getTime() if (typeof _fdCpOutput == "undefined") { var pfvtScript = document.createElement('script'); if (adstr != "") { pfvtScript.src = "http://" + this.clt.cpHost + "/cpv/viewer?divId=" + this.clt.divid + adstr; } else { pfvtScript.src = "http://" + this.clt.cpHost + "/cpv/viewer?divId=" + this.clt.divid; } pfvtScript.type = 'text/javascript'; document.getElementsByTagName("head")[0].appendChild(pfvtScript); } } /** * serialize any targeted images */ this.getImages = function() { var images = new Array(); var finalContent = ""; if (typeof fdImages != 'undefined') { for ( var n = 0; n < fdImages.length; n++) { var img = document.getElementById(fdImages[n]); if (img != null) { this.fdser.serializeNode(img, images, false); } } for ( var i = 0; i < images.length; i++) { finalContent += images[i]; } } finalContent += ""; return finalContent; } /** * enables/disables PrintTracker. Used to prevent double-counts across both * products. */ this.enPt = function(pval) { if (typeof formatDynamicsPT != 'undefined') { for (i = 0; i < document.styleSheets.length; i++) { try { var sheet = document.styleSheets[i]; if (navigator.appName.indexOf("Microsoft") == -1 && formatDynamicsPT .isPtCss(sheet.cssRules[0].style.content)) { sheet.disabled = !pval; break; } } catch (e) { } } } } /** * CPFailover(): cleans up from a cleanprint run. If the status is false, this means a cleanprint wasn't * accomplished and we need to do a failover print. */ this.CPFailover = function(status) { // reset the link clicked flag, which will allow a subsequent link print this.linkClicked = false; if (status == false && (!FDCPLoader.FDCPClient.cpc.templateTest && FDCPLoader.FDCPClient.cpc.templateTest!=true)) { // status is false - do a failover print. If a printer friendly value was provided, take the user to it. if (this.pfLink != null) { var pfType = this.clt.getCfg('pfType', null); if (pfType == null || pfType.toLowerCase() == 'replace') { window.open(this.pfLink, "_self"); return false; // TODO: false used? } else { window.open(this.pfLink); return false; // TODO: false used? } } // do the print FDCPLoader.fdPrintWrapper(); } // fire the onaftercleanprint event this.clt.onAfterCleanPrint(); } this.loadHandler = function() { var iswin = FDCPLoader.browserDetect.browser == "Explorer" && FDCPLoader.browserDetect.OS == "Windows"; if (!this.cpEn()) { // if this is a standalone install or cleanprint is disabled, turn // on the windows // PrintTracker print handler // TODO: shouldn't we be checking the iswin value here? formatDynamicsPT.initIE(); } else { // CleanPrint is enabled -- call the bridge's load handler fdcp.bridge.loadHandler(this); } } } var fdcp = new FDCP(); // if the loader exists, then onload has already fired. call the load handler // directly. if (typeof FDCPLoader != 'undefined') { fdcp.loadHandler(); } else { // TODO: can this work with the current loader? probably get rid of it if (window.addEventListener) window.addEventListener("load", function() { fdcp.loadHandler(); }, false); else if (window.attachEvent) window.attachEvent("onload", function() { fdcp.loadHandler(); }); } FDCPLoader.registerModuleLoaded("cp.js"); // TODO: the controller needs to fire this even, I think. // always keep the following line as the last line of the file (ok if other // files appended to this one) if (typeof FDCPLoader.FDCPClient.onCpLoad == "function") { FDCPLoader.FDCPClient.onCpLoad(); } function FDSerializer(fdclient){ this.fdclient = fdclient; this._bxs = "border-style"; this._bbs = "border-bottom-style"; this._bts = "border-top-style"; this._bls = "border-left-style"; this._brs = "border-right-style"; this._bxw = "border-width"; this._bbw = "border-bottom-width"; this._btw = "border-top-width"; this._blw = "border-left-width"; this._brw = "border-right-width"; this._bxc = "border-color"; this._bbc = "border-bottom-color"; this._btc = "border-top-color"; this._blc = "border-left-color"; this._brc = "border-right-color"; this._ffam = "font-family"; this._fsiz = "font-size"; this._fwei = "font-weight"; this._fsty = "font-style"; this._fcol = "color"; this._tdec = "text-decoration"; this._bgc = "background-color"; this._bgi = "background-image"; this._bgr = "background-repeat"; this._mta = "text-align"; this._brcl = "border-collapse"; this._brsp = "border-spacing"; this._px="padding"; this._pb="padding-bottom"; this._pt="padding-top"; this._pl="padding-left"; this._pr="padding-right"; this._clear="clear"; this._float="float" this._mb="margin-bottom"; this._mt="margin-top"; this.sm = new Array(); this.sm[this._bxs] = 'borderStyle'; this.sm[this._bbs] = 'borderBottomStyle'; this.sm[this._bts] = 'borderTopStyle'; this.sm[this._bls] = 'borderLeftStyle'; this.sm[this._brs] = 'borderRightStyle'; this.sm[this._bxw] = 'borderWidth'; this.sm[this._bbw] = 'borderBottomWidth'; this.sm[this._btw] = 'borderTopWidth'; this.sm[this._blw] = 'borderLeftWidth'; this.sm[this._brw] = 'borderRightWidth'; this.sm[this._bxc] = 'borderColor'; this.sm[this._bbc] = 'borderBottomColor'; this.sm[this._btc] = 'borderTopColor'; this.sm[this._blc] = 'borderLeftColor'; this.sm[this._brc] = 'borderRightColor'; this.sm[this._ffam] = 'fontFamily'; this.sm[this._fsiz] = 'fontSize'; this.sm[this._fwei] = 'fontWeight'; this.sm[this._fsty] = 'fontStyle'; this.sm[this._fcol] = 'color'; this.sm[this._tdec] = 'textDecoration'; this.sm[this._clear]='clear'; this.sm[this._float]='float'; this.sm[this._bgc] = 'backgroundColor'; this.sm[this._bgi] = 'backgroundImage'; this.sm[this._bgr] = 'backgroundRepeat'; this.sm[this._mta] = 'textAlign'; this.sm[this._brcl] = 'borderCollapse'; this.sm[this._brsp] = 'borderSpacing'; this.sm[this._px]="padding"; this.sm[this._pb]="paddingBottom"; this.sm[this._pt]="paddingTop"; this.sm[this._pl]="paddingLeft"; this.sm[this._pr]="paddingRight"; this.sm[this._mb]="marginBottom"; this.sm[this._mt]="marginTop"; this.sz = new Array(); this.sz['xx-small'] = '8pt'; this.sz['x-small'] = '10pt'; this.sz['small'] = '12pt'; this.sz['medium'] = '14pt'; this.sz['large'] = '18pt'; this.sz['x-large'] = '24pt'; this.sz['xx-large'] = '35pt'; this.sz['auto'] = '10pt'; //this.ftre = new RegExp("^\\d+$"); this.ftsz = new Array(); this.ftsz[1] = '10px'; this.ftsz[2] = '12px'; this.ftsz[3] = '14px'; this.ftsz[4] = '18px'; this.ftsz[5] = '24px'; this.ftsz[6] = '30px'; this.ftsz[7] = '48px'; this._widestblkwidth =0; this.excludesXpath = new Array(); this.text_only_state = { off: 0, on: 1, once: 2 }; this.getHeadingLevel = function(value){ if(value == "H1"){return "24pt";} else if(value == "H2"){return "18pt";} else if(value == "H3"){return "14pt";} else if(value == "H4"){return "12pt";} else if(value == "H5"){return "10pt";} else if(value == "H6"){return "8pt";} else return "12pt"; } this.translateStyle = function(skey){ if(skey == 'float'){ if(FDCPLoader.browserDetect.browser == 'Explorer'){ return 'styleFloat'; } else{ return 'cssFloat'; } } var v = this.sm[skey]; if(v){ return v; } return skey; } this.isMT = function(val){ return val == null || typeof val == 'undefined' || val == ""; } this.isRelFont = function(sz) { return sz.indexOf("%") > 0 || sz.indexOf("em") > 0 || sz.indexOf("ex") > 0; } this.getStyleValue = function(node, value, useEl){ var nvalue = this.translateStyle(value); if(typeof useEl != 'undefined' && useEl == true) { if(node.style[nvalue].length > 0){ return node.style[nvalue]; } else{ return null; } } if(value == 'width' && node.offsetWidth) { var pleft = this.getStyleValue(node, this._pl); var pright = this.getStyleValue(node, this._pr); var local_width = node.offsetWidth; if(pleft.indexOf('px') != -1) local_width -= pleft.substring(0, pleft.length - 2); if(pright.indexOf('px') != -1) local_width -= pright.substring(0, pright.length - 2); return local_width; } if(value=='height'&& (typeof node.offsetHeight != 'undefined' && node.offsetHeight != null)) { if(FDCPLoader.browserDetect.browser == "Firefox" && FDCPLoader.browserDetect.version == 2 && node.nodeName == "SPAN"){ var childrenTotalHeight = typeof node.offsetHeight != 'undefined' && node.offsetHeight != null ? node.offsetHeight : 0; for(var i = 0; i < node.childNodes.length; i++){ if(node.childNodes[i].nodeType != 3){//text nodes are already part of the span's offset height if first child childrenTotalHeight += this.getStyleValue(node.childNodes[i], "height"); } } return childrenTotalHeight; } else if(node.offsetHeight == 0) { if(node.childNodes.length == 1 ) { if(typeof this.getStyleValue(node.childNodes[0], 'float') != 'undefined' && this.getStyleValue(node.childNodes[0], 'float') != null){ var floatstyle = this.getStyleValue(node.childNodes[0], 'float'); var childHeight =0; if(floatstyle == "left"){ childHeight = this.getStyleValue(node.childNodes[0], "height"); return childHeight; } } } return node.offsetHeight; } else { var local_height = node.offsetHeight; if(node.nodeName == "DIV" || node.nodeName == "TD" || node.nodeName == "TH" || node.nodeName.match(/^H\d$/) != null) { var ptop = this.getStyleValue(node, this._pt); var pbot = this.getStyleValue(node, this._pb); // todo: needs to be expanded for other length measures if(ptop.indexOf('px') != -1) local_height -= ptop.substring(0, ptop.length - 2); if(pbot.indexOf('px') != -1) local_height -= pbot.substring(0, pbot.length - 2); } return local_height; } return node.offsetHeight; } if(node.currentStyle && FDCPLoader.browserDetect.browser == 'Explorer') { var svalue = node.currentStyle[nvalue]; // in explorer, if a font size is an integer without a length // unit, that means it came from a ... // so convert it to a pixel length if(value == this._fsiz && svalue.match(/^\d+$/) != null) { if(svalue < 1) svalue = 1; else if(svalue > 7) svalue = 7; svalue = this.ftsz[svalue]; } return svalue; } else{ try{ var cstyle = document.defaultView.getComputedStyle(node, ''); var ret = cstyle[nvalue]; //cstyle.getPropertyValue(nvalue); return ret; }catch(e){ // some values shouldn't be inherited from the parent if(value != this._float) { try{ var cstyle = document.defaultView.getComputedStyle(node.parentNode, ''); var ret = cstyle[nvalue]; //cstyle.getPropertyValue(nvalue); return ret; }catch(e2){ var retval = node.parentNode.currentStyle[nvalue]; if(FDCPLoader.browserDetect.browser == 'Explorer' && value == this._fsiz && retval.match(/^\d+$/) != null) { retval = this.getIeFtSz(retval) } return retval; } } else return null; } } } // return the pixel value for a font size set with in IE this.getIeFtSz = function(svalue) { if(svalue < 1) svalue = 1; else if(svalue > 7) svalue = 7; return this.ftsz[svalue]; } this.getBorderStyles = function(node){ var bxs,bbs,bts,bls,brs; var bxw,bbw,btw,blw,brw; var bxc,bbc,btc,blc,brc; bxs = this.getStyleValue(node, this._bxs); bbs = this.getStyleValue(node, this._bbs); bts = this.getStyleValue(node, this._bts); bls = this.getStyleValue(node, this._bls); brs = this.getStyleValue(node, this._brs); var bsin = bbs || bts || bls || brs; if(!bxs && !bsin){ return ""; } var retStyle = ""; if(bsin && !(bbs == bts && bts == bls && bls == brs)) { if(bbs && bbs!=null && bbs.length > 0){ retStyle += this._bbs + ":" + bbs + ";";} if(bts && bts!=null && bts.length > 0){ retStyle += this._bts + ":" + bts + ";";} if(bls && bls!=null && bls.length > 0){ retStyle += this._bls + ":" + bls + ";";} if(brs && brs!=null && brs.length > 0){ retStyle += this._brs + ":" + brs + ";";} } else if(bsin == 'none'){ return ""; } else if(bsin && (bbs == bts && bts == bls && bls == brs)){ retStyle += this._bxs + ":" + bbs + ";"; } else if(bxs && bxs!=null && bxs.length > 0) { retStyle += this._bxs + ":" + bxs + ";"; } bxw = this.getStyleValue(node,this._bxw); bbw = this.getStyleValue(node,this._bbw); btw = this.getStyleValue(node,this._btw); blw = this.getStyleValue(node,this._blw); brw = this.getStyleValue(node,this._brw); var bwin = bbw || btw || blw || brw; bxc = this.getStyleValue(node,this._bxc); bbc = this.getStyleValue(node,this._bbc); btc = this.getStyleValue(node,this._btc); blc = this.getStyleValue(node,this._blc); brc = this.getStyleValue(node,this._brc); var bcin = bbc || btc || blc || brc; if(bwin && !(bbw == btw && btw == blw && blw == brw)){ if(bbw && bbw!=null && bbw.length > 0){ retStyle += this._bbw + ":" + bbw + ";";} if(btw && btw!=null && btw.length > 0){ retStyle += this._btw + ":" + btw + ";";} if(blw && blw!=null && blw.length > 0){ retStyle += this._blw + ":" + blw + ";";} if(brw && brw!=null && brw.length > 0){ retStyle += this._brw + ":" + brw + ";";} } else if(bwin && (bbw == btw && btw == blw && blw == brw)){ retStyle += this._bxw + ":" + bbw + ";"; } else if(bxw && bxw!=null && bxw.length > 0){ retStyle += this._bxw + ":" + bxw + ";"; } if(bcin && !(bbc == btc && btc == blc && blc == brc)){ if(bbc && bbc!=null && bbc.length > 0){ retStyle += this._bbc + ":" + bbc + ";";} if(btc && btc!=null && btc.length > 0){ retStyle += this._btc + ":" + btc + ";";} if(blc && blc!=null && blc.length > 0){ retStyle += this._blc + ":" + blc + ";";} if(brc && brc!=null && brc.length > 0){ retStyle += this._brc + ":" + brc + ";";} } else if(bcin && (bbc == btc && btc == blc && blc == brc)){ retStyle += this._bxc + ":" + bbc + ";"; } else if(bxc && bxc!=null && bxc.length > 0){ retStyle += this._bxc + ":" + bxc + ";"; } return retStyle; } this.getPaddingStyle = function(node) { var px,pb,pt,pl,pr; px = this.getStyleValue(node, this._px); pb = this.getStyleValue(node, this._pb); pt = this.getStyleValue(node, this._pt); pl = this.getStyleValue(node, this._pl); pr = this.getStyleValue(node, this._pr); var bsin = pb || pt || pl || pr; if(!px && !bsin){ return ""; } var retStyle = ""; if(bsin && !(pb == pt && pt == pl && pl == pr)) { if(pb && pb !=null && pb.length > 0){ retStyle += this._pb + ":" + pb + ";";} if(pt && pt !=null && pt.length > 0){ retStyle += this._pt + ":" + pt + ";";} if(pl && pl !=null && pl.length > 0){ retStyle += this._pl + ":" + pl + ";";} if(pr && pr !=null && pr.length > 0){ retStyle += this._pr + ":" + pr + ";";} } else if(bsin == 'none'){ return ""; } else if(bsin && (pb == pt && pt == pl && pl == pr)){ retStyle += this._px + ":" + pb + ";"; } else if(px && px != null && px.length > 0) { retStyle += this._px + ":" + px + ";"; } return retStyle; } this.getMultiplier = function(str) { if(str.indexOf("%") > 0){ var num = str.substring(0, str.indexOf("%")); return num / 100; } if(str.indexOf("em") > 0){ var num = str.substring(0, str.indexOf("em")); return num; } if(str.indexOf("ex") > 0){ var num = str.substring(0, str.indexOf("ex")); return num * .4; } } /** * calculateFontSize: takes a node with a relative font size on it, and walks up the hierarchy and * eventually resolving it to an absolute length. */ this.calculateFontSize = function(node){ var multipliers = new Array(); var unit; var size; multipliers.push(this.getStyleValue(node, "font-size")); node = node.parentNode; while(node != null){ if(node.nodeType == 3){ node = node.parentNode; continue; } // try to get an inline style first and if that is null, look for an applied/inherited style if((size = this.getStyleValue(node, "font-size", true)) == null) size = this.getStyleValue(node, "font-size"); // if we're at the body, always find a way to get an absolute size, defaulting to 12pt if necessary if(node.nodeName=="BODY") { if(size == null) { size = "12pt"; } else if(size.indexOf("%") != -1) { var strippedSize = size.substring(0,size.length - 1); size = 12 * (strippedSize / 100); size = size + "pt"; } break; } else if(size != null) { if(this.isRelFont(size)) { if(size != multipliers[multipliers.length-1]) multipliers.push(size); } else { break; } } node=node.parentNode; } if(this.sz[size] != null){ size = this.sz[size]; } unit = size.substring(size.length - 2); size = size.substring(0, size.length - 2); for(var i = 0; i < multipliers.length; i++){ size = size * this.getMultiplier(multipliers[i]); } return Math.round(size) + unit; } this.getImageStyle = function(node, dataMode) { var width = node.width; var height = node.height; if(!width){ width = this.getStyleValue(node, "width"); } if(!height){ height = this.getStyleValue(node, "height"); } var retStr = "style=\"" + 'width:' + width + ';height:' + height + ';'; if(dataMode == false) { var borderInfo = this.getBorderStyles(node); if(typeof this.getStyleValue(node, 'float') != 'undefined' && this.getStyleValue(node, 'float') != null){ retStr += 'float:' + this.getStyleValue(node, 'float') + ';'; } if(borderInfo){ retStr += borderInfo; } } retStr += "\""; return retStr; } // tableCellpadding will exist while inside a table tag, and will // contain the cellpadding value from the parent table. It should // be undefined or null otherwise this.getNodeStyle = function(node, blk, tableCellpadding){ var retStyle = "style=\""; var f_fam = this.getStyleValue(node, this._ffam); var f_siz = this.getStyleValue(node, this._fsiz); var f_wei = this.getStyleValue(node, this._fwei); var t_dec = this.getStyleValue(node, this._tdec); if(FDCPLoader.browserDetect.browser == "Firefox"){ var adjustedWeight = parseInt(f_wei); if(typeof adjustedWeight != "undefined" && !isNaN(adjustedWeight) && adjustedWeight == 401){ f_wei = 700; } } var f_sty = this.getStyleValue(node, this._fsty); var color = this.getStyleValue(node, this._fcol); var reg = new RegExp('MS Sans Serif', 'i'); f_fam = f_fam.replace(reg, 'sans-serif'); if(f_fam.indexOf('"')>=0){ f_fam = f_fam.replace(/\"/g,""); } if(f_fam.indexOf('\'')>=0){ f_fam = f_fam.replace(/\'/g,""); } if(this.isRelFont(f_siz)){ f_siz = this.calculateFontSize(node); } // start with text styles retStyle += this._ffam + ':' + f_fam + ';' + this._fsiz + ':' + f_siz + ';' + this._fwei + ':' + f_wei + ';' + this._fsty + ':' + f_sty + ';' + this._fcol + ':' + color + ';' + (t_dec == "none" ? "" : this._tdec + ':' + t_dec + ';'); if(blk){ var use_inline_width_height = false; if(node.nodeName == "SPAN"){ // apai: 9/22/2008 // firefox reports offset heights and widths for spans if they have a // float value of left or right, otherwise the widths and heights are // reported as zero. If the node is a span and has a float style, go // ahead and use the offset height/width, otherwise look for the height // and width in the node's style object var f = this.getStyleValue(node, 'float'); if(typeof f == 'undefined' || f == null && (f != 'right' && f != 'left')){ use_inline_width_height = true; } } var width = this.getStyleValue(node,"width", use_inline_width_height); var height= this.getStyleValue(node,"height", use_inline_width_height); var borderInfo = this.getBorderStyles(node); var paddingInfo = this.getPaddingStyle(node); var textAlign = this.getStyleValue(node,this._mta); var bgColor = this.getStyleValue(node,this._bgc); var bgImg = this.getStyleValue(node,this._bgi).replace(/\"/g, "'"); var bgRpt = this.getStyleValue(node,this._bgr); var clear = this.getStyleValue(node,this._clear); var floatstyle = this.getStyleValue(node,this._float); var b_bw = this.getStyleValue(node, this._bbw); var b_tw = this.getStyleValue(node, this._btw); var b_lw = this.getStyleValue(node, this._blw); var b_rw = this.getStyleValue(node, this._brw); var cf = f_siz .substring(0, f_siz .length - 2); if(this.isRelFont(b_bw)){ b_bw = b_bw.substring(0, b_bw.length - 2); b_bw = b_bw * cf ; b_bw = b_bw + "px"; } if(this.isRelFont(b_tw)){ b_tw = b_tw.substring(0, b_tw.length - 2); b_tw = b_tw * cf ; b_tw = b_tw + "px"; } if(this.isRelFont(b_lw)){ b_lw = b_lw.substring(0, b_lw.length - 2); b_lw = b_lw * cf ; b_lw = b_lw + "px"; } if(this.isRelFont(b_rw)){ b_rw = b_rw.substring(0, b_rw.length - 2); b_rw = b_rw * cf ; b_rw = b_rw + "px"; } if(b_bw !=null){ retStyle += this._bbw + ":" + b_bw + ";"; } if(b_tw !=null){ retStyle += this._btw + ":" + b_tw + ";"; } if(b_lw !=null){ retStyle+= this._blw + ":" + b_lw + ";"; } if(b_rw !=null){ retStyle += this._brw + ":" + b_rw + ";"; } retStyle += this._clear + ':' + clear + ';' + (floatstyle == 'left' || floatstyle == 'right' ? (this._float + ':' + floatstyle + ';') : ""); retStyle += borderInfo + paddingInfo; if(width != null && width != 'auto' && width != "0auto"){ retStyle += "width: " + width + ";";} if(height != null && height != 'auto' && height != "0auto") { if(tableCellpadding && tableCellpadding > 0 && (node.nodeName == 'TD' || node.nodeName == 'TH')) height -= tableCellpadding; retStyle += "height: " + height + ";"; } var mt = this.getStyleValue(node,this._mt); var mb = this.getStyleValue(node,this._mb); if( mt != 'auto') { if((node.nodeName == 'LI' && mt.charAt(0) != "0") || (node.nodeName != 'LI' && (mt.charAt(0)=="0" || mt.charAt(0)=="-"||node.nodeName == 'P' || node.nodeName == 'UL' || node.nodeName == 'OL'))) retStyle += this._mt + ":" + mt + ";"; } if( mb != 'auto') { if((node.nodeName == 'LI' && mb.charAt(0) != "0") || (node.nodeName != 'LI' && (mb.charAt(0)=="0" || mb.charAt(0)=="-" || node.nodeName == 'UL' || node.nodeName == 'OL'))) retStyle += this._mb + ":" + mb + ";"; } if(node.nodeName == "UL" || node.nodeName == "OL" || node.nodeName == "LI"){ var lnHeight = this.getStyleValue(node,"lineHeight"); if(lnHeight != 'auto') { retStyle += "line-height:" + lnHeight + ";"; } else { retStyle += "line-height: 1.2;"; } if(node.nodeName == "UL" || node.nodeName == "OL" || node.nodeName == "LI"){ var listStyType = ""; if (node.currentStyle){ listStyType = node.currentStyle["listStyleType"]; retStyle += "list-style-type:" + listStyType + ";"; } else if (window.getComputedStyle){ listStyType = document.defaultView.getComputedStyle(node,null).getPropertyValue("list-style-type"); retStyle += "list-style-type:" + listStyType + ";"; } } } else{ var lnHeight = this.getStyleValue(node,"lineHeight"); if(lnHeight != 'auto') { retStyle += "line-height:" + lnHeight + ";"; } } if(bgColor != 'transparent'){ retStyle += this._bgc + ':' + bgColor + ";";} if(bgImg != 'none'){ if (FDCPLoader.browserDetect.browser == "Firefox"){ var temp = bgImg.replace("url(", "url('"); var temp2 = temp.replace(")", "')"); bgImg = temp2; retStyle += this._bgi + ':' + bgImg + ";"; } else{ retStyle += this._bgi + ':' + bgImg + ";"; } } if(bgRpt != 'repeat'){ retStyle += this._bgr + ':' + bgRpt + ";";} retStyle += this._mta + ':' + textAlign + ";"; if(node.nodeName == 'TABLE'){ var v = this.getStyleValue(node, this._brcl); if(!this.isMT(v)){ retStyle += this._brcl + ':' + v + ';'; } v = this.getStyleValue(node, this._brsp); if(!this.isMT(v)){ retStyle += this._brsp + ':' + v + ';'; } } } return retStyle + "\""; } this.serializeText = function(node,mode){ var st = node.nodeValue; if(st && st.replace(/[\r\n]/g, "").match(/^\t*$/)==null){ st = ""; if(mode != 'data'){ var st = " " + this.getNodeStyle(node, false); if(node.nodeValue == "<"){ node.nodeValue = "<"; } if(node.nodeValue == ">"){ node.nodeValue = ">"; } } return "" + C2E(node.nodeValue) + ""; } return ""; } function C2E(str){ var acc = ''; for(var i = 0; i < str.length; i++){ if (str.charCodeAt(i) > 31 && str.charCodeAt(i) < 127){ acc += str.charAt(i); } else{ acc += '&#' + str.charCodeAt(i) + ';'; } } acc = acc.replace(/&/g, '&'); acc = acc.replace(/'/g, '''); acc = acc.replace(/"/g, '"'); acc = acc.replace(/\\/g, '\'); acc = acc.replace(/\+/g, '+'); acc = acc.replace(/[<]/g, '<'); acc = acc.replace(/[>]/g, '>'); return acc; } this.serializeCDATA = function(node){ return ""; } this.serializeBR = function(node,mode){ return "<" + node.nodeName + " />"; } this.serializeAnchor = function(node,mode){ var retStr = ""; var hr; if(typeof node.href != 'undefined' && node.href != null && node.href.length > 0){ hr = node.href; } else{ hr = node.getAttribute('href'); } if(hr == null || hr.length == 0 || hr.indexOf("javascript")==0){ return ""; } // Only serialize anchor elements wrapping text for(var i=0; i"; //this._serNode(node.nextSibling, contentList, this.text_only_state.on, mode); //retStr += ""; return retStr; } this.serializeImage = function(node, mode){ var retStr; var st = ""; st = this.getImageStyle(node, mode == 'data'); var src = node.getAttribute("src"); var alt = node.getAttribute("alt"); var align = node.getAttribute("align"); var nodeDoc = node.ownerDocument; if(src.indexOf("http") == 0){ } // image path starts at domain root else if(src.charAt(0) == '/'){ var url = nodeDoc.URL; var regx = new RegExp('^http(?:s)?://[^\/]*'); var res = regx.exec(url); var base = res[0]; src = base + src; } // image path starts at last folder in page URL else{ var url = nodeDoc.URL; var regx = new RegExp('^http(?:s)?://[^?]*'); var res = regx.exec(url); var base = res[0]; base = base.substring(0, base.lastIndexOf("/")); src = base + '/' + src; } retStr = " 0){ retStr += "alt='" + C2E(alt) + "' "; } retStr += "/>"; return retStr; } this.serializeParagraph = function(node){ return this.serializeBR(node); } this.serializeGoogleImage=function(node){ var retStr; retStr = ""; }else{ return retStr+" style=' "+ st + " ' " + " src=' "+C2E(i.src)+ " ' />"; } } this.serializeGoogleMapElement=function(node, txtOnly){ var retStr = ""; if(node.nodeName=="SCRIPT"){ return retStr; } var to = txtOnly; if(txtOnly==this.text_only_state.once){ to=this.text_only_state.off; } if(node.nodeName.charAt(0)=="/"){ return retStr; } if(txtOnly==this.text_only_state.off&&node.nodeName!=""){ retStr="<"+node.nodeName+" "; if(node.id){ retStr+="id=\""+node.id+"\" "; } if(node.className){ retStr+="class=\""+node.className+"\" "; } if(node.nodeName=="TABLE"){ if(!this.isMT(node.border)){ retStr+="border=\""+node.border+"\" "; } if(!this.isMT(node.cellPadding)){ retStr+="cellpadding=\""+node.cellPadding+"\" "; } if(!this.isMT(node.cellSpacing)){ retStr+="cellspacing=\""+node.cellSpacing+"\" "; } }else{ if(node.nodeName=="TD"){ if(!this.isMT(node.colSpan)){ retStr+="colspan=\""+node.colSpan+"\" "; } if(!this.isMT(node.rowSpan)){ retStr+="rowspan=\""+node.rowSpan+"\" "; } if(!this.isMT(node.noWrap)){ retStr+="nowrap=\""+node.noWrap+"\" "; } if(!this.isMT(node.vAlign)){ retStr+="valign=\""+node.vAlign+"\" "; } } } var width=this.getStyleValue(node,"width"); var height=this.getStyleValue(node,"height"); var dimensions=""; if(width != null && width != 'auto' && width != "0auto"){ dimensions += "width: " + width + ";";} if(height != null && height != 'auto' && height != "0auto"){ dimensions += "height: " + height + ";";} if(node.style.cssText !=null ){ if(node.nodeName == "SPAN"){ if(node.className == "gmnoprint"){ retStr+="style=\"" + "position:absolute;height:30px;width:62px;-moz-user-select: none; position: absolute; left: 2px; bottom: 2px;"+"\" >"; }else{ retStr += this.getNodeStyle(node, true) + ">"; } }else if(node.id == "mapcontainer"){ retStr+="style=\"" + "position:relative;"+dimensions; var f = this.getStyleValue(node, 'float'); if(f == 'left' || f == 'right') retStr += 'float:' + f + ';">'; }else{ if(FDCPLoader.browserDetect.browser == 'Explorer'){ var width = node.currentStyle["width"]; if(width == "100%"){ var newwidth = node.parentNode.currentStyle["width"]; node.style.width = newwidth; } var height = node.currentStyle["height"]; if(height == "100%"){ var newheight = node.parentNode.currentStyle["height"]; node.style.height = newheight; } var cstyle = ""; if(node.currentStyle["top"] != "auto"){ node.style.top = node.currentStyle["top"]; } if(node.currentStyle["left"] != "auto"){ node.style.left = node.currentStyle["left"]; } if(node.currentStyle["position"] != "auto"){ node.style.position = node.currentStyle["position"]; } if(node.currentStyle["z-index"] != "auto"){ node.style.zindex = node.currentStyle["zindex"]; } retStr+="style=\"" + dimensions + node.style.cssText + "; " + "\" >"; //retStr+="style=\"" + node.style.cssText + ";" + "\" >"; }else{ if(document.defaultView.getComputedStyle(node,null).getPropertyValue('z-index') != "auto"){ node.style.zindex = document.defaultView.getComputedStyle(node,null).getPropertyValue('z-index'); } if(document.defaultView.getComputedStyle(node,null).getPropertyValue('position') != "auto"){ node.style.position = document.defaultView.getComputedStyle(node,null).getPropertyValue('position'); } if(document.defaultView.getComputedStyle(node,null).getPropertyValue('top') != "auto"){ node.style.top = document.defaultView.getComputedStyle(node,null).getPropertyValue('top'); } if(document.defaultView.getComputedStyle(node,null).getPropertyValue('left') != "auto"){ node.style.left = document.defaultView.getComputedStyle(node,null).getPropertyValue('left'); } if(node.getAttribute("style") != null){ retStr+="style=\"" +node.getAttribute("style") + dimensions + node.style.cssText + "; " +"\" >"; }else{ retStr+="style=\"" + dimensions + node.style.cssText + "; " +"\" >"; } } //retStr+="style=\"" +node.getAttribute("style") + dimensions +"\" >"; } }else{ retStr += this.getNodeStyle(node, true) + ">"; } } for(var i=0;i"; } return retStr; }; // tableCellpadding will exist while inside a table tag, and will // contain the cellpadding value from the parent table. It should // be undefined or null otherwise this.serializeInlineElement = function(node, txtOnly, tableCellpadding, mode){ if(typeof tableCellpadding == 'undefined') tableCellpadding = null; var retStr = ""; if(node.nodeName == 'SCRIPT'){ return retStr; } var height = this.getStyleValue(node, "height"); /* to do : Check with J to ensure this change is fine */ /* if(typeof height == "undefined" || height == null || height == 0 && (node.nodeName == 'DIV' || node.nodeName == 'TABLE')){ return retStr; }*/ var to = txtOnly; if(txtOnly == this.text_only_state.once){ to = this.text_only_state.off; } if(node.nodeName.charAt(0) == '/'){ return retStr; } /* tracking the widest block element */ if(parseInt(this.getStyleValue(node, "width")) >= 500){ var widthStr = this.getStyleValue(node, "width") ; if(parseInt(widthStr) > this.getWidestBlkWidth()){ this.setWidestBlkWidth(widthStr); } } if(txtOnly == this.text_only_state.off && node.nodeName != ''){ if(node.nodeName == "LI"){ if(node.parentNode != null && node.parentNode.nodeName != "UL" && node.parentNode.nodeName != "OL"){ retStr += "
    "; } } retStr += "<" + node.nodeName; if(node.id){ retStr += " id=\"" + node.id + "\""; } if(node.type){ retStr += " type=\"" + node.type+ "\""; } if(node.className){ retStr += " class=\"" + node.className+ "\""; } if(node.checked){ retStr += " checked=\"" + node.checked+ "\""; } if(mode != 'data'){ if(node.nodeName == 'TABLE'){ if(!this.isMT(node.border)){ retStr += ' border="' + node.border + '"'; } if(!this.isMT(node.cellPadding)){ retStr += ' cellpadding="' + node.cellPadding + '"'; tableCellpadding = node.cellPadding; } if(!this.isMT(node.cellSpacing)){ retStr += ' cellspacing="' + node.cellSpacing + '"'; } } else if(node.nodeName == 'TD'){ if(!this.isMT(node.colSpan)){ retStr += ' colspan="' + node.colSpan + '"'; } if(!this.isMT(node.rowSpan)){ retStr += ' rowspan="' + node.rowSpan + '"'; } if(!this.isMT(node.noWrap)){ retStr += ' nowrap="' + node.noWrap + '"'; } if(!this.isMT(node.vAlign)){ retStr+=" valign=\""+node.vAlign+"\""; } } retStr += " " + this.getNodeStyle(node, true, tableCellpadding); } retStr += ">"; } for(var i=0; i < node.childNodes.length; i++){ var childNode = node.childNodes[i]; if(this.isExcluded(childNode)){ continue; } if(childNode.nodeName=='DIV' && (childNode.id=='mapcontainer' || childNode.id == 'nearby_map')){ retStr+=this.serializeGoogleMapElement(childNode,to); }else{ if(this.getStyleValue(childNode, "display") == "none"){ continue; } if(childNode.nodeType == 3){ retStr += this.serializeText(childNode, mode); } else if(childNode.nodeType == 4){ retStr += this.serializeCDATA(childNode); } else if(childNode.nodeType == 1){ if(childNode.nodeName == 'BR'){ retStr += this.serializeBR(childNode, mode); } else if(childNode.nodeName == 'P'){ /* change to serialize p tags */ retStr += this.serializeInlineElement(childNode, to, undefined, mode); } else if(childNode.nodeName.match(/^H\d$/) != null){ retStr += this.serializeInlineElement(childNode, to, undefined, mode); } else if(childNode.nodeName == 'IMG' || node.nodeName == "IMAGE" || (childNode.nodeName == "INPUT" && childNode.type == "image")){ retStr += this.serializeImage(childNode, mode); } // else if(node.nodeName == "A"){ // if(txtOnly==this.text_only_state.off && node.getAttribute('href')){ // retStr += this.serializeAnchor(node, mode); // } // } else{ retStr += this.serializeInlineElement(childNode, to, tableCellpadding, mode); } } } } if(txtOnly == this.text_only_state.off && node.nodeName != '' ){ retStr += ""; if(node.nodeName == "LI"){ if(node.parentNode != null && node.parentNode.nodeName != "UL" && node.parentNode.nodeName != "OL"){ retStr += "
"; } } } return retStr; } this.newpg = function(contentList){ if(contentList.length > 0 && contentList[contentList.length-1] != ""){ contentList.push(""); } } this._serNode = function(node,contentList,txtOnly,mode){ var v; var is_h = false; if(this.isExcluded(node)){ return; } if(this.getStyleValue(node, "display") == "none") { return; } var height = this.getStyleValue(node, "height"); //|| node.nodeName == "P" if((typeof height == "undefined" || height == null || height == 0) && !(node.nodeName == "BR" || node.nodeName == "OL" || node.nodeName == "UL")){ return; } if(typeof txtOnly == 'undefined' || txtOnly == null){ txtOnly = this.text_only_state.off; } if(node.nodeType == 3){ v = this.serializeText(node,mode); if(v != null && v.length > 0){ contentList.push(v);} }else if(node.nodeType == 4){ contentList.push(this.serializeCDATA(node)); }else if(node.nodeType == 1){ if(node.nodeName=="SCRIPT"){ return; } if(node.nodeName == 'BR'){ contentList.push(this.serializeBR(node,mode)); }else if(node.nodeName == "IMG" || node.nodeName == "IMAGE" || (node.nodeName == "INPUT" && node.type == "image")){ contentList.push(this.serializeImage(node, mode)); }else{ if(node.nodeName == "P"){ if(contentList.length > 0){ this.newpg(contentList); } } else if(node.nodeName == "A"){ if(node.getAttribute('href')){ contentList.push(this.serializeAnchor(node, mode)); } } else if(node.nodeName == "TR"){ this.newpg(contentList); } else if(node.nodeName.match(/^H\d$/) != null){ is_h = true; this.newpg(contentList); } var width = node.offsetWidth; var doinline = new Boolean(true); var twidth = this.fdclient.getBlockThreshold(); if((typeof width != 'undefined' && width != null && width > twidth) || txtOnly > 0){ doinline = false; } if(((node.nodeName == 'DIV' && doinline) || node.nodeName == 'TABLE' && txtOnly != this.text_only_state.on) || node.nodeName == 'UL' || node.nodeName == 'OL' || node.nodeName == 'LI' || node.nodeName == 'BLOCKQUOTE'){ if(node.nodeName == 'UL' || node.nodeName == 'LI' || node.nodeName == 'OL'){ txtOnly = 0; } /* Google maps */ if(node.nodeName=='DIV' && (node.id=='mapcontainer' || node.id == 'nearby_map')){ contentList.push(this.serializeGoogleMapElement(node,txtOnly)); }else{ contentList.push(this.serializeInlineElement(node,txtOnly,undefined,mode)); } } else{ try{ if(node.nodeName == 'SPAN'){ // check for the span inline div if(node.getAttribute('inlineDiv') == "true"){ // throw away the span node var child = node.firstChild; // serialize it contentList.push(this.serializeInlineElement(child,txtOnly, undefined, mode)); } else if(node.getAttribute('inlineDiv') == "false"){ this.newpg(contentList); this._serNode(node.nextSibling, contentList, this.text_only_state.on, mode); } else if(node.getAttribute('formatdynamics') == "content"){ for(var m = node.firstChild; m != null; m = m.nextSibling){ this._serNode(m, contentList, this.text_only_state.off, mode); } } else{ for(var m = node.firstChild; m != null; m = m.nextSibling){ this._serNode(m, contentList, this.text_only_state.off, mode); } } } else{ if(node.nodeName == "DIV"){ if(contentList.length > 0){ this.newpg(contentList); } } for(var m = node.firstChild; m != null; m = m.nextSibling){ this._serNode(m, contentList, txtOnly, mode); } if(node.nodeName=="P"){ this.newpg(contentList); } else if(node.nodeName=="A"){ var closeA = true; for(var i=0; i"); } } }catch(e){ for(var m = node.firstChild; m != null; m = m.nextSibling){ this._serNode(m, contentList, this.text_only_state.once, mode); } } } if(is_h){ this.newpg(contentList); } } } } this.serializeNode = function(node, contentList, processed, textOnly, mode){ var tOnly = this.text_only_state.off; if(textOnly == 'true'){ tOnly = this.text_only_state.on; } this._serNode(node, contentList, tOnly, mode); } this.isExcluded = function(node){ //xpaths exclude test for(var i = 0; i < this.excludesXpath.length; i++){ if(node == this.excludesXpath[i]){ return true; } } //excludes test var excludes = this.fdclient.getCfg('excludes'); if(typeof excludes == 'undefined' || excludes == null){ return false; } var nodeName = ""; var className = ""; var id = ""; if(typeof node.nodeName != 'undefined' && node.nodeName != null){ nodeName = node.nodeName.toLowerCase(); } if(typeof node.className != 'undefined' && node.className != null){ className = node.className.toLowerCase(); } if(typeof node.id != 'undefined' && node.id != null){ id = node.id.toLowerCase(); } for(var i = 0; i < excludes.length; i++){ var e = excludes[i].toLowerCase(); var class_list = className.split(/\s+/); for(var cl in class_list){ // match on class only if(class_list[cl] == e || ('.' + class_list[cl]) == e){ return true; } if((nodeName + "." + class_list[cl]) == e){ return true; } if(id == e || ('#' + id) == e){ return true; } if((nodeName + "." + id) == e || (nodeName + "#" + id) == e){ return true; } } } return false; } this.setExcludes = function(_excludes){ this.excludesXpath = _excludes; } this.getWidestBlkWidth = function(){ return this._widestblkwidth; } this.setWidestBlkWidth = function(blkwidth){ this._widestblkwidth = blkwidth; } /* * topNodes - array of elements that will be fully serialized * ignoreClasses - array of string names of classed elements that will be thrown out, along with all descendants */ this.fullClientSerialize = function(topNodes, ignoreClasses){ ignoreClasses = typeof ignoreClasses == "undefined" ? new Array() : ignoreClasses; var clonedMap = new Array(); for(var i = 0; i < topNodes.length; i++){ var topNodeClone = topNodes[i].cloneNode(false); clonedMap.push(this.recurseMap(topNodes[i], topNodeClone, ignoreClasses)); } var rv = ""; for(var i = 0; i < clonedMap.length; i++){ rv += clonedMap[i].innerHTML; } //vml replacements for(var x in this.serializedVmlReplacements){ rv = rv.replace(x, this.serializedVmlReplacements[x]); } return rv; } this.recurseMap = function(topNode, nodeClone, ignoreClasses){ if(typeof topNode.childNodes != "undefined" && topNode.childNodes.length > 0){ for(var i = 0; i < topNode.childNodes.length; i++){ var classFound = false; var elClasses = []; if(topNode.childNodes[i].nodeName != "svg" && topNode.childNodes[i].nodeName != "path"){ try{ elClasses = typeof topNode.childNodes[i].className == "undefined" ? [] : topNode.childNodes[i].className.split(" "); }catch(e){} } for(var j = 0; j < elClasses.length; j++){ for(var k = 0; k < ignoreClasses.length; k++){ classFound = classFound || ignoreClasses[k] == elClasses[j]; } } if((topNode.childNodes[i].nodeType == 1 || topNode.childNodes[i].nodeType == 3) && !classFound){ var clonedNode; var isVML = this.arrayContains(topNode.childNodes[i].nodeName, this.serializeableVmlElements); if(typeof topNode.childNodes[i].namespaceURI != "undefined" && topNode.childNodes[i].namespaceURI != null && topNode.childNodes[i].namespaceURI.indexOf("svg") != -1){ clonedNode = this.cloneSvg(topNode.childNodes[i]); } else if(isVML){ clonedNode = this.cloneVml(topNode.childNodes[i]); } else{ clonedNode = topNode.childNodes[i].cloneNode(false); } if(typeof clonedNode.className != "undefined"){ try{ clonedNode.className = ""; }catch(e){} } nodeClone.appendChild(clonedNode); if(topNode.childNodes[i].nodeType == 1 && !isVML){ this.copyAppliedStyle(topNode.childNodes[i], clonedNode); } if(!isVML){ this.recurseMap(topNode.childNodes[i], clonedNode, ignoreClasses); } } } } return nodeClone; } this.serializeableVmlElements = ["shape", "stroke", "polyline", "fill"]; this.serializedVmlReplacements = {}; this.cloneVml = function(origNode){ var randomish = (new Date()).getTime() + "" + Math.floor(Math.random()*10000); this.serializedVmlReplacements[randomish] = origNode.outerHTML; var rv = document.createTextNode(randomish); return rv; } this.cloneSvg = function(origNode){ var clonedNode = document.createElementNS("http://www.w3.org/2000/svg", origNode.nodeName); for(var i = 0; i < origNode.attributes.length; i++){ clonedNode.setAttributeNS(null, origNode.attributes[i].nodeName, origNode.attributes[i].nodeValue); } return clonedNode; } this.arrayContains = function(theString, theArray){ for(var i = 0; i < theArray.length; i++){ if(theArray[i] == theString){ return true; } } return false; } this.fullSerializeDefaultStyles = {"background-attachment":"scroll","background-color":"transparent","background-image":"none","background-position":"0% 0%","background-repeat":"repeat","border-left-color":"rgb(0, 0, 0)","border-top-color":"rgb(0, 0, 0)","border-right-color":"rgb(0, 0, 0)","border-bottom-color":"rgb(0, 0, 0)","border-left-style":"none","border-top-style":"none","border-right-style":"none","border-bottom-style":"none","border-left-width":"0px","border-top-width":"0px","border-right-width":"0px","border-bottom-width":"0px","background":"transparent none repeat scroll 0% 0%","overflow":"visible","overflow-x":"visible","overflow-y":"visible","-moz-background-clip":"-moz-initial","-moz-background-origin":"-moz-initial","-moz-background-inline-policy":"-moz-initial","display":"block","visibility":"visible","opacity":"1","border-collapse":"separate","border-spacing":"0px 0px","clip":"auto","font-size-adjust":"none","font-weight":"400","list-style-image":"none","list-style-position":"outside","list-style-type":"disc","text-align":"left","text-indent":"0px","text-decoration":"none","z-index":"auto","vertical-align":"baseline","color":"rgb(0, 0, 0)","padding-top":"0px","padding-left":"0px","padding-right":"0px","padding-bottom":"0px","font-style":"normal","font-variant":"normal", "fill":"none"};//, "border-top-style":"none","border-right-style":"none","border-bottom-style":"none","border-left-style":"none"}; this.fullSerializeIgnoreStyles = ["captionSide", "clear", "content", "counterIncrement", "counterReset", "cursor", "direction", "emptyCells", "letterSpacing", "markerOffset", "maxHeight", "maxWidth", "minHeight", "minWidth", "outlineColor", "outlineStyle", "outlineWidth", "pageBreakAfter", "pageBreakBefore", "quotes", "tableLayout", "textTransform", "unicodeBidi", "whiteSpace", "wordSpacing", "outlineOffset", "imeMode", "zoom", "scrollbarDarkShadowColor", "scrollbar3dLightColor", "msBlockProgression", "widows", "orphans", "styleFloat", "clipTop", "clipBottom", "clipLeft", "clipRight", "blockDirection", "outlineStyle", "outlineColor", "hasLayout"]; this.copyAppliedStyle = function(src, dest){ var sss = ""; var cacheCheck = this.fullSerializeCacheCheck(src); if(cacheCheck != ""){ sss = this.cacheReplaceStyle(src, cacheCheck); } else{ var elStyles; if(FDCPLoader.browserDetect.browser == 'Explorer'){ elStyles = dest.currentStyle; } else{ elStyles = document.defaultView.getComputedStyle(dest, ''); } if(FDCPLoader.browserDetect.browser == 'Safari'){ elStyles = document.defaultView.getComputedStyle(src, ''); dest.style.cssText = elStyles.cssText; return; } for(var aStyle in elStyles){ if(aStyle.indexOf("Moz") != 0 && !this.arrayContains(aStyle, this.fullSerializeIgnoreStyles)){ var styleValue; var converted = ""; var stc = ""; if(src.currentStyle){ stc = src.currentStyle[aStyle]; } for(var j = 0, len = aStyle.length;j < len; ++j) { if(aStyle.charAt(j) == aStyle.charAt(j).toUpperCase()) { converted = converted + '-' + aStyle.charAt(j).toLowerCase(); } else{ converted = converted + aStyle.charAt(j); } } if(typeof stc == 'undefined'){ if(FDCPLoader.browserDetect.browser == 'Explorer'){ stc = src.currentStyle[converted]; } else{ stc = document.defaultView.getComputedStyle(src, null).getPropertyValue(converted); } } var theStyle = elStyles[aStyle]; var convertedInDefaultStylez = converted in this.fullSerializeDefaultStyles; if(typeof theStyle != "undefined" && typeof theStyle != "function" && theStyle != "" && (!(convertedInDefaultStylez) || (convertedInDefaultStylez && stc != this.fullSerializeDefaultStyles[converted]))){ sss += converted + ":" + stc + ";"; } } } if(src.nodeName == "IMG" && src.parentNode.nodeName == "A"){ sss += "border:none;"; } //cache this item this.fullSerializeCache.push({parent:src.parentNode, className:src.className,name:src.nodeName,value:sss}); } if(FDCPLoader.browserDetect.browser == 'Explorer'){ dest.style.cssText = sss; } else{ dest.setAttribute("style", sss); } } this.fullSerializeCache = new Array(); this.fullSerializeCacheCheck = function(theNode){ if(typeof theNode.id != "undefined" && theNode.id != ""){ return ""; } //key is className, parent, nodeName var theClassName = theNode.className; var theParent = theNode.parentNode; var theName = theNode.nodeName; for(var i = 0; i < this.fullSerializeCache.length; i++){ var cachedItem = this.fullSerializeCache[i]; if(theParent == cachedItem.parent && theClassName == cachedItem.className && theName == cachedItem.name){ return cachedItem.value; } } return ""; } this.cacheReplaceStyle = function(src, origString){ var replaceText = src.style.cssText; var styleParts = replaceText.split(";"); var loopCount = styleParts.length; if(replaceText.charAt(replaceText.length - 1) == ";"){ loopCount--; } for(var i = 0; i < loopCount; i++){ var splitIndex = styleParts[i].indexOf(":"); var styleName = styleParts[i].substr(0, splitIndex).replace(/^\s+|\s+$/g,""); var styleValue = styleParts[i].substr(splitIndex + 1); var regex = new RegExp("(^|;)\\s*" + styleName + "\\s*:[^;]*(;|$)", "i"); var origOrigString = origString; origString = origString.replace(regex, "$1" + styleName + ":" + styleValue + ";"); if(origOrigString == origString){ origString += styleName + ":" + styleValue + ";" } } origString = this.cacheYankMissingStyleAttributes(["display", "z-index"], origString, replaceText); if(src.nodeName == "IMG"){ var regex = new RegExp("(^|;)\\s*width\\s*:[^;]*(;|$)", "i"); if(origString.match(regex)){ origString = origString.replace(regex, "$1width:" + src.width + "px;"); } else{ origString += ";width:" + src.width + "px;"; } regex = new RegExp("(^|;)\\s*height\\s*:[^;]*(;|$)", "i"); if(origString.match(regex)){ origString = origString.replace(regex, "$1height:" + src.height + "px;"); } else{ origString += ";height:" + src.height + "px;"; } } return origString; } this.cacheYankMissingStyleAttributes = function(stylez, origString, replaceText){ for(var i = 0; i < stylez.length; i++){ var regex = new RegExp("(^|;)\\s*" + stylez[i] + "\\s*:[^;]*(;|$)", "i"); if(origString.match(regex) && !replaceText.match(regex)){ origString = origString.replace(regex, "$1"); } } return origString; } this.arrayRemove = function(array, from, to) { var rest = array.slice((to || from) + 1 || array.length); array.length = from < 0 ? array.length + from : from; return array.push.apply(array, rest); } }