You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by we...@apache.org on 2022/11/25 12:29:48 UTC

[myfaces] branch main updated: https://issues.apache.org/jira/browse/MYFACES-4499: https://issues.apache.org/jira/browse/MYFACES-4498: fix for both issues on the 2.3 branch

This is an automated email from the ASF dual-hosted git repository.

werpu pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/myfaces.git


The following commit(s) were added to refs/heads/main by this push:
     new b0b912a49 https://issues.apache.org/jira/browse/MYFACES-4499: https://issues.apache.org/jira/browse/MYFACES-4498: fix for both issues on the 2.3 branch
     new 75c06e18c Merge pull request #394 from werpu/main
b0b912a49 is described below

commit b0b912a49b183f528c452506dd24fb101e10cc3a
Author: Werner Punz <we...@gmail.com>
AuthorDate: Fri Nov 25 13:03:18 2022 +0100

    https://issues.apache.org/jira/browse/MYFACES-4499:
    https://issues.apache.org/jira/browse/MYFACES-4498: fix for both issues on the 2.3 branch
---
 .../META-INF/resources/myfaces/_impl/_util/_Dom.js |  25 +++++
 .../resources/myfaces/_impl/_util/_Lang.js         |   4 +-
 .../META-INF/resources/myfaces/_impl/core/Impl.js  |  68 ++++++------
 .../myfaces/_impl/xhrCore/_AjaxResponse.js         | 117 ++++++---------------
 4 files changed, 96 insertions(+), 118 deletions(-)

diff --git a/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js b/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js
index e70f14b2b..d64000dee 100644
--- a/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js
+++ b/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Dom.js
@@ -1303,6 +1303,31 @@ _MF_SINGLTN(_PFX_UTIL + "_Dom", Object, /** @lends myfaces._impl._util._Dom.prot
 
     getNamedElementFromForm: function(form, elementId) {
         return form[elementId];
+    },
+
+    /**
+     * backport new faces codebase, should work from ie9 onwards
+     * (cutoff point)
+     * builds the ie nodes properly in a placeholder
+     * and bypasses a non script insert bug that way
+     * @param markup the markup code to be executed from
+     */
+    fromMarkup: function(markup) {
+
+        // https:// developer.mozilla.org/de/docs/Web/API/DOMParser license creative commons
+        var doc = document.implementation.createHTMLDocument("");
+        var lowerMarkup = markup.toLowerCase();
+        if (lowerMarkup.indexOf('<!doctype') != -1 ||
+            lowerMarkup.indexOf('<html') != -1 ||
+            lowerMarkup.indexOf('<head') != -1 ||
+            lowerMarkup.indexOf('<body') != -1) {
+            doc.documentElement.innerHTML = markup;
+            return doc.documentElement;
+        } else {
+            var dummyPlaceHolder = document.createElement("div");
+            dummyPlaceHolder.html(markup);
+            return dummyPlaceHolder;
+        }
     }
 });
 
