michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: michael@0: #include "nsMathMLsemanticsFrame.h" michael@0: #include "nsMimeTypes.h" michael@0: #include "mozilla/gfx/2D.h" michael@0: michael@0: // michael@0: // -- associate annotations with a MathML expression michael@0: // michael@0: michael@0: nsIFrame* michael@0: NS_NewMathMLsemanticsFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) michael@0: { michael@0: return new (aPresShell) nsMathMLsemanticsFrame(aContext); michael@0: } michael@0: michael@0: NS_IMPL_FRAMEARENA_HELPERS(nsMathMLsemanticsFrame) michael@0: michael@0: nsMathMLsemanticsFrame::~nsMathMLsemanticsFrame() michael@0: { michael@0: } michael@0: michael@0: nsIFrame* michael@0: nsMathMLsemanticsFrame::GetSelectedFrame() michael@0: { michael@0: // By default, we will display the first child of the element. michael@0: nsIFrame* childFrame = mFrames.FirstChild(); michael@0: mSelectedFrame = childFrame; michael@0: michael@0: // An empty is invalid michael@0: if (!childFrame) { michael@0: mInvalidMarkup = true; michael@0: return mSelectedFrame; michael@0: } michael@0: mInvalidMarkup = false; michael@0: michael@0: // Using or as a first child is invalid. michael@0: // However some people use this syntax so we take care of this case too. michael@0: bool firstChildIsAnnotation = false; michael@0: nsIContent* childContent = childFrame->GetContent(); michael@0: if (childContent->GetNameSpaceID() == kNameSpaceID_MathML && michael@0: (childContent->Tag() == nsGkAtoms::annotation_ || michael@0: childContent->Tag() == nsGkAtoms::annotation_xml_)) { michael@0: firstChildIsAnnotation = true; michael@0: } michael@0: michael@0: // If the first child is a presentation MathML element other than michael@0: // or , we are done. michael@0: if (!firstChildIsAnnotation && michael@0: childFrame->IsFrameOfType(nsIFrame::eMathML)) { michael@0: nsIMathMLFrame* mathMLFrame = do_QueryFrame(childFrame); michael@0: if (mathMLFrame) { michael@0: TransmitAutomaticData(); michael@0: return mSelectedFrame; michael@0: } michael@0: // The first child is not an annotation, so skip it. michael@0: childFrame = childFrame->GetNextSibling(); michael@0: } michael@0: michael@0: // Otherwise, we read the list of annotations and select the first one that michael@0: // could be displayed in place of the first child of . If none is michael@0: // found, we fallback to this first child. michael@0: for ( ; childFrame; childFrame = childFrame->GetNextSibling()) { michael@0: nsIContent* childContent = childFrame->GetContent(); michael@0: michael@0: if (childContent->GetNameSpaceID() != kNameSpaceID_MathML) continue; michael@0: michael@0: if (childContent->Tag() == nsGkAtoms::annotation_) { michael@0: michael@0: // If the element has an src attribute we ignore it. michael@0: // XXXfredw Should annotation images be supported? See the related michael@0: // bug 297465 for mglyph. michael@0: if (childContent->HasAttr(kNameSpaceID_None, nsGkAtoms::src)) continue; michael@0: michael@0: // Otherwise, we assume it is a text annotation that can always be michael@0: // displayed and stop here. michael@0: mSelectedFrame = childFrame; michael@0: break; michael@0: } michael@0: michael@0: if (childContent->Tag() == nsGkAtoms::annotation_xml_) { michael@0: michael@0: // If the element has an src attribute we ignore it. michael@0: if (childContent->HasAttr(kNameSpaceID_None, nsGkAtoms::src)) continue; michael@0: michael@0: // If the element has an encoding attribute michael@0: // describing presentation MathML, SVG or HTML we assume the content michael@0: // can be displayed and stop here. michael@0: // michael@0: // We recognize the following encoding values: michael@0: // michael@0: // - "MathML-Presentation", which is mentioned in the MathML3 REC michael@0: // - "SVG1.1" which is mentioned in the W3C note michael@0: // http://www.w3.org/Math/Documents/Notes/graphics.xml michael@0: // - Other mime Content-Types for SVG and HTML michael@0: // michael@0: // We exclude APPLICATION_MATHML_XML = "application/mathml+xml" which michael@0: // is ambiguous about whether it is Presentation or Content MathML. michael@0: // Authors must use a more explicit encoding value. michael@0: nsAutoString value; michael@0: childContent->GetAttr(kNameSpaceID_None, nsGkAtoms::encoding, value); michael@0: if (value.EqualsLiteral("application/mathml-presentation+xml") || michael@0: value.EqualsLiteral("MathML-Presentation") || michael@0: value.EqualsLiteral(IMAGE_SVG_XML) || michael@0: value.EqualsLiteral("SVG1.1") || michael@0: value.EqualsLiteral(APPLICATION_XHTML_XML) || michael@0: value.EqualsLiteral(TEXT_HTML)) { michael@0: mSelectedFrame = childFrame; michael@0: break; michael@0: } michael@0: } michael@0: } michael@0: michael@0: TransmitAutomaticData(); michael@0: return mSelectedFrame; michael@0: }