A bunch of new BBCodes implemented; smileys parsing implemented

main
Inga 🏳‍🌈 15 years ago
parent a5407ca07f
commit a08f4af513
  1. 2
      Builder/IISMainHandler/build.txt
  2. 2
      Builder/IISUploadHandler/build.txt
  3. 2
      Common/BBCodes/Code.cs
  4. 6
      Common/BBCodes/FUrl.cs
  5. 19
      Common/BBCodes/Font.cs
  6. 19
      Common/BBCodes/FontColor.cs
  7. 19
      Common/BBCodes/FontSize.cs
  8. 19
      Common/BBCodes/List.cs
  9. 20
      Common/BBCodes/ListElem.cs
  10. 21
      Common/BBCodes/Quote.cs
  11. 21
      Common/BBCodes/Spoiler.cs
  12. 21
      Common/BBCodes/UploadImage.cs
  13. 24
      Common/BBCodes/UploadLink.cs
  14. 6
      Common/BBCodes/Url.cs
  15. 20
      Common/BBCodes/User.cs
  16. 14
      Common/BBCodes/helpers/BBCode.cs
  17. 10
      Common/Common.csproj
  18. 53
      Common/UBBParser.cs
  19. 6
      static/css/global.css
  20. 8
      static/js/common.js
  21. 1
      templates/Full/elems/Main.xslt
  22. 14
      templates/Full/elems/TextEditor.xslt

@ -12,7 +12,7 @@ namespace FLocal.Common.BBCodes {
} }
public override string Format(ITextFormatter formatter) { public override string Format(ITextFormatter formatter) {
return "<pre>" + this.InnerBBCode + "</pre>"; return "<pre>" + this.InnerBBCode.Trim() + "</pre><br/>";
} }
} }

@ -12,11 +12,7 @@ namespace FLocal.Common.BBCodes {
} }
public override string Format(ITextFormatter formatter) { public override string Format(ITextFormatter formatter) {
string rawUrl = this.Default; string rawUrl = this.DefaultOrValue;
if(rawUrl == null) {
// throw new ApplicationException(String.Join("; ", (from kvp in this.Attributes select kvp.Key + "=" + kvp.Value).ToArray()));
rawUrl = this.InnerText;
}
Uri uri = new Uri(rawUrl); Uri uri = new Uri(rawUrl);
return "<a href=\"" + uri.ToString() + "\">" + this.GetInnerHTML(formatter) + "</a>"; return "<a href=\"" + uri.ToString() + "\">" + this.GetInnerHTML(formatter) + "</a>";
} }

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PJonDevelopment.BBCode;
namespace FLocal.Common.BBCodes {
class Font : BBCode {
public Font()
: base("font") {
}
public override string Format(ITextFormatter formatter) {
return "<font face=\"" + this.Default + "\">" + this.GetInnerHTML(formatter) + "</font>";
}
}
}

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PJonDevelopment.BBCode;
namespace FLocal.Common.BBCodes {
class FontColor : BBCode {
public FontColor()
: base("color") {
}
public override string Format(ITextFormatter formatter) {
return "<font color=\"" + this.Default + "\">" + this.GetInnerHTML(formatter) + "</font>";
}
}
}

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PJonDevelopment.BBCode;
namespace FLocal.Common.BBCodes {
class FontSize : BBCode {
public FontSize()
: base("size") {
}
public override string Format(ITextFormatter formatter) {
return "<font size=\"" + this.Default + "\">" + this.GetInnerHTML(formatter) + "</font>";
}
}
}

@ -0,0 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PJonDevelopment.BBCode;
namespace FLocal.Common.BBCodes {
class List : BBCode {
public List()
: base("list") {
}
public override string Format(ITextFormatter formatter) {
return "<ul>" + this.GetInnerHTML(formatter) + "</ul>";
}
}
}

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PJonDevelopment.BBCode;
namespace FLocal.Common.BBCodes {
class ListElem : BBCode {
public ListElem()
: base("*") {
}
public override string Format(ITextFormatter formatter) {
// return "<li>" + this.GetInnerHTML(formatter) + "</li>";
return "<li>";
}
}
}

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PJonDevelopment.BBCode;
namespace FLocal.Common.BBCodes {
class Quote : BBCode {
public Quote()
: base("quote") {
}
public override string Format(ITextFormatter formatter) {
string marker = this.Default;
if(marker == null) marker = "Quote:";
return "<blockquote><font class=\"small\">" + marker + "</font><hr/><br/>" + this.GetInnerHTML(formatter).Trim() + "<br/><br/><hr/></blockquote><br/>";
}
}
}

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PJonDevelopment.BBCode;
namespace FLocal.Common.BBCodes {
class Spoiler : BBCode {
public Spoiler()
: base("spoiler") {
}
public override string Format(ITextFormatter formatter) {
string marker = this.Default;
if(marker == null) marker = "Spoiler";
return "<blockquote spoiler><font opener class=\"small\" onClick=\"showSpoiler(this)\">" + marker + "</font><hr/><div inner name=\"inner\">" + this.GetInnerHTML(formatter).Trim() + "</div><hr/></blockquote><br/>";
}
}
}

