/*!
* UI development toolkit for HTML5 (OpenUI5)
* (c) Copyright 2009-2018 SAP SE or an SAP affiliate company.
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
*/
/**
* FormattedText
helper.
* This class handles the AnchorGeneration
for the FormattedText
control.
*/
sap.ui.define([
"sap/ui/base/Metadata",
"sap/m/library",
"sap/base/security/URLWhitelist"
], function(Metadata, library, URLWhitelist) {
"use strict";
// shortcut for sap.m.LinkConversion
var LinkConversion = library.LinkConversion;
var AnchorGenerator = Metadata.createClass("sap.m.FormattedTextAnchorGenerator", {});
var LINK_SEARCH_PATTERN = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;()$]*[-A-Z0-9+&@#\/%=~_|])/gim;
var WWW_DETECTION_PATTERN = /(www\.[^\s><]+(\b|$))/gim;
var WWW_DETECTED_LINKS_PREFIX = "//";
var DETECT_HTML_TAGS = /<(?:"[^"]*"['"]*|'[^']*'['"]*|[^'">])+(?!\/\s\*)>/gim;
var EXISTING_ANCHOR_TAGS = /]*>([^<]+)<\/a>/gim;
var ENTITIES_TO_SKIP = [DETECT_HTML_TAGS, EXISTING_ANCHOR_TAGS];
/**
* Generates anchors based on the provided configuration.
* @param {string} sText The text to be processed
* @param {sap.m.LinkConversion} sLinkConversionStrategy The link conversion strategy
* @param {string} sTarget The target attribute of the newly created anchors
* @static
* @public
* @returns {string} The resulting text after the anchor generation
*/
AnchorGenerator.generateAnchors = function (sText, sLinkConversionStrategy, sTarget) {
if (sLinkConversionStrategy === LinkConversion.ProtocolOnly) {
sText = AnchorGenerator._createAnchors(sText, LINK_SEARCH_PATTERN, sTarget);
}
if (sLinkConversionStrategy === LinkConversion.All) {
sText = AnchorGenerator._createAnchors(sText, LINK_SEARCH_PATTERN, sTarget);
sText = AnchorGenerator._createAnchors(sText, WWW_DETECTION_PATTERN, sTarget, WWW_DETECTED_LINKS_PREFIX);
}
return sText;
};
/**
* Creates a positioning object from a starting point and length.
* @param {number} iIndex
* @param {number} iLength
* @returns {{iStartPos: (number), iEndPos: (number)}}
* @private
*/
AnchorGenerator._createPositionObject = function (iIndex, iLength) {
return {iStartPos: iIndex, iEndPos: iIndex + iLength};
};
/**
* Checks if the second object is nested inside the first one.
* @param {object} oFirst
* @param {object} oSecond
* @returns {boolean}
* @private
*/
AnchorGenerator._isNested = function (oFirst, oSecond) {
return oFirst.iStartPos < oSecond.iStartPos && oFirst.iEndPos > oSecond.iEndPos;
};
/**
* Checks if any of the blacklisted positions coincide with the newly discovered link that's about to be created.
* @param {Array