Author: fejj
Date: 2007-10-31 16:54:52 -0500 (Wed, 31 Oct 2007)
New Revision: 88609
Modified:
trunk/moon/src/ChangeLog
trunk/moon/src/text.cpp
trunk/moon/src/xaml.cpp
Log:
2007-10-31 Jeffrey Stedfast <[EMAIL PROTECTED]>
Fixes for handling lwsp cdata between <Run> elements.
* xaml.cpp (flush_char_data): Reworked a bit. Now takes a 'start'
arg suggesting that we are being called in response to a new
element starting vs an element ending.
(start_element_handler): Pass true as the start arg to
flush_char_data().
(end_element_handler): Pass false as the start arg to
flush_char_data().
* text.cpp (SetValue): Only add a run if the string is non-empty.
Modified: trunk/moon/src/ChangeLog
===================================================================
--- trunk/moon/src/ChangeLog 2007-10-31 21:47:27 UTC (rev 88608)
+++ trunk/moon/src/ChangeLog 2007-10-31 21:54:52 UTC (rev 88609)
@@ -1,3 +1,17 @@
+2007-10-31 Jeffrey Stedfast <[EMAIL PROTECTED]>
+
+ Fixes for handling lwsp cdata between <Run> elements.
+
+ * xaml.cpp (flush_char_data): Reworked a bit. Now takes a 'start'
+ arg suggesting that we are being called in response to a new
+ element starting vs an element ending.
+ (start_element_handler): Pass true as the start arg to
+ flush_char_data().
+ (end_element_handler): Pass false as the start arg to
+ flush_char_data().
+
+ * text.cpp (SetValue): Only add a run if the string is non-empty.
+
2007-10-31 Rolf Bjarne Kvinge <[EMAIL PROTECTED]>
* dependencyobject.cpp: Guard against calling NULL.
Modified: trunk/moon/src/text.cpp
===================================================================
--- trunk/moon/src/text.cpp 2007-10-31 21:47:27 UTC (rev 88608)
+++ trunk/moon/src/text.cpp 2007-10-31 21:54:52 UTC (rev 88609)
@@ -1027,9 +1027,13 @@
if (property == TextBlock::TextProperty) {
// Text is a virtual property and setting it deletes all
current runs,
// creating a new run
+ const char *str = value ? value->AsString () : NULL;
+
+ if (!str || !str[0])
+ return;
+
Run *run = new Run ();
- if (value)
- run_set_text (run, value->AsString ());
+ run_set_text (run, value->AsString ());
Inlines *inlines = text_block_get_inlines (this);
Modified: trunk/moon/src/xaml.cpp
===================================================================
--- trunk/moon/src/xaml.cpp 2007-10-31 21:47:27 UTC (rev 88608)
+++ trunk/moon/src/xaml.cpp 2007-10-31 21:54:52 UTC (rev 88609)
@@ -148,6 +148,7 @@
GHashTable *namespace_map;
GString *cdata;
+ bool has_cdata;
bool implicit_default_namespace;
@@ -165,7 +166,7 @@
parser (parser), file_name (file_name), namescope (new
NameScope()), top_element (NULL),
current_namespace (NULL), current_element (NULL),
- cdata (NULL), implicit_default_namespace (false), error_args
(NULL),
+ cdata (NULL), has_cdata(false), implicit_default_namespace
(false), error_args (NULL),
loader (NULL), created_elements (NULL)
{
namespace_map = g_hash_table_new (g_str_hash, g_str_equal);
@@ -696,7 +697,7 @@
}
}
-bool
+static bool
is_instance_of (XamlElementInstance *item, Type::Kind kind)
{
for (XamlElementInfo *walk = item->info; walk; walk = walk->parent) {
@@ -761,7 +762,7 @@
parser_error (p, NULL, NULL, error_code, message);
}
-DependencyObject *
+static DependencyObject *
get_parent (XamlElementInstance *inst)
{
XamlElementInstance *walk = inst;
@@ -775,7 +776,7 @@
return NULL;
}
-void
+static void
start_element (void *data, const char *el, const char **attr)
{
XamlParserInfo *p = (XamlParserInfo *) data;
@@ -860,47 +861,75 @@
p->current_element = inst;
}
-void
-flush_char_data (XamlParserInfo *p)
+static void
+flush_char_data (XamlParserInfo *p, bool start)
{
- if (p->cdata && p->cdata->len) {
+ DependencyProperty *content;
+ const char *prop_name;
+ Type::Kind prop_type;
+
+ if (!p->has_cdata || !p->current_element)
+ return;
+
+ prop_name = p->current_element->info->content_property;
+
+ if (!prop_name && p->cdata) {
+ char *err = g_strdup_printf ("%s does not support text
content.", p->current_element->element_name);
+ parser_error (p, NULL, NULL, 2011, err);
+ goto done;
+ } else if (!prop_name) {
+ goto done;
+ }
+
+ prop_type = p->current_element->info->dependency_type;
+ content = DependencyObject::GetDependencyProperty (prop_type,
prop_name);
+
+ // TODO: There might be other types that can be specified here,
+ // but string is all i have found so far. If you can specify other
+ // types, i should pull the property setting out of set_attributes
+ // and use that code
+
+ if ((content->value_type) == Type::STRING && p->cdata) {
g_strchomp (p->cdata->str);
-
- const char *cp = p->current_element->info->content_property;
- if (cp && p->cdata->str[0]) {
- DependencyProperty *con =
DependencyObject::GetDependencyProperty
(p->current_element->info->dependency_type, cp);
- // TODO: There might be other types that can be
specified here,
- // but string is all i have found so far. If you can
specify other
- // types, i should pull the property setting out of
set_attributes
- // and use that code
-
- if ((con->value_type) == Type::STRING) {
- p->current_element->item->SetValue (con, Value
(p->cdata->str));
- } else if (is_instance_of (p->current_element,
Type::TEXTBLOCK)) {
- Run *run = new Run ();
- run_set_text (run, p->cdata->str);
-
- Inlines *inlines = text_block_get_inlines
((TextBlock *) p->current_element->item);
-
- if (!inlines) {
- inlines = new Inlines ();
- text_block_set_inlines ((TextBlock *)
p->current_element->item, inlines);
- inlines->unref ();
- }
-
- inlines->Add (run);
- run->unref ();
- }
+ p->current_element->item->SetValue (content, Value
(p->cdata->str));
+ } else if (p->current_element->item && is_instance_of
(p->current_element, Type::TEXTBLOCK)) {
+ Inlines *inlines = text_block_get_inlines ((TextBlock *)
p->current_element->item);
+
+ if (!p->cdata && inlines && !inlines->list->IsEmpty () &&
start) {
+ // LWSP between <Run> elements is to be treated as a
single-SPACE <Run> element
+ p->cdata = g_string_new (" ");
+ } else if (p->cdata) {
+ // This is the normal case
+ g_strchomp (p->cdata->str);
} else {
- parser_error (p, NULL, NULL, 2011, g_strdup_printf ("%s
does not support text content.", p->current_element->element_name));
+ // This is either LWSP before the first <Run> element
or after the last <Run> element
+ goto done;
}
+ Run *run = new Run ();
+ run_set_text (run, p->cdata->str);
+
+ if (!inlines) {
+ inlines = new Inlines ();
+ text_block_set_inlines ((TextBlock *)
p->current_element->item, inlines);
+ inlines->unref ();
+ }
+
+ inlines->Add (run);
+ run->unref ();
+ }
+
+done:
+
+ if (p->cdata) {
g_string_free (p->cdata, FALSE);
p->cdata = NULL;
}
+
+ p->has_cdata = false;
}
-void
+static void
start_element_handler (void *data, const char *el, const char **attr)
{
XamlParserInfo *p = (XamlParserInfo *) data;
@@ -911,7 +940,7 @@
char **name = g_strsplit (el, "|", -1);
char *element = NULL;
- flush_char_data (p);
+ flush_char_data (p, true);
p->current_namespace = NULL;
if (g_strv_length (name) == 2) {
@@ -925,10 +954,7 @@
element = name [0];
}
-
-
if (!p->current_namespace) {
-
if (name [1])
parser_error (p, name [1], NULL, -1, g_strdup_printf
("No handlers available for namespace: '%s' (%s)\n", name [0], el));
else
@@ -943,7 +969,7 @@
g_strfreev (name);
}
-void
+static void
end_element_handler (void *data, const char *el)
{
XamlParserInfo *info = (XamlParserInfo *) data;
@@ -953,7 +979,7 @@
switch (info->current_element->element_type) {
case XamlElementInstance::ELEMENT:
- flush_char_data (info);
+ flush_char_data (info, false);
break;
case XamlElementInstance::PROPERTY: {
List::Node *walk = info->current_element->children->First ();
@@ -972,7 +998,7 @@
info->current_element = info->current_element->parent;
}
-void
+static void
char_data_handler (void *data, const char *in, int inlen)
{
XamlParserInfo *p = (XamlParserInfo *) data;
@@ -986,6 +1012,8 @@
return;
if (!p->cdata) {
+ p->has_cdata = true;
+
// unless we already have significant char data, ignore lwsp
while (inptr < inend && g_ascii_isspace (*inptr))
inptr++;
@@ -1017,7 +1045,7 @@
g_string_truncate (p->cdata, d - p->cdata->str);
}
-void
+static void
start_namespace_handler (void *data, const char *prefix, const char *uri)
{
XamlParserInfo *p = (XamlParserInfo *) data;
@@ -1053,7 +1081,7 @@
}
}
-void
+static void
start_doctype_handler (void *data,
const XML_Char *doctype_name,
const XML_Char *sysid,
@@ -1066,7 +1094,7 @@
parser_error (p, NULL, NULL, 5050, g_strdup ("DTD was found but
is prohibited"));
}
-void
+static void
add_default_namespaces (XamlParserInfo *p)
{
p->implicit_default_namespace = true;
@@ -1074,7 +1102,7 @@
g_hash_table_insert (p->namespace_map, (char *)
"http://schemas.microsoft.com/winfx/2006/xaml", x_namespace);
}
-void
+static void
print_tree (XamlElementInstance *el, int depth)
{
for (int i = 0; i < depth; i++)
_______________________________________________
Mono-patches maillist - [email protected]
http://lists.ximian.com/mailman/listinfo/mono-patches