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