Wed, 31 Dec 2014 06:55:50 +0100
Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | |
michael@0 | 7 | #include "nsMathMLsemanticsFrame.h" |
michael@0 | 8 | #include "nsMimeTypes.h" |
michael@0 | 9 | #include "mozilla/gfx/2D.h" |
michael@0 | 10 | |
michael@0 | 11 | // |
michael@0 | 12 | // <semantics> -- associate annotations with a MathML expression |
michael@0 | 13 | // |
michael@0 | 14 | |
michael@0 | 15 | nsIFrame* |
michael@0 | 16 | NS_NewMathMLsemanticsFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) |
michael@0 | 17 | { |
michael@0 | 18 | return new (aPresShell) nsMathMLsemanticsFrame(aContext); |
michael@0 | 19 | } |
michael@0 | 20 | |
michael@0 | 21 | NS_IMPL_FRAMEARENA_HELPERS(nsMathMLsemanticsFrame) |
michael@0 | 22 | |
michael@0 | 23 | nsMathMLsemanticsFrame::~nsMathMLsemanticsFrame() |
michael@0 | 24 | { |
michael@0 | 25 | } |
michael@0 | 26 | |
michael@0 | 27 | nsIFrame* |
michael@0 | 28 | nsMathMLsemanticsFrame::GetSelectedFrame() |
michael@0 | 29 | { |
michael@0 | 30 | // By default, we will display the first child of the <semantics> element. |
michael@0 | 31 | nsIFrame* childFrame = mFrames.FirstChild(); |
michael@0 | 32 | mSelectedFrame = childFrame; |
michael@0 | 33 | |
michael@0 | 34 | // An empty <semantics> is invalid |
michael@0 | 35 | if (!childFrame) { |
michael@0 | 36 | mInvalidMarkup = true; |
michael@0 | 37 | return mSelectedFrame; |
michael@0 | 38 | } |
michael@0 | 39 | mInvalidMarkup = false; |
michael@0 | 40 | |
michael@0 | 41 | // Using <annotation> or <annotation-xml> as a first child is invalid. |
michael@0 | 42 | // However some people use this syntax so we take care of this case too. |
michael@0 | 43 | bool firstChildIsAnnotation = false; |
michael@0 | 44 | nsIContent* childContent = childFrame->GetContent(); |
michael@0 | 45 | if (childContent->GetNameSpaceID() == kNameSpaceID_MathML && |
michael@0 | 46 | (childContent->Tag() == nsGkAtoms::annotation_ || |
michael@0 | 47 | childContent->Tag() == nsGkAtoms::annotation_xml_)) { |
michael@0 | 48 | firstChildIsAnnotation = true; |
michael@0 | 49 | } |
michael@0 | 50 | |
michael@0 | 51 | // If the first child is a presentation MathML element other than |
michael@0 | 52 | // <annotation> or <annotation-xml>, we are done. |
michael@0 | 53 | if (!firstChildIsAnnotation && |
michael@0 | 54 | childFrame->IsFrameOfType(nsIFrame::eMathML)) { |
michael@0 | 55 | nsIMathMLFrame* mathMLFrame = do_QueryFrame(childFrame); |
michael@0 | 56 | if (mathMLFrame) { |
michael@0 | 57 | TransmitAutomaticData(); |
michael@0 | 58 | return mSelectedFrame; |
michael@0 | 59 | } |
michael@0 | 60 | // The first child is not an annotation, so skip it. |
michael@0 | 61 | childFrame = childFrame->GetNextSibling(); |
michael@0 | 62 | } |
michael@0 | 63 | |
michael@0 | 64 | // Otherwise, we read the list of annotations and select the first one that |
michael@0 | 65 | // could be displayed in place of the first child of <semantics>. If none is |
michael@0 | 66 | // found, we fallback to this first child. |
michael@0 | 67 | for ( ; childFrame; childFrame = childFrame->GetNextSibling()) { |
michael@0 | 68 | nsIContent* childContent = childFrame->GetContent(); |
michael@0 | 69 | |
michael@0 | 70 | if (childContent->GetNameSpaceID() != kNameSpaceID_MathML) continue; |
michael@0 | 71 | |
michael@0 | 72 | if (childContent->Tag() == nsGkAtoms::annotation_) { |
michael@0 | 73 | |
michael@0 | 74 | // If the <annotation> element has an src attribute we ignore it. |
michael@0 | 75 | // XXXfredw Should annotation images be supported? See the related |
michael@0 | 76 | // bug 297465 for mglyph. |
michael@0 | 77 | if (childContent->HasAttr(kNameSpaceID_None, nsGkAtoms::src)) continue; |
michael@0 | 78 | |
michael@0 | 79 | // Otherwise, we assume it is a text annotation that can always be |
michael@0 | 80 | // displayed and stop here. |
michael@0 | 81 | mSelectedFrame = childFrame; |
michael@0 | 82 | break; |
michael@0 | 83 | } |
michael@0 | 84 | |
michael@0 | 85 | if (childContent->Tag() == nsGkAtoms::annotation_xml_) { |
michael@0 | 86 | |
michael@0 | 87 | // If the <annotation-xml> element has an src attribute we ignore it. |
michael@0 | 88 | if (childContent->HasAttr(kNameSpaceID_None, nsGkAtoms::src)) continue; |
michael@0 | 89 | |
michael@0 | 90 | // If the <annotation-xml> element has an encoding attribute |
michael@0 | 91 | // describing presentation MathML, SVG or HTML we assume the content |
michael@0 | 92 | // can be displayed and stop here. |
michael@0 | 93 | // |
michael@0 | 94 | // We recognize the following encoding values: |
michael@0 | 95 | // |
michael@0 | 96 | // - "MathML-Presentation", which is mentioned in the MathML3 REC |
michael@0 | 97 | // - "SVG1.1" which is mentioned in the W3C note |
michael@0 | 98 | // http://www.w3.org/Math/Documents/Notes/graphics.xml |
michael@0 | 99 | // - Other mime Content-Types for SVG and HTML |
michael@0 | 100 | // |
michael@0 | 101 | // We exclude APPLICATION_MATHML_XML = "application/mathml+xml" which |
michael@0 | 102 | // is ambiguous about whether it is Presentation or Content MathML. |
michael@0 | 103 | // Authors must use a more explicit encoding value. |
michael@0 | 104 | nsAutoString value; |
michael@0 | 105 | childContent->GetAttr(kNameSpaceID_None, nsGkAtoms::encoding, value); |
michael@0 | 106 | if (value.EqualsLiteral("application/mathml-presentation+xml") || |
michael@0 | 107 | value.EqualsLiteral("MathML-Presentation") || |
michael@0 | 108 | value.EqualsLiteral(IMAGE_SVG_XML) || |
michael@0 | 109 | value.EqualsLiteral("SVG1.1") || |
michael@0 | 110 | value.EqualsLiteral(APPLICATION_XHTML_XML) || |
michael@0 | 111 | value.EqualsLiteral(TEXT_HTML)) { |
michael@0 | 112 | mSelectedFrame = childFrame; |
michael@0 | 113 | break; |
michael@0 | 114 | } |
michael@0 | 115 | } |
michael@0 | 116 | } |
michael@0 | 117 | |
michael@0 | 118 | TransmitAutomaticData(); |
michael@0 | 119 | return mSelectedFrame; |
michael@0 | 120 | } |