summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog4
-rw-r--r--dw/fltkplatform.cc6
-rw-r--r--dw/fltkplatform.hh3
-rw-r--r--dw/fltkui.cc140
-rw-r--r--dw/fltkui.hh3
-rw-r--r--dw/textblock.cc4
-rw-r--r--dw/ui.hh3
-rw-r--r--src/capi.c4
-rw-r--r--src/form.cc16
-rw-r--r--src/html.cc65
-rw-r--r--test/dw_ui_test.cc5
11 files changed, 199 insertions, 54 deletions
diff --git a/ChangeLog b/ChangeLog
index f9018087..90f0b3e6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -33,7 +33,8 @@ dillo-3.1 [not released yet]
- Fix crash that's possible searching for text while page still being built.
Patches: Sebastian Geerken
+- Image buffer/cache improvements.
- Patch: Jorge Arellano Cid
+ - Fix for segfault when there's no dpid and view source is requested.
+ Patches: Jorge Arellano Cid
+- Crosscompile/buildroot-friendly fltk-config test.
Patch: Peter Seiderer
+- HTML5 character references.
@@ -43,6 +44,7 @@ dillo-3.1 [not released yet]
- Abort failed queries.
- In location bar, tend toward showing beginning of URL instead of end.
- Handle irix's version of vsnprintf().
+ - INPUT placeholder attribute.
Patches: corvid
+- Avoid requesting background images if an ancestor has display:none.
Patch: Johannes Hofmann
diff --git a/dw/fltkplatform.cc b/dw/fltkplatform.cc
index 2fc7ff41..67b04688 100644
--- a/dw/fltkplatform.cc
+++ b/dw/fltkplatform.cc
@@ -413,9 +413,11 @@ FltkPlatform::FltkResourceFactory::createOptionMenuResource ()
core::ui::EntryResource *
FltkPlatform::FltkResourceFactory::createEntryResource (int size,
bool password,
- const char *label)
+ const char *label,
+ const char *placeholder)
{
- return new ui::FltkEntryResource (platform, size, password, label);
+ return new ui::FltkEntryResource (platform, size, password, label,
+ placeholder);
}
core::ui::MultiLineTextResource *
diff --git a/dw/fltkplatform.hh b/dw/fltkplatform.hh
index cbf3c6f9..5aa86e62 100644
--- a/dw/fltkplatform.hh
+++ b/dw/fltkplatform.hh
@@ -110,7 +110,8 @@ private:
int rows);
core::ui::OptionMenuResource *createOptionMenuResource ();
core::ui::EntryResource *createEntryResource (int size, bool password,
- const char *label);
+ const char *label,
+ const char *placeholder);
core::ui::MultiLineTextResource *createMultiLineTextResource (int cols,
int rows);
core::ui::CheckButtonResource *createCheckButtonResource (bool
diff --git a/dw/fltkui.cc b/dw/fltkui.cc
index 6099fd69..a648638d 100644
--- a/dw/fltkui.cc
+++ b/dw/fltkui.cc
@@ -42,18 +42,115 @@
*/
/*
- * Used to enable CTRL+{a,e,d,k} in form inputs (for start,end,del,cut)
+ * Used to show optional placeholder text and to enable CTRL+{a,e,d,k} in
+ * form inputs (for start,end,del,cut)
*/
class CustInput2 : public Fl_Input {
public:
- CustInput2 (int x, int y, int w, int h, const char* l=0) :
- Fl_Input(x,y,w,h,l) {};
+ CustInput2 (int x, int y, int w, int h, const char* l=0);
+ ~CustInput2 () { if (placeholder) free(placeholder); };
+ void set_placeholder(const char *str);
+ int show_placeholder();
+ int show_normal(const char *str);
+ void textcolor(Fl_Color c);
+ void input_type(int t);
+ int value(const char* str);
+ const char* value();
int handle(int e);
+private:
+ Fl_Color dimmed(Fl_Color c) {return fl_color_average(c, color(), .33f); };
+ char *placeholder;
+ bool showing_placeholder;
+ Fl_Color usual_color;
+ int usual_type;
};
+CustInput2::CustInput2 (int x, int y, int w, int h, const char* l) :
+ Fl_Input(x,y,w,h,l)
+{
+ placeholder = NULL;
+ showing_placeholder = false;
+ usual_color = FL_BLACK; /* just init until widget style is set */
+};
+
+/*
+ * Show normal text.
+ */
+int CustInput2::show_normal(const char *str)
+{
+ showing_placeholder = false;
+ Fl_Input::textcolor(usual_color);
+ Fl_Input::input_type(usual_type);
+ return Fl_Input::value(str);
+}
+
+/*
+ * Show the placeholder text.
+ */
+int CustInput2::show_placeholder()
+{
+ showing_placeholder = true;
+ Fl_Input::textcolor(dimmed(usual_color));
+ Fl_Input::input_type(FL_NORMAL_INPUT);
+ return Fl_Input::value(placeholder);
+}
+
+/*
+ * Set the placeholder text.
+ */
+void CustInput2::set_placeholder(const char *str)
+{
+ if (placeholder)
+ free(placeholder);
+ placeholder = strdup(str);
+
+ if ((Fl::focus() != this) && !*value()) {
+ show_placeholder();
+ }
+}
+
+/*
+ * Set the text color.
+ */
+void CustInput2::textcolor(Fl_Color c)
+{
+ usual_color = c;
+ if (showing_placeholder)
+ c = dimmed(c);
+ Fl_Input::textcolor(c);
+}
+
+/*
+ * Set the input type (normal, password, etc.)
+ */
+void CustInput2::input_type(int t)
+{
+ usual_type = t;
+ Fl_Input::input_type(t);
+}
+
+/*
+ * Set the value of the input.
+ * NOTE that we're not being very careful with the return value, which is
+ * supposed to be nonzero iff the value was changed.
+ */
+int CustInput2::value(const char *str)
+{
+ return (placeholder && (!str || !*str) && Fl::focus() != this)
+ ? show_placeholder() : show_normal(str);
+}
+
+/*
+ * Return the value (text) of the input.
+ */
+const char* CustInput2::value()
+{
+ return showing_placeholder ? "" : Fl_Input::value();
+}
+
int CustInput2::handle(int e)
{
- int k = Fl::event_key();
+ int rc, k = Fl::event_key();
_MSG("CustInput2::handle event=%d\n", e);
@@ -82,8 +179,20 @@ int CustInput2::handle(int e)
return 0;
}
}
+ } else if (e == FL_UNFOCUS) {
+ if (placeholder && !value()[0]) {
+ show_placeholder();
+ }
+ }
+
+ rc = Fl_Input::handle(e);
+
+ if (rc && e == FL_FOCUS) {
+ // Nonzero return from handle() should mean that focus was accepted.
+ if (showing_placeholder)
+ show_normal("");
}
- return Fl_Input::handle(e);
+ return rc;
}
@@ -607,13 +716,15 @@ Fl_Widget *FltkComplexButtonResource::createNewWidget (core::Allocation
// ----------------------------------------------------------------------
FltkEntryResource::FltkEntryResource (FltkPlatform *platform, int size,
- bool password, const char *label):
+ bool password, const char *label,
+ const char *placeholder):
FltkSpecificResource <dw::core::ui::EntryResource> (platform)
{
this->size = size;
this->password = password;
this->label = label ? strdup(label) : NULL;
this->label_w = 0;
+ this->placeholder = placeholder ? strdup(placeholder) : NULL;
initText = NULL;
editable = false;
@@ -627,16 +738,17 @@ FltkEntryResource::~FltkEntryResource ()
free((char *)initText);
if (label)
free(label);
+ if (placeholder)
+ free(placeholder);
}
Fl_Widget *FltkEntryResource::createNewWidget (core::Allocation
*allocation)
{
- Fl_Input *input =
+ CustInput2 *input =
new CustInput2(allocation->x, allocation->y, allocation->width,
allocation->ascent + allocation->descent);
- if (password)
- input->type(FL_SECRET_INPUT);
+ input->input_type(password ? FL_SECRET_INPUT : FL_NORMAL_INPUT);
input->callback (widgetCallback, this);
input->when (FL_WHEN_ENTER_KEY_ALWAYS);
@@ -646,6 +758,8 @@ Fl_Widget *FltkEntryResource::createNewWidget (core::Allocation
}
if (initText)
input->value (initText);
+ if (placeholder)
+ input->set_placeholder(placeholder);
return input;
}
@@ -653,12 +767,12 @@ Fl_Widget *FltkEntryResource::createNewWidget (core::Allocation
void FltkEntryResource::setWidgetStyle (Fl_Widget *widget,
core::style::Style *style)
{
- Fl_Input *in = (Fl_Input *)widget;
+ CustInput2 *in = (CustInput2 *)widget;
FltkResource::setWidgetStyle(widget, style);
in->textcolor(widget->labelcolor());
- in->cursor_color(in->textcolor());
+ in->cursor_color(widget->labelcolor());
in->textsize(in->labelsize());
in->textfont(in->labelfont());
@@ -729,7 +843,7 @@ void FltkEntryResource::widgetCallback (Fl_Widget *widget, void *data)
const char *FltkEntryResource::getText ()
{
- return ((Fl_Input*)widget)->value ();
+ return ((CustInput2*)widget)->value ();
}
void FltkEntryResource::setText (const char *text)
@@ -738,7 +852,7 @@ void FltkEntryResource::setText (const char *text)
free((char *)initText);
initText = strdup (text);
- ((Fl_Input*)widget)->value (initText);
+ ((CustInput2*)widget)->value (initText);
}
bool FltkEntryResource::isEditable ()
diff --git a/dw/fltkui.hh b/dw/fltkui.hh
index 6ff024ca..fc22defd 100644
--- a/dw/fltkui.hh
+++ b/dw/fltkui.hh
@@ -303,6 +303,7 @@ private:
const char *initText;
char *label;
int label_w;
+ char *placeholder;
bool editable;
static void widgetCallback (Fl_Widget *widget, void *data);
@@ -314,7 +315,7 @@ protected:
public:
FltkEntryResource (FltkPlatform *platform, int size, bool password,
- const char *label);
+ const char *label, const char *placeholder);
~FltkEntryResource ();
void sizeRequest (core::Requisition *requisition);
diff --git a/dw/textblock.cc b/dw/textblock.cc
index e4bc72ab..40eb4014 100644
--- a/dw/textblock.cc
+++ b/dw/textblock.cc
@@ -577,7 +577,9 @@ void Textblock::sizeAllocateImpl (core::Allocation *allocation)
core::Allocation childAllocation;
core::Allocation *oldChildAllocation;
- if (allocation->width != this->allocation.width) {
+ if (allocation->x != this->allocation.x ||
+ allocation->y != this->allocation.y ||
+ allocation->width != this->allocation.width) {
redrawY = 0;
DBG_OBJ_SET_NUM ("redrawY", redrawY);
}
diff --git a/dw/ui.hh b/dw/ui.hh
index 4f1f9029..4ff6d848 100644
--- a/dw/ui.hh
+++ b/dw/ui.hh
@@ -580,7 +580,8 @@ public:
selectionMode, int rows) = 0;
virtual OptionMenuResource *createOptionMenuResource () = 0;
virtual EntryResource *createEntryResource (int size, bool password,
- const char *label) = 0;
+ const char *label,
+ const char *placeholder) = 0;
virtual MultiLineTextResource *createMultiLineTextResource (int cols,
int rows) = 0;
virtual CheckButtonResource *createCheckButtonResource (bool activated) = 0;
diff --git a/src/capi.c b/src/capi.c
index 242ae294..8013d3c9 100644
--- a/src/capi.c
+++ b/src/capi.c
@@ -570,8 +570,8 @@ int a_Capi_dpi_send_data(const DilloUrl *url, void *bw,
} else {
/* Re-use an open connection */
conn = Capi_conn_find(server);
- if (conn) {
- /* found */
+ if (conn && conn->InfoSend) {
+ /* found & active */
dbuf = a_Chain_dbuf_new(data, data_sz, 0);
a_Capi_ccc(OpSend, 1, BCK, conn->InfoSend, dbuf, NULL);
dFree(dbuf);
diff --git a/src/form.cc b/src/form.cc
index 9e7dc4f6..366b00b9 100644
--- a/src/form.cc
+++ b/src/form.cc
@@ -431,7 +431,7 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize)
DilloHtmlInputType inp_type;
Resource *resource = NULL;
Embed *embed = NULL;
- char *value, *name, *type, *init_str;
+ char *value, *name, *type, *init_str, *placeholder = NULL;
const char *attrbuf, *label;
bool init_val = false;
ResourceFactory *factory;
@@ -456,9 +456,10 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize)
inp_type = DILLO_HTML_INPUT_UNKNOWN;
if (!dStrAsciiCasecmp(type, "password")) {
inp_type = DILLO_HTML_INPUT_PASSWORD;
+ placeholder = a_Html_get_attr_wdef(html, tag,tagsize,"placeholder",NULL);
attrbuf = a_Html_get_attr(html, tag, tagsize, "size");
int size = Html_input_get_size(html, attrbuf);
- resource = factory->createEntryResource (size, true, NULL);
+ resource = factory->createEntryResource (size, true, NULL, placeholder);
init_str = value;
} else if (!dStrAsciiCasecmp(type, "checkbox")) {
inp_type = DILLO_HTML_INPUT_CHECKBOX;
@@ -478,7 +479,7 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize)
inp_type = DILLO_HTML_INPUT_HIDDEN;
init_str = value;
int size = Html_input_get_size(html, NULL);
- resource = factory->createEntryResource(size, false, name);
+ resource = factory->createEntryResource(size, false, name, NULL);
} else if (!dStrAsciiCasecmp(type, "submit")) {
inp_type = DILLO_HTML_INPUT_SUBMIT;
init_str = (value) ? value : dStrdup("submit");
@@ -531,9 +532,10 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize)
} else {
/* Text input, which also is the default */
inp_type = DILLO_HTML_INPUT_TEXT;
+ placeholder = a_Html_get_attr_wdef(html, tag,tagsize,"placeholder",NULL);
attrbuf = a_Html_get_attr(html, tag, tagsize, "size");
int size = Html_input_get_size(html, attrbuf);
- resource = factory->createEntryResource(size, false, NULL);
+ resource = factory->createEntryResource(size, false, NULL, placeholder);
init_str = value;
}
if (resource)
@@ -573,6 +575,7 @@ void Html_tag_open_input(DilloHtml *html, const char *tag, int tagsize)
dFree(name);
if (init_str != value)
dFree(init_str);
+ dFree(placeholder);
dFree(value);
}
@@ -606,7 +609,8 @@ void Html_tag_open_isindex(DilloHtml *html, const char *tag, int tagsize)
HT2TB(html)->addText(attrbuf, html->wordStyle ());
ResourceFactory *factory = HT2LT(html)->getResourceFactory();
- EntryResource *entryResource = factory->createEntryResource (20,false,NULL);
+ EntryResource *entryResource = factory->createEntryResource (20, false,
+ NULL, NULL);
embed = new Embed (entryResource);
Html_add_input(html, DILLO_HTML_INPUT_INDEX, embed, NULL, NULL, FALSE);
@@ -654,7 +658,7 @@ void Html_tag_content_textarea(DilloHtml *html, const char *tag, int tagsize)
} else {
if (html->DocType != DT_HTML || html->DocTypeVersion <= 4.01f)
BUG_MSG("<textarea> requires rows attribute.");
- rows = 10;
+ rows = 2;
}
if (rows < 1 || rows > MAX_ROWS) {
int badRows = rows;
diff --git a/src/html.cc b/src/html.cc
index 571acf77..d2e513b2 100644
--- a/src/html.cc
+++ b/src/html.cc
@@ -3108,20 +3108,23 @@ static void Html_tag_close_pre(DilloHtml *html)
* Check whether a tag is in the "excluding" element set for PRE
* Excl. Set = {IMG, OBJECT, APPLET, BIG, SMALL, SUB, SUP, FONT, BASEFONT}
*/
-static int Html_tag_pre_excludes(int tag_idx)
+static int Html_tag_pre_excludes(DilloHtml *html, int tag_idx)
{
- const char *es_set[] = {"img", "object", "applet", "big", "small", "sub",
- "sup", "font", "basefont", NULL};
- static int ei_set[10], i;
+ if (!(html->DocType == DT_HTML && html->DocTypeVersion >= 5.0f)) {
+ /* HTML5 doesn't say anything about excluding elements */
+ const char *es_set[] = {"img", "object", "applet", "big", "small", "sub",
+ "sup", "font", "basefont", NULL};
+ static int ei_set[10], i;
- /* initialize array */
- if (!ei_set[0])
- for (i = 0; es_set[i]; ++i)
- ei_set[i] = a_Html_tag_index(es_set[i]);
+ /* initialize array */
+ if (!ei_set[0])
+ for (i = 0; es_set[i]; ++i)
+ ei_set[i] = a_Html_tag_index(es_set[i]);
- for (i = 0; ei_set[i]; ++i)
- if (tag_idx == ei_set[i])
- return 1;
+ for (i = 0; ei_set[i]; ++i)
+ if (tag_idx == ei_set[i])
+ return 1;
+ }
return 0;
}
@@ -3171,7 +3174,13 @@ static void Html_tag_open_meta(DilloHtml *html, const char *tag, int tagsize)
/* only valid inside HEAD */
if (!(html->InFlags & IN_HEAD)) {
- BUG_MSG("<meta> must be inside the HEAD section.");
+ if (!((html->DocType == DT_HTML && html->DocTypeVersion >= 5.0f) &&
+ a_Html_get_attr(html, tag, tagsize, "itemprop"))) {
+ /* With the HTML 5.1 draft spec, meta with itemprop may appear
+ * in the body.
+ */
+ BUG_MSG("This <meta> element must be inside the HEAD section.");
+ }
return;
}
@@ -3409,14 +3418,13 @@ static void Html_tag_open_span(DilloHtml *html, const char *tag, int tagsize)
}
/*
- * <DIV> (TODO: make a complete implementation)
+ * html5 sectioning stuff: article aside nav section header footer
*/
-static void Html_tag_open_div(DilloHtml *html, const char *tag, int tagsize)
+static void Html_tag_open_sectioning(DilloHtml *html, const char *tag,
+ int tagsize)
{
const char *attrbuf;
- a_Html_tag_set_align_attr (html, tag, tagsize);
-
if (prefs.show_tooltip &&
(attrbuf = a_Html_get_attr(html, tag, tagsize, "title"))) {
@@ -3426,6 +3434,15 @@ static void Html_tag_open_div(DilloHtml *html, const char *tag, int tagsize)
}
/*
+ * <DIV> (TODO: make a complete implementation)
+ */
+static void Html_tag_open_div(DilloHtml *html, const char *tag, int tagsize)
+{
+ a_Html_tag_set_align_attr (html, tag, tagsize);
+ Html_tag_open_sectioning(html, tag, tagsize);
+}
+
+/*
* Default close for paragraph tags - pop the stack and break.
*/
static void Html_tag_close_par(DilloHtml *html)
@@ -3474,8 +3491,8 @@ const TagInfo Tags[] = {
{"address", B8(010110),'R',2,Html_tag_open_default, NULL, Html_tag_close_par},
{"area", B8(010001),'F',0, Html_tag_open_default, Html_tag_content_area,
NULL},
- {"article", B8(011110),'R',2, Html_tag_open_default, NULL, NULL},
- {"aside", B8(011110),'R',2, Html_tag_open_default, NULL, NULL},
+ {"article", B8(011110),'R',2, Html_tag_open_sectioning, NULL, NULL},
+ {"aside", B8(011110),'R',2, Html_tag_open_sectioning, NULL, NULL},
{"audio", B8(011101),'R',2, Html_tag_open_audio, NULL, Html_tag_close_media},
{"b", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
{"base", B8(100001),'F',0, Html_tag_open_base, NULL, NULL},
@@ -3508,7 +3525,7 @@ const TagInfo Tags[] = {
{"figcaption", B8(011110),'R',2, Html_tag_open_default, NULL, NULL},
{"figure", B8(011110),'R',2, Html_tag_open_default, NULL, NULL},
{"font", B8(010101),'R',2, Html_tag_open_font, NULL, NULL},
- {"footer", B8(011110),'R',2, Html_tag_open_default, NULL, NULL},
+ {"footer", B8(011110),'R',2, Html_tag_open_sectioning, NULL, NULL},
{"form", B8(011110),'R',2, Html_tag_open_form, NULL, Html_tag_close_form},
{"frame", B8(010010),'F',0, Html_tag_open_frame, Html_tag_content_frame,
NULL},
@@ -3521,7 +3538,7 @@ const TagInfo Tags[] = {
{"h5", B8(010110),'R',2, Html_tag_open_h, NULL, NULL},
{"h6", B8(010110),'R',2, Html_tag_open_h, NULL, NULL},
{"head", B8(101101),'O',1, Html_tag_open_head, NULL, Html_tag_close_head},
- {"header", B8(011110),'R',2, Html_tag_open_default, NULL, NULL},
+ {"header", B8(011110),'R',2, Html_tag_open_sectioning, NULL, NULL},
{"hr", B8(010010),'F',0, Html_tag_open_hr, Html_tag_content_hr,
NULL},
{"html", B8(001110),'O',1, Html_tag_open_html, NULL, Html_tag_close_html},
@@ -3543,8 +3560,8 @@ const TagInfo Tags[] = {
{"mark", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
/* menu 1010 -- TODO: not exactly 1010, it can contain LI and inline */
{"menu", B8(011010),'R',2, Html_tag_open_menu, NULL, Html_tag_close_par},
- {"meta", B8(100001),'F',0, Html_tag_open_meta, NULL, NULL},
- {"nav", B8(011110),'R',2, Html_tag_open_default, NULL, NULL},
+ {"meta", B8(110001),'F',0, Html_tag_open_meta, NULL, NULL},
+ {"nav", B8(011110),'R',2, Html_tag_open_sectioning, NULL, NULL},
/* noframes 1011 -- obsolete in HTML5 */
/* noscript 1011 */
{"object", B8(111101),'R',2, Html_tag_open_object, Html_tag_content_object,
@@ -3560,7 +3577,7 @@ const TagInfo Tags[] = {
{"s", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
{"samp", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
{"script", B8(111001),'R',2, Html_tag_open_script,NULL,Html_tag_close_script},
- {"section", B8(011110),'R',2, Html_tag_open_default, NULL, NULL},
+ {"section", B8(011110),'R',2, Html_tag_open_sectioning, NULL, NULL},
{"select", B8(010101),'R',2, Html_tag_open_select,NULL,Html_tag_close_select},
{"small", B8(010101),'R',2, Html_tag_open_default, NULL, NULL},
{"source", B8(010001),'F',0, Html_tag_open_source, Html_tag_content_source,
@@ -3961,7 +3978,7 @@ static void Html_process_tag(DilloHtml *html, char *tag, int tagsize)
/* TODO: this is only raising a warning, take some defined action.
* Note: apache uses IMG inside PRE (we could use its "alt"). */
- if ((html->InFlags & IN_PRE) && Html_tag_pre_excludes(ni))
+ if ((html->InFlags & IN_PRE) && Html_tag_pre_excludes(html, ni))
BUG_MSG("<pre> is not allowed to contain <%s>.", Tags[ni].name);
/* Make sure these elements don't nest each other */
diff --git a/test/dw_ui_test.cc b/test/dw_ui_test.cc
index 086a4976..b70349ca 100644
--- a/test/dw_ui_test.cc
+++ b/test/dw_ui_test.cc
@@ -81,10 +81,11 @@ int main(int argc, char **argv)
// First of all, the resources. Later, they are embedded into the
// widget tree.
EntryResource *entryres1 =
- layout->getResourceFactory()->createEntryResource (10, false, NULL);
+ layout->getResourceFactory()->createEntryResource (10, false, NULL,NULL);
entryres1->setText ("Hi!");
EntryResource *entryres2 =
- layout->getResourceFactory()->createEntryResource (10, true, NULL);
+ layout->getResourceFactory()->createEntryResource (10, true, NULL,
+ "password field!");
MultiLineTextResource *textres =
layout->getResourceFactory()->createMultiLineTextResource (15,3);
RadioButtonResource *radiores1 =