@ -0,0 +1,21 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PJonDevelopment.BBCode;
namespace FLocal.Common.BBCodes {
class UploadImage : BBCode {
public UploadImage()
: base("uploadimage") {
}
public override string Format(ITextFormatter formatter) {
var upload = dataobjects.Upload.LoadById(int.Parse(this.InnerText));
var name = upload.filename;
return "<f:img><f:src>/Upload/Item/" + upload.id.ToString() + "/</f:src><f:alt>" + this.Safe(upload.filename) + "</f:alt></f:img>";
}
}
}

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PJonDevelopment.BBCode;
namespace FLocal.Common.BBCodes {
class UploadLink : BBCode {
public UploadLink()
: base("uploadlink") {
}
public override string Format(ITextFormatter formatter) {
var upload = dataobjects.Upload.LoadById(int.Parse(this.DefaultOrValue));
var name = this.Safe(upload.filename);
if(this.Default != null) {
name = this.GetInnerHTML(formatter);
}
return "<a href=\"/Upload/Item/" + upload.id.ToString() + "/\">" + name + "</a>";
}
}
}

@ -12,11 +12,7 @@ namespace FLocal.Common.BBCodes {
} }
public override string Format(ITextFormatter formatter) { public override string Format(ITextFormatter formatter) {
string rawUrl = this.Default; string rawUrl = this.DefaultOrValue;
if(rawUrl == null) {
// throw new ApplicationException(String.Join("; ", (from kvp in this.Attributes select kvp.Key + "=" + kvp.Value).ToArray()));
rawUrl = this.InnerText;
}
var urlInfo = UrlProcessor.Process(rawUrl); var urlInfo = UrlProcessor.Process(rawUrl);
return "<a href=\"" + urlInfo.relativeUrl + "\">" + this.GetInnerHTML(formatter) + "</a>"; return "<a href=\"" + urlInfo.relativeUrl + "\">" + this.GetInnerHTML(formatter) + "</a>";
} }

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PJonDevelopment.BBCode;
namespace FLocal.Common.BBCodes {
class User : BBCode {
public User()
: base("user") {
}
public override string Format(ITextFormatter formatter) {
var user = dataobjects.User.LoadByName(this.Default);
return "<a href=\"/User/" + user.id.ToString() + "/\">" + this.Safe(user.name) + "</a>";
}
}
}

@ -31,5 +31,19 @@ namespace FLocal.Common.BBCodes {
} }
} }
protected string DefaultOrValue {
get {
string result = this.Default;
if(result == null) {
result = this.InnerText;
}
return result;
}
}
protected string Safe(string str) {
return System.Web.HttpUtility.HtmlEncode(str);
}
} }
} }

@ -58,14 +58,24 @@
<Compile Include="actions\UpdateChange.cs" /> <Compile Include="actions\UpdateChange.cs" />
<Compile Include="actions\ChangeSetUtil.cs" /> <Compile Include="actions\ChangeSetUtil.cs" />
<Compile Include="BBCodes\B.cs" /> <Compile Include="BBCodes\B.cs" />
<Compile Include="BBCodes\Font.cs" />
<Compile Include="BBCodes\FontColor.cs" />
<Compile Include="BBCodes\FontSize.cs" />
<Compile Include="BBCodes\helpers\BBCode.cs" /> <Compile Include="BBCodes\helpers\BBCode.cs" />
<Compile Include="BBCodes\Code.cs" /> <Compile Include="BBCodes\Code.cs" />
<Compile Include="BBCodes\FUrl.cs" /> <Compile Include="BBCodes\FUrl.cs" />
<Compile Include="BBCodes\Image.cs" /> <Compile Include="BBCodes\Image.cs" />
<Compile Include="BBCodes\List.cs" />
<Compile Include="BBCodes\ListElem.cs" />
<Compile Include="BBCodes\Quote.cs" />
<Compile Include="BBCodes\S.cs" /> <Compile Include="BBCodes\S.cs" />
<Compile Include="BBCodes\Spoiler.cs" />
<Compile Include="BBCodes\U.cs" /> <Compile Include="BBCodes\U.cs" />
<Compile Include="BBCodes\UploadImage.cs" />
<Compile Include="BBCodes\UploadLink.cs" />
<Compile Include="BBCodes\Url.cs" /> <Compile Include="BBCodes\Url.cs" />
<Compile Include="BBCodes\helpers\UrlProcessor.cs" /> <Compile Include="BBCodes\helpers\UrlProcessor.cs" />
<Compile Include="BBCodes\User.cs" />
<Compile Include="Config.cs" /> <Compile Include="Config.cs" />
<Compile Include="dataobjects\Account.cs" /> <Compile Include="dataobjects\Account.cs" />
<Compile Include="dataobjects\AccountIndicator.cs" /> <Compile Include="dataobjects\AccountIndicator.cs" />

