added: to htmlfilter: the filter is able to recognize a special tag, default called: <nofilter>

content between <nofilter>...</nofilter> will not be filtered



git-svn-id: svn://ttmath.org/publicrep/winix/trunk@955 e52654a7-88a9-db11-a3e9-0013d4bc506e
This commit is contained in:
Tomasz Sowa 2014-06-18 23:18:28 +00:00
parent 01892d2766
commit 160ddc258d
7 changed files with 142 additions and 20 deletions

View File

@ -202,6 +202,7 @@ void Config::AssignValues(bool stdout_is_closed)
html_filter_tabs = Size(L"html_filter_tabs", 2);
html_filter_orphans = Bool(L"html_filter_orphans", true);
html_filter_orphans_mode_str = Text(L"html_filter_orphans_mode_str", L"nbsp");
html_filter_nofilter_tag = Text(L"html_filter_nofilter_tag", L"nofilter");
locale_dir = Text(L"locale_dir");
locale_dir_default = Text(L"locale_dir_default");

View File

@ -224,6 +224,12 @@ public:
std::wstring html_filter_orphans_mode_str;
HTMLFilter::OrphanMode html_filter_orphans_mode;
// the html nofilter tag
// content betweeng these tags (opening and closing) will not be filtered
// and this tag will not be included in the html output
// default: nofilter
std::wstring html_filter_nofilter_tag;
// the url of a new empty item (if there is not the subject too)
// !! IMPROVE ME should be moved to locale
std::wstring item_url_empty;

View File

