Bug 7754 - DomNode's not getting the correct Value
Summary: DomNode's not getting the correct Value
Alias: None
Product: MonoMac
Classification: Desktop
Component: Bindings ()
Version: unspecified
Hardware: Macintosh Mac OS
: --- normal
Target Milestone: ---
Assignee: Bugzilla
Depends on:
Reported: 2012-10-09 18:16 UTC by Benry Yip
Modified: 2013-04-09 13:07 UTC (History)
2 users (show)

Is this bug a regression?: ---
Last known good build:

DOMTest.cs. Compile with mcs DOMTest.cs -r:MonoMac.dll -d:DEBUG and run with mono DOMTest.exe. (2.78 KB, text/plain)
2012-10-09 18:16 UTC, Benry Yip
Test application that shows that the DOM is not getting updated on user input. (26.72 KB, application/zip)
2013-02-01 11:24 UTC, Benry Yip

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Benry Yip 2012-10-09 18:16:45 UTC
Created attachment 2721 [details]
DOMTest.cs. Compile with mcs DOMTest.cs -r:MonoMac.dll -d:DEBUG and run with mono DOMTest.exe.

When loading a WebView and accessing the DomDocument, certain DomNodes do not have the correct Value property.

For instance, when loading a WebView with an HTML string that has a textarea element, if a user inputs some random string to the textarea, the Value property returns an empty string.

I've attached a small program that shows the problem. It can be compiled with mcs DOMTest.cs -r:MonoMac.dll -d:DEBUG and run with mono DOMTest.exe . (N.B. The DEBUG symbol is required as the program uses Debug.Assert().)

I have written an analogous program in Objective-C and verified that the Value property of a DomNode should update to be the same as user input or a given string defined in any HTML source.
Comment 1 Benry Yip 2012-10-09 18:22:02 UTC
Comment on attachment 2721 [details]
DOMTest.cs. Compile with mcs DOMTest.cs -r:MonoMac.dll -d:DEBUG and run with mono DOMTest.exe.

