зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central into mozilla-inbound
This commit is contained in:
Коммит
75ecc91244
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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::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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)) {
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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 {
|
||||
|
|
Загрузка…
Ссылка в новой задаче