1 /** 2 * @namespace 3 * @name window 4 * @description Eval routines, depending on the browser. 5 * <p/> 6 * The problem solved in this class is the problem on how to perform 7 * a global eval on multiple browsers. Some browsers auto eval themselves 8 * they do not need to be called 9 * <li>Some work with a window.eval.call(window,... </li> 10 * <li>Others use simply execScript <li> 11 * <li>Some others work only with the head appendix method 12 * head.appendChild(<script...., head.removeChild(<script </li> 13 * <p/> 14 * Note: The code here already is precompressed because the compressor 15 * fails on it, the deficits in readability will be covered by more comments 16 * 17 */ 18 19 20 if (!window.myfaces) { 21 /** 22 * @namespace 23 * @name myfaces 24 */ 25 var myfaces = new function() { 26 }; 27 window.myfaces = myfaces; 28 } 29 30 /** 31 * @memberOf myfaces 32 * @namespace 33 * @name _impl 34 */ 35 myfaces._impl = (myfaces._impl) ? myfaces._impl : {}; 36 /** 37 * @memberOf myfaces._impl 38 * @namespace 39 * @name core 40 */ 41 myfaces._impl.core = (myfaces._impl.core) ? myfaces._impl.core :{}; 42 43 if (!myfaces._impl.core._EvalHandlers) { 44 /** 45 * @memberOf myfaces._impl.core 46 * @namespace 47 * @name _EvalHandlers 48 */ 49 myfaces._impl.core._EvalHandlers = new function() { 50 //the rest of the namespaces can be handled by our namespace feature 51 //helper to avoid unneeded hitches 52 /** 53 * @borrows myfaces._impl.core._Runtime as _T 54 */ 55 var _T = this; 56 57 /*cascaded eval methods depending upon the browser*/ 58 59 /** 60 * @function 61 * @param code 62 63 * 64 * evals a script globally using exec script (ie6 fallback) 65 * @param {String} code the code which has to be evaluated 66 * @borrows myfaces._impl.core._Runtime as _T 67 * 68 * TODO eval if we cannot replace this method with the head appendix 69 * method which is faster for ie this also would reduce our code 70 * by a few bytes 71 */ 72 _T._evalExecScript = function(code) { 73 //execScript definitely only for IE otherwise we might have a custom 74 //window extension with undefined behavior on our necks 75 //window.execScript does not return anything 76 //on htmlunit it return "null object" 77 //_r == ret 78 var _r = window.execScript(code); 79 if ('undefined' != typeof _r && _r == "null" /*htmlunit bug*/) { 80 return null; 81 } 82 return _r; 83 }; 84 85 /** 86 * flakey head appendix method which does not work in the correct 87 * order or at all for all modern browsers 88 * but seems to be the only method which works on blackberry correctly 89 * hence we are going to use it as fallback 90 * 91 * @param {String} code the code part to be evaled 92 * @borrows myfaces._impl.core._Runtime as _T 93 */ 94 _T._evalHeadAppendix = function(code) { 95 //_l == location 96 var _l = document.getElementsByTagName("head")[0] || document.documentElement; 97 //_p == placeHolder 98 var _p = document.createElement("script"); 99 _p.type = "text/javascript"; 100 _p.text = code; 101 _l.insertBefore(_p, _l.firstChild); 102 _l.removeChild(_p); 103 return null; 104 }; 105 106 /** 107 * @name myfaces._impl.core._Runtime._standardGlobalEval 108 * @private 109 * @param {String} code 110 */ 111 _T._standardGlobalEval = function(code) { 112 //fix which works in a cross browser way 113 //we used to scope an anonymous function 114 //but I think this is better 115 //the reason is some Firefox versions 116 // apply a wrong scope 117 //if we call eval by not scoping 118 //_U == "undefined" 119 var _U = "undefined"; 120 var gEval = function () { 121 //_r == retVal; 122 var _r = window.eval.call(window, code); 123 if (_U == typeof _r) return null; 124 return _r; 125 }; 126 var _r = gEval(); 127 if (_U == typeof _r) return null; 128 return _r; 129 }; 130 131 /** 132 * global eval on scripts 133 * @param {String} c (code abbreviated since the compression does not work here) 134 * @name myfaces._impl.core._Runtime.globalEval 135 * @function 136 */ 137 _T.globalEval = function(c) { 138 //TODO add a config param which allows to evaluate global scripts even if the call 139 //is embedded in an iframe 140 //We lazy init the eval type upon the browsers 141 //capabilities 142 var _e = "_evalType"; 143 var _w = window; 144 var _b = myfaces._impl.core._Runtime.browser; 145 //central routine to determine the eval method 146 if (!_T[_e]) { 147 //execScript supported 148 _T[_e] = _w.execScript ? "_evalExecScript" : null; 149 150 //in case of no support we go to the standard global eval window.eval.call(window, 151 // with Firefox fixes for scoping 152 _T[_e] = _T[_e] ||(( _w.eval && (!_b.isBlackBerry ||_b.isBlackBerry >= 6)) ? "_standardGlobalEval" : null); 153 154 //this one routes into the hed appendix method 155 _T[_e] = _T[_e] ||((_w.eval ) ? "_evalHeadAppendix" : null); 156 } 157 if (_T[_e]) { 158 //we now execute the eval method 159 return _T[_T[_e]](c); 160 } 161 //we probably have covered all browsers, but this is a safety net which might be triggered 162 //by some foreign browser which is not covered by the above cases 163 eval.call(window, c); 164 return null; 165 }; 166 167 }; 168 }