TextEditor.xslt implemented; UBBCParser initial commit; PostReply implemented

main
Inga 🏳‍🌈 14 years ago
parent f274c02611
commit b138249550
  1. 2
      Builder/IISMainHandler/build.txt
  2. 2
      Builder/IISUploadHandler/build.txt
  3. 2
      Common/Common.csproj
  4. 18
      Common/UBBParser.cs
  5. 17
      Common/actions/ChangeSet.cs
  6. 2
      Common/actions/ReferenceFieldValue.cs
  7. 28
      Common/actions/TwoWayReferenceFieldValue.cs
  8. 123
      Common/dataobjects/Post.cs
  9. 4
      Common/dataobjects/User.cs
  10. 12
      IISMainHandler/HandlersFactory.cs
  11. 4
      IISMainHandler/IISMainHandler.csproj
  12. 1
      IISMainHandler/handlers/PostHandler.cs
  13. 1
      IISMainHandler/handlers/ThreadHandler.cs
  14. 27
      IISMainHandler/handlers/request/AbstractNewMessageHandler.cs
  15. 20
      IISMainHandler/handlers/request/CreateThreadHandler.cs
  16. 36
      IISMainHandler/handlers/request/ReplyHandler.cs
  17. 32
      IISMainHandler/handlers/response/ReplyHandler.cs
  18. 8
      static/css/coffeehaus.css
  19. 4
      static/css/global.css
  20. BIN
      static/js/textEditor.js
  21. 4
      templates/Full/Login.xslt
  22. 4
      templates/Full/Post.xslt
  23. 107
      templates/Full/PostReply.xslt
  24. 4
      templates/Full/Thread.xslt
  25. 3
      templates/Full/UploadNew.xslt
  26. 5
      templates/Full/elems/PostInfo.xslt
  27. 245
      templates/Full/elems/TextEditor.xslt
  28. 30
      templates/Full/result/MessageCreated.xslt

@ -53,6 +53,7 @@
<Compile Include="actions\InsertOrUpdateChange.cs" /> <Compile Include="actions\InsertOrUpdateChange.cs" />
<Compile Include="actions\ReferenceFieldValue.cs" /> <Compile Include="actions\ReferenceFieldValue.cs" />
<Compile Include="actions\ScalarFieldValue.cs" /> <Compile Include="actions\ScalarFieldValue.cs" />
<Compile Include="actions\TwoWayReferenceFieldValue.cs" />
<Compile Include="actions\UpdateChange.cs" /> <Compile Include="actions\UpdateChange.cs" />
<Compile Include="actions\ChangeSetUtil.cs" /> <Compile Include="actions\ChangeSetUtil.cs" />
<Compile Include="Config.cs" /> <Compile Include="Config.cs" />
@ -70,6 +71,7 @@
<Compile Include="ISqlObjectTableSpec.cs" /> <Compile Include="ISqlObjectTableSpec.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SqlObject.cs" /> <Compile Include="SqlObject.cs" />
<Compile Include="UBBParser.cs" />
<Compile Include="UploadManager.cs" /> <Compile Include="UploadManager.cs" />
<Compile Include="UserContext.cs" /> <Compile Include="UserContext.cs" />
<Compile Include="UserSettingsGateway.cs" /> <Compile Include="UserSettingsGateway.cs" />

@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common {
public static class UBBParser {
public static string UBBToIntermediate(string UBB) {
return UBB;
}
public static string ShallerToUBB(string shaller) {
return shaller;
}
}
}

@ -24,6 +24,7 @@ namespace FLocal.Common.actions {
dataobjects.Board.TableSpec.TABLE, dataobjects.Board.TableSpec.TABLE,
dataobjects.Thread.TableSpec.TABLE, dataobjects.Thread.TableSpec.TABLE,
dataobjects.Post.TableSpec.TABLE, dataobjects.Post.TableSpec.TABLE,
dataobjects.Post.RevisionTableSpec.TABLE,
dataobjects.Board.ReadMarkerTableSpec.TABLE, dataobjects.Board.ReadMarkerTableSpec.TABLE,
dataobjects.Thread.ReadMarkerTableSpec.TABLE, dataobjects.Thread.ReadMarkerTableSpec.TABLE,
dataobjects.Session.TableSpec.TABLE, dataobjects.Session.TableSpec.TABLE,
@ -94,11 +95,17 @@ namespace FLocal.Common.actions {
public void Dispose() { public void Dispose() {
//if(!this.isProcessed) throw new CriticalException("ChangeSet is not processed yet"); //if(!this.isProcessed) throw new CriticalException("ChangeSet is not processed yet");
foreach(KeyValuePair<string, HashSet<AbstractChange>> kvp in this.changesByTable) { if(this.isProcessed) {
foreach(AbstractChange change in kvp.Value) { foreach(KeyValuePair<string, HashSet<AbstractChange>> kvp in this.changesByTable) {
if(change.getId().HasValue) { foreach(AbstractChange change in kvp.Value) {
change.tableSpec.refreshSqlObject(change.getId().Value); if(change.getId().HasValue) {
} //otherwise we're disposing because of sql error or something, so we should show real cause of problem, not "id is null" try {
change.tableSpec.refreshSqlObject(change.getId().Value);
} catch(NotFoundInDBException) {
//it seems something broken earlier; transaction rollback etc...
}
} //otherwise we're disposing because of sql error or something, so we should show real cause of problem, not "id is null"
}
} }
} }
} }

@ -16,7 +16,7 @@ namespace FLocal.Common.actions {
return this.referenced.getId().Value.ToString(); return this.referenced.getId().Value.ToString();
} }
public override string getStringRepresentation(string oldInfo) { public override string getStringRepresentation(string oldInfo) {
return this.referenced.getId().Value.ToString(); return this.getStringRepresentation();
} }
} }

@ -0,0 +1,28 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace FLocal.Common.actions {
class TwoWayReferenceFieldValue : ReferenceFieldValue {
public delegate string Calculator(string old, string reference);
private Calculator calculator;
public TwoWayReferenceFieldValue(AbstractChange referenced, Calculator calculator)
: base(referenced) {
this.calculator = calculator;
}
public override string getStringRepresentation() {
throw new NotSupportedException();
}
public override string getStringRepresentation(string oldInfo) {
return this.calculator(oldInfo, base.getStringRepresentation());
}
}
}

@ -5,6 +5,8 @@ using System.Text;
using System.Xml.Linq; using System.Xml.Linq;
using FLocal.Core; using FLocal.Core;
using FLocal.Core.DB; using FLocal.Core.DB;
using FLocal.Common;
using FLocal.Common.actions;
namespace FLocal.Common.dataobjects { namespace FLocal.Common.dataobjects {
public class Post : SqlObject<Post> { public class Post : SqlObject<Post> {
@ -16,7 +18,7 @@ namespace FLocal.Common.dataobjects {
public const string FIELD_POSTDATE = "PostDate"; public const string FIELD_POSTDATE = "PostDate";
public const string FIELD_LASTCHANGEDATE = "LastChangeDate"; public const string FIELD_LASTCHANGEDATE = "LastChangeDate";
public const string FIELD_REVISION = "Revision"; public const string FIELD_REVISION = "Revision";
public const string FIELD_LAYER = "Layer"; public const string FIELD_LAYERID = "LayerId";
public const string FIELD_TITLE = "Title"; public const string FIELD_TITLE = "Title";
public const string FIELD_BODY = "Body"; public const string FIELD_BODY = "Body";
public const string FIELD_THREADID = "ThreadId"; public const string FIELD_THREADID = "ThreadId";
@ -27,6 +29,20 @@ namespace FLocal.Common.dataobjects {
public void refreshSqlObject(int id) { Refresh(id); } public void refreshSqlObject(int id) { Refresh(id); }
} }
public class RevisionTableSpec : ISqlObjectTableSpec {
public const string TABLE = "Revisions";
public const string FIELD_ID = "Id";
public const string FIELD_POSTID = "PostId";
public const string FIELD_CHANGEDATE = "ChangeDate";
public const string FIELD_TITLE = "Title";
public const string FIELD_BODY = "Body";
public const string FIELD_NUMBER = "Number";
public static readonly RevisionTableSpec instance = new RevisionTableSpec();
public string name { get { return TABLE; } }
public string idName { get { return FIELD_ID; } }
public void refreshSqlObject(int id) { }
}
protected override ISqlObjectTableSpec table { get { return TableSpec.instance; } } protected override ISqlObjectTableSpec table { get { return TableSpec.instance; } }
private int _posterId; private int _posterId;
@ -67,11 +83,11 @@ namespace FLocal.Common.dataobjects {
} }
} }
private int _layer; private int _layerId;
public int layer { public int layerId {
get { get {
this.LoadIfNotLoaded(); this.LoadIfNotLoaded();
return this._layer; return this._layerId;
} }
} }
@ -127,7 +143,7 @@ namespace FLocal.Common.dataobjects {
this._postDate = new DateTime(long.Parse(data[TableSpec.FIELD_POSTDATE])); this._postDate = new DateTime(long.Parse(data[TableSpec.FIELD_POSTDATE]));
this._lastChangeDate = Util.ParseDateTimeFromTimestamp(data[TableSpec.FIELD_LASTCHANGEDATE]); this._lastChangeDate = Util.ParseDateTimeFromTimestamp(data[TableSpec.FIELD_LASTCHANGEDATE]);
this._revision = int.Parse(data[TableSpec.FIELD_REVISION]); this._revision = int.Parse(data[TableSpec.FIELD_REVISION]);
this._layer = int.Parse(data[TableSpec.FIELD_LAYER]); this._layerId = int.Parse(data[TableSpec.FIELD_LAYERID]);
this._title = data[TableSpec.FIELD_TITLE]; this._title = data[TableSpec.FIELD_TITLE];
this._body = data[TableSpec.FIELD_BODY]; this._body = data[TableSpec.FIELD_BODY];
this._threadId = int.Parse(data[TableSpec.FIELD_THREADID]); this._threadId = int.Parse(data[TableSpec.FIELD_THREADID]);
@ -149,7 +165,7 @@ namespace FLocal.Common.dataobjects {
new XElement("postDate", this.postDate.ToXml()), new XElement("postDate", this.postDate.ToXml()),
new XElement("lastChangeDate", this.postDate.ToXml()), new XElement("lastChangeDate", this.postDate.ToXml()),
new XElement("revision", this.revision), new XElement("revision", this.revision),
new XElement("layer", this.layer), new XElement("layerId", this.layerId),
new XElement("title", this.title), new XElement("title", this.title),
new XElement("body", context.outputParams.preprocessBodyIntermediate(this.body)), new XElement("body", context.outputParams.preprocessBodyIntermediate(this.body)),
new XElement("bodyShort", this.bodyShort), new XElement("bodyShort", this.bodyShort),
@ -166,5 +182,100 @@ namespace FLocal.Common.dataobjects {
return result; return result;
} }
public Post Reply(User poster, string title, string body, int desiredLayerId) {
if(this.thread.isLocked) {
throw new FLocalException("thread locked");
}
int actualLayerId = Math.Max(poster.getMinAllowedLayer(this.thread.board), desiredLayerId);
AbstractChange postInsert = new InsertChange(
TableSpec.instance,
new Dictionary<string,AbstractFieldValue> {
{ TableSpec.FIELD_THREADID, new ScalarFieldValue(this.thread.id.ToString()) },
{ TableSpec.FIELD_PARENTPOSTID, new ScalarFieldValue(this.id.ToString()) },
{ TableSpec.FIELD_POSTERID, new ScalarFieldValue(poster.id.ToString()) },
{ TableSpec.FIELD_POSTDATE, new ScalarFieldValue(DateTime.Now.ToUTCString()) },
{ TableSpec.FIELD_REVISION, new ScalarFieldValue("0") },
{ TableSpec.FIELD_LASTCHANGEDATE, new ScalarFieldValue(DateTime.Now.ToUTCString()) },
{ TableSpec.FIELD_LAYERID, new ScalarFieldValue(layerId.ToString()) },
{ TableSpec.FIELD_TITLE, new ScalarFieldValue(title) },
{ TableSpec.FIELD_BODY, new ScalarFieldValue(UBBParser.UBBToIntermediate(body)) },
}
);
AbstractChange revisionInsert = new InsertChange(
RevisionTableSpec.instance,
new Dictionary<string,AbstractFieldValue> {
{ RevisionTableSpec.FIELD_POSTID, new ReferenceFieldValue(postInsert) },
{ RevisionTableSpec.FIELD_NUMBER, new ScalarFieldValue("0") },
{ RevisionTableSpec.FIELD_CHANGEDATE, new ScalarFieldValue(DateTime.Now.ToUTCString()) },
{ RevisionTableSpec.FIELD_TITLE, new ScalarFieldValue(title) },
{ RevisionTableSpec.FIELD_BODY, new ScalarFieldValue(body) },
}
);
AbstractChange threadUpdate = new UpdateChange(
Thread.TableSpec.instance,
new Dictionary<string,AbstractFieldValue> {
{ Thread.TableSpec.FIELD_LASTPOSTDATE, new ScalarFieldValue(DateTime.Now.ToUTCString()) },
{ Thread.TableSpec.FIELD_TOTALPOSTS, new IncrementFieldValue() },
{
Thread.TableSpec.FIELD_LASTPOSTID,
new TwoWayReferenceFieldValue(
postInsert,
(oldStringId, newStringId) => {
int oldId = int.Parse(oldStringId);
int newId = int.Parse(newStringId);
return Math.Max(oldId, newId).ToString();
}
)
}
},
this.thread.id
);
AbstractChange userUpdate = new UpdateChange(
User.TableSpec.instance,
new Dictionary<string,AbstractFieldValue> {
{ User.TableSpec.FIELD_TOTALPOSTS, new IncrementFieldValue() },
},
poster.id
);
List<AbstractChange> changes = new List<AbstractChange> {
postInsert,
revisionInsert,
threadUpdate,
userUpdate,
};
int? boardId = thread.boardId;
do {
Board board = Board.LoadById(boardId.Value);
changes.Add(
new UpdateChange(
Board.TableSpec.instance,
new Dictionary<string,AbstractFieldValue> {
{ Board.TableSpec.FIELD_TOTALPOSTS, new IncrementFieldValue() },
{
Board.TableSpec.FIELD_LASTPOSTID,
new TwoWayReferenceFieldValue(
postInsert,
(oldStringId, newStringId) => {
int oldId = int.Parse(oldStringId);
int newId = int.Parse(newStringId);
return Math.Max(oldId, newId).ToString();
}
)
}
},
board.id
)
);
boardId = board.parentBoardId;
} while(boardId.HasValue);
ChangeSetUtil.ApplyChanges(changes.ToArray());
return Post.LoadById(postInsert.getId().Value);
}
} }
} }

@ -192,5 +192,9 @@ namespace FLocal.Common.dataobjects {
); );
} }
public int getMinAllowedLayer(Board board) {
return 1;
}
} }
} }

@ -31,7 +31,15 @@ namespace FLocal.IISHandler {
case "thread": case "thread":
return new handlers.ThreadHandler(); return new handlers.ThreadHandler();
case "post": case "post":
return new handlers.PostHandler(); if(context.requestParts.Length < 2) {
return new handlers.WrongUrlHandler();
}
switch(context.requestParts[2].ToLower()) {
case "reply":
return new handlers.response.ReplyHandler();
default:
return new handlers.PostHandler();
}
case "login": case "login":
return new handlers.response.LoginHandler(); return new handlers.response.LoginHandler();
case "migrateaccount": case "migrateaccount":
@ -67,6 +75,8 @@ namespace FLocal.IISHandler {
return new handlers.request.LogoutHandler(); return new handlers.request.LogoutHandler();
case "migrateaccount": case "migrateaccount":
return new handlers.request.MigrateAccountHandler(); return new handlers.request.MigrateAccountHandler();
case "reply":
return new handlers.request.ReplyHandler();
default: default:
return new handlers.WrongUrlHandler(); return new handlers.WrongUrlHandler();
} }

@ -58,15 +58,19 @@
<Compile Include="handlers\BoardsHandler.cs" /> <Compile Include="handlers\BoardsHandler.cs" />
<Compile Include="handlers\DebugHandler.cs" /> <Compile Include="handlers\DebugHandler.cs" />
<Compile Include="handlers\PostHandler.cs" /> <Compile Include="handlers\PostHandler.cs" />
<Compile Include="handlers\request\AbstractNewMessageHandler.cs" />
<Compile Include="handlers\request\AbstractPostHandler.cs" /> <Compile Include="handlers\request\AbstractPostHandler.cs" />
<Compile Include="handlers\request\CreateThreadHandler.cs" />
<Compile Include="handlers\request\LoginHandler.cs" /> <Compile Include="handlers\request\LoginHandler.cs" />
<Compile Include="handlers\request\LogoutHandler.cs" /> <Compile Include="handlers\request\LogoutHandler.cs" />
<Compile Include="handlers\request\MigrateAccountHandler.cs" /> <Compile Include="handlers\request\MigrateAccountHandler.cs" />
<Compile Include="handlers\request\ReplyHandler.cs" />
<Compile Include="handlers\request\UploadHandler.cs" /> <Compile Include="handlers\request\UploadHandler.cs" />
<Compile Include="handlers\response\BoardAsThread.cs" /> <Compile Include="handlers\response\BoardAsThread.cs" />
<Compile Include="handlers\response\LegacyUploadHandler.cs" /> <Compile Include="handlers\response\LegacyUploadHandler.cs" />
<Compile Include="handlers\response\LoginHandler.cs" /> <Compile Include="handlers\response\LoginHandler.cs" />
<Compile Include="handlers\response\MigrateAccountHandler.cs" /> <Compile Include="handlers\response\MigrateAccountHandler.cs" />
<Compile Include="handlers\response\ReplyHandler.cs" />
<Compile Include="handlers\response\UploadHandler.cs" /> <Compile Include="handlers\response\UploadHandler.cs" />
<Compile Include="handlers\response\UploadListHandler.cs" /> <Compile Include="handlers\response\UploadListHandler.cs" />
<Compile Include="handlers\response\UploadNewHandler.cs" /> <Compile Include="handlers\response\UploadNewHandler.cs" />

@ -28,6 +28,7 @@ namespace FLocal.IISHandler.handlers {
XElement[] result = new XElement[] { XElement[] result = new XElement[] {
new XElement("currentLocation", post.exportToXmlSimpleWithParent(context)), new XElement("currentLocation", post.exportToXmlSimpleWithParent(context)),
post.thread.exportToXml(context, false),
new XElement("posts", post.exportToXmlWithoutThread(context, true, new XElement("isUnread", (post.id > lastReadId).ToPlainString()))) new XElement("posts", post.exportToXmlWithoutThread(context, true, new XElement("isUnread", (post.id > lastReadId).ToPlainString())))
}; };

@ -57,6 +57,7 @@ namespace FLocal.IISHandler.handlers {
XElement[] result = new XElement[] { XElement[] result = new XElement[] {
new XElement("currentLocation", thread.exportToXmlSimpleWithParent(context)), new XElement("currentLocation", thread.exportToXmlSimpleWithParent(context)),
thread.exportToXml(context, false),
new XElement("posts", new XElement("posts",
from post in posts select post.exportToXmlWithoutThread(context, true, new XElement("isUnread", (post.id > lastReadId).ToPlainString())), from post in posts select post.exportToXmlWithoutThread(context, true, new XElement("isUnread", (post.id > lastReadId).ToPlainString())),
pageOuter.exportToXml(2, 5, 2) pageOuter.exportToXml(2, 5, 2)

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using FLocal.Core;
namespace FLocal.IISHandler.handlers.request {
abstract class AbstractNewMessageHandler : AbstractPostHandler {
protected string getTitle(WebContext context) {
string title = context.httprequest.Form["title"].Trim();
if(title == "") {
throw new FLocalException("Title is empty");
}
return title;
}
protected string getBody(WebContext context) {
string body = context.httprequest.Form["body"].Trim();
if(body == "") {
throw new FLocalException("Body is empty");
}
return body;
}
}
}

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
namespace FLocal.IISHandler.handlers.request {
class CreateThreadHandler : AbstractNewMessageHandler {
protected override string templateName {
get {
throw new NotImplementedException();
}
}
protected override XElement[] Do(WebContext context) {
throw new NotImplementedException();
}
}
}

@ -0,0 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Linq;
using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.request {
class ReplyHandler : AbstractNewMessageHandler {
protected override string templateName {
get {
return "result/MessageCreated.xslt";
}
}
protected override XElement[] Do(WebContext context) {
// Post post = Post.LoadById(int.Parse(context.httprequest.Form["parent"]));
//int desiredLayerId = Math.Min(context.session.account.user.getMinAllowedLayer(post.thread.board), int.Parse(context.httprequest.Form["layer"]));
Post newPost = Post.LoadById(
int.Parse(context.httprequest.Form["parent"])
).Reply(
context.session.account.user,
this.getTitle(context),
this.getBody(context),
int.Parse(context.httprequest.Form["layerId"])
);
newPost.thread.markAsRead(context.session.account, newPost, newPost);
return new XElement[] { newPost.exportToXmlWithoutThread(context, false) };
}
}
}

@ -0,0 +1,32 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Xml.Linq;
using FLocal.Core;
using FLocal.Common;
using FLocal.Common.dataobjects;
namespace FLocal.IISHandler.handlers.response {
class ReplyHandler : AbstractGetHandler {
override protected string templateName {
get {
return "PostReply.xslt";
}
}
override protected XElement[] getSpecificData(WebContext context) {
Post post = Post.LoadById(int.Parse(context.requestParts[1]));
return new XElement[] {
post.thread.board.exportToXml(context, false),
post.thread.exportToXml(context, false),
post.exportToXmlWithoutThread(context, false),
};
}
}
}

@ -1,6 +1,12 @@
/* File Version 6.5.1 */ /* File Version 6.5.1 */
a:link { [pseudolink] {
color: #303030;
background: none;
text-decoration: underline;
}
a:link {
color: #303030; color: #303030;
background: none; background: none;
} }

@ -70,4 +70,8 @@ pre
} }
.navigation { .navigation {
margin:3px; margin:3px;
}
[pseudolink] {
cursor:hand;
} }

Binary file not shown.

@ -15,7 +15,7 @@
<td> <td>
<xsl:text>Введите ваше имя пользователя и пароль для регистрации в форуме.</xsl:text> <xsl:text>Введите ваше имя пользователя и пароль для регистрации в форуме.</xsl:text>
<br/> <br/>
<xsl:text>Если вы ещё не пользовались этим форумом, но пришли со старого форум.локала &#150; вы можете создать пароль в форме миграции.</xsl:text> <xsl:text>Если вы ещё не пользовались этим форумом, но пришли со старого форум.локала &#8211; вы можете создать пароль в форме миграции.</xsl:text>
</td> </td>
</tr> </tr>
<tr> <tr>
@ -45,7 +45,7 @@
</tr> </tr>
<tr class="darktable"> <tr class="darktable">
<td> <td>
<xsl:text>Если вы пришли со старого форум.локала &#150; введите свой логин.</xsl:text> <xsl:text>Если вы пришли со старого форум.локала &#8211; введите свой логин.</xsl:text>
</td> </td>
</tr> </tr>
<tr> <tr>

@ -9,7 +9,9 @@
<tr> <tr>
<td> <td>
<table cellpadding="0" cellspacing="1" width="100%" class="tableborders"> <table cellpadding="0" cellspacing="1" width="100%" class="tableborders">
<xsl:apply-templates select="posts/post"/> <xsl:apply-templates select="posts/post">
<xsl:with-param name="isReplyDisabled"><xsl:value-of select="thread/isLocked"/></xsl:with-param>
</xsl:apply-templates>
</table> </table>
</td> </td>
</tr> </tr>

@ -0,0 +1,107 @@
<?xml version="1.0" encoding="Windows-1251"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
<xsl:import href="elems\Main.xslt"/>
<xsl:import href="elems\TextEditor.xslt"/>
<xsl:template name="specific">
<table width="95%" align="center" cellpadding="1" cellspacing="1" class="tablesurround">
<tr>
<td>
<table cellpadding="3" cellspacing="1" width="100%" class="tableborders">
<tr>
<td class="tdheader">
<xsl:text>Îòâåò íà ñîîáùåíèå (</xsl:text>
<xsl:value-of select="board/name"/>
<xsl:text>)</xsl:text>
</td>
</tr>
<tr class="darktable">
<td>
<xsl:text>Çàïîëíèòå ïðèâåäåííóþ íèæå ôîðìó äëÿ îòïðàâêè ñîîáùåíèÿ â ôîðóì. HTML îòêëþ÷åí. UBBCode âêëþ÷åí, è âû ìîæåòå èñïîëüçîâàòü UBBCode â âàøèõ ñîîáùåíèÿõ. Àíîíèìíûå ñîîáùåíèÿ ðàçðåøåíû, è âû ìîæåòå âûáðàòü ëþáîå íåçàðåãèñòðèðîâàííîå èìÿ.</xsl:text>
</td>
</tr>
<tr>
<td class="lighttable">
<form method="post" action="/do/Reply/" name="replier">
<input type="hidden" name="parent">
<xsl:attribute name="value"><xsl:value-of select="post/id"/></xsl:attribute>
</input>
<xsl:text>Ïîëüçîâàòåëü: </xsl:text>
<xsl:value-of select="session/user/name"/>
<br/>
<br/>
<xsl:text>Òåìà: </xsl:text>
<br/>
<input type="text" tabindex="1" name="title" maxlength="70" class="formboxes" size="60">
<xsl:choose>
<xsl:when test="substring(post/title, 4)='Re: '">
<xsl:attribute name="value"><xsl:value-of select="post/title"/></xsl:attribute>
</xsl:when>
<xsl:otherwise>
<xsl:attribute name="value">
<xsl:text>Re: </xsl:text>
<xsl:value-of select="post/title"/>
</xsl:attribute>
</xsl:otherwise>
</xsl:choose>
</input>
<span class="small">Ñëîé ñîîáùåíèÿ:</span>
<select class="formboxes" name="layerId">
<option value="1" >Íîðìàëüíîå ñîîáùåíèå</option>
<option value="2" >Ôëóä/îôôòîïèê</option>
<option value="3" >Ìóñîð</option>
</select>
<br/>
<br/>
<xsl:call-template name="textEditor"/>
<br/>
<input type="checkbox" name="preview" value="1" checked="checked" class="formboxes"/>
<xsl:text>ß õî÷ó ïðåäâàðèòåëüíî ïðîñìîòðåòü ñîîáùåíèå ïåðåä îòïðàâêîé</xsl:text>
<br/>
<br/>
<input type="checkbox" name="spellcheck" value="1" class="formboxes" onclick="document.replier.preview.checked=true;"/>
<xsl:text>Ïðîâåðèòü ïðàâîïèñàíèå</xsl:text>
<br/>
<br/>
<input type="submit" tabindex="3" name="textcont" taborder="2" value="Ïðîäîëæèòü" class="buttons"/>
</form>
</td>
</tr>
</table>
</td>
</tr>
</table>
<br/>
<table width="95%" align="center" cellpadding="1" cellspacing="1" class="tablesurround">
<tr>
<td>
<table cellpadding="3" cellspacing="1" width="100%" class="tableborders">
<tr>
<td class="tdheader">
<xsl:text>Îòâåò íà ñîîáùåíèå</xsl:text>
</td>
</tr>
<tr class="darktable">
<td>
<b>
<xsl:text>Àâòîð: </xsl:text>
<xsl:value-of select="post/poster/user/name"/>
<br/>
<xsl:text>Òåìà: </xsl:text>
<xsl:value-of select="post/title"/>
</b>
</td>
</tr>
<tr>
<td class="lighttable">
<xsl:value-of select="post/body" disable-output-escaping="yes"/>
</td>
</tr>
</table>
</td>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>

@ -23,7 +23,9 @@
</table> </table>
</td> </td>
</tr> </tr>
<xsl:apply-templates select="posts/post"/> <xsl:apply-templates select="posts/post">
<xsl:with-param name="isReplyDisabled"><xsl:value-of select="thread/isLocked"/></xsl:with-param>
</xsl:apply-templates>
<tr class="tdheader"> <tr class="tdheader">
<td> <td>
<table width="100%" cellspacing="1" cellpadding="3" border="0"> <table width="100%" cellspacing="1" cellpadding="3" border="0">

@ -14,7 +14,8 @@
<tr class="darktable"> <tr class="darktable">
<td> <td>
<xsl:text>Âûáåðèòå ôàéë äëÿ çàãðóçêè</xsl:text> <xsl:text>Âûáåðèòå ôàéë äëÿ çàãðóçêè</xsl:text>
<xsl:text>Максимальный размер файла &#150; 1МБ, допустимые разрешения: gif, jpg, png</xsl:text> <br/>
<xsl:text>Максимальный размер файла &#8211; 1МБ, допустимые разрешения: gif, jpg, png</xsl:text>
</td> </td>
</tr> </tr>
<tr> <tr>

@ -3,6 +3,7 @@
<xsl:import href="UserInfoBar.xslt"/> <xsl:import href="UserInfoBar.xslt"/>
<xsl:template match="post"> <xsl:template match="post">
<xsl:param name="isReplyDisabled">true</xsl:param>
<tr> <tr>
<td> <td>
<table width="100%" cellspacing="1" cellpadding="3" border="0"> <table width="100%" cellspacing="1" cellpadding="3" border="0">
@ -54,7 +55,9 @@
<tr> <tr>
<td class="navigation"> <td class="navigation">
<a> <a>
<xsl:attribute name="href">/PostReply/<xsl:value-of select="id"/>/</xsl:attribute> <xsl:if test="$isReplyDisabled='false'">
<xsl:attribute name="href">/Post/<xsl:value-of select="id"/>/Reply/</xsl:attribute>
</xsl:if>
<img src="/static/images/reply.gif" border="0" alt="Îòâåò íà ñîîáùåíèå" width="27" height="14" title="Îòâåò íà ñîîáùåíèå" style="vertical-align: text-bottom" /> <img src="/static/images/reply.gif" border="0" alt="Îòâåò íà ñîîáùåíèå" width="27" height="14" title="Îòâåò íà ñîîáùåíèå" style="vertical-align: text-bottom" />
</a> </a>
</td> </td>

@ -0,0 +1,245 @@
<?xml version="1.0" encoding="Windows-1251"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
<xsl:template name="textEditor">
<xsl:param name="body"/>
<input type="hidden" name="convert" value="markup"/>
<xsl:text>Ñîîáùåíèå</xsl:text>
<br/>
<textarea cols="100" tabindex="2" rows="10" class="formboxes" name="Body">
<xsl:attribute name="onKeyUp">storeCaret(this);</xsl:attribute>
<xsl:attribute name="onClick">storeCaret(this);</xsl:attribute>
<xsl:attribute name="onKeyPress">checkKeyPressed(document.replier,event,false);</xsl:attribute>
<xsl:value-of select="$body"/>
</textarea>
<br/>
<br/>
<script language="Javascript" type="text/javascript" src="/static/js/textEditor.js"><xsl:text> </xsl:text></script>
<script language="Javascript" type="text/javascript">
<![CDATA[
function insertInBody(str) {
insertAtCaret(document.replier.Body, str);
document.replier.Body.focus();
}
]]>
</script>
<table border="0">
<tr class="tdheader">
<td><b>Ñìàéëèêè</b></td>
<td valign="top"><b>UBBCode</b></td>
<td valign="top"><b>Øðèôò</b></td>
</tr>
<tr>
<td valign="top" align="left" nowrap="nowrap">
<a pseudolink="pseudolink" onClick="insertInBody(' :) ');">
<img src="/static/smileys/smile.gif" border="0" alt="smile" />
</a>
<xsl:text> &#160; </xsl:text>
<a pseudolink="pseudolink" onClick="insertInBody(' :( ');">
<img src="/static/smileys/frown.gif" border="0" alt="frown" />
</a>
<xsl:text> &#160; </xsl:text>
<a pseudolink="pseudolink" onClick="insertInBody(' :o ');">
<img src="/static/smileys/blush.gif" border="0" alt="blush" />
</a>
<xsl:text> &#160; </xsl:text>
<a pseudolink="pseudolink" onClick="insertInBody(' :D ');">
<img src="/static/smileys/laugh.gif" border="0" alt="laugh" />
</a>
<xsl:text> &#160; </xsl:text>
<a pseudolink="pseudolink" onClick="insertInBody(' ;) ');">
<img src="/static/smileys/wink.gif" border="0" alt="wink" />
</a>
<xsl:text> &#160; </xsl:text>
<a pseudolink="pseudolink" onClick="insertInBody(' :p ');">
<img src="/static/smileys/tongue.gif" border="0" alt="tongue" />
</a>
<br/>
<a pseudolink="pseudolink" onClick="insertInBody(' :cool: ');">
<img src="/static/smileys/cool.gif" border="0" alt="cool" />
</a>
<xsl:text> &#160; </xsl:text>
<a pseudolink="pseudolink" onClick="insertInBody(' :crazy: ');">
<img src="/static/smileys/crazy.gif" border="0" alt="crazy" />
</a>
<xsl:text> &#160; </xsl:text>
<a pseudolink="pseudolink" onClick="insertInBody(' :mad: ');">
<img src="/static/smileys/mad.gif" border="0" alt="mad" />
</a>
<xsl:text> &#160; </xsl:text>
<a pseudolink="pseudolink" onClick="insertInBody(' :shocked: ');">
<img src="/static/smileys/shocked.gif" border="0" alt="shocked" />
</a>
<xsl:text> &#160; </xsl:text>
<a pseudolink="pseudolink" onClick="insertInBody(' :smirk: ');">
<img src="/static/smileys/smirk.gif" border="0" alt="smirk" />
</a>
<xsl:text> &#160; </xsl:text>
<a pseudolink="pseudolink" onClick="insertInBody(' :grin ');">
<img src="/static/smileys/grin.gif" border="0" alt="grin" />
</a>
<br/>
<a pseudolink="pseudolink" onClick="insertInBody(' :ooo: ');">
<img src="/static/smileys/ooo.gif" border="0" alt="ooo" />
</a>
<xsl:text> &#160; </xsl:text>
<a pseudolink="pseudolink" onClick="insertInBody(' :confused: ');">
<img src="/static/smileys/confused.gif" border="0" alt="confused" />
</a>
<xsl:text> &#160; </xsl:text>
<a>
<xsl:text>More!</xsl:text>
</a>
<xsl:text> &#160; </xsl:text>
<a href="/Upload/New/">
<xsl:text>Upload</xsl:text>
</a>
<xsl:text> &#160; </xsl:text>
<a>
<xsl:text>Mix</xsl:text>
</a>
</td>
<td valign="top" align="left" nowrap="nowrap">
<table border="0" cellpadding="3" cellspacing="1" class="tablesurround">
<tr>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('url');">URL</a>
</td>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('code');">Êîä</a>
</td>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('image');">Êàðòèíêà</a>
</td>
</tr>
<tr>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('liststart');">Íà÷àëî ñïèñêà</a>
</td>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('listitem');">Ýë-ò ñïèñêà</a>
</td>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('listend');">Êîíåö ñïèñêà</a>
</td>
</tr>
<tr>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('pollstart');">Íà÷àëî<br/>ãîëîñîâàíèÿ</a>
</td>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('polloption');">Âàðèàíò<br/>ãîëîñîâàíèÿ</a>
</td>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('pollstop');">Êîíåö<br/>ãîëîñîâàíèÿ</a>
</td>
</tr>
<tr>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('bold');">Æèðíûé</a>
</td>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('italics');">Íàêëîí</a>
</td>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('quote');">Öèòàòà</a>
</td>
</tr>
<tr>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('user');">Ïîëüçîâàòåëü</a>
</td>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('table');">Òàáëèöà</a>
</td>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('ecode');">Ecode</a>
</td>
</tr>
<tr>
<td class="darktable">
<a pseudolink="pseudolink" onclick="DoPrompt('video');">YouTube</a>
</td>
<td class="darktable" colspan="2">
<a pseudolink="pseudolink" onclick="DoPrompt('math');">Math</a>
</td>
</tr>
</table>
</td>
<td valign="top">
<table border="0">
<tr>
<td>
<select id="fontselect" class="formboxes" style="font-size:10px">
<xsl:attribute name="onChange">idx = this.selectedIndex; this.selectedIndex = 0; DoFont(this.options[idx].value);</xsl:attribute>
<option value="">[Font Face]</option>
<script type="text/javascript">fontlist();</script>
</select>
</td>
</tr>
<tr>
<td>
<select id="sizeselect" class="formboxes" style="font-size:10px">
<xsl:attribute name="onChange">idx = this.selectedIndex; this.selectedIndex = 0; DoSize(this.options[idx].value);</xsl:attribute>
<option value="">[Font Size]</option>
<option value="1">1</option>
<option value="2">2</option>
<option value="3">3</option>
<option value="4">4</option>
<option value="5">5</option>
<option value="6">6</option>
</select>
</td>
</tr>
</table>
<table border="1">
<tr>
<td bgcolor="red">
<a pseudolink="pseudolink" onclick="DoColor('red');">&#160; &#160; </a>
</td>
<td bgcolor="green">
<a pseudolink="pseudolink" onclick="DoColor('green');">&#160; &#160; </a>
</td>
<td bgcolor="blue">
<a pseudolink="pseudolink" onclick="DoColor('blue');">&#160; &#160; </a>
</td>
<td bgcolor="white">
<a pseudolink="pseudolink" onclick="DoColor('white');">&#160; &#160; </a>
</td>
</tr>
<tr>
<td bgcolor="orange">
<a pseudolink="pseudolink" onclick="DoColor('orange');">&#160; &#160; </a>
</td>
<td bgcolor="yellow">
<a pseudolink="pseudolink" onclick="DoColor('yellow');">&#160; &#160; </a>
</td>
<td bgcolor="black">
<a pseudolink="pseudolink" onclick="DoColor('black');">&#160; &#160; </a>
</td>
<td bgcolor="purple">
<a pseudolink="pseudolink" onclick="DoColor('purple');">&#160; &#160; </a>
</td>
</tr>
<tr>
<td bgcolor="pink">
<a pseudolink="pseudolink" onclick="DoColor('pink');">&#160; &#160; </a>
</td>
<td bgcolor="brown">
<a pseudolink="pseudolink" onclick="DoColor('brown');">&#160; &#160; </a>
</td>
<td bgcolor="#666666">
<a pseudolink="pseudolink" onclick="DoColor('#666666');">&#160; &#160; </a>
</td>
<td>
<a pseudolink="pseudolink" onclick="DoPrompt('color');">?</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="Windows-1251"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns="http://www.w3.org/1999/xhtml">
<xsl:import href="..\elems\Main.xslt"/>
<xsl:template name="specific">
<table width="95%" align="center" cellpadding="1" cellspacing="1" class="tablesurround">
<tr>
<td>
<table cellpadding="3" cellspacing="1" width="100%" class="tableborders">
<tr>
<td class="tdheader">
<xsl:text>Íîâîå ñîîáùåíèå</xsl:text>
</td>
</tr>
<tr>
<td class="lighttable">
<xsl:text>Âàøå ñîîáùåíèå áûëî óñïåøíî ñîçäàíî</xsl:text>
<br/>
<a>
<xsl:attribute name="href">/Thread/<xsl:value-of select="post/threadId"/>/p<xsl:value-of select="post/id"/></xsl:attribute>
<xsl:text>Ïðîñìîòðåòü ñîîáùåíèå</xsl:text>
</a>
</td>
</tr>
</table>
</td>
</tr>
</table>
</xsl:template>
</xsl:stylesheet>
Loading…
Cancel
Save