@ -10,6 +10,7 @@
#include "htmlfilter.h"
namespace Winix
{
@ -198,6 +199,13 @@ void HTMLFilter::SafeMode(bool safe_mode_)
}
void HTMLFilter::SetNoFilterTag(const std::wstring & tag_name)
{
no_filter_tag = tag_name;
}
HTMLFilter::Item & HTMLFilter::GetItem(size_t i)
{
@ -345,7 +353,6 @@ void HTMLFilter::PutLastTagWithClosingTag()
{
const wchar_t * start = pchar;
while( *pchar != 0 )
{
if( IsOpeningTagMark() )
@ -367,6 +374,31 @@ const wchar_t * start = pchar;
}
// used with <nofilter> </nofilter> tags
void HTMLFilter::PutTextBetweenLastTagWithClosingTag()
{
const wchar_t * start = pchar, * end = pchar;
while( *pchar != 0 )
{
if( IsOpeningTagMark() )
{
if( IsClosingTagForLastItem() )
{
PopStack();
CheckNewLine();
break;
}
}
else
{
pchar += 1;
end = pchar;
}
}
Put(start, end);
}
@ -449,16 +481,34 @@ void HTMLFilter::ReadItemAttrValue(bool has_quote)
{
size_t i;
// sprawdzic to wszedzie bo teraz jest tablica
attr_value.clear();
attr_value_temp.clear();
// !! moze dodac obsluge escepowania cudzyslowu? sprawdzic czy to jest dostepne w htmlu
for( i=0 ; *pchar && *pchar != '\"' && !IsClosingTagMark() && (has_quote || (*pchar!=10 && !IsWhite(*pchar)) ); ++i )
// !! dodac obsluge pojedynczego cudzyslowu
for(i=0 ; *pchar && *pchar != '\"' && !IsClosingTagMark() && (has_quote || (*pchar!=10 && !IsWhite(*pchar)) ); ++i )
{
if( *pchar==10 || IsWhite(*pchar) )
{
if( !attr_value_temp.empty() )
{
attr_value.push_back(attr_value_temp);
attr_value_temp.clear();
}
}
else
if( i < WINIX_HTMLFILTER_ATTR_VALUE_MAXLEN )
attr_value += *pchar;
attr_value_temp += *pchar;
++pchar;
}
if( !attr_value_temp.empty() )
{
attr_value.push_back(attr_value_temp);
attr_value_temp.clear();
}
}
@ -720,14 +770,22 @@ void HTMLFilter::PutClosingTagMark()
// !! zmienic na lepsza nazwe
// bo to nie zwraca true jesli tag jest safe
bool HTMLFilter::IsTagSafe(const wchar_t * tag)
{
if( !safe_mode )
return true;
if( IsNameEqual(tag, no_filter_tag.c_str()) )
return false;
static const wchar_t * unsafe_tags[] = {
L"script", L"iframe", L"frame", L"frameset",
L"applet", L"head", L"meta", L"html", L"link", L"body"
L"applet", L"base", L"body",
L"embed", L"head", L"html",
L"frame", L"frameset",L"iframe",
L"link", L"meta", L"param"
L"object", L"script"
};
size_t len = sizeof(unsafe_tags) / sizeof(const wchar_t*);
@ -755,7 +813,8 @@ bool HTMLFilter::IsTagSafe(const std::wstring & tag)
bool HTMLFilter::PutOpeningTag()
{
if( !IsTagSafe(LastItem().name) )
// dodac tutaj skipniecie calego tagu
// !! IMPROVE ME
// !! dodac tutaj skipniecie calego tagu
return false;
PutOpeningTagMark();
@ -945,6 +1004,9 @@ const wchar_t * last_non_white = pchar;
bool HTMLFilter::PrintOpeningItem()
{
if( IsNameEqual(no_filter_tag, LastItem().name) )
return true;
if( last_new_line )
{
PutNewLine();
@ -981,6 +1043,8 @@ bool HTMLFilter::ReadItemAttr()
pchar += 1; // skipping '='
SkipWhiteLines();
// !! dodac obsluge pojedynczego cudzyslowu
bool has_quote = (*pchar == '\"');
if( has_quote )
@ -1001,28 +1065,46 @@ bool HTMLFilter::CheckItemAttr()
if( attr_has_value && IsNameEqual(L"lang", attr_name) )
{
LastItem().porphans = 0;
attr_value_lower = attr_value;
ToLower(attr_value_lower);
OrphansTab::iterator i = orphans_tab.find(attr_value_lower);
if( !attr_value.empty() )
{
// we are taking the first value only
attr_value_lower = attr_value[0];
ToLower(attr_value_lower);
if( i != orphans_tab.end() )
LastItem().porphans = &i->second;
OrphansTab::iterator i = orphans_tab.find(attr_value_lower);
if( i != orphans_tab.end() )
LastItem().porphans = &i->second;
}
}
return true;
}
void HTMLFilter::PrinItemAttr()
void HTMLFilter::PrintItemAttr()
{
size_t i;
if( IsNameEqual(no_filter_tag, LastItem().name) )
return;
Put(' ');
Put(attr_name);
if( attr_has_value )
{
Put(L"=\"");
Put(attr_value);
for(i=0 ; i<attr_value.size() ; ++i)
{
Put(attr_value[i]);
if( i + 1 < attr_value.size() )
Put(' ');
}
Put('\"');
}
}
@ -1064,15 +1146,18 @@ void HTMLFilter::ReadItemOpening()
while( ReadItemAttr() )
{
if( CheckItemAttr() )
PrinItemAttr();
PrintItemAttr();
}
SkipAndCheckClosingTag(); // here LastItem().type can be changed to 'simple'
if( LastItem().type == Item::simple )
Put(L" /");
if( !IsNameEqual(no_filter_tag, LastItem().name) )
{
if( LastItem().type == Item::simple )
Put(L" /");
PutClosingTagMark();
PutClosingTagMark();
}
}
}
@ -1196,6 +1281,11 @@ bool HTMLFilter::IsLastTag(const wchar_t * name)
}
bool HTMLFilter::IsLastTag(const std::wstring & name)
{
return IsNameEqual(name, LastItem().name);
}
// checking exceptions for opening tags
void HTMLFilter::CheckExceptions()
@ -1222,6 +1312,9 @@ void HTMLFilter::CheckExceptions()
if( IsLastTag(L"pre") || IsLastTag(L"textarea") )
PutLastTagWithClosingTag();
if( IsLastTag(no_filter_tag) )
PutTextBetweenLastTagWithClosingTag();
if( IsLastTag(L"body") )
LastItem().has_body_tag = true;
}

View File

@ -110,6 +110,11 @@ public:
void InsertTabs(size_t tabsize);
// set a name of a html tag which will be used as 'nofilter' tag
// elements between such tags are not filtered (similarly as in <pre> and <textarea>)
// these tags (opening and closing) will no be placed in the html output
void SetNoFilterTag(const std::wstring & tag_name);
// orphans are checked only in 'body' tag
void AssignOrphans(const wchar_t * lang_code, const std::vector<std::wstring> & otab);
void AssignOrphans(const std::wstring & lang_code, const std::vector<std::wstring> & otab);
@ -143,6 +148,9 @@ protected:
typedef std::map<std::wstring, Orphans> OrphansTab;
OrphansTab orphans_tab;
// html <nofilter> tag name
std::wstring no_filter_tag;
struct Item
{
@ -173,6 +181,10 @@ protected:
};
/*
virtual methods
*/
@ -223,6 +235,7 @@ protected:
bool IsNameEqual(const std::wstring & name1, const std::wstring & name2, size_t len);
bool IsLastTag(const wchar_t * name);
bool IsLastTag(const std::wstring & name);
bool IsTagSafe(const wchar_t * tag);
bool IsTagSafe(const std::wstring & tag);
@ -254,7 +267,7 @@ protected:
bool ReadItemAttr();
bool CheckItemAttr();
void PrinItemAttr();
void PrintItemAttr();
void ReadItemClosing();
void ReadItemSpecial();
@ -270,6 +283,7 @@ protected:
void PutNormalNonWhite(const wchar_t * & str, const wchar_t * end);
void PutNormalWhite(const wchar_t * & str, const wchar_t * end);
void PutLastTagWithClosingTag();
void PutTextBetweenLastTagWithClosingTag();
void PutTabs(size_t len);
void PutNonBreakingSpace();
void PutNewLine();
@ -288,7 +302,8 @@ protected:
size_t tab_size;
OrphanMode orphan_mode;
std::wstring attr_name;
std::wstring attr_value;
std::vector<std::wstring> attr_value;
std::wstring attr_value_temp;
std::wstring attr_value_lower;
bool attr_has_value;
std::wstring lang_code_lower;

View File

@ -507,6 +507,7 @@ void Functions::ReadItemFilterHtml(Item & item)
html_filter.InsertTabs(0);
html_filter.SafeMode(true);
html_filter.ClearOrphans();
// SetNoFilterTag doesn't have to be called (default empty tag)
html_filter.Filter(cur->request->PostVar(L"itemcontent"), item.content);
}

View File

@ -264,6 +264,11 @@ void Passwd::MakePost()
{
const std::wstring * plogin;
// CHECK ME
// may it is better to check first for 'resetpassword'
// now if a user is logged then 'resetpassword' has no effect
// actually 'resetpassword' would be used for other user
if( cur->session->puser )
{
if( cur->session->puser->super_user )

View File

@ -749,6 +749,7 @@ using namespace TemplatesFunctions;
html_filter.BreakWord(config->html_filter_break_word);
html_filter.WrapLine(config->html_filter_wrap_line);
html_filter.InsertTabs(config->html_filter_tabs);
html_filter.SetNoFilterTag(config->html_filter_nofilter_tag);
html_filter.ClearOrphans();
if( config->html_filter_orphans )