📄 contentpane.js
字号:
default: // makes sure scripts can clean up after themselves, before we setContent if(this._callOnUnload){ this.onUnload(); } // makes sure we dont try to call onUnLoad again on this event, // ie onUnLoad before 'Loading...' but not before clearing 'Loading...' this._callOnUnload = false; // we might end up in a endless recursion here if domNode cant append content if(arguments.callee._loopStop){ dojo.debug(e.toString()); }else{ arguments.callee._loopStop = true; this._setContent(e.toString()); } } } arguments.callee._loopStop = false; }, // pathfixes, require calls, css stuff and neccesary content clean splitAndFixPaths: function(/*String*/s, /*String||dojo.uri.Uri, optional*/url){ // summary: // adjusts all relative paths in (hopefully) all cases, images, remote scripts, links etc. // splits up content in different pieces, scripts, title, style, link and whats left becomes .xml // s: The markup in string // url: url that pulled in markup var titles = [], scripts = [],tmp = [];// init vars var match = [], requires = [], attr = [], styles = []; var str = '', path = '', fix = '', tagFix = '', tag = '', origPath = ''; if(!url) { url = "./"; } // point to this page if not set if(s){ // make sure we dont run regexes on empty content /************** <title> ***********/ // khtml is picky about dom faults, you can't attach a <style> or <title> node as child of body // must go into head, so we need to cut out those tags var regex = /<title[^>]*>([\s\S]*?)<\/title>/i; while(match = regex.exec(s)){ titles.push(match[1]); s = s.substring(0, match.index) + s.substr(match.index + match[0].length); }; /************** adjust paths *****************/ if(this.adjustPaths){ // attributepaths one tag can have multiple paths example: // <input src="..." style="url(..)"/> or <a style="url(..)" href=".."> // strip out the tag and run fix on that. // this guarantees that we won't run replace on another tag's attribute + it was easier do var regexFindTag = /<[a-z][a-z0-9]*[^>]*\s(?:(?:src|href|style)=[^>])+[^>]*>/i; var regexFindAttr = /\s(src|href|style)=(['"]?)([\w()\[\]\/.,\\'"-:;#=&?\s@]+?)\2/i; // these are the supported protocols, all other is considered relative var regexProtocols = /^(?:[#]|(?:(?:https?|ftps?|file|javascript|mailto|news):))/; while(tag = regexFindTag.exec(s)){ str += s.substring(0, tag.index); s = s.substring((tag.index + tag[0].length), s.length); tag = tag[0]; // loop through attributes tagFix = ''; while(attr = regexFindAttr.exec(tag)){ path = ""; origPath = attr[3]; switch(attr[1].toLowerCase()){ case "src":// falltrough case "href": if(regexProtocols.exec(origPath)){ path = origPath; } else { path = (new dojo.uri.Uri(url, origPath).toString()); } break; case "style":// style path = dojo.html.fixPathsInCssText(origPath, url); break; default: path = origPath; } fix = " " + attr[1] + "=" + attr[2] + path + attr[2]; // slices up tag before next attribute check tagFix += tag.substring(0, attr.index) + fix; tag = tag.substring((attr.index + attr[0].length), tag.length); } str += tagFix + tag; //dojo.debug(tagFix + tag); } s = str+s; } /**************** cut out all <style> and <link rel="stylesheet" href=".."> **************/ regex = /(?:<(style)[^>]*>([\s\S]*?)<\/style>|<link ([^>]*rel=['"]?stylesheet['"]?[^>]*)>)/i; while(match = regex.exec(s)){ if(match[1] && match[1].toLowerCase() == "style"){ styles.push(dojo.html.fixPathsInCssText(match[2],url)); }else if(attr = match[3].match(/href=(['"]?)([^'">]*)\1/i)){ styles.push({path: attr[2]}); } s = s.substring(0, match.index) + s.substr(match.index + match[0].length); }; /***************** cut out all <script> tags, push them into scripts array ***************/ var regex = /<script([^>]*)>([\s\S]*?)<\/script>/i; var regexSrc = /src=(['"]?)([^"']*)\1/i; var regexDojoJs = /.*(\bdojo\b\.js(?:\.uncompressed\.js)?)$/; var regexInvalid = /(?:var )?\bdjConfig\b(?:[\s]*=[\s]*\{[^}]+\}|\.[\w]*[\s]*=[\s]*[^;\n]*)?;?|dojo\.hostenv\.writeIncludes\(\s*\);?/g; var regexRequires = /dojo\.(?:(?:require(?:After)?(?:If)?)|(?:widget\.(?:manager\.)?registerWidgetPackage)|(?:(?:hostenv\.)?setModulePrefix|registerModulePath)|defineNamespace)\((['"]).*?\1\)\s*;?/; while(match = regex.exec(s)){ if(this.executeScripts && match[1]){ if(attr = regexSrc.exec(match[1])){ // remove a dojo.js or dojo.js.uncompressed.js from remoteScripts // we declare all files named dojo.js as bad, regardless of path if(regexDojoJs.exec(attr[2])){ dojo.debug("Security note! inhibit:"+attr[2]+" from being loaded again."); }else{ scripts.push({path: attr[2]}); } } } if(match[2]){ // remove all invalid variables etc like djConfig and dojo.hostenv.writeIncludes() var sc = match[2].replace(regexInvalid, ""); if(!sc){ continue; } // cut out all dojo.require (...) calls, if we have execute // scripts false widgets dont get there require calls // takes out possible widgetpackage registration as well while(tmp = regexRequires.exec(sc)){ requires.push(tmp[0]); sc = sc.substring(0, tmp.index) + sc.substr(tmp.index + tmp[0].length); } if(this.executeScripts){ scripts.push(sc); } } s = s.substr(0, match.index) + s.substr(match.index + match[0].length); } /********* extract content *********/ if(this.extractContent){ match = s.match(/<body[^>]*>\s*([\s\S]+)\s*<\/body>/im); if(match) { s = match[1]; } } /*** replace scriptScope prefix in html Event handler * working order: find tags with scriptScope in a tag attribute * then replace all standalone scriptScope occurencies with reference to to this widget * valid onClick="scriptScope.func()" or onClick="scriptScope['func']();scriptScope.i++" * not valid onClick="var.scriptScope.ref" nor onClick="var['scriptScope'].ref" */ if(this.executeScripts && this.scriptSeparation){ var regex = /(<[a-zA-Z][a-zA-Z0-9]*\s[^>]*?\S=)((['"])[^>]*scriptScope[^>]*>)/; var regexAttr = /([\s'";:\(])scriptScope(.*)/; // we rely on that attribute begins ' or " str = ""; while(tag = regex.exec(s)){ tmp = ((tag[3]=="'") ? '"': "'");fix= ""; str += s.substring(0, tag.index) + tag[1]; while(attr = regexAttr.exec(tag[2])){ tag[2] = tag[2].substring(0, attr.index) + attr[1] + "dojo.widget.byId("+ tmp + this.widgetId + tmp + ").scriptScope" + attr[2]; } str += tag[2]; s = s.substr(tag.index + tag[0].length); } s = str + s; } } return {"xml": s, // Object "styles": styles, "titles": titles, "requires": requires, "scripts": scripts, "url": url}; }, _setContent: function(cont){ this.destroyChildren(); // remove old stylenodes from HEAD for(var i = 0; i < this._styleNodes.length; i++){ if(this._styleNodes[i] && this._styleNodes[i].parentNode){ this._styleNodes[i].parentNode.removeChild(this._styleNodes[i]); } } this._styleNodes = []; var node = this.containerNode || this.domNode; while(node.firstChild){ try{ dojo.event.browser.clean(node.firstChild); }catch(e){} node.removeChild(node.firstChild); } try{ if(typeof cont != "string"){ node.innerHTML = ""; node.appendChild(cont); }else{ node.innerHTML = cont; } }catch(e){ e.text = "Couldn't load content:"+e.description; this._handleDefaults(e, "onContentError"); } }, setContent: function(/*String||DomNode*/ data){ // summary: // Replaces old content with data content, include style classes from old content // data: new content, be it Document fragment or a DomNode chain // If data contains style tags, link rel=stylesheet it inserts those styles into DOM this.abort(); if(this._callOnUnload){ this.onUnload(); }// this tells a remote script clean up after itself this._callOnUnload = true; if(!data || dojo.html.isNode(data)){ // if we do a clean using setContent(""); or setContent(#node) bypass all parsing, extractContent etc this._setContent(data); this.onResized(); this.onLoad(); }else{ // need to run splitAndFixPaths? ie. manually setting content // adjustPaths is taken care of inside splitAndFixPaths if(typeof data.xml != "string"){ this.href = ""; // so we can refresh safely data = this.splitAndFixPaths(data); } this._setContent(data.xml); // insert styles from content (in same order they came in) for(var i = 0; i < data.styles.length; i++){ if(data.styles[i].path){ this._styleNodes.push(dojo.html.insertCssFile(data.styles[i].path)); }else{ this._styleNodes.push(dojo.html.insertCssText(data.styles[i])); } } if(this.parseContent){ for(var i = 0; i < data.requires.length; i++){ try{ eval(data.requires[i]); } catch(e){ e.text = "ContentPane: error in package loading calls, " + (e.description||e); this._handleDefaults(e, "onContentError", "debug"); } } } // need to allow async load, Xdomain uses it // is inline function because we cant send args to dojo.addOnLoad var _self = this; function asyncParse(){ if(_self.executeScripts){ _self._executeScripts(data.scripts); } if(_self.parseContent){ var node = _self.containerNode || _self.domNode; var parser = new dojo.xml.Parse(); var frag = parser.parseElement(node, null, true); // createSubComponents not createComponents because frag has already been created dojo.widget.getParser().createSubComponents(frag, _self); } _self.onResized(); _self.onLoad(); } // try as long as possible to make setContent sync call if(dojo.hostenv.isXDomain && data.requires.length){ dojo.addOnLoad(asyncParse); }else{ asyncParse(); } } }, setHandler: function(/*Function*/ handler) { // summary: // Generate pane content from given java function var fcn = dojo.lang.isFunction(handler) ? handler : window[handler]; if(!dojo.lang.isFunction(fcn)) { // FIXME: needs testing! somebody with java knowledge needs to try this this._handleDefaults("Unable to set handler, '" + handler + "' not a function.", "onExecError", true); return; } this.handler = function() { return fcn.apply(this, arguments); } }, _runHandler: function() { var ret = true; if(dojo.lang.isFunction(this.handler)) { this.handler(this, this.domNode); ret = false; } this.onLoad(); return ret; }, _executeScripts: function(scripts) { // loop through the scripts in the order they came in var self = this; var tmp = "", code = ""; for(var i = 0; i < scripts.length; i++){ if(scripts[i].path){ // remotescript dojo.io.bind(this._cacheSetting({ "url": scripts[i].path, "load": function(type, scriptStr){ dojo.lang.hitch(self, tmp = ";"+scriptStr); }, "error": function(type, error){ error.text = type + " downloading remote script"; self._handleDefaults.call(self, error, "onExecError", "debug"); }, "mimetype": "text/plain", "sync": true }, this.cacheContent)); code += tmp; }else{ code += scripts[i]; } } try{ if(this.scriptSeparation){ // initialize a new anonymous container for our script, dont make it part of this widgets scope chain // instead send in a variable that points to this widget, useful to connect events to onLoad, onUnload etc.. delete this.scriptScope; this.scriptScope = new (new Function('_container_', code+'; return this;'))(self); }else{ // exec in global, lose the _container_ feature var djg = dojo.global(); if(djg.execScript){ djg.execScript(code); }else{ var djd = dojo.doc(); var sc = djd.createElement("script"); sc.appendChild(djd.createTextNode(code)); (this.containerNode||this.domNode).appendChild(sc); } } }catch(e){ e.text = "Error running scripts from content:\n"+e.description; this._handleDefaults(e, "onExecError", "debug"); } } });
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -