added: a new editor: tinymce (function tinymce)

added: html filter can check orphans: "i", "a", "o" ... in a text


git-svn-id: svn://ttmath.org/publicrep/winix/trunk@607 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2010-06-20 22:47:24 +00:00
parent fe31e0e849
commit ff3c141138
16 changed files with 671 additions and 168 deletions

View File

@ -138,6 +138,7 @@ void Content::CallFunction()
{FUN_UPLOAD, &Content::FunUpload},
{FUN_TICKET, &Content::FunTicket},
{FUN_CKEDITOR, &Content::FunEmacs},
{FUN_TINYMCE, &Content::FunEmacs},
{FUN_LOGIN, &Content::FunLogin},
{FUN_MV, &Content::FunMv},
{FUN_UNAME, &Content::FunUname},
@ -220,6 +221,7 @@ void Content::CallPostFunction()
{FUN_UPLOAD, &Content::PostFunUpload},
{FUN_EDITTICKET,&Content::PostFunEditTicket},
{FUN_CKEDITOR, &Content::PostFunEmacs},
{FUN_TINYMCE, &Content::PostFunEmacs},
{FUN_ADDUSER, &Content::PostFunAddUser},
{FUN_MV, &Content::PostFunMv},
{FUN_SUBJECT, &Content::PostFunSubject},

View File

@ -45,6 +45,7 @@
#define FUN_ADDUSER 29
#define FUN_SUBJECT 30
#define FUN_CP 31
#define FUN_TINYMCE 32

View File

@ -73,6 +73,7 @@ void Functions::ReadFunctions()
AddFun(FUN_ADDUSER, "adduser");
AddFun(FUN_SUBJECT, "subject");
AddFun(FUN_CP, "cp");
AddFun(FUN_TINYMCE, "tinymce");
// functions which need more privileges

View File

@ -35,10 +35,24 @@ void HTMLFilter::Filter(const char * in, std::string & out)
last_new_line = false;
out_string->clear();
Init();
Read();
Deinit();
}
void HTMLFilter::Init()
{
}
void HTMLFilter::Deinit()
{
}
void HTMLFilter::Filter(const std::string & in, std::string & out)
{
out.reserve(in.size() * 2 + 1);
@ -51,9 +65,11 @@ HTMLFilter::HTMLFilter()
pstack = new Item[WINIX_HTMLFILTER_STACK_MAXLEN];
buffer = new char[WINIX_HTMLFILTER_BUFFER_MAXLEN];
tab_size = 2;
trim_white = false;
break_long_lines = false;
tab_size = 2;
trim_white = false;
break_after = 0;
lang = lang_none;
orphan_mode = orphan_nbsp;
}
@ -82,9 +98,12 @@ HTMLFilter::~HTMLFilter()
}
void HTMLFilter::BreakLongLines(bool break_lines)
void HTMLFilter::BreakLines(size_t break_after_)
{
break_long_lines = break_lines;
break_after = break_after_;
if( break_after > 10000 )
break_after = 10000;
}
@ -103,6 +122,15 @@ void HTMLFilter::InsertTabs(size_t tabsize)
}
void HTMLFilter::CheckOrphans(HTMLFilter::Lang lang_, HTMLFilter::OrphanMode mode)
{
lang = lang_;
orphan_mode = mode;
}
HTMLFilter::Item & HTMLFilter::GetItem(size_t i)
{
if( i >= stack_len )
@ -175,7 +203,34 @@ void HTMLFilter::SkipWhiteLines()
}
bool HTMLFilter::SkipTagCheck()
void HTMLFilter::SkipWhiteWithFirstNewLine()
{
SkipWhite();
if( *pchar == 10 )
{
pchar += 1;
SkipWhite();
}
}
void HTMLFilter::CheckNewLine()
{
const char * start = pchar;
SkipWhite();
last_new_line = (*pchar==10);
pchar = start;
}
bool HTMLFilter::IsClosingTagForLastItem()
{
pchar += 1;
SkipWhite();
@ -190,7 +245,7 @@ bool HTMLFilter::SkipTagCheck()
pchar += LastItem().name_len;
SkipWhite();
if( *pchar == '>' )
if( IsClosingTagMark() )
{
pchar += 1;
return true;
@ -202,23 +257,9 @@ return false;
}
void HTMLFilter::SkipNormalText()
{
while( *pchar!=0 && *pchar!='<' )
++pchar;
}
void HTMLFilter::CheckNewLine()
{
const char * start = pchar;
SkipWhite();
last_new_line = (*pchar==10);
pchar = start;
}
// used for such tags as: script, pre, textarea
void HTMLFilter::PutLastTagWithClosingTag()
{
const char * start = pchar;
@ -226,9 +267,9 @@ const char * start = pchar;
while( *pchar != 0 )
{
if( *pchar == '<' )
if( IsOpeningTagMark() )
{
if( SkipTagCheck() )
if( IsClosingTagForLastItem() )
{
PopStack();
CheckNewLine();
@ -246,29 +287,25 @@ const char * start = pchar;
void HTMLFilter::SkipItem()
const char * HTMLFilter::SkipItemCheckXmlSimple()
{
while( *pchar!=0 && *pchar!='>' )
++pchar;
if( *pchar == '>' )
++pchar;
}
const char * end = pchar;
void HTMLFilter::SkipItemCheckXmlSimple()
{
while( *pchar!=0 )
{
while( *pchar!=0 && *pchar!='>' && *pchar!='/')
while( *pchar!=0 && !IsClosingTagMark() && !IsClosingXmlSimpleTagMark())
++pchar;
if( *pchar == '/' ) // closing xml tag
if( IsClosingXmlSimpleTagMark() ) // closing xml tag: default '/'
{
end = pchar;
++pchar;
SkipWhite();
if( *pchar == '>' )
if( IsClosingTagMark() )
{
++pchar;
LastItem().type = Item::simple;
@ -276,12 +313,15 @@ void HTMLFilter::SkipItemCheckXmlSimple()
}
}
else
if( *pchar == '>' )
if( IsClosingTagMark() )
{
end = pchar;
++pchar;
break;
}
}
return end;
}
@ -324,37 +364,231 @@ void HTMLFilter::Put(const char * str, const char * end)
}
size_t HTMLFilter::PutTrimFillBuffer(const char * & str, const char * & end)
int HTMLFilter::CheckOrphan(const char * str, const char * end, const char * orphan)
{
size_t non_whites = 0;
size_t i = 0;
bool was_white;
size_t res;
for( ; str < end && i<WINIX_HTMLFILTER_BUFFER_MAXLEN-1 ; ++str )
for( ; str<end && *orphan!=0 ; ++str, ++orphan )
{
was_white = false;
res = ToLower(*(unsigned const char*)str) - ToLower(*(unsigned const char*)orphan);
if( res != 0 )
return res;
}
if( *str==10 || IsWhite(*str) )
if( str < end )
return ToLower(*(unsigned const char*)str);
return -ToLower(*(unsigned const char*)orphan);
}
// binary search in table
// o1 - index of the first element
// o2 - index of the last element
bool HTMLFilter::CheckOrphanTable(const char * str, const char * end, const char ** table, size_t o1, size_t o2)
{
int res;
res = CheckOrphan(str, end, table[o1]);
if( res == 0 )
return true;
if( res < 0 )
return false;
res = CheckOrphan(str, end, table[o2]);
if( res == 0 )
return true;
if( res > 0 )
return false;
while( o1 + 1 < o2 )
{
size_t o = (o1 + o2) / 2;
res = CheckOrphan(str, end, table[o]);
if( res == 0 )
return true;
if( res < 0 )
o2 = o;
else
o1 = o;
}
return false;
}
bool HTMLFilter::CheckOrphanLangPl(const char * str, const char * end)
{
// the table must be sorted in alphabetical order
// polish letters coded in iso-8859-2
static const char * orphans[] = {
"(np.", "s.", "a", "ale", "bo", "by", "co", "czy", "do", "go", "i",
"ich", "ja", "je", "jej", "jest", "ju¿", "", "ku", "li", "mi", "na",
"nie", "np.", "nr", "o", "od", "po", "", "ta", "to", "tu", "",
"", "u", "w", "we", "wy", "z", "za", "ze", "¿e", "ów"
};
size_t o1 = 0;
size_t o2 = sizeof(orphans) / sizeof(const char*) - 1;
return CheckOrphanTable(str, end, orphans, o1, o2);
}
// SK i CZ
bool HTMLFilter::CheckOrphanLangCz(const char * str, const char * end)
{
// the table must be sorted in alphabetical order
static const char * orphans[] = {
"a", "i", "k", "o", "s", "u", "v", "z"
};
size_t o1 = 0;
size_t o2 = sizeof(orphans) / sizeof(const char*) - 1;
return CheckOrphanTable(str, end, orphans, o1, o2);
}
bool HTMLFilter::CheckOrphan(const char * str, const char * end)
{
if( str == end || lang == lang_none )
return false;
if( lang == lang_cz || lang == lang_sk )
return CheckOrphanLangCz(str, end);
return CheckOrphanLangPl(str, end);
}
size_t HTMLFilter::PutNormalTextFillBuffer(const char * & str, const char * & end)
{
const char * word = str; // pointing at the beginning of a word
size_t i = 0;
// some space in the buffer for non break spaces (orphans) and spaces at the beginning of a line
size_t epsilon = WINIX_HTMLFILTER_BUFFER_MAXLEN / 10 + 1;
bool is_white;
bool was_white = true;
size_t non_whites = 0;
for( ; str < end && i<WINIX_HTMLFILTER_BUFFER_MAXLEN-epsilon ; ++str )
{
is_white = (*str==10 || IsWhite(*str));
if( is_white && !was_white )
{
// skipping the whole white string
for( ; (*str==10 || IsWhite(*str)) && str < end ; ++str );
if( CheckOrphan(word, str) )
{
i += PutNonBreakSpaceToBuffer(i);
was_white = true;
non_whites = 0;
// here we have to skip the whole white string
for( ; (*str==10 || IsWhite(*str)) && str < end ; ++str );
if( str == end )
break;
is_white = false;
was_white = true;
}
}
// skipping the last new line character (if exists)
if( *str == 10 && str < end-1 )
{
buffer[i] = *str;
i += 1;
i += PutTabsToBuffer(i, stack_len);
}
else
if( *str != 10 )
{
non_whites += 1;
buffer[i] = *str;
i += 1;
}
if( (non_whites>60 && break_long_lines) || was_white )
if( was_white && !is_white )
word = str;
if( !is_white )
non_whites += 1;
else
non_whites = 0;
if( break_after!=0 && non_whites>=break_after )
{
buffer[i] = ' ';
i += 1;
non_whites = 0;
}
was_white = is_white;
}
return i;
}
size_t HTMLFilter::PutNormalTextTrimFillBuffer(const char * & str, const char * & end)
{
const char * word = str; // pointint at the beginning of a word
size_t non_whites = 0;
size_t i = 0;
bool is_white;
// some space in the buffer for non break spaces (orphans) and spaces at the beginning of a line
size_t epsilon = WINIX_HTMLFILTER_BUFFER_MAXLEN / 10 + 1;
for( ; str < end && i<WINIX_HTMLFILTER_BUFFER_MAXLEN-epsilon ; ++str )
{
is_white = (*str==10 || IsWhite(*str));
if( is_white )
{
if( CheckOrphan(word, str) )
{
i += PutNonBreakSpaceToBuffer(i);
is_white = false;
}
else
{
non_whites = 0;
}
// skipping the whole white string
for( ; (*str==10 || IsWhite(*str)) && str < end ; ++str );
word = str;
}
if( !is_white )
non_whites += 1;
else
non_whites = 0;
if( (break_after!=0 && non_whites>break_after) || is_white )
{
buffer[i] = ' ';
i += 1;
non_whites = 1;
}
if( str < end )
{
buffer[i] = *str;
@ -366,102 +600,166 @@ return i;
}
// if there are more than one white characters then they will be changed into one space
// and putting a space between 50 characters (if there were not any other white characters between them)
void HTMLFilter::PutTrim(const char * str, const char * end)
void HTMLFilter::PutNormalText(const char * str, const char * end)
{
size_t buf_len;
// this buffer must have at least 2 bytes (PutTrimFillBuffer needs it)
if( !trim_white || WINIX_HTMLFILTER_BUFFER_MAXLEN < 2 )
{
Put(str, end);
return;
}
while( str < end )
{
buf_len = PutTrimFillBuffer(str, end);
buf_len = PutNormalTextFillBuffer(str, end);
Put(buffer, buffer+buf_len);
}
}
void HTMLFilter::PutOpeningTag(const char * tag)
void HTMLFilter::PutNormalTextTrim(const char * str, const char * end)
{
size_t i;
size_t buf_len;
if( WINIX_HTMLFILTER_BUFFER_MAXLEN < WINIX_HTMLFILTER_ITEM_MAXLEN+2 )
return;
while( str < end )
{
buf_len = PutNormalTextTrimFillBuffer(str, end);
Put(buffer, buffer+buf_len);
}
}
buffer[0] = '<';
for(i=1 ; *tag ; ++i, ++tag)
buffer[i] = *tag;
void HTMLFilter::PutOpeningTagMark()
{
(*out_string) += '<';
}
buffer[i] = '>';
i += 1;
Put(buffer, buffer+i);
void HTMLFilter::PutClosingTagMark()
{
(*out_string) += '>';
}
void HTMLFilter::PutTagName(const char * name)
{
(*out_string) += name;
}
// start, end - arguments
void HTMLFilter::PutOpeningTag(const char * start, const char * end)
{
PutOpeningTagMark();
PutTagName(LastItem().name);
if( start != end )
{
(*out_string) += ' ';
Put(start, end);
}
PutClosingTagMark();
}
void HTMLFilter::PutClosingTag(const char * tag)
{
size_t i;
if( WINIX_HTMLFILTER_BUFFER_MAXLEN < WINIX_HTMLFILTER_ITEM_MAXLEN+3 )
return;
buffer[0] = '<';
buffer[1] = '/';
for(i=2 ; *tag ; ++i, ++tag)
buffer[i] = *tag;
buffer[i] = '>';
i += 1;
Put(buffer, buffer+i);
PutOpeningTagMark();
(*out_string) += '/';
PutTagName(tag);
PutClosingTagMark();
}
void HTMLFilter::PutTabs(size_t len)
size_t HTMLFilter::PutTabsToBuffer(size_t index, size_t len)
{
if( len == 0 )
return;
return 0;
if( len > 20 )
len = 20;
// how many spaces do you want
size_t spaces = (len-1) * tab_size;
size_t i;
size_t spaces = len * tab_size;
size_t i = 0;
if( spaces < WINIX_HTMLFILTER_BUFFER_MAXLEN )
if( index+spaces < WINIX_HTMLFILTER_BUFFER_MAXLEN-1 )
{
for(i=0 ; i<spaces ; ++i)
buffer[i] = ' ';
Put(buffer, buffer+i);
for( ; i<spaces ; ++i )
buffer[index+i] = ' ';
}
return i;
}
size_t HTMLFilter::PutNonBreakSpaceToBuffer(size_t index)
{
size_t i = 0;
if( orphan_mode == orphan_nbsp )
{
static const char nb[] = "&nbsp;";
size_t len = sizeof(nb) / sizeof(char) - 1; // '0' at the end
if( index+len < WINIX_HTMLFILTER_BUFFER_MAXLEN-1 )
{
for( ; i<len ; ++i )
buffer[index+i] = nb[i];
}
}
else
{
if( index+1 < WINIX_HTMLFILTER_BUFFER_MAXLEN-1 )
{
i = 1;
buffer[index] = (char)160;
}
}
return i; // return i not len (can be zero)
}
void HTMLFilter::PutTabs(size_t len)
{
size_t i = PutTabsToBuffer(0, len);
Put(buffer, buffer+i);
}
void HTMLFilter::PutNewLine()
{
if( !trim_white )
// new line characters will be directly from the source html
return;
buffer[0] = 10;
Put(buffer, buffer+1);
}
// we assume the size of the opening mark to be one
bool HTMLFilter::IsOpeningTagMark()
{
return (*pchar == '<');
}
bool HTMLFilter::IsOpeningCommentaryTag()
// we assume the size of the closing mark to be one
bool HTMLFilter::IsClosingTagMark()
{
return (*pchar == '>');
}
// the slash at the end <img src=".." /> (without '>' character)
// we assume the size of the mark to be one
bool HTMLFilter::IsClosingXmlSimpleTagMark()
{
return (*pchar == '/');
}
bool HTMLFilter::IsOpeningCommentaryTagMark()
{
static char comm_open[] = "<!--";
size_t comm_open_len = sizeof(comm_open) / sizeof(char) - 1;
@ -470,6 +768,12 @@ size_t comm_open_len = sizeof(comm_open) / sizeof(char) - 1;
}
size_t HTMLFilter::OpeningCommentaryTagMarkSize()
{
return 4; // size of "<!--"
}
// skipping the commentary tag if exists
bool HTMLFilter::SkipCommentaryTagIfExists()
@ -477,10 +781,10 @@ bool HTMLFilter::SkipCommentaryTagIfExists()
static char comm_close[] = "-->";
size_t comm_close_len = sizeof(comm_close) / sizeof(char) - 1;
if( !IsOpeningCommentaryTag() )
if( !IsOpeningCommentaryTagMark() )
return false;
pchar += 4; // size of commentary opening tag
pchar += OpeningCommentaryTagMarkSize();
// looking for "-->"
while( *pchar!=0 && !IsNameEqual(pchar, comm_close, comm_close_len) )
@ -495,57 +799,96 @@ return true;
}
void HTMLFilter::ReadNormalTextSkipWhite(const char * & start, const char * & last_non_white)
{
if( trim_white )
{
// skipping all white chars (with new lines)
// but with remembering the last non white character
for( ; *pchar==10 || IsWhite(*pchar) ; ++pchar)
if( *pchar == 10 )
last_non_white = pchar;
}
else
{
// skipping first white chars with only one line between them
SkipWhite();
last_non_white = pchar;
if( *pchar == 10 )
{
++pchar;
SkipWhite();
}
}
start = pchar;
// exception for the commentary tag
if( IsOpeningCommentaryTagMark() || !IsOpeningTagMark() )
{
PutNewLine();
PutTabs(stack_len);
}
}
// reading text between html tags
void HTMLFilter::ReadNormalText()
{
const char * start = pchar;
const char * last_non_white = pchar;
SkipWhiteLines();
if( *pchar!=0 && (IsOpeningCommentaryTag() || *pchar!='<') && last_new_line )
{
if( *pchar == '<' )
// skipping some white characters before a opening commentary tag
// (but only a tag in a new line)
start = pchar;
PutNewLine();
PutTabs(stack_len+1);
last_new_line = false; // in normal text we don't allow a new line character
}
if( last_new_line )
ReadNormalTextSkipWhite(start, last_non_white);
while( *pchar != 0 )
{
if( !SkipCommentaryTagIfExists() )
if( SkipCommentaryTagIfExists() )
{
if( *pchar == '<' )
last_non_white = pchar - 1; // pointing at the last '>' from a commentary
}
else
{
if( IsOpeningTagMark() )
break;
if( !IsWhite(*pchar) )
last_non_white = pchar;
pchar += 1;
}
}
PutTrim(start, pchar);
last_new_line = (*last_non_white == 10);
if( trim_white )
PutNormalTextTrim(start, pchar);
else
PutNormalText(start, pchar);
}
// start, end - parameters to a tag
void HTMLFilter::PrintItem(const char * start, const char * end)
{
// closing tags will be printed later
// (when we check the stack)
if( LastItem().type != Item::closing )
{
if( last_new_line )
{
if( stack_len > 0 )
PutNewLine();
PutNewLine();
if( stack_len > 1 )
PutTabs(stack_len);
PutTabs(stack_len-1);
}
// closing tags will be printed later
// (when we check the stack)
Put(start, pchar);
PutOpeningTag(start, end);
}
}
@ -554,13 +897,12 @@ void HTMLFilter::PrintItem(const char * start, const char * end)
bool HTMLFilter::ReadItem()
{
const char * start;
const char * start = pchar;
if( *pchar == 0 )
return false;
// we have '<'
start = pchar;
pchar += 1;
SkipWhite();
@ -574,17 +916,20 @@ const char * start;
}
ReadItemName();
SkipWhite();
start = pchar; // arguments start here
if( LastItem().type != Item::closing )
LastItem().type = (LastItem().name[0] == '!') ? Item::special : Item::opening;
SkipItemCheckXmlSimple();
PrintItem(start, pchar);
const char * end = SkipItemCheckXmlSimple();
PrintItem(start, end);
CheckNewLine();
LastItem().new_line = last_new_line;
return true;
}
return true;
}
pchar = start;
return false;
@ -613,6 +958,7 @@ return false;
}
// len characters from both strings must be equal
bool HTMLFilter::IsNameEqual(const char * name1, const char * name2, size_t len)
{
@ -626,6 +972,8 @@ bool HTMLFilter::IsNameEqual(const char * name1, const char * name2, size_t len)
return false;
}
bool HTMLFilter::IsLastTag(const char * name)
{
const char * tag = LastItem().name;
@ -634,6 +982,7 @@ bool HTMLFilter::IsLastTag(const char * name)
}
// checking exceptions for opening tags
void HTMLFilter::CheckExceptions()
{
@ -685,7 +1034,7 @@ int i;
if( pstack[z].new_line )
{
PutNewLine();
PutTabs(z+1);
PutTabs(z);
}
PutClosingTag(pstack[z].name);
@ -699,6 +1048,19 @@ int i;
}
void HTMLFilter::CheckStackPrintRest()
{
while( stack_len-- > 0 )
{
if( stack_len==0 || pstack[stack_len-1].new_line )
PutNewLine();
PutTabs(stack_len);
PutClosingTag(pstack[stack_len].name);
}
}
void HTMLFilter::CheckClosingTags()
{
if( stack_len == 0 )
@ -722,7 +1084,7 @@ void HTMLFilter::CheckClosingTags()
if( pstack[stack_len-2].new_line )
{
PutNewLine();
PutTabs(stack_len-1);
PutTabs(stack_len-2);
}
PutClosingTag(pstack[stack_len-1].name);
@ -736,7 +1098,7 @@ void HTMLFilter::CheckClosingTags()
}
void HTMLFilter::PrintRest()
bool HTMLFilter::PrintRest()
{
const char * start = pchar;
@ -744,19 +1106,26 @@ const char * start = pchar;
++pchar;
if( pchar > start )
{
Put(start, pchar);
return true;
}
return false;
}
void HTMLFilter::Read()
{
// white characters at the beginning are skipped
SkipWhiteLines();
if( trim_white )
SkipWhiteLines();
// it can be some text before the first html tag (we print it)
// it can be some text or white lines before the first html tag (we print it)
ReadNormalText();
while( *pchar && ReadItem() )
while( ReadItem() )
{
if( LastItem().type == Item::opening )
{
@ -770,6 +1139,7 @@ void HTMLFilter::Read()
pstack[stack_len-2].new_line = LastItem().new_line;
}
else
if( trim_white )
{
// one new line after a simple or special tag
// (if the tag has level 0 in the tree - it not means that this is a first tag)
@ -790,7 +1160,8 @@ void HTMLFilter::Read()
// sometimes ReadItem() can return a false (when there is no space on the stack)
// we print the rest html without filtering
PrintRest();
if( !PrintRest() )
CheckStackPrintRest();
}

View File

@ -23,7 +23,7 @@
// length of a buffer used for printing
// it should be at least: WINIX_HTMLFILTER_ITEM_MAXLEN+3
#define WINIX_HTMLFILTER_BUFFER_MAXLEN 1024
#define WINIX_HTMLFILTER_BUFFER_MAXLEN 2048
@ -48,6 +48,23 @@ class HTMLFilter
{
public:
// for checking orphans
enum Lang
{
lang_pl,
lang_cz,
lang_sk,
lang_none
};
enum OrphanMode
{
orphan_nbsp,
orphan_nbspace
};
HTMLFilter();
HTMLFilter(const HTMLFilter & f);
HTMLFilter & operator=(const HTMLFilter & f);
@ -60,8 +77,8 @@ public:
// insert a white space into long lines
// only between html tags
// skipped in such tags: script, pre, textarea
// false by default
void BreakLongLines(bool break_lines);
// break_after - after how many characters insert a space (0 - off)
void BreakLines(size_t break_after_);
// trimming white characters (with new lines)
// at the beginning, at the end and in the middle of a string
@ -76,6 +93,10 @@ public:
// set 0 to turn off
void InsertTabs(size_t tabsize);
// check 'orphans' for the specicic language
// if an orphans is detected then the non-break space (&nbsp;) will be put
// default disable: lang_none
void CheckOrphans(Lang lang_, OrphanMode mode = orphan_nbsp);
@ -116,35 +137,57 @@ protected:
bool IsNameEqual(const char * name1, const char * name2, size_t len);
bool IsLastTag(const char * name);
public: // !!
int CheckOrphan(const char * str, const char * end, const char * orphan);
bool CheckOrphanTable(const char * str, const char * end, const char ** table, size_t o1, size_t o2);
bool CheckOrphanLangPl(const char * str, const char * end);
bool CheckOrphanLangCz(const char * str, const char * end);
bool CheckOrphan(const char * str, const char * end);
bool IsWhite(int c);
void SkipWhite();
void SkipWhiteLines();
bool SkipTagCheck();
void SkipNormalText();
bool IsOpeningCommentaryTag();
void SkipWhiteWithFirstNewLine();
bool IsClosingTagForLastItem();
virtual bool IsOpeningTagMark();
virtual bool IsOpeningCommentaryTagMark();
size_t OpeningCommentaryTagMarkSize();
virtual bool IsClosingTagMark();
virtual bool IsClosingXmlSimpleTagMark();
bool SkipCommentaryTagIfExists();
void SkipItem();
void SkipItemCheckXmlSimple();
const char * SkipItemCheckXmlSimple();
void PopStack();
bool PushStack();
bool IsValidCharForName(int c);
virtual bool IsValidCharForName(int c);
void CheckNewLine();
void CheckExceptions();
void CheckStackPrintRest();
void AddForgottenTags();
void CheckClosingTags();
void ReadNormalTextSkipWhite(const char * & start, const char * & last_non_white);
void ReadNormalText();
void PrintRest();
bool PrintRest();
void PrintItem(const char * start, const char * end);
void ReadItemName();
bool ReadItem();
virtual void Init();
virtual void Deinit();
void Read();
size_t PutTrimFillBuffer(const char * & str, const char * & end);
void PutTrim(const char * str, const char * end);
size_t PutNormalTextTrimFillBuffer(const char * & str, const char * & end);
size_t PutNormalTextFillBuffer(const char * & str, const char * & end);
void PutNormalText(const char * str, const char * end);
void PutNormalTextTrim(const char * str, const char * end);
void PutLastTagWithClosingTag();
void PutOpeningTag(const char * tag);
void PutClosingTag(const char * tag);
virtual void PutOpeningTagMark();
virtual void PutClosingTagMark();
virtual void PutTagName(const char * name);
virtual void PutOpeningTag(const char * start, const char * end);
virtual void PutClosingTag(const char * tag);
size_t PutTabsToBuffer(size_t index, size_t len);
size_t PutNonBreakSpaceToBuffer(size_t index);
void PutTabs(size_t len);
void PutNewLine();
@ -155,9 +198,11 @@ protected:
char * buffer; // buffer used when printing
std::string * out_string;
bool last_new_line;
bool break_long_lines; // insert a space into long lines
bool trim_white; // trimming white characters
size_t break_after; // insert a space into long lines after break_after characters
bool trim_white; // trimming white characters
size_t tab_size;
Lang lang; // current language for checking orphans
OrphanMode orphan_mode;
};

View File

@ -483,8 +483,9 @@ void Request::SendPage(bool compressing, const std::string & source_ref)
if( data.html_filter && !raw )
{
html_filter.TrimWhite(true);
html_filter.BreakLongLines(true);
html_filter.BreakLines(60);
html_filter.InsertTabs(2);
html_filter.CheckOrphans(HTMLFilter::lang_pl, HTMLFilter::orphan_nbspace);
html_filter.Filter(*source, clean_html);
source = &clean_html;

49
html/fun_tinymce.html Executable file
View File

@ -0,0 +1,49 @@
[if-one item_is]<h1>{edit}</h1>[else]<h1>{add}</h1>[end]
[include "error.html"]
<form id="additem" method="post" action="[doc_base_url][dir][if-one item_is][item_url]/[end]tinymce">
<fieldset>
<legend>{form_emacs_legend}</legend>
[if-one mount_type_is_cms]
<p class="withnext">{title}:</p>
<input class="edit" type="text" name="subject" value="[item_subject]">
<p class="withnext">{suggested_url}:</p>
<input class="edit" type="text" name="url" value="[item_url]">
[end]
[if-one mount_type_is_thread]
[is mount_thread_is "subject"]
<p class="withnext">{title}:</p>
<input class="edit" type="text" name="subject" value="[item_subject]">
<p class="withnext">{suggested_url}:</p>
<input class="edit" type="text" name="url" value="[item_url]">
[end]
[end]
[if-one mount_type_is_cms]<p class="withnext">{form_emacs_content_cms}</p>[end]
[if-one mount_type_is_thread]<p class="withnext">{form_emacs_content_thread}</p>[end]
[if-one mount_type_is_ticket]<p class="withnext">{form_emacs_content_ticket}</p>[end]
<textarea class="[if-one winix_content_full]multitextfull[else]multitext[end]" rows="[if-one mount_type_is_cms]30[else]10[end]" cols="60" name="itemcontent">[item_content]</textarea>
<input type="hidden" name="contenttype" value="2">
[if-no user_logged]
<p class="withnext">{nick}:</p>
<input class="edit" type="text" name="guestname" value="[item_guest_name]">
<p class="withnext">{rebus_how_is_it} [rebus_question]?</p>
<input class="edit" type="text" name="rebus">
[end]
<input class="submit" type="submit" value="[if-one item_is]{change}[else]{add}[end]">
</fieldset>
</form>

View File

@ -1,9 +1,19 @@
<head>
<title>[doc_title]</title>
<meta http-equiv="content-type" content="text/html; charset={charset}">
<meta name="description" content="">
<meta name="keywords" content="">
<link rel="stylesheet" href="[doc_base_url_static]/winix/winix.css" type="text/css">
<link rel="shortcut icon" href="[doc_base_url_static]/favicon.ico">
[is winix_function_is "ckeditor"]<script type="text/javascript" src="[doc_base_url_static_ext]/ckeditor/ckeditor.js"></script>[end]
<title>[doc_title]</title>
<meta http-equiv="content-type" content="text/html; charset={charset}">
<meta name="description" content="">
<meta name="keywords" content="">
<link rel="stylesheet" href="[doc_base_url_static]/winix/winix.css" type="text/css">
<link rel="shortcut icon" href="[doc_base_url_static]/favicon.ico">
[is winix_function_is "ckeditor"]
<script type="text/javascript" src="[doc_base_url_common]/ckeditor/ckeditor.js"></script>
[end]
[is winix_function_is "tinymce"]
<script type="text/javascript" src="[doc_base_url_common]/tiny_mce/tiny_mce.js"></script>
<script type="text/javascript" src="[doc_base_url_common]/tinymce.js"></script>
[end]
</head>

View File

@ -13,7 +13,7 @@
[include "index_header.html"]
[is-no winix_function_is "ckeditor"]
[if-no winix_content_full]
<div id="winix_middle">
[include "index_contentmenu.html"]

View File

@ -7,6 +7,7 @@
<ul class="itemmenu">
[if-one dir_can_write]<li><a href="[doc_base_url][dir]emacs">{admin_emacs_add}</a></li>[end]
[if-any dir_can_write user_can_use_html]<li><a href="[doc_base_url][dir]ckeditor">{admin_ckeditor_add}</a></li>[end]
[if-any dir_can_write user_can_use_html]<li><a href="[doc_base_url][dir]tinymce">{admin_tinymce_add}</a></li>[end]
</ul>
[end]
@ -15,6 +16,7 @@
<ul class="itemmenu">
[if-any item_is item_can_write]<li><a href="[doc_base_url][dir][item_url]/emacs">{admin_emacs_edit}</a></li>[end]
[if-any item_is item_can_write user_can_use_html]<li><a href="[doc_base_url][dir][item_url]/ckeditor">{admin_ckeditor_edit}</a></li>[end]
[if-any item_is item_can_write user_can_use_html]<li><a href="[doc_base_url][dir][item_url]/tinymce">{admin_tinymce_edit}</a></li>[end]
</ul>
[end]

View File

@ -167,7 +167,9 @@ admin_emacs_add = Add page (emacs)
admin_emacs_edit = Edit page (emacs)
admin_ckeditor_add = Add page (ckeditor)
admin_ckeditor_edit = Edit page (ckeditor)
admin_rm = Remove stronê (rm)
admin_tinymce_add = Add page (tinymce)
admin_tinymce_edit = Edit page (tinymce)
admin_rm = Remove page (rm)
admin_upload = Upload an image or file (upload)

View File

@ -170,6 +170,8 @@ admin_emacs_add = Dodaj stron
admin_emacs_edit = Edytuj stronê (emacs)
admin_ckeditor_add = Dodaj stronê (ckeditor)
admin_ckeditor_edit = Edytuj stronê (ckeditor)
admin_tinymce_add = Dodaj stronê (tinymce)
admin_tinymce_edit = Edytuj stronê (tinymce)
admin_rm = Usuñ stronê (rm)
admin_upload = Wy¶lij zdjêcie lub plik (upload)

View File

@ -476,6 +476,13 @@ display: block;
width: 530px;
}
#additem .multitextfull {
margin: 0.5em 0 0.5em 0;
border: 1px solid #dedede;
display: block;
width: 630px;
}
#additem .submit {
margin: 1.5em 0 0.5em 0;

View File

@ -68,7 +68,8 @@ Ezc::Pattern * p = 0;
{FUN_CKEDITOR, pat_fun_ckeditor},
{FUN_SUBJECT, pat_fun_subject},
{FUN_ADDUSER, pat_fun_adduser},
{FUN_CP, pat_fun_cp}
{FUN_CP, pat_fun_cp},
{FUN_TINYMCE, pat_fun_tinymce},
};
size_t i, len = sizeof(pat_name_tab)/sizeof(PatName);
@ -463,7 +464,7 @@ void Templates::CreateFunctions()
functions.Insert("winix_err_code", winix_err_code);
functions.Insert("winix_is_err_in_locales", winix_is_err_in_locales);
functions.Insert("winix_err_msg_from_locales",winix_err_msg_from_locales);
functions.Insert("winix_content_full", winix_content_full);
plugin.Call(WINIX_TEMPLATES_CREATEFUNCTIONS, &functions);
}
@ -524,6 +525,7 @@ using namespace TemplatesFunctions;
ReadFile(pat_fun_adduser, "fun_adduser.html");
ReadFile(pat_fun_subject, "fun_subject.html");
ReadFile(pat_fun_cp, "fun_cp.html");
ReadFile(pat_fun_tinymce, "fun_tinymce.html");
}

View File

@ -54,6 +54,7 @@ namespace TemplatesFunctions
pat_dir_last_info,
pat_fun_subject,
pat_fun_cp,
pat_fun_tinymce,
pat_last // should be last
};
@ -368,6 +369,7 @@ namespace TemplatesFunctions
void winix_err_code(Info & i);
void winix_is_err_in_locales(Info & i);
void winix_err_msg_from_locales(Info & i);
void winix_content_full(Info & i);
} // namespace TemplatesFunctions

View File

@ -170,6 +170,12 @@ char buff[40];
}
void winix_content_full(Info & i)
{
if( request.pfunction )
i.res = (request.pfunction->code == FUN_CKEDITOR || request.pfunction->code == FUN_TINYMCE);
}
} // namespace