Merge mozilla-central into mozilla-inbound

This commit is contained in:
Ehsan Akhgari 2012-10-16 20:43:47 -04:00
Родитель dc03f6c243 e2e70de025
Коммит 75ecc91244
22 изменённых файлов: 185 добавлений и 171 удалений

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

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

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

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

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

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

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

@ -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"

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

@ -1165,9 +1165,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(FragmentOrElement)
tmp->DeleteProperty(nsGkAtoms::itemtype); tmp->DeleteProperty(nsGkAtoms::itemtype);
tmp->DeleteProperty(nsGkAtoms::itemref); tmp->DeleteProperty(nsGkAtoms::itemref);
tmp->DeleteProperty(nsGkAtoms::itemprop); 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); cb.NoteXPCOMChild(property);
property = static_cast<nsISupports*>(tmp->GetProperty(nsGkAtoms::itemtype)); property = static_cast<nsISupports*>(tmp->GetProperty(nsGkAtoms::itemtype));
cb.NoteXPCOMChild(property); 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);
} }
} }

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

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

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

@ -1554,58 +1554,26 @@ nsXULElement::IsNodeOfType(uint32_t aFlags) const
return !(aFlags & ~eCONTENT); 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 nsresult
nsXULElement::AddPopupListener(nsIAtom* aName) nsXULElement::AddPopupListener(nsIAtom* aName)
{ {
// Add a popup listener to the element // Add a popup listener to the element
bool isContext = (aName == nsGkAtoms::context || bool isContext = (aName == nsGkAtoms::context ||
aName == nsGkAtoms::contextmenu); aName == nsGkAtoms::contextmenu);
nsIAtom* listenerAtom = isContext ? uint32_t listenerFlag = isContext ?
nsGkAtoms::contextmenulistener : XUL_ELEMENT_HAS_CONTENTMENU_LISTENER :
nsGkAtoms::popuplistener; XUL_ELEMENT_HAS_POPUP_LISTENER;
nsCOMPtr<nsIDOMEventListener> popupListener = if (HasFlag(listenerFlag)) {
static_cast<nsIDOMEventListener*>(GetProperty(listenerAtom));
if (popupListener) {
// Popup listener is already installed.
return NS_OK; return NS_OK;
} }
popupListener = new nsXULPopupListener(this, isContext); nsCOMPtr<nsIDOMEventListener> listener =
new nsXULPopupListener(this, isContext);
// Add the popup as a listener on this element. // Add the popup as a listener on this element.
nsEventListenerManager* manager = GetListenerManager(true); nsEventListenerManager* manager = GetListenerManager(true);
NS_ENSURE_TRUE(manager, NS_ERROR_FAILURE); SetFlags(listenerFlag);
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);
if (isContext) { if (isContext) {
manager->AddEventListenerByType(listener, manager->AddEventListenerByType(listener,

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

@ -321,11 +321,13 @@ public:
// XUL element specific bits // XUL element specific bits
enum { 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 // Make sure we have space for our bits
PR_STATIC_ASSERT(ELEMENT_TYPE_SPECIFIC_BITS_OFFSET < 32); PR_STATIC_ASSERT((ELEMENT_TYPE_SPECIFIC_BITS_OFFSET + 2) < 32);
#undef XUL_ELEMENT_FLAG_BIT #undef XUL_ELEMENT_FLAG_BIT

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

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

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

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

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

@ -11,6 +11,7 @@
#include "AccessCheck.h" #include "AccessCheck.h"
#include "WrapperFactory.h" #include "WrapperFactory.h"
#include "xpcprivate.h" #include "xpcprivate.h"
#include "nsContentUtils.h"
#include "XPCQuickStubs.h" #include "XPCQuickStubs.h"
#include "nsIXPConnect.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 dom
} // namespace mozilla } // namespace mozilla

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

@ -1227,6 +1227,15 @@ MustInheritFromNonRefcountedDOMObject(NonRefcountedDOMObject*)
JSObject* GetXrayExpandoChain(JSObject *obj); JSObject* GetXrayExpandoChain(JSObject *obj);
void SetXrayExpandoChain(JSObject *obj, JSObject *chain); 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 dom
} // namespace mozilla } // namespace mozilla

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

@ -5390,6 +5390,8 @@ class CGDictionary(CGThing):
d = self.dictionary d = self.dictionary
if d.parent: if d.parent:
inheritance = ": public %s " % self.makeClassName(d.parent) inheritance = ": public %s " % self.makeClassName(d.parent)
elif not self.workers:
inheritance = ": public MainThreadDictionaryBase "
else: else:
inheritance = "" inheritance = ""
memberDecls = [" %s %s;" % memberDecls = [" %s %s;" %
@ -5400,6 +5402,16 @@ class CGDictionary(CGThing):
"struct ${selfName} ${inheritance}{\n" "struct ${selfName} ${inheritance}{\n"
" ${selfName}() {}\n" " ${selfName}() {}\n"
" bool Init(JSContext* cx, const JS::Value& val);\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" +
"\n".join(memberDecls) + "\n" "\n".join(memberDecls) + "\n"
"private:\n" "private:\n"

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

@ -248,6 +248,14 @@ DeviceStorageRequestParent::WriteFileEvent::CancelableRun()
return NS_OK; 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); nsresult rv = mFile->Write(mInputStream);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {

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

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

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

@ -32,14 +32,12 @@ class nsPIDOMWindow;
#include "DeviceStorageRequestChild.h" #include "DeviceStorageRequestChild.h"
#define POST_ERROR_EVENT_FILE_DOES_NOT_EXIST "File location doesn't exists" #define POST_ERROR_EVENT_FILE_EXISTS "NoModificationAllowedError"
#define POST_ERROR_EVENT_FILE_NOT_ENUMERABLE "File location is not enumerable" #define POST_ERROR_EVENT_FILE_DOES_NOT_EXIST "NotFoundError"
#define POST_ERROR_EVENT_PERMISSION_DENIED "Permission Denied" #define POST_ERROR_EVENT_FILE_NOT_ENUMERABLE "TypeMismatchError"
#define POST_ERROR_EVENT_ILLEGAL_FILE_NAME "Illegal file name" #define POST_ERROR_EVENT_PERMISSION_DENIED "SecurityError"
#define POST_ERROR_EVENT_ILLEGAL_TYPE "Illegal content type" #define POST_ERROR_EVENT_ILLEGAL_TYPE "TypeMismatchError"
#define POST_ERROR_EVENT_UNKNOWN "Unknown" #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;
using namespace mozilla::dom; using namespace mozilla::dom;

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

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

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

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

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

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

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

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

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

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

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

@ -41,6 +41,15 @@ Cu.import("resource:///modules/services-common/log4moz.js");
let logger = Log4Moz.repository.getLogger("Marionette"); let logger = Log4Moz.repository.getLogger("Marionette");
logger.info('marionette-actors.js loaded'); 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 * Creates the root actor once a connection is established
*/ */
@ -438,7 +447,10 @@ MarionetteDriverActor.prototype = {
function waitForWindow() { function waitForWindow() {
let checkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); let checkTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
let win = this.getCurrentWindow(); 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); checkTimer.initWithCallback(waitForWindow.bind(this), 100, Ci.nsITimer.TYPE_ONE_SHOT);
} }
else { else {