This commit is contained in:
Ryan VanderMeulen 2013-10-14 14:44:16 -04:00
Родитель e4b1ec40fe 9abde8f9b2
Коммит f9448233f6
70 изменённых файлов: 1208 добавлений и 794 удалений

Просмотреть файл

@ -24,9 +24,17 @@ let WebrtcIndicator = {
fillPopup: function (aPopup) {
this._menuitemData = new WeakMap;
for (let streamData of this.UIModule.activeStreams) {
let pageURI = Services.io.newURI(streamData.uri, null, null);
let menuitem = document.createElement("menuitem");
menuitem.setAttribute("label", streamData.uri);
menuitem.setAttribute("class", "menuitem-iconic");
menuitem.setAttribute("label", streamData.browser.contentTitle || streamData.uri);
menuitem.setAttribute("tooltiptext", streamData.uri);
PlacesUtils.favicons.getFaviconURLForPage(pageURI, function (aURI) {
if (aURI) {
let iconURL = PlacesUtils.favicons.getFaviconLinkForIcon(aURI).spec;
menuitem.setAttribute("image", iconURL);
}
});
this._menuitemData.set(menuitem, streamData);

Просмотреть файл

@ -94,6 +94,7 @@ function cleanup() {
Services.obs.removeObserver(obs_DESTROYING, DESTROYING);
Services.obs.removeObserver(obs_BEFORE_DESTROYED, BEFORE_DESTROYED);
Services.obs.removeObserver(obs_DESTROYED, DESTROYED);
Services.obs.removeObserver(obs_STARTUP, STARTUP);
gBrowser.removeCurrentTab();
finish();

Просмотреть файл

@ -118,6 +118,7 @@ function cleanup() {
Services.obs.removeObserver(tab_DESTROYING, DESTROYING);
Services.obs.removeObserver(tab_SHOWN, SHOWN);
Services.obs.removeObserver(tab_HIDDEN, HIDDEN);
Services.obs.removeObserver(tab_STARTUP, STARTUP);
gBrowser.tabContainer.removeEventListener("TabSelect", tabSelect);
gBrowser.removeCurrentTab();

Просмотреть файл

@ -282,13 +282,6 @@ public:
uint16_t ReadyState();
// request
void Open(const nsACString& aMethod, const nsAString& aUrl, ErrorResult& aRv)
{
Open(aMethod, aUrl, true,
mozilla::dom::Optional<nsAString>(),
mozilla::dom::Optional<nsAString>(),
aRv);
}
void Open(const nsACString& aMethod, const nsAString& aUrl, bool aAsync,
const mozilla::dom::Optional<nsAString>& aUser,
const mozilla::dom::Optional<nsAString>& aPassword,

Просмотреть файл

@ -27,15 +27,11 @@ function checkDoc(title, expectedtitle, normalizedtitle) {
is(doc.doctype.internalSubset, null, "internalSubset should be null!");
isElement(doc.documentElement, "html");
isElement(doc.documentElement.firstChild, "head");
if (title !== undefined) {
is(doc.documentElement.firstChild.childNodes.length, 1);
isElement(doc.documentElement.firstChild.firstChild, "title");
// Doesn't always work out in WebKit.
ok(doc.documentElement.firstChild.firstChild.firstChild, "Need a text node.");
is(doc.documentElement.firstChild.firstChild.firstChild.data, expectedtitle);
} else {
is(doc.documentElement.firstChild.childNodes.length, 0);
}
is(doc.documentElement.firstChild.childNodes.length, 1);
isElement(doc.documentElement.firstChild.firstChild, "title");
// Doesn't always work out in WebKit.
ok(doc.documentElement.firstChild.firstChild.firstChild, "Need a text node.");
is(doc.documentElement.firstChild.firstChild.firstChild.data, expectedtitle);
isElement(doc.documentElement.lastChild, "body");
is(doc.documentElement.lastChild.childNodes.length, 0);
((!title || title.indexOf("\f") === -1) ? is : todo_is)
@ -45,7 +41,7 @@ function checkDoc(title, expectedtitle, normalizedtitle) {
}
checkDoc("", "", "");
checkDoc(null, "null", "null");
checkDoc(undefined, "", "");
checkDoc(undefined, "undefined", "undefined");
checkDoc("foo bar baz", "foo bar baz", "foo bar baz");
checkDoc("foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz");
checkDoc("foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz");

Просмотреть файл

@ -477,58 +477,6 @@ private:
NS_IMPL_ISUPPORTS1(DirPickerRecursiveFileEnumerator, nsISimpleEnumerator)
class DirPickerBuildFileListTask MOZ_FINAL
: public nsRunnable
{
public:
DirPickerBuildFileListTask(HTMLInputElement* aInput, nsIFile* aTopDir)
: mInput(aInput)
, mTopDir(aTopDir)
{}
NS_IMETHOD Run() {
if (!NS_IsMainThread()) {
// Build up list of nsDOMFileFile objects on this dedicated thread:
nsCOMPtr<nsISimpleEnumerator> iter =
new DirPickerRecursiveFileEnumerator(mTopDir);
bool hasMore = true;
nsCOMPtr<nsISupports> tmp;
while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
iter->GetNext(getter_AddRefs(tmp));
nsCOMPtr<nsIDOMFile> domFile = do_QueryInterface(tmp);
MOZ_ASSERT(domFile);
mFileList.AppendElement(domFile);
mInput->SetFileListProgress(mFileList.Length());
}
return NS_DispatchToMainThread(this);
}
// Now back on the main thread, set the list on our HTMLInputElement:
if (mFileList.IsEmpty()) {
return NS_OK;
}
// The text control frame (if there is one) isn't going to send a change
// event because it will think this is done by a script.
// So, we can safely send one by ourself.
mInput->SetFiles(mFileList, true);
mInput->MaybeDispatchProgressEvent(true); // last progress event
nsresult rv =
nsContentUtils::DispatchTrustedEvent(mInput->OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(mInput.get()),
NS_LITERAL_STRING("change"), true,
false);
// Clear mInput to make sure that it can't lose its last strong ref off the
// main thread (which may happen if our dtor runs off the main thread)!
mInput = nullptr;
return rv;
}
private:
nsRefPtr<HTMLInputElement> mInput;
nsCOMPtr<nsIFile> mTopDir;
nsTArray<nsCOMPtr<nsIDOMFile> > mFileList;
};
/**
* This may return nullptr if aDomFile's implementation of
* nsIDOMFile::mozFullPathInternal does not successfully return a non-empty
@ -554,6 +502,113 @@ DOMFileToLocalFile(nsIDOMFile* aDomFile)
} // anonymous namespace
class DirPickerFileListBuilderTask MOZ_FINAL
: public nsRunnable
{
public:
DirPickerFileListBuilderTask(HTMLInputElement* aInput, nsIFile* aTopDir)
: mPreviousFileListLength(0)
, mInput(aInput)
, mTopDir(aTopDir)
, mFileListLength(0)
, mCanceled(0)
{}
NS_IMETHOD Run() {
if (!NS_IsMainThread()) {
// Build up list of nsDOMFileFile objects on this dedicated thread:
nsCOMPtr<nsISimpleEnumerator> iter =
new DirPickerRecursiveFileEnumerator(mTopDir);
bool hasMore = true;
nsCOMPtr<nsISupports> tmp;
while (NS_SUCCEEDED(iter->HasMoreElements(&hasMore)) && hasMore) {
iter->GetNext(getter_AddRefs(tmp));
nsCOMPtr<nsIDOMFile> domFile = do_QueryInterface(tmp);
MOZ_ASSERT(domFile);
mFileList.AppendElement(domFile);
mFileListLength = mFileList.Length();
if (mCanceled) {
NS_ASSERTION(!mInput, "This is bad - how did this happen?");
// There's no point dispatching to the main thread (that doesn't
// guarantee that we'll be destroyed there).
return NS_OK;
}
}
return NS_DispatchToMainThread(this);
}
// Now back on the main thread, set the list on our HTMLInputElement:
if (mCanceled || mFileList.IsEmpty()) {
return NS_OK;
}
MOZ_ASSERT(mInput->mDirPickerFileListBuilderTask,
"But we aren't canceled!");
if (mInput->mProgressTimer) {
mInput->mProgressTimerIsActive = false;
mInput->mProgressTimer->Cancel();
}
mInput->MaybeDispatchProgressEvent(true); // Last progress event.
mInput->mDirPickerFileListBuilderTask = nullptr; // Now null out.
if (mCanceled) { // The last progress event may have canceled us
return NS_OK;
}
// The text control frame (if there is one) isn't going to send a change
// event because it will think this is done by a script.
// So, we can safely send one by ourself.
mInput->SetFiles(mFileList, true);
nsresult rv =
nsContentUtils::DispatchTrustedEvent(mInput->OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(mInput.get()),
NS_LITERAL_STRING("change"), true,
false);
// Clear mInput to make sure that it can't lose its last strong ref off the
// main thread (which may happen if our dtor runs off the main thread)!
mInput = nullptr;
return rv;
}
void Cancel()
{
MOZ_ASSERT(NS_IsMainThread() && !mCanceled);
// Clear mInput to make sure that it can't lose its last strong ref off the
// main thread (which may happen if our dtor runs off the main thread)!
mInput = nullptr;
mCanceled = 1; // true
}
uint32_t GetFileListLength() const
{
return mFileListLength;
}
/**
* The number of files added to the FileList at the time the last progress
* event was fired.
*
* This is only read/set by HTMLInputElement on the main thread. The reason
* that this member is stored here rather than on HTMLInputElement is so that
* we don't increase the size of HTMLInputElement for something that's rarely
* used.
*/
uint32_t mPreviousFileListLength;
private:
nsRefPtr<HTMLInputElement> mInput;
nsCOMPtr<nsIFile> mTopDir;
nsTArray<nsCOMPtr<nsIDOMFile> > mFileList;
// We access the list length on both threads, so we need the indirection of
// this atomic member to make the access thread safe:
mozilla::Atomic<uint32_t> mFileListLength;
// We'd prefer this member to be bool, but we don't support Atomic<bool>.
mozilla::Atomic<uint32_t> mCanceled;
};
NS_IMETHODIMP
HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
{
@ -561,6 +616,8 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
return NS_OK;
}
mInput->CancelDirectoryPickerScanIfRunning();
int16_t mode;
mFilePicker->GetMode(&mode);
@ -590,14 +647,14 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
= do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID);
NS_ASSERTION(target, "Must have stream transport service");
mInput->ResetProgressCounters();
mInput->StartProgressEventTimer();
// DirPickerBuildFileListTask takes care of calling SetFiles() and
// DirPickerFileListBuilderTask takes care of calling SetFiles() and
// dispatching the "change" event.
nsRefPtr<DirPickerBuildFileListTask> event =
new DirPickerBuildFileListTask(mInput.get(), pickedDir.get());
return target->Dispatch(event, NS_DISPATCH_NORMAL);
mInput->mDirPickerFileListBuilderTask =
new DirPickerFileListBuilderTask(mInput.get(), pickedDir.get());
return target->Dispatch(mInput->mDirPickerFileListBuilderTask,
NS_DISPATCH_NORMAL);
}
// Collect new selected filenames
@ -1020,8 +1077,6 @@ static nsresult FireEventForAccessibility(nsIDOMHTMLInputElement* aTarget,
HTMLInputElement::HTMLInputElement(already_AddRefed<nsINodeInfo> aNodeInfo,
FromParser aFromParser)
: nsGenericHTMLFormElementWithState(aNodeInfo)
, mFileListProgress(0)
, mLastFileListProgress(0)
, mType(kInputDefaultType->value)
, mDisabledChanged(false)
, mValueChanged(false)
@ -2463,6 +2518,20 @@ HTMLInputElement::OpenDirectoryPicker(ErrorResult& aRv)
InitFilePicker(FILE_PICKER_DIRECTORY);
}
void
HTMLInputElement::CancelDirectoryPickerScanIfRunning()
{
if (!mDirPickerFileListBuilderTask) {
return;
}
if (mProgressTimer) {
mProgressTimerIsActive = false;
mProgressTimer->Cancel();
}
mDirPickerFileListBuilderTask->Cancel();
mDirPickerFileListBuilderTask = nullptr;
}
void
HTMLInputElement::StartProgressEventTimer()
{
@ -2507,8 +2576,10 @@ HTMLInputElement::MaybeDispatchProgressEvent(bool aFinalProgress)
mProgressTimer->Cancel();
}
uint32_t fileListLength = mDirPickerFileListBuilderTask->GetFileListLength();
if (mProgressTimerIsActive ||
mFileListProgress == mLastFileListProgress) {
fileListLength == mDirPickerFileListBuilderTask->mPreviousFileListLength) {
return;
}
@ -2516,10 +2587,11 @@ HTMLInputElement::MaybeDispatchProgressEvent(bool aFinalProgress)
StartProgressEventTimer();
}
mLastFileListProgress = mFileListProgress;
mDirPickerFileListBuilderTask->mPreviousFileListLength = fileListLength;
DispatchProgressEvent(NS_LITERAL_STRING(PROGRESS_STR),
false, mLastFileListProgress,
false,
mDirPickerFileListBuilderTask->mPreviousFileListLength,
0);
}
@ -2542,12 +2614,16 @@ HTMLInputElement::DispatchProgressEvent(const nsAString& aType,
return;
}
progress->InitProgressEvent(aType, false, false, aLengthComputable,
progress->InitProgressEvent(aType, false, true, aLengthComputable,
aLoaded, (aTotal == UINT64_MAX) ? 0 : aTotal);
event->SetTrusted(true);
DispatchDOMEvent(nullptr, event, nullptr, nullptr);
bool doDefaultAction;
rv = DispatchEvent(event, &doDefaultAction);
if (NS_SUCCEEDED(rv) && !doDefaultAction) {
CancelDirectoryPickerScanIfRunning();
}
}
nsresult

Просмотреть файл

@ -32,6 +32,7 @@ namespace mozilla {
namespace dom {
class Date;
class DirPickerFileListBuilderTask;
class UploadLastDir MOZ_FINAL : public nsIObserver, public nsSupportsWeakReference {
public:
@ -87,6 +88,8 @@ class HTMLInputElement MOZ_FINAL : public nsGenericHTMLFormElementWithState,
public nsITimerCallback,
public nsIConstraintValidation
{
friend class DirPickerFileListBuilderTask;
public:
using nsIConstraintValidation::GetValidationMessage;
using nsIConstraintValidation::CheckValidity;
@ -402,12 +405,8 @@ public:
nsDOMFileList* GetFiles();
void OpenDirectoryPicker(ErrorResult& aRv);
void CancelDirectoryPickerScanIfRunning();
void ResetProgressCounters()
{
mFileListProgress = 0;
mLastFileListProgress = 0;
}
void StartProgressEventTimer();
void MaybeDispatchProgressEvent(bool aFinalProgress);
void DispatchProgressEvent(const nsAString& aType,
@ -677,13 +676,6 @@ public:
// XPCOM GetPhonetic() is OK
void SetFileListProgress(uint32_t mFileCount)
{
MOZ_ASSERT(!NS_IsMainThread(),
"Why are we calling this on the main thread?");
mFileListProgress = mFileCount;
}
protected:
virtual JSObject* WrapNode(JSContext* aCx,
JS::Handle<JSObject*> aScope) MOZ_OVERRIDE;
@ -1162,6 +1154,8 @@ protected:
nsRefPtr<nsDOMFileList> mFileList;
nsRefPtr<DirPickerFileListBuilderTask> mDirPickerFileListBuilderTask;
nsString mStaticDocFileList;
/**
@ -1202,19 +1196,6 @@ protected:
// Float value returned by GetStep() when the step attribute is set to 'any'.
static const Decimal kStepAny;
/**
* The number of files added to the FileList being built off-main-thread when
* mType == NS_FORM_INPUT_FILE and the user selects a directory. This is set
* off the main thread, read on main thread.
*/
mozilla::Atomic<uint32_t> mFileListProgress;
/**
* The number of files added to the FileList at the time the last progress
* event was fired.
*/
uint32_t mLastFileListProgress;
/**
* The type of this input (<input type=...>) as an integer.
* @see nsIFormControl.h (specifically NS_FORM_INPUT_*)

Просмотреть файл

@ -998,34 +998,8 @@ nsXBLPrototypeBinding::Read(nsIObjectInputStream* aStream,
previousHandler = handler;
} while (1);
if (mBinding) {
while (true) {
XBLBindingSerializeDetails type;
rv = aStream->Read8(&type);
NS_ENSURE_SUCCESS(rv, rv);
if (type != XBLBinding_Serialize_Attribute) {
break;
}
int32_t attrNamespace;
rv = ReadNamespace(aStream, attrNamespace);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoString attrName, attrValue;
rv = aStream->ReadString(attrName);
NS_ENSURE_SUCCESS(rv, rv);
rv = aStream->ReadString(attrValue);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIAtom> atomName = do_GetAtom(attrName);
mBinding->SetAttr(attrNamespace, atomName, attrValue, false);
}
}
// Finally, read in the resources.
while (true) {
do {
XBLBindingSerializeDetails type;
rv = aStream->Read8(&type);
NS_ENSURE_SUCCESS(rv, rv);
@ -1042,7 +1016,7 @@ nsXBLPrototypeBinding::Read(nsIObjectInputStream* aStream,
AddResource(type == XBLBinding_Serialize_Stylesheet ? nsGkAtoms::stylesheet :
nsGkAtoms::image, src);
}
} while (1);
if (isFirstBinding) {
aDocInfo->SetFirstPrototypeBinding(this);
@ -1152,30 +1126,6 @@ nsXBLPrototypeBinding::Write(nsIObjectOutputStream* aStream)
aStream->Write8(XBLBinding_Serialize_NoMoreItems);
NS_ENSURE_SUCCESS(rv, rv);
if (mBinding) {
uint32_t attributes = mBinding->GetAttrCount();
nsAutoString attrValue;
for (uint32_t i = 0; i < attributes; ++i) {
const nsAttrName* attr = mBinding->GetAttrNameAt(i);
nsDependentAtomString attrName = attr->Atom();
mBinding->GetAttr(attr->NamespaceID(), attr->Atom(), attrValue);
rv = aStream->Write8(XBLBinding_Serialize_Attribute);
NS_ENSURE_SUCCESS(rv, rv);
rv = WriteNamespace(aStream, attr->NamespaceID());
NS_ENSURE_SUCCESS(rv, rv);
rv = aStream->WriteWStringZ(attrName.get());
NS_ENSURE_SUCCESS(rv, rv);
rv = aStream->WriteWStringZ(attrValue.get());
NS_ENSURE_SUCCESS(rv, rv);
}
}
aStream->Write8(XBLBinding_Serialize_NoMoreItems);
NS_ENSURE_SUCCESS(rv, rv);
// Write out the resources
if (mResources) {
rv = mResources->Write(aStream);

Просмотреть файл

@ -15,7 +15,7 @@ typedef uint8_t XBLBindingSerializeDetails;
// A version number to ensure we don't load cached data in a different
// file format.
#define XBLBinding_Serialize_Version 0x00000003
#define XBLBinding_Serialize_Version 0x00000002
// Set for the first binding in a document
#define XBLBinding_Serialize_IsFirstBinding 1
@ -45,7 +45,6 @@ typedef uint8_t XBLBindingSerializeDetails;
#define XBLBinding_Serialize_Handler 8
#define XBLBinding_Serialize_Image 9
#define XBLBinding_Serialize_Stylesheet 10
#define XBLBinding_Serialize_Attribute 0xA
#define XBLBinding_Serialize_Mask 0x0F
#define XBLBinding_Serialize_ReadOnly 0x80

Просмотреть файл

@ -2703,7 +2703,8 @@ def getJSToNativeConversionInfo(type, descriptorProvider, failureCode=None,
# A helper function for wrapping up the template body for
# possibly-nullable objecty stuff
def wrapObjectTemplate(templateBody, type, codeToSetNull, failureCode=None):
if isNullOrUndefined and type.nullable():
if isNullOrUndefined:
assert type.nullable()
# Just ignore templateBody and set ourselves to null.
# Note that we don't have to worry about default values
# here either, since we already examined this value.
@ -3320,6 +3321,9 @@ for (uint32_t i = 0; i < length; ++i) {
"Default": "eStringify",
"EmptyString": "eEmpty",
"Null": "eNull",
# For Missing it doesn't matter what we use here, since we'll never
# call ConvertJSValueToString on undefined in that case.
"Missing": "eStringify"
}
if type.nullable():
# For nullable strings null becomes a null string.
@ -3839,8 +3843,11 @@ class CGArgumentConverter(CGThing):
"args[${index}]"
).substitute(replacer)
self.replacementVariables["mutableVal"] = self.replacementVariables["val"]
haveValueCheck = string.Template(
"args.hasDefined(${index})").substitute(replacer)
if argument.treatUndefinedAs == "Missing":
haveValueCheck = "args.hasDefined(${index})"
else:
haveValueCheck = "${index} < args.length()"
haveValueCheck = string.Template(haveValueCheck).substitute(replacer)
self.replacementVariables["haveValue"] = haveValueCheck
self.descriptorProvider = descriptorProvider
if self.argument.optional and not self.argument.defaultValue:
@ -4981,6 +4988,15 @@ class CGMethodCall(CGThing):
CGWrapper(CGIndenter(CGGeneric(code)), pre="\n", post="\n"))
return
# We don't handle [TreatUndefinedAs=Missing] arguments in overload
# resolution yet.
for (_, sigArgs) in signatures:
for arg in sigArgs:
if arg.treatUndefinedAs == "Missing":
raise TypeError("No support for [TreatUndefinedAs=Missing] "
"handling in overload resolution yet: %s" %
arg.location)
# Need to find the right overload
maxArgCount = method.maxArgCount
allowedArgCounts = method.allowedArgCounts
@ -5070,30 +5086,22 @@ class CGMethodCall(CGThing):
else:
failureCode = None
type = distinguishingType(signature)
# The argument at index distinguishingIndex can't possibly be
# unset here, because we've already checked that argc is large
# enough that we can examine this argument. But note that we
# still want to claim that optional arguments are optional, in
# case undefined was passed in.
argIsOptional = (distinguishingArgument(signature).optional and
not distinguishingArgument(signature).defaultValue)
# The argument at index distinguishingIndex can't possibly
# be unset here, because we've already checked that argc is
# large enough that we can examine this argument.
testCode = instantiateJSToNativeConversion(
getJSToNativeConversionInfo(type, descriptor,
failureCode=failureCode,
isDefinitelyObject=isDefinitelyObject,
isNullOrUndefined=isNullOrUndefined,
isOptional=argIsOptional,
sourceDescription=(argDesc % (distinguishingIndex + 1))),
{
"declName" : "arg%d" % distinguishingIndex,
"holderName" : ("arg%d" % distinguishingIndex) + "_holder",
"val" : distinguishingArg,
"mutableVal" : distinguishingArg,
"obj" : "obj",
"haveValue": "args.hasDefined(%d)" % distinguishingIndex
},
checkForValue=argIsOptional
)
"obj" : "obj"
})
caseBody.append(CGIndenter(testCode, indent));
# If we got this far, we know we unwrapped to the right
# C++ type, so just do the call. Start conversion with
@ -5103,76 +5111,24 @@ class CGMethodCall(CGThing):
getPerSignatureCall(signature, distinguishingIndex + 1),
indent))
def hasConditionalConversion(type):
"""
Return whether the argument conversion for this type will be
conditional on the type of incoming JS value. For example, for
interface types the conversion is conditional on the incoming
value being isObject().
For the types for which this returns false, we do not have to
output extra isUndefined() or isNullOrUndefined() cases, because
null/undefined values will just fall through into our
unconditional conversion.
"""
if type.isString() or type.isEnum():
return False
if type.isBoolean():
distinguishingTypes = (distinguishingType(s) for s in
possibleSignatures)
return any(t.isString() or t.isEnum() or t.isNumeric()
for t in distinguishingTypes)
if type.isNumeric():
distinguishingTypes = (distinguishingType(s) for s in
possibleSignatures)
return any(t.isString() or t.isEnum()
for t in distinguishingTypes)
return True
def needsNullOrUndefinedCase(type):
"""
Return true if the type needs a special isNullOrUndefined() case
"""
return ((type.nullable() and
hasConditionalConversion(type)) or
type.isDictionary())
# First check for undefined and optional distinguishing arguments
# and output a special branch for that case. Note that we don't
# use distinguishingArgument here because we actualy want to
# exclude variadic arguments. Also note that we skip this check if
# we plan to output a isNullOrUndefined() special case for this
# argument anyway, since that will subsume our isUndefined() check.
# This is safe, because there can be at most one nullable
# distinguishing argument, so if we're it we'll definitely get
# picked up by the nullable handling. Also, we can skip this check
# if the argument has an unconditional conversion later on.
undefSigs = [s for s in possibleSignatures if
distinguishingIndex < len(s[1]) and
s[1][distinguishingIndex].optional and
hasConditionalConversion(s[1][distinguishingIndex].type) and
not needsNullOrUndefinedCase(s[1][distinguishingIndex].type)]
# Can't have multiple signatures with an optional argument at the
# same index.
assert len(undefSigs) < 2
if len(undefSigs) > 0:
caseBody.append(CGGeneric("if (%s.isUndefined()) {" %
distinguishingArg))
tryCall(undefSigs[0], 2, isNullOrUndefined=True)
caseBody.append(CGGeneric("}"))
# Next, check for null or undefined. That means looking for
# First check for null or undefined. That means looking for
# nullable arguments at the distinguishing index and outputting a
# separate branch for them. But if the nullable argument has an
# unconditional conversion, we don't need to do that. The reason
# separate branch for them. But if the nullable argument is a
# primitive, string, or enum, we don't need to do that. The reason
# for that is that at most one argument at the distinguishing index
# is nullable (since two nullable arguments are not
# distinguishable), and null/undefined values will always fall
# through to the unconditional conversion we have, if any, since
# they will fail whatever the conditions on the input value are for
# our other conversions.
# distinguishable), and all the argument types other than
# primitive/string/enum end up inside isObject() checks. So if our
# nullable is a primitive/string/enum it's safe to not output the
# extra branch: we'll fall through to conversion for those types,
# which correctly handles null as needed, because isObject() will be
# false for null and undefined.
nullOrUndefSigs = [s for s in possibleSignatures
if needsNullOrUndefinedCase(distinguishingType(s))]
if ((distinguishingType(s).nullable() and not
distinguishingType(s).isString() and not
distinguishingType(s).isEnum() and not
distinguishingType(s).isPrimitive()) or
distinguishingType(s).isDictionary())]
# Can't have multiple nullable types here
assert len(nullOrUndefSigs) < 2
if len(nullOrUndefSigs) > 0:

Просмотреть файл

@ -81,6 +81,11 @@ public:
return !Equals(aOtherNullable);
}
operator bool() const
{
return !mIsNull;
}
// Make it possible to use a const Nullable of an array type with other
// array types.
template<typename U>

Просмотреть файл

@ -401,7 +401,12 @@ class IDLObjectWithIdentifier(IDLObject):
if isDictionaryMember:
raise WebIDLError("[TreatUndefinedAs] is not allowed for "
"dictionary members", [self.location])
if value == 'Null':
if value == 'Missing':
if not isOptional:
raise WebIDLError("[TreatUndefinedAs=Missing] is only "
"allowed on optional arguments",
[self.location])
elif value == 'Null':
if not self.type.isDOMString():
raise WebIDLError("[TreatUndefinedAs=Null] is only "
"allowed on arguments or "
@ -421,8 +426,8 @@ class IDLObjectWithIdentifier(IDLObject):
[self.location])
else:
raise WebIDLError("[TreatUndefinedAs] must take the "
"identifiers EmptyString or Null",
[self.location])
"identifiers EmptyString or Null or "
"Missing", [self.location])
self.treatUndefinedAs = value
else:
unhandledAttrs.append(attr)
@ -3138,12 +3143,15 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
def finish(self, scope):
for overload in self._overloads:
inOptionalArguments = False
variadicArgument = None
arguments = overload.arguments
for (idx, argument) in enumerate(arguments):
if not argument.isComplete():
argument.complete(scope)
if argument.isComplete():
continue
argument.complete(scope)
assert argument.type.isComplete()
if (argument.type.isDictionary() or
@ -3153,7 +3161,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
# end of the list or followed by optional arguments must be
# optional.
if (not argument.optional and
all(arg.optional for arg in arguments[idx+1:])):
(idx == len(arguments) - 1 or arguments[idx+1].optional)):
raise WebIDLError("Dictionary argument or union "
"argument containing a dictionary "
"not followed by a required argument "
@ -3171,6 +3179,13 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
if variadicArgument:
raise WebIDLError("Variadic argument is not last argument",
[variadicArgument.location])
# Once we see an optional argument, there can't be any non-optional
# arguments.
if inOptionalArguments and not argument.optional:
raise WebIDLError("Non-optional argument after optional "
"arguments",
[argument.location])
inOptionalArguments = argument.optional
if argument.variadic:
variadicArgument = argument
@ -3215,7 +3230,7 @@ class IDLMethod(IDLInterfaceMember, IDLScope):
return [overload for overload in self._overloads if
len(overload.arguments) == argc or
(len(overload.arguments) > argc and
all(arg.optional for arg in overload.arguments[argc:])) or
overload.arguments[argc].optional) or
(len(overload.arguments) < argc and
len(overload.arguments) > 0 and
overload.arguments[-1].variadic)]
@ -4045,6 +4060,21 @@ class Parser(Tokenizer):
raise WebIDLError("stringifier must have DOMString return type",
[self.getLocation(p, 2)])
inOptionalArguments = False
variadicArgument = False
for argument in arguments:
# Only the last argument can be variadic
if variadicArgument:
raise WebIDLError("Only the last argument can be variadic",
[variadicArgument.location])
# Once we see an optional argument, there can't be any non-optional
# arguments.
if inOptionalArguments and not argument.optional:
raise WebIDLError("Cannot have a non-optional argument following an optional argument",
[argument.location])
inOptionalArguments = argument.optional
variadicArgument = argument if argument.variadic else None
# identifier might be None. This is only permitted for special methods.
if not identifier:
if not getter and not setter and not creator and \

Просмотреть файл

@ -171,23 +171,6 @@ def WebIDLTest(parser, harness):
harness.ok(threw, "Dictionary arg followed by optional arg must be optional")
parser = parser.reset()
threw = False
try:
parser.parse("""
dictionary A {
};
interface X {
void doFoo(A arg1, optional long arg2, long arg3);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(not threw,
"Dictionary arg followed by non-optional arg doesn't have to be optional")
parser = parser.reset()
threw = False
try:

Просмотреть файл

@ -11,9 +11,9 @@ def WebIDLTest(parser, harness):
except:
threw = True
harness.ok(not threw,
"Should not have thrown on non-optional argument following "
"optional argument.")
harness.ok(threw,
"Should have thrown on non-optional argument following optional "
"argument.")
parser = parser.reset()
parser.parse("""

Просмотреть файл

@ -11,8 +11,6 @@ def WebIDLTest(parser, harness):
void withVariadics(long... numbers);
void withVariadics(TestOverloads iface);
void withVariadics(long num, TestOverloads iface);
void optionalTest();
void optionalTest(optional long num1, long num2);
};
""")
@ -25,7 +23,7 @@ def WebIDLTest(parser, harness):
"Should be an IDLInterface")
harness.check(iface.identifier.QName(), "::TestOverloads", "Interface has the right QName")
harness.check(iface.identifier.name, "TestOverloads", "Interface has the right name")
harness.check(len(iface.members), 4, "Expect %s members" % 4)
harness.check(len(iface.members), 3, "Expect %s members" % 3)
member = iface.members[0]
harness.check(member.identifier.QName(), "::TestOverloads::basic", "Method has the right QName")
@ -50,11 +48,3 @@ def WebIDLTest(parser, harness):
harness.check(argument.identifier.QName(), "::TestOverloads::basic::arg1", "Argument has the right QName")
harness.check(argument.identifier.name, "arg1", "Argument has the right name")
harness.check(str(argument.type), "Long", "Argument has the right type")
member = iface.members[3]
harness.check(len(member.overloadsForArgCount(0)), 1,
"Only one overload for no args")
harness.check(len(member.overloadsForArgCount(1)), 0,
"No overloads for one arg")
harness.check(len(member.overloadsForArgCount(2)), 1,
"Only one overload for two args")

Просмотреть файл

@ -1,62 +1,51 @@
def WebIDLTest(parser, harness):
threw = False
try:
parser.parse("""
results = parser.parse("""
interface VariadicConstraints1 {
void foo(byte... arg1, byte arg2);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should have thrown on variadic argument followed by required "
"argument.")
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
results = parser.parse("""
interface VariadicConstraints2 {
void foo(byte... arg1, optional byte arg2);
};
""")
results = parser.finish();
except:
threw = True
harness.ok(threw,
"Should have thrown on variadic argument followed by optional "
"argument.")
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
results = parser.parse("""
interface VariadicConstraints3 {
void foo(optional byte... arg1);
};
""")
results = parser.finish()
except:
threw = True
harness.ok(threw,
"Should have thrown on variadic argument explicitly flagged as "
"optional.")
harness.ok(threw, "Should have thrown.")
parser = parser.reset()
threw = False
try:
parser.parse("""
results = parser.parse("""
interface VariadicConstraints4 {
void foo(byte... arg1 = 0);
};
""")
results = parser.finish()
except:
threw = True

Просмотреть файл

@ -161,9 +161,9 @@ public:
void PassByte(int8_t);
int8_t ReceiveByte();
void PassOptionalByte(const Optional<int8_t>&);
void PassOptionalByteBeforeRequired(const Optional<int8_t>&, int8_t);
void PassOptionalUndefinedMissingByte(const Optional<int8_t>&);
void PassOptionalByteWithDefault(int8_t);
void PassOptionalByteWithDefaultBeforeRequired(int8_t, int8_t);
void PassOptionalUndefinedMissingByteWithDefault(int8_t);
void PassNullableByte(const Nullable<int8_t>&);
void PassOptionalNullableByte(const Optional< Nullable<int8_t> >&);
void PassVariadicByte(const Sequence<int8_t>&);
@ -410,7 +410,9 @@ public:
void PassString(const nsAString&);
void PassNullableString(const nsAString&);
void PassOptionalString(const Optional<nsAString>&);
void PassOptionalUndefinedMissingString(const Optional<nsAString>&);
void PassOptionalStringWithDefaultValue(const nsAString&);
void PassOptionalUndefinedMissingStringWithDefaultValue(const nsAString&);
void PassOptionalNullableString(const Optional<nsAString>&);
void PassOptionalNullableStringWithDefaultValue(const nsAString&);
void PassVariadicString(const Sequence<nsString>&);
@ -629,22 +631,6 @@ public:
void Overload7(const nsCString&);
void Overload8(int32_t);
void Overload8(TestInterface&);
void Overload9(const Nullable<int32_t>&);
void Overload9(const nsAString&);
void Overload10(const Nullable<int32_t>&);
void Overload10(JSContext*, JS::Handle<JSObject*>);
void Overload11(int32_t);
void Overload11(const nsAString&);
void Overload12(int32_t);
void Overload12(const Nullable<bool>&);
void Overload13(const Nullable<int32_t>&);
void Overload13(bool);
void Overload14(const Optional<int32_t>&);
void Overload14(TestInterface&);
void Overload15(int32_t);
void Overload15(const Optional<NonNull<TestInterface> >&);
void Overload16(int32_t);
void Overload16(const Optional<TestInterface*>&);
// Variadic handling
void PassVariadicThirdArg(const nsAString&, int32_t,

Просмотреть файл

@ -118,9 +118,9 @@ interface TestInterface {
void passByte(byte arg);
byte receiveByte();
void passOptionalByte(optional byte arg);
void passOptionalByteBeforeRequired(optional byte arg1, byte arg2);
void passOptionalUndefinedMissingByte([TreatUndefinedAs=Missing] optional byte arg);
void passOptionalByteWithDefault(optional byte arg = 0);
void passOptionalByteWithDefaultBeforeRequired(optional byte arg1 = 0, byte arg2);
void passOptionalUndefinedMissingByteWithDefault([TreatUndefinedAs=Missing] optional byte arg = 0);
void passNullableByte(byte? arg);
void passOptionalNullableByte(optional byte? arg);
void passVariadicByte(byte... arg);
@ -365,7 +365,9 @@ interface TestInterface {
void passString(DOMString arg);
void passNullableString(DOMString? arg);
void passOptionalString(optional DOMString arg);
void passOptionalUndefinedMissingString([TreatUndefinedAs=Missing] optional DOMString arg);
void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
void passOptionalUndefinedMissingStringWithDefaultValue([TreatUndefinedAs=Missing] optional DOMString arg = "abc");
void passOptionalNullableString(optional DOMString? arg);
void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
void passVariadicString(DOMString... arg);
@ -579,22 +581,6 @@ interface TestInterface {
void overload7(ByteString arg);
void overload8(long arg);
void overload8(TestInterface arg);
void overload9(long? arg);
void overload9(DOMString arg);
void overload10(long? arg);
void overload10(object arg);
void overload11(long arg);
void overload11(DOMString? arg);
void overload12(long arg);
void overload12(boolean? arg);
void overload13(long? arg);
void overload13(boolean arg);
void overload14(optional long arg);
void overload14(TestInterface arg);
void overload15(long arg);
void overload15(optional TestInterface arg);
void overload16(long arg);
void overload16(optional TestInterface? arg);
// Variadic handling
void passVariadicThirdArg(DOMString arg1, long arg2, TestInterface... arg3);

Просмотреть файл

@ -23,9 +23,9 @@ interface TestExampleInterface {
void passByte(byte arg);
byte receiveByte();
void passOptionalByte(optional byte arg);
void passOptionalByteBeforeRequired(optional byte arg1, byte arg2);
void passOptionalUndefinedMissingByte([TreatUndefinedAs=Missing] optional byte arg);
void passOptionalByteWithDefault(optional byte arg = 0);
void passOptionalByteWithDefaultBeforeRequired(optional byte arg1 = 0, byte arg2);
void passOptionalUndefinedMissingByteWithDefault([TreatUndefinedAs=Missing] optional byte arg = 0);
void passNullableByte(byte? arg);
void passOptionalNullableByte(optional byte? arg);
void passVariadicByte(byte... arg);
@ -263,7 +263,9 @@ interface TestExampleInterface {
void passString(DOMString arg);
void passNullableString(DOMString? arg);
void passOptionalString(optional DOMString arg);
void passOptionalUndefinedMissingString([TreatUndefinedAs=Missing] optional DOMString arg);
void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
void passOptionalUndefinedMissingStringWithDefaultValue([TreatUndefinedAs=Missing] optional DOMString arg = "abc");
void passOptionalNullableString(optional DOMString? arg);
void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
void passVariadicString(DOMString... arg);
@ -476,22 +478,6 @@ interface TestExampleInterface {
void overload7(ByteString arg);
void overload8(long arg);
void overload8(TestInterface arg);
void overload9(long? arg);
void overload9(DOMString arg);
void overload10(long? arg);
void overload10(object arg);
void overload11(long arg);
void overload11(DOMString? arg);
void overload12(long arg);
void overload12(boolean? arg);
void overload13(long? arg);
void overload13(boolean arg);
void overload14(optional long arg);
void overload14(TestInterface arg);
void overload15(long arg);
void overload15(optional TestInterface arg);
void overload16(long arg);
void overload16(optional TestInterface? arg);
// Variadic handling
void passVariadicThirdArg(DOMString arg1, long arg2, TestInterface... arg3);

Просмотреть файл

@ -35,9 +35,9 @@ interface TestJSImplInterface {
void passByte(byte arg);
byte receiveByte();
void passOptionalByte(optional byte arg);
void passOptionalByteBeforeRequired(optional byte arg1, byte arg2);
void passOptionalUndefinedMissingByte([TreatUndefinedAs=Missing] optional byte arg);
void passOptionalByteWithDefault(optional byte arg = 0);
void passOptionalByteWithDefaultBeforeRequired(optional byte arg1 = 0, byte arg2);
void passOptionalUndefinedMissingByteWithDefault([TreatUndefinedAs=Missing] optional byte arg = 0);
void passNullableByte(byte? arg);
void passOptionalNullableByte(optional byte? arg);
void passVariadicByte(byte... arg);
@ -285,7 +285,9 @@ interface TestJSImplInterface {
void passString(DOMString arg);
void passNullableString(DOMString? arg);
void passOptionalString(optional DOMString arg);
void passOptionalUndefinedMissingString([TreatUndefinedAs=Missing] optional DOMString arg);
void passOptionalStringWithDefaultValue(optional DOMString arg = "abc");
void passOptionalUndefinedMissingStringWithDefaultValue([TreatUndefinedAs=Missing] optional DOMString arg = "abc");
void passOptionalNullableString(optional DOMString? arg);
void passOptionalNullableStringWithDefaultValue(optional DOMString? arg = null);
void passVariadicString(DOMString... arg);
@ -504,22 +506,6 @@ interface TestJSImplInterface {
void overload7(ByteString arg);
void overload8(long arg);
void overload8(TestJSImplInterface arg);
void overload9(long? arg);
void overload9(DOMString arg);
void overload10(long? arg);
void overload10(object arg);
void overload11(long arg);
void overload11(DOMString? arg);
void overload12(long arg);
void overload12(boolean? arg);
void overload13(long? arg);
void overload13(boolean arg);
void overload14(optional long arg);
void overload14(TestInterface arg);
void overload15(long arg);
void overload15(optional TestInterface arg);
void overload16(long arg);
void overload16(optional TestInterface? arg);
// Variadic handling
void passVariadicThirdArg(DOMString arg1, long arg2, TestJSImplInterface... arg3);

Просмотреть файл

@ -18,21 +18,17 @@ function checkDoc(title, expectedtitle, normalizedtitle) {
assert_equals(doc.doctype.systemId, "")
assert_equals(doc.documentElement.localName, "html")
assert_equals(doc.documentElement.firstChild.localName, "head")
if (title !== undefined) {
assert_equals(doc.documentElement.firstChild.childNodes.length, 1)
assert_equals(doc.documentElement.firstChild.firstChild.localName, "title")
assert_equals(doc.documentElement.firstChild.firstChild.firstChild.data,
expectedtitle)
} else {
assert_equals(doc.documentElement.firstChild.childNodes.length, 0)
}
assert_equals(doc.documentElement.firstChild.childNodes.length, 1)
assert_equals(doc.documentElement.firstChild.firstChild.localName, "title")
assert_equals(doc.documentElement.firstChild.firstChild.firstChild.data,
expectedtitle)
assert_equals(doc.documentElement.lastChild.localName, "body")
assert_equals(doc.documentElement.lastChild.childNodes.length, 0)
})
}
checkDoc("", "", "")
checkDoc(null, "null", "null")
checkDoc(undefined, "", "")
checkDoc(undefined, "undefined", "undefined")
checkDoc("foo bar baz", "foo bar baz", "foo bar baz")
checkDoc("foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz")
checkDoc("foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz")

Просмотреть файл

@ -12,7 +12,7 @@ function checkDoc(title, expectedtitle, normalizedtitle) {
}
checkDoc("", "", "")
checkDoc(null, "null", "null")
checkDoc(undefined, "", "")
checkDoc(undefined, "undefined", "undefined")
checkDoc("foo bar baz", "foo bar baz", "foo bar baz")
checkDoc("foo\t\tbar baz", "foo\t\tbar baz", "foo bar baz")
checkDoc("foo\n\nbar baz", "foo\n\nbar baz", "foo bar baz")

Просмотреть файл

@ -2802,7 +2802,7 @@ QuotaManager::FindSynchronizedOp(const nsACString& aPattern,
for (uint32_t index = 0; index < mSynchronizedOps.Length(); index++) {
const nsAutoPtr<SynchronizedOp>& currentOp = mSynchronizedOps[index];
if (PatternMatchesOrigin(aPattern, currentOp->mOriginOrPattern) &&
(currentOp->mPersistenceType.IsNull() ||
(!currentOp->mPersistenceType ||
currentOp->mPersistenceType == aPersistenceType) &&
(!currentOp->mId || currentOp->mId == aId)) {
return currentOp;
@ -3067,7 +3067,7 @@ QuotaManager::CollectOriginsForEviction(uint64_t aMinSizeToBeFreed,
uint32_t index;
for (index = 0; index < mSynchronizedOps.Length(); index++) {
nsAutoPtr<SynchronizedOp>& op = mSynchronizedOps[index];
if (op->mPersistenceType.IsNull() ||
if (!op->mPersistenceType ||
op->mPersistenceType.Value() == PERSISTENCE_TYPE_TEMPORARY) {
if (op->mOriginOrPattern.IsPattern() &&
!originCollection.ContainsPattern(op->mOriginOrPattern)) {
@ -3078,7 +3078,7 @@ QuotaManager::CollectOriginsForEviction(uint64_t aMinSizeToBeFreed,
for (index = 0; index < mSynchronizedOps.Length(); index++) {
nsAutoPtr<SynchronizedOp>& op = mSynchronizedOps[index];
if (op->mPersistenceType.IsNull() ||
if (!op->mPersistenceType ||
op->mPersistenceType.Value() == PERSISTENCE_TYPE_TEMPORARY) {
if (op->mOriginOrPattern.IsOrigin() &&
!originCollection.ContainsOrigin(op->mOriginOrPattern)) {

Просмотреть файл

@ -74,7 +74,7 @@ interface CanvasRenderingContext2D {
// path API (see also CanvasPathMethods)
void beginPath();
void fill(optional CanvasWindingRule winding = "nonzero");
void fill([TreatUndefinedAs=Missing] optional CanvasWindingRule winding = "nonzero");
// NOT IMPLEMENTED void fill(Path path);
void stroke();
// NOT IMPLEMENTED void stroke(Path path);
@ -84,10 +84,10 @@ interface CanvasRenderingContext2D {
// NOT IMPLEMENTED boolean drawCustomFocusRing(Path path, Element element);
// NOT IMPLEMENTED void scrollPathIntoView();
// NOT IMPLEMENTED void scrollPathIntoView(Path path);
void clip(optional CanvasWindingRule winding = "nonzero");
void clip([TreatUndefinedAs=Missing] optional CanvasWindingRule winding = "nonzero");
// NOT IMPLEMENTED void clip(Path path);
// NOT IMPLEMENTED void resetClip();
boolean isPointInPath(unrestricted double x, unrestricted double y, optional CanvasWindingRule winding = "nonzero");
boolean isPointInPath(unrestricted double x, unrestricted double y, [TreatUndefinedAs=Missing] optional CanvasWindingRule winding = "nonzero");
// NOT IMPLEMENTED boolean isPointInPath(Path path, unrestricted double x, unrestricted double y);
boolean isPointInStroke(double x, double y);

Просмотреть файл

@ -28,9 +28,9 @@ interface Promise {
static Promise reject(any value);
[Creator]
Promise then(optional AnyCallback fulfillCallback,
optional AnyCallback rejectCallback);
Promise then([TreatUndefinedAs=Missing] optional AnyCallback fulfillCallback,
[TreatUndefinedAs=Missing] optional AnyCallback rejectCallback);
[Creator]
Promise catch(optional AnyCallback rejectCallback);
Promise catch([TreatUndefinedAs=Missing] optional AnyCallback rejectCallback);
};

Просмотреть файл

@ -71,9 +71,7 @@ interface XMLHttpRequest : XMLHttpRequestEventTarget {
// request
[Throws]
void open(ByteString method, DOMString url);
[Throws]
void open(ByteString method, DOMString url, boolean async,
void open(ByteString method, DOMString url, optional boolean async = true,
optional DOMString? user, optional DOMString? password);
[Throws]
void setRequestHeader(ByteString header, ByteString value);

Просмотреть файл

@ -121,11 +121,6 @@ public:
return mStateData.mReadyState;
}
void Open(const nsACString& aMethod, const nsAString& aUrl, ErrorResult& aRv)
{
Open(aMethod, aUrl, true, Optional<nsAString>(),
Optional<nsAString>(), aRv);
}
void
Open(const nsACString& aMethod, const nsAString& aUrl, bool aAsync,
const Optional<nsAString>& aUser, const Optional<nsAString>& aPassword,

Просмотреть файл

@ -289,7 +289,7 @@ ExposeGCThingToActiveJS(void *thing, JSGCTraceKind kind)
* All live objects in the nursery are moved to tenured at the beginning of
* each GC slice, so the gray marker never sees nursery things.
*/
if (uintptr_t(thing) >= rt->gcNurseryStart_ && uintptr_t(thing) < rt->gcNurseryEnd_)
if (js::gc::IsInsideNursery(rt, thing))
return;
#endif
if (IsIncrementalBarrierNeededOnGCThing(rt, thing, kind))

Просмотреть файл

@ -149,6 +149,16 @@ GetGCThingArena(void *thing)
return reinterpret_cast<JS::shadow::ArenaHeader *>(addr);
}
JS_ALWAYS_INLINE bool
IsInsideNursery(const JS::shadow::Runtime *runtime, const void *p)
{
#ifdef JSGC_GENERATIONAL
return uintptr_t(p) >= runtime->gcNurseryStart_ && uintptr_t(p) < runtime->gcNurseryEnd_;
#else
return false;
#endif
}
} /* namespace gc */
} /* namespace js */
@ -178,7 +188,7 @@ GCThingIsMarkedGray(void *thing)
* each GC slice, so the gray marker never sees nursery things.
*/
JS::shadow::Runtime *rt = js::gc::GetGCThingRuntime(thing);
if (uintptr_t(thing) >= rt->gcNurseryStart_ && uintptr_t(thing) < rt->gcNurseryEnd_)
if (js::gc::IsInsideNursery(rt, thing))
return false;
#endif
uintptr_t *word, mask;

Просмотреть файл

@ -38,6 +38,16 @@ template <typename T> class AutoVectorRooter;
template<typename K, typename V> class AutoHashMapRooter;
template<typename T> class AutoHashSetRooter;
class JS_PUBLIC_API(ContextOptions);
class JS_PUBLIC_API(AutoSaveContextOptions);
JS_PUBLIC_API(ContextOptions &) ContextOptionsRef(JSContext *cx);
class ContextOptions;
class AutoSaveContextOptions;
ContextOptions &ContextOptionsRef(JSContext *cx);
}
// Do the importing.
@ -112,6 +122,10 @@ using JS::MutableHandleValue;
using JS::Zone;
using JS::ContextOptions;
using JS::ContextOptionsRef;
using JS::AutoSaveContextOptions;
} /* namespace js */
#endif /* NamespaceImports_h */

Просмотреть файл

@ -1049,7 +1049,7 @@ Cell::isTenured() const
{
#ifdef JSGC_GENERATIONAL
JS::shadow::Runtime *rt = js::gc::GetGCThingRuntime(this);
return uintptr_t(this) < rt->gcNurseryStart_ || uintptr_t(this) >= rt->gcNurseryEnd_;
return !IsInsideNursery(rt, this);
#endif
return true;
}

Просмотреть файл

@ -66,7 +66,7 @@ class Nursery
template <typename T>
JS_ALWAYS_INLINE bool isInside(const T *p) const {
return uintptr_t(p) >= start() && uintptr_t(p) < heapEnd();
return gc::IsInsideNursery((JS::shadow::Runtime *)runtime_, p);
}
/*

Просмотреть файл

@ -0,0 +1,25 @@
var c = 0;
function g(o) {
try {
for(;;)
o.next();
} catch(e) {
c += e;
}
return o.x;
}
function f() {
var o = {x: 0, next: function() {
if (this.x++ > 100)
throw 3;
}};
g(o);
assertEq(o.x, 102);
o.x = 0;
g(o);
assertEq(o.x, 102);
}
f();
assertEq(c, 6);

Просмотреть файл

@ -0,0 +1,16 @@
// |jit-test| error: 4
function g(o) {
if (o.x >= 0) {
for(;;)
o.next();
}
return o.x;
}
function f() {
var o = {x: 0, next: function() {
if (this.x++ > 100)
throw 4;
}};
g(o);
}
f();

Просмотреть файл

@ -0,0 +1,20 @@
// |jit-test| error: 4
function h(o) {
o.next();
}
function g(o) {
for (var i=0; i<5; i++) {};
if (o.x >= 0) {
for(;;)
h(o);
}
return o.x;
}
function f() {
var o = {x: 0, next: function() {
if (this.x++ > 100)
throw 4;
}};
g(o);
}
f();

Просмотреть файл

@ -73,9 +73,13 @@ BlockMightReach(MBasicBlock *src, MBasicBlock *dest)
switch (src->numSuccessors()) {
case 0:
return false;
case 1:
src = src->getSuccessor(0);
case 1: {
MBasicBlock *successor = src->getSuccessor(0);
if (successor->id() <= src->id())
return true; // Don't iloop.
src = successor;
break;
}
default:
return true;
}

Просмотреть файл

@ -6540,7 +6540,7 @@ js::IsAsmJSCompilationAvailable(JSContext *cx, unsigned argc, Value *vp)
bool available = JSC::MacroAssembler::supportsFloatingPoint() &&
cx->gcSystemPageSize() == AsmJSPageSize &&
!cx->compartment()->debugMode() &&
cx->hasOption(JSOPTION_ASMJS);
cx->options().asmJS();
args.rval().set(BooleanValue(available));
return true;

Просмотреть файл

@ -274,7 +274,7 @@ struct BaselineScript
inline bool
IsBaselineEnabled(JSContext *cx)
{
return cx->hasOption(JSOPTION_BASELINE);
return cx->options().baseline();
}
MethodStatus

Просмотреть файл

@ -363,8 +363,8 @@ void FinishOffThreadBuilder(IonBuilder *builder);
static inline bool
IsIonEnabled(JSContext *cx)
{
return cx->hasOption(JSOPTION_ION) &&
cx->hasOption(JSOPTION_BASELINE) &&
return cx->options().ion() &&
cx->options().baseline() &&
cx->typeInferenceEnabled();
}

Просмотреть файл

@ -131,8 +131,10 @@ virtual
JSContext *createContext()
{
JSContext *cx = JSAPITest::createContext();
if (cx)
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_BASELINE | JSOPTION_ION);
if (!cx)
return NULL;
ContextOptionsRef(cx).setBaseline(true)
.setIon(true);
return cx;
}

Просмотреть файл

@ -9,8 +9,7 @@ BEGIN_TEST(testJSEvaluateScript)
JS::RootedObject obj(cx, JS_NewObject(cx, nullptr, nullptr, global));
CHECK(obj);
uint32_t options = JS_GetOptions(cx);
CHECK(options & JSOPTION_VAROBJFIX);
CHECK(ContextOptionsRef(cx).varObjFix());
static const char src[] = "var x = 5;";
@ -27,7 +26,7 @@ BEGIN_TEST(testJSEvaluateScript)
CHECK(hasProp);
// Now do the same thing, but without JSOPTION_VAROBJFIX
JS_SetOptions(cx, options & ~JSOPTION_VAROBJFIX);
ContextOptionsRef(cx).setVarObjFix(false);
static const char src2[] = "var y = 5;";

Просмотреть файл

@ -141,7 +141,8 @@ END_TEST(testProfileStrings_isCalledWithInterpreter)
BEGIN_TEST(testProfileStrings_isCalledWithJIT)
{
CHECK(initialize(cx));
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_BASELINE | JSOPTION_ION);
ContextOptionsRef(cx).setBaseline(true)
.setIon(true);
EXEC("function g() { var p = new Prof(); p.test_fn(); }");
EXEC("function f() { g(); }");
@ -189,12 +190,13 @@ END_TEST(testProfileStrings_isCalledWithJIT)
BEGIN_TEST(testProfileStrings_isCalledWhenError)
{
CHECK(initialize(cx));
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_BASELINE | JSOPTION_ION);
ContextOptionsRef(cx).setBaseline(true)
.setIon(true);
EXEC("function check2() { throw 'a'; }");
reset(cx);
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_DONT_REPORT_UNCAUGHT);
ContextOptionsRef(cx).setDontReportUncaught(true);
{
JS::RootedValue rval(cx);
/* Make sure the stack resets and we have an entry for each stack */
@ -212,7 +214,8 @@ END_TEST(testProfileStrings_isCalledWhenError)
BEGIN_TEST(testProfileStrings_worksWhenEnabledOnTheFly)
{
CHECK(initialize(cx));
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_BASELINE | JSOPTION_ION);
ContextOptionsRef(cx).setBaseline(true)
.setIon(true);
EXEC("function b(p) { p.test_fn(); }");
EXEC("function a() { var p = new Prof(); p.enable(); b(p); }");

Просмотреть файл

@ -300,7 +300,7 @@ class JSAPITest
JSContext *cx = JS_NewContext(rt, 8192);
if (!cx)
return nullptr;
JS_SetOptions(cx, JSOPTION_VAROBJFIX);
ContextOptionsRef(cx).setVarObjFix(true);
JS_SetErrorReporter(cx, &reportError);
return cx;
}

