|
134 | 134 | * @type {RegExp} wordCharRegExp
|
135 | 135 | */
|
136 | 136 | _this.wordCharRegExp = new RegExp('[' + regex_lib_1.alphaNumericAndMarksCharsStr + ']');
|
137 |
| -<span id='Autolinker-matcher-Url-property-openParensRe'> /** |
138 |
| -</span> * The regular expression to match opening parenthesis in a URL match. |
139 |
| - * |
140 |
| - * This is to determine if we have unbalanced parenthesis in the URL, and to |
141 |
| - * drop the final parenthesis that was matched if so. |
142 |
| - * |
143 |
| - * Ex: The text "(check out: wikipedia.com/something_(disambiguation))" |
144 |
| - * should only autolink the inner "wikipedia.com/something_(disambiguation)" |
145 |
| - * part, so if we find that we have unbalanced parenthesis, we will drop the |
146 |
| - * last one for the match. |
147 |
| - * |
148 |
| - * @protected |
149 |
| - * @property {RegExp} |
150 |
| - */ |
151 |
| - _this.openParensRe = /\(/g; |
152 |
| -<span id='Autolinker-matcher-Url-property-closeParensRe'> /** |
153 |
| -</span> * The regular expression to match closing parenthesis in a URL match. See |
154 |
| - * {@link #openParensRe} for more information. |
155 |
| - * |
156 |
| - * @protected |
157 |
| - * @property {RegExp} |
158 |
| - */ |
159 |
| - _this.closeParensRe = /\)/g; |
160 | 137 | _this.stripPrefix = cfg.stripPrefix;
|
161 | 138 | _this.stripTrailingSlash = cfg.stripTrailingSlash;
|
162 | 139 | _this.decodePercentEncoding = cfg.decodePercentEncoding;
|
|
186 | 163 | if (offset > 0 && protocolRelativeMatch && this.wordCharRegExp.test(prevChar)) {
|
187 | 164 | continue;
|
188 | 165 | }
|
| 166 | + // If the URL ends with a question mark, don't include the question |
| 167 | + // mark as part of the URL. We'll assume the question mark was the |
| 168 | + // end of a sentence, such as: "Going to google.com?" |
189 | 169 | if (/\?$/.test(matchStr)) {
|
190 | 170 | matchStr = matchStr.substr(0, matchStr.length - 1);
|
191 | 171 | }
|
192 |
| - // Handle a closing parenthesis at the end of the match, and exclude |
193 |
| - // it if there is not a matching open parenthesis in the match |
194 |
| - // itself. |
| 172 | + // Handle a closing parenthesis or square bracket at the end of the |
| 173 | + // match, and exclude it if there is not a matching open parenthesis |
| 174 | + // or square bracket in the match itself. |
195 | 175 | if (this.matchHasUnbalancedClosingParen(matchStr)) {
|
196 | 176 | matchStr = matchStr.substr(0, matchStr.length - 1); // remove the trailing ")"
|
197 | 177 | }
|
|
219 | 199 | return matches;
|
220 | 200 | };
|
221 | 201 | <span id='Autolinker-matcher-Url-method-matchHasUnbalancedClosingParen'> /**
|
222 |
| -</span> * Determines if a match found has an unmatched closing parenthesis. If so, |
223 |
| - * this parenthesis will be removed from the match itself, and appended |
224 |
| - * after the generated anchor tag. |
| 202 | +</span> * Determines if a match found has an unmatched closing parenthesis or |
| 203 | + * square bracket. If so, the parenthesis or square bracket will be removed |
| 204 | + * from the match itself, and appended after the generated anchor tag. |
225 | 205 | *
|
226 | 206 | * A match may have an extra closing parenthesis at the end of the match
|
227 | 207 | * because the regular expression must include parenthesis for URLs such as
|
228 | 208 | * "wikipedia.com/something_(disambiguation)", which should be auto-linked.
|
229 | 209 | *
|
230 | 210 | * However, an extra parenthesis *will* be included when the URL itself is
|
231 |
| - * wrapped in parenthesis, such as in the case of "(wikipedia.com/something_(disambiguation))". |
| 211 | + * wrapped in parenthesis, such as in the case of: |
| 212 | + * "(wikipedia.com/something_(disambiguation))" |
232 | 213 | * In this case, the last closing parenthesis should *not* be part of the
|
233 | 214 | * URL itself, and this method will return `true`.
|
234 | 215 | *
|
| 216 | + * For square brackets in URLs such as in PHP arrays, the same behavior as |
| 217 | + * parenthesis discussed above should happen: |
| 218 | + * "[http://www.example.com/foo.php?bar[]=1&bar[]=2&bar[]=3]" |
| 219 | + * The closing square bracket should not be part of the URL itself, and this |
| 220 | + * method will return `true`. |
| 221 | + * |
235 | 222 | * @protected
|
236 | 223 | * @param {String} matchStr The full match string from the {@link #matcherRegex}.
|
237 |
| - * @return {Boolean} `true` if there is an unbalanced closing parenthesis at |
238 |
| - * the end of the `matchStr`, `false` otherwise. |
| 224 | + * @return {Boolean} `true` if there is an unbalanced closing parenthesis or |
| 225 | + * square bracket at the end of the `matchStr`, `false` otherwise. |
239 | 226 | */
|
240 | 227 | UrlMatcher.prototype.matchHasUnbalancedClosingParen = function (matchStr) {
|
241 |
| - var lastChar = matchStr.charAt(matchStr.length - 1); |
242 |
| - if (lastChar === ')') { |
243 |
| - var openParensMatch = matchStr.match(this.openParensRe), closeParensMatch = matchStr.match(this.closeParensRe), numOpenParens = (openParensMatch && openParensMatch.length) || 0, numCloseParens = (closeParensMatch && closeParensMatch.length) || 0; |
244 |
| - if (numOpenParens < numCloseParens) { |
245 |
| - return true; |
| 228 | + var endChar = matchStr.charAt(matchStr.length - 1); |
| 229 | + var startChar; |
| 230 | + if (endChar === ')') { |
| 231 | + startChar = '('; |
| 232 | + } |
| 233 | + else if (endChar === ']') { |
| 234 | + startChar = '['; |
| 235 | + } |
| 236 | + else { |
| 237 | + return false; // not a close parenthesis or square bracket |
| 238 | + } |
| 239 | + // Find if there are the same number of open braces as close braces in |
| 240 | + // the URL string, minus the last character (which we have already |
| 241 | + // determined to be either ')' or ']' |
| 242 | + var numOpenBraces = 0; |
| 243 | + for (var i = 0, len = matchStr.length - 1; i < len; i++) { |
| 244 | + var char = matchStr.charAt(i); |
| 245 | + if (char === startChar) { |
| 246 | + numOpenBraces++; |
| 247 | + } |
| 248 | + else if (char === endChar) { |
| 249 | + numOpenBraces = Math.max(numOpenBraces - 1, 0); |
246 | 250 | }
|
247 | 251 | }
|
| 252 | + // If the number of open braces matches the number of close braces in |
| 253 | + // the URL minus the last character, then the match has *unbalanced* |
| 254 | + // braces because of the last character. Example of unbalanced braces |
| 255 | + // from the regex match: |
| 256 | + // "http://example.com?a[]=1]" |
| 257 | + if (numOpenBraces === 0) { |
| 258 | + return true; |
| 259 | + } |
248 | 260 | return false;
|
249 | 261 | };
|
250 | 262 | <span id='Autolinker-matcher-Url-method-matchHasInvalidCharAfterTld'> /**
|
|
0 commit comments