Merge inbound to m-c. a=merge

This commit is contained in:
Ryan VanderMeulen 2014-08-11 16:10:07 -04:00
commit 552da54d71
73 changed files with 1077 additions and 560 deletions

View File

@ -122,9 +122,10 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eOpenCloseAction,
eNoLiveAttr,
kGenericAccType,
states::COLLAPSED | states::HASPOPUP,
states::COLLAPSED | states::HASPOPUP | states::VERTICAL,
eARIAAutoComplete,
eARIAReadonly
eARIAReadonly,
eARIAOrientation
},
{ // dialog
&nsGkAtoms::dialog,
@ -261,10 +262,11 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
eListControl | eSelect,
kNoReqStates,
states::VERTICAL,
eARIAMultiSelectable,
eARIAReadonly,
eFocusableUntilDisabled
eFocusableUntilDisabled,
eARIAOrientation
},
{ // listitem
&nsGkAtoms::listitem,
@ -315,7 +317,8 @@ static nsRoleMapEntry sWAIRoleMaps[] =
// any action, but menu can be open or close.
eNoLiveAttr,
kGenericAccType,
kNoReqStates
states::VERTICAL,
eARIAOrientation
},
{ // menubar
&nsGkAtoms::menubar,
@ -325,7 +328,8 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
states::HORIZONTAL,
eARIAOrientation
},
{ // menuitem
&nsGkAtoms::menuitem,
@ -422,7 +426,8 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
kNoReqStates,
eARIAOrientation
},
{ // region
&nsGkAtoms::region,
@ -475,7 +480,7 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
states::VERTICAL,
eARIAOrientation,
eARIAReadonly
},
@ -487,7 +492,7 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
states::HORIZONTAL,
eARIAOrientation
},
{ // slider
@ -498,7 +503,7 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates,
states::HORIZONTAL,
eARIAOrientation,
eARIAReadonly
},
@ -542,7 +547,8 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
eSelect,
kNoReqStates
states::HORIZONTAL,
eARIAOrientation
},
{ // tabpanel
&nsGkAtoms::tabpanel,
@ -584,7 +590,8 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
kGenericAccType,
kNoReqStates
states::HORIZONTAL,
eARIAOrientation
},
{ // tooltip
&nsGkAtoms::tooltip,
@ -604,10 +611,11 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
eSelect,
kNoReqStates,
states::VERTICAL,
eARIAReadonly,
eARIAMultiSelectable,
eFocusableUntilDisabled
eFocusableUntilDisabled,
eARIAOrientation
},
{ // treegrid
&nsGkAtoms::treegrid,
@ -617,10 +625,11 @@ static nsRoleMapEntry sWAIRoleMaps[] =
eNoAction,
eNoLiveAttr,
eSelect | eTable,
kNoReqStates,
states::VERTICAL,
eARIAReadonlyOrEditable,
eARIAMultiSelectable,
eFocusableUntilDisabled
eFocusableUntilDisabled,
eARIAOrientation
},
{ // treeitem
&nsGkAtoms::treeitem,

View File

@ -180,6 +180,7 @@ struct nsRoleMapEntry
mozilla::a11y::aria::EStateRule attributeMap1;
mozilla::a11y::aria::EStateRule attributeMap2;
mozilla::a11y::aria::EStateRule attributeMap3;
mozilla::a11y::aria::EStateRule attributeMap4;
};

View File

