Commit 894a28d9 authored by Carsten "Tomcat" Book's avatar Carsten "Tomcat" Book
Browse files

merge mozilla-inbound to mozilla-central on a CLOSED TREE

parents fddab43f e1cd84d8
Loading
Loading
Loading
Loading
+64 −27
Original line number Diff line number Diff line
@@ -658,12 +658,15 @@ AccessibleWrap::get_accFocus(
  if (IsDefunct())
    return CO_E_OBJNOTCONNECTED;

  // TODO make this work with proxies.
  if (IsProxy())
    return E_NOTIMPL;

  // Return the current IAccessible child that has focus
  Accessible* focusedAccessible = FocusedChild();
  Accessible* focusedAccessible;
  if (IsProxy()) {
    ProxyAccessible* proxy = Proxy()->FocusedChild();
    focusedAccessible = proxy ? WrapperFor(proxy) : nullptr;
  } else {
    focusedAccessible = FocusedChild();
  }

  if (focusedAccessible == this) {
    pvarChild->vt = VT_I4;
    pvarChild->lVal = CHILDID_SELF;
@@ -830,7 +833,17 @@ AccessibleWrap::get_accSelection(VARIANT __RPC_FAR *pvarChildren)

  if (IsSelect()) {
    nsAutoTArray<Accessible*, 10> selectedItems;
    if (IsProxy()) {
      nsTArray<ProxyAccessible*> proxies;
      Proxy()->SelectedItems(&proxies);

      uint32_t selectedCount = proxies.Length();
      for (uint32_t i = 0; i < selectedCount; i++) {
        selectedItems.AppendElement(WrapperFor(proxies[i]));
      }
    } else {
      SelectedItems(&selectedItems);
    }

    // 1) Create and initialize the enumeration
    RefPtr<AccessibleEnumerator> pEnum = new AccessibleEnumerator(selectedItems);
@@ -864,12 +877,13 @@ AccessibleWrap::get_accDefaultAction(
  if (xpAccessible->IsDefunct())
    return CO_E_OBJNOTCONNECTED;

  // TODO make this work with proxies.
  if (xpAccessible->IsProxy())
    return E_NOTIMPL;

  nsAutoString defaultAction;
  if (xpAccessible->IsProxy()) {
    xpAccessible->Proxy()->ActionNameAt(0, defaultAction);
  } else {
    xpAccessible->ActionNameAt(0, defaultAction);
  }

  *pszDefaultAction = ::SysAllocStringLen(defaultAction.get(),
                                          defaultAction.Length());
  return *pszDefaultAction ? S_OK : E_OUTOFMEMORY;
@@ -895,23 +909,42 @@ AccessibleWrap::accSelect(
  if (xpAccessible->IsDefunct())
    return CO_E_OBJNOTCONNECTED;

  // TODO make this work with proxies.
  if (xpAccessible->IsProxy())
    return E_NOTIMPL;

  if (flagsSelect & (SELFLAG_TAKEFOCUS|SELFLAG_TAKESELECTION|SELFLAG_REMOVESELECTION))
  {
    if (flagsSelect & SELFLAG_TAKEFOCUS)
  if (flagsSelect & SELFLAG_TAKEFOCUS) {
    if (xpAccessible->IsProxy()) {
      xpAccessible->Proxy()->TakeFocus();
    } else {
      xpAccessible->TakeFocus();
    }

    return S_OK;
  }

    if (flagsSelect & SELFLAG_TAKESELECTION)
  if (flagsSelect & SELFLAG_TAKESELECTION) {
    if (xpAccessible->IsProxy()) {
      xpAccessible->Proxy()->TakeSelection();
    } else {
      xpAccessible->TakeSelection();
    }

    if (flagsSelect & SELFLAG_ADDSELECTION)
    return S_OK;
  }

  if (flagsSelect & SELFLAG_ADDSELECTION) {
    if (xpAccessible->IsProxy()) {
      xpAccessible->Proxy()->SetSelected(true);
    } else {
      xpAccessible->SetSelected(true);
    }

    return S_OK;
  }

    if (flagsSelect & SELFLAG_REMOVESELECTION)
  if (flagsSelect & SELFLAG_REMOVESELECTION) {
    if (xpAccessible->IsProxy()) {
      xpAccessible->Proxy()->SetSelected(false);
    } else {
      xpAccessible->SetSelected(false);
    }

    return S_OK;
  }
@@ -1063,11 +1096,15 @@ AccessibleWrap::accHitTest(
  if (IsDefunct())
    return CO_E_OBJNOTCONNECTED;

  // TODO make this work with proxies.
  if (IsProxy())
    return E_NOTIMPL;

  Accessible* accessible = ChildAtPoint(xLeft, yTop, eDirectChild);
  Accessible* accessible = nullptr;
  if (IsProxy()) {
    ProxyAccessible* proxy = Proxy()->ChildAtPoint(xLeft, yTop, eDirectChild);
    if (proxy) {
      accessible = WrapperFor(proxy);
    }
  } else {
    accessible = ChildAtPoint(xLeft, yTop, eDirectChild);
  }

  // if we got a child
  if (accessible) {
@@ -1107,7 +1144,7 @@ AccessibleWrap::accDoDefaultAction(

  // TODO make this work with proxies.
  if (xpAccessible->IsProxy())
    return E_NOTIMPL;
    return xpAccessible->Proxy()->DoAction(0) ? S_OK : E_INVALIDARG;

  return xpAccessible->DoAction(0) ? S_OK : E_INVALIDARG;

+8 −0
Original line number Diff line number Diff line
@@ -1446,11 +1446,19 @@ pref("plain_text.wrap_long_lines", true);
pref("dom.debug.propagate_gesture_events_through_content", false);

// The request URL of the GeoLocation backend.
#ifdef RELEASE_BUILD
pref("geo.wifi.uri", "https://www.googleapis.com/geolocation/v1/geolocate?key=%GOOGLE_API_KEY%");
#else
pref("geo.wifi.uri", "https://location.services.mozilla.com/v1/geolocate?key=%MOZILLA_API_KEY%");
#endif

#ifdef XP_MACOSX
#ifdef RELEASE_BUILD
pref("geo.provider.use_corelocation", false);
#else
pref("geo.provider.use_corelocation", true);
#endif
#endif

#ifdef XP_WIN
pref("geo.provider.ms-windows-location", false);
+1 −602
Original line number Diff line number Diff line
@@ -2062,492 +2062,6 @@ FragmentOrElement::IndexOf(const nsINode* aPossibleChild) const
  return mAttrsAndChildren.IndexOfChild(aPossibleChild);
}

// Try to keep the size of StringBuilder close to a jemalloc bucket size.
#define STRING_BUFFER_UNITS 1020

namespace {

// We put StringBuilder in the anonymous namespace to prevent anything outside
// this file from accidentally being linked against it.

class StringBuilder
{
private:
  class Unit
  {
  public:
    Unit() : mAtom(nullptr), mType(eUnknown), mLength(0)
    {
      MOZ_COUNT_CTOR(StringBuilder::Unit);
    }
    ~Unit()
    {
      if (mType == eString || mType == eStringWithEncode) {
        delete mString;
      }
      MOZ_COUNT_DTOR(StringBuilder::Unit);
    }

    enum Type
    {
      eUnknown,
      eAtom,
      eString,
      eStringWithEncode,
      eLiteral,
      eTextFragment,
      eTextFragmentWithEncode,
    };

    union
    {
      nsIAtom*              mAtom;
      const char*           mLiteral;
      nsAutoString*         mString;
      const nsTextFragment* mTextFragment;
    };
    Type     mType;
    uint32_t mLength;
  };
public:
  StringBuilder() : mLast(this), mLength(0)
  {
    MOZ_COUNT_CTOR(StringBuilder);
  }

  ~StringBuilder()
  {
    MOZ_COUNT_DTOR(StringBuilder);
  }

  void Append(nsIAtom* aAtom)
  {
    Unit* u = AddUnit();
    u->mAtom = aAtom;
    u->mType = Unit::eAtom;
    uint32_t len = aAtom->GetLength();
    u->mLength = len;
    mLength += len;
  }

  template<int N>
  void Append(const char (&aLiteral)[N])
  {
    Unit* u = AddUnit();
    u->mLiteral = aLiteral;
    u->mType = Unit::eLiteral;
    uint32_t len = N - 1;
    u->mLength = len;
    mLength += len;
  }

  template<int N>
  void Append(char (&aLiteral)[N])
  {
    Unit* u = AddUnit();
    u->mLiteral = aLiteral;
    u->mType = Unit::eLiteral;
    uint32_t len = N - 1;
    u->mLength = len;
    mLength += len;
  }

  void Append(const nsAString& aString)
  {
    Unit* u = AddUnit();
    u->mString = new nsAutoString(aString);
    u->mType = Unit::eString;
    uint32_t len = aString.Length();
    u->mLength = len;
    mLength += len;
  }

  void Append(nsAutoString* aString)
  {
    Unit* u = AddUnit();
    u->mString = aString;
    u->mType = Unit::eString;
    uint32_t len = aString->Length();
    u->mLength = len;
    mLength += len;
  }

  void AppendWithAttrEncode(nsAutoString* aString, uint32_t aLen)
  {
    Unit* u = AddUnit();
    u->mString = aString;
    u->mType = Unit::eStringWithEncode;
    u->mLength = aLen;
    mLength += aLen;
  }

  void Append(const nsTextFragment* aTextFragment)
  {
    Unit* u = AddUnit();
    u->mTextFragment = aTextFragment;
    u->mType = Unit::eTextFragment;
    uint32_t len = aTextFragment->GetLength();
    u->mLength = len;
    mLength += len;
  }

  void AppendWithEncode(const nsTextFragment* aTextFragment, uint32_t aLen)
  {
    Unit* u = AddUnit();
    u->mTextFragment = aTextFragment;
    u->mType = Unit::eTextFragmentWithEncode;
    u->mLength = aLen;
    mLength += aLen;
  }

  bool ToString(nsAString& aOut)
  {
    if (!aOut.SetCapacity(mLength, fallible)) {
      return false;
    }

    for (StringBuilder* current = this; current; current = current->mNext) {
      uint32_t len = current->mUnits.Length();
      for (uint32_t i = 0; i < len; ++i) {
        Unit& u = current->mUnits[i];
        switch (u.mType) {
          case Unit::eAtom:
            aOut.Append(nsDependentAtomString(u.mAtom));
            break;
          case Unit::eString:
            aOut.Append(*(u.mString));
            break;
          case Unit::eStringWithEncode:
            EncodeAttrString(*(u.mString), aOut);
            break;
          case Unit::eLiteral:
            aOut.AppendASCII(u.mLiteral, u.mLength);
            break;
          case Unit::eTextFragment:
            u.mTextFragment->AppendTo(aOut);
            break;
          case Unit::eTextFragmentWithEncode:
            EncodeTextFragment(u.mTextFragment, aOut);
            break;
          default:
            MOZ_CRASH("Unknown unit type?");
        }
      }
    }
    return true;
  }
private:
  Unit* AddUnit()
  {
    if (mLast->mUnits.Length() == STRING_BUFFER_UNITS) {
      new StringBuilder(this);
    }
    return mLast->mUnits.AppendElement();
  }

  explicit StringBuilder(StringBuilder* aFirst)
  : mLast(nullptr), mLength(0)
  {
    MOZ_COUNT_CTOR(StringBuilder);
    aFirst->mLast->mNext = this;
    aFirst->mLast = this;
  }

  void EncodeAttrString(const nsAutoString& aValue, nsAString& aOut)
  {
    const char16_t* c = aValue.BeginReading();
    const char16_t* end = aValue.EndReading();
    while (c < end) {
      switch (*c) {
      case '"':
        aOut.AppendLiteral("&quot;");
        break;
      case '&':
        aOut.AppendLiteral("&amp;");
        break;
      case 0x00A0:
        aOut.AppendLiteral("&nbsp;");
        break;
      default:
        aOut.Append(*c);
        break;
      }
      ++c;
    }
  }

  void EncodeTextFragment(const nsTextFragment* aValue, nsAString& aOut)
  {
    uint32_t len = aValue->GetLength();
    if (aValue->Is2b()) {
      const char16_t* data = aValue->Get2b();
      for (uint32_t i = 0; i < len; ++i) {
        const char16_t c = data[i];
        switch (c) {
          case '<':
            aOut.AppendLiteral("&lt;");
            break;
          case '>':
            aOut.AppendLiteral("&gt;");
            break;
          case '&':
            aOut.AppendLiteral("&amp;");
            break;
          case 0x00A0:
            aOut.AppendLiteral("&nbsp;");
            break;
          default:
            aOut.Append(c);
            break;
        }
      }
    } else {
      const char* data = aValue->Get1b();
      for (uint32_t i = 0; i < len; ++i) {
        const unsigned char c = data[i];
        switch (c) {
          case '<':
            aOut.AppendLiteral("&lt;");
            break;
          case '>':
            aOut.AppendLiteral("&gt;");
            break;
          case '&':
            aOut.AppendLiteral("&amp;");
            break;
          case 0x00A0:
            aOut.AppendLiteral("&nbsp;");
            break;
          default:
            aOut.Append(c);
            break;
        }
      }
    }
  }

  nsAutoTArray<Unit, STRING_BUFFER_UNITS> mUnits;
  nsAutoPtr<StringBuilder>                mNext;
  StringBuilder*                          mLast;
  // mLength is used only in the first StringBuilder object in the linked list.
  uint32_t                                mLength;
};

} // namespace

static void
AppendEncodedCharacters(const nsTextFragment* aText, StringBuilder& aBuilder)
{
  uint32_t extraSpaceNeeded = 0;
  uint32_t len = aText->GetLength();
  if (aText->Is2b()) {
    const char16_t* data = aText->Get2b();
    for (uint32_t i = 0; i < len; ++i) {
      const char16_t c = data[i];
      switch (c) {
        case '<':
          extraSpaceNeeded += ArrayLength("&lt;") - 2;
          break;
        case '>':
          extraSpaceNeeded += ArrayLength("&gt;") - 2;
          break;
        case '&':
          extraSpaceNeeded += ArrayLength("&amp;") - 2;
          break;
        case 0x00A0:
          extraSpaceNeeded += ArrayLength("&nbsp;") - 2;
          break;
        default:
          break;
      }
    }
  } else {
    const char* data = aText->Get1b();
    for (uint32_t i = 0; i < len; ++i) {
      const unsigned char c = data[i];
      switch (c) {
        case '<':
          extraSpaceNeeded += ArrayLength("&lt;") - 2;
          break;
        case '>':
          extraSpaceNeeded += ArrayLength("&gt;") - 2;
          break;
        case '&':
          extraSpaceNeeded += ArrayLength("&amp;") - 2;
          break;
        case 0x00A0:
          extraSpaceNeeded += ArrayLength("&nbsp;") - 2;
          break;
        default:
          break;
      }
    }
  }

  if (extraSpaceNeeded) {
    aBuilder.AppendWithEncode(aText, len + extraSpaceNeeded);
  } else {
    aBuilder.Append(aText);
  }
}

static void
AppendEncodedAttributeValue(nsAutoString* aValue, StringBuilder& aBuilder)
{
  const char16_t* c = aValue->BeginReading();
  const char16_t* end = aValue->EndReading();

  uint32_t extraSpaceNeeded = 0;
  while (c < end) {
    switch (*c) {
      case '"':
        extraSpaceNeeded += ArrayLength("&quot;") - 2;
        break;
      case '&':
        extraSpaceNeeded += ArrayLength("&amp;") - 2;
        break;
      case 0x00A0:
        extraSpaceNeeded += ArrayLength("&nbsp;") - 2;
        break;
      default:
        break;
    }
    ++c;
  }

  if (extraSpaceNeeded) {
    aBuilder.AppendWithAttrEncode(aValue, aValue->Length() + extraSpaceNeeded);
  } else {
    aBuilder.Append(aValue);
  }
}

static void
StartElement(Element* aContent, StringBuilder& aBuilder)
{
  nsIAtom* localName = aContent->NodeInfo()->NameAtom();
  int32_t tagNS = aContent->GetNameSpaceID();

  aBuilder.Append("<");
  if (aContent->IsHTMLElement() || aContent->IsSVGElement() ||
      aContent->IsMathMLElement()) {
    aBuilder.Append(localName);
  } else {
    aBuilder.Append(aContent->NodeName());
  }

  int32_t count = aContent->GetAttrCount();
  for (int32_t i = count; i > 0;) {
    --i;
    const nsAttrName* name = aContent->GetAttrNameAt(i);
    int32_t attNs = name->NamespaceID();
    nsIAtom* attName = name->LocalName();

    // Filter out any attribute starting with [-|_]moz
    nsDependentAtomString attrNameStr(attName);
    if (StringBeginsWith(attrNameStr, NS_LITERAL_STRING("_moz")) ||
        StringBeginsWith(attrNameStr, NS_LITERAL_STRING("-moz"))) {
      continue;
    }

    nsAutoString* attValue = new nsAutoString();
    aContent->GetAttr(attNs, attName, *attValue);

    // Filter out special case of <br type="_moz*"> used by the editor.
    // Bug 16988.  Yuck.
    if (localName == nsGkAtoms::br && tagNS == kNameSpaceID_XHTML &&
        attName == nsGkAtoms::type && attNs == kNameSpaceID_None &&
        StringBeginsWith(*attValue, NS_LITERAL_STRING("_moz"))) {
      delete attValue;
      continue;
    }

    aBuilder.Append(" ");

    if (MOZ_LIKELY(attNs == kNameSpaceID_None) ||
        (attNs == kNameSpaceID_XMLNS &&
         attName == nsGkAtoms::xmlns)) {
      // Nothing else required
    } else if (attNs == kNameSpaceID_XML) {
      aBuilder.Append("xml:");
    } else if (attNs == kNameSpaceID_XMLNS) {
      aBuilder.Append("xmlns:");
    } else if (attNs == kNameSpaceID_XLink) {
      aBuilder.Append("xlink:");
    } else {
      nsIAtom* prefix = name->GetPrefix();
      if (prefix) {
        aBuilder.Append(prefix);
        aBuilder.Append(":");
      }
    }

    aBuilder.Append(attName);
    aBuilder.Append("=\"");
    AppendEncodedAttributeValue(attValue, aBuilder);
    aBuilder.Append("\"");
  }

  aBuilder.Append(">");

  /*
  // Per HTML spec we should append one \n if the first child of
  // pre/textarea/listing is a textnode and starts with a \n.
  // But because browsers haven't traditionally had that behavior,
  // we're not changing our behavior either - yet.
  if (aContent->IsHTMLElement()) {
    if (localName == nsGkAtoms::pre || localName == nsGkAtoms::textarea ||
        localName == nsGkAtoms::listing) {
      nsIContent* fc = aContent->GetFirstChild();
      if (fc &&
          (fc->NodeType() == nsIDOMNode::TEXT_NODE ||
           fc->NodeType() == nsIDOMNode::CDATA_SECTION_NODE)) {
        const nsTextFragment* text = fc->GetText();
        if (text && text->GetLength() && text->CharAt(0) == char16_t('\n')) {
          aBuilder.Append("\n");
        }
      }
    }
  }*/
}

static inline bool
ShouldEscape(nsIContent* aParent)
{
  if (!aParent || !aParent->IsHTMLElement()) {
    return true;
  }

  static const nsIAtom* nonEscapingElements[] = {
    nsGkAtoms::style, nsGkAtoms::script, nsGkAtoms::xmp,
    nsGkAtoms::iframe, nsGkAtoms::noembed, nsGkAtoms::noframes,
    nsGkAtoms::plaintext,
    // Per the current spec noscript should be escaped in case
    // scripts are disabled or if document doesn't have
    // browsing context. However the latter seems to be a spec bug
    // and Gecko hasn't traditionally done the former.
    nsGkAtoms::noscript
  };
  static mozilla::BloomFilter<12, nsIAtom> sFilter;
  static bool sInitialized = false;
  if (!sInitialized) {
    sInitialized = true;
    for (uint32_t i = 0; i < ArrayLength(nonEscapingElements); ++i) {
      sFilter.add(nonEscapingElements[i]);
    }
  }

  nsIAtom* tag = aParent->NodeInfo()->NameAtom();
  if (sFilter.mightContain(tag)) {
    for (uint32_t i = 0; i < ArrayLength(nonEscapingElements); ++i) {
      if (tag == nonEscapingElements[i]) {
        return false;
      }
    }
  }
  return true;
}

static inline bool
IsVoidTag(nsIAtom* aTag)
{
@@ -2580,15 +2094,6 @@ IsVoidTag(nsIAtom* aTag)
  return false;
}

static inline bool
IsVoidTag(Element* aElement)
{
  if (!aElement->IsHTMLElement()) {
    return false;
  }
  return IsVoidTag(aElement->NodeInfo()->NameAtom());
}

/* static */
bool
FragmentOrElement::IsHTMLVoid(nsIAtom* aLocalName)
@@ -2596,112 +2101,6 @@ FragmentOrElement::IsHTMLVoid(nsIAtom* aLocalName)
  return aLocalName && IsVoidTag(aLocalName);
}

static bool
Serialize(FragmentOrElement* aRoot, bool aDescendentsOnly, nsAString& aOut)
{
  nsINode* current = aDescendentsOnly ?
    nsNodeUtils::GetFirstChildOfTemplateOrNode(aRoot) : aRoot;

  if (!current) {
    return true;
  }

  StringBuilder builder;
  nsIContent* next;
  while (true) {
    bool isVoid = false;
    switch (current->NodeType()) {
      case nsIDOMNode::ELEMENT_NODE: {
        Element* elem = current->AsElement();
        StartElement(elem, builder);
        isVoid = IsVoidTag(elem);
        if (!isVoid &&
            (next = nsNodeUtils::GetFirstChildOfTemplateOrNode(current))) {
          current = next;
          continue;
        }
        break;
      }

      case nsIDOMNode::TEXT_NODE:
      case nsIDOMNode::CDATA_SECTION_NODE: {
        const nsTextFragment* text = static_cast<nsIContent*>(current)->GetText();
        nsIContent* parent = current->GetParent();
        if (ShouldEscape(parent)) {
          AppendEncodedCharacters(text, builder);
        } else {
          builder.Append(text);
        }
        break;
      }

      case nsIDOMNode::COMMENT_NODE: {
        builder.Append("<!--");
        builder.Append(static_cast<nsIContent*>(current)->GetText());
        builder.Append("-->");
        break;
      }

      case nsIDOMNode::DOCUMENT_TYPE_NODE: {
        builder.Append("<!DOCTYPE ");
        builder.Append(current->NodeName());
        builder.Append(">");
        break;
      }

      case nsIDOMNode::PROCESSING_INSTRUCTION_NODE: {
        builder.Append("<?");
        builder.Append(current->NodeName());
        builder.Append(" ");
        builder.Append(static_cast<nsIContent*>(current)->GetText());
        builder.Append(">");
        break;
      }
    }

    while (true) {
      if (!isVoid && current->NodeType() == nsIDOMNode::ELEMENT_NODE) {
        builder.Append("</");
        nsIContent* elem = static_cast<nsIContent*>(current);
        if (elem->IsHTMLElement() || elem->IsSVGElement() ||
            elem->IsMathMLElement()) {
          builder.Append(elem->NodeInfo()->NameAtom());
        } else {
          builder.Append(current->NodeName());
        }
        builder.Append(">");
      }
      isVoid = false;

      if (current == aRoot) {
        return builder.ToString(aOut);
      }

      if ((next = current->GetNextSibling())) {
        current = next;
        break;
      }

      current = current->GetParentNode();

      // Handle template element. If the parent is a template's content,
      // then adjust the parent to be the template element.
      if (current != aRoot &&
          current->NodeType() == nsIDOMNode::DOCUMENT_FRAGMENT_NODE) {
        DocumentFragment* frag = static_cast<DocumentFragment*>(current);
        nsIContent* fragHost = frag->GetHost();
        if (fragHost && nsNodeUtils::IsTemplateElement(fragHost)) {
          current = fragHost;
        }
      }

      if (aDescendentsOnly && current == aRoot) {
        return builder.ToString(aOut);
      }
    }
  }
}

void
FragmentOrElement::GetMarkup(bool aIncludeSelf, nsAString& aMarkup)
{
@@ -2709,7 +2108,7 @@ FragmentOrElement::GetMarkup(bool aIncludeSelf, nsAString& aMarkup)

  nsIDocument* doc = OwnerDoc();
  if (IsInHTMLDocument()) {
    Serialize(this, !aIncludeSelf, aMarkup);
    nsContentUtils::SerializeNodeToMarkup(this, !aIncludeSelf, aMarkup);
    return;
  }

+18 −6
Original line number Diff line number Diff line
@@ -48,12 +48,22 @@ NodeIsInTraversalRange(nsINode* aNode, bool aIsPreMode,
    return false;
  }

  // If a chardata node contains an end point of the traversal range, it is
  // If a leaf node contains an end point of the traversal range, it is
  // always in the traversal range.
  if (aNode->IsNodeOfType(nsINode::eDATA_NODE) &&
      (aNode == aStartNode || aNode == aEndNode)) {
  if (aNode == aStartNode || aNode == aEndNode) {
    if (aNode->IsNodeOfType(nsINode::eDATA_NODE)) {
      return true; // text node or something
    }
    if (!aNode->HasChildren()) {
      MOZ_ASSERT(aNode != aStartNode || !aStartOffset,
        "aStartNode doesn't have children and not a data node, "
        "aStartOffset should be 0");
      MOZ_ASSERT(aNode != aEndNode || !aEndOffset,
        "aStartNode doesn't have children and not a data node, "
        "aStartOffset should be 0");
      return true;
    }
  }

  nsINode* parent = aNode->GetParentNode();
  if (!parent) {
@@ -341,12 +351,14 @@ nsContentIterator::Init(nsIDOMRange* aDOMRange)
      //      character in the cdata node, should we set mFirst to
      //      the next sibling?

      if (!startIsData) {
      // If the node has no child, the child may be <br> or something.
      // So, we shouldn't skip the empty node if the start offset is 0.
      // In other words, if the offset is 1, the node should be ignored.
      if (!startIsData && startIndx) {
        mFirst = GetNextSibling(startNode);

        // Does mFirst node really intersect the range?  The range could be
        // 'degenerate', i.e., not collapsed but still contain no content.

        if (mFirst && !NodeIsInTraversalRange(mFirst, mPre, startNode,
                                              startIndx, endNode, endIndx)) {
          mFirst = nullptr;
+607 −0

File changed.

Preview size limit exceeded, changes collapsed.

Loading