diff --git a/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Lang.js b/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Lang.js
index c13736574..401f985c0 100644
--- a/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Lang.js
+++ b/api/src/main/javascript/META-INF/resources/myfaces/_impl/_util/_Lang.js
@@ -585,12 +585,12 @@ _MF_SINGLTN(_PFX_UTIL + "_Lang", Object, /** @lends myfaces._impl._util._Lang.pr
         }
         if (!this.FormDataDecoratorOther) {
             this.FormDataDecoratorOther = function (theFormData) {
-                this._valBuf = theFormData;
+                this._valBuf = theFormData || [];
                 this._idx = {};
             };
             _newCls = this.FormDataDecoratorOther;
             _newCls.prototype.append = function (key, val) {
-                this._valBuf.append(key, val);
+                this._valBuf.push([encodeURIComponent(key), encodeURIComponent(val)]);
                 this._idx[key] = true;
             };
             _newCls.prototype.hasKey = function (key) {
diff --git a/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/Impl.js b/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/Impl.js
index ff5e15719..2fac974d4 100644
--- a/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/Impl.js
+++ b/api/src/main/javascript/META-INF/resources/myfaces/_impl/core/Impl.js
@@ -100,8 +100,8 @@ _MF_SINGLTN(_PFX_CORE + "Impl", _MF_OBJECT, /**  @lends myfaces._impl.core.Impl.
         }
 
         if (!form
-                || !form.nodeName
-                || form.nodeName.toLowerCase() != "form") {
+            || !form.nodeName
+            || form.nodeName.toLowerCase() != "form") {
             throw new Error(this._Lang.getMessage("ERR_VIEWSTATE"));
         }
 
@@ -142,7 +142,7 @@ _MF_SINGLTN(_PFX_CORE + "Impl", _MF_OBJECT, /**  @lends myfaces._impl.core.Impl.
          *all the time
          **/
         var _Lang = this._Lang,
-                _Dom = this._Dom;
+            _Dom = this._Dom;
         /*assert if the onerror is set and once if it is set it must be of type function*/
         _Lang.assertType(options.onerror, "function");
         /*assert if the onevent is set and once if it is set it must be of type function*/
@@ -209,8 +209,8 @@ _MF_SINGLTN(_PFX_CORE + "Impl", _MF_OBJECT, /**  @lends myfaces._impl.core.Impl.
          * with detached objects
          */
         var form = (options.myfaces && options.myfaces.form) ?
-                _Lang.byId(options.myfaces.form) :
-                this._getForm(elem, event);
+            _Lang.byId(options.myfaces.form) :
+            this._getForm(elem, event);
 
         /**
          * faces2.2 client window must be part of the issuing form so it is encoded
@@ -365,8 +365,8 @@ _MF_SINGLTN(_PFX_CORE + "Impl", _MF_OBJECT, /**  @lends myfaces._impl.core.Impl.
         //for now we turn off the transport auto selection, to enable 2.0 backwards compatibility
         //on protocol level, the file upload only can be turned on if the auto selection is set to true
         var getConfig = this._RT.getLocalOrGlobalConfig,
-                _Lang = this._Lang,
-                _Dom = this._Dom;
+            _Lang = this._Lang,
+            _Dom = this._Dom;
 
         var transportAutoSelection = getConfig(context, "transportAutoSelection", true);
         /*var isMultipart = (transportAutoSelection && _Dom.getAttribute(form, "enctype") == "multipart/form-data") ?
@@ -377,7 +377,7 @@ _MF_SINGLTN(_PFX_CORE + "Impl", _MF_OBJECT, /**  @lends myfaces._impl.core.Impl.
             return getConfig(context, "transportType", "xhrQueuedPost");
         }
         var multiPartCandidate = _Dom.isMultipartCandidate((!getConfig(context, "pps", false)) ?
-                form : passThrgh[this.P_EXECUTE]);
+            form : passThrgh[this.P_EXECUTE]);
         var multipartForm = (_Dom.getAttribute(form, "enctype") || "").toLowerCase() == "multipart/form-data";
         //spec section jsdoc, if we have a multipart candidate in our execute (aka fileupload)
         //and the form is not multipart then we have to raise an error
@@ -398,8 +398,8 @@ _MF_SINGLTN(_PFX_CORE + "Impl", _MF_OBJECT, /**  @lends myfaces._impl.core.Impl.
          *
          */
         var transportType = (!isMultipart) ?
-                getConfig(context, "transportType", "xhrQueuedPost") :
-                getConfig(context, "transportType", "multipartQueuedPost");
+            getConfig(context, "transportType", "xhrQueuedPost") :
+            getConfig(context, "transportType", "multipartQueuedPost");
         if (!this._transport[transportType]) {
             //throw new Error("Transport type " + transportType + " does not exist");
             throw new Error(_Lang.getMessage("ERR_TRANSPORT", null, transportType));
@@ -428,14 +428,14 @@ _MF_SINGLTN(_PFX_CORE + "Impl", _MF_OBJECT, /**  @lends myfaces._impl.core.Impl.
         //false
         srcStr = this._Lang.trim(srcStr);
         var offset = 1,
-                vals = (srcStr) ? srcStr.split(/\s+/) : [],
-                idIdx = (vals.length) ? _Lang.arrToMap(vals, offset) : {},
+            vals = (srcStr) ? srcStr.split(/\s+/) : [],
+            idIdx = (vals.length) ? _Lang.arrToMap(vals, offset) : {},
 
-        //helpers to improve speed and compression
-                none = idIdx[this.IDENT_NONE],
-                all = idIdx[this.IDENT_ALL],
-                theThis = idIdx[this.IDENT_THIS],
-                theForm = idIdx[this.IDENT_FORM];
+            //helpers to improve speed and compression
+            none = idIdx[this.IDENT_NONE],
+            all = idIdx[this.IDENT_ALL],
+            theThis = idIdx[this.IDENT_THIS],
+            theForm = idIdx[this.IDENT_FORM];
 
         if (none) {
             //in case of none nothing is returned
@@ -538,10 +538,10 @@ _MF_SINGLTN(_PFX_CORE + "Impl", _MF_OBJECT, /**  @lends myfaces._impl.core.Impl.
 
         if (faces.getProjectStage() === "Development" && this._errListeners.length() == 0 && !context["onerror"]) {
             var DIVIDER = "--------------------------------------------------------",
-                    defaultErrorOutput = myfaces._impl.core._Runtime.getGlobalConfig("defaultErrorOutput", alert),
-                    finalMessage = [],
-            //we remap the function to achieve a better compressability
-                    pushMsg = _Lang.hitch(finalMessage, finalMessage.push);
+                defaultErrorOutput = myfaces._impl.core._Runtime.getGlobalConfig("defaultErrorOutput", alert),
+                finalMessage = [],
+                //we remap the function to achieve a better compressability
+                pushMsg = _Lang.hitch(finalMessage, finalMessage.push);
 
             (errorMessage) ? pushMsg(_Lang.getMessage("MSG_ERROR_MESSAGE") + " " + errorMessage + "\n") : null;
 
@@ -591,7 +591,7 @@ _MF_SINGLTN(_PFX_CORE + "Impl", _MF_OBJECT, /**  @lends myfaces._impl.core.Impl.
             } catch (e) {
                 var impl = myfaces._impl.core._Runtime.getGlobalConfig("facesAjaxImpl", myfaces._impl.core.Impl);
                 impl.sendError(request, context, this.CLIENT_ERROR, "ErrorRetrievingResponse",
-                        _Lang.getMessage("ERR_CONSTRUCT", e.toString()));
+                    _Lang.getMessage("ERR_CONSTRUCT", e.toString()));
 
                 //client errors are not swallowed
                 throw e;
@@ -629,11 +629,11 @@ _MF_SINGLTN(_PFX_CORE + "Impl", _MF_OBJECT, /**  @lends myfaces._impl.core.Impl.
             return this.separatorchar;
         }
         var SEPARATOR_CHAR = "separatorchar",
-                found = false,
-                getConfig = myfaces._impl.core._Runtime.getGlobalConfig,
-                scriptTags = document.getElementsByTagName("script");
+            found = false,
+            getConfig = myfaces._impl.core._Runtime.getGlobalConfig,
+            scriptTags = document.getElementsByTagName("script");
         for (var i = 0; i < scriptTags.length && !found; i++) {
-            if (scriptTags[i].src.search(/\/jakarta\.faces\.resource.*\/faces\.js.*separator/) != -1) {
+            if (scriptTags[i] && scriptTags[i] && scriptTags[i].src.search(/\/jakarta\.faces\.resource.*\/faces\.js.*separator/) != -1) {
                 found = true;
                 var result = scriptTags[i].src.match(/separator=([^&;]*)/);
                 this._separator = decodeURIComponent(result[1]);
@@ -653,17 +653,17 @@ _MF_SINGLTN(_PFX_CORE + "Impl", _MF_OBJECT, /**  @lends myfaces._impl.core.Impl.
 
         if (!this._projectStage) {
             var PRJ_STAGE = "projectStage",
-                    STG_PROD = "Production",
+                STG_PROD = "Production",
 
-                    scriptTags = document.getElementsByTagName("script"),
-                    getConfig = myfaces._impl.core._Runtime.getGlobalConfig,
-                    projectStage = null,
-                    found = false,
-                    allowedProjectStages = {STG_PROD:1, "Development":1, "SystemTest":1, "UnitTest":1};
+                scriptTags = document.getElementsByTagName("script"),
+                getConfig = myfaces._impl.core._Runtime.getGlobalConfig,
+                projectStage = null,
+                found = false,
+                allowedProjectStages = {STG_PROD:1, "Development":1, "SystemTest":1, "UnitTest":1};
 
             /* run through all script tags and try to find the one that includes faces.js */
             for (var i = 0; i < scriptTags.length && !found; i++) {
-                if (scriptTags[i].src.search(/\/jakarta\.faces\.resource\/faces\.js.*ln=jakarta\.faces/) != -1) {
+                if (scriptTags[i] && scriptTags[i] && scriptTags[i].src.search(/\/jakarta\.faces\.resource\/faces\.js.*ln=jakarta\.faces/) != -1) {
                     var result = scriptTags[i].src.match(/stage=([^&;]*)/);
                     found = true;
                     if (result) {
@@ -788,7 +788,7 @@ _MF_SINGLTN(_PFX_CORE + "Impl", _MF_OBJECT, /**  @lends myfaces._impl.core.Impl.
             var finalMsg = [];
             finalMsg.push(exception.message);
             this.sendError(request, context,
-                    mfInternal.title || this.CLIENT_ERROR, mfInternal.name || exception.name, finalMsg.join("\n"), mfInternal.caller, mfInternal.callFunc);
+                mfInternal.title || this.CLIENT_ERROR, mfInternal.name || exception.name, finalMsg.join("\n"), mfInternal.caller, mfInternal.callFunc);
         }
     },
 
diff --git a/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxResponse.js b/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxResponse.js
index a0a807c07..c12c9282f 100644
--- a/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxResponse.js
+++ b/api/src/main/javascript/META-INF/resources/myfaces/_impl/xhrCore/_AjaxResponse.js
@@ -607,49 +607,27 @@ _MF_SINGLTN(_PFX_XHR + "_AjaxResponse", _MF_OBJECT, /** @lends myfaces._impl.xhr
     _replaceHead: function (request, context, newData) {
 
         var _Lang = this._Lang,
-            _Dom = this._Dom,
-            isWebkit = this._RT.browser.isWebKit,
-            //we have to work around an xml parsing bug in Webkit
-            //see https://issues.apache.org/jira/browse/MYFACES-3061
-            doc = (!isWebkit) ? _Lang.parseXML(newData) : null,
-            newHead = null;
-
-        if (!isWebkit && _Lang.isXMLParseError(doc)) {
-            doc = _Lang.parseXML(newData.replace(/<!\-\-[\s\n]*<!\-\-/g, "<!--").replace(/\/\/-->[\s\n]*\/\/-->/g, "//-->"));
-        }
+            _Dom = this._Dom;
 
-        if (isWebkit || _Lang.isXMLParseError(doc)) {
-            //the standard xml parser failed we retry with the stripper
-            var parser = new (this._RT.getGlobalConfig("updateParser", myfaces._impl._util._HtmlStripper))();
-            var headData = parser.parse(newData, "head");
-            //We cannot avoid it here, but we have reduced the parsing now down to the bare minimum
-            //for further processing
-            newHead = _Lang.parseXML("<head>" + headData + "</head>");
-            //last and slowest option create a new head element and let the browser
-            //do its slow job
-            if (_Lang.isXMLParseError(newHead)) {
-                try {
-                    newHead = _Dom.createElement("head");
-                    newHead.innerHTML = headData;
-                } catch (e) {
-                    //we give up no further fallbacks
-                    throw this._raiseError(new Error(), "Error head replacement failed reason:" + e.toString(), "_replaceHead");
-                }
-            }
-        } else {
-            //parser worked we go on
-            newHead = doc.getElementsByTagName("head")[0];
-        }
 
-        var oldTags = _Dom.findByTagNames(document.getElementsByTagName("head")[0], {"link": true, "style": true});
-        _Dom.runCss(newHead, true);
-        _Dom.deleteItems(oldTags);
+        var newDom = _Dom.fromMarkup(newData);
+
+        //newHead = _Dom.createElement("head");
+        //newHead.innerHTML = parsedHead.content();
+
+        var head = document.getElementsByTagName("head")[0];
+        var newHead = newDom.getElementsByTagName("head")[0];
+        var oldTags = head.childNodes;
 
-        //var oldTags = _Dom.findByTagNames(document.getElementsByTagName("head")[0], {"script": true});
-        //_Dom.deleteScripts(oldTags);
-        _Dom.runScripts(newHead, true);
+        _Dom.deleteItems(_Lang.objToArray(oldTags));
+        var childNodes = Lang.objToArray(newHead.childNodes);
 
-        return doc;
+        var placeHolder = document.createElement("meta");
+
+        head.appendChild(placeHolder);
+        _Dom.replaceElements(placeHolder, childNodes);
+        _Dom.runScripts(head);
+        return head;
     },
 
     _addResourceToHead: function (request, context, newData) {
@@ -673,61 +651,36 @@ _MF_SINGLTN(_PFX_XHR + "_AjaxResponse", _MF_OBJECT, /** @lends myfaces._impl.xhr
     _replaceBody: function (request, context, newData /*varargs*/) {
         var _RT = this._RT,
             _Dom = this._Dom,
-            _Lang = this._Lang,
 
-            oldBody = document.getElementsByTagName("body")[0],
-            placeHolder = document.createElement("div"),
-            isWebkit = _RT.browser.isWebKit;
+        oldBody = document.getElementsByTagName("body")[0],
+        placeHolder = document.createElement("div");
 
         placeHolder.id = "myfaces_bodyplaceholder";
 
+        var newDom = _Dom.fromMarkup(newData);
+        var newBodyData = newDom.getElementsByTagName("body")[0];
+
         _Dom._removeChildNodes(oldBody);
         oldBody.innerHTML = "";
         oldBody.appendChild(placeHolder);
 
-        var bodyData, doc = null, parser;
-
-        //we have to work around an xml parsing bug in Webkit
-        //see https://issues.apache.org/jira/browse/MYFACES-3061
-        if (!isWebkit) {
-            doc = (arguments.length > 3) ? arguments[3] : _Lang.parseXML(newData);
-        }
-
-        if (!isWebkit && _Lang.isXMLParseError(doc)) {
-            doc = _Lang.parseXML(newData.replace(/<!\-\-[\s\n]*<!\-\-/g, "<!--").replace(/\/\/-->[\s\n]*\/\/-->/g, "//-->"));
-        }
 
-        if (isWebkit || _Lang.isXMLParseError(doc)) {
-            //the standard xml parser failed we retry with the stripper
-
-            parser = new (_RT.getGlobalConfig("updateParser", myfaces._impl._util._HtmlStripper))();
-
-            bodyData = parser.parse(newData, "body");
-        } else {
-            //parser worked we go on
-            var newBodyData = doc.getElementsByTagName("body")[0];
-
-            //speedwise we serialize back into the code
-            //for code reduction, speedwise we will take a small hit
-            //there which we will clean up in the future, but for now
-            //this is ok, I guess, since replace body only is a small subcase
-            //bodyData = _Lang.serializeChilds(newBodyData);
-            var browser = _RT.browser;
-            if (!browser.isIEMobile || browser.isIEMobile >= 7) {
-                //TODO check what is failing there
-                for (var cnt = 0; cnt < newBodyData.attributes.length; cnt++) {
-                    var value = newBodyData.attributes[cnt].value;
-                    if (value)
-                        _Dom.setAttribute(oldBody, newBodyData.attributes[cnt].name, value);
-                }
+        //speedwise we serialize back into the code
+        //for code reduction, speedwise we will take a small hit
+        //there which we will clean up in the future, but for now
+        //this is ok, I guess, since replace body only is a small subcase
+        //bodyData = _Lang.serializeChilds(newBodyData);
+        var browser = _RT.browser;
+        if (!browser.isIEMobile || browser.isIEMobile >= 7) {
+            //TODO check what is failing there
+            for (var cnt = 0; cnt < newBodyData.attributes.length; cnt++) {
+                var value = newBodyData.attributes[cnt].value;
+                if (value)
+                    _Dom.setAttribute(oldBody, newBodyData.attributes[cnt].name, value);
             }
         }
-        //we cannot serialize here, due to escape problems
-        //we must parse, this is somewhat unsafe but should be safe enough
-        parser = new (_RT.getGlobalConfig("updateParser", myfaces._impl._util._HtmlStripper))();
-        bodyData = parser.parse(newData, "body");
 
-        var returnedElement = this.replaceHtmlItem(request, context, placeHolder, bodyData);
+        var returnedElement = this.replaceHtmlItem(request, context, placeHolder, newBodyData.innerHTML);
 
         if (returnedElement) {
             this._pushOperationResult(context, returnedElement);