@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Web; using System.Web;
using System.Text.RegularExpressions;
using PJonDevelopment.BBCode; using PJonDevelopment.BBCode;
namespace FLocal.Common { namespace FLocal.Common {
@ -10,6 +11,46 @@ namespace FLocal.Common {
private class BBParserGateway { private class BBParserGateway {
private class TextFormatter : ITextFormatter {
public static readonly TextFormatter instance = new TextFormatter();
private static readonly Dictionary<string, string> SMILEYS = new Dictionary<string, string> {
{ ":)", "smile" },
{ ":(", "frown" },
{ ":o", "blush" },
{ ":D", "laugh" },
{ ";)", "wink" },
{ ":p", "tongue" },
{ ":cool:", "cool" },
{ ":crazy:", "crazy" },
{ ":mad:", "mad" },
{ ":shocked:", "shocked" },
{ ":smirk:", "smirk" },
{ ":grin:", "grin" },
{ ":ooo:", "ooo" },
{ ":confused:", "confused" },
{ ":lol:", "lol" },
};
private static readonly Dictionary<Regex, MatchEvaluator> SMILEYS_DATA = (from smile in SMILEYS select new KeyValuePair<Regex, MatchEvaluator>(new Regex("(\\s+)" + Regex.Escape(smile.Key) + "(\\s+)", RegexOptions.Compiled | RegexOptions.IgnoreCase | RegexOptions.Singleline), match => match.Groups[1] + "<img src=\"/static/smileys/" + smile.Value + ".gif\" alt=\"" + smile.Key + "\"/>" + match.Groups[2])).ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
private ITextFormatter inner;
private TextFormatter() {
this.inner = new BBCodeHtmlFormatter();
}
public string Format(string source) {
string result = this.inner.Format(source);
foreach(var smile in SMILEYS_DATA) {
result = smile.Key.Replace(result, smile.Value);
}
return result;
}
}
public static readonly BBParserGateway instance = new BBParserGateway(); public static readonly BBParserGateway instance = new BBParserGateway();
private BBCodeParser parser; private BBCodeParser parser;
@ -19,13 +60,23 @@ namespace FLocal.Common {
this.parser = new BBCodeParser(); this.parser = new BBCodeParser();
this.parser.ElementTypes.Add("b", typeof(BBCodes.B), true); this.parser.ElementTypes.Add("b", typeof(BBCodes.B), true);
this.parser.ElementTypes.Add("code", typeof(BBCodes.Code), true); this.parser.ElementTypes.Add("code", typeof(BBCodes.Code), true);
this.parser.ElementTypes.Add("font", typeof(BBCodes.Font), true);
this.parser.ElementTypes.Add("color", typeof(BBCodes.FontColor), true);
this.parser.ElementTypes.Add("size", typeof(BBCodes.FontSize), true);
this.parser.ElementTypes.Add("furl", typeof(BBCodes.FUrl), true); this.parser.ElementTypes.Add("furl", typeof(BBCodes.FUrl), true);
this.parser.ElementTypes.Add("i", typeof(BBCodes.I), true); this.parser.ElementTypes.Add("i", typeof(BBCodes.I), true);
this.parser.ElementTypes.Add("image", typeof(BBCodes.Image), true); this.parser.ElementTypes.Add("image", typeof(BBCodes.Image), true);
this.parser.ElementTypes.Add("list", typeof(BBCodes.List), true);
this.parser.ElementTypes.Add("*", typeof(BBCodes.ListElem), false);
this.parser.ElementTypes.Add("quote", typeof(BBCodes.Quote), true);this.parser.ElementTypes.Add("q", typeof(BBCodes.Quote), true);
this.parser.ElementTypes.Add("s", typeof(BBCodes.S), true); this.parser.ElementTypes.Add("s", typeof(BBCodes.S), true);
this.parser.ElementTypes.Add("spoiler", typeof(BBCodes.Spoiler), true);this.parser.ElementTypes.Add("cut", typeof(BBCodes.Spoiler), true);
this.parser.ElementTypes.Add("u", typeof(BBCodes.U), true); this.parser.ElementTypes.Add("u", typeof(BBCodes.U), true);
this.parser.ElementTypes.Add("uploadimage", typeof(BBCodes.UploadImage), true);
this.parser.ElementTypes.Add("uploadlink", typeof(BBCodes.UploadLink), true);
this.parser.ElementTypes.Add("url", typeof(BBCodes.Url), true); this.parser.ElementTypes.Add("url", typeof(BBCodes.Url), true);
this.formatter = new BBCodeHtmlFormatter(); this.parser.ElementTypes.Add("user", typeof(BBCodes.User), false);
this.formatter = TextFormatter.instance;
} }
public string Parse(string input) { public string Parse(string input) {

@ -76,3 +76,9 @@ pre
cursor:hand; cursor:hand;
text-decoration:underline; text-decoration:underline;
} }
[spoiler] [inner] {
display:none;
}
[spoiler] [opener] {
cursor:hand;
}

@ -0,0 +1,8 @@
function showSpoiler(obj) {
var inner = obj.parentNode.getElementsByTagName("div")[0];
if(inner.style.display == "none" || inner.style.display == null || inner.style.display == "") {
inner.style.display = "block";
} else {
inner.style.display = "none";
}
}

@ -10,6 +10,7 @@
<xsl:attribute name="href">/static/css/<xsl:value-of select="skin/name"/>.css</xsl:attribute> <xsl:attribute name="href">/static/css/<xsl:value-of select="skin/name"/>.css</xsl:attribute>
</link> </link>
<link rel="shortcut icon" href="/static/favicons/smirk.ico" type="image/x-icon" /> <link rel="shortcut icon" href="/static/favicons/smirk.ico" type="image/x-icon" />
<script language="Javascript" type="text/javascript" src="/static/js/common.js"><xsl:text> </xsl:text></script>
<title><xsl:value-of select="title"/></title> <title><xsl:value-of select="title"/></title>
</head> </head>
<body> <body>

@ -125,13 +125,13 @@ function insertInBody(str) {
</tr> </tr>
<tr> <tr>
<td class="darktable"> <td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('pollstart');">Íà÷àëî<br/>ãîëîñîâàíèÿ</a> <a pseudolink="pseudolink" onclick="alert('Not implemented');return;DoPrompt('pollstart');">Íà÷àëî<br/>ãîëîñîâàíèÿ</a>
</td> </td>
<td class="darktable"> <td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('polloption');">Âàðèàíò<br/>ãîëîñîâàíèÿ</a> <a pseudolink="pseudolink" onclick="alert('Not implemented');return;DoPrompt('polloption');">Âàðèàíò<br/>ãîëîñîâàíèÿ</a>
</td> </td>
<td class="darktable"> <td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('pollstop');">Êîíåö<br/>ãîëîñîâàíèÿ</a> <a pseudolink="pseudolink" onclick="alert('Not implemented');return;DoPrompt('pollstop');">Êîíåö<br/>ãîëîñîâàíèÿ</a>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -150,18 +150,18 @@ function insertInBody(str) {
<a pseudolink="pseudolink" onclick="DoPrompt('user');">Ïîëüçîâàòåëü</a> <a pseudolink="pseudolink" onclick="DoPrompt('user');">Ïîëüçîâàòåëü</a>
</td> </td>
<td class="darktable"> <td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('table');">Òàáëèöà</a> <a pseudolink="pseudolink" onclick="alert('Not implemented');return;DoPrompt('table');">Òàáëèöà</a>
</td> </td>
<td class="darktable"> <td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('ecode');">Ecode</a> <a pseudolink="pseudolink" onclick="alert('Not implemented');return;DoPrompt('ecode');">Ecode</a>
</td> </td>
</tr> </tr>
<tr> <tr>
<td class="darktable"> <td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('video');">YouTube</a> <a pseudolink="pseudolink" onclick="alert('Not implemented');return;DoPrompt('video');">YouTube</a>
</td> </td>
<td class="darktable" colspan="2"> <td class="darktable" colspan="2">
<a pseudolink="pseudolink" onclick="DoPrompt('math');">Math</a> <a pseudolink="pseudolink" onclick="alert('Not implemented');return;DoPrompt('math');">Math</a>
</td> </td>
</tr> </tr>
</table> </table>

Loading…
Cancel
Save