| dojo.provide("struts.widget.Bind"); |
| |
| dojo.require("dojo.widget.HtmlWidget"); |
| dojo.require("dojo.io"); |
| |
| dojo.widget.defineWidget( |
| "struts.widget.Bind", |
| dojo.widget.HtmlWidget, { |
| widgetType : "Bind", |
| executeScripts : false, |
| targets : "", |
| targetsArray : null, |
| href : "", |
| handler : "", |
| |
| //messages |
| loadingText : "Loading...", |
| errorText : "", |
| showError : true, |
| showLoading : true, |
| |
| //pub/sub events |
| listenTopics : "", |
| notifyTopics : "", |
| notifyTopicsArray : null, |
| |
| //callbacks |
| beforeLoading : "", |
| afterLoading : "", |
| |
| formId : "", |
| formFilter : "", |
| formNode : null, |
| |
| event : "", |
| indicator : "", |
| |
| parseContent : true, |
| postCreate : function() { |
| var self = this; |
| |
| //attach listeners |
| if(!dojo.string.isBlank(this.listenTopics)) { |
| this.log("Listening to " + this.listenTopics + " to refresh"); |
| var topics = this.listenTopics.split(","); |
| if(topics) { |
| dojo.lang.forEach(topics, function(topic){ |
| dojo.event.topic.subscribe(topic, self, "reloadContents"); |
| }); |
| } |
| } |
| |
| if(!dojo.string.isBlank(this.notifyTopics)) { |
| this.notifyTopicsArray = this.notifyTopics.split(","); |
| } |
| |
| if(!dojo.string.isBlank(this.targets)) { |
| //split targets |
| this.targetsArray = this.targets.split(","); |
| } |
| |
| if(!dojo.string.isBlank(this.event)) { |
| dojo.event.connect(this.domNode, this.event, function(evt) { |
| evt.preventDefault(); |
| evt.stopPropagation(); |
| self.reloadContents(); |
| }); |
| } |
| |
| if(dojo.string.isBlank(this.href) && dojo.string.isBlank(this.formId)) { |
| //no href and no formId, we must be inside a form |
| this.formNode = dojo.dom.getFirstAncestorByTag(this.domNode, "form"); |
| } else { |
| this.formNode = dojo.byId(this.formId); |
| } |
| |
| if(this.formNode && dojo.string.isBlank(this.href)) { |
| this.href = this.formNode.action; |
| } |
| |
| if(!dojo.string.isBlank(this.formId)) { |
| this.formNode = dojo.byId(this.formId); |
| } |
| }, |
| |
| log : function(text) { |
| dojo.debug("[" + (this.widgetId ? this.widgetId : "unknown") + "] " + text); |
| }, |
| |
| setContent : function(text) { |
| if(this.targetsArray) { |
| var self = this; |
| var xmlParser = new dojo.xml.Parse(); |
| dojo.lang.forEach(this.targetsArray, function(target) { |
| var node = dojo.byId(target); |
| node.innerHTML = text; |
| |
| if(self.parseContent && text != self.loadingText){ |
| var frag = xmlParser.parseElement(node, null, true); |
| dojo.widget.getParser().createSubComponents(frag, dojo.widget.byId(target)); |
| } |
| }); |
| } |
| }, |
| |
| bindHandler : function(type, data, e) { |
| //hide indicator |
| dojo.html.hide(this.indicator); |
| |
| //post script |
| if(!dojo.string.isBlank(this.afterLoading)) { |
| this.log("Executing " + this.afterLoading); |
| eval(this.afterLoading); |
| } |
| //publish topics |
| this.notify(data, type, e); |
| |
| if(type == "load") { |
| if(this.executeScripts) { |
| //update targets content |
| var parsed = this.parse(data); |
| //eval scripts |
| if(parsed.scripts && parsed.scripts.length > 0) { |
| var scripts = ""; |
| for(var i = 0; i < parsed.scripts.length; i++){ |
| scripts += parsed.scripts[i]; |
| } |
| (new Function('_container_', scripts+'; return this;'))(this); |
| } |
| this.setContent(parsed.text); |
| } |
| else { |
| this.setContent(data); |
| } |
| } else { |
| if(this.showError) { |
| var message = dojo.string.isBlank(this.errorText) ? e.message : this.errorText; |
| this.setContent(message); |
| } |
| } |
| }, |
| |
| notify : function(data, type, e) { |
| if(this.notifyTopicsArray) { |
| var self = this; |
| dojo.lang.forEach(this.notifyTopicsArray, function(topic) { |
| try { |
| dojo.event.topic.publish(topic, data, type, e); |
| } catch(ex){ |
| self.log(ex); |
| } |
| }); |
| } |
| }, |
| |
| onDownloadStart : function(event) { |
| if(!dojo.string.isBlank(this.beforeLoading)) { |
| //for backward compatibility |
| var data = null; |
| var type = null; |
| |
| eval(this.beforeLoading); |
| } |
| if(this.showLoading && !dojo.string.isBlank(this.loadingText)) { |
| event.text = this.loadingText; |
| } |
| }, |
| |
| reloadContents : function(evt) { |
| |
| if(!dojo.string.isBlank(this.handler)) { |
| //use custom handler |
| this.log("Invoking handler: " + this.handler); |
| window[this.handler](this, this.domNode); |
| } |
| else { |
| //pre script |
| if(!dojo.string.isBlank(this.beforeLoading)) { |
| this.log("Executing " + this.beforeLoading); |
| //backward compatibility |
| var data = null; |
| var type = null; |
| |
| eval(this.beforeLoading); |
| } |
| |
| try { |
| var self = this; |
| var request = {cancel: false}; |
| this.notify(this.widgetId, "before", request); |
| if(request.cancel) { |
| this.log("Request canceled"); |
| return; |
| } |
| |
| //if the href is null, we still call the "beforeLoading" |
| // and publish the notigy topics |
| if(dojo.string.isBlank(this.href)) { |
| return; |
| } |
| |
| //if there is a parent form, and it has a "onsubmit" |
| //execute it, validation is usually there |
| if(this.formNode && this.formNode.onsubmit != null) { |
| var makeRequest = this.formNode.onsubmit.call(evt); |
| if(makeRequest != null && !makeRequest) { |
| this.log("Request canceled by 'onsubmit' of the form"); |
| return; |
| } |
| } |
| |
| //show indicator |
| dojo.html.show(this.indicator); |
| if(this.showLoading) { |
| this.setContent(this.loadingText); |
| } |
| |
| dojo.io.bind({ |
| url: this.href, |
| useCache: false, |
| preventCache: true, |
| formNode: self.formNode, |
| formFilter: window[self.formFilter], |
| handler: function(type, data, e) { |
| dojo.lang.hitch(self, "bindHandler")(type, data, e); |
| }, |
| mimetype: "text/html" |
| }); |
| } |
| catch(ex) { |
| var message = dojo.string.isBlank(this.errorText) ? ex : this.errorText; |
| this.setContent(message); |
| } |
| } |
| }, |
| |
| //from Dojo's ContentPane |
| parse : function(s) { |
| this.log("Parsing: " + s); |
| var match = []; |
| var tmp = []; |
| var scripts = []; |
| while(match){ |
| match = s.match(/<script([^>]*)>([\s\S]*?)<\/script>/i); |
| if(!match){ break; } |
| if(match[1]){ |
| attr = match[1].match(/src=(['"]?)([^"']*)\1/i); |
| if(attr){ |
| // remove a dojo.js or dojo.js.uncompressed.js from remoteScripts |
| // we declare all files with dojo.js as bad, regardless of folder |
| var tmp2 = attr[2].search(/.*(\bdojo\b(?:\.uncompressed)?\.js)$/); |
| if(tmp2 > -1){ |
| this.log("Security note! inhibit:"+attr[2]+" from beeing loaded again."); |
| } |
| } |
| } |
| if(match[2]){ |
| // strip out all djConfig variables from script tags nodeValue |
| // this is ABSOLUTLY needed as reinitialize djConfig after dojo is initialised |
| // makes a dissaster greater than Titanic, update remove writeIncludes() to |
| var sc = match[2].replace(/(?:var )?\bdjConfig\b(?:[\s]*=[\s]*\{[^}]+\}|\.[\w]*[\s]*=[\s]*[^;\n]*)?;?|dojo\.hostenv\.writeIncludes\(\s*\);?/g, ""); |
| if(!sc){ continue; } |
| |
| // cut out all dojo.require (...) calls, if we have execute |
| // scripts false widgets dont get there require calls |
| // does suck out possible widgetpackage registration as well |
| tmp = []; |
| while(tmp){ |
| tmp = sc.match(/dojo\.(?:(?:require(?:After)?(?:If)?)|(?:widget\.(?:manager\.)?registerWidgetPackage)|(?:(?:hostenv\.)?setModulePrefix))\((['"]).*?\1\)\s*;?/); |
| if(!tmp){ break;} |
| sc = sc.replace(tmp[0], ""); |
| } |
| scripts.push(sc); |
| } |
| s = s.replace(/<script[^>]*>[\s\S]*?<\/script>/i, ""); |
| } |
| |
| return { |
| text: s, |
| scripts: scripts |
| }; |
| } |
| }); |
| |
| |
| |