Merge mozilla-central into mozilla-inbound

This commit is contained in:
Ehsan Akhgari 2012-10-16 20:43:47 -04:00
commit 75ecc91244
22 changed files with 185 additions and 171 deletions

View File

@ -1125,7 +1125,7 @@ DocAccessible::AttributeChangedImpl(nsIContent* aContent, int32_t aNameSpaceID,
if (aAttribute == nsGkAtoms::value) {
Accessible* accessible = GetAccessible(aContent);
if(accessible->IsProgress()) {
if(accessible && accessible->IsProgress()) {
FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_VALUE_CHANGE,
aContent);
}

View File

@ -3,6 +3,9 @@ ac_add_options --enable-official-branding
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --enable-update-packaging
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
. $topsrcdir/build/unix/mozconfig.linux

View File

@ -3,6 +3,9 @@ ac_add_options --enable-official-branding
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --enable-update-packaging
# Avoid dependency on libstdc++ 4.5
ac_add_options --enable-stdcxx-compat
. $topsrcdir/build/unix/mozconfig.linux

View File

@ -0,0 +1,13 @@
. "$topsrcdir/browser/config/mozconfigs/common"
ac_add_options --with-l10n-base=../../l10n-central
if [ "${MOZ_UPDATE_CHANNEL}" = "release" -o "${MOZ_UPDATE_CHANNEL}" = "beta" ]; then
ac_add_options --enable-official-branding
fi
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --enable-update-packaging
ac_add_options --with-ccache
. "$topsrcdir/build/mozconfig.common.override"

View File

@ -1165,9 +1165,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FragmentOrElement)
tmp->DeleteProperty(nsGkAtoms::itemtype);
tmp->DeleteProperty(nsGkAtoms::itemref);
tmp->DeleteProperty(nsGkAtoms::itemprop);
} else if (tmp->IsXUL()) {
tmp->DeleteProperty(nsGkAtoms::contextmenulistener);
tmp->DeleteProperty(nsGkAtoms::popuplistener);
}
}
@ -1708,13 +1705,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INTERNAL(FragmentOrElement)
cb.NoteXPCOMChild(property);
property = static_cast<nsISupports*>(tmp->GetProperty(nsGkAtoms::itemtype));
cb.NoteXPCOMChild(property);
} else if (tmp->IsXUL()) {
nsISupports* property = static_cast<nsISupports*>
(tmp->GetProperty(nsGkAtoms::contextmenulistener));
cb.NoteXPCOMChild(property);
property = static_cast<nsISupports*>
(tmp->GetProperty(nsGkAtoms::popuplistener));
cb.NoteXPCOMChild(property);
}
}

View File

@ -226,7 +226,6 @@ GK_ATOM(headerContentStyleType, "content-style-type")
GK_ATOM(headerContentType, "content-type")
GK_ATOM(context, "context")
GK_ATOM(contextmenu, "contextmenu")
GK_ATOM(contextmenulistener, "contextmenulistener")
GK_ATOM(control, "control")
GK_ATOM(controls, "controls")
GK_ATOM(coords, "coords")
@ -833,7 +832,6 @@ GK_ATOM(popupanchor, "popupanchor")
GK_ATOM(popupgroup, "popupgroup")
GK_ATOM(popuphidden, "popuphidden")
GK_ATOM(popuphiding, "popuphiding")
GK_ATOM(popuplistener, "popuplistener")
GK_ATOM(popupset, "popupset")
GK_ATOM(popupshowing, "popupshowing")
GK_ATOM(popupshown, "popupshown")

View File

