layout/mathml/nsMathMLsemanticsFrame.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/layout/mathml/nsMathMLsemanticsFrame.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,120 @@
     1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
     1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +
    1.10 +#include "nsMathMLsemanticsFrame.h"
    1.11 +#include "nsMimeTypes.h"
    1.12 +#include "mozilla/gfx/2D.h"
    1.13 +
    1.14 +//
    1.15 +// <semantics> -- associate annotations with a MathML expression
    1.16 +//
    1.17 +
    1.18 +nsIFrame*
    1.19 +NS_NewMathMLsemanticsFrame(nsIPresShell* aPresShell, nsStyleContext* aContext)
    1.20 +{
    1.21 +  return new (aPresShell) nsMathMLsemanticsFrame(aContext);
    1.22 +}
    1.23 +
    1.24 +NS_IMPL_FRAMEARENA_HELPERS(nsMathMLsemanticsFrame)
    1.25 +
    1.26 +nsMathMLsemanticsFrame::~nsMathMLsemanticsFrame()
    1.27 +{
    1.28 +}
    1.29 +
    1.30 +nsIFrame* 
    1.31 +nsMathMLsemanticsFrame::GetSelectedFrame()
    1.32 +{
    1.33 +  // By default, we will display the first child of the <semantics> element.
    1.34 +  nsIFrame* childFrame = mFrames.FirstChild(); 
    1.35 +  mSelectedFrame = childFrame;
    1.36 +
    1.37 +  // An empty <semantics> is invalid
    1.38 +  if (!childFrame) {
    1.39 +    mInvalidMarkup = true;
    1.40 +    return mSelectedFrame;
    1.41 +  }
    1.42 +  mInvalidMarkup = false;
    1.43 +
    1.44 +  // Using <annotation> or <annotation-xml> as a first child is invalid.
    1.45 +  // However some people use this syntax so we take care of this case too.
    1.46 +  bool firstChildIsAnnotation = false;
    1.47 +  nsIContent* childContent = childFrame->GetContent();
    1.48 +  if (childContent->GetNameSpaceID() == kNameSpaceID_MathML &&
    1.49 +      (childContent->Tag() == nsGkAtoms::annotation_ ||
    1.50 +       childContent->Tag() == nsGkAtoms::annotation_xml_)) {
    1.51 +    firstChildIsAnnotation = true;
    1.52 +  }
    1.53 +
    1.54 +  // If the first child is a presentation MathML element other than
    1.55 +  // <annotation> or <annotation-xml>, we are done.
    1.56 +  if (!firstChildIsAnnotation &&
    1.57 +      childFrame->IsFrameOfType(nsIFrame::eMathML)) {
    1.58 +    nsIMathMLFrame* mathMLFrame = do_QueryFrame(childFrame);
    1.59 +    if (mathMLFrame) {
    1.60 +      TransmitAutomaticData();
    1.61 +      return mSelectedFrame;
    1.62 +    }
    1.63 +    // The first child is not an annotation, so skip it.
    1.64 +    childFrame = childFrame->GetNextSibling();
    1.65 +  }
    1.66 +
    1.67 +  // Otherwise, we read the list of annotations and select the first one that
    1.68 +  // could be displayed in place of the first child of <semantics>. If none is
    1.69 +  // found, we fallback to this first child.
    1.70 +  for ( ; childFrame; childFrame = childFrame->GetNextSibling()) {
    1.71 +    nsIContent* childContent = childFrame->GetContent();
    1.72 +
    1.73 +    if (childContent->GetNameSpaceID() != kNameSpaceID_MathML) continue;
    1.74 +
    1.75 +    if (childContent->Tag() == nsGkAtoms::annotation_) {
    1.76 +
    1.77 +      // If the <annotation> element has an src attribute we ignore it.
    1.78 +      // XXXfredw Should annotation images be supported? See the related
    1.79 +      // bug 297465 for mglyph.
    1.80 +      if (childContent->HasAttr(kNameSpaceID_None, nsGkAtoms::src)) continue;
    1.81 +
    1.82 +      // Otherwise, we assume it is a text annotation that can always be
    1.83 +      // displayed and stop here.
    1.84 +      mSelectedFrame = childFrame;
    1.85 +      break;
    1.86 +    }
    1.87 +
    1.88 +    if (childContent->Tag() == nsGkAtoms::annotation_xml_) {
    1.89 +
    1.90 +      // If the <annotation-xml> element has an src attribute we ignore it.
    1.91 +      if (childContent->HasAttr(kNameSpaceID_None, nsGkAtoms::src)) continue;
    1.92 +
    1.93 +      // If the <annotation-xml> element has an encoding attribute
    1.94 +      // describing presentation MathML, SVG or HTML we assume the content
    1.95 +      // can be displayed and stop here.
    1.96 +      //
    1.97 +      // We recognize the following encoding values:
    1.98 +      //
    1.99 +      // - "MathML-Presentation", which is mentioned in the MathML3 REC
   1.100 +      // - "SVG1.1" which is mentioned in the W3C note
   1.101 +      //                   http://www.w3.org/Math/Documents/Notes/graphics.xml
   1.102 +      // - Other mime Content-Types for SVG and HTML
   1.103 +      //
   1.104 +      // We exclude APPLICATION_MATHML_XML = "application/mathml+xml" which
   1.105 +      // is ambiguous about whether it is Presentation or Content MathML.
   1.106 +      // Authors must use a more explicit encoding value.
   1.107 +      nsAutoString value;
   1.108 +      childContent->GetAttr(kNameSpaceID_None, nsGkAtoms::encoding, value);
   1.109 +      if (value.EqualsLiteral("application/mathml-presentation+xml") ||
   1.110 +          value.EqualsLiteral("MathML-Presentation") ||
   1.111 +          value.EqualsLiteral(IMAGE_SVG_XML) ||
   1.112 +          value.EqualsLiteral("SVG1.1") ||
   1.113 +          value.EqualsLiteral(APPLICATION_XHTML_XML) ||
   1.114 +          value.EqualsLiteral(TEXT_HTML)) {
   1.115 +        mSelectedFrame = childFrame;
   1.116 +        break;
   1.117 +      }
   1.118 +    }
   1.119 +  }
   1.120 +
   1.121 +  TransmitAutomaticData();
   1.122 +  return mSelectedFrame;
   1.123 +}

mercurial