Loading accessible/windows/msaa/AccessibleWrap.cpp +64 −27 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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) { Loading Loading @@ -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; Loading browser/app/profile/firefox.js +8 −0 Original line number Diff line number Diff line Loading @@ -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); Loading dom/base/FragmentOrElement.cpp +1 −602 Original line number Diff line number Diff line Loading @@ -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("""); break; case '&': aOut.AppendLiteral("&"); break; case 0x00A0: aOut.AppendLiteral(" "); 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("<"); break; case '>': aOut.AppendLiteral(">"); break; case '&': aOut.AppendLiteral("&"); break; case 0x00A0: aOut.AppendLiteral(" "); 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("<"); break; case '>': aOut.AppendLiteral(">"); break; case '&': aOut.AppendLiteral("&"); break; case 0x00A0: aOut.AppendLiteral(" "); 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("<") - 2; break; case '>': extraSpaceNeeded += ArrayLength(">") - 2; break; case '&': extraSpaceNeeded += ArrayLength("&") - 2; break; case 0x00A0: extraSpaceNeeded += ArrayLength(" ") - 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("<") - 2; break; case '>': extraSpaceNeeded += ArrayLength(">") - 2; break; case '&': extraSpaceNeeded += ArrayLength("&") - 2; break; case 0x00A0: extraSpaceNeeded += ArrayLength(" ") - 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(""") - 2; break; case '&': extraSpaceNeeded += ArrayLength("&") - 2; break; case 0x00A0: extraSpaceNeeded += ArrayLength(" ") - 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) { Loading Loading @@ -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) Loading @@ -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) { Loading @@ -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; } Loading dom/base/nsContentIterator.cpp +18 −6 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; Loading dom/base/nsContentUtils.cpp +607 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
accessible/windows/msaa/AccessibleWrap.cpp +64 −27 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); Loading Loading @@ -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; Loading @@ -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; } Loading Loading @@ -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) { Loading Loading @@ -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; Loading
browser/app/profile/firefox.js +8 −0 Original line number Diff line number Diff line Loading @@ -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); Loading
dom/base/FragmentOrElement.cpp +1 −602 Original line number Diff line number Diff line Loading @@ -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("""); break; case '&': aOut.AppendLiteral("&"); break; case 0x00A0: aOut.AppendLiteral(" "); 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("<"); break; case '>': aOut.AppendLiteral(">"); break; case '&': aOut.AppendLiteral("&"); break; case 0x00A0: aOut.AppendLiteral(" "); 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("<"); break; case '>': aOut.AppendLiteral(">"); break; case '&': aOut.AppendLiteral("&"); break; case 0x00A0: aOut.AppendLiteral(" "); 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("<") - 2; break; case '>': extraSpaceNeeded += ArrayLength(">") - 2; break; case '&': extraSpaceNeeded += ArrayLength("&") - 2; break; case 0x00A0: extraSpaceNeeded += ArrayLength(" ") - 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("<") - 2; break; case '>': extraSpaceNeeded += ArrayLength(">") - 2; break; case '&': extraSpaceNeeded += ArrayLength("&") - 2; break; case 0x00A0: extraSpaceNeeded += ArrayLength(" ") - 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(""") - 2; break; case '&': extraSpaceNeeded += ArrayLength("&") - 2; break; case 0x00A0: extraSpaceNeeded += ArrayLength(" ") - 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) { Loading Loading @@ -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) Loading @@ -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) { Loading @@ -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; } Loading
dom/base/nsContentIterator.cpp +18 −6 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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; Loading
dom/base/nsContentUtils.cpp +607 −0 File changed.Preview size limit exceeded, changes collapsed. Show changes