@ -19,39 +19,18 @@ using namespace mozilla::a11y::aria;
*/
struct EnumTypeData
{
EnumTypeData(nsIAtom* aAttrName,
nsIAtom** aValue1, uint64_t aState1,
nsIAtom** aValue2, uint64_t aState2,
nsIAtom** aValue3 = 0, uint64_t aState3 = 0) :
mState1(aState1), mState2(aState2), mState3(aState3), mDefaultState(0),
mAttrName(aAttrName), mValue1(aValue1), mValue2(aValue2), mValue3(aValue3),
mNullValue(nullptr)
{ }
EnumTypeData(nsIAtom* aAttrName, uint64_t aDefaultState,
nsIAtom** aValue1, uint64_t aState1) :
mState1(aState1), mState2(0), mState3(0), mDefaultState(aDefaultState),
mAttrName(aAttrName), mValue1(aValue1), mValue2(nullptr), mValue3(nullptr),
mNullValue(nullptr)
{ }
// States applied if corresponding enum values are matched.
const uint64_t mState1;
const uint64_t mState2;
const uint64_t mState3;
// Default state if no one enum value is matched.
const uint64_t mDefaultState;
// ARIA attribute name.
nsIAtom* const mAttrName;
// States if the attribute value is matched to the enum value. Used as
// nsIContent::AttrValuesArray.
nsIAtom* const* const mValue1;
nsIAtom* const* const mValue2;
nsIAtom* const* const mValue3;
nsIAtom* const* const mNullValue;
// nsIContent::AttrValuesArray, last item must be nullptr.
nsIAtom* const* const mValues[4];
// States applied if corresponding enum values are matched.
const uint64_t mStates[3];
// States to clear in case of match.
const uint64_t mClearState;
};
enum ETokenType
@ -108,11 +87,15 @@ aria::MapToState(EStateRule aRule, dom::Element* aElement, uint64_t* aState)
switch (aRule) {
case eARIAAutoComplete:
{
static const EnumTypeData data(
static const EnumTypeData data = {
nsGkAtoms::aria_autocomplete,
&nsGkAtoms::inlinevalue, states::SUPPORTS_AUTOCOMPLETION,
&nsGkAtoms::list, states::HASPOPUP | states::SUPPORTS_AUTOCOMPLETION,
&nsGkAtoms::both, states::HASPOPUP | states::SUPPORTS_AUTOCOMPLETION);
{ &nsGkAtoms::inlinevalue,
&nsGkAtoms::list,
&nsGkAtoms::both, nullptr },
{ states::SUPPORTS_AUTOCOMPLETION,
states::HASPOPUP | states::SUPPORTS_AUTOCOMPLETION,
states::HASPOPUP | states::SUPPORTS_AUTOCOMPLETION }, 0
};
MapEnumType(aElement, aState, data);
return true;
@ -120,10 +103,13 @@ aria::MapToState(EStateRule aRule, dom::Element* aElement, uint64_t* aState)
case eARIABusy:
{
static const EnumTypeData data(
static const EnumTypeData data = {
nsGkAtoms::aria_busy,
&nsGkAtoms::_true, states::BUSY,
&nsGkAtoms::error, states::INVALID);
{ &nsGkAtoms::_true,
&nsGkAtoms::error, nullptr },
{ states::BUSY,
states::INVALID }, 0
};
MapEnumType(aElement, aState, data);
return true;
@ -221,23 +207,16 @@ aria::MapToState(EStateRule aRule, dom::Element* aElement, uint64_t* aState)
case eARIAOrientation:
{
if (aElement->AttrValueIs(kNameSpaceID_None, nsGkAtoms::aria_orientation,
NS_LITERAL_STRING("horizontal"), eCaseMatters)) {
*aState &= ~states::VERTICAL;
*aState |= states::HORIZONTAL;
} else if (aElement->AttrValueIs(kNameSpaceID_None,
nsGkAtoms::aria_orientation,
NS_LITERAL_STRING("vertical"),
eCaseMatters)) {
*aState &= ~states::HORIZONTAL;
*aState |= states::VERTICAL;
} else {
NS_ASSERTION(!(*aState & (states::HORIZONTAL | states::VERTICAL)),
"orientation state on role with default aria-orientation!");
*aState |= GetRoleMap(aElement)->Is(nsGkAtoms::scrollbar) ?
states::VERTICAL : states::HORIZONTAL;
}
static const EnumTypeData data = {
nsGkAtoms::aria_orientation,
{ &nsGkAtoms::horizontal,
&nsGkAtoms::vertical, nullptr },
{ states::HORIZONTAL,
states::VERTICAL },
states::HORIZONTAL | states::VERTICAL
};
MapEnumType(aElement, aState, data);
return true;
}
@ -347,19 +326,17 @@ static void
MapEnumType(dom::Element* aElement, uint64_t* aState, const EnumTypeData& aData)
{
switch (aElement->FindAttrValueIn(kNameSpaceID_None, aData.mAttrName,
&aData.mValue1, eCaseMatters)) {
aData.mValues, eCaseMatters)) {
case 0:
*aState |= aData.mState1;
*aState = (*aState & ~aData.mClearState) | aData.mStates[0];
return;
case 1:
*aState |= aData.mState2;
*aState = (*aState & ~aData.mClearState) | aData.mStates[1];
return;
case 2:
*aState |= aData.mState3;
*aState = (*aState & ~aData.mClearState) | aData.mStates[2];
return;
}
*aState |= aData.mDefaultState;
}
static void

View File

@ -1592,8 +1592,9 @@ Accessible::ApplyARIAState(uint64_t* aState) const
*aState |= mRoleMapEntry->state;
if (aria::MapToState(mRoleMapEntry->attributeMap1, element, aState) &&
aria::MapToState(mRoleMapEntry->attributeMap2, element, aState))
aria::MapToState(mRoleMapEntry->attributeMap3, element, aState);
aria::MapToState(mRoleMapEntry->attributeMap2, element, aState) &&
aria::MapToState(mRoleMapEntry->attributeMap3, element, aState))
aria::MapToState(mRoleMapEntry->attributeMap4, element, aState);
// ARIA gridcell inherits editable/readonly states from the grid until it's
// overridden.

View File

@ -749,7 +749,9 @@ PivotContext.prototype = {
if (this._includeInvisible) {
include = true;
} else {
include = !(Utils.getState(child).contains(States.INVISIBLE));
// Need to account for aria-hidden, so can't just check for INVISIBLE
// state.
include = Utils.getAttributes(child).hidden !== 'true';
}
if (include) {
if (aPreorder) {

View File

@ -388,6 +388,13 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
expectedBraille: [
[{"string": "listboxoptionAbbr"}, "Search suggestion"],
["Search suggestion", {"string": "listboxoptionAbbr"}]]
}, {
accOrElmOrID: "listbox-option2",
oldAccOrElmOrID: "listbox-option",
expectedUtterance: [[{"string": "listboxoption"}, "555-12345"],
["555-12345", {"string": "listboxoption"}]],
expectedBraille: [[{"string": "listboxoptionAbbr"}, "555-12345"],
["555-12345", {"string": "listboxoptionAbbr"}]]
}];
// Test all possible utterance order preference values.
@ -507,6 +514,12 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
<div id="togglebutton_pressed" aria-pressed="true" role="button" tabindex="-1">I am pressed!</div>
<ul role="listbox" style="list-style-type: none;">
<li role="option" id="listbox-option">Search suggestion</li>
<li role="option" id="listbox-option2">
<label aria-hidden="true">
<input type="checkbox" />
</label>
555-12345
</li>
</ul>
</div>
</body>

View File

@ -48,7 +48,7 @@
children = acc.children;
} catch(e) {}
ok(children, "Could not get children for " + aAccOrElmOrID +"!");
if (children) {
for (var i = 0; i < children.length; i++) {
var childAcc = children.queryElementAt(i, nsIAccessible);
@ -213,7 +213,22 @@
testStates("aria_main_anchor", STATE_SELECTABLE);
testStates("aria_navigation_anchor", STATE_SELECTABLE);
// aria-orientation (applied to scrollbar, separator, slider)
// aria-orientation
testStates("aria_combobox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_hcombobox", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vcombobox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_listbox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_hlistbox", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vlistbox", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_menu", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_hmenu", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vmenu", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_menubar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_hmenubar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vmenubar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_radiogroup", 0, 0, 0, EXT_STATE_HORIZONTAL | EXT_STATE_VERTICAL);
testStates("aria_hradiogroup", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vradiogroup", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_scrollbar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_hscrollbar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vscrollbar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
@ -223,6 +238,18 @@
testStates("aria_slider", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_hslider", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vslider", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_tablist", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_htablist", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vtablist", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_toolbar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_htoolbar", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vtoolbar", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_tree", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_htree", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vtree", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_treegrid", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
testStates("aria_htreegrid", 0, EXT_STATE_HORIZONTAL, 0, EXT_STATE_VERTICAL);
testStates("aria_vtreegrid", 0, EXT_STATE_VERTICAL, 0, EXT_STATE_HORIZONTAL);
// indeterminate ARIA progressbars (no aria-valuenow or aria-valuetext attribute)
// should expose mixed state
@ -498,6 +525,21 @@
<a id="aria_navigation_anchor" role="navigation" name="nav_anchor">nav</a>
<!-- aria-orientation -->
<div id="aria_combobox" role="combobox">combobox</div>
<div id="aria_hcombobox" role="combobox" aria-orientation="horizontal">horizontal combobox</div>
<div id="aria_vcombobox" role="combobox" aria-orientation="vertical">vertical combobox</div>
<div id="aria_listbox" role="listbox">listbox</div>
<div id="aria_hlistbox" role="listbox" aria-orientation="horizontal">horizontal listbox</div>
<div id="aria_vlistbox" role="listbox" aria-orientation="vertical">vertical listbox</div>
<div id="aria_menu" role="menu">menu</div>
<div id="aria_hmenu" role="menu" aria-orientation="horizontal">horizontal menu</div>
<div id="aria_vmenu" role="menu" aria-orientation="vertical">vertical menu</div>
<div id="aria_menubar" role="menubar">menubar</div>
<div id="aria_hmenubar" role="menubar" aria-orientation="horizontal">horizontal menubar</div>
<div id="aria_vmenubar" role="menubar" aria-orientation="vertical">vertical menubar</div>
<div id="aria_radiogroup" role="radiogroup">radiogroup</div>
<div id="aria_hradiogroup" role="radiogroup" aria-orientation="horizontal">horizontal radiogroup</div>
<div id="aria_vradiogroup" role="radiogroup" aria-orientation="vertical">vertical radiogroup</div>
<div id="aria_scrollbar" role="scrollbar">scrollbar</div>
<div id="aria_hscrollbar" role="scrollbar" aria-orientation="horizontal">horizontal scrollbar</div>
<div id="aria_vscrollbar" role="scrollbar" aria-orientation="vertical">vertical scrollbar</div>
@ -507,7 +549,20 @@
<div id="aria_slider" role="slider">slider</div>
<div id="aria_hslider" role="slider" aria-orientation="horizontal">horizontal slider</div>
<div id="aria_vslider" role="slider" aria-orientation="vertical">vertical slider</div>
<div id="aria_tablist" role="tablist">tablist</div>
<div id="aria_htablist" role="tablist" aria-orientation="horizontal">horizontal tablist</div>
<div id="aria_vtablist" role="tablist" aria-orientation="vertical">vertical tablist</div>
<div id="aria_toolbar" role="toolbar">toolbar</div>
<div id="aria_htoolbar" role="toolbar" aria-orientation="horizontal">horizontal toolbar</div>
<div id="aria_vtoolbar" role="toolbar" aria-orientation="vertical">vertical toolbar</div>
<div id="aria_tree" role="tree">tree</div>
<div id="aria_htree" role="tree" aria-orientation="horizontal">horizontal tree</div>
<div id="aria_vtree" role="tree" aria-orientation="vertical">vertical tree</div>
<div id="aria_treegrid" role="treegrid">treegrid</div>
<div id="aria_htreegrid" role="treegrid" aria-orientation="horizontal">horizontal treegrid</div>
<div id="aria_vtreegrid" role="treegrid" aria-orientation="vertical">vertical treegrid</div>
<!-- indeterminate ARIA progressbars should expose mixed state -->
<div id="aria_progressbar" role="progressbar"></div>
<div id="aria_progressbar_valuenow" role="progressbar" aria-valuenow="1"></div>

View File

@ -15,28 +15,7 @@ import sys
import tempfile
from urlparse import urlparse
import zipfile
try:
import mozinfo
except ImportError:
# Stub out fake mozinfo since this is not importable on Android 4.0 Opt.
# This should be fixed; see
# https://bugzilla.mozilla.org/show_bug.cgi?id=650881
mozinfo = type('mozinfo', (), dict(info={}))()
mozinfo.isWin = mozinfo.isLinux = mozinfo.isUnix = mozinfo.isMac = False
# TODO! FILE: localautomation :/
# mapping from would-be mozinfo attr <-> sys.platform
mapping = {'isMac': ['mac', 'darwin'],
'isLinux': ['linux', 'linux2'],
'isWin': ['win32', 'win64'],
}
mapping = dict(sum([[(value, key) for value in values] for key, values in mapping.items()], []))
attr = mapping.get(sys.platform)
if attr:
setattr(mozinfo, attr, True)
if mozinfo.isLinux:
mozinfo.isUnix = True
import mozinfo
__all__ = [
"ZipFileReader",

View File

@ -192,44 +192,29 @@ ASSERT_NODE_FLAGS_SPACE(NODE_TYPE_SPECIFIC_BITS_OFFSET);
* nsMutationGuard on the stack before unexpected mutations could occur.
* You can then at any time call Mutated to check if any unexpected mutations
* have occurred.
*
* When a guard is instantiated sMutationCount is set to 300. It is then
* decremented by every mutation (capped at 0). This means that we can only
* detect 300 mutations during the lifetime of a single guard, however that
* should be more then we ever care about as we usually only care if more then
* one mutation has occurred.
*
* When the guard goes out of scope it will adjust sMutationCount so that over
* the lifetime of the guard the guard itself has not affected sMutationCount,
* while mutations that happened while the guard was alive still will. This
* allows a guard to be instantiated even if there is another guard higher up
* on the callstack watching for mutations.
*
* The only thing that has to be avoided is for an outer guard to be used
* while an inner guard is alive. This can be avoided by only ever
* instantiating a single guard per scope and only using the guard in the
* current scope.
*/
class nsMutationGuard {
public:
nsMutationGuard()
{
mDelta = eMaxMutations - sMutationCount;
sMutationCount = eMaxMutations;
}
~nsMutationGuard()
{
sMutationCount =
mDelta > sMutationCount ? 0 : sMutationCount - mDelta;
mStartingGeneration = sGeneration;
}
/**
* Returns true if any unexpected mutations have occurred. You can pass in
* an 8-bit ignore count to ignore a number of expected mutations.
*
* We don't need to care about overflow because subtraction of uint64_t's is
* finding the difference between two elements of the group Z < 2^64. Once
* we know the difference between two elements we only need to check that is
* less than the given number of mutations to know less than that many
* mutations occured. Assuming constant 1ns mutations it would take 584
* years for sGeneration to fully wrap around so we can ignore a guard living
* through a full wrap around.
*/
bool Mutated(uint8_t aIgnoreCount)
{
return sMutationCount < static_cast<uint32_t>(eMaxMutations - aIgnoreCount);
return (sGeneration - mStartingGeneration) > aIgnoreCount;
}
// This function should be called whenever a mutation that we want to keep
@ -237,26 +222,15 @@ public:
// removed, but we might do it for attribute changes too in the future.
static void DidMutate()
{
if (sMutationCount) {
--sMutationCount;
}
sGeneration++;
}
private:
// mDelta is the amount sMutationCount was adjusted when the guard was
// initialized. It is needed so that we can undo that adjustment once
// the guard dies.
uint32_t mDelta;
// This is the value sGeneration had when the guard was constructed.
uint64_t mStartingGeneration;
// The value 300 is not important, as long as it is bigger then anything
// ever passed to Mutated().
enum { eMaxMutations = 300 };
// sMutationCount is a global mutation counter which is decreased by one at
// every mutation. It is capped at 0 to avoid wrapping.
// Its value is always between 0 and 300, inclusive.
static uint32_t sMutationCount;
// This value is incremented on every mutation, for the life of the process.
static uint64_t sGeneration;
};
// This should be used for any nsINode sub-class that has fields of its own

View File

@ -132,7 +132,7 @@ using namespace mozilla::dom;
int32_t nsIContent::sTabFocusModel = eTabFocus_any;
bool nsIContent::sTabFocusModelAppliesToXUL = false;
uint32_t nsMutationGuard::sMutationCount = 0;
uint64_t nsMutationGuard::sGeneration = 0;
nsIContent*
nsIContent::FindFirstNonChromeOnlyAccessContent() const

View File

@ -2054,7 +2054,7 @@ GK_ATOM(az, "az")
GK_ATOM(ba, "ba")
GK_ATOM(crh, "crh")
GK_ATOM(el, "el")
GK_ATOM(ga_ie, "ga-ie")
GK_ATOM(ga, "ga")
GK_ATOM(nl, "nl")
// Names for editor transactions

View File

@ -3592,11 +3592,13 @@ nsXMLHttpRequest::OnProgress(nsIRequest *aRequest, nsISupports *aContext, uint64
// So, try to remove the headers, if possible.
bool lengthComputable = (aProgressMax != UINT64_MAX);
if (upload) {
mUploadTransferred = aProgress;
uint64_t loaded = aProgress;
if (lengthComputable) {
mUploadTransferred = aProgressMax - mUploadTotal;
uint64_t headerSize = aProgressMax - mUploadTotal;
loaded -= headerSize;
}
mUploadLengthComputable = lengthComputable;
mUploadTransferred = loaded;
mProgressSinceLastProgressEvent = true;
MaybeDispatchProgressEvents(false);

View File

@ -3654,10 +3654,14 @@ already_AddRefed<TimeRanges>
HTMLMediaElement::Buffered() const
{
nsRefPtr<TimeRanges> ranges = new TimeRanges();
if (mDecoder && mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING) {
// If GetBuffered fails we ignore the error result and just return the
// time ranges we found up till the error.
mDecoder->GetBuffered(ranges);
if (mReadyState > nsIDOMHTMLMediaElement::HAVE_NOTHING) {
if (mMediaSource) {
mMediaSource->GetBuffered(ranges);
} else if (mDecoder) {
// If GetBuffered fails we ignore the error result and just return the
// time ranges we found up till the error.
mDecoder->GetBuffered(ranges);
}
}
ranges->Normalize();
return ranges.forget();

View File

@ -126,6 +126,35 @@ TimeRanges::Normalize()
}
}
void
TimeRanges::Union(const TimeRanges* aOtherRanges)
{
mRanges.AppendElements(aOtherRanges->mRanges);
Normalize();
}
void
TimeRanges::Intersection(const TimeRanges* aOtherRanges)
{
nsAutoTArray<TimeRange,4> intersection;
const nsTArray<TimeRange>& otherRanges = aOtherRanges->mRanges;
for (index_type i = 0, j = 0; i < mRanges.Length() && j < otherRanges.Length();) {
double start = std::max(mRanges[i].mStart, otherRanges[j].mStart);
double end = std::min(mRanges[i].mEnd, otherRanges[j].mEnd);
if (start < end) {
intersection.AppendElement(TimeRange(start, end));
}
if (mRanges[i].mEnd < otherRanges[j].mEnd) {
i += 1;
} else {
j += 1;
}
}
mRanges = intersection;
}
TimeRanges::index_type
TimeRanges::Find(double aTime)
{

View File

@ -44,6 +44,12 @@ public:
// See http://www.whatwg.org/html/#normalized-timeranges-object
void Normalize();
// Mutate this TimeRange to be the union of this and aOtherRanges.
void Union(const TimeRanges* aOtherRanges);
// Mutate this TimeRange to be the intersection of this and aOtherRanges.
void Intersection(const TimeRanges* aOtherRanges);
JSObject* WrapObject(JSContext* aCx);
uint32_t Length() const

View File

@ -15,6 +15,7 @@
#include "mozilla/Preferences.h"
#include "mozilla/dom/BindingDeclarations.h"
#include "mozilla/dom/HTMLMediaElement.h"
#include "mozilla/dom/TimeRanges.h"
#include "mozilla/mozalloc.h"
#include "nsContentTypeParser.h"
#include "nsDebug.h"
@ -329,6 +330,42 @@ MediaSource::Detach()
SetReadyState(MediaSourceReadyState::Closed);
}
void
MediaSource::GetBuffered(TimeRanges* aBuffered)
{
if (mActiveSourceBuffers->IsEmpty()) {
return;
}
nsTArray<nsRefPtr<TimeRanges>> ranges;
for (uint32_t i = 0; i < mActiveSourceBuffers->Length(); ++i) {
bool found;
SourceBuffer* sourceBuffer = mActiveSourceBuffers->IndexedGetter(i, found);
ErrorResult dummy;
*ranges.AppendElement() = sourceBuffer->GetBuffered(dummy);
}
double highestEndTime = mActiveSourceBuffers->GetHighestBufferedEndTime();
if (highestEndTime <= 0) {
return;
}
MOZ_ASSERT(aBuffered->Length() == 0);
aBuffered->Add(0, highestEndTime);
for (uint32_t i = 0; i < ranges.Length(); ++i) {
if (mReadyState == MediaSourceReadyState::Ended) {
ranges[i]->Add(ranges[i]->GetEndTime(), highestEndTime);
}
aBuffered->Intersection(ranges[i]);
}
MSE_DEBUG("MediaSource(%p)::GetBuffered start=%f end=%f length=%u",
this, aBuffered->GetStartTime(), aBuffered->GetEndTime(), aBuffered->Length());
}
MediaSource::MediaSource(nsPIDOMWindow* aWindow)
: DOMEventTargetHelper(aWindow)
, mDuration(UnspecifiedNaN<double>())

View File

@ -75,6 +75,8 @@ public:
bool Attach(MediaSourceDecoder* aDecoder);
void Detach();
void GetBuffered(TimeRanges* aBuffered);
// Set mReadyState to aState and fire the required events at the MediaSource.
void SetReadyState(MediaSourceReadyState aState);

View File

@ -156,7 +156,6 @@ public:
nsresult ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags) MOZ_OVERRIDE;
nsresult Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
int64_t aCurrentTime) MOZ_OVERRIDE;
nsresult GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime) MOZ_OVERRIDE;
already_AddRefed<SubBufferDecoder> CreateSubDecoder(const nsACString& aType,
MediaSourceDecoder* aParentDecoder,
MediaTaskQueue* aTaskQueue);
@ -346,7 +345,7 @@ MediaSourceDecoder::GetSeekable(dom::TimeRanges* aSeekable)
// Return empty range.
} else if (duration > 0 && mozilla::IsInfinite(duration)) {
nsRefPtr<dom::TimeRanges> bufferedRanges = new dom::TimeRanges();
GetBuffered(bufferedRanges);
mMediaSource->GetBuffered(bufferedRanges);
aSeekable->Add(bufferedRanges->GetStartTime(), bufferedRanges->GetEndTime());
} else {
aSeekable->Add(0, duration);
@ -577,23 +576,6 @@ MediaSourceReader::Seek(int64_t aTime, int64_t aStartTime, int64_t aEndTime,
return NS_OK;
}
nsresult
MediaSourceReader::GetBuffered(dom::TimeRanges* aBuffered, int64_t aStartTime)
{
for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
nsRefPtr<dom::TimeRanges> r = new dom::TimeRanges();
mDecoders[i]->GetBuffered(r);
MSE_DEBUGV("MediaSourceReader(%p)::GetBuffered i=%u start=%f end=%f%s",
this, i, r->GetStartTime(), r->GetEndTime(),
mDecoders[i]->IsDiscarded() ? " [discarded]" : "");
aBuffered->Add(r->GetStartTime(), r->GetEndTime());
}
aBuffered->Normalize();
MSE_DEBUGV("MediaSourceReader(%p)::GetBuffered start=%f end=%f ranges=%u",
this, aBuffered->GetStartTime(), aBuffered->GetEndTime(), aBuffered->Length());
return NS_OK;
}
nsresult
MediaSourceReader::ReadMetadata(MediaInfo* aInfo, MetadataTags** aTags)
{

View File

@ -31,9 +31,11 @@ extern PRLogModuleInfo* GetMediaSourceLog();
extern PRLogModuleInfo* GetMediaSourceAPILog();
#define MSE_DEBUG(...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG, (__VA_ARGS__))
#define MSE_DEBUGV(...) PR_LOG(GetMediaSourceLog(), PR_LOG_DEBUG+1, (__VA_ARGS__))
#define MSE_API(...) PR_LOG(GetMediaSourceAPILog(), PR_LOG_DEBUG, (__VA_ARGS__))
#else
#define MSE_DEBUG(...)
#define MSE_DEBUGV(...)
#define MSE_API(...)
#endif
@ -171,12 +173,17 @@ SourceBuffer::GetBuffered(ErrorResult& aRv)
return nullptr;
}
nsRefPtr<TimeRanges> ranges = new TimeRanges();
if (mDecoder) {
mDecoder->GetBuffered(ranges);
// TODO: Need to adjust mDecoders so it only tracks active decoders.
// Once we have an abstraction for track buffers, this needs to report the
// intersection of buffered ranges within those track buffers.
for (uint32_t i = 0; i < mDecoders.Length(); ++i) {
nsRefPtr<TimeRanges> r = new TimeRanges();
mDecoders[i]->GetBuffered(r);
ranges->Union(r);
}
ranges->Normalize();
MSE_DEBUG("SourceBuffer(%p)::GetBuffered startTime=%f endTime=%f",
this, ranges->GetStartTime(), ranges->GetEndTime());
MSE_DEBUGV("SourceBuffer(%p)::GetBuffered startTime=%f endTime=%f length=%u",
this, ranges->GetStartTime(), ranges->GetEndTime(), ranges->Length());
return ranges.forget();
}
@ -369,6 +376,7 @@ SourceBuffer::InitNewDecoder()
}
mDecoder = decoder;
mDecoderInitialized = false;
mDecoders.AppendElement(mDecoder);
return true;
}
@ -467,16 +475,12 @@ SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aR
const uint32_t evict_threshold = 75 * (1 << 20);
bool evicted = mDecoder->GetResource()->EvictData(evict_threshold);
if (evicted) {
double start = 0.0;
double end = 0.0;
GetBufferedStartEndTime(&start, &end);
MSE_DEBUG("SourceBuffer(%p)::AppendBuffer Evict; current start=%f end=%f",
this, start, end);
MSE_DEBUG("SourceBuffer(%p)::AppendBuffer Evict; current buffered start=%f",
this, GetBufferedStart());
// We notify that we've evicted from the time range 0 through to
// the current start point.
mMediaSource->NotifyEvicted(0.0, start);
mMediaSource->NotifyEvicted(0.0, GetBufferedStart());
}
StopUpdating();
@ -487,18 +491,22 @@ SourceBuffer::AppendData(const uint8_t* aData, uint32_t aLength, ErrorResult& aR
mMediaSource->NotifyGotData();
}
void
SourceBuffer::GetBufferedStartEndTime(double* aStart, double* aEnd)
double
SourceBuffer::GetBufferedStart()
{
MOZ_ASSERT(NS_IsMainThread());
ErrorResult dummy;
nsRefPtr<TimeRanges> ranges = GetBuffered(dummy);
if (!ranges || ranges->Length() == 0) {
*aStart = *aEnd = 0.0;
return;
}
*aStart = ranges->GetStartTime();
*aEnd = ranges->GetEndTime();
return ranges->Length() > 0 ? ranges->GetStartTime() : 0;
}
double
SourceBuffer::GetBufferedEnd()
{
MOZ_ASSERT(NS_IsMainThread());
ErrorResult dummy;
nsRefPtr<TimeRanges> ranges = GetBuffered(dummy);
return ranges->Length() > 0 ? ranges->GetEndTime() : 0;
}
void

View File

@ -111,9 +111,8 @@ public:
// Returns true if the data in the source buffer contains the given time.
bool ContainsTime(double aTime);
// Provide the minimum start time and maximum end time that is available
// in the data buffered by this SourceBuffer.
void GetBufferedStartEndTime(double* aStart, double* aEnd);
double GetBufferedStart();
double GetBufferedEnd();
private:
~SourceBuffer();
@ -146,6 +145,7 @@ private:
nsAutoPtr<ContainerParser> mParser;
nsRefPtr<SubBufferDecoder> mDecoder;
nsTArray<nsRefPtr<SubBufferDecoder>> mDecoders;
double mAppendWindowStart;
double mAppendWindowEnd;

View File

@ -158,9 +158,7 @@ SourceBufferList::GetHighestBufferedEndTime()
MOZ_ASSERT(NS_IsMainThread());
double highestEnd = 0;
for (uint32_t i = 0; i < mSourceBuffers.Length(); ++i) {
double start, end;
mSourceBuffers[i]->GetBufferedStartEndTime(&start, &end);
highestEnd = std::max(highestEnd, end);
highestEnd = std::max(highestEnd, mSourceBuffers[i]->GetBufferedEnd());
}
return highestEnd;
}

View File

@ -4,8 +4,9 @@
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DIRS += ['gmp-plugin']
if CONFIG['MOZ_WEBRTC']:
DIRS += ['bridge', 'gmp-plugin']
DIRS += ['bridge']
LOCAL_INCLUDES += [
'/media/webrtc/signaling/src/common',

View File

@ -5,16 +5,20 @@
#include "WorkerRunnable.h"
#include "nsGlobalWindow.h"
#include "nsIEventTarget.h"
#include "nsIGlobalObject.h"
#include "nsIRunnable.h"
#include "nsThreadUtils.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/dom/ScriptSettings.h"
#include "js/RootingAPI.h"
#include "js/Value.h"
#include "WorkerPrivate.h"
#include "WorkerScope.h"
USING_WORKERS_NAMESPACE
@ -258,9 +262,10 @@ WorkerRunnable::Run()
return NS_OK;
}
JSContext* cx;
nsCOMPtr<nsIGlobalObject> globalObject;
bool isMainThread = !targetIsWorkerThread && !mWorkerPrivate->GetParent();
MOZ_ASSERT(isMainThread == NS_IsMainThread());
nsRefPtr<WorkerPrivate> kungFuDeathGrip;
nsCxPusher pusher;
if (targetIsWorkerThread) {
if (mWorkerPrivate->AllPendingRunnablesShouldBeCanceled() &&
@ -280,44 +285,51 @@ WorkerRunnable::Run()
return NS_OK;
}
cx = mWorkerPrivate->GetJSContext();
MOZ_ASSERT(cx);
globalObject = mWorkerPrivate->GlobalScope();
}
else {
cx = mWorkerPrivate->ParentJSContext();
MOZ_ASSERT(cx);
kungFuDeathGrip = mWorkerPrivate;
if (!mWorkerPrivate->GetParent()) {
AssertIsOnMainThread();
pusher.Push(cx);
if (isMainThread) {
globalObject = static_cast<nsGlobalWindow*>(mWorkerPrivate->GetWindow());
} else {
globalObject = mWorkerPrivate->GetParent()->GlobalScope();
}
}
JSAutoRequest ar(cx);
JS::Rooted<JSObject*> targetCompartmentObject(cx);
if (targetIsWorkerThread) {
targetCompartmentObject = JS::CurrentGlobalOrNull(cx);
// We might run script as part of WorkerRun, so we need an AutoEntryScript.
// This is part of the HTML spec for workers at:
// http://www.whatwg.org/specs/web-apps/current-work/#run-a-worker
// If we don't have a globalObject we have to use an AutoJSAPI instead, but
// this is OK as we won't be running script in these circumstances.
// It's important that aes is declared after jsapi, because if WorkerRun
// creates a global then we construct aes before PostRun and we need them to
// be destroyed in the correct order.
mozilla::dom::AutoJSAPI jsapi;
Maybe<mozilla::dom::AutoEntryScript> aes;
JSContext* cx;
if (globalObject) {
aes.construct(globalObject, isMainThread, isMainThread ? nullptr :
GetCurrentThreadJSContext());
cx = aes.ref().cx();
} else {
targetCompartmentObject = mWorkerPrivate->GetWrapper();
jsapi.Init();
cx = jsapi.cx();
}
// If we're not on the worker thread we'll either be in our parent's
// compartment or the null compartment, so we need to enter our own.
Maybe<JSAutoCompartment> ac;
if (targetCompartmentObject) {
ac.construct(cx, targetCompartmentObject);
if (!targetIsWorkerThread && mWorkerPrivate->GetWrapper()) {
ac.construct(cx, mWorkerPrivate->GetWrapper());
}
bool result = WorkerRun(cx, mWorkerPrivate);
// In the case of CompileScriptRunnnable, WorkerRun above can cause us to
// lazily create a global, in which case we need to be in its compartment
// when calling PostRun() below. Maybe<> this time...
if (targetIsWorkerThread &&
ac.empty() &&
js::DefaultObjectForContextOrNull(cx)) {
ac.construct(cx, js::DefaultObjectForContextOrNull(cx));
// lazily create a global, so we construct aes here before calling PostRun.
if (targetIsWorkerThread && aes.empty() && mWorkerPrivate->GlobalScope()) {
aes.construct(mWorkerPrivate->GlobalScope(), false, GetCurrentThreadJSContext());
cx = aes.ref().cx();
}
PostRun(cx, mWorkerPrivate, result);

View File

@ -1,12 +0,0 @@
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
# XXX need configure test
EX_LIBS = $(shell $(GLIB_CONFIG) --libs)
include $(topsrcdir)/config/rules.mk
# XXX replace with proper configure test for glib
CFLAGS += $(shell $(GLIB_CONFIG) --cflags)

View File

@ -16,6 +16,7 @@
#endif
#include "mozilla/Assertions.h"
#include "mozilla/DebugOnly.h"
#include "nsDebug.h"
#include "nsISupportsImpl.h"
#include "nsXULAppAPI.h"
@ -376,7 +377,12 @@ ProcessLink::OnCloseChannel()
MonitorAutoLock lock(*mChan->mMonitor);
MOZ_ALWAYS_TRUE(this == mTransport->set_listener(mExistingListener));
DebugOnly<IPC::Channel::Listener*> previousListener =
mTransport->set_listener(mExistingListener);
// OnChannelError may have reset the listener already.
MOZ_ASSERT(previousListener == this ||
previousListener == mExistingListener);
mChan->mChannelState = ChannelClosed;
mChan->mMonitor->Notify();

View File

@ -260,7 +260,7 @@ class File(Node):
class CppDirective(Node):
'''represents |#[directive] [rest]|, where |rest| is any string'''
def __init__(self, directive, rest=''):
def __init__(self, directive, rest=None):
Node.__init__(self)
self.directive = directive
self.rest = rest

View File

@ -20,7 +20,10 @@ class CxxCodeGen(CodePrinter, Visitor):
self.write(ws.ws)
def visitCppDirective(self, cd):
self.println('#%s %s'% (cd.directive, cd.rest))
if cd.rest:
self.println('#%s %s'% (cd.directive, cd.rest))
else:
self.println('#%s'% (cd.directive))
def visitNamespace(self, ns):
self.println('namespace '+ ns.name +' {')

View File

@ -11,7 +11,6 @@
#include "mozilla/Assertions.h"
#include "mozilla/Attributes.h"
#include "mozilla/Casting.h"
#include "mozilla/DebugOnly.h"
#include "mozilla/MemoryReporting.h"
#include "mozilla/Move.h"
#include "mozilla/NullPtr.h"
@ -762,7 +761,7 @@ class HashTable : private AllocPolicy
void nonNull() {}
Entry *entry_;
#ifdef DEBUG
#ifdef JS_DEBUG
const HashTable *table_;
uint32_t generation;
#endif
@ -770,7 +769,7 @@ class HashTable : private AllocPolicy
protected:
Ptr(Entry &entry, const HashTable &tableArg)
: entry_(&entry)
#ifdef DEBUG
#ifdef JS_DEBUG
, table_(&tableArg)
, generation(tableArg.generation())
#endif
@ -785,7 +784,9 @@ class HashTable : private AllocPolicy
}
bool found() const {
#ifdef JS_DEBUG
MOZ_ASSERT(generation == table_->generation());
#endif
return entry_->isLive();
}
@ -799,17 +800,23 @@ class HashTable : private AllocPolicy
}
bool operator!=(const Ptr &rhs) const {
#ifdef JS_DEBUG
MOZ_ASSERT(generation == table_->generation());
#endif
return !(*this == rhs);
}
T &operator*() const {
#ifdef JS_DEBUG
MOZ_ASSERT(generation == table_->generation());
#endif
return entry_->get();
}
T *operator->() const {
#ifdef JS_DEBUG
MOZ_ASSERT(generation == table_->generation());
#endif
return &entry_->get();
}
};
@ -819,14 +826,14 @@ class HashTable : private AllocPolicy
{
friend class HashTable;
HashNumber keyHash;
#ifdef DEBUG
#ifdef JS_DEBUG
uint64_t mutationCount;
#endif
AddPtr(Entry &entry, const HashTable &tableArg, HashNumber hn)
: Ptr(entry, tableArg)
, keyHash(hn)
#ifdef DEBUG
#ifdef JS_DEBUG
, mutationCount(tableArg.mutationCount)
#endif
{}
@ -848,7 +855,7 @@ class HashTable : private AllocPolicy
Range(const HashTable &tableArg, Entry *c, Entry *e)
: cur(c)
, end(e)
#ifdef DEBUG
#ifdef JS_DEBUG
, table_(&tableArg)
, mutationCount(tableArg.mutationCount)
, generation(tableArg.generation())
@ -860,7 +867,7 @@ class HashTable : private AllocPolicy
}
Entry *cur, *end;
#ifdef DEBUG
#ifdef JS_DEBUG
const HashTable *table_;
uint64_t mutationCount;
uint32_t generation;
@ -871,7 +878,7 @@ class HashTable : private AllocPolicy
Range()
: cur(nullptr)
, end(nullptr)
#ifdef DEBUG
#ifdef JS_DEBUG
, table_(nullptr)
, mutationCount(0)
, generation(0)
@ -880,26 +887,32 @@ class HashTable : private AllocPolicy
{}
bool empty() const {
#ifdef JS_DEBUG
MOZ_ASSERT(generation == table_->generation());
MOZ_ASSERT(mutationCount == table_->mutationCount);
#endif
return cur == end;
}
T &front() const {
MOZ_ASSERT(validEntry);
MOZ_ASSERT(!empty());
#ifdef JS_DEBUG
MOZ_ASSERT(validEntry);
MOZ_ASSERT(generation == table_->generation());
MOZ_ASSERT(mutationCount == table_->mutationCount);
#endif
return cur->get();
}
void popFront() {
MOZ_ASSERT(!empty());
#ifdef JS_DEBUG
MOZ_ASSERT(generation == table_->generation());
MOZ_ASSERT(mutationCount == table_->mutationCount);
#endif
while (++cur < end && !cur->isLive())
continue;
#ifdef DEBUG
#ifdef JS_DEBUG
validEntry = true;
#endif
}
@ -936,7 +949,7 @@ class HashTable : private AllocPolicy
void removeFront() {
table_.remove(*this->cur);
removed = true;
#ifdef DEBUG
#ifdef JS_DEBUG
this->validEntry = false;
this->mutationCount = table_.mutationCount;
#endif
@ -949,7 +962,7 @@ class HashTable : private AllocPolicy
Ptr p(*this->cur, table_);
table_.rekeyWithoutRehash(p, l, k);
rekeyed = true;
#ifdef DEBUG
#ifdef JS_DEBUG
this->validEntry = false;
this->mutationCount = table_.mutationCount;
#endif
@ -1002,8 +1015,8 @@ class HashTable : private AllocPolicy
uint32_t hashShift:8; // multiplicative hash shift
#ifdef JS_DEBUG
mozilla::DebugOnly<uint64_t> mutationCount;
mutable mozilla::DebugOnly<bool> mEntered;
uint64_t mutationCount;
mutable bool mEntered;
mutable struct Stats
{
uint32_t searches; // total number of table searches
@ -1085,7 +1098,7 @@ class HashTable : private AllocPolicy
, entryCount(0)
, removedCount(0)
, hashShift(sHashBits)
#ifdef DEBUG
#ifdef JS_DEBUG
, mutationCount(0)
, mEntered(false)
#endif
@ -1375,7 +1388,7 @@ class HashTable : private AllocPolicy
e.clearLive();
}
entryCount--;
#ifdef DEBUG
#ifdef JS_DEBUG
mutationCount++;
#endif
}
@ -1460,15 +1473,16 @@ class HashTable : private AllocPolicy
}
removedCount = 0;
entryCount = 0;
#ifdef DEBUG
#ifdef JS_DEBUG
mutationCount++;
#endif
}
void finish()
{
#ifdef JS_DEBUG
MOZ_ASSERT(!mEntered);
#endif
if (!table)
return;
@ -1477,7 +1491,7 @@ class HashTable : private AllocPolicy
gen++;
entryCount = 0;
removedCount = 0;
#ifdef DEBUG
#ifdef JS_DEBUG
mutationCount++;
#endif
}
@ -1569,7 +1583,7 @@ class HashTable : private AllocPolicy
p.entry_->setLive(p.keyHash, mozilla::Forward<U>(u));
entryCount++;
#ifdef DEBUG
#ifdef JS_DEBUG
mutationCount++;
p.generation = generation();
p.mutationCount = mutationCount;
@ -1595,7 +1609,7 @@ class HashTable : private AllocPolicy
entry->setLive(keyHash, mozilla::Forward<U>(u));
entryCount++;
#ifdef DEBUG
#ifdef JS_DEBUG
mutationCount++;
#endif
}
@ -1617,7 +1631,7 @@ class HashTable : private AllocPolicy
template <class U>
bool relookupOrAdd(AddPtr& p, const Lookup &l, U &&u)
{
#ifdef DEBUG
#ifdef JS_DEBUG
p.generation = generation();
p.mutationCount = mutationCount;
#endif

View File

@ -3862,7 +3862,9 @@ Simulator::decodeSpecialCondition(SimInstruction *instr)
case 5:
if (instr->bits(18, 16) == 0 && instr->bits(11, 6) == 0x28 && instr->bit(4) == 1) {
// vmovl signed
int Vd = (instr->bit(22) << 4) | instr->vdValue();
if ((instr->vdValue() & 1) != 0)
MOZ_CRASH("Undefined behavior");
int Vd = (instr->bit(22) << 3) | (instr->vdValue() >> 1);
int Vm = (instr->bit(5) << 4) | instr->vmValue();
int imm3 = instr->bits(21, 19);
if (imm3 != 1 && imm3 != 2 && imm3 != 4)
@ -3885,7 +3887,9 @@ Simulator::decodeSpecialCondition(SimInstruction *instr)
case 7:
if (instr->bits(18, 16) == 0 && instr->bits(11, 6) == 0x28 && instr->bit(4) == 1) {
// vmovl unsigned.
int Vd = (instr->bit(22) << 4) | instr->vdValue();
if ((instr->vdValue() & 1) != 0)
MOZ_CRASH("Undefined behavior");
int Vd = (instr->bit(22) << 3) | (instr->vdValue() >> 1);
int Vm = (instr->bit(5) << 4) | instr->vmValue();
int imm3 = instr->bits(21, 19);
if (imm3 != 1 && imm3 != 2 && imm3 != 4)

View File

@ -829,7 +829,7 @@ MacroAssemblerMIPS::ma_sw(Imm32 imm, Address address)
ma_li(ScratchRegister, imm);
if (Imm16::IsInSignedRange(address.offset)) {
as_sw(ScratchRegister, address.base, Imm16(address.offset).encode());
as_sw(ScratchRegister, address.base, address.offset);
} else {
MOZ_ASSERT(address.base != SecondScratchReg);
@ -1362,7 +1362,7 @@ void
MacroAssemblerMIPS::ma_ls(FloatRegister ft, Address address)
{
if (Imm16::IsInSignedRange(address.offset)) {
as_ls(ft, address.base, Imm16(address.offset).encode());
as_ls(ft, address.base, address.offset);
} else {
MOZ_ASSERT(address.base != ScratchRegister);
ma_li(ScratchRegister, Imm32(address.offset));
@ -1379,8 +1379,8 @@ MacroAssemblerMIPS::ma_ld(FloatRegister ft, Address address)
int32_t off2 = address.offset + TAG_OFFSET;
if (Imm16::IsInSignedRange(address.offset) && Imm16::IsInSignedRange(off2)) {
as_ls(ft, address.base, Imm16(address.offset).encode());
as_ls(getOddPair(ft), address.base, Imm16(off2).encode());
as_ls(ft, address.base, address.offset);
as_ls(getOddPair(ft), address.base, off2);
} else {
ma_li(ScratchRegister, Imm32(address.offset));
as_addu(ScratchRegister, address.base, ScratchRegister);
@ -1394,8 +1394,8 @@ MacroAssemblerMIPS::ma_sd(FloatRegister ft, Address address)
{
int32_t off2 = address.offset + TAG_OFFSET;
if (Imm16::IsInSignedRange(address.offset) && Imm16::IsInSignedRange(off2)) {
as_ss(ft, address.base, Imm16(address.offset).encode());
as_ss(getOddPair(ft), address.base, Imm16(off2).encode());
as_ss(ft, address.base, address.offset);
as_ss(getOddPair(ft), address.base, off2);
} else {
ma_li(ScratchRegister, Imm32(address.offset));
as_addu(ScratchRegister, address.base, ScratchRegister);
@ -1415,7 +1415,7 @@ void
MacroAssemblerMIPS::ma_ss(FloatRegister ft, Address address)
{
if (Imm16::IsInSignedRange(address.offset)) {
as_ss(ft, address.base, Imm16(address.offset).encode());
as_ss(ft, address.base, address.offset);
} else {
ma_li(ScratchRegister, Imm32(address.offset));
as_addu(ScratchRegister, address.base, ScratchRegister);

View File

@ -201,7 +201,13 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
}
void pushValue(const Value &val) {
jsval_layout jv = JSVAL_TO_IMPL(val);
push(ImmWord(jv.asBits));
if (val.isMarkable()) {
movWithPatch(ImmWord(jv.asBits), ScratchReg);
writeDataRelocation(val);
push(ScratchReg);
} else {
push(ImmWord(jv.asBits));
}
}
void pushValue(JSValueType type, Register reg) {
boxValue(type, reg, ScratchReg);

View File

@ -1004,7 +1004,7 @@ static int
usage(void)
{
fprintf(gErrFile, "%s\n", JS_GetImplementationVersion());
fprintf(gErrFile, "usage: xpcshell [-g gredir] [-a appdir] [-r manifest]... [-PsSwWCijmIn] [-v version] [-f scriptfile] [-e script] [scriptfile] [scriptarg...]\n");
fprintf(gErrFile, "usage: xpcshell [-g gredir] [-a appdir] [-r manifest]... [-WwxiCSsmIp] [-v version] [-f scriptfile] [-e script] [scriptfile] [scriptarg...]\n");
return 2;
}
@ -1117,6 +1117,8 @@ ProcessArgs(JSContext *cx, JS::Handle<JSObject*> obj, char **argv, int argc, XPC
case 'd':
/* This used to try to turn on the debugger. */
break;
case 'm':
break;
case 'f':
if (++i == argc) {
return usage();
@ -1151,7 +1153,6 @@ ProcessArgs(JSContext *cx, JS::Handle<JSObject*> obj, char **argv, int argc, XPC
break;
case 'S':
case 's':
case 'm':
case 'I':
// These options are processed in ProcessArgsForCompartment.
break;

View File

@ -7,95 +7,12 @@
#include "nsCxPusher.h"
#include "nsIScriptContext.h"
#include "mozilla/dom/EventTarget.h"
#include "nsDOMJSUtils.h"
#include "xpcprivate.h"
#include "WorkerPrivate.h"
using mozilla::dom::EventTarget;
using mozilla::DebugOnly;
bool
nsCxPusher::Push(EventTarget *aCurrentTarget)
{
MOZ_ASSERT(mPusher.empty());
NS_ENSURE_TRUE(aCurrentTarget, false);
nsresult rv;
nsIScriptContext* scx =
aCurrentTarget->GetContextForEventHandlers(&rv);
#ifdef DEBUG_smaug
NS_ENSURE_SUCCESS(rv, false);
#else
if(NS_FAILED(rv)) {
return false;
}
#endif
if (!scx) {
// The target may have a special JS context for event handlers.
JSContext* cx = aCurrentTarget->GetJSContextForEventHandlers();
if (cx) {
mPusher.construct(cx);
}
// Nothing to do here, I guess. Have to return true so that event firing
// will still work correctly even if there is no associated JSContext
return true;
}
mPusher.construct(scx->GetNativeContext());
return true;
}
bool
nsCxPusher::RePush(EventTarget *aCurrentTarget)
{
if (mPusher.empty()) {
return Push(aCurrentTarget);
}
if (aCurrentTarget) {
nsresult rv;
nsIScriptContext* scx =
aCurrentTarget->GetContextForEventHandlers(&rv);
if (NS_FAILED(rv)) {
mPusher.destroy();
return false;
}
// If we have the same script context and native context is still
// alive, no need to Pop/Push.
if (scx && scx == mPusher.ref().GetScriptContext() &&
scx->GetNativeContext()) {
return true;
}
}
mPusher.destroy();
return Push(aCurrentTarget);
}
void
nsCxPusher::Push(JSContext *cx)
{
mPusher.construct(cx);
}
void
nsCxPusher::PushNull()
{
// Note: The Maybe<> template magic seems to need the static_cast below to
// work right on some older compilers.
mPusher.construct(static_cast<JSContext*>(nullptr), /* aAllowNull = */ true);
}
void
nsCxPusher::Pop()
{
if (!mPusher.empty())
mPusher.destroy();
}
namespace mozilla {
AutoCxPusher::AutoCxPusher(JSContext* cx, bool allowNull)

View File

@ -11,12 +11,6 @@
#include "mozilla/Maybe.h"
#include "nsCOMPtr.h"
namespace mozilla {
namespace dom {
class EventTarget;
}
}
class nsIScriptContext;
namespace mozilla {
@ -29,7 +23,6 @@ class MOZ_STACK_CLASS AutoCxPusher
{
public:
explicit AutoCxPusher(JSContext *aCx, bool aAllowNull = false);
// XPCShell uses an nsCxPusher, which contains an AutoCxPusher.
~AutoCxPusher();
nsIScriptContext* GetScriptContext() { return mScx; }
@ -49,47 +42,6 @@ private:
#endif
};
} /* namespace mozilla */
/**
* Legacy cx pushing class.
*
* This class provides a rather wonky interface, with the following quirks:
* * The constructor is a no-op, and callers must explicitly call one of
* the Push() methods.
* * Null must be pushed with PushNull().
* * The cx pusher can be reused multiple times with RePush().
*
* This class implements this interface in terms of the much simpler
* AutoCxPusher class below.
*/
class MOZ_STACK_CLASS nsCxPusher
{
public:
// Returns false if something erroneous happened.
bool Push(mozilla::dom::EventTarget *aCurrentTarget);
// If nothing has been pushed to stack, this works like Push.
// Otherwise if context will change, Pop and Push will be called.
bool RePush(mozilla::dom::EventTarget *aCurrentTarget);
// If a null JSContext is passed to Push(), that will cause no
// push to happen and false to be returned.
void Push(JSContext *cx);
// Explicitly push a null JSContext on the the stack
void PushNull();
// Pop() will be a no-op if Push() or PushNull() fail
void Pop();
nsIScriptContext* GetCurrentScriptContext() {
return mPusher.empty() ? nullptr : mPusher.ref().GetScriptContext();
}
private:
mozilla::Maybe<mozilla::AutoCxPusher> mPusher;
};
namespace mozilla {
/**
* Use AutoJSContext when you need a JS context on the stack but don't have one
* passed as a parameter. AutoJSContext will take care of finding the most

View File

@ -3165,6 +3165,12 @@ nsRect nsDisplayWrapList::GetComponentAlphaBounds(nsDisplayListBuilder* aBuilder
return bounds;
}
void
nsDisplayWrapList::SetVisibleRect(const nsRect& aRect)
{
mVisibleRect = aRect;
}
static nsresult
WrapDisplayList(nsDisplayListBuilder* aBuilder, nsIFrame* aFrame,
nsDisplayList* aList, nsDisplayWrapper* aWrapper) {
@ -4357,6 +4363,7 @@ void
nsDisplayTransform::Init(nsDisplayListBuilder* aBuilder)
{
mStoredList.SetClip(aBuilder, DisplayItemClip::NoClip());
mStoredList.SetVisibleRect(mChildrenVisibleRect);
mPrerender = ShouldPrerenderTransformedContent(aBuilder, mFrame);
if (mPrerender) {
bool snap;

View File

@ -2602,6 +2602,8 @@ public:
mOverrideZIndex = aZIndex;
}
void SetVisibleRect(const nsRect& aRect);
/**
* This creates a copy of this item, but wrapping aItem instead of
* our existing list. Only gets called if this item returned nullptr

View File

@ -235,6 +235,9 @@ enum LanguageSpecificCasingBehavior {
static LanguageSpecificCasingBehavior
GetCasingFor(const nsIAtom* aLang)
{
if (!aLang) {
return eLSCB_None;
}
if (aLang == nsGkAtoms::tr ||
aLang == nsGkAtoms::az ||
aLang == nsGkAtoms::ba ||
@ -248,9 +251,19 @@ GetCasingFor(const nsIAtom* aLang)
if (aLang == nsGkAtoms::el) {
return eLSCB_Greek;
}
if (aLang == nsGkAtoms::ga_ie) {
if (aLang == nsGkAtoms::ga) {
return eLSCB_Irish;
}
// Is there a region subtag we should ignore?
nsAtomString langStr(const_cast<nsIAtom*>(aLang));
int index = langStr.FindChar('-');
if (index > 0) {
langStr.Truncate(index);
nsCOMPtr<nsIAtom> truncatedLang = do_GetAtom(langStr);
return GetCasingFor(truncatedLang);
}
return eLSCB_None;
}

View File

@ -33,6 +33,9 @@ td.features {
@styleset { multi-def2: 3 4 5; }
@styleset { MULTI-def2: 2 6; }
@styleset { out-of-bounds1: 0; out-of-bounds2: 100; }
@styleset { scope-test1: 23; scope-test2: 24 1 }
@character-variant { scope-test1: 24; scope-test2: 23 2 }
@character-variant { overlap1: 23 1; overlap2: 23 2 }
}
@font-feature-values bogus-family {

View File

@ -10,6 +10,31 @@ gPrefix = "";
// each of these tests evaluate whether a given feature is enabled as required
// and also whether features that shouldn't be enabled are or not.
var gPropertyData = [
// font-variant-alternates
// valid values
{ prop: "font-variant-alternates", value: "normal", features: {"salt": 0, "swsh": 0} },
{ prop: "font-variant-alternates", value: "historical-forms", features: {"hist": 1, "hlig": 0} },
{ prop: "font-variant-alternates", value: "styleset(ok-alt-a, ok-alt-b)", features: {"ss01": 1, "ss02": 0, "ss03": 1, "ss04": 0, "ss05": 1, "ss19": 1, "ss20": 0} },
{ prop: "font-variant-alternates", value: "character-variant(ok-1)", features: {"cv78": 2, "cv79": 0, "cv77": 0} },
{ prop: "font-variant-alternates", value: "character-variant(ok-1, ok-3)", features: {"cv78": 2, "cv79": 0, "cv77": 0, "cv23": 1, "cv22": 0, "cv24": 0} },
{ prop: "font-variant-alternates", value: "annotation(circled)", features: {"nalt": 1} },
{ prop: "font-variant-alternates", value: "styleset(out-of-bounds1, out-of-bounds2)", features: {"ss00": 0, "ss01": 0, "ss99": 0} }, // out-of-bounds values but not invalid syntax
{ prop: "font-variant-alternates", value: "styleset(circled)", features: {"nalt": 0, "ss00": 0, "ss01": 0} }, // circled defined for annotation not styleset
{ prop: "font-variant-alternates", value: "styleset(scope-test1)", features: {"ss23": 1, "ss24": 0} },
{ prop: "font-variant-alternates", value: "character-variant(scope-test1)", features: {"cv23": 0, "cv24": 1} },
{ prop: "font-variant-alternates", value: "styleset(scope-test2)", features: {"ss23": 0, "ss24": 1, "ss01": 1} },
{ prop: "font-variant-alternates", value: "character-variant(scope-test2)", features: {"cv23": 2, "cv24": 0, "cv01": 0} },
{ prop: "font-variant-alternates", value: "character-variant(overlap1, overlap2)", features: {"cv23": 2} },
{ prop: "font-variant-alternates", value: "character-variant(overlap2, overlap1)", features: {"cv23": 1} },
// invalid values
{ prop: "font-variant-alternates", value: "historical-forms normal", features: {"hist": 0}, invalid: true },
{ prop: "font-variant-alternates", value: "historical-forms historical-forms", features: {"hist": 0}, invalid: true },
{ prop: "font-variant-alternates", value: "swash", features: {"swsh": 0}, invalid: true },
{ prop: "font-variant-alternates", value: "swash(3)", features: {"swsh": 0}, invalid: true },
{ prop: "font-variant-alternates", value: "annotation(a, b)", features: {"nalt": 0}, invalid: true },
{ prop: "font-variant-alternates", value: "ornaments(a,b)", features: {"ornm": 0, "nalt": 0}, invalid: true },
// font-variant-caps
// valid values
{ prop: "font-variant-caps", value: "normal", features: {"smcp": 0} },

View File

@ -76,10 +76,30 @@ var gFeatures = {
"ss07": 0xe330, "ss08": 0xe334, "ss09": 0xe338, "ss10": 0xe33c,
"ss11": 0xe340, "ss12": 0xe344, "ss13": 0xe348, "ss14": 0xe34c,
"ss15": 0xe350, "ss16": 0xe354, "ss17": 0xe358, "ss18": 0xe35c,
"ss19": 0xe360, "ss20": 0xe364, "ss21": 0xe368, "subs": 0xe36c,
"sups": 0xe370, "swsh": 0xe374, "titl": 0xe378, "tjmo": 0xe37c,
"tnam": 0xe380, "tnum": 0xe384, "trad": 0xe388, "twid": 0xe38c,
"unic": 0xe390, "valt": 0xe394, "vatu": 0xe398, "vert": 0xe39c,
"vhal": 0xe3a0, "vjmo": 0xe3a4, "vkna": 0xe3a8, "vkrn": 0xe3ac,
"vpal": 0xe3b0, "vrt2": 0xe3b4, "zero": 0xe3b8
"ss19": 0xe360, "ss20": 0xe364, "ss21": 0xe368, "ss22": 0xe36c,
"ss23": 0xe370, "ss24": 0xe374, "ss25": 0xe378, "ss26": 0xe37c,
"ss27": 0xe380, "ss28": 0xe384, "ss29": 0xe388, "ss30": 0xe38c,
"ss31": 0xe390, "ss32": 0xe394, "ss33": 0xe398, "ss34": 0xe39c,
"ss35": 0xe3a0, "ss36": 0xe3a4, "ss37": 0xe3a8, "ss38": 0xe3ac,
"ss39": 0xe3b0, "ss40": 0xe3b4, "ss41": 0xe3b8, "ss42": 0xe3bc,
"ss43": 0xe3c0, "ss44": 0xe3c4, "ss45": 0xe3c8, "ss46": 0xe3cc,
"ss47": 0xe3d0, "ss48": 0xe3d4, "ss49": 0xe3d8, "ss50": 0xe3dc,
"ss51": 0xe3e0, "ss52": 0xe3e4, "ss53": 0xe3e8, "ss54": 0xe3ec,
"ss55": 0xe3f0, "ss56": 0xe3f4, "ss57": 0xe3f8, "ss58": 0xe3fc,
"ss59": 0xe400, "ss60": 0xe404, "ss61": 0xe408, "ss62": 0xe40c,
"ss63": 0xe410, "ss64": 0xe414, "ss65": 0xe418, "ss66": 0xe41c,
"ss67": 0xe420, "ss68": 0xe424, "ss69": 0xe428, "ss70": 0xe42c,
"ss71": 0xe430, "ss72": 0xe434, "ss73": 0xe438, "ss74": 0xe43c,
"ss75": 0xe440, "ss76": 0xe444, "ss77": 0xe448, "ss78": 0xe44c,
"ss79": 0xe450, "ss80": 0xe454, "ss81": 0xe458, "ss82": 0xe45c,
"ss83": 0xe460, "ss84": 0xe464, "ss85": 0xe468, "ss86": 0xe46c,
"ss87": 0xe470, "ss88": 0xe474, "ss89": 0xe478, "ss90": 0xe47c,
"ss91": 0xe480, "ss92": 0xe484, "ss93": 0xe488, "ss94": 0xe48c,
"ss95": 0xe490, "ss96": 0xe494, "ss97": 0xe498, "ss98": 0xe49c,
"ss99": 0xe4a0, "subs": 0xe4a4, "sups": 0xe4a8, "swsh": 0xe4ac,
"titl": 0xe4b0, "tjmo": 0xe4b4, "tnam": 0xe4b8, "tnum": 0xe4bc,
"trad": 0xe4c0, "twid": 0xe4c4, "unic": 0xe4c8, "valt": 0xe4cc,
"vatu": 0xe4d0, "vert": 0xe4d4, "vhal": 0xe4d8, "vjmo": 0xe4dc,
"vkna": 0xe4e0, "vkrn": 0xe4e4, "vpal": 0xe4e8, "vrt2": 0xe4ec,
"zero": 0xe4f0
};

View File

@ -222,8 +222,85 @@ ss17
ss18
ss19
ss20
# ss21 is a deliberately invalid feature tag
ss21
ss22
ss23
ss24
ss25
ss26
ss27
ss28
ss29
ss30
ss31
ss32
ss33
ss34
ss35
ss36
ss37
ss38
ss39
ss40
ss41
ss42
ss43
ss44
ss45
ss46
ss47
ss48
ss49
ss50
ss51
ss52
ss53
ss54
ss55
ss56
ss57
ss58
ss59
ss60
ss61
ss62
ss63
ss64
ss65
ss66
ss67
ss68
ss69
ss70
ss71
ss72
ss73
ss74
ss75
ss76
ss77
ss78
ss79
ss80
ss81
ss82
ss83
ss84
ss85
ss86
ss87
ss88
ss89
ss90
ss91
ss92
ss93
ss94
ss95
ss96
ss97
ss98
ss99
subs
sups
swsh

View File

@ -0,0 +1,22 @@
<!DOCTYPE html>
<html>
<head>
<title>Test for uppercasing of Greek (NFC)</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<style type="text/css">
/* Note that this test depends on finding the same "serif" font for the
English- and Greek-tagged elements; on most platforms, our default prefs
provide that, but on Android they currently differ, hence the explicit
Droid Serif setting below. */
div {
font: 150% "Droid Serif", serif; /* explicitly prefer Droid over Charis on Android */
text-transform: uppercase;
margin: 1em;
}
</style>
</head>
<body lang="en">
<div>Πατάτα, Αέρας, Μάιος, άυλος, αϋπνία, Μαΐου, χούι</div>
<div lang="el-GR">Πατάτα, Αέρας, Μάιος, άυλος, αϋπνία, Μαΐου, χούι</div>
</body>
</html>

View File

@ -0,0 +1,226 @@
<!DOCTYPE html>
<html lang="ga">
<head>
<meta charset="utf-8">
<title>Test for Irish lowercasing</title>
<style>
body {
font: 16px/20px monospace;
text-transform: lowercase;
}
</style>
</head>
<body>
ÁR nACMHAINNÍ UISCE
/ ÁR N-ACMHAINNÍ UISCE
/ Ár nAcmhainní Uisce
/ Ár n-Acmhainní Uisce
/ ár n-acmhainní uisce
/ Ár nathair
/ ÁR NATHAIR
/ Ár Nathair
/ N-a shaighdiúir
/ gan dul as aca ach le nA chabhair
/ EOLAÍOCHT NA nÁBHAR
/ EOLAÍOCHT NA n-ÁBHAR
/ Eolaíocht na nÁbhar
/ Eolaíocht na n-Ábhar
/ eolaíocht na n-ábhar
/ Amhrán náisiúnta
/ Amhrán Náisiúnta
/ AMHRÁN NÁISIÚNTA
/ LUCHT NA nEALAÍON
/ LUCHT NA n-EALAÍON
/ Lucht na nEalaíon
/ Lucht na n-Ealaíon
/ lucht na n-ealaíon
/ Neart Daoine
/ neart daoine
/ NEART DAOINE
/ CEOL NA nÉAN
/ CEOL NA n-ÉAN
/ Ceol na nÉan
/ Ceol na n-Éan
/ ceol na n-éan
/ Sa Néal
/ Sa néal
/ SA NÉAL
/ ORD NA nIMEACHTAÍ
/ ORD NA n-IMEACHTAÍ
/ Ord na nImeachtaí
/ Ord na n-Imeachtaí
/ ord na n-imeachtaí
/ Nathair Nimhe
/ Nathair nimhe
/ NATHAIR NIMHE
/ LUCHT ADHARTHA NA nÍOMHÁNNA
/ LUCHT ADHARTHA NA n-ÍOMHÁNNA
/ Lucht Adhartha na nÍomhánna
/ Lucht Adhartha na n-Íomhánna
/ lucht adhartha na n-íomhánna
/ Níos Measa
/ níos measa
/ NÍOS MEASA
/ GNÉITHE DÁR nOIDHREACHT
/ GNÉITHE DÁR n-OIDHREACHT
/ Gnéithe Dár nOidhreacht
/ Gnéithe Dár n-Oidhreacht
/ gnéithe dár n-oidhreacht
/ Duine Nochta
/ Duine nochta
/ DUINE NOCHTA
/ CULTÚR NA nÓG
/ CULTÚR NA n-ÓG
/ Cultúr na nÓg
/ Cultúr na n-Óg
/ cultúr na n-óg
/ Dhá Nóiméad
/ Dhá nóiméad
/ DHÁ NÓIMÉAD
/ OCHT nUAIRE SA LÁ
/ OCHT n-UAIRE SA LÁ
/ Ocht nUaire Sa Lá
/ Ocht n-Uaire Sa Lá
/ ocht n-uaire sa lá
/ Gúna Nua
/ gúna nua
/ GÚNA NUA
/ FORMHÓR NA nÚDARÁS
/ FORMHÓR NA n-ÚDARÁS
/ Formhór na nÚdarás
/ Formhór na n-Údarás
/ formhór na n-údarás
/ Imoibreoir Núicléach
/ Imoibreoir núicléach
/ IMOIBREOIR NÚICLÉACH
/ sean-Airteagal
/ SeanAirteagal
/ BunIoncaim
/ Bun-Ioncaim
/ BuanOrduithe
/ Buan-Orduithe
/ ÁR nATHAIR
/ Ár nAthair
/ CLÁR NA nÁBHAR
/ Clár na nÁbhar
/ CEOL NA nDAOINE
/ Ceol na nDaoine
/ TÁIM I nGRÁ LEAT
/ Táim i nGrá Leat
/ CÉN tAM É?
/ CÉN t-AM É?
/ Cén tAm É?
/ Cén t-Am É?
/ cén t-am é?
/ Tar Ar Ais!
/ tar ar ais!
/ TÁ AN tÁDH ORM INNIU!
/ TÁ AN t-ÁDH ORM INNIU!
/ Tá An tÁdh Orm Inniu!
/ Tá An t-Ádh Orm Inniu!
/ tá an t-ádh orm inniu!
/ Rud Tábhachtach
/ Rud tábhachtach
/ rud tábhachtach
/ DEN OBAIR AN tEOLAS
/ DEN OBAIR AN t-EOLAS
/ Den Obair an tEolas
/ Den Obair an t-Eolas
/ den obair an t-eolas
/ AN tÉILEAMH A ÍOC
/ AN t-ÉILEAMH A ÍOC
/ An tÉileamh a Íoc
/ An t-Éileamh a Íoc
/ an t-éileamh a íoc
/ AN tINNEALL CUARDAIGH IS FEARR
/ AN t-INNEALL CUARDAIGH IS FEARR
/ An tInneall Cuardaigh Is Fearr
/ An t-Inneall Cuardaigh Is Fearr
/ an t-inneall cuardaigh is fearr
/ AN tÍOCHTAR A CHUR IN UACHTAR
/ AN t-ÍOCHTAR A CHUR IN UACHTAR
/ An tÍochtar a Chur In Uachtar
/ An t-Íochtar a Chur In Uachtar
/ an t-íochtar a chur in uachtar
/ TABHAIR AN tORDÚ SEO DÓ!
/ TABHAIR AN t-ORDÚ SEO DÓ!
/ Tabhair An tOrdú Seo Dó!
/ Tabhair An t-Ordú Seo Dó!
/ tabhair an t-ordú seo dó!
/ TÁ AN tÓR BUÍ AIGE.
/ TÁ AN t-ÓR BUÍ AIGE.
/ Tá An tÓr Buí Aige.
/ Tá An t-Ór Buí Aige.
/ tá an t-ór buí aige.
/ AN tUISCE BEATHA AR AN TÁBLA.
/ AN t-UISCE BEATHA AR AN TÁBLA.
/ An tUisce Beatha Ar An Tábla.
/ An t-Uisce Beatha Ar An Tábla.
/ an t-uisce beatha ar an tábla.
/ AN tÚRSCÉAL IS DEIREANAÍ
/ AN t-ÚRSCÉAL IS DEIREANAÍ
/ An tÚrscéal Is Deireanaí
/ An t-Úrscéal Is Deireanaí
/ an t-úrscéal is deireanaí
/ Dréacht-Acht
/ DréachtPhlean
/ Dréacht-Phlean
/ Dréacht-Íocaíocht
/ ÁitAinmneacha
/ Áit-Ainmneacha
/ StátUrraithe
/ Stát-Urraithe
/ AR AON tSLÍ
/ Ar Aon tSlí
/ AMACH ÓN tSNÁTHAID
/ Amach Ón tSnáthaid
/ AR AN tSRÁID
/ Ar An tSráid
/ CAINT AN tSRÁIDBHAILE
/ Caint An tSráidbhaile
/ CORA CRUA AN tSAOIL
/ Cora Crua An tSaoil
/ BHOLADH AN tSÁILE
/ Bholadh An tSáile
/ UAIR SA tSEACHTAIN
/ Uair Sa tSeachtain
/ DEIREADH AN tSÉASÚIR
/ Deireadh An tSéasúir
/ FEAR AN tSIOPA
/ Fear an tSiopa
/ AN tSÍOCHÁIN A CHOIMEÁD
/ An tSíocháin a Choimeád
/ AN tSOCHAÍ FAISNÉISE
/ An tSochaí Faisnéise
/ GAOTH AN tSÓLÁIS
/ Gaoth aN tSóláis
/ IS BEAG AN tSUIM IAD
/ Is Beag An tSuim Iad
/ INFHEICTHE AG AN tSÚIL
/ Infheicthe Ag An tSúil
/ SCRÍOBHFAIDH
/ Scríobhfaidh
/ PREABPHAS
/ Preabphas
/ ÚSÁIDTEAR
/ Úsáidtear
/ SNAGCHEOL
/ Snagcheol
/ IN-ATHNUAITE AGATSA
/ In-Athnuaite AGATSA
/ TEANGA DHOMHANDA
/ Teanga Dhomhanda
/ RÉALTSRUTH
/ Réaltsruth
/ NA HATAÍ
/ Na Hataí
/ T-LÉINE
/ T-Léine
/ t-Léine
/ t-léine
/ TORC ALLTA
/ Torc Allta
/ TSK TSK TSK A CHARA
/ Tsk Tsk Tsk a Chara
</body>
</html>

View File

@ -25,11 +25,13 @@ skip-if(B2G) HTTP(..) == all-title.html all-title-ref.html # bug 773482
== smtp-title.html smtp-title-ref.html
== turkish-casing-1.html turkish-casing-1-ref.html
HTTP(..) != small-caps-turkish-1.html small-caps-turkish-1-notref.html
== greek-uppercase-1.html greek-uppercase-1-ref.html
== greek-uppercase-1a.html greek-uppercase-1-ref.html
== greek-uppercase-1b.html greek-uppercase-1-ref.html
== greek-uppercase-2.html greek-uppercase-2-ref.html
HTTP(..) == greek-small-caps-1.html greek-small-caps-1-ref.html
== irish-uppercase-1.html irish-uppercase-1-ref.html
== irish-lowercase-1.html irish-lowercase-1-ref.html
== irish-lowercase-1a.html irish-lowercase-1-ref.html
== irish-lowercase-1b.html irish-lowercase-1-ref.html
== fullwidth-1.html fullwidth-1-ref.html
== fullwidth-2.html fullwidth-2-ref.html
== fullwidth-all.html fullwidth-all-ref.html

View File

@ -244,7 +244,7 @@ nsSegmentEncoder::InitUnicodeEncoder()
static PRCList gAllURLs;
#endif
nsStandardURL::nsStandardURL(bool aSupportsFileURL)
nsStandardURL::nsStandardURL(bool aSupportsFileURL, bool aTrackURL)
: mDefaultPort(-1)
, mPort(-1)
, mHostA(nullptr)
@ -270,7 +270,11 @@ nsStandardURL::nsStandardURL(bool aSupportsFileURL)
mParser = net_GetStdURLParser();
#ifdef DEBUG_DUMP_URLS_AT_SHUTDOWN
PR_APPEND_LINK(&mDebugCList, &gAllURLs);
if (aTrackURL) {
PR_APPEND_LINK(&mDebugCList, &gAllURLs);
} else {
PR_INIT_CLIST(&mDebugCList);
}
#endif
}
@ -282,7 +286,9 @@ nsStandardURL::~nsStandardURL()
free(mHostA);
}
#ifdef DEBUG_DUMP_URLS_AT_SHUTDOWN
PR_REMOVE_LINK(&mDebugCList);
if (!PR_CLIST_IS_EMPTY(&mDebugCList)) {
PR_REMOVE_LINK(&mDebugCList);
}
#endif
}
@ -1135,10 +1141,13 @@ nsStandardURL::SetSpec(const nsACString &input)
LOG(("nsStandardURL::SetSpec [spec=%s]\n", spec));
Clear();
if (!spec || !*spec)
return NS_OK;
return NS_ERROR_MALFORMED_URI;
// Make a backup of the curent URL
nsStandardURL prevURL(false,false);
prevURL.CopyMembers(this, eHonorRef);
Clear();
// filter out unexpected chars "\r\n\t" if necessary
nsAutoCString buf1;
@ -1157,6 +1166,9 @@ nsStandardURL::SetSpec(const nsACString &input)
if (NS_FAILED(rv)) {
Clear();
// If parsing the spec has failed, restore the old URL
// so we don't end up with an empty URL.
CopyMembers(&prevURL, eHonorRef);
return rv;
}
@ -1835,39 +1847,57 @@ nsStandardURL::CloneInternal(nsStandardURL::RefHandlingEnum refHandlingMode,
if (!clone)
return NS_ERROR_OUT_OF_MEMORY;
clone->mSpec = mSpec;
clone->mDefaultPort = mDefaultPort;
clone->mPort = mPort;
clone->mScheme = mScheme;
clone->mAuthority = mAuthority;
clone->mUsername = mUsername;
clone->mPassword = mPassword;
clone->mHost = mHost;
clone->mPath = mPath;
clone->mFilepath = mFilepath;
clone->mDirectory = mDirectory;
clone->mBasename = mBasename;
clone->mExtension = mExtension;
clone->mQuery = mQuery;
clone->mRef = mRef;
clone->mOriginCharset = mOriginCharset;
clone->mURLType = mURLType;
clone->mParser = mParser;
clone->mFile = mFile;
clone->mHostA = mHostA ? strdup(mHostA) : nullptr;
clone->mMutable = true;
clone->mSupportsFileURL = mSupportsFileURL;
clone->mHostEncoding = mHostEncoding;
clone->mSpecEncoding = mSpecEncoding;
if (refHandlingMode == eIgnoreRef) {
clone->SetRef(EmptyCString());
}
// Copy local members into clone.
// Also copies the cached members mFile, mHostA
clone->CopyMembers(this, refHandlingMode, true);
clone.forget(result);
return NS_OK;
}
nsresult nsStandardURL::CopyMembers(nsStandardURL * source,
nsStandardURL::RefHandlingEnum refHandlingMode, bool copyCached)
{
mSpec = source->mSpec;
mDefaultPort = source->mDefaultPort;
mPort = source->mPort;
mScheme = source->mScheme;
mAuthority = source->mAuthority;
mUsername = source->mUsername;
mPassword = source->mPassword;
mHost = source->mHost;
mPath = source->mPath;
mFilepath = source->mFilepath;
mDirectory = source->mDirectory;
mBasename = source->mBasename;
mExtension = source->mExtension;
mQuery = source->mQuery;
mRef = source->mRef;
mOriginCharset = source->mOriginCharset;
mURLType = source->mURLType;
mParser = source->mParser;
mMutable = true;
mSupportsFileURL = source->mSupportsFileURL;
mHostEncoding = source->mHostEncoding;
if (copyCached) {
mFile = source->mFile;
mHostA = source->mHostA ? strdup(source->mHostA) : nullptr;
mSpecEncoding = source->mSpecEncoding;
} else {
// The same state as after calling InvalidateCache()
mFile = nullptr;
mHostA = nullptr;
mSpecEncoding = eEncoding_Unknown;
}
if (refHandlingMode == eIgnoreRef) {
SetRef(EmptyCString());
}
return NS_OK;
}
NS_IMETHODIMP
nsStandardURL::Resolve(const nsACString &in, nsACString &out)
{

View File

@ -61,7 +61,7 @@ public:
virtual size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
explicit nsStandardURL(bool aSupportsFileURL = false);
explicit nsStandardURL(bool aSupportsFileURL = false, bool aTrackURL = true);
static void InitGlobalObjects();
static void ShutdownGlobalObjects();
@ -156,6 +156,10 @@ protected:
// Helper to share code between Clone methods.
nsresult CloneInternal(RefHandlingEnum aRefHandlingMode,
nsIURI** aClone);
// Helper method that copies member variables from the source StandardURL
// if copyCached = true, it will also copy mFile and mHostA
nsresult CopyMembers(nsStandardURL * source, RefHandlingEnum mode,
bool copyCached = false);
// Helper for subclass implementation of GetFile(). Subclasses that map
// URIs to files in a special way should implement this method. It should

View File

@ -1,16 +0,0 @@
# vim: noexpandtab ts=8 sw=8
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
DEFINES += $(TK_CFLAGS)
include $(topsrcdir)/config/rules.mk
# One of the xpcshell unit tests needs this file, so make sure it winds
# up in the test directory.
libs::
$(NSINSTALL) -D $(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit/data
$(INSTALL) $(topsrcdir)/netwerk/dns/effective_tld_names.dat \
$(DEPTH)/_tests/xpcshell/$(relativesrcdir)/unit/

View File

@ -69,3 +69,5 @@ USE_LIBS += [
'xpcomglue_s',
'xul',
]
CXXFLAGS += CONFIG['TK_CFLAGS']

View File

@ -208,6 +208,18 @@ function test_ipv6_fail()
Assert.throws(() => { url.hostPort = "[2001::1]:bad"; }, "bad port number");
}
function test_clearedSpec()
{
var url = stringToURL("http://example.com/path");
Assert.throws(() => { url.spec = "http: example"; }, "set bad spec");
Assert.throws(() => { url.spec = ""; }, "set empty spec");
do_check_eq(url.spec, "http://example.com/path");
url.host = "allizom.org";
var ref = stringToURL("http://allizom.org/path");
symmetricEquality(true, url, ref);
}
function run_test()
{
test_setEmptyPath();
@ -215,4 +227,5 @@ function run_test()
test_setRef();
test_ipv6();
test_ipv6_fail();
test_clearedSpec();
}

View File

@ -17,6 +17,7 @@ support-files =
socks_client_subprocess.js
test_link.desktop
test_link.url
../../dns/effective_tld_names.dat
[test_nsIBufferedOutputStream_writeFrom_block.js]
[test_cache2-00-service-get.js]

View File

@ -47,8 +47,6 @@
using namespace mozilla;
#define IS_SECURE(state) ((state & 0xFFFF) == STATE_IS_SECURE)
#if defined(PR_LOGGING)
//
// Log module for nsSecureBrowserUI logging...
@ -341,7 +339,8 @@ static nsresult IsChildOfDomWindow(nsIDOMWindow *parent, nsIDOMWindow *child,
return NS_OK;
}
static uint32_t GetSecurityStateFromSecurityInfo(nsISupports *info)
static uint32_t GetSecurityStateFromSecurityInfoAndRequest(nsISupports* info,
nsIRequest* request)
{
nsresult res;
uint32_t securityState;
@ -361,7 +360,32 @@ static uint32_t GetSecurityStateFromSecurityInfo(nsISupports *info)
res));
securityState = nsIWebProgressListener::STATE_IS_BROKEN;
}
if (securityState != nsIWebProgressListener::STATE_IS_INSECURE) {
// A secure connection does not yield a secure per-uri channel if the
// scheme is plain http.
nsCOMPtr<nsIURI> uri;
nsCOMPtr<nsIChannel> channel(do_QueryInterface(request));
if (channel) {
channel->GetURI(getter_AddRefs(uri));
} else {
nsCOMPtr<imgIRequest> imgRequest(do_QueryInterface(request));
if (imgRequest) {
imgRequest->GetURI(getter_AddRefs(uri));
}
}
if (uri) {
bool isHttp, isFtp;
if ((NS_SUCCEEDED(uri->SchemeIs("http", &isHttp)) && isHttp) ||
(NS_SUCCEEDED(uri->SchemeIs("ftp", &isFtp)) && isFtp)) {
PR_LOG(gSecureDocLog, PR_LOG_DEBUG, ("SecureUI: GetSecurityState: - "
"channel scheme is insecure.\n"));
securityState = nsIWebProgressListener::STATE_IS_INSECURE;
}
}
}
PR_LOG(gSecureDocLog, PR_LOG_DEBUG, ("SecureUI: GetSecurityState: - Returning %d\n",
securityState));
return securityState;
@ -476,7 +500,8 @@ nsSecureBrowserUIImpl::EvaluateAndUpdateSecurityState(nsIRequest* aRequest,
bool updateStatus = false;
nsCOMPtr<nsISSLStatus> temp_SSLStatus;
temp_NewToplevelSecurityState = GetSecurityStateFromSecurityInfo(info);
temp_NewToplevelSecurityState =
GetSecurityStateFromSecurityInfoAndRequest(info, aRequest);
PR_LOG(gSecureDocLog, PR_LOG_DEBUG,
("SecureUI:%p: OnStateChange: remember mNewToplevelSecurityState => %x\n", this,
@ -527,11 +552,13 @@ nsSecureBrowserUIImpl::EvaluateAndUpdateSecurityState(nsIRequest* aRequest,
}
void
nsSecureBrowserUIImpl::UpdateSubrequestMembers(nsISupports *securityInfo)
nsSecureBrowserUIImpl::UpdateSubrequestMembers(nsISupports* securityInfo,
nsIRequest* request)
{
// For wyciwyg channels in subdocuments we only update our
// subrequest state members.
uint32_t reqState = GetSecurityStateFromSecurityInfo(securityInfo);
uint32_t reqState = GetSecurityStateFromSecurityInfoAndRequest(securityInfo,
request);
// the code above this line should run without a lock
ReentrantMonitorAutoEnter lock(mReentrantMonitor);
@ -927,7 +954,7 @@ nsSecureBrowserUIImpl::OnStateChange(nsIWebProgress* aWebProgress,
{
PR_LOG(gSecureDocLog, PR_LOG_DEBUG,
("SecureUI:%p: OnStateChange: seeing STOP with security state: %d\n", this,
GetSecurityStateFromSecurityInfo(securityInfo)
GetSecurityStateFromSecurityInfoAndRequest(securityInfo, aRequest)
));
}
#endif
@ -1227,7 +1254,7 @@ nsSecureBrowserUIImpl::OnStateChange(nsIWebProgress* aWebProgress,
if (allowSecurityStateChange && requestHasTransferedData)
{
UpdateSubrequestMembers(securityInfo);
UpdateSubrequestMembers(securityInfo, aRequest);
// Care for the following scenario:
// A new top level document load might have already started,
@ -1460,7 +1487,7 @@ nsSecureBrowserUIImpl::OnLocationChange(nsIWebProgress* aWebProgress,
}
// For channels in subdocuments we only update our subrequest state members.
UpdateSubrequestMembers(securityInfo);
UpdateSubrequestMembers(securityInfo, aRequest);
// Care for the following scenario:

View File

@ -106,7 +106,7 @@ protected:
nsresult EvaluateAndUpdateSecurityState(nsIRequest* aRequest, nsISupports *info,
bool withNewLocation, bool withNewSink);
void UpdateSubrequestMembers(nsISupports *securityInfo);
void UpdateSubrequestMembers(nsISupports* securityInfo, nsIRequest* request);
void ObtainEventSink(nsIChannel *channel,
nsCOMPtr<nsISecurityEventSink> &sink);

View File

@ -29,7 +29,6 @@
#include "pkix/nullptr.h"
#include "pkix/Result.h"
#include "prlog.h"
#include "stdint.h"
namespace mozilla { namespace pkix {
@ -283,8 +282,7 @@ public:
Result GetInput(const Mark& mark, /*out*/ Input& item)
{
if (&mark.input != this || mark.mark > input) {
PR_NOT_REACHED("invalid mark");
return Result::FATAL_ERROR_INVALID_ARGS;
return NotReached("invalid mark", Result::FATAL_ERROR_INVALID_ARGS);
}
return item.Init(mark.mark, static_cast<uint16_t>(input - mark.mark));
}

View File

@ -25,6 +25,8 @@
#ifndef mozilla_pkix__Result_h
#define mozilla_pkix__Result_h
#include <cassert>
#include "pkix/enumclass.h"
namespace mozilla { namespace pkix {
@ -103,6 +105,13 @@ IsFatalError(Result rv)
return static_cast<unsigned int>(rv) & FATAL_ERROR_FLAG;
}
inline Result
NotReached(const char* /*explanation*/, Result result)
{
assert(false);
return result;
}
} } // namespace mozilla::pkix
#endif // mozilla_pkix__Result_h

View File

@ -97,8 +97,8 @@ PathBuildingStep::RecordResult(Result newResult, /*out*/ bool& keepGoing)
if (resultWasSet) {
if (result == Success) {
PR_NOT_REACHED("RecordResult called after finding a chain");
return Result::FATAL_ERROR_INVALID_STATE;
return NotReached("RecordResult called after finding a chain",
Result::FATAL_ERROR_INVALID_STATE);
}
// If every potential issuer has the same problem (e.g. expired) and/or if
// there is only one bad potential issuer, then return a more specific
@ -240,8 +240,7 @@ BuildForward(TrustDomain& trustDomain,
for (const BackCert* cert = &subject; cert; cert = cert->childCert) {
rv = chain.Append(cert->GetDER());
if (rv != Success) {
PR_NOT_REACHED("NonOwningDERArray::SetItem failed.");
return rv;
return NotReached("NonOwningDERArray::SetItem failed.", rv);
}
}
@ -262,7 +261,7 @@ BuildForward(TrustDomain& trustDomain,
}
++subCACount;
} else {
PR_ASSERT(subCACount == 0);
assert(subCACount == 0);
}
// Find a trusted issuer.

View File

@ -63,7 +63,7 @@ CheckValidity(Input encodedValidity, Time time)
// bit and bit 7 is the least significant bit.
inline uint8_t KeyUsageToBitMask(KeyUsage keyUsage)
{
PR_ASSERT(keyUsage != KeyUsage::noParticularKeyUsageRequired);
assert(keyUsage != KeyUsage::noParticularKeyUsageRequired);
return 0x80u >> static_cast<uint8_t>(keyUsage);
}
@ -194,9 +194,9 @@ CertPolicyId::IsAnyPolicy() const {
if (this == &CertPolicyId::anyPolicy) {
return true;
}
return numBytes == PR_ARRAY_SIZE(::mozilla::pkix::anyPolicy) &&
return numBytes == sizeof(::mozilla::pkix::anyPolicy) &&
!memcmp(bytes, ::mozilla::pkix::anyPolicy,
PR_ARRAY_SIZE(::mozilla::pkix::anyPolicy));
sizeof(::mozilla::pkix::anyPolicy));
}
// certificatePolicies ::= SEQUENCE SIZE (1..MAX) OF PolicyInformation
@ -524,12 +524,12 @@ MatchEKU(Reader& value, KeyPurposeId requiredEKU,
break;
case KeyPurposeId::anyExtendedKeyUsage:
PR_NOT_REACHED("anyExtendedKeyUsage should start with found==true");
return Result::FATAL_ERROR_LIBRARY_FAILURE;
return NotReached("anyExtendedKeyUsage should start with found==true",
Result::FATAL_ERROR_LIBRARY_FAILURE);
default:
PR_NOT_REACHED("unrecognized EKU");
return Result::FATAL_ERROR_LIBRARY_FAILURE;
return NotReached("unrecognized EKU",
Result::FATAL_ERROR_LIBRARY_FAILURE);
}
}

View File

@ -35,7 +35,7 @@ namespace internal {
Result
ExpectTagAndGetLength(Reader& input, uint8_t expectedTag, uint16_t& length)
{
PR_ASSERT((expectedTag & 0x1F) != 0x1F); // high tag number form not allowed
assert((expectedTag & 0x1F) != 0x1F); // high tag number form not allowed
uint8_t tag;
Result rv;
@ -184,6 +184,15 @@ SignatureAlgorithmOIDValue(Reader& algorithmID,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05
};
// NIST Open Systems Environment (OSE) Implementor's Workshop (OIW)
// http://www.oiw.org/agreements/stable/12s-9412.txt (no longer works).
// http://www.imc.org/ietf-pkix/old-archive-97/msg01166.html
// We need to support this this non-PKIX OID for compatibility.
// python DottedOIDToCode.py sha1WithRSASignature 1.3.14.3.2.29
static const uint8_t sha1WithRSASignature[] = {
0x2b, 0x0e, 0x03, 0x02, 0x1d
};
// RFC 3279 Section 2.2.2
// python DottedOIDToCode.py id-dsa-with-sha1 1.2.840.10040.4.3
static const uint8_t id_dsa_with_sha1[] = {
@ -227,6 +236,9 @@ SignatureAlgorithmOIDValue(Reader& algorithmID,
algorithm = SignatureAlgorithm::dsa_with_sha1;
} else if (algorithmID.MatchRest(id_dsa_with_sha256)) {
algorithm = SignatureAlgorithm::dsa_with_sha256;
} else if (algorithmID.MatchRest(sha1WithRSASignature)) {
// XXX(bug 1042479): recognize this old OID for compatibility.
algorithm = SignatureAlgorithm::rsa_pkcs1_with_sha1;
} else {
// Any MD5-based signature algorithm, or any unknown signature algorithm.
return Result::ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED;
@ -406,8 +418,8 @@ TimeChoice(Reader& tagged, uint8_t expectedTag, /*out*/ Time& time)
}
yearHi = yearLo >= 50u ? 19u : 20u;
} else {
PR_NOT_REACHED("invalid tag given to TimeChoice");
return Result::ERROR_INVALID_TIME;
return NotReached("invalid tag given to TimeChoice",
Result::ERROR_INVALID_TIME);
}
unsigned int year = (yearHi * 100u) + yearLo;
if (year < 1970u) {
@ -462,8 +474,8 @@ TimeChoice(Reader& tagged, uint8_t expectedTag, /*out*/ Time& time)
jul + aug + sep + oct + nov;
break;
default:
PR_NOT_REACHED("month already bounds-checked by ReadTwoDigits");
return Result::FATAL_ERROR_INVALID_STATE;
return NotReached("month already bounds-checked by ReadTwoDigits",
Result::FATAL_ERROR_INVALID_STATE);
}
unsigned int dayOfMonth;

View File

@ -74,8 +74,8 @@ MOZILLA_PKIX_ENUM_CLASS EmptyAllowed { No = 0, Yes = 1 };
inline Result
ExpectTagAndLength(Reader& input, uint8_t expectedTag, uint8_t expectedLength)
{
PR_ASSERT((expectedTag & 0x1F) != 0x1F); // high tag number form not allowed
PR_ASSERT(expectedLength < 128); // must be a single-byte length
assert((expectedTag & 0x1F) != 0x1F); // high tag number form not allowed
assert(expectedLength < 128); // must be a single-byte length
uint16_t tagAndLength;
Result rv = input.Read(tagAndLength);

View File

@ -323,8 +323,7 @@ VerifyEncodedOCSPResponse(TrustDomain& trustDomain, const struct CertID& certID,
return Result::ERROR_OCSP_UNKNOWN_CERT;
}
PR_NOT_REACHED("unknown CertStatus");
return Result::ERROR_OCSP_UNKNOWN_CERT;
return NotReached("unknown CertStatus", Result::ERROR_OCSP_UNKNOWN_CERT);
}
// OCSPResponse ::= SEQUENCE {
@ -888,7 +887,7 @@ CreateEncodedOCSPRequest(TrustDomain& trustDomain, const struct CertID& certID,
+ 2 // requestList
+ 2 // Request
+ 2 // reqCert (CertID)
+ PR_ARRAY_SIZE(hashAlgorithm) // hashAlgorithm
+ sizeof(hashAlgorithm) // hashAlgorithm
+ 2 + hashLen // issuerNameHash
+ 2 + hashLen // issuerKeyHash
+ 2; // serialNumber (header)
@ -918,7 +917,7 @@ CreateEncodedOCSPRequest(TrustDomain& trustDomain, const struct CertID& certID,
*d++ = 0x30; *d++ = totalLen - 10u; // reqCert (CertID SEQUENCE)
// reqCert.hashAlgorithm
for (size_t i = 0; i < PR_ARRAY_SIZE(hashAlgorithm); ++i) {
for (size_t i = 0; i < sizeof(hashAlgorithm); ++i) {
*d++ = hashAlgorithm[i];
}
@ -952,7 +951,7 @@ CreateEncodedOCSPRequest(TrustDomain& trustDomain, const struct CertID& certID,
++d;
} while (!serialNumber.AtEnd());
PR_ASSERT(d == out + totalLen);
assert(d == out + totalLen);
return Success;
}

View File

@ -185,8 +185,8 @@ private:
inline unsigned int
DaysBeforeYear(unsigned int year)
{
PR_ASSERT(year >= 1);
PR_ASSERT(year <= 9999);
assert(year >= 1);
assert(year <= 9999);
return ((year - 1u) * 365u)
+ ((year - 1u) / 4u) // leap years are every 4 years,
- ((year - 1u) / 100u) // except years divisible by 100,

View File

@ -441,7 +441,7 @@ TEST_F(pkixder_input_tests, MarkAndGetInput)
ASSERT_TRUE(InputsAreEqual(expected, item));
}
// Cannot run this test on debug builds because of the PR_NOT_REACHED
// Cannot run this test on debug builds because of the NotReached
#ifndef DEBUG
TEST_F(pkixder_input_tests, MarkAndGetInputDifferentInput)
{

View File

@ -338,10 +338,17 @@ static const AlgorithmIdentifierTestInfo<SignatureAlgorithm>
13,
},
{ SignatureAlgorithm::rsa_pkcs1_with_sha1,
// IETF Standard OID
{ 0x30, 0x0b, 0x06, 0x09,
0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05 },
13,
},
{ SignatureAlgorithm::rsa_pkcs1_with_sha1,
// Legacy OIW OID (bug 1042479)
{ 0x30, 0x07, 0x06, 0x05,
0x2b, 0x0e, 0x03, 0x02, 0x1d },
9,
},
// DSA
{ SignatureAlgorithm::dsa_with_sha256,

View File

@ -392,7 +392,7 @@ protected:
SECOidTag signerEKU = SEC_OID_OCSP_RESPONDER,
/*optional, out*/ Input* signerDEROut = nullptr)
{
PR_ASSERT(certSubjectName);
assert(certSubjectName);
const SECItem* extensions[] = {
signerEKU != SEC_OID_UNKNOWN

View File

@ -59,10 +59,10 @@ deleteCharArray(char* chars)
FILE*
OpenFile(const char* dir, const char* filename, const char* mode)
{
PR_ASSERT(dir);
PR_ASSERT(*dir);
PR_ASSERT(filename);
PR_ASSERT(*filename);
assert(dir);
assert(*dir);
assert(filename);
assert(*filename);
ScopedPtr<char, deleteCharArray>
path(new (nothrow) char[strlen(dir) + 1 + strlen(filename) + 1]);
@ -171,8 +171,8 @@ public:
// lifetime that extends at least to where Squash is called.
Result Add(const SECItem* item)
{
PR_ASSERT(item);
PR_ASSERT(item->data);
assert(item);
assert(item->data);
if (numItems >= MaxSequenceItems) {
return Result::FATAL_ERROR_INVALID_ARGS;
@ -189,7 +189,7 @@ public:
SECItem* Squash(PLArenaPool* arena, uint8_t tag)
{
PR_ASSERT(arena);
assert(arena);
size_t lengthLength = length < 128 ? 1
: length < 256 ? 2
@ -367,7 +367,7 @@ BitString(PLArenaPool* arena, const SECItem* rawBytes, bool corrupt)
prefixed->data[0] = 0;
memcpy(prefixed->data + 1, rawBytes->data, rawBytes->len);
if (corrupt) {
PR_ASSERT(prefixed->len > 8);
assert(prefixed->len > 8);
prefixed->data[8]++;
}
return EncodeNested(arena, der::BIT_STRING, prefixed);
@ -376,7 +376,7 @@ BitString(PLArenaPool* arena, const SECItem* rawBytes, bool corrupt)
static SECItem*
Boolean(PLArenaPool* arena, bool value)
{
PR_ASSERT(arena);
assert(arena);
SECItem* result(SECITEM_AllocItem(arena, nullptr, 3));
if (!result) {
return nullptr;
@ -424,7 +424,7 @@ enum TimeEncoding { UTCTime = 0, GeneralizedTime = 1 };
static SECItem*
PRTimeToEncodedTime(PLArenaPool* arena, PRTime time, TimeEncoding encoding)
{
PR_ASSERT(encoding == UTCTime || encoding == GeneralizedTime);
assert(encoding == UTCTime || encoding == GeneralizedTime);
PRExplodedTime exploded;
PR_ExplodeTime(time, PR_GMTParameters, &exploded);
@ -518,9 +518,9 @@ SignedData(PLArenaPool* arena, const SECItem* tbsData,
SECKEYPrivateKey* privKey, SECOidTag hashAlg,
bool corrupt, /*optional*/ SECItem const* const* certs)
{
PR_ASSERT(arena);
PR_ASSERT(tbsData);
PR_ASSERT(privKey);
assert(arena);
assert(tbsData);
assert(privKey);
if (!arena || !tbsData || !privKey) {
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
return nullptr;
@ -601,7 +601,7 @@ static SECItem*
Extension(PLArenaPool* arena, SECOidTag extnIDTag,
ExtensionCriticality criticality, Output& value)
{
PR_ASSERT(arena);
assert(arena);
if (!arena) {
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
return nullptr;
@ -642,7 +642,7 @@ Extension(PLArenaPool* arena, SECOidTag extnIDTag,
SECItem*
MaybeLogOutput(SECItem* result, const char* suffix)
{
PR_ASSERT(suffix);
assert(suffix);
if (!result) {
return nullptr;
@ -693,11 +693,11 @@ GenerateKeyPair(/*out*/ ScopedSECKEYPublicKey& publicKey,
nullptr);
if (privateKey) {
publicKey = publicKeyTemp;
PR_ASSERT(publicKey);
assert(publicKey);
return SECSuccess;
}
PR_ASSERT(!publicKeyTemp);
assert(!publicKeyTemp);
if (PR_GetError() != SEC_ERROR_PKCS11_FUNCTION_FAILED) {
return SECFailure;
@ -736,9 +736,9 @@ CreateEncodedCertificate(PLArenaPool* arena, long version,
SECOidTag signatureHashAlg,
/*out*/ ScopedSECKEYPrivateKey& privateKeyResult)
{
PR_ASSERT(arena);
PR_ASSERT(issuerNameDER);
PR_ASSERT(subjectNameDER);
assert(arena);
assert(issuerNameDER);
assert(subjectNameDER);
if (!arena || !issuerNameDER || !subjectNameDER) {
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
return nullptr;
@ -796,10 +796,10 @@ TBSCertificate(PLArenaPool* arena, long versionValue,
const SECKEYPublicKey* subjectPublicKey,
/*optional*/ SECItem const* const* extensions)
{
PR_ASSERT(arena);
PR_ASSERT(issuer);
PR_ASSERT(subject);
PR_ASSERT(subjectPublicKey);
assert(arena);
assert(issuer);
assert(subject);
assert(subjectPublicKey);
if (!arena || !issuer || !subject || !subjectPublicKey) {
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
return nullptr;
@ -935,7 +935,7 @@ CreateEncodedBasicConstraints(PLArenaPool* arena, bool isCA,
/*optional*/ long* pathLenConstraintValue,
ExtensionCriticality criticality)
{
PR_ASSERT(arena);
assert(arena);
if (!arena) {
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
return nullptr;
@ -968,8 +968,8 @@ SECItem*
CreateEncodedEKUExtension(PLArenaPool* arena, SECOidTag const* ekus,
size_t ekusCount, ExtensionCriticality criticality)
{
PR_ASSERT(arena);
PR_ASSERT(ekus);
assert(arena);
assert(ekus);
if (!arena || (!ekus && ekusCount != 0)) {
PR_SetError(SEC_ERROR_INVALID_ARGS, 0);
return nullptr;

View File

@ -3,6 +3,7 @@
# You can obtain one at http://mozilla.org/MPL/2.0/.
import os
import re
import select
import signal
import subprocess
@ -838,10 +839,17 @@ falling back to not using job objects for managing child processes"""
PeekNamedPipe = ctypes.windll.kernel32.PeekNamedPipe
GetLastError = ctypes.windll.kernel32.GetLastError
@staticmethod
def _normalize_newline(line):
# adb on windows returns \r\r\n at the end of each line, to get around
# this normalize all newlines to have a unix-style '\n'
# http://src.chromium.org/viewvc/chrome/trunk/src/build/android/pylib/android_commands.py#l1944
return re.sub(r'\r+\n?$', '\n', line)
def _readWithTimeout(self, f, timeout):
if timeout is None:
# shortcut to allow callers to pass in "None" for no timeout.
return (f.readline(), False)
return (self._normalize_newline(f.readline()), False)
x = msvcrt.get_osfhandle(f.fileno())
l = ctypes.c_long()
done = time.time() + timeout
@ -855,7 +863,7 @@ falling back to not using job objects for managing child processes"""
if l.value > 0:
# we're assuming that the output is line-buffered,
# which is not unreasonable
return (f.readline(), False)
return (self._normalize_newline(f.readline()), False)
time.sleep(0.01)
return ('', True)

View File

@ -4,7 +4,7 @@
from setuptools import setup
PACKAGE_VERSION = '0.20'
PACKAGE_VERSION = '0.21'
setup(name='mozprocess',
version=PACKAGE_VERSION,

View File

@ -359,6 +359,7 @@
"description": "XUL cache was disabled"
},
"MEMORY_RESIDENT": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"low": "32 * 1024",
@ -368,6 +369,7 @@
"description": "Resident memory size (KB)"
},
"MEMORY_VSIZE": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"low": "32 * 1024",
@ -377,6 +379,7 @@
"description": "Virtual memory size (KB)"
},
"MEMORY_VSIZE_MAX_CONTIGUOUS": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"low": "32 * 1024",
@ -386,6 +389,7 @@
"description": "Maximum-sized block of contiguous virtual memory (KB)"
},
"MEMORY_JS_COMPARTMENTS_SYSTEM": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"high": "1000",
@ -394,6 +398,7 @@
"description": "Total JavaScript compartments used for add-ons and internals."
},
"MEMORY_JS_COMPARTMENTS_USER": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"high": "1000",
@ -402,6 +407,7 @@
"description": "Total JavaScript compartments used for web pages"
},
"MEMORY_JS_MAIN_RUNTIME_TEMPORARY_PEAK": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"low": 1024,
@ -411,6 +417,7 @@
"description": "Peak memory used by the main JSRuntime to store transient data (KB)"
},
"MEMORY_JS_GC_HEAP": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"low": 1024,
@ -420,6 +427,7 @@
"description": "Memory used by the garbage-collected JavaScript heap (KB)"
},
"MEMORY_STORAGE_SQLITE": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"low": 1024,
@ -429,6 +437,7 @@
"description": "Memory used by SQLite (KB)"
},
"MEMORY_IMAGES_CONTENT_USED_UNCOMPRESSED": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"low": 1024,
@ -438,6 +447,7 @@
"description": "Memory used for uncompressed, in-use content images (KB)"
},
"MEMORY_HEAP_ALLOCATED": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"low": 1024,
@ -447,6 +457,7 @@
"description": "Heap memory allocated (KB)"
},
"MEMORY_HEAP_COMMITTED_UNUSED": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"low": 1024,
@ -456,6 +467,7 @@
"description": "Committed, unused heap memory (KB)"
},
"MEMORY_HEAP_COMMITTED_UNUSED_RATIO": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "linear",
"high": "100",
@ -463,6 +475,7 @@
"description": "Ratio of committed, unused memory to allocated memory in the heap (percentage)."
},
"GHOST_WINDOWS": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"high": "128",
@ -471,6 +484,7 @@
"description": "Number of ghost windows"
},
"MEMORY_FREE_PURGED_PAGES_MS": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"high": "1024",
@ -480,6 +494,7 @@
"cpp_guard": "XP_MACOSX"
},
"LOW_MEMORY_EVENTS_VIRTUAL": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"high": "1024",
@ -489,6 +504,7 @@
"cpp_guard": "XP_WIN"
},
"LOW_MEMORY_EVENTS_PHYSICAL": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"high": "1024",
@ -498,6 +514,7 @@
"cpp_guard": "XP_WIN"
},
"LOW_MEMORY_EVENTS_COMMIT_SPACE": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"high": "1024",
@ -4611,6 +4628,7 @@
"description": "Time (ms) it takes to figure out extension last modified time"
},
"TELEMETRY_MEMORY_REPORTER_MS": {
"alert_emails": ["memshrink-telemetry-alerts@mozilla.com"],
"expires_in_version": "never",
"kind": "exponential",
"high": "5000",

View File

@ -963,14 +963,12 @@ nsTextStore::DidLockGranted()
mNativeCaretIsCreated = false;
}
if (IsReadWriteLocked()) {
if (IsPendingCompositionUpdateIncomplete()) {
// FreeCJ (TIP for Traditional Chinese) calls SetSelection() to set caret
// to the start of composition string and insert a full width space for
// a placeholder with a call of SetText(). After that, it calls
// OnUpdateComposition() without new range. Therefore, let's record the
// composition update information here.
RecordCompositionUpdateAction();
}
// FreeCJ (TIP for Traditional Chinese) calls SetSelection() to set caret
// to the start of composition string and insert a full width space for
// a placeholder with a call of SetText(). After that, it calls
// OnUpdateComposition() without new range. Therefore, let's record the
// composition update information here.
CompleteLastActionIfStillIncomplete();
FlushPendingActions();
}
@ -1008,18 +1006,20 @@ nsTextStore::FlushPendingActions()
MOZ_ASSERT(mComposition.mLastData.IsEmpty());
// Select composition range so the new composition replaces the range
WidgetSelectionEvent selectionSet(true, NS_SELECTION_SET, mWidget);
mWidget->InitEvent(selectionSet);
selectionSet.mOffset = static_cast<uint32_t>(action.mSelectionStart);
selectionSet.mLength = static_cast<uint32_t>(action.mSelectionLength);
selectionSet.mReversed = false;
mWidget->DispatchWindowEvent(&selectionSet);
if (!selectionSet.mSucceeded) {
PR_LOG(sTextStoreLog, PR_LOG_ERROR,
("TSF: 0x%p nsTextStore::FlushPendingActions() "
"FAILED due to NS_SELECTION_SET failure", this));
break;
if (action.mAdjustSelection) {
// Select composition range so the new composition replaces the range
WidgetSelectionEvent selectionSet(true, NS_SELECTION_SET, mWidget);
mWidget->InitEvent(selectionSet);
selectionSet.mOffset = static_cast<uint32_t>(action.mSelectionStart);
selectionSet.mLength = static_cast<uint32_t>(action.mSelectionLength);
selectionSet.mReversed = false;
mWidget->DispatchWindowEvent(&selectionSet);
if (!selectionSet.mSucceeded) {
PR_LOG(sTextStoreLog, PR_LOG_ERROR,
("TSF: 0x%p nsTextStore::FlushPendingActions() "
"FAILED due to NS_SELECTION_SET failure", this));
break;
}
}
PR_LOG(sTextStoreLog, PR_LOG_DEBUG,
("TSF: 0x%p nsTextStore::FlushPendingActions() "
@ -1787,6 +1787,7 @@ nsTextStore::SetSelectionInternal(const TS_SELECTION_ACP* pSelection,
return S_OK;
}
CompleteLastActionIfStillIncomplete();
PendingAction* action = mPendingActions.AppendElement();
action->mType = PendingAction::SELECTION_SET;
action->mSelectionStart = pSelection->acpStart;
@ -2812,12 +2813,28 @@ nsTextStore::RecordCompositionStartAction(ITfCompositionView* pComposition,
return E_FAIL;
}
CompleteLastActionIfStillIncomplete();
PendingAction* action = mPendingActions.AppendElement();
action->mType = PendingAction::COMPOSITION_START;
action->mSelectionStart = start;
action->mSelectionLength = length;
currentContent.StartComposition(pComposition, *action, aPreserveSelection);
if (aPreserveSelection) {
action->mAdjustSelection = false;
} else {
Selection& currentSel = CurrentSelection();
if (currentSel.IsDirty()) {
PR_LOG(sTextStoreLog, PR_LOG_ERROR,
("TSF: 0x%p nsTextStore::RecordCompositionStartAction() FAILED "
"due to CurrentSelection() failure", this));
action->mAdjustSelection = true;
} else {
action->mAdjustSelection = currentSel.MinOffset() != start ||
currentSel.MaxOffset() != start + length;
}
}
currentContent.StartComposition(pComposition, *action);
PR_LOG(sTextStoreLog, PR_LOG_ALWAYS,
("TSF: 0x%p nsTextStore::RecordCompositionStartAction() succeeded: "
@ -2842,6 +2859,7 @@ nsTextStore::RecordCompositionEndAction()
MOZ_ASSERT(mComposition.IsComposing());
CompleteLastActionIfStillIncomplete();
PendingAction* action = mPendingActions.AppendElement();
action->mType = PendingAction::COMPOSITION_END;
action->mData = mComposition.mString;
@ -4049,8 +4067,7 @@ nsTextStore::Content::ReplaceTextWith(LONG aStart, LONG aLength,
void
nsTextStore::Content::StartComposition(ITfCompositionView* aCompositionView,
const PendingAction& aCompStart,
bool aPreserveSelection)
const PendingAction& aCompStart)
{
MOZ_ASSERT(mInitialized);
MOZ_ASSERT(aCompositionView);
@ -4060,7 +4077,7 @@ nsTextStore::Content::StartComposition(ITfCompositionView* aCompositionView,
mComposition.Start(aCompositionView, aCompStart.mSelectionStart,
GetSubstring(static_cast<uint32_t>(aCompStart.mSelectionStart),
static_cast<uint32_t>(aCompStart.mSelectionLength)));
if (!aPreserveSelection) {
if (aCompStart.mAdjustSelection) {
mSelection.SetSelection(mComposition.mStart, mComposition.mString.Length(),
false);
}

View File

@ -508,6 +508,8 @@ protected:
bool mSelectionReversed;
// For compositionupdate
bool mIncomplete;
// For compositionstart
bool mAdjustSelection;
};
// Items of mPendingActions are appended when TSF tells us to need to dispatch
// DOM composition events. However, we cannot dispatch while the document is
@ -540,6 +542,14 @@ protected:
lastAction.mIncomplete;
}
void CompleteLastActionIfStillIncomplete()
{
if (!IsPendingCompositionUpdateIncomplete()) {
return;
}
RecordCompositionUpdateAction();
}
// When On*Composition() is called without document lock, we need to flush
// the recorded actions at quitting the method.
// AutoPendingActionAndContentFlusher class is usedful for it.
@ -602,8 +612,7 @@ protected:
void ReplaceTextWith(LONG aStart, LONG aLength, const nsAString& aString);
void StartComposition(ITfCompositionView* aCompositionView,
const PendingAction& aCompStart,
bool aPreserveSelection);
const PendingAction& aCompStart);
void EndComposition(const PendingAction& aCompEnd);
const nsString& Text() const