Пример #1
0
		/// <summary>
		/// Process RSDN link tag
		/// </summary>
		/// <param name="name">Regexp match with RSDN link tag</param>
		/// <returns>Formatted link as HtmlAnchor</returns>
		protected virtual HtmlAnchor ProcessRsdnLinkAsAnchor(Match name)
		{
			var link =
				new HtmlAnchor
				{
					Target = "_blank",
					HRef = $"{GetPathToRoot()}/Forum/Info/{name.Groups[1].Value.EncodeAgainstXSS()}.aspx",
					InnerText = name.Groups[1].Value
				};
			return AddClass(link, "m");
		}
Пример #2
0
		/// <summary>
		/// Renders HTML for url.
		/// </summary>
		protected static string RenderHtmlAnchor(HtmlAnchor htmlAnchor)
		{
			var stringBuilder = new StringBuilder();
			stringBuilder.Append("<a");

			foreach(var attribute in htmlAnchor.Attributes.OrderBy(a => a.Key))
				stringBuilder.AppendFormat(
					" {0}=\"{1}\"",
					attribute.Key,
					attribute.Value);

			var inner = htmlAnchor.InnerHtml;
			if(string.IsNullOrWhiteSpace(inner))
				inner = htmlAnchor.InnerText;

			if(!string.IsNullOrWhiteSpace(inner))
				stringBuilder.AppendFormat(">{0}</a>", inner);
			else
				stringBuilder.Append(" />");

			return stringBuilder.ToString();
		}
Пример #3
0
		/// <summary>
		/// Format RSDN URLs to hyperlinks.
		/// Used in both, explicitly &amp; implicitly specified links.
		/// </summary>
		/// <param name="urlMatch">Regex match with URL address.</param>
		/// <param name="link">HtmlLink, initialized by default</param>
		/// <returns>true - processed by formatter itself, no further processing</returns>
		protected virtual bool FormatRsdnURLs(Match urlMatch, HtmlAnchor link)
		{
			var urlScheme = urlMatch.Groups["scheme"];
			var urlHostname = urlMatch.Groups["hostname"];
			var originalScheme = urlScheme.Success ? urlScheme.Value : Uri.UriSchemeHttp;

			Action<String> rsdnHostReplacer =
				delegate(string urlHost)
					{
						var schemeMatchStart = (urlScheme.Success ? urlScheme.Index : urlMatch.Index);
						link.HRef =
							(((HttpContext.Current != null) && HttpContext.Current.Request.IsSecureConnection)
								?
									Uri.UriSchemeHttps
								: originalScheme) + (urlScheme.Success ? null : "://") +
							link.HRef.Substring(schemeMatchStart - urlMatch.Index + urlScheme.Length,
																	urlHostname.Index - schemeMatchStart - urlScheme.Length) +
							urlHost +
							link.HRef.Substring(urlHostname.Index - urlMatch.Index + urlHostname.Length);
					};

			IDictionary<string, ThreadStart> rsdnSchemesProcessing =
				new Dictionary<string, ThreadStart>(3, StringComparer.OrdinalIgnoreCase);

			// redirect rsdn svn
			rsdnSchemesProcessing["svn"] =
				(() => rsdnHostReplacer("svn.rsdn.ru"));

			// rebase only http or https links
			rsdnSchemesProcessing[Uri.UriSchemeHttp] =
				rsdnSchemesProcessing[Uri.UriSchemeHttps] =
				(() => rsdnHostReplacer(CanonicalRsdnHostName));

			if (rsdnSchemesProcessing.ContainsKey(originalScheme))
				rsdnSchemesProcessing[originalScheme]();

			AddClass(link, "m");
			if (_openRsdnLinksInNewWindow)
				link.Target = "_blank";

			return true;
		}
Пример #4
0
		/// <summary>
		/// Format URLs to hyperlinks.
		/// Used in both, explicitly &amp; implicitly specified links.
		/// </summary>
		/// <param name="urlMatch">Regex match with URL address.</param>
		/// <param name="urlAdsress">URL address.</param>
		/// <param name="urlName">URL name. May be or may be not different from URL address.</param>
		/// <returns>Formatted link for specified URL.</returns>
		protected virtual string FormatURLs(Match urlMatch, string urlAdsress, string urlName)
		{
			// by default pass url directly (just antiXSS processing)
			var link =
				new HtmlAnchor
				{
					HRef = urlAdsress.EncodeAgainstXSS(),
					InnerHtml = urlName.EncodeAgainstXSS()
				};

			var processesedItself = false;

			// if valid url detected - do additional formatting
			if (urlMatch.Success)
			{
				// if no scheme detected - use default http
				if (!urlMatch.Groups["scheme"].Success)
					link.HRef = Uri.UriSchemeHttp + "://" + link.HRef;
				else
				{
					// process custom scheme formatting, if exists
					ProcessUrl schemeFormatter;
					if (SchemeFormatting.TryGetValue(urlMatch.Groups["scheme"].Value, out schemeFormatter))
						processesedItself = schemeFormatter(urlMatch, link);
				}

				if (!processesedItself)
				{
					var matchedHostname = urlMatch.Groups["hostname"].Value;
					ProcessUrl hostFormatter;
					if (HostFormatting.TryGetValue(matchedHostname, out hostFormatter))
						processesedItself = hostFormatter(urlMatch, link);
					else
					{
						foreach (var host in _wellKnownHosts)
							if (matchedHostname.EndsWith(host.Key))
								AddClass(link, host.Value);
					}
				}
			}

			if (!processesedItself)
			{
				AddClass(link, "m");
				link.Target = "_blank";
			}

			return RenderHtmlAnchor(link);
		}