@ -1554,58 +1554,26 @@ nsXULElement::IsNodeOfType(uint32_t aFlags) const
return !(aFlags & ~eCONTENT);
}
static void
PopupListenerPropertyDtor(void* aObject, nsIAtom* aPropertyName,
void* aPropertyValue, void* aData)
{
nsIDOMEventListener* listener =
static_cast<nsIDOMEventListener*>(aPropertyValue);
if (!listener) {
return;
}
nsEventListenerManager* manager = static_cast<nsINode*>(aObject)->
GetListenerManager(false);
if (manager) {
manager->RemoveEventListenerByType(listener,
NS_LITERAL_STRING("mousedown"),
NS_EVENT_FLAG_BUBBLE |
NS_EVENT_FLAG_SYSTEM_EVENT);
manager->RemoveEventListenerByType(listener,
NS_LITERAL_STRING("contextmenu"),
NS_EVENT_FLAG_BUBBLE |
NS_EVENT_FLAG_SYSTEM_EVENT);
}
NS_RELEASE(listener);
}
nsresult
nsXULElement::AddPopupListener(nsIAtom* aName)
{
// Add a popup listener to the element
bool isContext = (aName == nsGkAtoms::context ||
aName == nsGkAtoms::contextmenu);
nsIAtom* listenerAtom = isContext ?
nsGkAtoms::contextmenulistener :
nsGkAtoms::popuplistener;
uint32_t listenerFlag = isContext ?
XUL_ELEMENT_HAS_CONTENTMENU_LISTENER :
XUL_ELEMENT_HAS_POPUP_LISTENER;
nsCOMPtr<nsIDOMEventListener> popupListener =
static_cast<nsIDOMEventListener*>(GetProperty(listenerAtom));
if (popupListener) {
// Popup listener is already installed.
if (HasFlag(listenerFlag)) {
return NS_OK;
}
popupListener = new nsXULPopupListener(this, isContext);
nsCOMPtr<nsIDOMEventListener> listener =
new nsXULPopupListener(this, isContext);
// Add the popup as a listener on this element.
nsEventListenerManager* manager = GetListenerManager(true);
NS_ENSURE_TRUE(manager, NS_ERROR_FAILURE);
nsresult rv = SetProperty(listenerAtom, popupListener,
PopupListenerPropertyDtor, true);
NS_ENSURE_SUCCESS(rv, rv);
// Want the property to have a reference to the listener.
nsIDOMEventListener* listener = nullptr;
popupListener.swap(listener);
SetFlags(listenerFlag);
if (isContext) {
manager->AddEventListenerByType(listener,

View File

@ -321,11 +321,13 @@ public:
// XUL element specific bits
enum {
XUL_ELEMENT_TEMPLATE_GENERATED = XUL_ELEMENT_FLAG_BIT(0)
XUL_ELEMENT_TEMPLATE_GENERATED = XUL_ELEMENT_FLAG_BIT(0),
XUL_ELEMENT_HAS_CONTENTMENU_LISTENER = XUL_ELEMENT_FLAG_BIT(1),
XUL_ELEMENT_HAS_POPUP_LISTENER = XUL_ELEMENT_FLAG_BIT(2)
};
// Make sure we have space for our bit
PR_STATIC_ASSERT(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET < 32);
// Make sure we have space for our bits
PR_STATIC_ASSERT((ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + 2) < 32);
#undef XUL_ELEMENT_FLAG_BIT

View File

@ -33,7 +33,7 @@
#include "nsHTMLReflowState.h"
#include "nsIObjectLoadingContent.h"
#include "mozilla/Preferences.h"
#include "mozilla/dom/Element.h"
#include "mozilla/dom/FragmentOrElement.h"
// for event firing in context menus
#include "nsPresContext.h"
@ -52,7 +52,8 @@ using namespace mozilla;
#define NS_CONTEXT_MENU_IS_MOUSEUP 1
#endif
nsXULPopupListener::nsXULPopupListener(nsIDOMElement *aElement, bool aIsContext)
nsXULPopupListener::nsXULPopupListener(mozilla::dom::Element* aElement,
bool aIsContext)
: mElement(aElement), mPopupContent(nullptr), mIsContext(aIsContext)
{
}
@ -66,6 +67,25 @@ NS_IMPL_CYCLE_COLLECTION_2(nsXULPopupListener, mElement, mPopupContent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULPopupListener)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULPopupListener)
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsXULPopupListener)
// If the owner, mElement, can be skipped, so can we.
if (tmp->mElement) {
return mozilla::dom::FragmentOrElement::CanSkip(tmp->mElement, true);
}
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsXULPopupListener)
if (tmp->mElement) {
return mozilla::dom::FragmentOrElement::CanSkipInCC(tmp->mElement);
}
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsXULPopupListener)
if (tmp->mElement) {
return mozilla::dom::FragmentOrElement::CanSkipThis(tmp->mElement);
}
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULPopupListener)
NS_INTERFACE_MAP_ENTRY(nsIDOMEventListener)
NS_INTERFACE_MAP_ENTRY(nsISupports)
@ -307,44 +327,37 @@ nsXULPopupListener::LaunchPopup(nsIDOMEvent* aEvent, nsIContent* aTargetContent)
{
nsresult rv = NS_OK;
nsAutoString type(NS_LITERAL_STRING("popup"));
if (mIsContext)
type.AssignLiteral("context");
nsIAtom* type = mIsContext ? nsGkAtoms::context : nsGkAtoms::popup;
nsAutoString identifier;
mElement->GetAttribute(type, identifier);
mElement->GetAttr(kNameSpaceID_None, type, identifier);
if (identifier.IsEmpty()) {
if (type.EqualsLiteral("popup"))
mElement->GetAttribute(NS_LITERAL_STRING("menu"), identifier);
else if (type.EqualsLiteral("context"))
mElement->GetAttribute(NS_LITERAL_STRING("contextmenu"), identifier);
if (type == nsGkAtoms::popup) {
mElement->GetAttr(kNameSpaceID_None, nsGkAtoms::menu, identifier);
} else {
mElement->GetAttr(kNameSpaceID_None, nsGkAtoms::contextmenu, identifier);
}
if (identifier.IsEmpty())
return rv;
}
// Try to find the popup content and the document.
nsCOMPtr<nsIContent> content = do_QueryInterface(mElement);
nsCOMPtr<nsIDocument> document = content->GetDocument();
// Turn the document into a DOM document so we can use getElementById
nsCOMPtr<nsIDOMDocument> domDocument = do_QueryInterface(document);
if (!domDocument) {
NS_ERROR("Popup attached to an element that isn't in XUL!");
nsCOMPtr<nsIDocument> document = mElement->GetDocument();
if (!document) {
NS_WARNING("No document!");
return NS_ERROR_FAILURE;
}
// Handle the _child case for popups and context menus
nsCOMPtr<nsIDOMElement> popupElement;
nsCOMPtr<nsIContent> popup;
if (identifier.EqualsLiteral("_child")) {
nsCOMPtr<nsIContent> popup = GetImmediateChild(content, nsGkAtoms::menupopup);
if (popup)
popupElement = do_QueryInterface(popup);
else {
nsCOMPtr<nsIDOMDocumentXBL> nsDoc(do_QueryInterface(domDocument));
popup = GetImmediateChild(mElement, nsGkAtoms::menupopup);
if (!popup) {
nsCOMPtr<nsIDOMDocumentXBL> nsDoc(do_QueryInterface(document));
nsCOMPtr<nsIDOMNodeList> list;
nsDoc->GetAnonymousNodes(mElement, getter_AddRefs(list));
nsCOMPtr<nsIDOMElement> el = do_QueryInterface(mElement);
nsDoc->GetAnonymousNodes(el, getter_AddRefs(list));
if (list) {
uint32_t ctr,listLength;
nsCOMPtr<nsIDOMNode> node;
@ -355,15 +368,13 @@ nsXULPopupListener::LaunchPopup(nsIDOMEvent* aEvent, nsIContent* aTargetContent)
if (childContent->NodeInfo()->Equals(nsGkAtoms::menupopup,
kNameSpaceID_XUL)) {
popupElement = do_QueryInterface(childContent);
popup.swap(childContent);
break;
}
}
}
}
}
else if (NS_FAILED(rv = domDocument->GetElementById(identifier,
getter_AddRefs(popupElement)))) {
} else if (!(popup = document->GetElementById(identifier))) {
// Use getElementById to obtain the popup content and gracefully fail if
// we didn't find any popup content in the document.
NS_ERROR("GetElementById had some kind of spasm.");
@ -371,12 +382,11 @@ nsXULPopupListener::LaunchPopup(nsIDOMEvent* aEvent, nsIContent* aTargetContent)
}
// return if no popup was found or the popup is the element itself.
if ( !popupElement || popupElement == mElement)
if (!popup || popup == mElement)
return NS_OK;
// Submenus can't be used as context menus or popups, bug 288763.
// Similar code also in nsXULTooltipListener::GetTooltipFor.
nsCOMPtr<nsIContent> popup = do_QueryInterface(popupElement);
nsIContent* parent = popup->GetParent();
if (parent) {
nsMenuFrame* menu = do_QueryFrame(parent->GetPrimaryFrame());
@ -397,7 +407,7 @@ nsXULPopupListener::LaunchPopup(nsIDOMEvent* aEvent, nsIContent* aTargetContent)
(mPopupContent->HasAttr(kNameSpaceID_None, nsGkAtoms::position) ||
(mPopupContent->HasAttr(kNameSpaceID_None, nsGkAtoms::popupanchor) &&
mPopupContent->HasAttr(kNameSpaceID_None, nsGkAtoms::popupalign)))) {
pm->ShowPopup(mPopupContent, content, EmptyString(), 0, 0,
pm->ShowPopup(mPopupContent, mElement, EmptyString(), 0, 0,
false, true, false, aEvent);
}
else {

View File

@ -12,7 +12,7 @@
#include "nsCOMPtr.h"
#include "nsIContent.h"
#include "mozilla/dom/Element.h"
#include "nsIDOMElement.h"
#include "nsIDOMMouseEvent.h"
#include "nsIDOMEventListener.h"
@ -25,12 +25,12 @@ public:
// false, the popup opens on left click on aElement or a descendant. If
// aIsContext is true, the popup is a context menu which opens on a
// context menu event.
nsXULPopupListener(nsIDOMElement *aElement, bool aIsContext);
nsXULPopupListener(mozilla::dom::Element* aElement, bool aIsContext);
virtual ~nsXULPopupListener(void);
// nsISupports
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(nsXULPopupListener)
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_CLASS(nsXULPopupListener)
NS_DECL_NSIDOMEVENTLISTENER
protected:
@ -48,7 +48,7 @@ private:
#endif
// |mElement| is the node to which this listener is attached.
nsCOMPtr<nsIDOMElement> mElement;
nsCOMPtr<mozilla::dom::Element> mElement;
// The popup that is getting shown on top of mElement.
nsCOMPtr<nsIContent> mPopupContent;

View File

@ -11,6 +11,7 @@
#include "AccessCheck.h"
#include "WrapperFactory.h"
#include "xpcprivate.h"
#include "nsContentUtils.h"
#include "XPCQuickStubs.h"
#include "nsIXPConnect.h"
@ -739,5 +740,27 @@ SetXrayExpandoChain(JSObject* obj, JSObject* chain)
}
}
JSContext*
MainThreadDictionaryBase::ParseJSON(const nsAString& aJSON,
mozilla::Maybe<JSAutoRequest>& aAr,
mozilla::Maybe<JSAutoCompartment>& aAc,
JS::Value& aVal)
{
JSContext* cx = nsContentUtils::ThreadJSContextStack()->GetSafeJSContext();
NS_ENSURE_TRUE(cx, nullptr);
JSObject* global = JS_GetGlobalObject(cx);
aAr.construct(cx);
aAc.construct(cx, global);
if (aJSON.IsEmpty()) {
return cx;
}
if (!JS_ParseJSON(cx,
static_cast<const jschar*>(PromiseFlatString(aJSON).get()),
aJSON.Length(), &aVal)) {
return nullptr;
}
return cx;
}
} // namespace dom
} // namespace mozilla

