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 }