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  * @class
 19  * @name _HtmlStripper
 20  * @memberOf myfaces._impl._util
 21  * @extends myfaces._impl.core._Runtime
 22  * @description
 23  *  Fallback routine if the browser embedded xml parser fails on the document
 24  *  This fallback is not failsafe but should give enough cover to handle all cases
 25  */
 26 
 27 /** @namespace myfaces._impl._util._HtmlStripper */
 28 _MF_CLS(_PFX_UTIL + "_HtmlStripper", _MF_OBJECT, /** @lends myfaces._impl._util._HtmlStripper.prototype */ {
 29 
 30     /**
 31      * main parse routine parses the document for a given tag name
 32      *
 33      *
 34      * @param theString  the markup string to be parsed
 35      * @param tagNameStart the tag name to be parsed for
 36      */
 37     parse : function(theString, tagNameStart) {
 38 
 39         var BEGIN_TAG = "html",
 40                 _tagStart = -1,
 41                 _tagEnd = -1,
 42                 _contentStart = -1,
 43                 _contentEnd = -1,
 44                 _tokenPos = 0,
 45                 _tokenForward = 1,
 46                 tagNameStart = (!tagNameStart) ? BEGIN_TAG : tagNameStart;
 47 
 48         var proposedTagStartPos = theString.indexOf("<" + tagNameStart);
 49         var _T = this;
 50 
 51         //we use closures instead of private methods to improve the compressability
 52 
 53         var isValidPositionCombination = function(pos1, pos2, pos3, pos4) {
 54             return pos1 <= pos2 && pos3 <= pos4;
 55         };
 56 
 57         /**
 58          * trace for a forward comment
 59          *
 60          * @param theStr the string to be checked
 61          * @param tagPos the tag position from which the check onwards has to be perfomed
 62          * @return true in case a comment is found
 63          */
 64         var checkForwardForComment = function(theStr, tagPos) {
 65             var toCheck = theStr.substring(tagPos),
 66                     indexOf = _T._Lang.hitch(toCheck, toCheck.indexOf),
 67                     firstBeginComment = indexOf("<!--"),
 68                     firstEndComment = indexOf("-->"),
 69 
 70                     firstBeginCDATA = indexOf("<[CDATA["),
 71                     firstEndCDATA = indexOf("]]>");
 72 
 73             if (isValidPositionCombination(firstBeginComment, firstEndComment, firstBeginCDATA, firstEndCDATA)) {
 74                 return true;
 75             }
 76 
 77             return firstBeginComment <= firstEndComment && firstBeginCDATA <= firstEndCDATA;
 78         };
 79 
 80         /**
 81          * check backwards for a comment
 82          *
 83          * @param theStr the check string
 84          * @param tagPos the tag position from which the check should be performed
 85          * @return true in case a comment is found
 86          */
 87         var checkBackForComment = function(theStr, tagPos) {
 88             var toCheck = theStr.substring(tagPos),
 89                     indexOf = _T._Lang.hitch(toCheck, toCheck.indexOf),
 90                     lastBeginComment = indexOf("<!--"),
 91                     lastEndComment = indexOf("-->"),
 92                     lastBeginCDATA = indexOf("<[CDATA["),
 93                     lastEndCDATA = indexOf("]]>");
 94 
 95             if (isValidPositionCombination(lastBeginComment, lastEndComment, lastBeginCDATA, lastEndCDATA)) {
 96                 //TODO we have to handle the embedded cases, for now we leave them out
 97                 return true;
 98             }
 99         };
100 
101         //no need for ll parsing a handful of indexofs instead of slower regepx suffices
102         var theSubStr = this._Lang.hitch(theString, theString.substring);
103         while (_contentStart == -1 && proposedTagStartPos != -1) {
104             if (checkBackForComment(theString, proposedTagStartPos)) {
105                 _tagStart = proposedTagStartPos;
106                 _contentStart = proposedTagStartPos + theSubStr(proposedTagStartPos).indexOf(">") + 1;
107             }
108             proposedTagStartPos = theSubStr(proposedTagStartPos + tagNameStart.length + 2).indexOf("<" + tagNameStart);
109         }
110 
111         var proposedEndTagPos = theString.lastIndexOf("</" + tagNameStart);
112         while (_contentEnd == -1 && proposedEndTagPos > 0) {
113             if (checkForwardForComment(theString, proposedEndTagPos)) {
114                 _tagEnd = proposedEndTagPos;
115                 _contentEnd = proposedEndTagPos;
116             }
117             proposedTagStartPos = theSubStr(proposedTagStartPos - tagNameStart.length - 2).lastIndexOf("</" + tagNameStart);
118         }
119         if (_contentStart != -1 && _contentEnd != -1) {
120             return theSubStr(_contentStart, _contentEnd);
121         }
122         return null;
123     }
124 });
125 
126 
127 
128