Changeset 15411 in legacy


Ignore:
Timestamp:
Oct 5, 2008 9:18:21 PM (8 years ago)
Author:
alex
Message:

make the default loader work in strict XHTML environments and fix Opera to correctly detect case sensitivity in XML/XHTML environments for queries. A small PHP script is added to test these. Sadly, both Safari and Opera don't observe script ordering for injected tags, so we had to make the dev loader script a bit more complicated to accomidate. Fixes #7455. Fixes #7214. !strict

Location:
dojo/trunk
Files:
1 added
5 edited

Legend:

Unmodified
Added
Removed
  • dojo/trunk/_base/_loader/bootstrap.js

    r15278 r15411  
    9595        // firebug stubs
    9696
    97         // if((!this["console"])||(!console["firebug"])){
    98 
    99         if(!this["console"]){
    100                 this.console = {
    101                 };
    102         }
    103 
    104         //      Be careful to leave 'log' always at the end
    105         var cn = [
    106                 "assert", "count", "debug", "dir", "dirxml", "error", "group",
    107                 "groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
    108                 "trace", "warn", "log"
    109         ];
    110         var i=0, tn;
    111         while((tn=cn[i++])){
    112                 if(!console[tn]){
    113                         (function(){
    114                                 var tcn = tn+"";
    115                                 console[tcn] = ('log' in console) ? function(){
    116                                         var a = Array.apply({}, arguments);
    117                                         a.unshift(tcn+":");
    118                                         console["log"](a.join(" "));
    119                                 } : function(){}
    120                         })();
     97        if(typeof this["loadFirebugConsole"] == "function"){
     98                // Firebug 1.2 is a PITA
     99                this["loadFirebugConsole"]();
     100        }else{
     101                if(!this["console"]){
     102                        this.console = {
     103                        };
     104                }
     105
     106                //      Be careful to leave 'log' always at the end
     107                var cn = [
     108                        "assert", "count", "debug", "dir", "dirxml", "error", "group",
     109                        "groupEnd", "info", "profile", "profileEnd", "time", "timeEnd",
     110                        "trace", "warn", "log"
     111                ];
     112                var i=0, tn;
     113                while((tn=cn[i++])){
     114                        if(!console[tn]){
     115                                (function(){
     116                                        var tcn = tn+"";
     117                                        console[tcn] = ('log' in console) ? function(){
     118                                                var a = Array.apply({}, arguments);
     119                                                a.unshift(tcn+":");
     120                                                console["log"](a.join(" "));
     121                                        } : function(){}
     122                                })();
     123                        }
    121124                }
    122125        }
  • dojo/trunk/_base/_loader/hostenv_browser.js

    r15202 r15411  
    4141        //      isKhtml: Number | undefined
    4242        //              Version as a Number if client is a KTHML-derived browser (Konqueror,
    43         //              Safari, etc.). undefined otherwise. Corresponds to major detected version.
     43        //              Safari, Chrome, etc.). undefined otherwise. Corresponds to major
     44        //              detected version.
    4445        isKhtml: 0,
     46        //      isWebKit: Number | undefined
     47        //              Version as a Number if client is a KTHML-derived browser (Konqueror,
     48        //              Safari, Chrome, etc.). undefined otherwise. Same as isKhtml.
     49        isWebKit: 0,
    4550        //      isMozilla: Number | undefined
    4651        //              Version as a Number if client is a Mozilla-based browser (Firefox,
     
    97102                // fill in the rendering support information in dojo.render.*
    98103                var n = navigator;
    99                 var dua = n.userAgent;
    100                 var dav = n.appVersion;
    101                 var tv = parseFloat(dav);
     104                var dua = n.userAgent,
     105                        dav = n.appVersion,
     106                        tv = parseFloat(dav);
    102107
    103108                if(dua.indexOf("Opera") >= 0){ d.isOpera = tv; }
     
    114119                }
    115120                if(dua.indexOf("AdobeAIR") >= 0){ d.isAIR = 1; }
    116                 if(dav.indexOf("Konqueror") >= 0 || d.isSafari){ d.isKhtml =  tv; }
     121                if(     dav.indexOf("WebKit") >= 0 ||
     122                        dav.indexOf("Konqueror") >= 0 ||
     123                        d.isSafari ||
     124                        d.isAIR
     125                ){
     126                        d.isWebKit = d.isKhtml =  tv;
     127                }
    117128                if(dua.indexOf("Gecko") >= 0 && !d.isKhtml){ d.isMozilla = d.isMoz = tv; }
    118129                if(d.isMoz){
     
    201212                        //              failure and failure is okay (an exception otherwise)
    202213
    203                         // alert("_getText: " + uri);
    204 
    205214                        // NOTE: must be declared before scope switches ie. this._xhrObj()
    206215                        var http = this._xhrObj();
     
    209218                                uri = (new dojo._Url(owloc, uri)).toString();
    210219                        }
    211                         /*
    212                         console.debug("_getText:", uri);
    213                         console.debug(window.location+"");
    214                         alert(uri);
    215                         */
    216220
    217221                        if(d.config.cacheBust){
     
    224228                        try{
    225229                                http.send(null);
    226                                 // alert(http);
    227230                                if(!d._isDocumentOk(http)){
    228231                                        var err = Error("Unable to load "+uri+" status:"+ http.status);
  • dojo/trunk/_base/html.js

    r15330 r15411  
    12651265        }
    12661266
    1267         /*
    1268         dojo.createElement = function(type, attrs, parent, position){
    1269                 // TODO: need to finish this!
    1270         }
    1271         */
     1267        /*=====
     1268        dojo.__CreateElementArgs = function(){
     1269                //      tagName: String
     1270                //              The type of element to create, e.g. "div"
     1271                //      style: Object?
     1272                //              Style rules to apply directly to the element, as though passed to dojo.style()
     1273                //      className: String?
     1274                //              Classes to apply to the node
     1275                //      innerHTML: String?
     1276                //              Serialized content to inject into the node.
     1277                //      childNodes: Array?
     1278                //              An array of dojo.__CreateElementArgs definitions of nodes to
     1279                //              place inside of this element.
     1280                //      id: String?
     1281                //              ID that the node may be fetch by with dojo.byId
     1282                //      parentNode: DOMNode|String?
     1283                //              the node or ID of a node to insert this new element relative to
     1284                //      position: String|Number?
     1285                //              the location relative to parentNode at which this node will be
     1286                //              located. Defaults to "last". See dojo.place() for more details
     1287                //              on number values and other possible placement options.
     1288
     1289                this.tagName = tagName;
     1290                this.style =  style;
     1291                this.className = className;
     1292                this.innerHTML = innerHTML;
     1293                this.childNodes = childNodes;
     1294                this.id = id;
     1295                this.parentNode = parentNode;
     1296                this.position = position;
     1297        }
     1298        =====*/
     1299        var tmpNode;
     1300        dojo.createElement = function(/* dojo.__CreateElementArgs|String */ obj){
     1301                //      summary:
     1302                //              creates an element (and potentially sub-elements) based on the
     1303                //              structure passed-in. If a string is passed, treat it as HTML to
     1304                //              be de-serialized via innerHTML but only return the first
     1305                //              element. If an object is passed, its structure roughly
     1306                //              represents a serialized DOM representation of a node. Note that
     1307                //              the returned element tree will NOT be attached to the visible
     1308                //              DOM when returned unless a parentNode (and optionally
     1309                //              "position") attribute is specified. See also dojo.elem()
     1310                //      obj:
     1311                //              an object that represents the DOM to be constructed. Properties
     1312                //              such as childNodes an innerHTML are supported as are functions
     1313                //              to specify event handler and a style object to represent inline
     1314                //              styles. Use of `childNodes` and `innerHTML` are exclusive, so
     1315                //              be sure to only use one or the other.
     1316                //      example:
     1317                //              create a set of nested elements, starting with a div:
     1318                //      |       var el = dojo.createElement({
     1319                //      |               tagName: "div",
     1320                //      |
     1321                //      |               // specify styling and classes to apply
     1322                //      |               style: { border: "1px solid black" },
     1323                //      |
     1324                //      |               className: "thinger redBackground",
     1325                //      |
     1326                //      |               // attaching an anonymous function
     1327                //      |               onmouseenter: function(e){
     1328                //      |                       console.debug("entered", e.target);
     1329                //      |               },
     1330                //      |
     1331                //      |               // attaching a member of an object
     1332                //      |               onclick: dojo.hitch(console, "debug", "clicked!"),
     1333                //      |
     1334                //      |               // attaching a member of an object
     1335                //      |               // specify children in the same format
     1336                //      |               childNodes: [
     1337                //      |                       {
     1338                //      |                               tagName: "img",
     1339                //      |                               src: "http://www.dojotoolkit.org/sites/all/themes/dtk/img/demo.png"
     1340                //      |                               style: { border: "none" }
     1341                //      |                       },
     1342                //      |                       {
     1343                //      |                               tagName: "div",
     1344                //      |                               innerHTML: "howdy there, pardner!"
     1345                //      |                       }
     1346                //      |               ]
     1347                //      |       });
     1348                //      example:
     1349                //              create a link with text and an image inside and place it at the
     1350                //              top of the document:
     1351                //      |       var el = dojo.createElement({
     1352                //      |               tagName: "a",
     1353                //      |               href: "http://dojotoolkit.org",
     1354                //      |               parentNode: dojo.body(),
     1355                //      |               childNodes: [
     1356                //      |                       "<span>howdy!</span>",
     1357                //      |                       {
     1358                //      |                               tagName: "img",
     1359                //      |                               src: "http://www.dojotoolkit.org/sites/all/themes/dtk/img/demo.png"
     1360                //      |                       },
     1361                //      |               ]
     1362                //      |       });
     1363                if(dojo.isString(obj)){
     1364                        // make sure we've got a temporary node to push the contents into
     1365                        // and ensure that it's from the current document context
     1366                        if(!tmpNode || tmpNode.ownerDocument != dojo.doc){
     1367                                tmpNode = dojo.doc.createElement("div");
     1368                        }
     1369                        tmpNode.innerHTML = obj;
     1370                        return tmpNode.removeChild(tmp.firstChild);
     1371                }
     1372                var type = obj.nodeName||obj.tagName||obj.tag;
     1373                delete obj.nodeName;
     1374                delete obj.tagName;
     1375                delete obj.tag;
     1376
     1377                var cn = obj.childNodes;
     1378                delete obj.childNodes;
     1379
     1380                var doc = obj.ownerDocument||dojo.doc;
     1381                delete obj.ownerDocument;
     1382
     1383                var ih = obj.innerHTML;
     1384                delete obj.innerHTML;
     1385
     1386                var tn = doc.createElement(type);
     1387                dojo.attr(tn, obj);
     1388                if(ih){
     1389                        tn.innerHTML = ih;
     1390                }else if(cn){
     1391                        dojo.forEach(cn, function(child){
     1392                                child.parentNode = child.parentNode||tn;
     1393                                return dojo.createElement(child);
     1394                        });
     1395                }
     1396                if(obj.parentNode){
     1397                        obj.position = (typeof obj.position != undefined) ? obj.position : "last";
     1398                        dojo.place(tn, obj.parentNode, obj.position);
     1399                }
     1400                return tn; // DOMNode
     1401        };
     1402
     1403        dojo.elem = function(   /*String*/ type,
     1404                                                        /*Object?*/ attrs,
     1405                                                        /*DOMNode|String?*/ par,
     1406                                                        /*String|Integer?*/ location){
     1407                //      summary:
     1408                //              a shorthand for dojo.createElement which provides ease-of-use
     1409                //              for the case of building single elements. It supports optional
     1410                //              placement via the parent and location arguments
     1411                //      type:
     1412                //              the node type to create, e.g. "div"
     1413                //      attrs:
     1414                //              an optional list of attributes to assign to the element,
     1415                //              potentially including innerHTML or childNodes. See
     1416                //              dojo.createElement for an understanding of all of the types of
     1417                //              attributes which may be specified.
     1418                //      parent:
     1419                //              an optional reference to a node to place the created element
     1420                //              relative to
     1421                //      location:
     1422                //              if a parent is specified, this location indicates where to put
     1423                //              the created element relative to the parent. See dojo.place()
     1424                //              for accepted values. If no location is provided, the element is
     1425                //              added to the end of the referenced parent.
     1426                var al = arguments.length;
     1427                // FIXME: what if it's a string that starts w/ an "<", shouldn't we just create it?
     1428                if((al == 1)&&(!dojo.isString(type))){
     1429                        return dojo.createElement(type);
     1430                }
     1431                // FIXME: what if attrs is a string? Should we treat is specially, say by making it the ID or by setting innerHTML to it?
     1432                if(!attrs){
     1433                        attrs = {};
     1434                }
     1435                attrs.tag = type;
     1436                if(par){
     1437                        attrs.parentNode = par;
     1438                        if(al == 4){
     1439                                attrs.position = location;
     1440                        }
     1441                }
     1442                return dojo.createElement(attrs); // DOMNode
     1443        }
    12721444
    12731445        // =============================
  • dojo/trunk/_base/query.js

    r15410 r15411  
    1 if(this["dojo"]){
     1if(dojo){
    22        dojo.provide("dojo._base.query");
    33        dojo.require("dojo._base.NodeList");
     4        dojo.require("dojo._base.lang");
    45}
    56
     
    13511352                root = root||getDoc();
    13521353                var od = root.ownerDocument||root.documentElement;
    1353                 caseSensitive = (root.contentType && root.contentType=="application/xml") || (!!od) && (d.isIE ? od.xml : (root.xmlVersion||od.xmlVersion));
     1354                // FIXME: Opera in XHTML mode doesn't detect case-sensitivity correctly
     1355                caseSensitive = (root.contentType && root.contentType=="application/xml") ||
     1356                                                (d.isOpera && root.doctype) ||
     1357                                                (!!od) &&
     1358                                                (d.isIE ? od.xml : (root.xmlVersion||od.xmlVersion));
    13541359                return _zip(getQueryFunc(query)(root)); // dojo.NodeList
    13551360        }
  • dojo/trunk/dojo.js

    r15409 r15411  
    147147                                var root = getRootNode().root; 
    148148                                if(!this["djConfig"]){ djConfig = {}; }
    149                                 // console.debug(root);
    150                                 // alert(root);
    151149                                djConfig["baseUrl"] = root;
    152150                        }
     
    161159                // it last
    162160                tmps.push(root+"_base.js");
    163        
     161
     162                var lastRoot = getRootNode().node;
     163                var isOpera = 0;
     164                var isWebKit = 0;
     165
     166                if(hostEnv == "browser"){
     167                        try{
     168                                var ua = navigator.userAgent;
     169                                isOpera = (ua.indexOf("Opera") >= 0);
     170                                isWebKit = (ua.indexOf("WebKit") >= 0);
     171                        }catch(e){ /* squelch */ }
     172                }
     173
     174                // Opera and Safari don't handle injected script tags in the right
     175                // order, so we resort to XHR to make things work there when we find
     176                // ourselves in a strict XHTML environment (e.g., document.write bombs
     177                // out)
     178                var injectXHRCode = function(src){
     179                        var xhr = new XMLHttpRequest();
     180                        xhr.open("GET", src, false);
     181                        xhr.send();
     182                        eval(xhr.responseText);
     183                }
     184       
     185                var injectScriptNode = function(src){
     186                        if(isWebKit){ return injectXHRCode(src); }
     187                        var head = document.getElementsByTagName("head")[0];
     188                        var script = document.createElement("script");
     189                        script.setAttribute("type", "text/javascript");
     190                        if(head.lastChild === lastRoot){
     191                                head.appendChild(script);
     192                        }else{
     193                                lastRoot.parentNode.insertBefore(script, lastRoot.nextSibling);
     194                        }
     195                        script.src = src;
     196                        lastRoot = script;
     197                }
    164198                for(var x=0; x < tmps.length; x++){
    165199                        if(isRhino || isSpidermonkey || (this.Jaxer && this.Jaxer.isOnServer)){
    166200                                load(tmps[x]);
    167201                        }else if(isFFExt){
    168                                 /*
    169                                 try{
    170                                         document.write("<scr"+"ipt type='text/javascript' src='"+tmps[x]+"'></scr"+"ipt>");
    171                                 }catch(e){
    172                                 */
    173                                         var l = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
    174                                                 .getService(Components.interfaces.mozIJSSubScriptLoader);
    175                                         l.loadSubScript(tmps[x], this)
    176                                 // }
     202                                var l = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
     203                                        .getService(Components.interfaces.mozIJSSubScriptLoader);
     204                                l.loadSubScript(tmps[x], this)
     205                        }else if(isOpera){ // opera fails silently!!
     206                                injectXHRCode(tmps[x]);
    177207                        }else{
    178208                                try{
    179209                                        document.write("<scr"+"ipt type='text/javascript' src='"+tmps[x]+"'></scr"+"ipt>");
    180210                                }catch(e){
    181                                         var lastRoot = getRootNode().node;
    182                                         var head = document.getElementsByTagName("head")[0];
    183                                         var script = document.createElement("script");
    184                                         script.setAttribute("type", "text/javascript");
    185                                         if(head.lastChild === lastRoot){
    186                                                 head.appendChild(script);
    187                                         }else{
    188                                                 lastRoot.parentNode.insertBefore(script, lastRoot.nextSibling);
    189                                         }
    190                                         script.src = tmps[x];
    191                                         lastRoot = script;
     211                                        // strict XHTML mode, no document.write
     212                                        injectScriptNode(tmps[x]);
    192213                                }
    193214                        }
Note: See TracChangeset for help on using the changeset viewer.