Пример #5
0
		/// <summary>
		/// Add css class to HtmlAnchor
		/// </summary>
		protected static HtmlAnchor AddClass(HtmlAnchor link, string className)
		{
			const string @class = "class";

			if(!link.Attributes.ContainsKey(@class))
					link.Attributes[@class] = "";

			var cssClass = link.Attributes[@class];
			if (!string.IsNullOrEmpty(cssClass))
				cssClass += " ";
			link.Attributes[@class] = cssClass + className;
			return link;
		}
Пример #6
0
		/// <summary>
		/// Process local MSDN links (ms-help scheme).
		/// </summary>
		/// <param name="urlMatch">Input URL match</param>
		/// <param name="link">Output formatted URL</param>
		private static bool ProcessMsHelpLink(Match urlMatch, HtmlAnchor link)
		{
			var guidMatch = _msdnGuidDetector.Match(urlMatch.Value);
			if (guidMatch.Success)
			{
				link.HRef = string.Format(
					guidMatch.Groups["section"].Success
						? "http://msdn.microsoft.com/library/en-us/{1}/html/{0}.asp"
						: "http://msdn2.microsoft.com/{0}.aspx",
					guidMatch.Value,
					guidMatch.Groups["section"].Value);
			}
			return false;
		}
Пример #7
0
		/// <summary>
		/// Process RSDN link tag
		/// </summary>
		/// <param name="name">Regexp match with RSDN link tag</param>
		/// <returns>Formatted link as HtmlAnchor</returns>
		protected virtual HtmlAnchor ProcessRsdnLinkAsAnchor(Match name)
		{
			var link =
				new HtmlAnchor
				{
					Target = "_blank",
					HRef =
						string.Format(
							"{0}/Forum/Info/{1}.aspx",
							GetPathToRoot(),
							name.Groups[1].Value),
					InnerText = name.Groups[1].Value
				};
			return AddClass(link, "m");
		}
Пример #8
0
		/// <summary>
		/// Process RSDN partneship links.
		/// </summary>
		/// <param name="urlMatch"></param>
		/// <param name="link"></param>
		protected static bool ProcessPartnerLink(Match urlMatch, HtmlAnchor link)
		{
			var uriBuilder = new UriBuilder(link.HRef);
			var queryBuilder = new QueryBuilder(uriBuilder.Query);
			var partnerRecord = _partnresIDs[uriBuilder.Host];
			queryBuilder[partnerRecord.QueryParameter] = partnerRecord.PartnerID;
			uriBuilder.Query = HttpUtility.HtmlEncode(queryBuilder.ToString());
			link.HRef = uriBuilder.Uri.AbsoluteUri;
			return false;
		}
Пример #9
0
		private static bool ProcessPiterLink(Match urlMatch, HtmlAnchor link)
		{
			var uriBuilder = new UriBuilder(link.HRef);
			var queryBuilder = new QueryBuilder(uriBuilder.Query);
			// если есть анонимный параметр
			if (!string.IsNullOrEmpty(queryBuilder[null]))
			{
				queryBuilder["id"] = queryBuilder[null];
				queryBuilder.Remove(null);
				uriBuilder.Query = HttpUtility.HtmlEncode(queryBuilder.ToString());
				link.HRef = uriBuilder.Uri.AbsoluteUri;
			}
			// стандартная обработка
			return ProcessPartnerLink(urlMatch, link);
		}
Пример #10
0
		/// <summary>
		/// Process Amazon.com links
		/// </summary>
		private static bool ProcessAmazonLink(Match urlMatch, HtmlAnchor link)
		{
			var url = HttpUtility.UrlDecode(link.HRef);
			if (url == null)
				return false;
			var asinMatch = _asinDetector.Match(url);
			if (asinMatch.Success)
				link.HRef = string.Format(_directAmazonUrl, asinMatch.Groups["asin"].Value);
			else
			{
				var originalAmazonUri = new Uri(link.HRef);
				if (originalAmazonUri.PathAndQuery.StartsWith(_amazonPathPrefix))
					link.HRef = _amazonUrl + originalAmazonUri.PathAndQuery.Substring(_amazonPathPrefix.Length);
				else
					link.HRef = _amazonUrl + HttpUtility.UrlEncode(link.HRef);
			}
			return false;
		}