>using System;
>using System.Diagnostics;
>using MonoMac.AppKit;
>using MonoMac.Foundation;
>using MonoMac.WebKit;
>namespace DOMTest
>    public class DOMTest
>    {
>        public const string TestTitleString = "testtitlestring";
>        public const string TestDataIDString = "testdataidattribute";
>        public const string TestTextAreaString = "testtextareastring";
>        public static bool done;
>        public static DomDocument dom;
>        public static void Main(string[] args)
>        {
>            NSApplication.Init();
>            done = false;
>            // Populate a WebView with a test HTML string.
>            WebView webView = new WebView();
>            webView.FinishedLoad += HandleWebViewMainFrame_FinishedLoad;
>            webView.MainFrame.LoadHtmlString("<html><head><title>" + TestTitleString + "</title></head><body><textarea >data-id=\"" + TestDataIDString + "\">" + TestTextAreaString + "</textarea></body></html>", null);
>            // Run in 1s intervals until WebView is done loading.
>            while (!done)
>            {
>                NSRunLoop.Current.RunUntil(NSDate.FromTimeIntervalSinceNow(1));
>            }
>            // Check our DOM values.
>            TextWriterTraceListener consoleWriter = new TextWriterTraceListener(Console.Out);
>            Debug.Listeners.Add(consoleWriter);
>            Debug.Assert(dom.Title.Equals(TestTitleString),
>                AssertString(dom.Title, TestTitleString, "The DOM's Title does not match."));
>            Debug.Assert(dom.body.Children.Count == 1,
>                AssertString(dom.body.Children.Count.ToString(), "1", "The body should have 1 child."));
>            DomNode textareaNode = dom.body.Children[0];
>            Debug.Assert(textareaNode != null, "The textarea element should not be null.");
>            Debug.Assert(textareaNode.Attributes["data-id"].Value.Equals(TestDataIDString),
>                AssertString(textareaNode.Attributes["data-id"].Value, TestDataIDString, "The textarea data-id >attribute does not match."));
>            Debug.Assert(textareaNode.TextContent.Equals(TestTextAreaString),
>                AssertString(textareaNode.TextContent, TestTextAreaString, "The textarea's TextContent does not match.">));
>            // This assertion fails.
>            //
>            // The Value of the textarea in the DOM is incorrect.
>            Debug.Assert(textareaNode.Value.Equals(TestTextAreaString),
>                AssertString(textareaNode.Value, TestTextAreaString, "The textarea's Value does not match."));
>            return;
>        }
>        /// <summary>
>        /// Grabs the DOM from the WebView.
>        /// </summary>
>        public static void HandleWebViewMainFrame_FinishedLoad(object sender, WebFrameEventArgs e)
>        {
>            WebView webView = sender as WebView;
>            if (webView != null)
>            {
>                dom = webView.MainFrame.DomDocument;
>            }
>            done = true;
>        }
>        /// <summary>
>        /// Pretty prints assertion values and message.
>        /// </summary>
>        public static string AssertString(string actual, string expected, string message)
>        {
>            return "Actual: <" + actual + ">. Expected: <" + expected + ">. " + message;
>        }
>    }
Comment 2 Benry Yip 2012-10-09 18:23:37 UTC
Ah, sorry about the super long second comment - was trying to edit the attachment. Am still learning how to use bugzilla.
Comment 3 Sebastien Pouliot 2013-01-31 16:42:54 UTC
[ref: http://stackoverflow.com/a/14635665/220643]

I rarely have to work with DOM but it seems to be the returned node is of type Element and the nodeValue will return a string only for a Text type.

From an Element you can try the TextContent, that does return the expected value for the bug report you mentioned.

Or you can access the Text node (it will be textarea.FirstChild.Value in your case) and that should also return the value you expect.
Comment 4 Benry Yip 2013-02-01 11:14:30 UTC
You're correct. My test doesn't exercise the real problem, that's my mistake.

What's really going on is that when a WebView has some form elements, when a user inputs data into those elements, the DOM isn't updated and so even using TextContent is incorrect.

I'm working on a test that will demonstrate this and will post it ASAP.
Comment 5 Benry Yip 2013-02-01 11:24:25 UTC
Created attachment 3321 [details]
Test application that shows that the DOM is not getting updated on user input.

The application presents a webview with some textareas in it. If you put in text into those textareas and click "Save Inputs", the output window on the bottom should display what you have typed into those textareas. However, because the DOM doesn't seem to get updated on user input, the output window displays only empty strings for both nodeValue and textContent.
Comment 6 Benry Yip 2013-02-01 11:25:36 UTC
I attached a test app that demonstrates the problem - please let me know if you need an automated test.
Comment 7 Sebastien Pouliot 2013-02-01 21:50:14 UTC
I see two issues. 

1. the bindings are incomplete and DomHtmlInputElement is missing (for the first <input> the textarea is likely identical);

2. `nodeValue` was bound as Value, DomHtmlInputElement introduce a `value` (so it's confusing - but not the property you expect).

Adding this:

	[BaseType (typeof (DomHtmlElement), Name="DOMHTMLInputElement")]
	[DisableDefaultCtor] // An uncaught exception was raised: +[DOMHTMLElement init]: should never be used
	interface DomHtmlInputElement {
		[Export ("value")]
		string RealValue { get; set; }

to webkit.cs allows me to get "a" (my value) when I query RealValue.
Comment 8 Sebastien Pouliot 2013-02-12 16:15:49 UTC
Fixed in monomac 7f4a126133b2a2cc2025d92841b194c146fdc561

This renames NodeValue (to match DOM API) and add (complete, as far as possible) bindings for DomHtmlInputElement. 

However webkit is still not fully bound.
Comment 9 Benry Yip 2013-04-09 12:14:45 UTC
When will WebKit be fully bound? Textareas are still broken.
Comment 10 Sebastien Pouliot 2013-04-09 13:07:56 UTC
Please do not re-open bug report *unless* a regression occurs. It only confuse people (on c.c. or querying bugzilla) about the original issue and makes it hard to use the bug history when regressions occurs.

note: I do not know what else is missing from WebKit bindings (but the issue is known). You might want to open a(bother) bug report so you'll get updates when progress is being made.