View File

@ -1227,6 +1227,15 @@ MustInheritFromNonRefcountedDOMObject(NonRefcountedDOMObject*)
JSObject* GetXrayExpandoChain(JSObject *obj);
void SetXrayExpandoChain(JSObject *obj, JSObject *chain);
struct MainThreadDictionaryBase
{
protected:
JSContext* ParseJSON(const nsAString& aJSON,
mozilla::Maybe<JSAutoRequest>& aAr,
mozilla::Maybe<JSAutoCompartment>& aAc,
JS::Value& aVal);
};
} // namespace dom
} // namespace mozilla

View File

@ -5390,6 +5390,8 @@ class CGDictionary(CGThing):
d = self.dictionary
if d.parent:
inheritance = ": public %s " % self.makeClassName(d.parent)
elif not self.workers:
inheritance = ": public MainThreadDictionaryBase "
else:
inheritance = ""
memberDecls = [" %s %s;" %
@ -5400,6 +5402,16 @@ class CGDictionary(CGThing):
"struct ${selfName} ${inheritance}{\n"
" ${selfName}() {}\n"
" bool Init(JSContext* cx, const JS::Value& val);\n"
" \n" +
(" bool Init(const nsAString& aJSON)\n"
" {\n"
" mozilla::Maybe<JSAutoRequest> ar;\n"
" mozilla::Maybe<JSAutoCompartment> ac;\n"
" jsval json = JSVAL_VOID;\n"
" JSContext* cx = ParseJSON(aJSON, ar, ac, json);\n"
" NS_ENSURE_TRUE(cx, false);\n"
" return Init(cx, json);\n"
" }\n" if not self.workers else "") +
"\n" +
"\n".join(memberDecls) + "\n"
"private:\n"

View File

@ -248,6 +248,14 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
return NS_OK;
}
bool check = false;
mFile->mFile->Exists(&check);
if (check) {
nsCOMPtr<PostErrorEvent> event = new PostErrorEvent(mParent, POST_ERROR_EVENT_FILE_EXISTS);
NS_DispatchToMainThread(event);
return NS_OK;
}
nsresult rv = mFile->Write(mInputStream);
if (NS_FAILED(rv)) {

View File

@ -847,44 +847,20 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
class PostErrorEvent : public nsRunnable
{
public:
PostErrorEvent(nsRefPtr<DOMRequest>& aRequest, const char* aMessage, DeviceStorageFile* aFile)
PostErrorEvent(nsRefPtr<DOMRequest>& aRequest, const char* aMessage)
{
mRequest.swap(aRequest);
BuildErrorString(aMessage, aFile);
CopyASCIItoUTF16(aMessage, mError);
}
PostErrorEvent(DOMRequest* aRequest, const char* aMessage, DeviceStorageFile* aFile)
PostErrorEvent(DOMRequest* aRequest, const char* aMessage)
: mRequest(aRequest)
{
BuildErrorString(aMessage, aFile);
CopyASCIItoUTF16(aMessage, mError);
}
~PostErrorEvent() {}
void BuildErrorString(const char* aMessage, DeviceStorageFile* aFile)
{
nsAutoString fullPath;
if (aFile && aFile->mFile) {
aFile->mFile->GetPath(fullPath);
}
else {
fullPath.Assign(NS_LITERAL_STRING("null file"));
}
mError = NS_ConvertASCIItoUTF16(aMessage);
mError.Append(NS_LITERAL_STRING(" file path = "));
mError.Append(fullPath.get());
mError.Append(NS_LITERAL_STRING(" path = "));
if (aFile) {
mError.Append(aFile->mPath);
}
else {
mError.Append(NS_LITERAL_STRING("null path"));
}
}
NS_IMETHOD Run()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
@ -1002,9 +978,7 @@ public:
bool check;
mFile->mFile->IsDirectory(&check);
if (!check) {
nsCOMPtr<PostErrorEvent> event = new PostErrorEvent(mRequest,
POST_ERROR_EVENT_FILE_NOT_ENUMERABLE,
mFile);
nsCOMPtr<PostErrorEvent> event = new PostErrorEvent(mRequest, POST_ERROR_EVENT_FILE_NOT_ENUMERABLE);
NS_DispatchToMainThread(event);
return NS_OK;
}
@ -1089,9 +1063,7 @@ nsDOMDeviceStorageCursor::GetElement(nsIDOMElement * *aRequestingElement)
NS_IMETHODIMP
nsDOMDeviceStorageCursor::Cancel()
{
nsCOMPtr<PostErrorEvent> event = new PostErrorEvent(this,
POST_ERROR_EVENT_PERMISSION_DENIED,
mFile);
nsCOMPtr<PostErrorEvent> event = new PostErrorEvent(this, POST_ERROR_EVENT_PERMISSION_DENIED);
NS_DispatchToMainThread(event);
return NS_OK;
}
@ -1100,9 +1072,7 @@ NS_IMETHODIMP
nsDOMDeviceStorageCursor::Allow()
{
if (!mFile->IsSafePath()) {
nsCOMPtr<nsIRunnable> r = new PostErrorEvent(this,
POST_ERROR_EVENT_ILLEGAL_FILE_NAME,
mFile);
nsCOMPtr<nsIRunnable> r = new PostErrorEvent(this, POST_ERROR_EVENT_PERMISSION_DENIED);
NS_DispatchToMainThread(r);
return NS_OK;
}
@ -1281,14 +1251,20 @@ public:
nsCOMPtr<nsIInputStream> stream;
mBlob->GetInternalStream(getter_AddRefs(stream));
bool check = false;
mFile->mFile->Exists(&check);
if (check) {
nsCOMPtr<PostErrorEvent> event = new PostErrorEvent(mRequest, POST_ERROR_EVENT_FILE_EXISTS);
NS_DispatchToMainThread(event);
return NS_OK;
}
nsresult rv = mFile->Write(stream);
if (NS_FAILED(rv)) {
mFile->mFile->Remove(false);
nsCOMPtr<PostErrorEvent> event = new PostErrorEvent(mRequest,
POST_ERROR_EVENT_UNKNOWN,
mFile);
nsCOMPtr<PostErrorEvent> event = new PostErrorEvent(mRequest, POST_ERROR_EVENT_UNKNOWN);
NS_DispatchToMainThread(event);
return NS_OK;
}
@ -1325,7 +1301,7 @@ public:
bool check = false;
mFile->mFile->Exists(&check);
if (!check) {
r = new PostErrorEvent(mRequest, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST, mFile);
r = new PostErrorEvent(mRequest, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
}
}
@ -1362,7 +1338,7 @@ public:
bool check = false;
mFile->mFile->Exists(&check);
if (check) {
r = new PostErrorEvent(mRequest, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST, mFile);
r = new PostErrorEvent(mRequest, POST_ERROR_EVENT_FILE_DOES_NOT_EXIST);
}
else {
r = new PostResultEvent(mRequest, mFile->mPath);
@ -1523,9 +1499,7 @@ public:
NS_IMETHOD Cancel()
{
nsCOMPtr<PostErrorEvent> event = new PostErrorEvent(mRequest,
POST_ERROR_EVENT_PERMISSION_DENIED,
mFile);
nsCOMPtr<PostErrorEvent> event = new PostErrorEvent(mRequest, POST_ERROR_EVENT_PERMISSION_DENIED);
NS_DispatchToMainThread(event);
return NS_OK;
}
@ -1833,12 +1807,11 @@ nsDOMDeviceStorage::AddNamed(nsIDOMBlob *aBlob,
nsCOMPtr<nsIRunnable> r;
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType, mRootDirectory, aPath);
if (!typeChecker->Check(mStorageType, dsf->mFile) ||
if (!dsf->IsSafePath()) {
r = new PostErrorEvent(request, POST_ERROR_EVENT_PERMISSION_DENIED);
} else if (!typeChecker->Check(mStorageType, dsf->mFile) ||
!typeChecker->Check(mStorageType, aBlob)) {
r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_TYPE, dsf);
}
else if (!dsf->IsSafePath()) {
r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_FILE_NAME, dsf);
r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_TYPE);
}
else {
r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_WRITE,
@ -1884,10 +1857,7 @@ nsDOMDeviceStorage::GetInternal(const JS::Value & aPath,
JSString* jsstr = JS_ValueToString(aCx, aPath);
nsDependentJSString path;
if (!path.init(aCx, jsstr)) {
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType, mRootDirectory);
r = new PostErrorEvent(request,
POST_ERROR_EVENT_NON_STRING_TYPE_UNSUPPORTED,
dsf);
r = new PostErrorEvent(request, POST_ERROR_EVENT_UNKNOWN);
NS_DispatchToMainThread(r);
return NS_OK;
}
@ -1895,7 +1865,7 @@ nsDOMDeviceStorage::GetInternal(const JS::Value & aPath,
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType, mRootDirectory, path);
dsf->SetEditable(aEditable);
if (!dsf->IsSafePath()) {
r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_FILE_NAME, dsf);
r = new PostErrorEvent(request, POST_ERROR_EVENT_PERMISSION_DENIED);
} else {
r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_READ,
win, mPrincipal, dsf, request);
@ -1920,8 +1890,7 @@ nsDOMDeviceStorage::Delete(const JS::Value & aPath, JSContext* aCx, nsIDOMDOMReq
JSString* jsstr = JS_ValueToString(aCx, aPath);
nsDependentJSString path;
if (!path.init(aCx, jsstr)) {
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType, mRootDirectory);
r = new PostErrorEvent(request, POST_ERROR_EVENT_NON_STRING_TYPE_UNSUPPORTED, dsf);
r = new PostErrorEvent(request, POST_ERROR_EVENT_UNKNOWN);
NS_DispatchToMainThread(r);
return NS_OK;
}
@ -1929,7 +1898,7 @@ nsDOMDeviceStorage::Delete(const JS::Value & aPath, JSContext* aCx, nsIDOMDOMReq
nsRefPtr<DeviceStorageFile> dsf = new DeviceStorageFile(mStorageType, mRootDirectory, path);
if (!dsf->IsSafePath()) {
r = new PostErrorEvent(request, POST_ERROR_EVENT_ILLEGAL_FILE_NAME, dsf);
r = new PostErrorEvent(request, POST_ERROR_EVENT_PERMISSION_DENIED);
}
else {
r = new DeviceStorageRequest(DeviceStorageRequest::DEVICE_STORAGE_REQUEST_DELETE,

View File

@ -32,14 +32,12 @@ class nsPIDOMWindow;
#include "DeviceStorageRequestChild.h"
#define POST_ERROR_EVENT_FILE_DOES_NOT_EXIST "File location doesn't exists"
#define POST_ERROR_EVENT_FILE_NOT_ENUMERABLE "File location is not enumerable"
#define POST_ERROR_EVENT_PERMISSION_DENIED "Permission Denied"
#define POST_ERROR_EVENT_ILLEGAL_FILE_NAME "Illegal file name"
#define POST_ERROR_EVENT_ILLEGAL_TYPE "Illegal content type"
#define POST_ERROR_EVENT_FILE_EXISTS "NoModificationAllowedError"
#define POST_ERROR_EVENT_FILE_DOES_NOT_EXIST "NotFoundError"
#define POST_ERROR_EVENT_FILE_NOT_ENUMERABLE "TypeMismatchError"
#define POST_ERROR_EVENT_PERMISSION_DENIED "SecurityError"
#define POST_ERROR_EVENT_ILLEGAL_TYPE "TypeMismatchError"
#define POST_ERROR_EVENT_UNKNOWN "Unknown"
#define POST_ERROR_EVENT_NON_STRING_TYPE_UNSUPPORTED "Non-string type unsupported"
#define POST_ERROR_EVENT_NOT_IMPLEMENTED "Not implemented"
using namespace mozilla;
using namespace mozilla::dom;

View File

@ -43,6 +43,8 @@ var tests = [
function fail(e) {
ok(false, "addSuccess was called");
ok(e.target.error.name == "TypeMismatchError", "Error must be TypeMismatchError");
devicestorage_cleanup();
}

View File

@ -13,7 +13,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=717103
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body onunload="unload()">
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717103">Mozilla Bug 717103</a>
<p id="display"></p>
<div id="content" style="display: none">
@ -22,15 +22,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=717103
<pre id="test">
<script class="testbody" type="text/javascript">
function unload() {
delete gDataBlob;
gDataBlob = null;
delete gFileReader;
gFileReader = null;
}
devicestorage_setup();
var gFileName = "devicestorage/hi.png";

View File

@ -45,9 +45,11 @@ function fail(e) {
function next(e) {
if (e != undefined)
ok(true, "addError was called");
if (e != undefined) {
ok(true, "addError was called");
ok(e.target.error.name == "SecurityError", "Error must be SecurityError");
}
var f = tests.pop();
if (f == undefined) {

View File

@ -44,6 +44,7 @@ function addOverwritingSuccess(e) {
function addOverwritingError(e) {
ok(true, "Adding to the same location should fail");
ok(e.target.error.name == "NoModificationAllowedError", "Error must be NoModificationAllowedError");
var storage = navigator.getDeviceStorage("pictures");
request = storage.delete(filename)

View File

@ -3,7 +3,7 @@ b2g = true
browser = false
qemu = true
[test_between_emulators.py]
;[test_between_emulators.py]
[test_incoming.js]
[test_outgoing.js]
[test_message_classes.js]

View File

@ -41,6 +41,15 @@ Cu.import("resource:///modules/services-common/log4moz.js");
let logger = Log4Moz.repository.getLogger("Marionette");
logger.info('marionette-actors.js loaded');
// This is used to prevent newSession from returning before the telephony
// API's are ready; see bug 792647. This assumes that marionette-actors.js
// will be loaded before the 'system-message-listener-ready' message
// is fired. If this stops being true, this approach will have to change.
let systemMessageListenerReady = false;
Services.obs.addObserver(function() {
systemMessageListenerReady = true;
}, "system-message-listener-ready", false);
/**
* Creates the root actor once a connection is established
*/
@ -438,7 +447,10 @@ MarionetteDriverActor.prototype = {
function waitForWindow() {
let checkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
let win = this.getCurrentWindow();
if (!win || (appName == "Firefox" && !win.gBrowser) || (appName == "Fennec" && !win.BrowserApp)) {
if (!win ||
(appName == "Firefox" && !win.gBrowser) ||
(appName == "Fennec" && !win.BrowserApp) ||
(appName == "B2G" && !systemMessageListenerReady)) {
checkTimer.initWithCallback(waitForWindow.bind(this), 100, Ci.nsITimer.TYPE_ONE_SHOT);
}
else {