Closed Bug 132844 Opened 23 years ago Closed 23 years ago

Transformed docs lack the DOCTYPE, detect the MathML namespace

Categories

(Core :: MathML, defect, P1)

defect

Tracking

()

RESOLVED FIXED
mozilla1.0

People

(Reporter: rbs, Assigned: rbs)

References

()

Details

Attachments

(1 file, 1 obsolete file)

The ability to load mathml.css on demand depends on a reliable detection of the presence of MathML content inside the document (bug 124570). The current way of doing this detection uses the <DOCTYPE>, but documents produced on the fly with XSLT don't have a <DOCTYPE>. So it was suggested on n.p.m.mathml to also look for the presence of the declaration of the MathML namespace in <html>. Thread: "XSL Stylesheet for Cross Browser MathML viewing" - 21 March 2002 http://groups.google.com/groups?threadm=3C9A7135.BF7DC4DD%40maths.uq.edu.au
Uh, how about documents that just have MathML somewhere in the middle? <a> <b> This is a random document in a random language. </b> <b> <math xmlns="http://www.w3.org/1998/Math/MathML"> <mi> x </mi> <mo> = </mo> <mi> y </mi> </math> </b> </a>
The idea is to ask authors to please declare xmlns:mathml="..." within <html> so that there is only one place to test for that for cross-browser support, like that other bug where IE expected the XHTML prefix to be "html", remember? [In reality, this is only compliant with transformed docs, since all XHTML docs must have a DOCTYPE in order to be XHTML compliant per the XHTML spec.]
XHTML documents need not be valid, only well formed. And my sample document was not XHTML. What about cases where the auther adds MathML content through the DOM? What if he doesn't know in advance that it will be MathML content? I'm sorry, but we can't depend on a namespace being declared in a particular place. There is zero basis in the specs for behaviour of that kind. How about the MathML frame constructor checks to see if the MathML stylesheet has been enabled in that document's UA stylesheet set when it creates the document's first MathML frame?
(The examples that you gave are way too sophisticated... Do you know that for some of the other renderers you have to add the "mml:" prefix on every tag :-) >There is zero basis in the specs for behaviour of that kind. Yes, it is a hack pending a better proposal. I haven't yet started coding anything. If there is a better way, I am taker. >How about the MathML frame constructor checks to see if the MathML stylesheet >has been enabled in that document's UA stylesheet set when it creates the >document's first MathML frame? So you mean loading mathml.css upfront and disabling it? That's what the other bug aimed at avoiding. No mathml.css anywhere until MathML content is encountered. It is technically possible to load the mathml.css on the fly (there are APIs for that). The side-effect is that if done from the frame construction code, it will be done half-way during the construction, causing the frame tree to be destroyed in a re-entrant manner. If done from the DOM/content construction, then that might be okay. To do so would require testing every node against the MathML namespace. I am not sure how much of a cost that would be. I haven't yet looked at the code ATM.
I didn't particularly mean disabled vs not loaded -- whichever you need. > It is technically possible to load the mathml.css on the fly (there are APIs > for that). The side-effect is that if done from the frame construction code, > it will be done half-way during the construction, causing the frame tree to be > destroyed in a re-entrant manner. Can this be scheduled? Or can frame construction be aborted or re-started? This will probably happen during the initial frame construction that occurs (after 1.2s or when the page is completed) -- can this fact be used to optimise this somehow? I actually just thought of a much neater way of doing this. Simply add an XBL binding on the root MathML element, and import the stylesheet through that. Or, use the stylesheet scoping mechanism of XBL, but hook it in manually at the frame constructor level. This should mean we don't need to reframe anything. > If done from the DOM/content construction, then that might be okay. To do so > would require testing every node against the MathML namespace. I am not sure > how much of a cost that would be. I haven't yet looked at the code ATM. Won't that have to be done anyway when we implement the MathML DOM?
>I didn't particularly mean disabled vs not loaded -- whichever you need. It was concluded that the increase came mostly from the I/O (17.5ms). We are speaking of at an atomic level here :-). Plus, not loading it has a positive impact on the bloat numbers. >Can this be scheduled? Or can frame construction be aborted or re-started? This >will probably happen during the initial frame construction that occurs (after >1.2s or when the page is completed) -- can this fact be used to optimise this >somehow? We are speaking of mathml.css, it needs a little friendly solution, not a big scary thing... >I actually just thought of a much neater way of doing this. Simply add an XBL >binding on the root MathML element, and import the stylesheet through that. Wouldn't that import it several times, i.e., for _all_ <math> elements? Did you try it already? >Won't that have to be done anyway when we implement the MathML DOM? At that time, yes.
Here is what you have to do to get MathML elsewhere, <html m:mathmlNS> needs to occur as the first line in your document: http://www.dessci.com/webmath/mathplayer/authoring.stm I hope Mozilla can do something better/transparent than that, but if it is too much trouble, why make our life so hard at this already crucial stage where the tree closes in a week.
[note: it reminds the proposal in bug 51684 - Revisiting nsIFrame]
hyatt: Can you give us some insight into how XBL could help us? (See above.) rbs: Using the stylesheet scoping mechanism of XBL, but hooked in manually at the frame constructor level, might be the relatively simple way you are looking for.
You mean there is some XBL magic that could trigger the load of mathml.css if the transformed doc has a node with an attribute that read: '<html ... xmlns:m="http://www.w3.org/1998/Math/MathML"> if so, that will be great, no code-level changes...
No, I meant that there would be a way of bringing in the MathML sheet only for MathML content, just like in the chrome we only bring in the button stylesheets for buttons, the menu stylesheets for menus, etc. My theory is that there is a way to trigger that without even using the overhead of XBL by simply hooking in the scoped stylesheet import at the frame construction level. I am strongly against anything that limits users' abilities to insert MathML nodes dynamically without any sort of special provisions. That other renderers are screwed up in that way is in no way a reason for us to make that kind of fundamental mistake.
Ok hixie, no time for theory. m1.0 is around the corner. If there is an easy way to fix this bug, let's take it rather than stick on an idealized solution. Actually, I already have some code that creates a stylesheet on the fly from the frame construction side -- that's how I added the support for the inline MathML stylistic attributes (c.f. bug 69409 comment 4) - the source for that is at: nsMathMLFrame::MapAttributesIntoCSS(). I had some troubles at that time because of a reframe mid-way (not sure if the related bugs have been fixed since then). If there is a more robust XBL way to load mathml.css, I will be more inclined toward it.
Status: NEW → ASSIGNED
Priority: -- → P1
Target Milestone: --- → mozilla1.0
> Ok hixie, no time for theory. m1.0 is around the corner. Well, XBL works now. We could fix this most easily just by adding a single line to html.css, namely mathml|math { -moz-binding: url(resource:/.../mathml.css); } I don't know what this does w.r.t. memory footprint, but since that's how the chrome does stuff for each <button>, I assume it's optimised for sharing.
Tried it, but it doesn't work yet. Directly trying to use -moz-binding on the .css file caused an invalid syntaxt error. So I switched to the following steps: 1: create a mathml-test-xbl.xhtml with the following content: ============================================================= <?xml version="1.0"?> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>Bug 132844</title> <style> *|math { -moz-binding: url("mathmlBindings.xml#math-element"); } </style> </head> <body> <math xmlns="http://www.w3.org/1998/Math/MathML"> <mfrac> <mi>a</mi> <mi>b</mi> </mfrac> </math> </body> </html> 2: create a mathmlBindings.xml file with the content: ===================================================== <?xml version="1.0"?> <bindings id="mathmlBindings" xmlns="http://www.mozilla.org/xbl"> <binding id="math-element"> <resources> <stylesheet src="resource:/res/mathml.css"/> </resources> </binding> </bindings> ============ But when I try to load mathml-test-xbl.xhtml in the browser, I get a fraction in which 'a' and 'b' don't appear italicized in scriptstyle. Got a clue?
Severity: normal → blocker
It's something to do with the scoping rules for stylesheets... there are attributes on one of the elements in the binding that control what the stylesheets apply to (children, only anonymous nodes, etc). I forget what they are called.
And you are not that much thrilled to lookup... The attribute turned out to be: styleexplicitcontent: The styleexplicitcontent attribute indicates whether or not style sheets loaded from an XBL document are applied to a bound element's explicit children (in addition to the bound element itself). If omitted, a value of false is assumed. Guess what? It isn't yet implemented. So I have little option at this stage than to hand-roll a hack to fix this bug.
I didn't look it up because I don't know _where_ to look it up. I'm the author of the latest version of the XBL specification, so I could tell you that the official way to do it is as follows: <?xml version="1.0"?> <bindings xmlns="http://www.mozilla.org/xbl"> <binding id="math-element"> <content><children applybindingsheets="true"/></content> <stylesheet src="resource:/res/mathml.css"/> </binding> </bindings> mathml|math { binding: -moz-mathml; } However, I know for a fact that Mozilla doesn't implement that version of the XBL specification and therefore it wouldn't help you much. I was hoping hyatt might chime in and give you some pointers -- I know very little about our XBL implementation. I'm just a theory guy, sorry! :-)
With the fix, mathml.css is now loaded when creating MathML nodes in the DOM. If the document has a DOCTYPE, then the stylesheet is loaded as per bug 124570. Otherwise, the first MathML node that is created triggers the load. To my surprise with XLST, my good printf friend is telling me that it is loaded _thrice_ for the XSLT case: when parsing the initial doc, when transforming, and then, some copying of the doc that the XSLT engine is doing. I couldn't tell from within the element factory what is going on with the document, and therefore I couldn't figure out how to avoid loading the stylesheet if the document is just in a transient transformation state. I wonder why nsXSLContentSink is not overloading nsXMLContentSink::CreateElement() to just create vanilla XML elements rather than going through the overhead of creating elements through the factory since these elements are going to be transformed. If it was doing so, it will avoid loading the stylesheet unnecessarily. There are perhaps other things that nsXSLContentSink may overload too to tighten things a bit. But these are questions for another time... I am just going to hunt for r/sr/a on what I have so far...
Testcase: http://www.w3.org/Math/XSL/csmall2.xml The Universal MathML Stylesheets: http://www.w3.org/Math/XSL/
Summary: Transformed docs lack the DOCTYPE, detect the MathML namespace within <html> → Transformed docs lack the DOCTYPE, detect the MathML namespace
Attachment #77138 - Attachment is obsolete: true
For the record, the nsXSLContentSink could and should override CreateElement(). (That'll also avoid loading <script>s and <style>s).
Summary: Transformed docs lack the DOCTYPE, detect the MathML namespace → [fix, awaiting r/sr/a] Transformed docs lack the DOCTYPE, detect the MathML namespace
Comment on attachment 77166 [details] [diff] [review] same as patch 77138 - but with a missing portion from mathml/content - In NS_NewMathMLElementFactory(): + NS_ADDREF(result); + *aResult = result; I'd swap those two lines and addref the out param, which is what you really want here. No big deal though... sr=jst
Attachment #77166 - Flags: superreview+
Indeed, that's what I want. Corrected in my tree. (Also corrected in the code just above -- where the copy-paste came from :-)
Summary: [fix, awaiting r/sr/a] Transformed docs lack the DOCTYPE, detect the MathML namespace → [fix, have sr, awaiting r/a] Transformed docs lack the DOCTYPE, detect the MathML namespace
Whiteboard: have sr=jst, awaiting r/sr
Comment on attachment 77166 [details] [diff] [review] same as patch 77138 - but with a missing portion from mathml/content + NS_PRECONDITION(aResult != nsnull, "null ptr"); + if (! aResult) + return NS_ERROR_NULL_POINTER; could be simply: NS_ENSURE_ARG_POINTER(aResult); Are you sure you will always get a sheet below, wouldn't it be safer to test if you got it (null check)? + doc->GetStyleSheetAt(i, getter_AddRefs(sheet)); + nsCOMPtr<nsIURI> uri; + sheet->GetURL(*getter_AddRefs(uri)); Same with uri right after that. Fix those and r=heikki
Attachment #77166 - Flags: review+
fixed in my tree. I have also left an assertion in the null check for the stylesheet since it is an unexpected situtation.
Summary: [fix, have sr, awaiting r/a] Transformed docs lack the DOCTYPE, detect the MathML namespace → [fix, have r/sr, awaiting a] Transformed docs lack the DOCTYPE, detect the MathML namespace
Whiteboard: have sr=jst, awaiting r/sr → have r=heikki & sr=jst, awaiting a=
Comment on attachment 77166 [details] [diff] [review] same as patch 77138 - but with a missing portion from mathml/content a=asa (on behalf of drivers) for checkin to the 1.0 trunk
Attachment #77166 - Flags: approval+
it seems awfully expensive to search for the mathml.css stylesheet for every mathml-element that is created. Couldn't you set a flag in the document when the stylesheet is added and just look at that flag? We never have many documents alive so bloat shouldn't be a problem.
yay, just realized that adding the stylesheet on creation won't work if an element is moved from one document to another. You could fix this by creating special mathml-elements and adding the stylesheet in nsMathMLElement::SetDocument. Not sure if it's a big deal though
If we want this, fiddle importNode instead. Just moving an element between documents is verboten
>it seems awfully expensive to search for the mathml.css stylesheet for every >mathml-element that is created. Couldn't you set a flag in the document when >the stylesheet is added and just look at that flag? Yeah, it is a pain. I considered setting up such a flag in the document but thought that it will be too MathML-specific. Then I thought of setting up a hashtable in the factory to record documents for which the stylesheet has already been added. Maybe later -- when this thing is factored out in his separate file. But notice that actually, what will practically happen is that the stylesheet will be added as the _first_ stylesheet (due to the catalog flag) and so, the loop will generally stop at the first iteration. It is in the case where someone has explicitly included the stylesheet that it will slow the loop down. Fortunately, people are unlikely to include such a stylesheet explicitly. I have taken note of comment #29 -- provided that comment #30 is not saying that it is not a clean thing to do?
Patch checked in. Resolving as FIXED.
Status: ASSIGNED → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
Summary: [fix, have r/sr, awaiting a] Transformed docs lack the DOCTYPE, detect the MathML namespace → Transformed docs lack the DOCTYPE, detect the MathML namespace
Whiteboard: have r=heikki & sr=jst, awaiting a=
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: