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