Просмотреть файл

@ -964,6 +964,48 @@ JS_StringToVersion(const char *string)
return JSVERSION_UNKNOWN;
}
static unsigned
GetOptionsCommon(JSContext *cx)
{
return (cx->options().extraWarnings() ? JSOPTION_EXTRA_WARNINGS : 0)
| (cx->options().werror() ? JSOPTION_WERROR : 0)
| (cx->options().varObjFix() ? JSOPTION_VAROBJFIX : 0)
| (cx->options().privateIsNSISupports() ? JSOPTION_PRIVATE_IS_NSISUPPORTS : 0)
| (cx->options().compileAndGo() ? JSOPTION_COMPILE_N_GO : 0)
| (cx->options().dontReportUncaught() ? JSOPTION_DONT_REPORT_UNCAUGHT : 0)
| (cx->options().noDefaultCompartmentObject() ? JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT : 0)
| (cx->options().noScriptRval() ? JSOPTION_NO_SCRIPT_RVAL : 0)
| (cx->options().baseline() ? JSOPTION_BASELINE : 0)
| (cx->options().typeInference() ? JSOPTION_TYPE_INFERENCE : 0)
| (cx->options().strictMode() ? JSOPTION_STRICT_MODE : 0)
| (cx->options().ion() ? JSOPTION_ION : 0)
| (cx->options().asmJS() ? JSOPTION_ASMJS : 0);
}
static unsigned
SetOptionsCommon(JSContext *cx, unsigned newopts)
{
JS_ASSERT((newopts & JSOPTION_MASK) == newopts);
unsigned oldopts = GetOptionsCommon(cx);
cx->options().setExtraWarnings(newopts & JSOPTION_EXTRA_WARNINGS);
cx->options().setWerror(newopts & JSOPTION_WERROR);
cx->options().setVarObjFix(newopts & JSOPTION_VAROBJFIX);
cx->options().setPrivateIsNSISupports(newopts & JSOPTION_PRIVATE_IS_NSISUPPORTS);
cx->options().setCompileAndGo(newopts & JSOPTION_COMPILE_N_GO);
cx->options().setDontReportUncaught(newopts & JSOPTION_DONT_REPORT_UNCAUGHT);
cx->options().setNoDefaultCompartmentObject(newopts & JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT);
cx->options().setNoScriptRval(newopts & JSOPTION_NO_SCRIPT_RVAL);
cx->options().setBaseline(newopts & JSOPTION_BASELINE);
cx->options().setTypeInference(newopts & JSOPTION_TYPE_INFERENCE);
cx->options().setStrictMode(newopts & JSOPTION_STRICT_MODE);
cx->options().setIon(newopts & JSOPTION_ION);
cx->options().setAsmJS(newopts & JSOPTION_ASMJS);
cx->updateJITEnabled();
return oldopts;
}
JS_PUBLIC_API(uint32_t)
JS_GetOptions(JSContext *cx)
{
@ -972,18 +1014,7 @@ JS_GetOptions(JSContext *cx)
* We may have been synchronized with a script version that was formerly on
* the stack, but has now been popped.
*/
return cx->options();
}
static unsigned
SetOptionsCommon(JSContext *cx, unsigned options)
{
JS_ASSERT((options & JSOPTION_MASK) == options);
unsigned oldopts = cx->options();
unsigned newopts = options & JSOPTION_MASK;
cx->setOptions(newopts);
cx->updateJITEnabled();
return oldopts;
return GetOptionsCommon(cx);
}
JS_PUBLIC_API(uint32_t)
@ -995,11 +1026,17 @@ JS_SetOptions(JSContext *cx, uint32_t options)
JS_PUBLIC_API(uint32_t)
JS_ToggleOptions(JSContext *cx, uint32_t options)
{
unsigned oldopts = cx->options();
unsigned oldopts = GetOptionsCommon(cx);
unsigned newopts = oldopts ^ options;
return SetOptionsCommon(cx, newopts);
}
JS_PUBLIC_API(JS::ContextOptions &)
JS::ContextOptionsRef(JSContext *cx)
{
return cx->options();
}
JS_PUBLIC_API(void)
JS_SetJitHardening(JSRuntime *rt, bool enabled)
{
@ -4383,7 +4420,7 @@ struct AutoLastFrameCheck
~AutoLastFrameCheck() {
if (cx->isExceptionPending() &&
!JS_IsRunning(cx) &&
!cx->hasOption(JSOPTION_DONT_REPORT_UNCAUGHT)) {
!cx->options().dontReportUncaught()) {
js_ReportUncaughtException(cx);
}
}
@ -4489,15 +4526,15 @@ JS::CompileOptions::CompileOptions(JSContext *cx, JSVersion version)
lineno(1),
column(0),
element(NullPtr()),
compileAndGo(cx->hasOption(JSOPTION_COMPILE_N_GO)),
compileAndGo(cx->options().compileAndGo()),
forEval(false),
noScriptRval(cx->hasOption(JSOPTION_NO_SCRIPT_RVAL)),
noScriptRval(cx->options().noScriptRval()),
selfHostingMode(false),
canLazilyParse(true),
strictOption(cx->hasOption(JSOPTION_STRICT_MODE)),
extraWarningsOption(cx->hasExtraWarningsOption()),
werrorOption(cx->hasWErrorOption()),
asmJSOption(cx->hasOption(JSOPTION_ASMJS)),
strictOption(cx->options().strictMode()),
extraWarningsOption(cx->options().extraWarnings()),
werrorOption(cx->options().werror()),
asmJSOption(cx->options().asmJS()),
sourcePolicy(SAVE_SOURCE)
{
}

Просмотреть файл

@ -1542,6 +1542,196 @@ JS_SetOptions(JSContext *cx, uint32_t options);
extern JS_PUBLIC_API(uint32_t)
JS_ToggleOptions(JSContext *cx, uint32_t options);
namespace JS {
class JS_PUBLIC_API(ContextOptions) {
public:
ContextOptions()
: extraWarnings_(false),
werror_(false),
varObjFix_(false),
privateIsNSISupports_(false),
compileAndGo_(false),
dontReportUncaught_(false),
noDefaultCompartmentObject_(false),
noScriptRval_(false),
baseline_(false),
typeInference_(false),
strictMode_(false),
ion_(false),
asmJS_(false)
{
}
bool extraWarnings() const { return extraWarnings_; }
ContextOptions &setExtraWarnings(bool flag) {
extraWarnings_ = flag;
return *this;
}
ContextOptions &toggleExtraWarnings() {
extraWarnings_ = !extraWarnings_;
return *this;
}
bool werror() const { return werror_; }
ContextOptions &setWerror(bool flag) {
werror_ = flag;
return *this;
}
ContextOptions &toggleWerror() {
werror_ = !werror_;
return *this;
}
bool varObjFix() const { return varObjFix_; }
ContextOptions &setVarObjFix(bool flag) {
varObjFix_ = flag;
return *this;
}
ContextOptions &toggleVarObjFix() {
varObjFix_ = !varObjFix_;
return *this;
}
bool privateIsNSISupports() const { return privateIsNSISupports_; }
ContextOptions &setPrivateIsNSISupports(bool flag) {
privateIsNSISupports_ = flag;
return *this;
}
ContextOptions &togglePrivateIsNSISupports() {
privateIsNSISupports_ = !privateIsNSISupports_;
return *this;
}
bool compileAndGo() const { return compileAndGo_; }
ContextOptions &setCompileAndGo(bool flag) {
compileAndGo_ = flag;
return *this;
}
ContextOptions &toggleCompileAndGo() {
compileAndGo_ = !compileAndGo_;
return *this;
}
bool dontReportUncaught() const { return dontReportUncaught_; }
ContextOptions &setDontReportUncaught(bool flag) {
dontReportUncaught_ = flag;
return *this;
}
ContextOptions &toggleDontReportUncaught() {
dontReportUncaught_ = !dontReportUncaught_;
return *this;
}
bool noDefaultCompartmentObject() const { return noDefaultCompartmentObject_; }
ContextOptions &setNoDefaultCompartmentObject(bool flag) {
noDefaultCompartmentObject_ = flag;
return *this;
}
ContextOptions &toggleNoDefaultCompartmentObject() {
noDefaultCompartmentObject_ = !noDefaultCompartmentObject_;
return *this;
}
bool noScriptRval() const { return noScriptRval_; }
ContextOptions &setNoScriptRval(bool flag) {
noScriptRval_ = flag;
return *this;
}
ContextOptions &toggleNoScriptRval() {
noScriptRval_ = !noScriptRval_;
return *this;
}
bool baseline() const { return baseline_; }
ContextOptions &setBaseline(bool flag) {
baseline_ = flag;
return *this;
}
ContextOptions &toggleBaseline() {
baseline_ = !baseline_;
return *this;
}
bool typeInference() const { return typeInference_; }
ContextOptions &setTypeInference(bool flag) {
typeInference_ = flag;
return *this;
}
ContextOptions &toggleTypeInference() {
typeInference_ = !typeInference_;
return *this;
}
bool strictMode() const { return strictMode_; }
ContextOptions &setStrictMode(bool flag) {
strictMode_ = flag;
return *this;
}
ContextOptions &toggleStrictMode() {
strictMode_ = !strictMode_;
return *this;
}
bool ion() const { return ion_; }
ContextOptions &setIon(bool flag) {
ion_ = flag;
return *this;
}
ContextOptions &toggleIon() {
ion_ = !ion_;
return *this;
}
bool asmJS() const { return asmJS_; }
ContextOptions &setAsmJS(bool flag) {
asmJS_ = flag;
return *this;
}
ContextOptions &toggleAsmJS() {
asmJS_ = !asmJS_;
return *this;
}
private:
bool extraWarnings_ : 1;
bool werror_ : 1;
bool varObjFix_ : 1;
bool privateIsNSISupports_ : 1;
bool compileAndGo_ : 1;
bool dontReportUncaught_ : 1;
bool noDefaultCompartmentObject_ : 1;
bool noScriptRval_ : 1;
bool baseline_ : 1;
bool typeInference_ : 1;
bool strictMode_ : 1;
bool ion_ : 1;
bool asmJS_ : 1;
};
JS_PUBLIC_API(ContextOptions &)
ContextOptionsRef(JSContext *cx);
class JS_PUBLIC_API(AutoSaveContextOptions) {
public:
AutoSaveContextOptions(JSContext *cx)
: cx_(cx),
oldOptions_(ContextOptionsRef(cx_))
{
}
~AutoSaveContextOptions()
{
ContextOptionsRef(cx_) = oldOptions_;
}
private:
JSContext *cx_;
JS::ContextOptions oldOptions_;
};
} /* namespace JS */
extern JS_PUBLIC_API(void)
JS_SetJitHardening(JSRuntime *rt, bool enabled);

Просмотреть файл

@ -769,7 +769,7 @@ js::WouldDefinePastNonwritableLength(ThreadSafeContext *cx,
JSContext *ncx = cx->asJSContext();
if (!strict && !ncx->hasExtraWarningsOption())
if (!strict && !ncx->options().extraWarnings())
return true;
// XXX include the index and maybe array length in the error message

Просмотреть файл

@ -457,18 +457,18 @@ checkReportFlags(JSContext *cx, unsigned *flags)
JSScript *script = cx->currentScript();
if (script && script->strict)
*flags &= ~JSREPORT_WARNING;
else if (cx->hasExtraWarningsOption())
else if (cx->options().extraWarnings())
*flags |= JSREPORT_WARNING;
else
return true;
} else if (JSREPORT_IS_STRICT(*flags)) {
/* Warning/error only when JSOPTION_STRICT is set. */
if (!cx->hasExtraWarningsOption())
if (!cx->options().extraWarnings())
return true;
}
/* Warnings become errors when JSOPTION_WERROR is set. */
if (JSREPORT_IS_WARNING(*flags) && cx->hasWErrorOption())
if (JSREPORT_IS_WARNING(*flags) && cx->options().werror())
*flags &= ~JSREPORT_WARNING;
return false;
@ -1057,7 +1057,7 @@ JSContext::JSContext(JSRuntime *rt)
: ExclusiveContext(rt, &rt->mainThread, Context_JS),
throwing(false),
exception(UndefinedValue()),
options_(0),
options_(),
reportGranularity(JS_DEFAULT_JITREPORT_GRANULARITY),
resolvingList(nullptr),
generatingError(false),

Просмотреть файл

@ -428,7 +428,7 @@ struct JSContext : public js::ExclusiveContext,
js::Value exception; /* most-recently-thrown exception */
/* Per-context options. */
unsigned options_; /* see jsapi.h for JSOPTION_* */
JS::ContextOptions options_;
public:
int32_t reportGranularity; /* see vm/Probes.h */
@ -463,7 +463,7 @@ struct JSContext : public js::ExclusiveContext,
inline void setDefaultCompartmentObject(JSObject *obj);
inline void setDefaultCompartmentObjectIfUnset(JSObject *obj);
JSObject *maybeDefaultCompartmentObject() const {
JS_ASSERT(!hasOption(JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT));
JS_ASSERT(!options().noDefaultCompartmentObject());
return defaultCompartmentObject_;
}
@ -492,21 +492,14 @@ struct JSContext : public js::ExclusiveContext,
*/
JSVersion findVersion() const;
void setOptions(unsigned opts) {
JS_ASSERT((opts & JSOPTION_MASK) == opts);
options_ = opts;
const JS::ContextOptions &options() const {
return options_;
}
unsigned options() const { return options_; }
bool hasOption(unsigned opt) const {
JS_ASSERT((opt & JSOPTION_MASK) == opt);
return !!(options_ & opt);
JS::ContextOptions &options() {
return options_;
}
bool hasExtraWarningsOption() const { return hasOption(JSOPTION_EXTRA_WARNINGS); }
bool hasWErrorOption() const { return hasOption(JSOPTION_WERROR); }
js::LifoAlloc &tempLifoAlloc() { return runtime()->tempLifoAlloc; }
#ifdef JS_THREADSAFE

Просмотреть файл

@ -433,14 +433,14 @@ JSContext::setPendingException(js::Value v) {
inline void
JSContext::setDefaultCompartmentObject(JSObject *obj)
{
JS_ASSERT(!hasOption(JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT));
JS_ASSERT(!options().noDefaultCompartmentObject());
defaultCompartmentObject_ = obj;
}
inline void
JSContext::setDefaultCompartmentObjectIfUnset(JSObject *obj)
{
if (!hasOption(JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT) &&
if (!options().noDefaultCompartmentObject() &&
!defaultCompartmentObject_)
{
setDefaultCompartmentObject(obj);

Просмотреть файл

@ -91,15 +91,6 @@ ShouldNurseryAllocate(const Nursery &nursery, AllocKind kind, InitialHeap heap)
}
#endif
inline bool
IsInsideNursery(JSRuntime *rt, const void *thing)
{
#ifdef JSGC_GENERATIONAL
return rt->gcNursery.isInside(thing);
#endif
return false;
}
inline JSGCTraceKind
GetGCThingTraceKind(const void *thing)
{

Просмотреть файл

@ -1471,7 +1471,7 @@ void
TypeZone::init(JSContext *cx)
{
if (!cx ||
!cx->hasOption(JSOPTION_TYPE_INFERENCE) ||
!cx->options().typeInference() ||
!cx->runtime()->jitSupportsFloatingPoint)
{
return;

Просмотреть файл

@ -4252,7 +4252,7 @@ GetPropertyHelperInline(JSContext *cx,
}
/* Don't warn if extra warnings not enabled or for random getprop operations. */
if (!cx->hasExtraWarningsOption() || (op != JSOP_GETPROP && op != JSOP_GETELEM))
if (!cx->options().extraWarnings() || (op != JSOP_GETPROP && op != JSOP_GETELEM))
return true;
/* Don't warn repeatedly for the same script. */
@ -4518,7 +4518,7 @@ MaybeReportUndeclaredVarAssignment(JSContext *cx, JSString *propname)
// If the code is not strict and extra warnings aren't enabled, then no
// check is needed.
if (!script->strict && !cx->hasExtraWarningsOption())
if (!script->strict && !cx->options().extraWarnings())
return true;
}
@ -4542,7 +4542,7 @@ js::ReportIfUndeclaredVarAssignment(JSContext *cx, HandleString propname)
// If the code is not strict and extra warnings aren't enabled, then no
// check is needed.
if (!script->strict && !cx->hasExtraWarningsOption())
if (!script->strict && !cx->options().extraWarnings())
return true;
/*
@ -4682,7 +4682,7 @@ baseops::SetPropertyHelper(typename ExecutionModeTraits<mode>::ContextType cxArg
if (pd.isReadonly()) {
if (strict)
return JSObject::reportReadOnly(cx, id, JSREPORT_ERROR);
if (cx->hasExtraWarningsOption())
if (cx->options().extraWarnings())
return JSObject::reportReadOnly(cx, id, JSREPORT_STRICT | JSREPORT_WARNING);
return true;
}
@ -4744,7 +4744,7 @@ baseops::SetPropertyHelper(typename ExecutionModeTraits<mode>::ContextType cxArg
JSContext *cx = cxArg->asJSContext();
if (strict)
return JSObject::reportReadOnly(cx, id, JSREPORT_ERROR);
if (cx->hasExtraWarningsOption())
if (cx->options().extraWarnings())
return JSObject::reportReadOnly(cx, id, JSREPORT_STRICT | JSREPORT_WARNING);
return true;
}
@ -4840,7 +4840,7 @@ baseops::SetPropertyHelper(typename ExecutionModeTraits<mode>::ContextType cxArg
/* Error in strict mode code, warn with extra warnings option, otherwise do nothing. */
if (strict)
return obj->reportNotExtensible(cxArg);
if (mode == SequentialExecution && cxArg->asJSContext()->hasExtraWarningsOption())
if (mode == SequentialExecution && cxArg->asJSContext()->options().extraWarnings())
return obj->reportNotExtensible(cxArg, JSREPORT_STRICT | JSREPORT_WARNING);
return true;
}

Просмотреть файл

@ -411,23 +411,26 @@ RunFile(JSContext *cx, Handle<JSObject*> obj, const char *filename, FILE *file,
ungetc(ch, file);
int64_t t1 = PRMJ_Now();
uint32_t oldopts = JS_GetOptions(cx);
gGotError = false;
JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
CompileOptions options(cx);
options.setUTF8(true)
.setFileAndLine(filename, 1);
RootedScript script(cx);
script = JS::Compile(cx, obj, options, file);
#ifdef DEBUG
if (dumpEntrainedVariables)
AnalyzeEntrainedVariables(cx, script);
#endif
{
AutoSaveContextOptions asco(cx);
ContextOptionsRef(cx).setCompileAndGo(true)
.setNoScriptRval(true);
JS_SetOptions(cx, oldopts);
JS_ASSERT_IF(!script, gGotError);
CompileOptions options(cx);
options.setUTF8(true)
.setFileAndLine(filename, 1);
gGotError = false;
script = JS::Compile(cx, obj, options, file);
JS_ASSERT_IF(!script, gGotError);
}
#ifdef DEBUG
if (dumpEntrainedVariables)
AnalyzeEntrainedVariables(cx, script);
#endif
if (script && !compileOnly) {
if (!JS_ExecuteScript(cx, obj, script, nullptr)) {
if (!gQuitting && !gTimedOut)
@ -570,50 +573,6 @@ Process(JSContext *cx, JSObject *obj_, const char *filename, bool forceTTY)
}
}
/*
* JSContext option name to flag map. The option names are in alphabetical
* order for better reporting.
*/
static const struct JSOption {
const char *name;
uint32_t flag;
} js_options[] = {
{"strict", JSOPTION_EXTRA_WARNINGS},
{"typeinfer", JSOPTION_TYPE_INFERENCE},
{"werror", JSOPTION_WERROR},
{"strict_mode", JSOPTION_STRICT_MODE},
};
static uint32_t
MapContextOptionNameToFlag(JSContext* cx, const char* name)
{
for (size_t i = 0; i < ArrayLength(js_options); ++i) {
if (strcmp(name, js_options[i].name) == 0)
return js_options[i].flag;
}
char* msg = JS_sprintf_append(nullptr,
"unknown option name '%s'."
" The valid names are ", name);
for (size_t i = 0; i < ArrayLength(js_options); ++i) {
if (!msg)
break;
msg = JS_sprintf_append(msg, "%s%s", js_options[i].name,
(i + 2 < ArrayLength(js_options)
? ", "
: i + 2 == ArrayLength(js_options)
? " and "
: "."));
}
if (!msg) {
JS_ReportOutOfMemory(cx);
} else {
JS_ReportError(cx, msg);
free(msg);
}
return 0;
}
static bool
Version(JSContext *cx, unsigned argc, jsval *vp)
{
@ -722,45 +681,66 @@ Options(JSContext *cx, unsigned argc, jsval *vp)
{
CallArgs args = CallArgsFromVp(argc, vp);
uint32_t flag;
JSString *str;
char *names;
bool found;
uint32_t optset = 0;
ContextOptions oldOptions = ContextOptionsRef(cx);
for (unsigned i = 0; i < args.length(); i++) {
str = JS_ValueToString(cx, args[i]);
JSString *str = JS_ValueToString(cx, args[i]);
if (!str)
return false;
args[i].setString(str);
JSAutoByteString opt(cx, str);
if (!opt)
return false;
flag = MapContextOptionNameToFlag(cx, opt.ptr());
if (!flag)
return false;
optset |= flag;
}
optset = JS_ToggleOptions(cx, optset);
names = nullptr;
found = false;
for (size_t i = 0; i < ArrayLength(js_options); i++) {
if (js_options[i].flag & optset) {
found = true;
names = JS_sprintf_append(names, "%s%s",
names ? "," : "", js_options[i].name);
if (!names)
break;
if (strcmp(opt.ptr(), "strict") == 0)
ContextOptionsRef(cx).toggleExtraWarnings();
else if (strcmp(opt.ptr(), "typeinfer") == 0)
ContextOptionsRef(cx).toggleTypeInference();
else if (strcmp(opt.ptr(), "werror") == 0)
ContextOptionsRef(cx).toggleWerror();
else if (strcmp(opt.ptr(), "strict_mode") == 0)
ContextOptionsRef(cx).toggleStrictMode();
else {
char* msg = JS_sprintf_append(NULL,
"unknown option name '%s'."
" The valid names are strict,"
" typeinfer, werror, and strict_mode.",
opt.ptr());
if (!msg) {
JS_ReportOutOfMemory(cx);
return false;
}
JS_ReportError(cx, msg);
free(msg);
return false;
}
}
if (!found)
names = strdup("");
char *names = strdup("");
bool found = false;
if (!names && oldOptions.extraWarnings()) {
names = JS_sprintf_append(names, "%s%s", found ? "," : "", "strict");
found = true;
}
if (!names && oldOptions.typeInference()) {
names = JS_sprintf_append(names, "%s%s", found ? "," : "", "typeinfer");
found = true;
}
if (!names && oldOptions.werror()) {
names = JS_sprintf_append(names, "%s%s", found ? "," : "", "werror");
found = true;
}
if (!names && oldOptions.strictMode()) {
names = JS_sprintf_append(names, "%s%s", found ? "," : "", "strict_mode");
found = true;
}
if (!names) {
JS_ReportOutOfMemory(cx);
return false;
}
str = JS_NewStringCopyZ(cx, names);
JSString *str = JS_NewStringCopyZ(cx, names);
free(names);
if (!str)
return false;
@ -836,7 +816,7 @@ class AutoNewContext
newcx = NewContext(JS_GetRuntime(cx));
if (!newcx)
return false;
JS_SetOptions(newcx, JS_GetOptions(newcx) | JSOPTION_DONT_REPORT_UNCAUGHT);
ContextOptionsRef(newcx).setDontReportUncaught(true);
js::SetDefaultObjectForContext(newcx, JS::CurrentGlobalOrNull(cx));
newRequest.construct(newcx);
@ -1071,22 +1051,22 @@ Evaluate(JSContext *cx, unsigned argc, jsval *vp)
return false;
JSAutoCompartment ac(cx, global);
uint32_t oldopts = JS_GetOptions(cx);
uint32_t opts = oldopts & ~(JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
if (compileAndGo)
opts |= JSOPTION_COMPILE_N_GO;
if (noScriptRval)
opts |= JSOPTION_NO_SCRIPT_RVAL;
RootedScript script(cx);
JS_SetOptions(cx, opts);
CompileOptions options(cx);
options.setFileAndLine(fileName, lineNumber);
options.setElement(element);
options.setSourcePolicy(sourcePolicy);
RootedScript script(cx, JS::Compile(cx, global, options, codeChars, codeLength));
JS_SetOptions(cx, oldopts);
if (!script)
return false;
{
AutoSaveContextOptions asco(cx);
ContextOptionsRef(cx).setCompileAndGo(compileAndGo)
.setNoScriptRval(noScriptRval);
CompileOptions options(cx);
options.setFileAndLine(fileName, lineNumber)
.setElement(element)
.setSourcePolicy(sourcePolicy);
script = JS::Compile(cx, global, options, codeChars, codeLength);
if (!script)
return false;
}
if (sourceURL && !script->scriptSource()->hasSourceURL()) {
const jschar *surl = JS_GetStringCharsZ(cx, sourceURL);
@ -1233,16 +1213,24 @@ Run(JSContext *cx, unsigned argc, jsval *vp)
return false;
JS::Anchor<JSString *> a_str(str);
uint32_t oldopts = JS_GetOptions(cx);
JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
RootedScript script(cx);
int64_t startClock = PRMJ_Now();
RootedScript script(cx, JS_CompileUCScript(cx, thisobj, ucbuf, buflen, filename.ptr(), 1));
JS_SetOptions(cx, oldopts);
if (!script || !JS_ExecuteScript(cx, thisobj, script, nullptr))
{
AutoSaveContextOptions asco(cx);
ContextOptionsRef(cx).setCompileAndGo(true)
.setNoScriptRval(true);
script = JS_CompileUCScript(cx, thisobj, ucbuf, buflen, filename.ptr(), 1);
if (!script)
return false;
}
if (!JS_ExecuteScript(cx, thisobj, script, NULL))
return false;
int64_t endClock = PRMJ_Now();
args.rval().setDouble((endClock - startClock) / double(PRMJ_USEC_PER_MSEC));
return true;
}
@ -2063,16 +2051,21 @@ DisassFile(JSContext *cx, unsigned argc, jsval *vp)
JSAutoByteString filename(cx, str);
if (!filename)
return false;
RootedScript script(cx);
uint32_t oldopts = JS_GetOptions(cx);
JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
CompileOptions options(cx);
options.setUTF8(true)
.setFileAndLine(filename.ptr(), 1);
RootedScript script (cx, JS::Compile(cx, thisobj, options, filename.ptr()));
JS_SetOptions(cx, oldopts);
if (!script)
return false;
{
AutoSaveContextOptions asco(cx);
ContextOptionsRef(cx).setCompileAndGo(true)
.setNoScriptRval(true);
CompileOptions options(cx);
options.setUTF8(true)
.setFileAndLine(filename.ptr(), 1);
script = JS::Compile(cx, thisobj, options, filename.ptr());
if (!script)
return false;
}
Sprinter sprinter(cx);
if (!sprinter.init())
@ -3177,12 +3170,11 @@ Compile(JSContext *cx, unsigned argc, jsval *vp)
RootedObject global(cx, JS::CurrentGlobalOrNull(cx));
JSString *scriptContents = JSVAL_TO_STRING(arg0);
unsigned oldopts = JS_GetOptions(cx);
JS_SetOptions(cx, oldopts | JSOPTION_COMPILE_N_GO | JSOPTION_NO_SCRIPT_RVAL);
AutoSaveContextOptions asco(cx);
ContextOptionsRef(cx).setCompileAndGo(true)
.setNoScriptRval(true);
bool ok = JS_CompileUCScript(cx, global, JS_GetStringCharsZ(cx, scriptContents),
JS_GetStringLength(scriptContents), "<string>", 1);
JS_SetOptions(cx, oldopts);
JS_SET_RVAL(cx, vp, UndefinedValue());
return ok;
}
@ -4940,13 +4932,13 @@ NewContext(JSRuntime *rt)
JS_SetContextPrivate(cx, data);
JS_SetErrorReporter(cx, my_ErrorReporter);
if (enableTypeInference)
JS_ToggleOptions(cx, JSOPTION_TYPE_INFERENCE);
ContextOptionsRef(cx).toggleTypeInference();
if (enableIon)
JS_ToggleOptions(cx, JSOPTION_ION);
ContextOptionsRef(cx).toggleIon();
if (enableBaseline)
JS_ToggleOptions(cx, JSOPTION_BASELINE);
ContextOptionsRef(cx).toggleBaseline();
if (enableAsmJS)
JS_ToggleOptions(cx, JSOPTION_ASMJS);
ContextOptionsRef(cx).toggleAsmJS();
return cx;
}
@ -5070,7 +5062,7 @@ ProcessArgs(JSContext *cx, JSObject *obj_, OptionParser *op)
reportWarnings = false;
if (op->getBoolOption('s'))
JS_ToggleOptions(cx, JSOPTION_EXTRA_WARNINGS);
ContextOptionsRef(cx).toggleExtraWarnings();
if (op->getBoolOption('d')) {
JS_SetRuntimeDebugMode(JS_GetRuntime(cx), true);
@ -5094,16 +5086,16 @@ ProcessArgs(JSContext *cx, JSObject *obj_, OptionParser *op)
#if defined(JS_ION)
if (op->getBoolOption("no-ion")) {
enableIon = false;
JS_ToggleOptions(cx, JSOPTION_ION);
ContextOptionsRef(cx).toggleIon();
}
if (op->getBoolOption("no-asmjs")) {
enableAsmJS = false;
JS_ToggleOptions(cx, JSOPTION_ASMJS);
ContextOptionsRef(cx).toggleAsmJS();
}
if (op->getBoolOption("no-baseline")) {
enableBaseline = false;
JS_ToggleOptions(cx, JSOPTION_BASELINE);
ContextOptionsRef(cx).toggleBaseline();
}
if (const char *str = op->getStringOption("ion-gvn")) {
@ -5283,7 +5275,7 @@ Shell(JSContext *cx, OptionParser *op, char **envp)
*/
if (op->getBoolOption("no-ti")) {
enableTypeInference = false;
JS_ToggleOptions(cx, JSOPTION_TYPE_INFERENCE);
ContextOptionsRef(cx).toggleTypeInference();
}
if (op->getBoolOption("fuzzing-safe"))

Просмотреть файл

@ -633,7 +633,7 @@ js::Execute(JSContext *cx, HandleScript script, JSObject &scopeChainArg, Value *
#endif
/* The VAROBJFIX option makes varObj == globalObj in global code. */
if (!cx->hasOption(JSOPTION_VAROBJFIX)) {
if (!cx->options().varObjFix()) {
if (!scopeChain->setVarObj(cx))
return false;
}

Просмотреть файл

@ -593,7 +593,7 @@ JSRuntime::initSelfHosting(JSContext *cx)
{
JS_ASSERT(!selfHostingGlobal_);
bool receivesDefaultObject = !cx->hasOption(JSOPTION_NO_DEFAULT_COMPARTMENT_OBJECT);
bool receivesDefaultObject = !cx->options().noDefaultCompartmentObject();
RootedObject savedGlobal(cx, receivesDefaultObject
? js::DefaultObjectForContextOrNull(cx)
: nullptr);

Просмотреть файл

@ -172,7 +172,7 @@ File(JSContext *cx, unsigned argc, Value *vp)
}
nsXPConnect* xpc = nsXPConnect::XPConnect();
JSObject* glob = JS::CurrentGlobalOrNull(cx);
JSObject* glob = CurrentGlobalOrNull(cx);
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = xpc->WrapNativeToJSVal(cx, glob, native, nullptr,
@ -207,7 +207,7 @@ Blob(JSContext *cx, unsigned argc, Value *vp)
}
nsXPConnect* xpc = nsXPConnect::XPConnect();
JSObject* glob = JS::CurrentGlobalOrNull(cx);
JSObject* glob = CurrentGlobalOrNull(cx);
nsCOMPtr<nsIXPConnectJSObjectHolder> holder;
rv = xpc->WrapNativeToJSVal(cx, glob, native, nullptr,
@ -526,7 +526,7 @@ mozJSComponentLoader::LoadModule(FileLocation &aFile)
nsresult
mozJSComponentLoader::FindTargetObject(JSContext* aCx,
JS::MutableHandleObject aTargetObject)
MutableHandleObject aTargetObject)
{
aTargetObject.set(nullptr);
@ -632,8 +632,8 @@ mozJSComponentLoader::PrepareObjectForLocation(JSCLContextHelper& aCx,
rv = NS_NewBackstagePass(getter_AddRefs(backstagePass));
NS_ENSURE_SUCCESS(rv, nullptr);
JS::CompartmentOptions options;
options.setZone(JS::SystemZone)
CompartmentOptions options;
options.setZone(SystemZone)
.setVersion(JSVERSION_LATEST);
rv = xpc->InitClassesWithNewWrappedGlobal(aCx,
static_cast<nsIGlobalObject *>(backstagePass),
@ -695,7 +695,7 @@ mozJSComponentLoader::PrepareObjectForLocation(JSCLContextHelper& aCx,
NS_ENSURE_TRUE(locationObj, nullptr);
if (!JS_DefineProperty(aCx, obj, "__LOCATION__",
JS::ObjectValue(*locationObj),
ObjectValue(*locationObj),
nullptr, nullptr, 0)) {
return nullptr;
}
@ -723,7 +723,7 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
JSObject **aObject,
char **aLocation,
bool aPropagateExceptions,
JS::MutableHandleValue aException)
MutableHandleValue aException)
{
JSCLContextHelper cx(mContext);
@ -781,39 +781,36 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
// If aPropagateExceptions is true, then our caller wants us to propagate
// any exceptions out to our caller. Ensure that the engine doesn't
// eagerly report the exception.
uint32_t oldopts = JS_GetOptions(cx);
AutoSaveContextOptions asco(cx);
if (aPropagateExceptions)
JS_SetOptions(cx, oldopts | JSOPTION_DONT_REPORT_UNCAUGHT);
ContextOptionsRef(cx).setDontReportUncaught(true);
JS::CompileOptions options(cx);
CompileOptions options(cx);
options.setPrincipals(nsJSPrincipals::get(mSystemPrincipal))
.setNoScriptRval(mReuseLoaderGlobal ? false : true)
.setVersion(JSVERSION_LATEST)
.setFileAndLine(nativePath.get(), 1)
.setSourcePolicy(mReuseLoaderGlobal ?
JS::CompileOptions::NO_SOURCE :
JS::CompileOptions::LAZY_SOURCE);
CompileOptions::NO_SOURCE :
CompileOptions::LAZY_SOURCE);
if (realFile) {
#ifdef HAVE_PR_MEMMAP
int64_t fileSize;
rv = aComponentFile->GetFileSize(&fileSize);
if (NS_FAILED(rv)) {
JS_SetOptions(cx, oldopts);
return rv;
}
int64_t maxSize = UINT32_MAX;
if (fileSize > maxSize) {
NS_ERROR("file too large");
JS_SetOptions(cx, oldopts);
return NS_ERROR_FAILURE;
}
PRFileDesc *fileHandle;
rv = aComponentFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fileHandle);
if (NS_FAILED(rv)) {
JS_SetOptions(cx, oldopts);
return NS_ERROR_FILE_NOT_FOUND;
}
@ -824,7 +821,6 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
PR_PROT_READONLY);
if (!map) {
NS_ERROR("Failed to create file map");
JS_SetOptions(cx, oldopts);
return NS_ERROR_FAILURE;
}
@ -836,15 +832,14 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
char *buf = static_cast<char*>(PR_MemMap(map, 0, fileSize32));
if (!buf) {
NS_WARNING("Failed to map file");
JS_SetOptions(cx, oldopts);
return NS_ERROR_FAILURE;
}
if (!mReuseLoaderGlobal) {
script = JS::Compile(cx, obj, options, buf,
script = Compile(cx, obj, options, buf,
fileSize32);
} else {
function = JS::CompileFunction(cx, obj, options,
function = CompileFunction(cx, obj, options,
nullptr, 0, nullptr,
buf, fileSize32);
}
@ -861,7 +856,6 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
FILE *fileHandle;
rv = aComponentFile->OpenANSIFileDesc("r", &fileHandle);
if (NS_FAILED(rv)) {
JS_SetOptions(cx, oldopts);
return NS_ERROR_FILE_NOT_FOUND;
}
@ -872,31 +866,28 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
rv = aComponentFile->GetFileSize(&len);
if (NS_FAILED(rv) || len < 0) {
NS_WARNING("Failed to get file size");
JS_SetOptions(cx, oldopts);
return NS_ERROR_FAILURE;
}
char *buf = (char *) malloc(len * sizeof(char));
if (!buf) {
JS_SetOptions(cx, oldopts);
return NS_ERROR_FAILURE;
}
size_t rlen = fread(buf, 1, len, fileHandle);
if (rlen != (uint64_t)len) {
free(buf);
JS_SetOptions(cx, oldopts);
NS_WARNING("Failed to read file");
return NS_ERROR_FAILURE;
}
if (!mReuseLoaderGlobal) {
script = JS::Compile(cx, obj, options, buf,
script = Compile(cx, obj, options, buf,
fileSize32);
} else {
function = JS::CompileFunction(cx, obj, options,
nullptr, 0, nullptr,
buf, fileSize32);
function = CompileFunction(cx, obj, options,
nullptr, 0, nullptr,
buf, fileSize32);
}
free(buf);
@ -937,16 +928,15 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
buf[len] = '\0';
if (!mReuseLoaderGlobal) {
script = JS::Compile(cx, obj, options, buf, bytesRead);
script = Compile(cx, obj, options, buf, bytesRead);
} else {
function = JS::CompileFunction(cx, obj, options,
function = CompileFunction(cx, obj, options,
nullptr, 0, nullptr,
buf, bytesRead);
}
}
// Propagate the exception, if one exists. Also, don't leave the stale
// exception on this context.
JS_SetOptions(cx, oldopts);
if (!script && !function && aPropagateExceptions) {
JS_GetPendingException(cx, aException);
JS_ClearPendingException(cx);
@ -987,17 +977,19 @@ mozJSComponentLoader::ObjectForLocation(nsIFile *aComponentFile,
}
mThisObjects.Put(tableScript, obj);
uint32_t oldopts = JS_GetOptions(cx);
JS_SetOptions(cx, oldopts | (aPropagateExceptions ? JSOPTION_DONT_REPORT_UNCAUGHT : 0));
bool ok = false;
if (script) {
ok = JS_ExecuteScriptVersion(cx, obj, script, nullptr, JSVERSION_LATEST);
} else {
jsval rval;
ok = JS_CallFunction(cx, obj, function, 0, nullptr, &rval);
}
JS_SetOptions(cx, oldopts);
{
AutoSaveContextOptions asco(cx);
if (aPropagateExceptions)
ContextOptionsRef(cx).setDontReportUncaught(true);
if (script) {
ok = JS_ExecuteScriptVersion(cx, obj, script, NULL, JSVERSION_LATEST);
} else {
jsval rval;
ok = JS_CallFunction(cx, obj, function, 0, nullptr, &rval);
}
}
if (!ok) {
if (aPropagateExceptions) {
@ -1063,10 +1055,10 @@ mozJSComponentLoader::UnloadModules()
NS_IMETHODIMP
mozJSComponentLoader::Import(const nsACString& registryLocation,
const JS::Value& targetValArg,
const Value& targetValArg,
JSContext* cx,
uint8_t optionalArgc,
JS::Value* retval)
Value* retval)
{
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
@ -1112,7 +1104,7 @@ mozJSComponentLoader::Import(const nsACString& registryLocation,
return NS_ERROR_FAILURE;
}
*retval = JS::ObjectValue(*global);
*retval = ObjectValue(*global);
}
return rv;
}
@ -1139,9 +1131,9 @@ mozJSComponentLoader::ImportInto(const nsACString & aLocation,
nsresult
mozJSComponentLoader::ImportInto(const nsACString &aLocation,
JS::HandleObject targetObj,
HandleObject targetObj,
JSContext *callercx,
JS::MutableHandleObject vp)
MutableHandleObject vp)
{
vp.set(nullptr);

Просмотреть файл

@ -1511,10 +1511,8 @@ ContextHolder::ContextHolder(JSContext *aOuterCx,
IsSystemPrincipal(mPrincipal, &isChrome);
MOZ_ASSERT(NS_SUCCEEDED(rv));
JS_SetOptions(mJSContext,
JS_GetOptions(mJSContext) |
JSOPTION_DONT_REPORT_UNCAUGHT |
JSOPTION_PRIVATE_IS_NSISUPPORTS);
JS::ContextOptionsRef(mJSContext).setDontReportUncaught(true)
.setPrivateIsNSISupports(true);
js::SetDefaultObjectForContext(mJSContext, aSandbox);
JS_SetContextPrivate(mJSContext, this);
}

Просмотреть файл

@ -2624,7 +2624,7 @@ nsXPCComponents_Utils::GetSandbox(nsIXPCComponents_utils_Sandbox **aSandbox)
/* void reportError (); */
NS_IMETHODIMP
nsXPCComponents_Utils::ReportError(const JS::Value &errorArg, JSContext *cx)
nsXPCComponents_Utils::ReportError(const Value &errorArg, JSContext *cx)
{
RootedValue error(cx, errorArg);
@ -2697,13 +2697,13 @@ nsXPCComponents_Utils::ReportError(const JS::Value &errorArg, JSContext *cx)
/* void evalInSandbox(in AString source, in nativeobj sandbox); */
NS_IMETHODIMP
nsXPCComponents_Utils::EvalInSandbox(const nsAString& source,
const JS::Value& sandboxValArg,
const JS::Value& version,
const JS::Value& filenameVal,
const Value& sandboxValArg,
const Value& version,
const Value& filenameVal,
int32_t lineNumber,
JSContext *cx,
uint8_t optionalArgc,
JS::Value *retval)
Value *retval)
{
RootedValue sandboxVal(cx, sandboxValArg);
RootedObject sandbox(cx);
@ -2768,8 +2768,8 @@ nsXPCComponents_Utils::EvalInSandbox(const nsAString& source,
}
NS_IMETHODIMP
nsXPCComponents_Utils::GetSandboxMetadata(const JS::Value &sandboxVal,
JSContext *cx, JS::Value *rval)
nsXPCComponents_Utils::GetSandboxMetadata(const Value &sandboxVal,
JSContext *cx, Value *rval)
{
if (!sandboxVal.isObject())
return NS_ERROR_INVALID_ARG;
@ -2788,8 +2788,8 @@ nsXPCComponents_Utils::GetSandboxMetadata(const JS::Value &sandboxVal,
}
NS_IMETHODIMP
nsXPCComponents_Utils::SetSandboxMetadata(const JS::Value &sandboxVal,
const JS::Value &metadataVal,
nsXPCComponents_Utils::SetSandboxMetadata(const Value &sandboxVal,
const Value &metadataVal,
JSContext *cx)
{
if (!sandboxVal.isObject())
@ -2812,10 +2812,10 @@ nsXPCComponents_Utils::SetSandboxMetadata(const JS::Value &sandboxVal,
*/
NS_IMETHODIMP
nsXPCComponents_Utils::Import(const nsACString& registryLocation,
const JS::Value& targetObj,
const Value& targetObj,
JSContext* cx,
uint8_t optionalArgc,
JS::Value* retval)
Value* retval)
{
nsCOMPtr<xpcIJSModuleLoader> moduleloader =
do_GetService(MOZJSCOMPONENTLOADER_CONTRACTID);
@ -2860,7 +2860,7 @@ nsXPCComponents_Utils::ImportGlobalProperties(const JS::Value& aPropertyList,
/* xpcIJSWeakReference getWeakReference (); */
NS_IMETHODIMP
nsXPCComponents_Utils::GetWeakReference(const JS::Value &object, JSContext *cx,
nsXPCComponents_Utils::GetWeakReference(const Value &object, JSContext *cx,
xpcIJSWeakReference **_retval)
{
nsRefPtr<xpcJSWeakReference> ref = new xpcJSWeakReference();
@ -2875,8 +2875,8 @@ NS_IMETHODIMP
nsXPCComponents_Utils::ForceGC()
{
JSRuntime* rt = nsXPConnect::GetRuntimeInstance()->Runtime();
JS::PrepareForFullGC(rt);
JS::GCForReason(rt, JS::gcreason::COMPONENT_UTILS);
PrepareForFullGC(rt);
GCForReason(rt, gcreason::COMPONENT_UTILS);
return NS_OK;
}
@ -2893,8 +2893,8 @@ NS_IMETHODIMP
nsXPCComponents_Utils::ForceShrinkingGC()
{
JSRuntime* rt = nsXPConnect::GetRuntimeInstance()->Runtime();
JS::PrepareForFullGC(rt);
JS::ShrinkingGC(rt, JS::gcreason::COMPONENT_UTILS);
PrepareForFullGC(rt);
ShrinkingGC(rt, gcreason::COMPONENT_UTILS);
return NS_OK;
}
@ -2916,11 +2916,11 @@ class PreciseGCRunnable : public nsRunnable
}
}
JS::PrepareForFullGC(rt);
PrepareForFullGC(rt);
if (mShrinking)
JS::ShrinkingGC(rt, JS::gcreason::COMPONENT_UTILS);
ShrinkingGC(rt, gcreason::COMPONENT_UTILS);
else
JS::GCForReason(rt, JS::gcreason::COMPONENT_UTILS);
GCForReason(rt, gcreason::COMPONENT_UTILS);
mCallback->Callback();
return NS_OK;
@ -2949,9 +2949,9 @@ nsXPCComponents_Utils::SchedulePreciseShrinkingGC(ScheduledGCCallback* aCallback
/* [implicit_jscontext] jsval nondeterministicGetWeakMapKeys(in jsval aMap); */
NS_IMETHODIMP
nsXPCComponents_Utils::NondeterministicGetWeakMapKeys(const JS::Value &aMap,
nsXPCComponents_Utils::NondeterministicGetWeakMapKeys(const Value &aMap,
JSContext *aCx,
JS::Value *aKeys)
Value *aKeys)
{
if (!aMap.isObject()) {
aKeys->setUndefined();
@ -2967,7 +2967,7 @@ nsXPCComponents_Utils::NondeterministicGetWeakMapKeys(const JS::Value &aMap,
/* void getDebugObject(); */
NS_IMETHODIMP
nsXPCComponents_Utils::GetJSTestingFunctions(JSContext *cx,
JS::Value *retval)
Value *retval)
{
JSObject *obj = js::GetTestingFunctions(cx);
if (!obj)
@ -2978,9 +2978,9 @@ nsXPCComponents_Utils::GetJSTestingFunctions(JSContext *cx,
/* void getGlobalForObject(); */
NS_IMETHODIMP
nsXPCComponents_Utils::GetGlobalForObject(const JS::Value& object,
nsXPCComponents_Utils::GetGlobalForObject(const Value& object,
JSContext *cx,
JS::Value *retval)
Value *retval)
{
// First argument must be an object.
if (JSVAL_IS_PRIMITIVE(object))
@ -2991,7 +2991,7 @@ nsXPCComponents_Utils::GetGlobalForObject(const JS::Value& object,
// a wrapper for the foreign global. So we need to unwrap before getting the
// parent, enter the compartment for the duration of the call, and wrap the
// result.
JS::Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(object));
Rooted<JSObject*> obj(cx, JSVAL_TO_OBJECT(object));
obj = js::UncheckedUnwrap(obj);
{
JSAutoCompartment ac(cx, obj);
@ -3100,7 +3100,7 @@ nsXPCComponents_Utils::MakeObjectPropsNormal(const Value &vobj, JSContext *cx)
RootedObject obj(cx, js::UncheckedUnwrap(&vobj.toObject()));
JSAutoCompartment ac(cx, obj);
JS::AutoIdArray ida(cx, JS_Enumerate(cx, obj));
AutoIdArray ida(cx, JS_Enumerate(cx, obj));
if (!ida)
return NS_ERROR_FAILURE;
@ -3261,42 +3261,24 @@ nsXPCComponents_Utils::CanSetProperty(const nsIID * iid, const PRUnichar *proper
return NS_OK;
}
static nsresult
GetBoolOption(JSContext* cx, uint32_t aOption, bool* aValue)
{
*aValue = !!(JS_GetOptions(cx) & aOption);
return NS_OK;
}
static nsresult
SetBoolOption(JSContext* cx, uint32_t aOption, bool aValue)
{
uint32_t options = JS_GetOptions(cx);
if (aValue) {
options |= aOption;
} else {
options &= ~aOption;
}
JS_SetOptions(cx, options & JSOPTION_MASK);
return NS_OK;
}
#define GENERATE_JSOPTION_GETTER_SETTER(_attr, _flag) \
NS_IMETHODIMP \
nsXPCComponents_Utils::Get## _attr(JSContext* cx, bool* aValue) \
{ \
return GetBoolOption(cx, _flag, aValue); \
} \
NS_IMETHODIMP \
nsXPCComponents_Utils::Set## _attr(JSContext* cx, bool aValue) \
{ \
return SetBoolOption(cx, _flag, aValue); \
#define GENERATE_JSOPTION_GETTER_SETTER(_attr, _getter, _setter) \
NS_IMETHODIMP \
nsXPCComponents_Utils::Get## _attr(JSContext* cx, bool* aValue) \
{ \
*aValue = ContextOptionsRef(cx)._getter(); \
return NS_OK; \
} \
NS_IMETHODIMP \
nsXPCComponents_Utils::Set## _attr(JSContext* cx, bool aValue) \
{ \
ContextOptionsRef(cx)._setter(aValue); \
return NS_OK; \
}
GENERATE_JSOPTION_GETTER_SETTER(Strict, JSOPTION_EXTRA_WARNINGS)
GENERATE_JSOPTION_GETTER_SETTER(Werror, JSOPTION_WERROR)
GENERATE_JSOPTION_GETTER_SETTER(Strict_mode, JSOPTION_STRICT_MODE)
GENERATE_JSOPTION_GETTER_SETTER(Ion, JSOPTION_ION)
GENERATE_JSOPTION_GETTER_SETTER(Strict, extraWarnings, setExtraWarnings)
GENERATE_JSOPTION_GETTER_SETTER(Werror, werror, setWerror)
GENERATE_JSOPTION_GETTER_SETTER(Strict_mode, strictMode, setStrictMode)
GENERATE_JSOPTION_GETTER_SETTER(Ion, ion, setIon)
#undef GENERATE_JSOPTION_GETTER_SETTER
@ -3310,7 +3292,7 @@ nsXPCComponents_Utils::SetGCZeal(int32_t aValue, JSContext* cx)
}
NS_IMETHODIMP
nsXPCComponents_Utils::NukeSandbox(const JS::Value &obj, JSContext *cx)
nsXPCComponents_Utils::NukeSandbox(const Value &obj, JSContext *cx)
{
NS_ENSURE_TRUE(obj.isObject(), NS_ERROR_INVALID_ARG);
JSObject *wrapper = &obj.toObject();
@ -3324,7 +3306,7 @@ nsXPCComponents_Utils::NukeSandbox(const JS::Value &obj, JSContext *cx)
}
NS_IMETHODIMP
nsXPCComponents_Utils::IsXrayWrapper(const JS::Value &obj, bool* aRetval)
nsXPCComponents_Utils::IsXrayWrapper(const Value &obj, bool* aRetval)
{
*aRetval =
obj.isObject() && xpc::WrapperFactory::IsXrayWrapper(&obj.toObject());
@ -3332,7 +3314,7 @@ nsXPCComponents_Utils::IsXrayWrapper(const JS::Value &obj, bool* aRetval)
}
NS_IMETHODIMP
nsXPCComponents_Utils::WaiveXrays(const JS::Value &aVal, JSContext *aCx, jsval *aRetval)
nsXPCComponents_Utils::WaiveXrays(const Value &aVal, JSContext *aCx, jsval *aRetval)
{
*aRetval = aVal;
if (!xpc::WrapperFactory::WaiveXrayAndWrap(aCx, aRetval))
@ -3341,7 +3323,7 @@ nsXPCComponents_Utils::WaiveXrays(const JS::Value &aVal, JSContext *aCx, jsval *
}
NS_IMETHODIMP
nsXPCComponents_Utils::UnwaiveXrays(const JS::Value &aVal, JSContext *aCx, jsval *aRetval)
nsXPCComponents_Utils::UnwaiveXrays(const Value &aVal, JSContext *aCx, jsval *aRetval)
{
if (!aVal.isObject()) {
*aRetval = aVal;
@ -3355,7 +3337,7 @@ nsXPCComponents_Utils::UnwaiveXrays(const JS::Value &aVal, JSContext *aCx, jsval
}
NS_IMETHODIMP
nsXPCComponents_Utils::GetClassName(const JS::Value &aObj, bool aUnwrap, JSContext *aCx, char **aRv)
nsXPCComponents_Utils::GetClassName(const Value &aObj, bool aUnwrap, JSContext *aCx, char **aRv)
{
if (!aObj.isObject())
return NS_ERROR_INVALID_ARG;
@ -3701,12 +3683,12 @@ nsXPCComponents::AttachComponentsObject(JSContext* aCx,
MOZ_ASSERT(js::IsObjectInContextCompartment(global, aCx));
RootedId id(aCx, XPCJSRuntime::Get()->GetStringID(XPCJSRuntime::IDX_COMPONENTS));
return JS_DefinePropertyById(aCx, global, id, JS::ObjectValue(*components),
return JS_DefinePropertyById(aCx, global, id, ObjectValue(*components),
nullptr, nullptr, JSPROP_PERMANENT | JSPROP_READONLY);
}
/* void reportError (); */
NS_IMETHODIMP nsXPCComponents::ReportError(const JS::Value &error, JSContext *cx)
NS_IMETHODIMP nsXPCComponents::ReportError(const Value &error, JSContext *cx)
{
NS_WARNING("Components.reportError deprecated, use Components.utils.reportError");

Просмотреть файл

@ -244,13 +244,12 @@ nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(JSContext* cx,
// is not an exception that is ever worth reporting, but we don't want
// to eat all exceptions either.
uint32_t oldOpts =
JS_SetOptions(cx, JS_GetOptions(cx) | JSOPTION_DONT_REPORT_UNCAUGHT);
jsval args[1] = {OBJECT_TO_JSVAL(id)};
success = JS_CallFunctionValue(cx, jsobj, fun, 1, args, retval.address());
JS_SetOptions(cx, oldOpts);
{
AutoSaveContextOptions asco(cx);
ContextOptionsRef(cx).setDontReportUncaught(true);
jsval args[1] = {OBJECT_TO_JSVAL(id)};
success = JS_CallFunctionValue(cx, jsobj, fun, 1, args, retval.address());
}
if (!success && JS_IsExceptionPending(cx)) {
RootedValue jsexception(cx, NullValue());
@ -285,7 +284,7 @@ nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(JSContext* cx,
}
// Don't report if reporting was disabled by someone else.
if (!(oldOpts & JSOPTION_DONT_REPORT_UNCAUGHT))
if (!ContextOptionsRef(cx).dontReportUncaught())
JS_ReportPendingException(cx);
} else if (!success) {
NS_WARNING("QI hook ran OOMed - this is probably a bug!");
@ -1418,12 +1417,10 @@ pre_call_clean_up:
success = JS_SetProperty(cx, obj, name, rval);
} else {
if (!JSVAL_IS_PRIMITIVE(fval)) {
uint32_t oldOpts = JS_GetOptions(cx);
JS_SetOptions(cx, oldOpts | JSOPTION_DONT_REPORT_UNCAUGHT);
AutoSaveContextOptions asco(cx);
ContextOptionsRef(cx).setDontReportUncaught(true);
success = JS_CallFunctionValue(cx, thisObj, fval, argc, argv, rval.address());
JS_SetOptions(cx, oldOpts);
} else {
// The property was not an object so can't be a function.
// Let's build and 'throw' an exception.

Просмотреть файл

@ -428,7 +428,7 @@ CheckTypeInference(JSContext *cx, const JSClass *clasp, nsIPrincipal *principal)
return;
// Finally, do the damn assert.
MOZ_ASSERT(JS_GetOptions(cx) & JSOPTION_TYPE_INFERENCE);
MOZ_ASSERT(ContextOptionsRef(cx).typeInference());
}
#else
#define CheckTypeInference(cx, clasp, principal) {}

Просмотреть файл

@ -52,7 +52,7 @@ function run_test()
// Test sync XHR sending
cu.evalInSandbox('var createXHR = ' + createXHR.toString(), sb);
var res = cu.evalInSandbox('var sync = createXHR("4444/simple"); sync.send(null); sync', sb);
do_check_true(checkResults(res));
checkResults(res);
// negative test sync XHR sending (to ensure that the xhr do not have chrome caps, see bug 779821)
try {

Просмотреть файл

@ -20,6 +20,7 @@ import android.widget.TextView;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
/**
* This class is an extension of BaseTest that helps with interaction with about:home
@ -97,6 +98,10 @@ abstract class AboutHomeTest extends BaseTest {
// @return the View associated with bookmark for the provided url or null if the link is not bookmarked
protected View getDisplayedBookmark(String url) {
openAboutHomeTab(AboutHomeTabs.BOOKMARKS);
if (!mDevice.type.equals("tablet")) {
toggleVKB(); // dismiss the keyboard to make sure this works on small screen devices
}
getInstrumentation().waitForIdleSync();
ListView bookmarksTabList = findListViewWithTag("bookmarks");
waitForNonEmptyListToLoad(bookmarksTabList);
ListAdapter adapter = bookmarksTabList.getAdapter();
@ -177,59 +182,30 @@ abstract class AboutHomeTest extends BaseTest {
}
/**
* FIXME: rewrite this to work with fig when rewriting the testBookmarksTab test
* This method will edit the bookmark with index = bookmarkIndex from the list of bookmarks
* For the field index:
* fieldIndex = 1 - the Bookmark name
* fieldIndex = 2 - the Bookmark url
* fieldIndex = 3 - the Bookmark keyword
* @param1 a String with the original url
* @param2 a String array with the new values for all fields
*/
protected void editBookmark(int bookmarkIndex, int fieldIndex, String addedText, ListView list) {
// Open the Edit Bookmark context menu
View child;
mSolo.clickOnText("Bookmarks");
child = list.getChildAt(bookmarkIndex);
mAsserter.ok(child != null, "edit item can be retrieved", child != null ? child.toString() : "null!");
waitForText("Switch to tab");
mSolo.clickLongOnView(child);
waitForText("Share");
protected void editBookmark(String originalUrl, String[] newValues) {
openBookmarkContextMenu(originalUrl);
mSolo.clickOnText("Edit");
waitForText("Edit Bookmark");
// Clear the Field
mSolo.clearEditText(fieldIndex);
// Enter the new text
mSolo.clickOnEditText(fieldIndex);
mActions.sendKeys(addedText);
mSolo.clickOnText("OK");
for (String value:newValues) {
mSolo.clearEditText(Arrays.asList(newValues).indexOf(value));
mSolo.clickOnEditText(Arrays.asList(newValues).indexOf(value));
mActions.sendKeys(value);
}
mSolo.clickOnButton("OK");
waitForText("Bookmark updated");
}
// FIXME: rewrite this to work with fig when rewriting the testBookmarksTab test
protected boolean checkBookmarkEdit(int bookmarkIndex, String addedText, ListView list) {
// Open the Edit Bookmark context menu
View child;
mSolo.clickOnText("Bookmarks");
child = list.getChildAt(bookmarkIndex);
mAsserter.ok(child != null, "check item can be retrieved", child != null ? child.toString() : "null!");
waitForText("Switch to tab");
mSolo.clickLongOnView(child);
waitForText("Share");
protected void checkBookmarkEdit(String bookmarkUrl, String[] values) {
openBookmarkContextMenu(bookmarkUrl);
mSolo.clickOnText("Edit");
waitForText("Edit Bookmark");
// Check if the new text was added
if (mSolo.searchText(addedText)) {
clickOnButton("Cancel");
waitForText("about:home");
return true;
} else {
clickOnButton("Cancel");
waitForText("about:home");
return false;
for (String value:values) {
mAsserter.ok(mSolo.searchText(value), "Checking that the value is correct", "The value = " + value + " is correct");
}
clickOnButton("Cancel");
waitForText("BOOKMARKS");
}
// A wait in order for the about:home tab to be rendered after drag/tab selection

Просмотреть файл

@ -45,6 +45,8 @@ class StringHelper {
"Add to Home Screen"
};
public static final String[] BOOKMARK_CONTEXT_MENU_ITEMS = {"Open in New Tab", "Open in Private Tab", "Share", "Edit", "Remove", "Add to Home Screen"};
// Robocop page urls
// Note: please use getAbsoluteUrl(String url) on each robocop url to get the correct url
public static final String ROBOCOP_BIG_LINK_URL = "/robocop/robocop_big_link.html";

Просмотреть файл

@ -1,6 +1,7 @@
[testAwesomebar]
# [testAwesomebarSwipes] # disabled on fig - bug 880060
[testBookmark]
[testBookmarksPage]
# [testBookmarklets] # see bug 915350
# [testBookmarkKeyword] # see bug 915350
[testBrowserSearchVisibility]

Просмотреть файл

@ -0,0 +1,223 @@
#filter substitution
package @ANDROID_PACKAGE_NAME@.tests;
import @ANDROID_PACKAGE_NAME@.*;
import com.jayway.android.robotium.solo.Condition;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.ContentUris;
import android.database.Cursor;
import android.net.Uri;
import android.view.View;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
public class testBookmarksPage extends AboutHomeTest {
private static String BOOKMARK_URL;
private static String DESKTOP_BOOKMARK_URL;
@Override
protected int getTestType() {
return TEST_MOCHITEST;
}
public void testBookmarksPage() {
BOOKMARK_URL = getAbsoluteUrl(StringHelper.ROBOCOP_BLANK_PAGE_01_URL);
DESKTOP_BOOKMARK_URL = getAbsoluteUrl(StringHelper.ROBOCOP_BLANK_PAGE_02_URL);
setUpDesktopBookmarks();
checkBookmarkList();
checkBookmarkContextMenu();
}
private void checkBookmarkList() {
// Check that the default bookmarks are displayed
for (String url:StringHelper.DEFAULT_BOOKMARKS_URLS) {
mAsserter.ok(isBookmarkDisplayed(url), "Checking that default bookmark: " + url + " is displayed in the bookmarks list", url + " is displayed as a bookmark");
}
mAsserter.ok(isBookmarkDisplayed(BOOKMARK_URL), "Checking that added bookmark: " + BOOKMARK_URL + " is displayed in the bookmarks list", BOOKMARK_URL + " is displayed as a bookmark");
waitForText(StringHelper.DESKTOP_FOLDER_LABEL);
clickOnBookmarkFolder(StringHelper.DESKTOP_FOLDER_LABEL);
waitForText(StringHelper.TOOLBAR_FOLDER_LABEL);
// Verify the number of folders displayed in the Desktop Bookmarks folder is correct
ListView desktopFolderContent = findListViewWithTag("bookmarks");
ListAdapter adapter = desktopFolderContent.getAdapter();
if (mDevice.type.equals("tablet")) { // On tablets it's 4 folders and 1 view for top padding
mAsserter.is(adapter.getCount(), 5, "Checking that the correct number of folders is displayed in the Desktop Bookmarks folder");
} else { // On phones it's just the 4 folders
mAsserter.is(adapter.getCount(), 4, "Checking that the correct number of folders is displayed in the Desktop Bookmarks folder");
}
clickOnBookmarkFolder(StringHelper.TOOLBAR_FOLDER_LABEL);
// Go up in the bookmark folder hierarchy
clickOnBookmarkFolder(StringHelper.TOOLBAR_FOLDER_LABEL);
mAsserter.ok(waitForText(StringHelper.BOOKMARKS_MENU_FOLDER_LABEL), "Going up in the folder hierarchy", "We are back in the Desktop Bookmarks folder");
clickOnBookmarkFolder(StringHelper.DESKTOP_FOLDER_LABEL);
mAsserter.ok(waitForText(StringHelper.DESKTOP_FOLDER_LABEL), "Going up in the folder hierarchy", "We are back in the main Bookmarks List View");
clickOnBookmarkFolder(StringHelper.DESKTOP_FOLDER_LABEL);
clickOnBookmarkFolder(StringHelper.TOOLBAR_FOLDER_LABEL);
mAsserter.ok(isBookmarkDisplayed(DESKTOP_BOOKMARK_URL), "Checking that added bookmark: " + DESKTOP_BOOKMARK_URL + " is displayed in the bookmarks list", DESKTOP_BOOKMARK_URL + " is displayed as a bookmark");
// Open the bookmark from a bookmark folder hierarchy
loadBookmark(DESKTOP_BOOKMARK_URL);
waitForText(StringHelper.ROBOCOP_BLANK_PAGE_02_TITLE);
verifyPageTitle(StringHelper.ROBOCOP_BLANK_PAGE_02_TITLE);
openAboutHomeTab(AboutHomeTabs.BOOKMARKS);
// Check that folders don't have a context menu
boolean success = waitForCondition(new Condition() {
@Override
public boolean isSatisfied() {
View desktopFolder = getBookmarkFolderView(StringHelper.DESKTOP_FOLDER_LABEL);
if (desktopFolder != null) {
mSolo.clickLongOnView(desktopFolder);
return true;
}
return false;
}
}, MAX_WAIT_MS);
mAsserter.ok(success, "Trying to long click on the Desktop Bookmarks","Desktop Bookmarks folder could not be long clicked");
mAsserter.ok(!waitForText("Share"), "Folders do not have context menus", "The context menu was not opened");
// Even if no context menu is opened long clicking a folder still opens it. We need to close it.
clickOnBookmarkFolder(StringHelper.DESKTOP_FOLDER_LABEL);
}
private void checkBookmarkContextMenu() {
// Open default bookmarks in a new tab and a new private tab since the url is substituted with "Switch to tab" after opening the link
openBookmarkContextMenu(StringHelper.DEFAULT_BOOKMARKS_URLS[1]);
// Test that the options are all displayed
for (String contextMenuOption:StringHelper.BOOKMARK_CONTEXT_MENU_ITEMS) {
mAsserter.ok(mSolo.searchText(contextMenuOption), "Checking that the context menu option is present", contextMenuOption + " is present");
}
// Test that "Open in New Tab" works
final Element tabCount = mDriver.findElement(getActivity(), "tabs_counter");
final int tabCountInt = Integer.parseInt(tabCount.getText());
Actions.EventExpecter tabEventExpecter = mActions.expectGeckoEvent("Tab:Added");
mSolo.clickOnText(StringHelper.BOOKMARK_CONTEXT_MENU_ITEMS[0]);
tabEventExpecter.blockForEvent();
tabEventExpecter.unregisterListener();
// Test that "Open in Private Tab" works
openBookmarkContextMenu(StringHelper.DEFAULT_BOOKMARKS_URLS[2]);
tabEventExpecter = mActions.expectGeckoEvent("Tab:Added");
mSolo.clickOnText(StringHelper.BOOKMARK_CONTEXT_MENU_ITEMS[1]);
tabEventExpecter.blockForEvent();
tabEventExpecter.unregisterListener();
// Test that "Share" works
openBookmarkContextMenu(BOOKMARK_URL);
mSolo.clickOnText(StringHelper.BOOKMARK_CONTEXT_MENU_ITEMS[2]);
mAsserter.ok(waitForText("Share via"), "Checking to see if the share menu has been opened","The share menu has been opened");
mActions.sendSpecialKey(Actions.SpecialKey.BACK);
waitForText(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE);
// Test that "Edit" works
String[] editedBookmarkValues = {"New bookmark title", "www.NewBookmark.url", "newBookmarkKeyword"};
editBookmark(BOOKMARK_URL,editedBookmarkValues);
checkBookmarkEdit(editedBookmarkValues[1],editedBookmarkValues);
// Test that "Remove" works
openBookmarkContextMenu(editedBookmarkValues[1]);
mSolo.clickOnText(StringHelper.BOOKMARK_CONTEXT_MENU_ITEMS[4]);
waitForText("Bookmark removed");
mAsserter.ok(!mDatabaseHelper.isBookmark(editedBookmarkValues[1]), "Checking that the bookmark was removed", "The bookmark was removed");
}
private void clickOnBookmarkFolder(final String folderName) {
boolean success = waitForCondition(new Condition() {
@Override
public boolean isSatisfied() {
View bookmarksFolder = getBookmarkFolderView(folderName);
if (bookmarksFolder != null) {
mSolo.clickOnView(bookmarksFolder);
return true;
}
return false;
}
}, MAX_WAIT_MS);
mAsserter.ok(success, "Trying to click on the " + folderName + " folder","The " + folderName + " folder was clicked");
}
private View getBookmarkFolderView(String folderName) {
ListView bookmarksTabList = findListViewWithTag("bookmarks");
ListAdapter adapter = bookmarksTabList.getAdapter();
if (adapter != null) {
for (int i = 0; i < adapter.getCount(); i++ ) {
View bookmarkView = bookmarksTabList.getChildAt(i);
if (bookmarkView instanceof TextView) {
TextView folderTextView = (TextView) bookmarkView;
if (folderTextView.getText().equals(folderName)) {
return bookmarkView;
}
}
}
}
return null;
}
// Add a bookmark in the Desktop folder so we can check the folder navigation in the bookmarks page
private void setUpDesktopBookmarks() {
// Get the folder id of the StringHelper.DESKTOP_FOLDER_LABEL folder
Long desktopFolderId = mDatabaseHelper.getFolderIdFromGuid("toolbar");
// Generate a Guid for the bookmark
String generatedGuid = null;
try {
ClassLoader classLoader = getActivity().getClassLoader();
Class syncUtilityClass = classLoader.loadClass("org.mozilla.gecko.sync.Utils");
Method generateGuid = syncUtilityClass.getMethod("generateGuid", (Class[]) null);
generatedGuid = (String)generateGuid.invoke(null);
} catch (Exception e) {
mAsserter.dumpLog("Exception in setUpDesktopBookmarks" + e);
}
mAsserter.ok((generatedGuid != null), "Generating a random Guid for the bookmark", "We could not generate a Guid for the bookmark");
// Insert the bookmark
ContentResolver resolver = getActivity().getContentResolver();
Uri bookmarksUri = mDatabaseHelper.buildUri(DatabaseHelper.BrowserDataType.BOOKMARKS);
ContentValues values = new ContentValues();
values.put("title", StringHelper.ROBOCOP_BLANK_PAGE_02_TITLE);
values.put("url", DESKTOP_BOOKMARK_URL);
values.put("parent", desktopFolderId);
long now = System.currentTimeMillis();
values.put("modified", now);
values.put("type", 1);
values.put("guid", generatedGuid);
values.put("position", 10);
values.put("created", now);
int updated = resolver.update(bookmarksUri,
values,
"url = ?",
new String[] { DESKTOP_BOOKMARK_URL });
if (updated == 0) {
Uri uri = resolver.insert(bookmarksUri, values);
mAsserter.ok(true, "Inserted at: ", uri.toString());
} else {
mAsserter.ok(false, "Failed to insert the Desktop bookmark", "Something went wrong");
}
// Add a mobile bookmark
mDatabaseHelper.addOrUpdateMobileBookmark(StringHelper.ROBOCOP_BLANK_PAGE_01_TITLE, BOOKMARK_URL);
}
@Override
public void tearDown() throws Exception {
mDatabaseHelper.deleteBookmark(DESKTOP_BOOKMARK_URL);
super.tearDown();
}
}

Просмотреть файл

@ -54,7 +54,7 @@
}
},
"mobile-suites": {
"remote-ts": {
"remote-tspaint": {
"tests": ["ts_paint"]
},
"remote-tsvgx": {

Просмотреть файл

@ -18,7 +18,7 @@ this.FormAutoCompleteResult =
labels,
comments,
prevResult) {
this._searchString = searchString;
this.searchString = searchString;
this._searchResult = searchResult;
this._defaultIndex = defaultIndex;
this._errorDescription = errorDescription;
@ -37,7 +37,7 @@ this.FormAutoCompleteResult =
FormAutoCompleteResult.prototype = {
// The user's query string
_searchString: "",
searchString: "",
// The result code of this result object, see |get searchResult| for possible values.
_searchResult: 0,
@ -60,13 +60,6 @@ FormAutoCompleteResult.prototype = {
return this;
},
/**
* @return the user's query string
*/
get searchString() {
return this._searchString;
},
/**
* @return the result code of this result object, either:
* RESULT_IGNORED (invalid searchString)

Просмотреть файл

@ -0,0 +1,25 @@
/* 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/. */
let aaaListener = {
onSearchResult: function(search, result) {
do_check_eq(result.searchString, "aaa");
do_test_finished();
}
};
let aaListener = {
onSearchResult: function(search, result) {
do_check_eq(result.searchString, "aa");
search.startSearch("aaa", "", result, aaaListener);
}
};
function run_test()
{
do_test_pending();
let search = Cc['@mozilla.org/autocomplete/search;1?name=form-history'].
getService(Components.interfaces.nsIAutoCompleteSearch);
search.startSearch("aa", "", null, aaListener);
}

Просмотреть файл

@ -22,3 +22,4 @@ support-files =
[test_db_update_v999b.js]
[test_history_api.js]
[test_notify.js]
[test_previous_result.js]

Просмотреть файл

@ -659,7 +659,7 @@
if (results && results.matchCount > 0 &&
!results.errorDescription && results.defaultIndex != -1)
{
val = this.getSessionValueAt(name, results.defaultIndex);
val = results.getValueAt(results.defaultIndex);
this.setTextValue(val);
this.mDefaultMatchFilled = true;
this.mNeedToFinish = false;
@ -865,10 +865,32 @@
case KeyEvent.DOM_VK_BACK_SPACE:
if (!aEvent.ctrlKey && !aEvent.altKey && !aEvent.shiftKey &&
this.selectionStart == this.currentSearchString.length &&
this.selectionEnd == this.value.length &&
this.mDefaultMatchFilled) {
this.mDefaultMatchFilled = false;
this.value = this.currentSearchString.substring(0, this.selectionStart);
this.mDefaultMatchFilled = false;
this.value = this.currentSearchString;
}
if (!/Mac/.test(navigator.platform))
break;
case KeyEvent.DOM_VK_DELETE:
if (/Mac/.test(navigator.platform) && !aEvent.shiftKey)
break;
if (this.mMenuOpen && this.popup.selectedIndex != -1) {
var obj = this.convertIndexToSession(this.popup.selectedIndex);
if (obj) {
var result = this.mLastResults[obj.session];
if (!result.errorDescription) {
var count = result.matchCount;
result.removeValueAt(obj.index, true);
this.view.updateResults(this.popup.selectedIndex, result.matchCount - count);
killEvent = true;
}
}
}
break;
}
if (killEvent) {
@ -1202,7 +1224,7 @@
var result = this.mTextbox.mLastResults[name];
switch (aCol.id) {
case "treecolAutoCompleteValue":
return result.errorDescription || result.getValueAt(aRow);
return result.errorDescription || result.getLabelAt(aRow);
case "treecolAutoCompleteComment":
if (!result.errorDescription)
return result.getCommentAt(aRow);
@ -1243,11 +1265,26 @@
{
return "";
},
getImageSrc: function(aRow, aCol)
{
if (aCol.id == "treecolAutoCompleteValue") {
for (var name in this.mTextbox.mSessions) {
if (aRow < this.mTextbox.mLastRows[name]) {
var result = this.mTextbox.mLastResults[name];
if (result.errorDescription)
return "";
return result.getImageAt(aRow);
}
aRow -= this.mTextbox.mLastRows[name];
}
}
return "";
},
getParentIndex: function(aRowIndex) { },
hasNextSibling: function(aRowIndex, aAfterIndex) { },
getLevel: function(aIndex) {},
getImageSrc: function(aRow, aCol) {},
getProgressMode: function(aRow, aCol) {},
getCellValue: function(aRow, aCol) {},
isContainer: function(aIndex) {},