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 myfaces._impl.core._Runtime.extendClass("myfaces._impl._util._HtmlStripper", Object, 29 /** @lends myfaces._impl._util._HtmlStripper.prototype */ 30 { 31 BEGIN_TAG: "html", 32 END_TAG: "lmth", 33 /** 34 * main parse routine parses the document for a given tag name 35 * 36 * 37 * @param theString the markup string to be parsed 38 * @param tagNameStart the tag name to be parsed for 39 */ 40 parse : function(theString, tagNameStart) { 41 this.tokens = theString.split(""); 42 this.tagAttributes = {}; 43 44 this._tagStart = -1; 45 this._tagEnd = -1; 46 47 this._contentStart = -1; 48 this._contentEnd = -1; 49 this._tokenPos = 0; 50 51 this._tokenForward = 1; 52 53 this.tagNameStart = (!tagNameStart) ? this.BEGIN_TAG : tagNameStart; 54 55 //no need for ll parsing a handful of indexofs instead of slower regepx suffices 56 57 var proposedTagStartPos = theString.indexOf("<"+tagNameStart); 58 59 while(this._contentStart == -1 && proposedTagStartPos != -1) { 60 if(this.checkBackForComment(theString, proposedTagStartPos)) { 61 this._tagStart = proposedTagStartPos; 62 this._contentStart = proposedTagStartPos+theString.substring(proposedTagStartPos).indexOf(">")+1; 63 } 64 proposedTagStartPos = theString.substring(proposedTagStartPos+tagNameStart.length+2).indexOf("<"+tagNameStart); 65 } 66 67 var proposedEndTagPos = theString.lastIndexOf("</"+tagNameStart); 68 while(this._contentEnd == -1 && proposedEndTagPos > 0) { 69 if(this.checkForwardForComment(theString, proposedEndTagPos)) { 70 this._tagEnd = proposedEndTagPos; 71 this._contentEnd = proposedEndTagPos; 72 } 73 proposedTagStartPos = theString.substring(proposedTagStartPos-tagNameStart.length-2).lastIndexOf("</"+tagNameStart); 74 } 75 if(this._contentStart != -1 && this._contentEnd != -1) { 76 return theString.substring(this._contentStart, this._contentEnd); 77 } 78 return null; 79 }, 80 81 checkForwardForComment: function(theStr, tagPos) { 82 var toCheck = theStr.substring(tagPos); 83 var firstBeginComment = toCheck.indexOf("<!--"); 84 var firstEndComment = toCheck.indexOf("-->"); 85 86 var firstBeginCDATA = toCheck.indexOf("<[CDATA["); 87 var firstEndCDATA = toCheck.indexOf("]]>"); 88 89 if(this.isValidPositionCombination(firstBeginComment, firstEndComment, firstBeginCDATA, firstEndCDATA)) { 90 return true; 91 } 92 93 return firstBeginComment <= firstEndComment && firstBeginCDATA <= firstEndCDATA; 94 }, 95 96 checkBackForComment: function(theStr, tagPos) { 97 var toCheck = theStr.substring(tagPos); 98 var lastBeginComment = toCheck.lastIndexOf("<!--"); 99 var lastEndComment = toCheck.lastIndexOf("-->"); 100 101 var lastBeginCDATA = toCheck.lastIndexOf("<[CDATA["); 102 var lastEndCDATA = toCheck.lastIndexOf("]]>"); 103 104 105 if(this.isValidPositionCombination(lastBeginComment, lastEndComment, lastBeginCDATA, lastEndCDATA)) { 106 //TODO we have to handle the embedded cases, for now we leave them out 107 return true; 108 } 109 110 }, 111 112 isValidPositionCombination: function(pos1, pos2, pos3, pos4) { 113 return pos1 <= pos2 && pos3 <= pos4; 114 }, 115 116 isFullyEmbedded: function(pos1, pos2, embedPos1, embedPos2) { 117 return embedPos1 < pos1 < pos2 < embedPos2; 118 }, 119 120 isPartiallyEmbedded: function(pos1, pos2, embedPos1, embedPos2) { 121 return embedPos1 < pos1 < embedPos2 < pos2 || pos1 < embedPos1 < pos2 < embedPos2 ; 122 } 123 124 }); 125 126 127 128