mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
mozilla-central merge
This commit is contained in:
commit
12059d0133
@ -94,7 +94,10 @@ EXTRA_DSO_LDOPTS += $(MOZ_GTK2_LIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
OS_LIBS += oleaut32.lib
|
||||
OS_LIBS += \
|
||||
oleaut32.lib \
|
||||
version.lib \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -112,12 +112,23 @@ nsIAccessibilityService *nsAccessNode::GetAccService()
|
||||
* Class nsAccessNode
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------
|
||||
// construction
|
||||
//-----------------------------------------------------
|
||||
NS_IMPL_QUERY_INTERFACE2(nsAccessNode, nsIAccessNode, nsPIAccessNode)
|
||||
NS_IMPL_ADDREF(nsAccessNode)
|
||||
NS_IMPL_RELEASE_WITH_DESTROY(nsAccessNode, LastRelease())
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessible. nsISupports
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_0(nsAccessNode)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsAccessNode)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAccessNode)
|
||||
NS_INTERFACE_MAP_ENTRY(nsPIAccessNode)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIAccessNode)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsAccessNode, nsIAccessNode)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE_FULL(nsAccessNode, nsIAccessNode,
|
||||
LastRelease())
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessible. Constructor
|
||||
|
||||
nsAccessNode::nsAccessNode(nsIDOMNode *aNode, nsIWeakReference* aShell):
|
||||
mDOMNode(aNode), mWeakShell(aShell)
|
||||
|
@ -74,13 +74,16 @@ class nsIDocShellTreeItem;
|
||||
typedef nsInterfaceHashtable<nsVoidPtrHashKey, nsIAccessNode>
|
||||
nsAccessNodeHashtable;
|
||||
|
||||
class nsAccessNode: public nsIAccessNode, public nsPIAccessNode
|
||||
class nsAccessNode: public nsIAccessNode,
|
||||
public nsPIAccessNode
|
||||
{
|
||||
public: // construction, destruction
|
||||
nsAccessNode(nsIDOMNode *, nsIWeakReference* aShell);
|
||||
virtual ~nsAccessNode();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsAccessNode, nsIAccessNode)
|
||||
|
||||
NS_DECL_NSIACCESSNODE
|
||||
NS_DECL_NSPIACCESSNODE
|
||||
|
||||
|
@ -65,6 +65,7 @@
|
||||
#include "nsIEventStateManager.h"
|
||||
#include "nsISelection2.h"
|
||||
#include "nsISelectionController.h"
|
||||
#include "nsGUIEvent.h"
|
||||
|
||||
#include "nsContentCID.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
@ -291,6 +292,48 @@ nsAccUtils::HasListener(nsIContent *aContent, const nsAString& aEventType)
|
||||
return listenerManager && listenerManager->HasListenersFor(aEventType);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccUtils::DispatchMouseEvent(PRUint32 aEventType,
|
||||
nsIPresShell *aPresShell,
|
||||
nsIContent *aContent)
|
||||
{
|
||||
nsIFrame *frame = aPresShell->GetPrimaryFrameFor(aContent);
|
||||
if (!frame)
|
||||
return PR_FALSE;
|
||||
|
||||
nsIFrame* rootFrame = aPresShell->GetRootFrame();
|
||||
if (!rootFrame)
|
||||
return PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIWidget> rootWidget = rootFrame->GetWindow();
|
||||
if (!rootWidget)
|
||||
return PR_FALSE;
|
||||
|
||||
// Compute x and y coordinates.
|
||||
nsPoint point = frame->GetOffsetToExternal(rootFrame);
|
||||
nsSize size = frame->GetSize();
|
||||
|
||||
nsPresContext* presContext = aPresShell->GetPresContext();
|
||||
|
||||
PRInt32 x = presContext->AppUnitsToDevPixels(point.x + size.width / 2);
|
||||
PRInt32 y = presContext->AppUnitsToDevPixels(point.y + size.height / 2);
|
||||
|
||||
// Fire mouse event.
|
||||
nsMouseEvent event(PR_TRUE, aEventType, rootWidget,
|
||||
nsMouseEvent::eReal, nsMouseEvent::eNormal);
|
||||
|
||||
event.refPoint = nsIntPoint(x, y);
|
||||
|
||||
event.clickCount = 1;
|
||||
event.button = nsMouseEvent::eLeftButton;
|
||||
event.time = PR_IntervalNow();
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
aPresShell->HandleEventWithTarget(&event, frame, aContent, &status);
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
PRUint32
|
||||
nsAccUtils::GetAccessKeyFor(nsIContent *aContent)
|
||||
{
|
||||
|
@ -124,6 +124,17 @@ public:
|
||||
*/
|
||||
static PRBool HasListener(nsIContent *aContent, const nsAString& aEventType);
|
||||
|
||||
/**
|
||||
* Send mouse events to the given element.
|
||||
*
|
||||
* @param aEventType an event type (see nsGUIEvent.h for constants)
|
||||
* @param aPresShell the presshell for the given element
|
||||
* @param aContent the element element
|
||||
*/
|
||||
static PRBool DispatchMouseEvent(PRUint32 aEventType,
|
||||
nsIPresShell *aPresShell,
|
||||
nsIContent *aContent);
|
||||
|
||||
/**
|
||||
* Return an accesskey registered on the given element by
|
||||
* nsIEventStateManager or 0 if there is no registered accesskey.
|
||||
|
@ -140,9 +140,23 @@ nsAccessibleDOMStringList::Contains(const nsAString& aString, PRBool *aResult)
|
||||
* Class nsAccessible
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------
|
||||
// construction
|
||||
//-----------------------------------------------------
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessible. nsISupports
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsAccessible)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsAccessible, nsAccessNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFirstChild)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mNextSibling)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsAccessible, nsAccessNode)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mParent)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mFirstChild)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mNextSibling)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsAccessible, nsAccessNode)
|
||||
NS_IMPL_RELEASE_INHERITED(nsAccessible, nsAccessNode)
|
||||
|
||||
@ -189,6 +203,11 @@ nsresult nsAccessible::QueryInterface(REFNSIID aIID, void** aInstancePtr)
|
||||
// based on role attribute and aria-multiselectable
|
||||
*aInstancePtr = nsnull;
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsXPCOMCycleCollectionParticipant))) {
|
||||
*aInstancePtr = &NS_CYCLE_COLLECTION_NAME(nsAccessible);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (aIID.Equals(NS_GET_IID(nsIAccessible))) {
|
||||
*aInstancePtr = static_cast<nsIAccessible*>(this);
|
||||
NS_ADDREF_THIS();
|
||||
@ -483,7 +502,7 @@ NS_IMETHODIMP nsAccessible::SetFirstChild(nsIAccessible *aFirstChild)
|
||||
|
||||
NS_IMETHODIMP nsAccessible::SetNextSibling(nsIAccessible *aNextSibling)
|
||||
{
|
||||
mNextSibling = aNextSibling? aNextSibling: DEAD_END_ACCESSIBLE;
|
||||
mNextSibling = aNextSibling;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -538,15 +557,13 @@ NS_IMETHODIMP nsAccessible::InvalidateChildren()
|
||||
// CacheChildren() is called.
|
||||
// Note: we don't want to start creating accessibles at this point,
|
||||
// so don't use GetNextSibling() here. (bug 387252)
|
||||
nsAccessible* child = static_cast<nsAccessible*>(mFirstChild);
|
||||
nsAccessible* child = static_cast<nsAccessible*>(mFirstChild.get());
|
||||
while (child) {
|
||||
child->mParent = nsnull;
|
||||
if (child->mNextSibling == DEAD_END_ACCESSIBLE) {
|
||||
break;
|
||||
}
|
||||
nsIAccessible *next = child->mNextSibling;
|
||||
|
||||
nsCOMPtr<nsIAccessible> next = child->mNextSibling;
|
||||
child->mNextSibling = nsnull;
|
||||
child = static_cast<nsAccessible*>(next);
|
||||
child = static_cast<nsAccessible*>(next.get());
|
||||
}
|
||||
|
||||
mAccChildCount = eChildCountUninitialized;
|
||||
@ -608,9 +625,8 @@ NS_IMETHODIMP nsAccessible::GetNextSibling(nsIAccessible * *aNextSibling)
|
||||
if (mNextSibling || !mParent) {
|
||||
// If no parent, don't try to calculate a new sibling
|
||||
// It either means we're at the root or shutting down the parent
|
||||
if (mNextSibling != DEAD_END_ACCESSIBLE) {
|
||||
NS_IF_ADDREF(*aNextSibling = mNextSibling);
|
||||
}
|
||||
NS_IF_ADDREF(*aNextSibling = mNextSibling);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -3137,40 +3153,30 @@ NS_IMETHODIMP nsAccessible::GetNativeInterface(void **aOutAccessible)
|
||||
|
||||
void nsAccessible::DoCommandCallback(nsITimer *aTimer, void *aClosure)
|
||||
{
|
||||
NS_ASSERTION(gDoCommandTimer, "How did we get here if there was no gDoCommandTimer?");
|
||||
NS_ASSERTION(gDoCommandTimer,
|
||||
"How did we get here if there was no gDoCommandTimer?");
|
||||
NS_RELEASE(gDoCommandTimer);
|
||||
|
||||
nsIContent *content = reinterpret_cast<nsIContent*>(aClosure);
|
||||
nsCOMPtr<nsIDOMXULElement> xulElement(do_QueryInterface(content));
|
||||
if (xulElement) {
|
||||
xulElement->Click();
|
||||
}
|
||||
else {
|
||||
nsIDocument *doc = content->GetDocument();
|
||||
if (!doc) {
|
||||
return;
|
||||
}
|
||||
nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
|
||||
nsPIDOMWindow *outerWindow = doc->GetWindow();
|
||||
if (presShell && outerWindow) {
|
||||
nsAutoPopupStatePusher popupStatePusher(outerWindow, openAllowed);
|
||||
nsCOMPtr<nsIContent> content =
|
||||
reinterpret_cast<nsIContent*>(aClosure);
|
||||
|
||||
nsMouseEvent downEvent(PR_TRUE, NS_MOUSE_BUTTON_DOWN, nsnull,
|
||||
nsMouseEvent::eSynthesized);
|
||||
nsMouseEvent upEvent(PR_TRUE, NS_MOUSE_BUTTON_UP, nsnull,
|
||||
nsMouseEvent::eSynthesized);
|
||||
nsMouseEvent clickEvent(PR_TRUE, NS_MOUSE_CLICK, nsnull,
|
||||
nsMouseEvent::eSynthesized);
|
||||
nsIDocument *doc = content->GetDocument();
|
||||
if (!doc)
|
||||
return;
|
||||
|
||||
nsEventStatus eventStatus = nsEventStatus_eIgnore;
|
||||
content->DispatchDOMEvent(&downEvent, nsnull,
|
||||
presShell->GetPresContext(), &eventStatus);
|
||||
content->DispatchDOMEvent(&upEvent, nsnull,
|
||||
presShell->GetPresContext(), &eventStatus);
|
||||
content->DispatchDOMEvent(&clickEvent, nsnull,
|
||||
presShell->GetPresContext(), &eventStatus);
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIPresShell> presShell = doc->GetPrimaryShell();
|
||||
|
||||
// Scroll into view.
|
||||
presShell->ScrollContentIntoView(content, NS_PRESSHELL_SCROLL_ANYWHERE,
|
||||
NS_PRESSHELL_SCROLL_ANYWHERE);
|
||||
|
||||
// Fire mouse down and mouse up events.
|
||||
PRBool res = nsAccUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_DOWN, presShell,
|
||||
content);
|
||||
if (!res)
|
||||
return;
|
||||
|
||||
nsAccUtils::DispatchMouseEvent(NS_MOUSE_BUTTON_UP, presShell, content);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -69,9 +69,6 @@ class nsIView;
|
||||
#define NS_OK_NO_ARIA_VALUE \
|
||||
NS_ERROR_GENERATE_SUCCESS(NS_ERROR_MODULE_GENERAL, 0x21)
|
||||
|
||||
// When mNextSibling is set to this, it indicates there ar eno more siblings
|
||||
#define DEAD_END_ACCESSIBLE static_cast<nsIAccessible*>((void*)1)
|
||||
|
||||
// Saves a data member -- if child count equals this value we haven't
|
||||
// cached children or child count yet
|
||||
enum { eChildCountUninitialized = -1 };
|
||||
@ -106,6 +103,8 @@ public:
|
||||
virtual ~nsAccessible();
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsAccessible, nsAccessNode)
|
||||
|
||||
NS_DECL_NSIACCESSIBLE
|
||||
NS_DECL_NSPIACCESSIBLE
|
||||
NS_DECL_NSIACCESSIBLEHYPERLINK
|
||||
@ -272,7 +271,9 @@ protected:
|
||||
|
||||
// Data Members
|
||||
nsCOMPtr<nsIAccessible> mParent;
|
||||
nsIAccessible *mFirstChild, *mNextSibling;
|
||||
nsCOMPtr<nsIAccessible> mFirstChild;
|
||||
nsCOMPtr<nsIAccessible> mNextSibling;
|
||||
|
||||
nsRoleMapEntry *mRoleMapEntry; // Non-null indicates author-supplied role; possibly state & value as well
|
||||
PRInt32 mAccChildCount;
|
||||
};
|
||||
|
@ -57,7 +57,22 @@
|
||||
PRBool nsAccEvent::gLastEventFromUserInput = PR_FALSE;
|
||||
nsIDOMNode* nsAccEvent::gLastEventNodeWeak = 0;
|
||||
|
||||
NS_IMPL_ISUPPORTS2(nsAccEvent, nsAccEvent, nsIAccessibleEvent)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccEvent. nsISupports
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_2(nsAccEvent, mAccessible, mDocAccessible)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsAccEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAccessibleEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsAccEvent)
|
||||
NS_INTERFACE_MAP_ENTRY(nsISupports)
|
||||
NS_INTERFACE_MAP_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAccEvent)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsAccEvent)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccEvent. Constructors
|
||||
|
||||
nsAccEvent::nsAccEvent(PRUint32 aEventType, nsIAccessible *aAccessible,
|
||||
PRBool aIsAsynch, EEventRule aEventRule):
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "nsIAccessibleDocument.h"
|
||||
#include "nsIDOMNode.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
class nsIPresShell;
|
||||
|
||||
@ -93,7 +94,9 @@ public:
|
||||
EEventRule aEventRule = eRemoveDupes);
|
||||
virtual ~nsAccEvent() {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsAccEvent)
|
||||
|
||||
NS_DECL_NSIACCESSIBLEEVENT
|
||||
|
||||
static void GetLastEventAttributes(nsIDOMNode *aNode,
|
||||
@ -105,13 +108,13 @@ protected:
|
||||
void CaptureIsFromUserInput(PRBool aIsAsynch);
|
||||
PRBool mIsFromUserInput;
|
||||
|
||||
private:
|
||||
PRUint32 mEventType;
|
||||
EEventRule mEventRule;
|
||||
nsCOMPtr<nsIAccessible> mAccessible;
|
||||
nsCOMPtr<nsIDOMNode> mDOMNode;
|
||||
nsCOMPtr<nsIAccessibleDocument> mDocAccessible;
|
||||
|
||||
private:
|
||||
static PRBool gLastEventFromUserInput;
|
||||
static nsIDOMNode* gLastEventNodeWeak;
|
||||
|
||||
|
@ -50,11 +50,48 @@ nsApplicationAccessible::nsApplicationAccessible():
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsISupports
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsApplicationAccessible,
|
||||
nsAccessible)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsApplicationAccessible)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsApplicationAccessible,
|
||||
nsAccessible)
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> enumerator;
|
||||
tmp->mChildren->Enumerate(getter_AddRefs(enumerator));
|
||||
|
||||
nsCOMPtr<nsIWeakReference> childWeakRef;
|
||||
nsCOMPtr<nsIAccessible> accessible;
|
||||
|
||||
PRBool hasMoreElements;
|
||||
while(NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreElements))
|
||||
&& hasMoreElements) {
|
||||
|
||||
enumerator->GetNext(getter_AddRefs(childWeakRef));
|
||||
accessible = do_QueryReferent(childWeakRef);
|
||||
if (accessible) {
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, accessible);
|
||||
cb.NoteXPCOMChild(accessible);
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsApplicationAccessible,
|
||||
nsAccessible)
|
||||
tmp->mChildren->Clear();
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsApplicationAccessible)
|
||||
NS_INTERFACE_MAP_END_INHERITING(nsAccessible)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsApplicationAccessible, nsAccessible)
|
||||
NS_IMPL_RELEASE_INHERITED(nsApplicationAccessible, nsAccessible)
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsIAccessNode
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsApplicationAccessible::Init()
|
||||
{
|
||||
|
@ -63,6 +63,8 @@ public:
|
||||
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsApplicationAccessible,
|
||||
nsAccessible)
|
||||
|
||||
// nsPIAccessNode
|
||||
NS_IMETHOD Init();
|
||||
|
@ -188,11 +188,14 @@ nsLinkableAccessible::GetActionName(PRUint8 aIndex, nsAString& aName)
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::DoAction(PRUint8 aIndex)
|
||||
{
|
||||
if (aIndex != eAction_Jump)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsCOMPtr<nsIAccessible> actionAcc = GetActionAccessible();
|
||||
if (actionAcc)
|
||||
return actionAcc->DoAction(aIndex);
|
||||
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
return nsHyperTextAccessibleWrap::DoAction(aIndex);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -135,7 +135,34 @@ nsDocAccessible::~nsDocAccessible()
|
||||
{
|
||||
}
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsDocAccessible)
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsDocAccessible. nsISupports
|
||||
|
||||
PR_STATIC_CALLBACK(PLDHashOperator)
|
||||
ElementTraverser(const void *aKey, nsIAccessNode *aAccessNode,
|
||||
void *aUserArg)
|
||||
{
|
||||
nsCycleCollectionTraversalCallback *cb =
|
||||
static_cast<nsCycleCollectionTraversalCallback*>(aUserArg);
|
||||
|
||||
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(*cb, aAccessNode);
|
||||
cb->NoteXPCOMChild(aAccessNode);
|
||||
return PL_DHASH_NEXT;
|
||||
}
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDocAccessible)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mEventsToFire)
|
||||
tmp->mAccessNodeCache.EnumerateRead(ElementTraverser, &cb);
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDocAccessible, nsAccessible)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mEventsToFire)
|
||||
tmp->ClearCache(tmp->mAccessNodeCache);
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsDocAccessible)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIAccessibleDocument)
|
||||
NS_INTERFACE_MAP_ENTRY(nsPIAccessibleDocument)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver)
|
||||
|
@ -65,6 +65,8 @@ class nsDocAccessible : public nsHyperTextAccessibleWrap,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDocAccessible, nsAccessible)
|
||||
|
||||
NS_DECL_NSIACCESSIBLEDOCUMENT
|
||||
NS_DECL_NSPIACCESSIBLEDOCUMENT
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
@ -37,6 +37,7 @@
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsAccessNodeWrap.h"
|
||||
#include <tchar.h>
|
||||
#include "ISimpleDOMNode_i.c"
|
||||
#include "nsAccessibilityAtoms.h"
|
||||
#include "nsIAccessibilityService.h"
|
||||
@ -66,6 +67,8 @@ LPFNNOTIFYWINEVENT nsAccessNodeWrap::gmNotifyWinEvent = nsnull;
|
||||
LPFNGETGUITHREADINFO nsAccessNodeWrap::gmGetGUIThreadInfo = nsnull;
|
||||
|
||||
PRBool nsAccessNodeWrap::gIsEnumVariantSupportDisabled = 0;
|
||||
// Used to determine whether an IAccessible2 compatible screen reader is loaded.
|
||||
PRBool nsAccessNodeWrap::gIsIA2Disabled = PR_FALSE;
|
||||
|
||||
nsIAccessibleTextChangeEvent *nsAccessNodeWrap::gTextEvent = nsnull;
|
||||
|
||||
@ -599,6 +602,8 @@ void nsAccessNodeWrap::InitAccessibility()
|
||||
gmGetGUIThreadInfo = (LPFNGETGUITHREADINFO)GetProcAddress(gmUserLib,"GetGUIThreadInfo");
|
||||
}
|
||||
|
||||
DoATSpecificProcessing();
|
||||
|
||||
nsAccessNode::InitXPAccessibility();
|
||||
}
|
||||
|
||||
@ -655,3 +660,40 @@ GetHRESULT(nsresult aResult)
|
||||
}
|
||||
}
|
||||
|
||||
PRBool nsAccessNodeWrap::IsOnlyMsaaCompatibleJawsPresent()
|
||||
{
|
||||
HMODULE jhookhandle = ::GetModuleHandleW(NS_LITERAL_STRING("jhook").get());
|
||||
if (!jhookhandle)
|
||||
return PR_FALSE; // No JAWS, or some other screen reader, use IA2
|
||||
|
||||
PRUnichar fileName[MAX_PATH];
|
||||
::GetModuleFileNameW(jhookhandle, fileName, MAX_PATH);
|
||||
|
||||
DWORD dummy;
|
||||
DWORD length = ::GetFileVersionInfoSizeW(fileName, &dummy);
|
||||
|
||||
LPBYTE versionInfo = new BYTE[length];
|
||||
::GetFileVersionInfoW(fileName, 0, length, versionInfo);
|
||||
|
||||
UINT uLen;
|
||||
VS_FIXEDFILEINFO *fixedFileInfo;
|
||||
::VerQueryValueW(versionInfo, L"\\", (LPVOID*)&fixedFileInfo, &uLen);
|
||||
DWORD dwFileVersionMS = fixedFileInfo->dwFileVersionMS;
|
||||
DWORD dwFileVersionLS = fixedFileInfo->dwFileVersionLS;
|
||||
delete [] versionInfo;
|
||||
|
||||
DWORD dwLeftMost = HIWORD(dwFileVersionMS);
|
||||
// DWORD dwSecondLeft = LOWORD(dwFileVersionMS);
|
||||
DWORD dwSecondRight = HIWORD(dwFileVersionLS);
|
||||
// DWORD dwRightMost = LOWORD(dwFileVersionLS);
|
||||
|
||||
return (dwLeftMost < 8
|
||||
|| (dwLeftMost == 8 && dwSecondRight < 2173));
|
||||
}
|
||||
|
||||
void nsAccessNodeWrap::DoATSpecificProcessing()
|
||||
{
|
||||
if (IsOnlyMsaaCompatibleJawsPresent())
|
||||
// All versions below 8.0.2173 are not compatible
|
||||
gIsIA2Disabled = PR_TRUE;
|
||||
}
|
||||
|
@ -158,12 +158,20 @@ class nsAccessNodeWrap : public nsAccessNode,
|
||||
|
||||
static int FilterA11yExceptions(unsigned int aCode, EXCEPTION_POINTERS *aExceptionInfo);
|
||||
|
||||
static PRBool IsOnlyMsaaCompatibleJawsPresent();
|
||||
static void DoATSpecificProcessing();
|
||||
protected:
|
||||
void GetAccessibleFor(nsIDOMNode *node, nsIAccessible **newAcc);
|
||||
ISimpleDOMNode* MakeAccessNode(nsIDOMNode *node);
|
||||
|
||||
static PRBool gIsEnumVariantSupportDisabled;
|
||||
|
||||
/**
|
||||
* Used to determine whether an IAccessible2 compatible screen reader is
|
||||
* loaded. Currently used for JAWS versions older than 8.0.2173.
|
||||
*/
|
||||
static PRBool gIsIA2Disabled;
|
||||
|
||||
/**
|
||||
* It is used in nsHyperTextAccessibleWrap for IA2::newText/oldText
|
||||
* implementation.
|
||||
|
@ -117,7 +117,7 @@ __try {
|
||||
*ppv = static_cast<IEnumVARIANT*>(this);
|
||||
} else if (IID_IServiceProvider == iid)
|
||||
*ppv = static_cast<IServiceProvider*>(this);
|
||||
else if (IID_IAccessible2 == iid)
|
||||
else if (IID_IAccessible2 == iid && !gIsIA2Disabled)
|
||||
*ppv = static_cast<IAccessible2*>(this);
|
||||
|
||||
if (NULL == *ppv) {
|
||||
|
@ -47,6 +47,7 @@ include $(topsrcdir)/config/rules.mk
|
||||
|
||||
_TEST_FILES =\
|
||||
moz.png \
|
||||
nsIAccessible_actions.js \
|
||||
nsIAccessible_name.css \
|
||||
nsIAccessible_name.xbl \
|
||||
test_aria_activedescendant.html \
|
||||
@ -56,6 +57,8 @@ _TEST_FILES =\
|
||||
test_cssattrs.html \
|
||||
test_groupattrs.xul \
|
||||
$(warning test_table_indexes.html temporarily disabled) \
|
||||
test_nsIAccessible_actions.html \
|
||||
test_nsIAccessible_actions.xul \
|
||||
test_nsIAccessible_name.html \
|
||||
test_nsIAccessible_name.xul \
|
||||
test_nsIAccessibleTable_1.html \
|
||||
|
150
accessible/tests/mochitest/nsIAccessible_actions.js
Normal file
150
accessible/tests/mochitest/nsIAccessible_actions.js
Normal file
@ -0,0 +1,150 @@
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// General
|
||||
|
||||
const nsIAccessibleRetrieval = Components.interfaces.nsIAccessibleRetrieval;
|
||||
const nsIAccessibleRole = Components.interfaces.nsIAccessibleRole;
|
||||
|
||||
var gAccRetrieval = null;
|
||||
|
||||
function initialize()
|
||||
{
|
||||
gAccRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
|
||||
getService(nsIAccessibleRetrieval);
|
||||
}
|
||||
|
||||
addLoadEvent(initialize);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Event constants
|
||||
|
||||
const MOUSEDOWN_EVENT = 1;
|
||||
const MOUSEUP_EVENT = 2;
|
||||
const CLICK_EVENT = 4;
|
||||
const COMMAND_EVENT = 8;
|
||||
|
||||
const CLICK_EVENTS = MOUSEDOWN_EVENT | MOUSEUP_EVENT | CLICK_EVENT;
|
||||
const ALL_EVENTS = CLICK_EVENTS | COMMAND_EVENT;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Public functions
|
||||
|
||||
function testActions(aArray, aIndex)
|
||||
{
|
||||
if (!aIndex)
|
||||
aIndex = 0;
|
||||
|
||||
if (aIndex == aArray.length) {
|
||||
SimpleTest.finish();
|
||||
return;
|
||||
}
|
||||
|
||||
var ID = aArray[aIndex].ID;
|
||||
var actionName = aArray[aIndex].actionName;
|
||||
var events = aArray[aIndex].events;
|
||||
|
||||
var elm = document.getElementById(ID);
|
||||
if (!elm) {
|
||||
ok(false, "There is no element with ID " + ID);
|
||||
SimpleTest.finish();
|
||||
return null;
|
||||
}
|
||||
|
||||
var acc = null;
|
||||
try {
|
||||
acc = gAccRetrieval.getAccessibleFor(elm);
|
||||
} catch(e) {
|
||||
}
|
||||
|
||||
if (!acc) {
|
||||
ok(false, "There is no accessible for " + ID);
|
||||
SimpleTest.finish();
|
||||
return null;
|
||||
}
|
||||
|
||||
is(acc.getActionName(0), actionName,
|
||||
"Wrong action name of the accessible for " + ID);
|
||||
|
||||
gEventHandler.initialize(ID, elm, events);
|
||||
|
||||
acc.doAction(0);
|
||||
|
||||
window.setTimeout(
|
||||
function()
|
||||
{
|
||||
gEventHandler.checkEvents();
|
||||
testActions(aArray, aIndex + 1);
|
||||
},
|
||||
200
|
||||
);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Private
|
||||
|
||||
var gEventHandler =
|
||||
{
|
||||
initialize: function(aID, aElm, aExpectedEvents)
|
||||
{
|
||||
this.ID = aID,
|
||||
this.element = aElm;
|
||||
this.mExpectedEvents = aExpectedEvents;
|
||||
this.mFiredEvents = 0;
|
||||
|
||||
if (this.mExpectedEvents & MOUSEDOWN_EVENT)
|
||||
aElm.addEventListener("mousedown", this, false);
|
||||
|
||||
if (this.mExpectedEvents & MOUSEUP_EVENT)
|
||||
aElm.addEventListener("mouseup", this, false);
|
||||
|
||||
if (this.mExpectedEvents & CLICK_EVENT)
|
||||
aElm.addEventListener("click", this, false);
|
||||
|
||||
if (this.mExpectedEvents & COMMAND_EVENT)
|
||||
aElm.addEventListener("command", this, false);
|
||||
},
|
||||
|
||||
checkEvents: function()
|
||||
{
|
||||
if (this.mExpectedEvents & MOUSEDOWN_EVENT) {
|
||||
ok(this.mFiredEvents & MOUSEDOWN_EVENT,
|
||||
"mousedown hasn't been fired for " + this.ID);
|
||||
this.element.removeEventListener("mousedown", this, false);
|
||||
}
|
||||
|
||||
if (this.mExpectedEvents & MOUSEUP_EVENT) {
|
||||
ok(this.mFiredEvents & MOUSEUP_EVENT,
|
||||
"mouseup hasn't been fired for " + this.ID);
|
||||
this.element.removeEventListener("mouseup", this, false);
|
||||
}
|
||||
|
||||
if (this.mExpectedEvents & CLICK_EVENT) {
|
||||
ok(this.mFiredEvents & CLICK_EVENT,
|
||||
"click hasn't been fired for " + this.ID);
|
||||
this.element.removeEventListener("click", this, false);
|
||||
}
|
||||
|
||||
if (this.mExpectedEvents & COMMAND_EVENT) {
|
||||
ok(this.mFiredEvents & COMMAND_EVENT,
|
||||
"command hasn't been fired for " + this.ID);
|
||||
this.element.removeEventListener("command", this, false);
|
||||
}
|
||||
},
|
||||
|
||||
ID: "",
|
||||
element: null,
|
||||
|
||||
handleEvent : function(aEvent)
|
||||
{
|
||||
if (aEvent.type == "mousedown")
|
||||
this.mFiredEvents |= MOUSEDOWN_EVENT;
|
||||
else if(aEvent.type == "mouseup")
|
||||
this.mFiredEvents |= MOUSEUP_EVENT;
|
||||
else if(aEvent.type == "click")
|
||||
this.mFiredEvents |= CLICK_EVENT;
|
||||
else if(aEvent.type == "command")
|
||||
this.mFiredEvents |= COMMAND_EVENT;
|
||||
},
|
||||
|
||||
mExpectedEvents: 0,
|
||||
mFiredEvents: 0
|
||||
};
|
49
accessible/tests/mochitest/test_nsIAccessible_actions.html
Normal file
49
accessible/tests/mochitest/test_nsIAccessible_actions.html
Normal file
@ -0,0 +1,49 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>nsIAccessible actions testing</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/nsIAccessible_actions.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function doTest()
|
||||
{
|
||||
var actionsArray = [
|
||||
{
|
||||
ID: "clickable",
|
||||
actionName: "click",
|
||||
events: CLICK_EVENTS
|
||||
}
|
||||
];
|
||||
testActions(actionsArray);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=410765"
|
||||
title="nsIAccessible actions testing">
|
||||
Mozilla Bug 410765
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<div id="clickable" onclick="">Clickable text</div>
|
||||
|
||||
</body>
|
||||
</html>
|
98
accessible/tests/mochitest/test_nsIAccessible_actions.xul
Normal file
98
accessible/tests/mochitest/test_nsIAccessible_actions.xul
Normal file
@ -0,0 +1,98 @@
|
||||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/a11y/accessible/nsIAccessible_name.css"
|
||||
type="text/css"?>
|
||||
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="nsIAccessible actions testing">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/a11y/accessible/nsIAccessible_actions.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
function doTest()
|
||||
{
|
||||
var actionsArray = [
|
||||
{
|
||||
ID: "menu",
|
||||
actionName: "click",
|
||||
events: CLICK_EVENTS
|
||||
},
|
||||
{
|
||||
ID: "submenu",
|
||||
actionName: "click",
|
||||
events: CLICK_EVENTS
|
||||
},
|
||||
{
|
||||
ID: "menuitem",
|
||||
actionName: "click",
|
||||
events: ALL_EVENTS
|
||||
},
|
||||
{
|
||||
ID: "button",
|
||||
actionName: "press",
|
||||
events: ALL_EVENTS
|
||||
},
|
||||
{
|
||||
ID: "buttonmenu",
|
||||
actionName: "press",
|
||||
events: CLICK_EVENTS
|
||||
},
|
||||
{
|
||||
ID: "buttonmenu_item",
|
||||
actionName: "click",
|
||||
events: CLICK_EVENTS
|
||||
}
|
||||
];
|
||||
testActions(actionsArray);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=410765"
|
||||
title="nsIAccessible actions testing">
|
||||
Mozilla Bug 410765
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<menubar>
|
||||
<menu label="menu" id="menu">
|
||||
<menupopup>
|
||||
<menuitem label="menu item" id="menuitem"/>
|
||||
<menu label="submenu" id="submenu">
|
||||
<menupopup>
|
||||
<menuitem label="menu item"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menubar>
|
||||
|
||||
<button label="button" id="button"/>
|
||||
|
||||
<button type="menu" id="buttonmenu" label="button">
|
||||
<menupopup>
|
||||
<menuitem label="item1" id="buttonmenu_item"/>
|
||||
<menuitem label="item1"/>
|
||||
</menupopup>
|
||||
</button>
|
||||
</window>
|
||||
|
BIN
browser/base/content/aboutRobots-icon-rtl.png
Normal file
BIN
browser/base/content/aboutRobots-icon-rtl.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.7 KiB |
@ -29,6 +29,7 @@
|
||||
# Jeff Walden <jwalden+code@mit.edu>
|
||||
# Johnathan Nightingale <johnath@mozilla.com>
|
||||
# Justin Dolske <dolske@mozilla.com>
|
||||
# Ehsan Akhgari <ehsan.akhgari@gmail.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
@ -80,13 +81,32 @@
|
||||
}
|
||||
}
|
||||
]]></script>
|
||||
|
||||
<style type="text/css"><![CDATA[
|
||||
#errorPageContainer {
|
||||
background: url('chrome://browser/content/aboutRobots-icon.png') left 0 no-repeat -moz-Field;
|
||||
-moz-background-origin: content;
|
||||
}
|
||||
|
||||
#errorTrailerDescText {
|
||||
float: right;
|
||||
}
|
||||
|
||||
body[dir=rtl] #errorPageContainer {
|
||||
background-image: url('chrome://browser/content/aboutRobots-icon-rtl.png');
|
||||
background-position: right 0;
|
||||
}
|
||||
|
||||
body[dir=rtl] #errorTrailerDescText {
|
||||
float: left;
|
||||
}
|
||||
]]></style>
|
||||
</head>
|
||||
|
||||
<body dir="&locale.dir;">
|
||||
|
||||
<!-- PAGE CONTAINER (for styling purposes only) -->
|
||||
<div id="errorPageContainer"
|
||||
style="background: url('chrome://browser/content/aboutRobots-icon.png') left 0 no-repeat -moz-Field; -moz-background-origin: content;">
|
||||
<div id="errorPageContainer">
|
||||
|
||||
<!-- Error Title -->
|
||||
<div id="errorTitle">
|
||||
@ -113,7 +133,7 @@
|
||||
|
||||
<!-- Short Description -->
|
||||
<div id="errorTrailerDesc">
|
||||
<p id="errorTrailerDescText" style="float: right;">&robots.errorTrailerDescText;</p>
|
||||
<p id="errorTrailerDescText">&robots.errorTrailerDescText;</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
@ -104,10 +104,14 @@
|
||||
<!-- for url bar autocomplete -->
|
||||
<panel type="autocomplete-richlistbox" chromedir="&locale.dir;" id="PopupAutoCompleteRichResult" noautofocus="true" hidden="true"/>
|
||||
|
||||
<!-- XXX panel element that has one or more text fields should not be
|
||||
top-most panel, for IME users. See bug 433340 comment 100. -->
|
||||
<panel id="editBookmarkPanel"
|
||||
orient="vertical"
|
||||
ignorekeys="true"
|
||||
hidden="true"
|
||||
noautohide="true"
|
||||
onpopupshowing="this.removeAttribute('noautohide');"
|
||||
onpopupshown="StarUI.panelShown(event);"
|
||||
aria-labelledby="editBookmarkPanelTitle">
|
||||
<hbox flex="1" align="top">
|
||||
|
@ -278,7 +278,6 @@
|
||||
mTab: aTab,
|
||||
mBrowser: aBrowser,
|
||||
mBlank: aStartsBlank,
|
||||
mLastURI: null,
|
||||
|
||||
// cache flags for correct status bar update after tab switching
|
||||
mStateFlags: 0,
|
||||
@ -1389,6 +1388,18 @@
|
||||
|
||||
<method name="removeTab">
|
||||
<parameter name="aTab"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
this._endRemoveTab(this._beginRemoveTab(aTab, true));
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<!-- Returns the tab being removed. This might not be the same as aTab,
|
||||
in cases when aTab is not actually a tab -->
|
||||
<method name="_beginRemoveTab">
|
||||
<parameter name="aTab"/>
|
||||
<parameter name="aFireBeforeUnload"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
this._browsers = null; // invalidate cache
|
||||
@ -1403,9 +1414,11 @@
|
||||
return;
|
||||
}
|
||||
|
||||
var ds = this.getBrowserForTab(aTab).docShell;
|
||||
if (ds.contentViewer && !ds.contentViewer.permitUnload())
|
||||
return;
|
||||
if (aFireBeforeUnload) {
|
||||
var ds = this.getBrowserForTab(aTab).docShell;
|
||||
if (ds.contentViewer && !ds.contentViewer.permitUnload())
|
||||
return;
|
||||
}
|
||||
|
||||
// see notes in addTab
|
||||
var _delayedUpdate = function(aTabContainer) {
|
||||
@ -1435,15 +1448,7 @@
|
||||
evt.initEvent("TabClose", true, false);
|
||||
aTab.dispatchEvent(evt);
|
||||
|
||||
var index = -1;
|
||||
if (this.mCurrentTab == aTab)
|
||||
index = this.mTabContainer.selectedIndex;
|
||||
else {
|
||||
// Find and locate the tab in our list.
|
||||
for (var i = 0; i < l; i++)
|
||||
if (this.mTabContainer.childNodes[i] == aTab)
|
||||
index = i;
|
||||
}
|
||||
var index = aTab._tPos;
|
||||
|
||||
// Remove the tab's filter and progress listener.
|
||||
const filter = this.mTabFilters[index];
|
||||
@ -1459,22 +1464,34 @@
|
||||
// We are no longer the primary content area.
|
||||
oldBrowser.setAttribute("type", "content-targetable");
|
||||
|
||||
// Get the index of the tab we're removing before unselecting it
|
||||
var currentIndex = this.mTabContainer.selectedIndex;
|
||||
|
||||
var oldTab = aTab;
|
||||
|
||||
// clean up the before/afterselected attributes before removing the tab
|
||||
oldTab._selected = false;
|
||||
|
||||
// Remove this tab as the owner of any other tabs, since it's going away.
|
||||
for (i = 0; i < this.mTabContainer.childNodes.length; ++i) {
|
||||
for (var i = 0; i < this.mTabs.length; ++i) {
|
||||
var tab = this.mTabContainer.childNodes[i];
|
||||
if ("owner" in tab && tab.owner == oldTab)
|
||||
if ("owner" in tab && tab.owner == aTab)
|
||||
// |tab| is a child of the tab we're removing, make it an orphan
|
||||
tab.owner = null;
|
||||
}
|
||||
|
||||
return aTab;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="_endRemoveTab">
|
||||
<parameter name="aTab"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var browser = this.getBrowserForTab(aTab);
|
||||
var length = this.mTabs.length;
|
||||
|
||||
// Get the index of the tab we're removing before unselecting it
|
||||
var currentIndex = this.mTabContainer.selectedIndex;
|
||||
var index = aTab._tPos;
|
||||
|
||||
// clean up the before/afterselected attributes before removing the
|
||||
// tab. But make sure this happens after we grab currentIndex.
|
||||
aTab._selected = false;
|
||||
|
||||
// Because of the way XBL works (fields just set JS
|
||||
// properties on the element) and the code we have in place
|
||||
// to preserve the JS objects for any elements that have
|
||||
@ -1485,16 +1502,18 @@
|
||||
// XBL implementation of nsIObserver still works. But
|
||||
// clearing focusedWindow happens below because it gets
|
||||
// reset by updateCurrentBrowser.
|
||||
oldBrowser.destroy();
|
||||
browser.destroy();
|
||||
|
||||
if (oldBrowser == this.mCurrentBrowser)
|
||||
if (browser == this.mCurrentBrowser)
|
||||
this.mCurrentBrowser = null;
|
||||
|
||||
// Remove the tab
|
||||
this.mTabContainer.removeChild(oldTab);
|
||||
this.mTabContainer.removeChild(aTab);
|
||||
// Update our length
|
||||
--length;
|
||||
// invalidate cache, because mTabContainer is about to change
|
||||
this._browsers = null;
|
||||
this.mPanelContainer.removeChild(oldBrowser.parentNode);
|
||||
this.mPanelContainer.removeChild(browser.parentNode);
|
||||
|
||||
try {
|
||||
// if we're at the right side (and not the logical end,
|
||||
@ -1523,24 +1542,24 @@
|
||||
else if (currentIndex < index)
|
||||
newIndex = currentIndex;
|
||||
else {
|
||||
if ("owner" in oldTab && oldTab.owner &&
|
||||
if ("owner" in aTab && aTab.owner &&
|
||||
this.mPrefs.getBoolPref("browser.tabs.selectOwnerOnClose")) {
|
||||
for (i = 0; i < this.mTabContainer.childNodes.length; ++i) {
|
||||
for (var i = 0; i < length; ++i) {
|
||||
tab = this.mTabContainer.childNodes[i];
|
||||
if (tab == oldTab.owner) {
|
||||
if (tab == aTab.owner) {
|
||||
newIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (newIndex == -1)
|
||||
newIndex = (index == l - 1) ? index - 1 : index;
|
||||
newIndex = (index == length) ? index - 1 : index;
|
||||
}
|
||||
|
||||
// Select the new tab
|
||||
this.selectedTab = this.mTabContainer.childNodes[newIndex];
|
||||
this.selectedTab = this.mTabs[newIndex];
|
||||
|
||||
for (i = oldTab._tPos; i < this.mTabContainer.childNodes.length; i++) {
|
||||
for (i = aTab._tPos; i < length; i++) {
|
||||
this.mTabContainer.childNodes[i]._tPos = i;
|
||||
}
|
||||
this.mTabBox.selectedPanel = this.getBrowserForTab(this.mCurrentTab).parentNode;
|
||||
@ -1549,8 +1568,53 @@
|
||||
this.updateCurrentBrowser();
|
||||
|
||||
// see comment above destroy above
|
||||
oldBrowser.focusedWindow = null;
|
||||
oldBrowser.focusedElement = null;
|
||||
browser.focusedWindow = null;
|
||||
browser.focusedElement = null;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
||||
<method name="swapBrowsersAndCloseOther">
|
||||
<parameter name="aOurTab"/>
|
||||
<parameter name="aOtherTab"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
var remoteBrowser =
|
||||
aOtherTab.ownerDocument.defaultView.getBrowser();
|
||||
var tabCount = remoteBrowser.mTabs.length;
|
||||
|
||||
// First, start teardown of the other browser. Make sure to not
|
||||
// fire the beforeunload event in the process.
|
||||
var tabToRemove = remoteBrowser._beginRemoveTab(aOtherTab, false);
|
||||
|
||||
// Unhook our progress listener
|
||||
var ourIndex = aOurTab._tPos;
|
||||
const filter = this.mTabFilters[ourIndex];
|
||||
var tabListener = this.mTabListeners[ourIndex];
|
||||
var ourBrowser = this.getBrowserForTab(aOurTab);
|
||||
ourBrowser.webProgress.removeProgressListener(filter);
|
||||
filter.removeProgressListener(tabListener);
|
||||
var tabListenerBlank = tabListener.mBlank;
|
||||
|
||||
// Swap the docshells
|
||||
ourBrowser.swapDocShells(remoteBrowser.getBrowserForTab(aOtherTab));
|
||||
|
||||
// Finish tearing down the tab that's going away.
|
||||
remoteBrowser._endRemoveTab(tabToRemove);
|
||||
|
||||
// Restore the progress listener
|
||||
tabListener = this.mTabProgressListener(aOurTab, ourBrowser,
|
||||
tabListenerBlank);
|
||||
this.mTabListeners[ourIndex] = tabListener;
|
||||
filter.addProgressListener(tabListener,
|
||||
Components.interfaces.nsIWebProgress.NOTIFY_ALL);
|
||||
|
||||
ourBrowser.webProgress.addProgressListener(filter,
|
||||
Components.interfaces.nsIWebProgress.NOTIFY_ALL);
|
||||
|
||||
// close the other window if this was its last tab
|
||||
if (tabCount == 1)
|
||||
aOtherTab.ownerDocument.defaultView.close();
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
@ -1879,19 +1943,26 @@
|
||||
}
|
||||
}
|
||||
else if (draggedTab) {
|
||||
// copy the dropped tab and remove it from the other window
|
||||
// (making it seem to have moved between windows)
|
||||
// swap the dropped tab with a new one we create and then close
|
||||
// it in the other window (making it seem to have moved between
|
||||
// windows)
|
||||
newIndex = this.getNewIndex(aEvent);
|
||||
newTab = this.duplicateTab(draggedTab);
|
||||
this.moveTabTo(newTab, newIndex);
|
||||
this.selectedTab = newTab;
|
||||
newTab = this.addTab("about:blank");
|
||||
var newBrowser = this.getBrowserForTab(newTab);
|
||||
// Stop the about:blank load
|
||||
newBrowser.stop();
|
||||
// make sure it has a docshell
|
||||
newBrowser.docShell;
|
||||
|
||||
var remoteBrowser = draggedTab.ownerDocument.defaultView.getBrowser();
|
||||
var tabCount = remoteBrowser.tabContainer.childNodes.length;
|
||||
remoteBrowser.removeTab(draggedTab);
|
||||
// close the other window if this was its last tab
|
||||
if (tabCount == 1)
|
||||
draggedTab.ownerDocument.defaultView.close();
|
||||
this.moveTabTo(newTab, newIndex);
|
||||
|
||||
this.swapBrowsersAndCloseOther(newTab, draggedTab);
|
||||
|
||||
// We need to set selectedTab after we've done
|
||||
// swapBrowsersAndCloseOther, so that the updateCurrentBrowser
|
||||
// it triggers will correctly update our URL bar.
|
||||
this.selectedTab = newTab;
|
||||
this.setTabTitle(newTab);
|
||||
}
|
||||
else {
|
||||
var url = transferUtils.retrieveURLFromData(aXferData.data, aXferData.flavour.contentType);
|
||||
|
@ -59,6 +59,8 @@ _BROWSER_FILES = browser_bug321000.js \
|
||||
autodiscovery.html \
|
||||
moz.png \
|
||||
browser_getshortcutoruri.js \
|
||||
browser_page_style_menu.js \
|
||||
page_style_sample.html \
|
||||
$(NULL)
|
||||
|
||||
ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT)))
|
||||
|
66
browser/base/content/test/browser_page_style_menu.js
Normal file
66
browser/base/content/test/browser_page_style_menu.js
Normal file
@ -0,0 +1,66 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
finish();
|
||||
return;
|
||||
|
||||
var tab = gBrowser.addTab();
|
||||
gBrowser.selectedTab = tab;
|
||||
tab.linkedBrowser.addEventListener("load", checkPageStyleMenu, true);
|
||||
content.location =
|
||||
"chrome://mochikit/content/browser/browser/base/content/test/page_style_sample.html";
|
||||
}
|
||||
|
||||
function checkPageStyleMenu() {
|
||||
var menupopup = document.getElementById("pageStyleMenu")
|
||||
.getElementsByTagName("menupopup")[0];
|
||||
stylesheetFillPopup(menupopup);
|
||||
|
||||
var items = [];
|
||||
var current = menupopup.getElementsByTagName("menuseparator")[0];
|
||||
while (current.nextSibling) {
|
||||
current = current.nextSibling;
|
||||
items.push(current);
|
||||
}
|
||||
|
||||
var validLinks = 0;
|
||||
Array.forEach(content.document.getElementsByTagName("link"), function (link) {
|
||||
var title = link.getAttribute("title");
|
||||
var rel = link.getAttribute("rel");
|
||||
var media = link.getAttribute("media");
|
||||
var idstring = "link " + (title ? title : "without title and") +
|
||||
" with rel=\"" + rel + "\"" +
|
||||
(media ? " and media=\"" + media + "\"" : "");
|
||||
|
||||
var item = items.filter(function (item) item.label == title);
|
||||
var found = item.length == 1;
|
||||
var checked = found && (item[0].getAttribute("checked") == "true");
|
||||
|
||||
switch (link.getAttribute("data-state")) {
|
||||
case "0":
|
||||
ok(!found, idstring + " does not show up in page style menu");
|
||||
break;
|
||||
case "0-todo":
|
||||
validLinks++;
|
||||
todo(!found, idstring + " should not show up in page style menu");
|
||||
ok(!checked, idstring + " is not selected");
|
||||
break;
|
||||
case "1":
|
||||
validLinks++;
|
||||
ok(found, idstring + " shows up in page style menu");
|
||||
ok(!checked, idstring + " is not selected");
|
||||
break;
|
||||
case "2":
|
||||
validLinks++;
|
||||
ok(found, idstring + " shows up in page style menu");
|
||||
ok(checked, idstring + " is selected");
|
||||
break;
|
||||
default:
|
||||
throw "data-state attribute is missing or has invalid value";
|
||||
}
|
||||
});
|
||||
|
||||
is(validLinks, items.length, "all valid links found");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
31
browser/base/content/test/page_style_sample.html
Normal file
31
browser/base/content/test/page_style_sample.html
Normal file
@ -0,0 +1,31 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for page style menu</title>
|
||||
<!-- data-state values:
|
||||
0: should not appear in the page style menu
|
||||
0-todo: should not appear in the page style menu, but does
|
||||
1: should appear in the page style menu
|
||||
2: should appear in the page style menu as the selected stylesheet -->
|
||||
<link data-state="1" href="404.css" title="1" rel="alternate stylesheet">
|
||||
<link data-state="0" title="2" rel="alternate stylesheet">
|
||||
<link data-state="0" href="404.css" rel="alternate stylesheet">
|
||||
<link data-state="0" href="404.css" title="" rel="alternate stylesheet">
|
||||
<link data-state="1" href="404.css" title="3" rel="stylesheet alternate">
|
||||
<link data-state="1" href="404.css" title="4" rel=" alternate stylesheet ">
|
||||
<link data-state="1" href="404.css" title="5" rel="alternate stylesheet">
|
||||
<link data-state="2" href="404.css" title="6" rel="stylesheet">
|
||||
<link data-state="1" href="404.css" title="7" rel="foo stylesheet">
|
||||
<link data-state="0" href="404.css" title="8" rel="alternate">
|
||||
<link data-state="1" href="404.css" title="9" rel="alternate STYLEsheet">
|
||||
<link data-state="1" href="404.css" title="10" rel="alternate stylesheet" media="">
|
||||
<link data-state="1" href="404.css" title="11" rel="alternate stylesheet" media="all">
|
||||
<link data-state="1" href="404.css" title="12" rel="alternate stylesheet" media="ALL ">
|
||||
<link data-state="1" href="404.css" title="13" rel="alternate stylesheet" media="screen">
|
||||
<link data-state="1" href="404.css" title="14" rel="alternate stylesheet" media=" Screen">
|
||||
<link data-state="1" href="404.css" title="15" rel="alternate stylesheet" media="screen foo">
|
||||
<link data-state="1" href="404.css" title="16" rel="alternate stylesheet" media="all screen">
|
||||
<link data-state="0-todo" href="404.css" title="17" rel="alternate stylesheet" media="allscreen">
|
||||
<link data-state="0-todo" href="404.css" title="18" rel="alternate stylesheet" media="_all">
|
||||
</head>
|
||||
<body></body>
|
||||
</html>
|
@ -15,6 +15,7 @@ browser.jar:
|
||||
content/browser/aboutDialog.css (content/aboutDialog.css)
|
||||
* content/browser/aboutRobots.xhtml (content/aboutRobots.xhtml)
|
||||
content/browser/aboutRobots-icon.png (content/aboutRobots-icon.png)
|
||||
content/browser/aboutRobots-icon-rtl.png (content/aboutRobots-icon-rtl.png)
|
||||
content/browser/aboutRobots-widget-left.png (content/aboutRobots-widget-left.png)
|
||||
content/browser/aboutRobots-widget-right.png (content/aboutRobots-widget-right.png)
|
||||
* content/browser/browser.css (content/browser.css)
|
||||
|
@ -63,8 +63,7 @@
|
||||
|
||||
<hbox align="center">
|
||||
<label value="&search.label;" accesskey="&search.accesskey;" control="search-box"/>
|
||||
<textbox id="search-box" flex="1"
|
||||
type="timed" timeout="500"
|
||||
<textbox id="search-box" flex="1" type="search"
|
||||
oncommand="searchBookmarks(this.value);"/>
|
||||
</hbox>
|
||||
|
||||
|
@ -86,7 +86,7 @@
|
||||
<hbox align="center">
|
||||
<label value="&find.label;" accesskey="&find.accesskey;"
|
||||
control="search-box"/>
|
||||
<textbox id="search-box" flex="1" type="timed" timeout="500"
|
||||
<textbox id="search-box" flex="1" type="search"
|
||||
oncommand="searchHistory(this.value);"/>
|
||||
<button id="viewButton" style="min-width:0px !important;" type="menu"
|
||||
label="&view.label;" accesskey="&view.accesskey;" selectedsort="day"
|
||||
|
@ -902,12 +902,12 @@
|
||||
<getter><![CDATA[
|
||||
// By default, the insertion point is at the top level, at the end.
|
||||
var index = PlacesUtils.bookmarks.DEFAULT_INDEX;
|
||||
var folderId = 0;
|
||||
var container = null;
|
||||
var orientation = Ci.nsITreeView.DROP_BEFORE;
|
||||
var isTag = false;
|
||||
|
||||
if (PlacesUtils.nodeIsFolder(this._resultNode)) {
|
||||
folderId = PlacesUtils.getConcreteItemId(this._resultNode);
|
||||
container = this._resultNode;
|
||||
isTag = PlacesUtils.nodeIsTagQuery(this._resultNode);
|
||||
}
|
||||
|
||||
@ -917,20 +917,37 @@
|
||||
if (!popupNode.node) {
|
||||
// If a static menuitem is selected the insertion point
|
||||
// is inside the folder, at the end.
|
||||
folderId = PlacesUtils.getConcreteItemId(selectedNode);
|
||||
container = selectedNode;
|
||||
orientation = Ci.nsITreeView.DROP_ON;
|
||||
}
|
||||
else {
|
||||
// In all other cases the insertion point is before that node.
|
||||
folderId = PlacesUtils.getConcreteItemId(selectedNode.parent);
|
||||
container = selectedNode.parent;
|
||||
index = PlacesUtils.getIndexOfNode(selectedNode);
|
||||
isTag = PlacesUtils.nodeIsTagQuery(selectedNode.parent);
|
||||
}
|
||||
}
|
||||
return new InsertionPoint(folderId, index, orientation, isTag);
|
||||
|
||||
if (this._disallowInsertion(container))
|
||||
return null;
|
||||
|
||||
return new InsertionPoint(PlacesUtils.getConcreteItemId(container),
|
||||
index, orientation, isTag);
|
||||
]]></getter>
|
||||
</property>
|
||||
|
||||
<method name="_disallowInsertion">
|
||||
<parameter name="aContainer"/>
|
||||
<body><![CDATA[
|
||||
// allow dropping into Tag containers
|
||||
if (PlacesUtils.nodeIsTagQuery(aContainer))
|
||||
return false;
|
||||
// Disallow insertion of items under readonly folders
|
||||
return (!PlacesUtils.nodeIsFolder(aContainer) ||
|
||||
PlacesUtils.nodeIsReadOnly(aContainer));
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<!-- nsIPlacesView -->
|
||||
<method name="selectAll">
|
||||
<body/>
|
||||
|
@ -385,7 +385,7 @@
|
||||
<getter><![CDATA[
|
||||
// By default, the insertion point is at the top level, at the end.
|
||||
var index = PlacesUtils.bookmarks.DEFAULT_INDEX;
|
||||
var folderId = PlacesUtils.getConcreteItemId(this._result.root);
|
||||
var container = this._result.root;
|
||||
var orientation = Ci.nsITreeView.DROP_BEFORE;
|
||||
var isTag = false;
|
||||
|
||||
@ -395,20 +395,37 @@
|
||||
if (!popupNode.node) {
|
||||
// If a static menuitem is selected the insertion point
|
||||
// is inside the folder, at the end.
|
||||
folderId = PlacesUtils.getConcreteItemId(selectedNode);
|
||||
container = selectedNode;
|
||||
orientation = Ci.nsITreeView.DROP_ON;
|
||||
}
|
||||
else {
|
||||
// In all other cases the insertion point is before that node.
|
||||
folderId = PlacesUtils.getConcreteItemId(selectedNode.parent);
|
||||
container = selectedNode.parent;
|
||||
index = PlacesUtils.getIndexOfNode(selectedNode);
|
||||
isTag = PlacesUtils.nodeIsTagQuery(selectedNode.parent);
|
||||
}
|
||||
}
|
||||
return new InsertionPoint(folderId, index, orientation, isTag);
|
||||
|
||||
if (this._disallowInsertion(container))
|
||||
return null;
|
||||
|
||||
return new InsertionPoint(PlacesUtils.getConcreteItemId(container),
|
||||
index, orientation, isTag);
|
||||
]]></getter>
|
||||
</property>
|
||||
|
||||
<method name="_disallowInsertion">
|
||||
<parameter name="aContainer"/>
|
||||
<body><![CDATA[
|
||||
// allow dropping into Tag containers
|
||||
if (PlacesUtils.nodeIsTagQuery(aContainer))
|
||||
return false;
|
||||
// Disallow insertion of items under readonly folders
|
||||
return (!PlacesUtils.nodeIsFolder(aContainer) ||
|
||||
PlacesUtils.nodeIsReadOnly(aContainer));
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<!-- nsIPlacesView -->
|
||||
<method name="selectAll">
|
||||
<body><![CDATA[
|
||||
|
@ -1602,36 +1602,7 @@ var gApplicationsPane = {
|
||||
* Filter the list when the user enters a filter term into the filter field.
|
||||
*/
|
||||
filter: function() {
|
||||
if (this._filter.value == "") {
|
||||
this.clearFilter();
|
||||
return;
|
||||
}
|
||||
|
||||
this._rebuildView();
|
||||
|
||||
document.getElementById("clearFilter").disabled = false;
|
||||
},
|
||||
|
||||
_filterTimeout: null,
|
||||
|
||||
onFilterInput: function() {
|
||||
if (this._filterTimeout)
|
||||
clearTimeout(this._filterTimeout);
|
||||
|
||||
this._filterTimeout = setTimeout("gApplicationsPane.filter()", 500);
|
||||
},
|
||||
|
||||
onFilterKeyPress: function(aEvent) {
|
||||
if (aEvent.keyCode == KeyEvent.DOM_VK_ESCAPE)
|
||||
this.clearFilter();
|
||||
},
|
||||
|
||||
clearFilter: function() {
|
||||
this._filter.value = "";
|
||||
this._rebuildView();
|
||||
|
||||
this._filter.focus();
|
||||
document.getElementById("clearFilter").disabled = true;
|
||||
},
|
||||
|
||||
focusFilterBox: function() {
|
||||
|
@ -110,12 +110,11 @@
|
||||
<key key="&focusSearch2.key;" modifiers="accel" oncommand="gApplicationsPane.focusFilterBox();"/>
|
||||
</keyset>
|
||||
|
||||
<hbox align="center">
|
||||
<label accesskey="&filter.accesskey;" control="filter">&filter.label;</label>
|
||||
<textbox id="filter" flex="1" oninput="gApplicationsPane.onFilterInput();"
|
||||
onkeypress="gApplicationsPane.onFilterKeyPress(event);"/>
|
||||
<button id="clearFilter" icon="clear" label="&clear.label;" accesskey="&clear.accesskey;"
|
||||
oncommand="gApplicationsPane.clearFilter();" disabled="true"/>
|
||||
<hbox>
|
||||
<textbox id="filter" flex="1"
|
||||
type="search"
|
||||
emptytext="&filter.emptytext;"
|
||||
oncommand="gApplicationsPane.filter();"/>
|
||||
</hbox>
|
||||
|
||||
<separator class="thin"/>
|
||||
|
@ -228,10 +228,7 @@ SessionStoreService.prototype = {
|
||||
this._initialState.session && this._initialState.session.state &&
|
||||
this._initialState.session.state == STATE_RUNNING_STR;
|
||||
|
||||
// restore the features of the first window from localstore.rdf
|
||||
WINDOW_ATTRIBUTES.forEach(function(aAttr) {
|
||||
delete this._initialState.windows[0][aAttr];
|
||||
}, this);
|
||||
// make sure that at least the first window doesn't have anything hidden
|
||||
delete this._initialState.windows[0].hidden;
|
||||
}
|
||||
catch (ex) { debug("The session file is invalid: " + ex); }
|
||||
|
@ -222,7 +222,7 @@ static SETTING gSettings[] = {
|
||||
};
|
||||
|
||||
PRBool
|
||||
nsWindowsShellService::IsDefaultBrowserVista(PRBool aStartupCheck, PRBool* aIsDefaultBrowser)
|
||||
nsWindowsShellService::IsDefaultBrowserVista(PRBool* aIsDefaultBrowser)
|
||||
{
|
||||
#if !defined(MOZ_DISABLE_VISTA_SDK_REQUIREMENTS)
|
||||
IApplicationAssociationRegistration* pAAR;
|
||||
@ -238,12 +238,6 @@ nsWindowsShellService::IsDefaultBrowserVista(PRBool aStartupCheck, PRBool* aIsDe
|
||||
APP_REG_NAME,
|
||||
aIsDefaultBrowser);
|
||||
|
||||
// If this is the first browser window, maintain internal state that we've
|
||||
// checked this session (so that subsequent window opens don't show the
|
||||
// default browser dialog).
|
||||
if (aStartupCheck)
|
||||
mCheckedThisSession = PR_TRUE;
|
||||
|
||||
pAAR->Release();
|
||||
return PR_TRUE;
|
||||
}
|
||||
@ -316,26 +310,29 @@ nsWindowsShellService::IsDefaultBrowser(PRBool aStartupCheck,
|
||||
::ZeroMemory(currValue, sizeof(currValue));
|
||||
HKEY theKey;
|
||||
rv = OpenKeyForReading(HKEY_CLASSES_ROOT, key, &theKey);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
DWORD len = sizeof currValue;
|
||||
DWORD res = ::RegQueryValueExW(theKey, PromiseFlatString(value).get(),
|
||||
NULL, NULL, (LPBYTE)currValue, &len);
|
||||
// Close the key we opened.
|
||||
::RegCloseKey(theKey);
|
||||
if (REG_FAILED(res) ||
|
||||
!dataLongPath.Equals(currValue, CaseInsensitiveCompare) &&
|
||||
!dataShortPath.Equals(currValue, CaseInsensitiveCompare)) {
|
||||
// Key wasn't set, or was set to something else (something else became the default browser)
|
||||
*aIsDefaultBrowser = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
if (NS_FAILED(rv)) {
|
||||
*aIsDefaultBrowser = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
DWORD len = sizeof currValue;
|
||||
DWORD res = ::RegQueryValueExW(theKey, PromiseFlatString(value).get(),
|
||||
NULL, NULL, (LPBYTE)currValue, &len);
|
||||
// Close the key we opened.
|
||||
::RegCloseKey(theKey);
|
||||
if (REG_FAILED(res) ||
|
||||
!dataLongPath.Equals(currValue, CaseInsensitiveCompare) &&
|
||||
!dataShortPath.Equals(currValue, CaseInsensitiveCompare)) {
|
||||
// Key wasn't set, or was set to something other than our registry entry
|
||||
*aIsDefaultBrowser = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
// Only check if Firefox is the default browser on Vista if the previous
|
||||
// checks show that Firefox is the default browser.
|
||||
if (aIsDefaultBrowser)
|
||||
IsDefaultBrowserVista(aStartupCheck, aIsDefaultBrowser);
|
||||
if (*aIsDefaultBrowser)
|
||||
IsDefaultBrowserVista(aIsDefaultBrowser);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
@ -358,8 +355,8 @@ nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUs
|
||||
rv = appHelper->AppendNative(NS_LITERAL_CSTRING("helper.exe"));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCAutoString appHelperPath;
|
||||
rv = appHelper->GetNativePath(appHelperPath);
|
||||
nsAutoString appHelperPath;
|
||||
rv = appHelper->GetPath(appHelperPath);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (aForAllUsers) {
|
||||
@ -368,11 +365,11 @@ nsWindowsShellService::SetDefaultBrowser(PRBool aClaimAllTypes, PRBool aForAllUs
|
||||
appHelperPath.AppendLiteral(" /SetAsDefaultAppUser");
|
||||
}
|
||||
|
||||
STARTUPINFO si = {sizeof(si), 0};
|
||||
STARTUPINFOW si = {sizeof(si), 0};
|
||||
PROCESS_INFORMATION pi = {0};
|
||||
|
||||
BOOL ok = CreateProcess(NULL, (LPSTR)appHelperPath.get(), NULL, NULL,
|
||||
FALSE, 0, NULL, NULL, &si, &pi);
|
||||
BOOL ok = CreateProcessW(NULL, (LPWSTR)appHelperPath.get(), NULL, NULL,
|
||||
FALSE, 0, NULL, NULL, &si, &pi);
|
||||
|
||||
if (!ok)
|
||||
return NS_ERROR_FAILURE;
|
||||
@ -766,8 +763,8 @@ nsWindowsShellService::GetUnreadMailCount(PRUint32* aCount)
|
||||
if (REG_SUCCEEDED(res))
|
||||
*aCount = unreadCount;
|
||||
|
||||
// Close the key we opened.
|
||||
::RegCloseKey(accountKey);
|
||||
// Close the key we opened.
|
||||
::RegCloseKey(accountKey);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -57,16 +57,9 @@ public:
|
||||
NS_DECL_NSIWINDOWSSHELLSERVICE
|
||||
|
||||
protected:
|
||||
PRBool IsDefaultBrowserVista(PRBool aStartupCheck, PRBool* aIsDefaultBrowser);
|
||||
PRBool IsDefaultBrowserVista(PRBool* aIsDefaultBrowser);
|
||||
|
||||
PRBool GetMailAccountKey(HKEY* aResult);
|
||||
void SetRegKey(const nsString& aKeyName,
|
||||
const nsString& aValueName,
|
||||
const nsString& aValue, PRBool aHKLMOnly);
|
||||
|
||||
DWORD DeleteRegKey(HKEY baseKey, const nsString& keyName);
|
||||
DWORD DeleteRegKeyDefaultValue(HKEY baseKey,
|
||||
const nsString& keyName);
|
||||
|
||||
private:
|
||||
PRBool mCheckedThisSession;
|
||||
|
@ -1,7 +1,6 @@
|
||||
af
|
||||
ar
|
||||
be
|
||||
bg
|
||||
ca
|
||||
cs
|
||||
da
|
||||
@ -18,7 +17,6 @@ ga-IE
|
||||
gu-IN
|
||||
he
|
||||
hu
|
||||
hy-AM
|
||||
id
|
||||
it
|
||||
ja
|
||||
@ -38,9 +36,7 @@ pt-BR
|
||||
pt-PT
|
||||
ro
|
||||
ru
|
||||
si
|
||||
sk
|
||||
sl
|
||||
sq
|
||||
sr
|
||||
sv-SE
|
||||
|
@ -7,8 +7,4 @@
|
||||
<!ENTITY focusSearch1.key "f">
|
||||
<!ENTITY focusSearch2.key "k">
|
||||
|
||||
<!ENTITY filter.label "Search:">
|
||||
<!ENTITY filter.accesskey "S">
|
||||
|
||||
<!ENTITY clear.label "Clear">
|
||||
<!ENTITY clear.accesskey "l">
|
||||
<!ENTITY filter.emptytext "Search">
|
||||
|
@ -84,8 +84,11 @@ MOZ_CHROME_FILE_FORMAT = @MOZ_CHROME_FILE_FORMAT@
|
||||
|
||||
MOZ_WIDGET_TOOLKIT = @MOZ_WIDGET_TOOLKIT@
|
||||
MOZ_GFX_TOOLKIT = @MOZ_GFX_TOOLKIT@
|
||||
MOZ_DFB = @MOZ_DFB@
|
||||
MOZ_X11 = @MOZ_X11@
|
||||
|
||||
MOZ_PANGO = @MOZ_PANGO@
|
||||
|
||||
MOZ_JS_LIBS = @MOZ_JS_LIBS@
|
||||
|
||||
MOZ_DEBUG = @MOZ_DEBUG@
|
||||
|
@ -80,7 +80,6 @@ cairo-atsui.h
|
||||
cairo-beos.h
|
||||
cairo-ft.h
|
||||
cairo-glitz.h
|
||||
cairo-nquartz.h
|
||||
cairo-os2.h
|
||||
cairo-pdf.h
|
||||
cairo-ps.h
|
||||
@ -88,6 +87,8 @@ cairo-quartz.h
|
||||
cairo-win32.h
|
||||
cairo-xlib.h
|
||||
cairo-xlib-xrender.h
|
||||
cairo-directfb.h
|
||||
cairo-qpainter.h
|
||||
#endif
|
||||
callconv.h
|
||||
Carbon/Carbon.h
|
||||
|
@ -50,7 +50,7 @@ sub daysFromBuildID
|
||||
{
|
||||
my ($buildid,) = @_;
|
||||
|
||||
my ($y, $m, $d, $h) = ($buildid =~ /^(\d{4})(\d{2})(\d{2})(\d{2})$/);
|
||||
my ($y, $m, $d, $h) = ($buildid =~ /^(\d{4})(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})$/);
|
||||
$d || die("Unrecognized buildid string.");
|
||||
|
||||
my $secondstodays = 60 * 60 * 24;
|
||||
|
102
configure.in
102
configure.in
@ -965,7 +965,7 @@ MOZ_PNG_LIBS='$(call EXPAND_LIBNAME_PATH,mozpng,$(DEPTH)/modules/libimg/png)'
|
||||
|
||||
MOZ_JS_LIBS='-L$(LIBXUL_DIST)/bin -lmozjs'
|
||||
DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/bin -lxpcom -lxpcom_core'
|
||||
MOZ_FIX_LINK_PATHS='-Wl,-rpath-link,$(LIBXUL_DIST)/bin'
|
||||
MOZ_FIX_LINK_PATHS='-Wl,-rpath-link,$(LIBXUL_DIST)/bin -Wl,-rpath-link,$(PREFIX)/lib'
|
||||
XPCOM_FROZEN_LDOPTS='-L$(LIBXUL_DIST)/bin -lxpcom'
|
||||
LIBXUL_LIBS='$(XPCOM_FROZEN_LDOPTS) -lxul'
|
||||
XPCOM_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) $(XPCOM_FROZEN_LDOPTS)'
|
||||
@ -4708,6 +4708,7 @@ MOZ_ARG_HEADER(Toolkit Options)
|
||||
OS/2 - cairo-os2
|
||||
Win32 - cairo-windows
|
||||
WinCE - windows
|
||||
Gtk2 with DirectFB - cairo-gtk2-dfb
|
||||
* - cairo-gtk2
|
||||
* - cairo-qt],
|
||||
[ _DEFAULT_TOOLKIT=$enableval ],
|
||||
@ -4716,6 +4717,8 @@ MOZ_ARG_HEADER(Toolkit Options)
|
||||
if test "$_DEFAULT_TOOLKIT" = "photon" \
|
||||
-o "$_DEFAULT_TOOLKIT" = "cairo-windows" \
|
||||
-o "$_DEFAULT_TOOLKIT" = "cairo-gtk2" \
|
||||
-o "$_DEFAULT_TOOLKIT" = "cairo-gtk2-dfb" \
|
||||
-o "$_DEFAULT_TOOLKIT" = "cairo-gtk2-x11" \
|
||||
-o "$_DEFAULT_TOOLKIT" = "cairo-qt" \
|
||||
-o "$_DEFAULT_TOOLKIT" = "cairo-beos" \
|
||||
-o "$_DEFAULT_TOOLKIT" = "cairo-os2" \
|
||||
@ -4726,11 +4729,7 @@ MOZ_ARG_HEADER(Toolkit Options)
|
||||
dnl so ignore everything after the first comma (",").
|
||||
MOZ_WIDGET_TOOLKIT=`echo "$_DEFAULT_TOOLKIT" | sed -e "s/,.*$//"`
|
||||
else
|
||||
if test "$no_x" != "yes"; then
|
||||
AC_MSG_ERROR([Toolkit must be cairo-gtk2 or cairo-qt.])
|
||||
else
|
||||
AC_MSG_ERROR([Toolkit must be $_PLATFORM_DEFAULT_TOOLKIT (if supported).])
|
||||
fi
|
||||
AC_MSG_ERROR([You must specify a default toolkit (perhaps $_PLATFORM_DEFAULT_TOOLKIT).])
|
||||
fi
|
||||
|
||||
AC_DEFINE_UNQUOTED(MOZ_DEFAULT_TOOLKIT,"$MOZ_WIDGET_TOOLKIT")
|
||||
@ -4750,24 +4749,51 @@ cairo-windows)
|
||||
MOZ_GFX_TOOLKIT=cairo
|
||||
;;
|
||||
|
||||
cairo-gtk2)
|
||||
cairo-gtk2|cairo-gtk2-x11)
|
||||
MOZ_WIDGET_TOOLKIT=gtk2
|
||||
MOZ_GFX_TOOLKIT=cairo
|
||||
MOZ_ENABLE_GTK2=1
|
||||
MOZ_ENABLE_XREMOTE=1
|
||||
|
||||
AC_DEFINE(MOZ_X11)
|
||||
MOZ_X11=1
|
||||
|
||||
TK_CFLAGS='$(MOZ_GTK2_CFLAGS)'
|
||||
TK_LIBS='$(MOZ_GTK2_LIBS)'
|
||||
AC_DEFINE(MOZ_WIDGET_GTK2)
|
||||
;;
|
||||
|
||||
cairo-gtk2-dfb)
|
||||
MOZ_WIDGET_TOOLKIT=gtk2
|
||||
MOZ_GFX_TOOLKIT=cairo
|
||||
MOZ_ENABLE_GTK2=1
|
||||
|
||||
AC_DEFINE(MOZ_DFB)
|
||||
MOZ_DFB=1
|
||||
|
||||
TK_CFLAGS='$(MOZ_GTK2_CFLAGS)'
|
||||
TK_LIBS='$(MOZ_GTK2_LIBS)'
|
||||
AC_DEFINE(MOZ_WIDGET_GTK2)
|
||||
if test "$no_x" != "yes"; then
|
||||
AC_MSG_WARN([Disabling X when DirectFB is specified.])
|
||||
no_x=yes
|
||||
fi
|
||||
;;
|
||||
|
||||
cairo-qt)
|
||||
MOZ_WIDGET_TOOLKIT=qt
|
||||
MOZ_GFX_TOOLKIT=cairo
|
||||
MOZ_ENABLE_QT=1
|
||||
MOZ_ENABLE_XREMOTE=1
|
||||
|
||||
AC_DEFINE(MOZ_X11)
|
||||
MOZ_X11=1
|
||||
|
||||
TK_CFLAGS='$(MOZ_QT_CFLAGS)'
|
||||
TK_LIBS='$(MOZ_QT_LIBS)'
|
||||
AC_DEFINE(MOZ_WIDGET_QT)
|
||||
;;
|
||||
|
||||
cairo-beos)
|
||||
MOZ_WIDGET_TOOLKIT=beos
|
||||
MOZ_GFX_TOOLKIT=cairo
|
||||
@ -4807,10 +4833,17 @@ if test "$MOZ_ENABLE_XREMOTE"; then
|
||||
fi
|
||||
|
||||
if test "$COMPILE_ENVIRONMENT"; then
|
||||
if test "$MOZ_ENABLE_GTK2"
|
||||
then
|
||||
PKG_CHECK_MODULES(MOZ_GTK2, gtk+-2.0 >= $GTK2_VERSION gtk+-unix-print-2.0 gdk-x11-2.0 glib-2.0 gobject-2.0)
|
||||
fi
|
||||
if test "$MOZ_ENABLE_GTK2"; then
|
||||
if test "$MOZ_X11"; then
|
||||
GDK_PACKAGES=gdk-x11-2.0
|
||||
elif test "$MOZ_DFB"; then
|
||||
PKG_CHECK_MODULES(MOZ_DFB, directfb >= 1.1.0)
|
||||
GDK_PACKAGES=directfb
|
||||
fi
|
||||
|
||||
PKG_CHECK_MODULES(MOZ_GTK2, gtk+-2.0 >= $GTK2_VERSION gtk+-unix-print-2.0 glib-2.0 gobject-2.0 $GDK_PACKAGES)
|
||||
fi
|
||||
|
||||
fi # COMPILE_ENVIRONMENT
|
||||
|
||||
AC_SUBST(MOZ_DEFAULT_TOOLKIT)
|
||||
@ -4906,12 +4939,7 @@ AC_SUBST(MOZ_QT_LIBS)
|
||||
|
||||
AC_SUBST(MOC)
|
||||
|
||||
if test "$MOZ_ENABLE_GTK2" \
|
||||
|| test "$MOZ_ENABLE_QT"
|
||||
then
|
||||
AC_DEFINE(MOZ_X11)
|
||||
MOZ_X11=1
|
||||
fi
|
||||
AC_SUBST(MOZ_DFB)
|
||||
AC_SUBST(MOZ_X11)
|
||||
|
||||
dnl ========================================================
|
||||
@ -5026,19 +5054,47 @@ fi
|
||||
AC_DEFINE_UNQUOTED(MOZ_DISTRIBUTION_ID,"$MOZ_DISTRIBUTION_ID")
|
||||
AC_SUBST(MOZ_DISTRIBUTION_ID)
|
||||
|
||||
|
||||
dnl ========================================================
|
||||
dnl complex text support off by default
|
||||
dnl ========================================================
|
||||
MOZ_PANGO=1
|
||||
MOZ_ARG_DISABLE_BOOL(pango,
|
||||
[ --disable-pango Disable usage of Pango ],
|
||||
MOZ_PANGO=,
|
||||
MOZ_PANGO=1)
|
||||
|
||||
|
||||
dnl ========================================================
|
||||
dnl = Xft and Pango
|
||||
dnl ========================================================
|
||||
if test "$MOZ_ENABLE_GTK2"
|
||||
then
|
||||
PKG_CHECK_MODULES(MOZ_XFT, xft)
|
||||
AC_SUBST(MOZ_XFT_CFLAGS)
|
||||
AC_SUBST(MOZ_XFT_LIBS)
|
||||
if test "$MOZ_X11"; then
|
||||
PKG_CHECK_MODULES(MOZ_XFT, xft)
|
||||
AC_SUBST(MOZ_XFT_CFLAGS)
|
||||
AC_SUBST(MOZ_XFT_LIBS)
|
||||
fi
|
||||
|
||||
AC_SUBST(MOZ_PANGO)
|
||||
|
||||
PKG_CHECK_MODULES(_PANGOCHK, pango >= $PANGO_VERSION)
|
||||
PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangocairo >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION)
|
||||
AC_SUBST(MOZ_PANGO_CFLAGS)
|
||||
AC_SUBST(MOZ_PANGO_LIBS)
|
||||
|
||||
if test "$MOZ_PANGO"
|
||||
then
|
||||
PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangocairo >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION)
|
||||
AC_SUBST(MOZ_PANGO_CFLAGS)
|
||||
AC_SUBST(MOZ_PANGO_LIBS)
|
||||
AC_DEFINE(MOZ_PANGO)
|
||||
else
|
||||
PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION)
|
||||
AC_SUBST(MOZ_PANGO_CFLAGS)
|
||||
AC_SUBST(MOZ_PANGO_LIBS)
|
||||
|
||||
PKG_CHECK_MODULES(FT2, freetype2 > 6.1.0 fontconfig)
|
||||
AC_SUBST(FT2_CFLAGS)
|
||||
AC_SUBST(FT2_LIBS)
|
||||
fi
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
|
@ -223,9 +223,7 @@ public:
|
||||
virtual void SetBaseTarget(const nsAString &aBaseTarget) = 0;
|
||||
|
||||
/**
|
||||
* Return a standard name for the document's character set. This
|
||||
* will trigger a startDocumentLoad if necessary to answer the
|
||||
* question.
|
||||
* Return a standard name for the document's character set.
|
||||
*/
|
||||
const nsCString& GetDocumentCharacterSet() const
|
||||
{
|
||||
|
@ -76,8 +76,23 @@ interface nsIFrameLoader : nsISupports
|
||||
readonly attribute boolean depthTooGreat;
|
||||
};
|
||||
|
||||
[scriptable, uuid(feaf9285-05ac-4898-a69f-c3bd350767e4)]
|
||||
[scriptable, uuid(641c2d90-4ada-4367-bdb1-80831614161d)]
|
||||
interface nsIFrameLoaderOwner : nsISupports
|
||||
{
|
||||
/**
|
||||
* The frame loader owned by this nsIFrameLoaderOwner
|
||||
*/
|
||||
readonly attribute nsIFrameLoader frameLoader;
|
||||
|
||||
/**
|
||||
* Swap frame loaders with the given nsIFrameLoaderOwner. This may
|
||||
* only be posible in a very limited range of circumstances, or
|
||||
* never, depending on the object implementing this interface.
|
||||
*
|
||||
* @throws NS_ERROR_NOT_IMPLEMENTED if the swapping logic is not
|
||||
* implemented for the two given frame loader owners.
|
||||
* @throws NS_ERROR_DOM_SECURITY_ERR if the swap is not allowed on
|
||||
* security grounds.
|
||||
*/
|
||||
void swapFrameLoaders(in nsIFrameLoaderOwner aOtherOwner);
|
||||
};
|
||||
|
@ -82,6 +82,11 @@ public:
|
||||
|
||||
virtual void GetScriptCharset(nsAString& charset) = 0;
|
||||
|
||||
/**
|
||||
* Is the script deferred. Currently only supported by HTML scripts.
|
||||
*/
|
||||
virtual PRBool GetScriptDeferred() = 0;
|
||||
|
||||
void SetScriptLineNumber(PRUint32 aLineNumber)
|
||||
{
|
||||
mLineNumber = aLineNumber;
|
||||
|
@ -58,6 +58,11 @@ public:
|
||||
}
|
||||
return shell;
|
||||
}
|
||||
|
||||
PRBool HasMoreThanOneShell() {
|
||||
return mDoc->mPresShells.Length() > 1;
|
||||
}
|
||||
|
||||
private:
|
||||
static void* operator new(size_t) CPP_THROW_NEW { return 0; }
|
||||
static void operator delete(void*, size_t) {}
|
||||
|
@ -1711,6 +1711,8 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
||||
|
||||
mMayStartLayout = PR_FALSE;
|
||||
|
||||
mHaveInputEncoding = PR_TRUE;
|
||||
|
||||
if (aReset) {
|
||||
Reset(aChannel, aLoadGroup);
|
||||
}
|
||||
@ -3174,6 +3176,10 @@ nsDocument::BeginLoad()
|
||||
// unblocking it while we know the document is loading.
|
||||
BlockOnload();
|
||||
|
||||
if (mScriptLoader) {
|
||||
mScriptLoader->BeginDeferringScripts();
|
||||
}
|
||||
|
||||
NS_DOCUMENT_NOTIFY_OBSERVERS(BeginLoad, (this));
|
||||
}
|
||||
|
||||
@ -3417,6 +3423,10 @@ nsDocument::DispatchContentLoadedEvents()
|
||||
} while (parent);
|
||||
}
|
||||
|
||||
if (mScriptLoader) {
|
||||
mScriptLoader->EndDeferringScripts();
|
||||
}
|
||||
|
||||
UnblockOnload(PR_TRUE);
|
||||
}
|
||||
|
||||
@ -4959,7 +4969,12 @@ nsDocument::LookupNamespaceURI(const nsAString& aNamespacePrefix,
|
||||
NS_IMETHODIMP
|
||||
nsDocument::GetInputEncoding(nsAString& aInputEncoding)
|
||||
{
|
||||
return GetCharacterSet(aInputEncoding);
|
||||
if (mHaveInputEncoding) {
|
||||
return GetCharacterSet(aInputEncoding);
|
||||
}
|
||||
|
||||
SetDOMStringToNull(aInputEncoding);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -947,6 +947,10 @@ protected:
|
||||
|
||||
PRPackedBool mSynchronousDOMContentLoaded:1;
|
||||
|
||||
// If true, we have an input encoding. If this is false, then the
|
||||
// document was created entirely in memory
|
||||
PRPackedBool mHaveInputEncoding:1;
|
||||
|
||||
PRUint8 mXMLDeclarationBits;
|
||||
|
||||
PRUint8 mDefaultElementType;
|
||||
|
@ -354,7 +354,7 @@ nsDocumentEncoder::SerializeToStringRecursive(nsIDOMNode* aNode,
|
||||
PRBool aDontSerializeRoot)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
PRBool serializeClonedChildren;
|
||||
PRBool serializeClonedChildren = PR_FALSE;
|
||||
nsCOMPtr<nsIDOMNode> maybeFixedNode;
|
||||
|
||||
if (mNodeFixup)
|
||||
|
@ -22,6 +22,7 @@
|
||||
*
|
||||
* Contributor(s):
|
||||
* Johnny Stenback <jst@netscape.com> (original author)
|
||||
* Boris Zbarsky <bzbarsky@mit.edu>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either of the GNU General Public License Version 2 or later (the "GPL"),
|
||||
@ -65,6 +66,12 @@
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsFrameLoader.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIFrameFrame.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsPresShellIterator.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
|
||||
#include "nsIURI.h"
|
||||
#include "nsIURL.h"
|
||||
@ -281,6 +288,367 @@ nsFrameLoader::Finalize()
|
||||
mDocShell = nsnull;
|
||||
}
|
||||
|
||||
static void
|
||||
FirePageHideEvent(nsIDocShellTreeItem* aItem,
|
||||
nsIDOMEventTarget* aChromeEventHandler)
|
||||
{
|
||||
nsPageTransitionEvent event(PR_TRUE, NS_PAGE_HIDE, PR_TRUE);
|
||||
nsCOMPtr<nsIDOMDocument> doc = do_GetInterface(aItem);
|
||||
event.target = do_QueryInterface(doc);
|
||||
nsEventDispatcher::Dispatch(aChromeEventHandler, nsnull, &event);
|
||||
|
||||
PRInt32 childCount = 0;
|
||||
aItem->GetChildCount(&childCount);
|
||||
nsAutoTArray<nsCOMPtr<nsIDocShellTreeItem>, 8> kids;
|
||||
kids.AppendElements(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; ++i) {
|
||||
aItem->GetChildAt(i, getter_AddRefs(kids[i]));
|
||||
}
|
||||
|
||||
for (PRUint32 i = 0; i < kids.Length(); ++i) {
|
||||
if (kids[i]) {
|
||||
FirePageHideEvent(kids[i], aChromeEventHandler);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
FirePageShowEvent(nsIDocShellTreeItem* aItem,
|
||||
nsIDOMEventTarget* aChromeEventHandler)
|
||||
{
|
||||
PRInt32 childCount = 0;
|
||||
aItem->GetChildCount(&childCount);
|
||||
nsAutoTArray<nsCOMPtr<nsIDocShellTreeItem>, 8> kids;
|
||||
kids.AppendElements(childCount);
|
||||
for (PRInt32 i = 0; i < childCount; ++i) {
|
||||
aItem->GetChildAt(i, getter_AddRefs(kids[i]));
|
||||
}
|
||||
|
||||
for (PRUint32 i = 0; i < kids.Length(); ++i) {
|
||||
if (kids[i]) {
|
||||
FirePageShowEvent(kids[i], aChromeEventHandler);
|
||||
}
|
||||
}
|
||||
|
||||
nsPageTransitionEvent event(PR_TRUE, NS_PAGE_SHOW, PR_TRUE);
|
||||
nsCOMPtr<nsIDOMDocument> doc = do_GetInterface(aItem);
|
||||
event.target = do_QueryInterface(doc);
|
||||
nsEventDispatcher::Dispatch(aChromeEventHandler, nsnull, &event);
|
||||
}
|
||||
|
||||
static void
|
||||
SetTreeOwnerAndChromeEventHandlerOnDocshellTree(nsIDocShellTreeItem* aItem,
|
||||
nsIDocShellTreeOwner* aOwner,
|
||||
nsIDOMEventTarget* aHandler)
|
||||
{
|
||||
NS_PRECONDITION(aItem, "Must have item");
|
||||
#ifdef DEBUG
|
||||
PRInt32 itemType;
|
||||
aItem->GetItemType(&itemType);
|
||||
NS_ASSERTION(itemType == nsIDocShellTreeItem::typeContent,
|
||||
"How did something else get in here?");
|
||||
#endif
|
||||
|
||||
aItem->SetTreeOwner(aOwner);
|
||||
nsCOMPtr<nsIDocShell> shell(do_QueryInterface(aItem));
|
||||
shell->SetChromeEventHandler(aHandler);
|
||||
|
||||
PRInt32 childCount = 0;
|
||||
aItem->GetChildCount(&childCount);
|
||||
for (PRInt32 i = 0; i < childCount; ++i) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> item;
|
||||
aItem->GetChildAt(i, getter_AddRefs(item));
|
||||
SetTreeOwnerAndChromeEventHandlerOnDocshellTree(item, aOwner, aHandler);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the type of the treeitem and hook it up to the treeowner.
|
||||
* @param aItem the treeitem we're wrking working with
|
||||
* @param aOwningContent the content node that owns aItem
|
||||
* @param aTreeOwner the relevant treeowner; might be null
|
||||
* @param aParentType the nsIDocShellTreeItem::GetType of our parent docshell
|
||||
* @param aParentNode if non-null, the docshell we should be added as a child to
|
||||
*
|
||||
* @return whether aItem is top-level content
|
||||
*/
|
||||
static PRBool
|
||||
AddTreeItemToTreeOwner(nsIDocShellTreeItem* aItem, nsIContent* aOwningContent,
|
||||
nsIDocShellTreeOwner* aOwner, PRInt32 aParentType,
|
||||
nsIDocShellTreeNode* aParentNode)
|
||||
{
|
||||
NS_PRECONDITION(aItem, "Must have docshell treeitem");
|
||||
NS_PRECONDITION(aOwningContent, "Must have owning content");
|
||||
|
||||
nsAutoString value;
|
||||
PRBool isContent = PR_FALSE;
|
||||
|
||||
if (aOwningContent->IsNodeOfType(nsINode::eXUL)) {
|
||||
aOwningContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
|
||||
}
|
||||
|
||||
// we accept "content" and "content-xxx" values.
|
||||
// at time of writing, we expect "xxx" to be "primary" or "targetable", but
|
||||
// someday it might be an integer expressing priority or something else.
|
||||
|
||||
isContent = value.LowerCaseEqualsLiteral("content") ||
|
||||
StringBeginsWith(value, NS_LITERAL_STRING("content-"),
|
||||
nsCaseInsensitiveStringComparator());
|
||||
|
||||
if (isContent) {
|
||||
// The web shell's type is content.
|
||||
|
||||
aItem->SetItemType(nsIDocShellTreeItem::typeContent);
|
||||
} else {
|
||||
// Inherit our type from our parent webshell. If it is
|
||||
// chrome, we'll be chrome. If it is content, we'll be
|
||||
// content.
|
||||
|
||||
aItem->SetItemType(aParentType);
|
||||
}
|
||||
|
||||
// Now that we have our type set, add ourselves to the parent, as needed.
|
||||
if (aParentNode) {
|
||||
aParentNode->AddChild(aItem);
|
||||
}
|
||||
|
||||
PRBool retval = PR_FALSE;
|
||||
if (aParentType == nsIDocShellTreeItem::typeChrome && isContent) {
|
||||
retval = PR_TRUE;
|
||||
|
||||
PRBool is_primary = value.LowerCaseEqualsLiteral("content-primary");
|
||||
|
||||
if (aOwner) {
|
||||
PRBool is_targetable = is_primary ||
|
||||
value.LowerCaseEqualsLiteral("content-targetable");
|
||||
aOwner->ContentShellAdded(aItem, is_primary, is_targetable, value);
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
nsRefPtr<nsFrameLoader>& aFirstToSwap,
|
||||
nsRefPtr<nsFrameLoader>& aSecondToSwap)
|
||||
{
|
||||
NS_PRECONDITION((aFirstToSwap == this && aSecondToSwap == aOther) ||
|
||||
(aFirstToSwap == aOther && aSecondToSwap == this),
|
||||
"Swapping some sort of random loaders?");
|
||||
|
||||
nsIContent* ourContent = mOwnerContent;
|
||||
nsIContent* otherContent = aOther->mOwnerContent;
|
||||
|
||||
if (!ourContent || !otherContent) {
|
||||
// Can't handle this
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// Make sure there are no same-origin issues
|
||||
PRBool equal;
|
||||
nsresult rv =
|
||||
ourContent->NodePrincipal()->Equals(otherContent->NodePrincipal(), &equal);
|
||||
if (NS_FAILED(rv) || !equal) {
|
||||
// Security problems loom. Just bail on it all
|
||||
return NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> ourDochell = GetExistingDocShell();
|
||||
nsCOMPtr<nsIDocShell> otherDocshell = aOther->GetExistingDocShell();
|
||||
if (!ourDochell || !otherDocshell) {
|
||||
// How odd
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// To avoid having to mess with session history, avoid swapping
|
||||
// frameloaders that don't correspond to root same-type docshells.
|
||||
nsCOMPtr<nsIDocShellTreeItem> ourTreeItem = do_QueryInterface(ourDochell);
|
||||
nsCOMPtr<nsIDocShellTreeItem> otherTreeItem =
|
||||
do_QueryInterface(otherDocshell);
|
||||
nsCOMPtr<nsIDocShellTreeItem> ourRootTreeItem, otherRootTreeItem;
|
||||
ourTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(ourRootTreeItem));
|
||||
otherTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(otherRootTreeItem));
|
||||
if (ourRootTreeItem != ourTreeItem || otherRootTreeItem != otherTreeItem) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// Also make sure that the two docshells are the same type. Otherwise
|
||||
// swapping is certainly not safe. As far as that goes, make sure we only
|
||||
// swap typeContent docshells, since otherwise it's hard to get treeowners
|
||||
// right.
|
||||
PRInt32 ourType = nsIDocShellTreeItem::typeChrome;
|
||||
PRInt32 otherType = nsIDocShellTreeItem::typeChrome;
|
||||
ourTreeItem->GetItemType(&ourType);
|
||||
otherTreeItem->GetItemType(&otherType);
|
||||
if (ourType != nsIDocShellTreeItem::typeContent ||
|
||||
otherType != nsIDocShellTreeItem::typeContent) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// Save off the tree owners, frame elements, chrome event handlers, and
|
||||
// docshell and document parents before doing anything else.
|
||||
nsCOMPtr<nsIDocShellTreeOwner> ourOwner, otherOwner;
|
||||
ourTreeItem->GetTreeOwner(getter_AddRefs(ourOwner));
|
||||
otherTreeItem->GetTreeOwner(getter_AddRefs(otherOwner));
|
||||
// Note: it's OK to have null treeowners.
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> ourParentItem, otherParentItem;
|
||||
ourTreeItem->GetParent(getter_AddRefs(ourParentItem));
|
||||
otherTreeItem->GetParent(getter_AddRefs(otherParentItem));
|
||||
if (!ourParentItem || !otherParentItem) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsPIDOMWindow> ourWindow = do_GetInterface(ourDochell);
|
||||
nsCOMPtr<nsPIDOMWindow> otherWindow = do_GetInterface(otherDocshell);
|
||||
|
||||
nsCOMPtr<nsIDOMElement> ourFrameElement =
|
||||
ourWindow->GetFrameElementInternal();
|
||||
nsCOMPtr<nsIDOMElement> otherFrameElement =
|
||||
otherWindow->GetFrameElementInternal();
|
||||
|
||||
nsCOMPtr<nsIDOMEventTarget> ourChromeEventHandler =
|
||||
do_QueryInterface(ourWindow->GetChromeEventHandler());
|
||||
nsCOMPtr<nsIDOMEventTarget> otherChromeEventHandler =
|
||||
do_QueryInterface(otherWindow->GetChromeEventHandler());
|
||||
|
||||
NS_ASSERTION(SameCOMIdentity(ourFrameElement, ourContent) &&
|
||||
SameCOMIdentity(otherFrameElement, otherContent) &&
|
||||
SameCOMIdentity(ourChromeEventHandler, ourContent) &&
|
||||
SameCOMIdentity(otherChromeEventHandler, otherContent),
|
||||
"How did that happen, exactly?");
|
||||
|
||||
nsCOMPtr<nsIDocument> ourChildDocument =
|
||||
do_QueryInterface(ourWindow->GetExtantDocument());
|
||||
nsCOMPtr<nsIDocument> otherChildDocument =
|
||||
do_QueryInterface(otherWindow->GetExtantDocument());
|
||||
if (!ourChildDocument || !otherChildDocument) {
|
||||
// This shouldn't be happening
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocument> ourParentDocument =
|
||||
ourChildDocument->GetParentDocument();
|
||||
nsCOMPtr<nsIDocument> otherParentDocument =
|
||||
otherChildDocument->GetParentDocument();
|
||||
|
||||
// Make sure to swap docshells between the two frames.
|
||||
nsIDocument* ourDoc = ourContent->GetCurrentDoc();
|
||||
nsIDocument* otherDoc = otherContent->GetCurrentDoc();
|
||||
if (!ourDoc || !otherDoc) {
|
||||
// Again, how odd, given that we had docshells
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_ASSERTION(ourDoc == ourParentDocument, "Unexpected parent document");
|
||||
NS_ASSERTION(otherDoc == otherParentDocument, "Unexpected parent document");
|
||||
|
||||
nsPresShellIterator iter1(ourDoc);
|
||||
nsPresShellIterator iter2(otherDoc);
|
||||
if (iter1.HasMoreThanOneShell() || iter2.HasMoreThanOneShell()) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsIPresShell* ourShell = ourDoc->GetPrimaryShell();
|
||||
nsIPresShell* otherShell = otherDoc->GetPrimaryShell();
|
||||
if (!ourShell || !otherShell) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
if (mInSwap || aOther->mInSwap) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
mInSwap = aOther->mInSwap = PR_TRUE;
|
||||
|
||||
// Fire pagehide events. Note that we do NOT fire these in the normal way,
|
||||
// but just fire them on the chrome event handlers.
|
||||
FirePageHideEvent(ourTreeItem, ourChromeEventHandler);
|
||||
FirePageHideEvent(otherTreeItem, otherChromeEventHandler);
|
||||
|
||||
nsIFrame* ourFrame = ourShell->GetPrimaryFrameFor(ourContent);
|
||||
nsIFrame* otherFrame = otherShell->GetPrimaryFrameFor(otherContent);
|
||||
if (!ourFrame || !otherFrame) {
|
||||
mInSwap = aOther->mInSwap = PR_FALSE;
|
||||
FirePageShowEvent(ourTreeItem, ourChromeEventHandler);
|
||||
FirePageShowEvent(otherTreeItem, otherChromeEventHandler);
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsIFrameFrame* ourFrameFrame = nsnull;
|
||||
CallQueryInterface(ourFrame, &ourFrameFrame);
|
||||
if (!ourFrameFrame) {
|
||||
mInSwap = aOther->mInSwap = PR_FALSE;
|
||||
FirePageShowEvent(ourTreeItem, ourChromeEventHandler);
|
||||
FirePageShowEvent(otherTreeItem, otherChromeEventHandler);
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// OK. First begin to swap the docshells in the two nsIFrames
|
||||
rv = ourFrameFrame->BeginSwapDocShells(otherFrame);
|
||||
if (NS_FAILED(rv)) {
|
||||
mInSwap = aOther->mInSwap = PR_FALSE;
|
||||
FirePageShowEvent(ourTreeItem, ourChromeEventHandler);
|
||||
FirePageShowEvent(otherTreeItem, otherChromeEventHandler);
|
||||
return rv;
|
||||
}
|
||||
|
||||
// Now move the docshells to the right docshell trees. Note that this
|
||||
// resets their treeowners to null.
|
||||
ourParentItem->RemoveChild(ourTreeItem);
|
||||
otherParentItem->RemoveChild(otherTreeItem);
|
||||
if (ourType == nsIDocShellTreeItem::typeContent) {
|
||||
ourOwner->ContentShellRemoved(ourTreeItem);
|
||||
otherOwner->ContentShellRemoved(otherTreeItem);
|
||||
}
|
||||
|
||||
ourParentItem->AddChild(otherTreeItem);
|
||||
otherParentItem->AddChild(ourTreeItem);
|
||||
|
||||
// Restore the correct treeowners
|
||||
SetTreeOwnerAndChromeEventHandlerOnDocshellTree(ourTreeItem, otherOwner,
|
||||
otherChromeEventHandler);
|
||||
SetTreeOwnerAndChromeEventHandlerOnDocshellTree(otherTreeItem, ourOwner,
|
||||
ourChromeEventHandler);
|
||||
|
||||
AddTreeItemToTreeOwner(ourTreeItem, otherContent, otherOwner,
|
||||
nsIDocShellTreeItem::typeChrome, nsnull);
|
||||
AddTreeItemToTreeOwner(otherTreeItem, ourContent, ourOwner,
|
||||
nsIDocShellTreeItem::typeChrome, nsnull);
|
||||
|
||||
// SetSubDocumentFor nulls out parent documents on the old child doc if a
|
||||
// new non-null document is passed in, so just go ahead and remove both
|
||||
// kids before reinserting in the parent subdoc maps, to avoid
|
||||
// complications.
|
||||
ourParentDocument->SetSubDocumentFor(ourContent, nsnull);
|
||||
otherParentDocument->SetSubDocumentFor(otherContent, nsnull);
|
||||
ourParentDocument->SetSubDocumentFor(ourContent, otherChildDocument);
|
||||
otherParentDocument->SetSubDocumentFor(otherContent, ourChildDocument);
|
||||
|
||||
ourWindow->SetFrameElementInternal(otherFrameElement);
|
||||
otherWindow->SetFrameElementInternal(ourFrameElement);
|
||||
|
||||
mOwnerContent = otherContent;
|
||||
aOther->mOwnerContent = ourContent;
|
||||
|
||||
aFirstToSwap.swap(aSecondToSwap);
|
||||
|
||||
// We shouldn't have changed frames, but be really careful about it
|
||||
if (ourFrame == ourShell->GetPrimaryFrameFor(ourContent) &&
|
||||
otherFrame == otherShell->GetPrimaryFrameFor(otherContent)) {
|
||||
ourFrameFrame->EndSwapDocShells(otherFrame);
|
||||
}
|
||||
|
||||
ourParentDocument->FlushPendingNotifications(Flush_Layout);
|
||||
otherParentDocument->FlushPendingNotifications(Flush_Layout);
|
||||
|
||||
FirePageShowEvent(ourTreeItem, otherChromeEventHandler);
|
||||
FirePageShowEvent(otherTreeItem, ourChromeEventHandler);
|
||||
|
||||
mInSwap = aOther->mInSwap = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsFrameLoader::Destroy()
|
||||
{
|
||||
@ -402,52 +770,13 @@ nsFrameLoader::EnsureDocShell()
|
||||
PRInt32 parentType;
|
||||
parentAsItem->GetItemType(&parentType);
|
||||
|
||||
nsAutoString value;
|
||||
PRBool isContent = PR_FALSE;
|
||||
|
||||
if (mOwnerContent->IsNodeOfType(nsINode::eXUL)) {
|
||||
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::type, value);
|
||||
}
|
||||
|
||||
// we accept "content" and "content-xxx" values.
|
||||
// at time of writing, we expect "xxx" to be "primary" or "targetable", but
|
||||
// someday it might be an integer expressing priority or something else.
|
||||
|
||||
isContent = value.LowerCaseEqualsLiteral("content") ||
|
||||
StringBeginsWith(value, NS_LITERAL_STRING("content-"),
|
||||
nsCaseInsensitiveStringComparator());
|
||||
|
||||
if (isContent) {
|
||||
// The web shell's type is content.
|
||||
|
||||
docShellAsItem->SetItemType(nsIDocShellTreeItem::typeContent);
|
||||
} else {
|
||||
// Inherit our type from our parent webshell. If it is
|
||||
// chrome, we'll be chrome. If it is content, we'll be
|
||||
// content.
|
||||
|
||||
docShellAsItem->SetItemType(parentType);
|
||||
}
|
||||
|
||||
parentAsNode->AddChild(docShellAsItem);
|
||||
|
||||
if (parentType == nsIDocShellTreeItem::typeChrome && isContent) {
|
||||
mIsTopLevelContent = PR_TRUE;
|
||||
|
||||
// XXXbz why is this in content code, exactly? We should handle
|
||||
// this some other way..... Not sure how yet.
|
||||
nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
|
||||
parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
|
||||
|
||||
PRBool is_primary = value.LowerCaseEqualsLiteral("content-primary");
|
||||
|
||||
if (parentTreeOwner) {
|
||||
PRBool is_targetable = is_primary ||
|
||||
value.LowerCaseEqualsLiteral("content-targetable");
|
||||
parentTreeOwner->ContentShellAdded(docShellAsItem, is_primary,
|
||||
is_targetable, value);
|
||||
}
|
||||
}
|
||||
// XXXbz why is this in content code, exactly? We should handle
|
||||
// this some other way..... Not sure how yet.
|
||||
nsCOMPtr<nsIDocShellTreeOwner> parentTreeOwner;
|
||||
parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
|
||||
mIsTopLevelContent =
|
||||
AddTreeItemToTreeOwner(docShellAsItem, mOwnerContent, parentTreeOwner,
|
||||
parentType, parentAsNode);
|
||||
|
||||
// Make sure all shells have links back to the content element
|
||||
// in the nearest enclosing chrome shell.
|
||||
|
@ -60,7 +60,8 @@ public:
|
||||
mDepthTooGreat(PR_FALSE),
|
||||
mIsTopLevelContent(PR_FALSE),
|
||||
mDestroyCalled(PR_FALSE),
|
||||
mInDestructor(PR_FALSE)
|
||||
mInDestructor(PR_FALSE),
|
||||
mInSwap(PR_FALSE)
|
||||
{}
|
||||
|
||||
~nsFrameLoader() {
|
||||
@ -75,6 +76,13 @@ public:
|
||||
nsresult ReallyStartLoading();
|
||||
void Finalize();
|
||||
nsIDocShell* GetExistingDocShell() { return mDocShell; }
|
||||
|
||||
// The guts of an nsIFrameLoaderOwner::SwapFrameLoader implementation. A
|
||||
// frame loader owner needs to call this, and pass in the two references to
|
||||
// nsRefPtrs for frame loaders that need to be swapped.
|
||||
nsresult SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
nsRefPtr<nsFrameLoader>& aFirstToSwap,
|
||||
nsRefPtr<nsFrameLoader>& aSecondToSwap);
|
||||
private:
|
||||
|
||||
NS_HIDDEN_(nsresult) EnsureDocShell();
|
||||
@ -84,10 +92,11 @@ private:
|
||||
nsCOMPtr<nsIDocShell> mDocShell;
|
||||
nsCOMPtr<nsIURI> mURIToLoad;
|
||||
nsIContent *mOwnerContent; // WEAK
|
||||
PRPackedBool mDepthTooGreat;
|
||||
PRPackedBool mIsTopLevelContent;
|
||||
PRPackedBool mDestroyCalled;
|
||||
PRPackedBool mInDestructor;
|
||||
PRPackedBool mDepthTooGreat : 1;
|
||||
PRPackedBool mIsTopLevelContent : 1;
|
||||
PRPackedBool mDestroyCalled : 1;
|
||||
PRPackedBool mInDestructor : 1;
|
||||
PRPackedBool mInSwap : 1;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -486,6 +486,22 @@ nsImageLoadingContent::LoadImage(const nsAString& aNewURI,
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
// XXXbiesi fire onerror if that failed?
|
||||
|
||||
PRBool equal;
|
||||
|
||||
if (aNewURI.IsEmpty() &&
|
||||
doc->GetDocumentURI() &&
|
||||
NS_SUCCEEDED(doc->GetDocumentURI()->Equals(imageURI, &equal)) &&
|
||||
equal) {
|
||||
|
||||
// Loading an embedded img from the same URI as the document URI will not work
|
||||
// as a resource cannot recursively embed itself. Attempting to do so generally
|
||||
// results in having to pre-emptively close down an in-flight HTTP transaction
|
||||
// and then incurring the significant cost of establishing a new TCP channel.
|
||||
// This is generally triggered from <img src="">
|
||||
// In light of that, just skip loading it..
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_TryToSetImmutable(imageURI);
|
||||
|
||||
return LoadImage(imageURI, aForce, aNotify, doc);
|
||||
|
@ -670,6 +670,12 @@ nsObjectLoadingContent::GetFrameLoader(nsIFrameLoader** aFrameLoader)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsObjectLoadingContent::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherLoader)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
// nsIObjectLoadingContent
|
||||
NS_IMETHODIMP
|
||||
nsObjectLoadingContent::GetActualType(nsACString& aType)
|
||||
|
@ -98,6 +98,7 @@ public:
|
||||
|
||||
nsCOMPtr<nsIScriptElement> mElement;
|
||||
PRPackedBool mLoading; // Are we still waiting for a load to complete?
|
||||
PRPackedBool mDefer; // Is execution defered?
|
||||
PRPackedBool mIsInline; // Is the script inline or loaded?
|
||||
nsString mScriptText; // Holds script for loaded scripts
|
||||
PRUint32 mJSVersion;
|
||||
@ -125,8 +126,8 @@ nsScriptLoader::~nsScriptLoader()
|
||||
{
|
||||
mObservers.Clear();
|
||||
|
||||
for (PRInt32 i = 0; i < mPendingRequests.Count(); i++) {
|
||||
mPendingRequests[i]->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
for (PRInt32 i = 0; i < mRequests.Count(); i++) {
|
||||
mRequests[i]->FireScriptAvailable(NS_ERROR_ABORT);
|
||||
}
|
||||
|
||||
// Unblock the kids, in case any of them moved to a different document
|
||||
@ -379,6 +380,10 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
nsRefPtr<nsScriptLoadRequest> request = new nsScriptLoadRequest(aElement, version);
|
||||
NS_ENSURE_TRUE(request, NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
request->mDefer = mDeferEnabled && aElement->GetScriptDeferred();
|
||||
|
||||
PRBool hadPendingRequests = !!GetFirstPendingRequest();
|
||||
|
||||
// First check to see if this is an external script
|
||||
nsCOMPtr<nsIURI> scriptURI = aElement->GetScriptURI();
|
||||
if (scriptURI) {
|
||||
@ -448,20 +453,23 @@ nsScriptLoader::ProcessScriptElement(nsIScriptElement *aElement)
|
||||
|
||||
// If we've got existing pending requests, add ourselves
|
||||
// to this list.
|
||||
if (mPendingRequests.Count() == 0 && ReadyToExecuteScripts() &&
|
||||
nsContentUtils::IsSafeToRunScript()) {
|
||||
if (!request->mDefer && !hadPendingRequests &&
|
||||
ReadyToExecuteScripts() && nsContentUtils::IsSafeToRunScript()) {
|
||||
return ProcessRequest(request);
|
||||
}
|
||||
}
|
||||
|
||||
// Add the request to our pending requests list
|
||||
NS_ENSURE_TRUE(mPendingRequests.AppendObject(request),
|
||||
// Add the request to our requests list
|
||||
NS_ENSURE_TRUE(mRequests.AppendObject(request),
|
||||
NS_ERROR_OUT_OF_MEMORY);
|
||||
|
||||
if (request->mDefer) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// If there weren't any pending requests before, and this one is
|
||||
// ready to execute, do that as soon as it's safe.
|
||||
if (mPendingRequests.Count() == 1 && !request->mLoading &&
|
||||
ReadyToExecuteScripts()) {
|
||||
if (!request->mLoading && !hadPendingRequests && ReadyToExecuteScripts()) {
|
||||
nsContentUtils::AddScriptRunner(new nsRunnableMethod<nsScriptLoader>(this,
|
||||
&nsScriptLoader::ProcessPendingRequests));
|
||||
}
|
||||
@ -612,10 +620,22 @@ nsScriptLoader::EvaluateScript(nsScriptLoadRequest* aRequest,
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsScriptLoadRequest*
|
||||
nsScriptLoader::GetFirstPendingRequest()
|
||||
{
|
||||
for (PRInt32 i = 0; i < mRequests.Count(); ++i) {
|
||||
if (!mRequests[i]->mDefer) {
|
||||
return mRequests[i];
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
nsScriptLoader::ProcessPendingRequestsAsync()
|
||||
{
|
||||
if (mPendingRequests.Count() || !mPendingChildLoaders.IsEmpty()) {
|
||||
if (GetFirstPendingRequest() || !mPendingChildLoaders.IsEmpty()) {
|
||||
nsCOMPtr<nsIRunnable> ev = new nsRunnableMethod<nsScriptLoader>(this,
|
||||
&nsScriptLoader::ProcessPendingRequests);
|
||||
|
||||
@ -627,9 +647,10 @@ void
|
||||
nsScriptLoader::ProcessPendingRequests()
|
||||
{
|
||||
nsRefPtr<nsScriptLoadRequest> request;
|
||||
while (mPendingRequests.Count() && ReadyToExecuteScripts() &&
|
||||
!(request = mPendingRequests[0])->mLoading) {
|
||||
mPendingRequests.RemoveObjectAt(0);
|
||||
while (ReadyToExecuteScripts() &&
|
||||
(request = GetFirstPendingRequest()) &&
|
||||
!request->mLoading) {
|
||||
mRequests.RemoveObject(request);
|
||||
ProcessRequest(request);
|
||||
}
|
||||
|
||||
@ -800,7 +821,7 @@ nsScriptLoader::OnStreamComplete(nsIStreamLoader* aLoader,
|
||||
nsresult rv = PrepareLoadedRequest(request, aLoader, aStatus, aStringLen,
|
||||
aString);
|
||||
if (NS_FAILED(rv)) {
|
||||
mPendingRequests.RemoveObject(request);
|
||||
mRequests.RemoveObject(request);
|
||||
FireScriptAvailable(rv, request);
|
||||
}
|
||||
|
||||
@ -863,7 +884,7 @@ nsScriptLoader::PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
|
||||
// inserting the request in the array. However it's an unlikely case
|
||||
// so if you see this assertion it is likely something else that is
|
||||
// wrong, especially if you see it more than once.
|
||||
NS_ASSERTION(mPendingRequests.IndexOf(aRequest) >= 0,
|
||||
NS_ASSERTION(mRequests.IndexOf(aRequest) >= 0,
|
||||
"aRequest should be pending!");
|
||||
|
||||
// Mark this as loaded
|
||||
@ -901,3 +922,14 @@ nsScriptLoader::ShouldExecuteScript(nsIDocument* aDocument,
|
||||
rv = channelPrincipal->Subsumes(docPrincipal, &subsumes);
|
||||
return NS_SUCCEEDED(rv) && subsumes;
|
||||
}
|
||||
|
||||
void
|
||||
nsScriptLoader::EndDeferringScripts()
|
||||
{
|
||||
mDeferEnabled = PR_FALSE;
|
||||
for (PRUint32 i = 0; i < mRequests.Count(); ++i) {
|
||||
mRequests[i]->mDefer = PR_FALSE;
|
||||
}
|
||||
|
||||
ProcessPendingRequests();
|
||||
}
|
||||
|
@ -187,6 +187,24 @@ public:
|
||||
static PRBool ShouldExecuteScript(nsIDocument* aDocument,
|
||||
nsIChannel* aChannel);
|
||||
|
||||
/**
|
||||
* Starts deferring deferred scripts and puts them in the mDeferredRequests
|
||||
* queue instead.
|
||||
*/
|
||||
void BeginDeferringScripts()
|
||||
{
|
||||
mDeferEnabled = PR_TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops defering scripts and immediately processes the mDeferredRequests
|
||||
* queue.
|
||||
*
|
||||
* WARNING: This function will syncronously execute content scripts, so be
|
||||
* prepared that the world might change around you.
|
||||
*/
|
||||
void EndDeferringScripts();
|
||||
|
||||
protected:
|
||||
/**
|
||||
* Process any pending requests asyncronously (i.e. off an event) if there
|
||||
@ -229,14 +247,18 @@ protected:
|
||||
PRUint32 aStringLen,
|
||||
const PRUint8* aString);
|
||||
|
||||
// Returns the first pending (non deferred) request
|
||||
nsScriptLoadRequest* GetFirstPendingRequest();
|
||||
|
||||
nsIDocument* mDocument; // [WEAK]
|
||||
nsCOMArray<nsIScriptLoaderObserver> mObservers;
|
||||
nsCOMArray<nsScriptLoadRequest> mPendingRequests;
|
||||
nsCOMArray<nsScriptLoadRequest> mRequests;
|
||||
nsCOMPtr<nsIScriptElement> mCurrentScript;
|
||||
// XXXbz do we want to cycle-collect these or something? Not sure.
|
||||
nsTArray< nsRefPtr<nsScriptLoader> > mPendingChildLoaders;
|
||||
PRUint32 mBlockerCount;
|
||||
PRPackedBool mEnabled;
|
||||
PRPackedBool mDeferEnabled;
|
||||
};
|
||||
|
||||
#endif //__nsScriptLoader_h__
|
||||
|
@ -84,6 +84,7 @@
|
||||
#include "nsLayoutStatics.h"
|
||||
#include "nsDOMError.h"
|
||||
#include "nsIHTMLDocument.h"
|
||||
#include "nsIDOM3Document.h"
|
||||
#include "nsWhitespaceTokenizer.h"
|
||||
#include "nsIMultiPartChannel.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
@ -702,9 +703,15 @@ nsXMLHttpRequest::ConvertBodyToText(nsAString& aOutBuffer)
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCAutoString dataCharset;
|
||||
nsCOMPtr<nsIDocument> document(do_QueryInterface(mDocument));
|
||||
nsCOMPtr<nsIDOM3Document> document(do_QueryInterface(mDocument));
|
||||
if (document) {
|
||||
dataCharset = document->GetDocumentCharacterSet();
|
||||
nsAutoString inputEncoding;
|
||||
document->GetInputEncoding(inputEncoding);
|
||||
if (DOMStringIsNull(inputEncoding)) {
|
||||
dataCharset.AssignLiteral("UTF-8");
|
||||
} else {
|
||||
CopyUTF16toUTF8(inputEncoding, dataCharset);
|
||||
}
|
||||
} else {
|
||||
if (NS_FAILED(DetectCharset(dataCharset)) || dataCharset.IsEmpty()) {
|
||||
// MS documentation states UTF-8 is default for responseText
|
||||
|
@ -192,6 +192,8 @@ _TEST_FILES = test_bug5141.html \
|
||||
test_NodeIterator_basics_filters.xhtml \
|
||||
test_NodeIterator_mutations_1.xhtml \
|
||||
test_NodeIterator_mutations_2.html \
|
||||
test_bug28293.html \
|
||||
file_bug28293.sjs \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
5
content/base/test/file_bug28293.sjs
Normal file
5
content/base/test/file_bug28293.sjs
Normal file
@ -0,0 +1,5 @@
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
response.setHeader("Content-Type", "text/plain", false);
|
||||
response.write(decodeURIComponent(request.queryString));
|
||||
}
|
99
content/base/test/test_bug28293.html
Normal file
99
content/base/test/test_bug28293.html
Normal file
@ -0,0 +1,99 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=28293
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 28293</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<script>
|
||||
res = 'A';
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
onload = function () {
|
||||
|
||||
res+='2';
|
||||
|
||||
s = document.createElement('script');
|
||||
s.textContent="res+='g';";
|
||||
s.defer = true;
|
||||
document.body.appendChild(s);
|
||||
|
||||
res+='3';
|
||||
|
||||
s = document.createElement('script');
|
||||
s.src="file_bug28293.sjs?res+='h';";
|
||||
s.defer = true;
|
||||
document.body.appendChild(s);
|
||||
|
||||
s = document.createElement('script');
|
||||
s.textContent="res+='i';done()";
|
||||
s.defer = true;
|
||||
document.body.appendChild(s);
|
||||
|
||||
res+='4';
|
||||
}
|
||||
|
||||
function done() {
|
||||
is(res, "ABCDEFGHIJ1abcdefM2g34hi", "scripts executed in the wrong order");
|
||||
ok(!fHadExecuted, "Dynamic script executed too late");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=28293">Mozilla Bug 28293</a>
|
||||
|
||||
<script defer>
|
||||
res += 'a';
|
||||
</script>
|
||||
<script defer src="data:text/plain,res+='b'"></script>
|
||||
<script defer>
|
||||
res += 'c';
|
||||
</script>
|
||||
<script>
|
||||
res += 'B';
|
||||
</script>
|
||||
<script>
|
||||
res += 'C';
|
||||
|
||||
s = document.createElement('script');
|
||||
s.src="file_bug28293.sjs?res+='d';";
|
||||
s.defer = true;
|
||||
document.body.appendChild(s);
|
||||
|
||||
s = document.createElement('script');
|
||||
s.textContent="res+='D';";
|
||||
document.body.appendChild(s);
|
||||
|
||||
res += 'E';
|
||||
</script>
|
||||
<script>
|
||||
res += 'F';
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
res += '1'
|
||||
s = document.createElement('script');
|
||||
s.src="file_bug28293.sjs?res+='M';";
|
||||
document.body.appendChild(s);
|
||||
}, false);
|
||||
res += 'G';
|
||||
</script>
|
||||
<script defer>
|
||||
res += 'e';
|
||||
</script>
|
||||
<script src="file_bug28293.sjs?res+='H';"></script>
|
||||
<script>
|
||||
res += 'I';
|
||||
s = document.createElement('script');
|
||||
s.src="file_bug28293.sjs?fHadExecuted=(res.indexOf('f')>=0);";
|
||||
document.body.appendChild(s);
|
||||
res += 'J';
|
||||
</script>
|
||||
<script defer>
|
||||
res += 'f';
|
||||
</script>
|
||||
|
||||
</body>
|
||||
</html>
|
@ -375,6 +375,12 @@ protected:
|
||||
|
||||
PRUint32 mSaveCount;
|
||||
|
||||
/**
|
||||
* Flag to avoid duplicate calls to InvalidateFrame. Set to true whenever
|
||||
* Redraw is called, reset to false when Render is called.
|
||||
*/
|
||||
PRBool mIsFrameInvalid;
|
||||
|
||||
/**
|
||||
* Draws a rectangle in the given style; used by FillRect and StrokeRect.
|
||||
*/
|
||||
@ -551,7 +557,7 @@ NS_NewCanvasRenderingContext2D(nsIDOMCanvasRenderingContext2D** aResult)
|
||||
|
||||
nsCanvasRenderingContext2D::nsCanvasRenderingContext2D()
|
||||
: mValid(PR_FALSE), mOpaque(PR_FALSE), mCanvasElement(nsnull),
|
||||
mSaveCount(0), mStyleStack(20)
|
||||
mSaveCount(0), mIsFrameInvalid(PR_FALSE), mStyleStack(20)
|
||||
{
|
||||
}
|
||||
|
||||
@ -566,6 +572,7 @@ nsCanvasRenderingContext2D::Destroy()
|
||||
mSurface = nsnull;
|
||||
mThebes = nsnull;
|
||||
mValid = PR_FALSE;
|
||||
mIsFrameInvalid = PR_FALSE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
@ -737,7 +744,12 @@ nsCanvasRenderingContext2D::Redraw()
|
||||
if (!mCanvasElement)
|
||||
return NS_OK;
|
||||
|
||||
return mCanvasElement->InvalidateFrame();
|
||||
if (!mIsFrameInvalid) {
|
||||
mIsFrameInvalid = PR_TRUE;
|
||||
return mCanvasElement->InvalidateFrame();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
@ -855,6 +867,7 @@ nsCanvasRenderingContext2D::Render(gfxContext *ctx)
|
||||
if (mOpaque)
|
||||
ctx->SetOperator(op);
|
||||
|
||||
mIsFrameInvalid = PR_FALSE;
|
||||
return rv;
|
||||
}
|
||||
|
||||
@ -1378,7 +1391,7 @@ NS_IMETHODIMP
|
||||
nsCanvasRenderingContext2D::Clip()
|
||||
{
|
||||
mThebes->Clip();
|
||||
return Redraw();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -41,10 +41,10 @@
|
||||
#include "nsEvent.h"
|
||||
#include "nsISupports.h"
|
||||
|
||||
// {889792DC-22D8-4d1a-AC3D-58AD7DEBA17B}
|
||||
// {901B82D5-67C0-45ad-86AE-AB9A6BD74111}
|
||||
#define NS_IPRIVATECOMPOSITIONEVENT_IID \
|
||||
{ 0x889792dc, 0x22d8, 0x4d1a, \
|
||||
{ 0xac, 0x3d, 0x58, 0xad, 0x7d, 0xeb, 0xa1, 0x7b }}
|
||||
{ 0x901b82d5, 0x67c0, 0x45ad, \
|
||||
{ 0x86, 0xae, 0xab, 0x9a, 0x6b, 0xd7, 0x41, 0x11 } }
|
||||
|
||||
class nsIPrivateCompositionEvent : public nsISupports {
|
||||
|
||||
@ -52,8 +52,6 @@ public:
|
||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRIVATECOMPOSITIONEVENT_IID)
|
||||
|
||||
NS_IMETHOD GetCompositionReply(struct nsTextEventReply** aReply) = 0;
|
||||
NS_IMETHOD GetReconversionReply(nsReconversionEventReply** aReply) = 0;
|
||||
NS_IMETHOD GetQueryCaretRectReply(nsQueryCaretRectEventReply** aReply) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIPrivateCompositionEvent,
|
||||
|
@ -788,12 +788,6 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
|
||||
isInputEvent = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
case NS_RECONVERSION_EVENT:
|
||||
{
|
||||
newEvent = new nsReconversionEvent(PR_FALSE, msg, nsnull);
|
||||
isInputEvent = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
case NS_MOUSE_SCROLL_EVENT:
|
||||
{
|
||||
nsMouseScrollEvent* mouseScrollEvent =
|
||||
@ -885,12 +879,6 @@ NS_METHOD nsDOMEvent::DuplicatePrivateData()
|
||||
static_cast<nsUIEvent*>(mEvent)->detail);
|
||||
break;
|
||||
}
|
||||
case NS_QUERYCARETRECT_EVENT:
|
||||
{
|
||||
newEvent = new nsQueryCaretRectEvent(PR_FALSE, msg, nsnull);
|
||||
isInputEvent = PR_TRUE;
|
||||
break;
|
||||
}
|
||||
case NS_PAGETRANSITION_EVENT:
|
||||
{
|
||||
newEvent =
|
||||
|
@ -370,8 +370,7 @@ nsDOMUIEvent::GetPreventDefault(PRBool* aReturn)
|
||||
|
||||
NS_METHOD nsDOMUIEvent::GetCompositionReply(nsTextEventReply** aReply)
|
||||
{
|
||||
if((mEvent->eventStructType == NS_RECONVERSION_EVENT) ||
|
||||
(mEvent->message == NS_COMPOSITION_START) ||
|
||||
if((mEvent->message == NS_COMPOSITION_START) ||
|
||||
(mEvent->message == NS_COMPOSITION_QUERY))
|
||||
{
|
||||
*aReply = &(static_cast<nsCompositionEvent*>(mEvent)->theReply);
|
||||
@ -381,30 +380,6 @@ NS_METHOD nsDOMUIEvent::GetCompositionReply(nsTextEventReply** aReply)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsDOMUIEvent::GetReconversionReply(nsReconversionEventReply** aReply)
|
||||
{
|
||||
if (mEvent->eventStructType == NS_RECONVERSION_EVENT)
|
||||
{
|
||||
*aReply = &(static_cast<nsReconversionEvent*>(mEvent)->theReply);
|
||||
return NS_OK;
|
||||
}
|
||||
*aReply = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsDOMUIEvent::GetQueryCaretRectReply(nsQueryCaretRectEventReply** aReply)
|
||||
{
|
||||
if (mEvent->eventStructType == NS_QUERYCARETRECT_EVENT)
|
||||
{
|
||||
*aReply = &(static_cast<nsQueryCaretRectEvent*>(mEvent)->theReply);
|
||||
return NS_OK;
|
||||
}
|
||||
*aReply = nsnull;
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_METHOD
|
||||
nsDOMUIEvent::DuplicatePrivateData()
|
||||
{
|
||||
|
@ -67,8 +67,6 @@ public:
|
||||
|
||||
// nsIPrivateCompositionEvent interface
|
||||
NS_IMETHOD GetCompositionReply(nsTextEventReply** aReply);
|
||||
NS_IMETHOD GetReconversionReply(nsReconversionEventReply** aReply);
|
||||
NS_IMETHOD GetQueryCaretRectReply(nsQueryCaretRectEventReply** aReply);
|
||||
|
||||
// Forward to nsDOMEvent
|
||||
NS_FORWARD_TO_NSDOMEVENT
|
||||
|
@ -562,8 +562,6 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
|
||||
static_cast<nsMutationEvent*>(aEvent));
|
||||
case NS_GUI_EVENT:
|
||||
case NS_COMPOSITION_EVENT:
|
||||
case NS_RECONVERSION_EVENT:
|
||||
case NS_QUERYCARETRECT_EVENT:
|
||||
case NS_SCROLLPORT_EVENT:
|
||||
return NS_NewDOMUIEvent(aDOMEvent, aPresContext,
|
||||
static_cast<nsGUIEvent*>(aEvent));
|
||||
|
@ -225,11 +225,7 @@ static const EventDispatchData sCompositionEvents[] = {
|
||||
{ NS_COMPOSITION_END,
|
||||
HANDLER(&nsIDOMCompositionListener::HandleEndComposition) },
|
||||
{ NS_COMPOSITION_QUERY,
|
||||
HANDLER(&nsIDOMCompositionListener::HandleQueryComposition) },
|
||||
{ NS_RECONVERSION_QUERY,
|
||||
HANDLER(&nsIDOMCompositionListener::HandleQueryReconversion) },
|
||||
{ NS_QUERYCARETRECT,
|
||||
HANDLER(&nsIDOMCompositionListener::HandleQueryCaretRect) }
|
||||
HANDLER(&nsIDOMCompositionListener::HandleQueryComposition) }
|
||||
};
|
||||
|
||||
static const EventDispatchData sTextEvents[] = {
|
||||
|
@ -3001,6 +3001,13 @@ nsGenericHTMLFrameElement::GetFrameLoader(nsIFrameLoader **aFrameLoader)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsGenericHTMLFrameElement::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner)
|
||||
{
|
||||
// We don't support this yet
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsGenericHTMLFrameElement::LoadSrc()
|
||||
{
|
||||
|
@ -408,6 +408,8 @@ nsHTMLMediaElement::nsHTMLMediaElement(nsINodeInfo *aNodeInfo, PRBool aFromParse
|
||||
|
||||
nsHTMLMediaElement::~nsHTMLMediaElement()
|
||||
{
|
||||
if (mDecoder)
|
||||
mDecoder->Stop();
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -513,6 +515,9 @@ nsresult nsHTMLMediaElement::BindToTree(nsIDocument* aDocument, nsIContent* aPar
|
||||
void nsHTMLMediaElement::UnbindFromTree(PRBool aDeep,
|
||||
PRBool aNullParent)
|
||||
{
|
||||
if (!mPaused && mNetworkState != nsIDOMHTMLMediaElement::EMPTY)
|
||||
Pause();
|
||||
|
||||
nsGenericHTMLElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
|
@ -338,6 +338,7 @@ public:
|
||||
virtual already_AddRefed<nsIURI> GetScriptURI();
|
||||
virtual void GetScriptText(nsAString& text);
|
||||
virtual void GetScriptCharset(nsAString& charset);
|
||||
virtual PRBool GetScriptDeferred();
|
||||
|
||||
// nsIContent
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
@ -524,6 +525,15 @@ nsHTMLScriptElement::GetScriptCharset(nsAString& charset)
|
||||
GetCharset(charset);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLScriptElement::GetScriptDeferred()
|
||||
{
|
||||
PRBool defer;
|
||||
GetDefer(&defer);
|
||||
|
||||
return defer;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsHTMLScriptElement::HasScriptContent()
|
||||
{
|
||||
|
@ -143,10 +143,10 @@ nsresult nsHTMLVideoElement::BindToTree(nsIDocument* aDocument, nsIContent* aPar
|
||||
void nsHTMLVideoElement::UnbindFromTree(PRBool aDeep,
|
||||
PRBool aNullParent)
|
||||
{
|
||||
nsHTMLMediaElement::UnbindFromTree(aDeep, aNullParent);
|
||||
|
||||
if (mDecoder)
|
||||
mDecoder->ElementUnavailable();
|
||||
|
||||
nsHTMLMediaElement::UnbindFromTree(aDeep, aNullParent);
|
||||
}
|
||||
|
||||
nsresult nsHTMLVideoElement::InitializeDecoder(nsAString& aChosenMediaResource)
|
||||
|
@ -317,6 +317,9 @@ private:
|
||||
// the metadata then it should start playing.
|
||||
PRPackedBool mPlayAfterLoad;
|
||||
|
||||
// True if we are registered with the observer service for shutdown.
|
||||
PRPackedBool mNotifyOnShutdown;
|
||||
|
||||
/******
|
||||
* The following member variables can be accessed from any thread.
|
||||
******/
|
||||
|
@ -260,6 +260,7 @@ nsOggDecoder::nsOggDecoder() :
|
||||
mVideoNextFrameTime(0.0),
|
||||
mLoadInProgress(PR_FALSE),
|
||||
mPlayAfterLoad(PR_FALSE),
|
||||
mNotifyOnShutdown(PR_FALSE),
|
||||
mVideoCurrentFrameTime(0.0),
|
||||
mInitialVolume(1.0),
|
||||
mAudioRate(0),
|
||||
@ -286,15 +287,6 @@ PRBool nsOggDecoder::Init()
|
||||
mDecodeEvent = new nsVideoDecodeEvent(this);
|
||||
mPresentationEvent = new nsVideoPresentationEvent(this);
|
||||
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService("@mozilla.org/observer-service;1");
|
||||
if (observerService) {
|
||||
observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, PR_FALSE);
|
||||
}
|
||||
else {
|
||||
NS_WARNING("Could not get an observer service. Video decoding events may not shutdown cleanly.");
|
||||
}
|
||||
|
||||
return mFirstFrameLock &&
|
||||
mFirstFrameCondVar &&
|
||||
mDecodeEvent && mDecodeEvent->Init() &&
|
||||
@ -473,6 +465,20 @@ nsresult nsOggDecoder::Play()
|
||||
StartPlaybackThreads();
|
||||
}
|
||||
|
||||
if (!mNotifyOnShutdown) {
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService("@mozilla.org/observer-service;1");
|
||||
if (observerService) {
|
||||
mNotifyOnShutdown =
|
||||
NS_SUCCEEDED(observerService->AddObserver(this,
|
||||
NS_XPCOM_SHUTDOWN_OBSERVER_ID,
|
||||
PR_FALSE));
|
||||
}
|
||||
else {
|
||||
NS_WARNING("Could not get an observer service. Video decoding events may not shutdown cleanly.");
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -514,6 +520,15 @@ void nsOggDecoder::Stop()
|
||||
}
|
||||
mPaused = PR_TRUE;
|
||||
mVideoCurrentFrameTime = 0.0;
|
||||
|
||||
if (mNotifyOnShutdown) {
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService("@mozilla.org/observer-service;1");
|
||||
if (observerService) {
|
||||
mNotifyOnShutdown = PR_FALSE;
|
||||
observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nsOggDecoder::HandleVideoData(int track_num, OggPlayVideoData* video_data) {
|
||||
|
@ -173,7 +173,6 @@ nsresult nsVideoDecoder::StartProgress()
|
||||
|
||||
nsresult nsVideoDecoder::StopProgress()
|
||||
{
|
||||
return NS_OK;
|
||||
nsresult rv = NS_OK;
|
||||
if (mProgressTimer) {
|
||||
rv = mProgressTimer->Cancel();
|
||||
|
BIN
content/media/video/test/320x240.ogg
Normal file
BIN
content/media/video/test/320x240.ogg
Normal file
Binary file not shown.
@ -52,8 +52,10 @@ _TEST_FILES = test_autoplay.html \
|
||||
test_paused.html \
|
||||
test_playbackRate.html \
|
||||
test_readyState.html \
|
||||
test_start.html \
|
||||
$(NULL)
|
||||
test_start.html \
|
||||
# test_bug448534.html \
|
||||
320x240.ogg \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
$(INSTALL) $(foreach f,$^,"$f") $(DEPTH)/_tests/testing/mochitest/tests/$(relativesrcdir)
|
||||
|
51
content/media/video/test/test_bug448534.html
Normal file
51
content/media/video/test/test_bug448534.html
Normal file
@ -0,0 +1,51 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=448534
|
||||
-->
|
||||
|
||||
<head>
|
||||
<title>Test for Bug 448534</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=448535">Mozilla Bug 448534</a>
|
||||
<!-- Ogg video obtained from Theora test suite: http://v2v.cc/~j/theora_testsuite/ -->
|
||||
<video id='v'
|
||||
src='320x240.ogg'
|
||||
onplay='return started();'
|
||||
onpause='return stopped();'></video>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
var v = $('v');
|
||||
var played = false;
|
||||
var passed = false;
|
||||
function started() {
|
||||
ok(!v.paused, "Video should not be paused while playing");
|
||||
v.parentNode.removeChild(v);
|
||||
played = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function stopped() {
|
||||
ok(v.paused, "Video should be paused after removing from the Document");
|
||||
passed = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
setTimeout(function () {
|
||||
ok(played, "Video did not send play event");
|
||||
ok(passed, "Video was not paused when removed from the Document");
|
||||
SimpleTest.finish();
|
||||
return false;
|
||||
}, 6000);
|
||||
|
||||
v.play();
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -256,12 +256,8 @@ nsSVGAElement::IsLink(nsIURI** aURI) const
|
||||
nsIContent::ATTR_VALUE_NO_MATCH) {
|
||||
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
|
||||
// Get absolute URI
|
||||
// XXX: should really be using href->GetStringValue(), but nsSVGElement::
|
||||
// ParseAttribute has set the nsAttrValue type to eSVGValue, so we need
|
||||
// to use the more expensive ToString (generates, rather than fetches).
|
||||
nsAutoString hrefStr;
|
||||
href->ToString(hrefStr);
|
||||
nsContentUtils::NewURIWithDocumentCharset(aURI, hrefStr,
|
||||
nsContentUtils::NewURIWithDocumentCharset(aURI,
|
||||
mStringAttributes[HREF].GetAnimValue(),
|
||||
GetOwnerDoc(), baseURI);
|
||||
// must promise out param is non-null if we return true
|
||||
return !!*aURI;
|
||||
@ -274,7 +270,7 @@ nsSVGAElement::IsLink(nsIURI** aURI) const
|
||||
void
|
||||
nsSVGAElement::GetLinkTarget(nsAString& aTarget)
|
||||
{
|
||||
GetAttr(kNameSpaceID_None, nsGkAtoms::target, aTarget);
|
||||
aTarget = mStringAttributes[TARGET].GetAnimValue();
|
||||
if (aTarget.IsEmpty()) {
|
||||
|
||||
static nsIContent::AttrValuesArray sShowVals[] =
|
||||
|
@ -641,6 +641,24 @@ nsSVGElement::ResetOldStyleBaseType(nsISVGValue *svg_value)
|
||||
}
|
||||
}
|
||||
|
||||
nsChangeHint
|
||||
nsSVGElement::GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||
PRInt32 aModType) const
|
||||
{
|
||||
nsChangeHint retval =
|
||||
nsSVGElementBase::GetAttributeChangeHint(aAttribute, aModType);
|
||||
|
||||
if (aAttribute == nsGkAtoms::requiredFeatures ||
|
||||
aAttribute == nsGkAtoms::requiredExtensions ||
|
||||
aAttribute == nsGkAtoms::systemLanguage) {
|
||||
// It would be nice to only reconstruct the frame if the value returned by
|
||||
// NS_SVG_PassesConditionalProcessingTests has changed, but we don't know
|
||||
// that
|
||||
NS_UpdateHint(retval, nsChangeHint_ReconstructFrame);
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSVGElement::IsNodeOfType(PRUint32 aFlags) const
|
||||
{
|
||||
|
@ -87,6 +87,9 @@ public:
|
||||
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
|
||||
PRBool aNotify);
|
||||
|
||||
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
|
||||
PRInt32 aModType) const;
|
||||
|
||||
virtual PRBool IsNodeOfType(PRUint32 aFlags) const;
|
||||
|
||||
virtual already_AddRefed<nsIURI> GetBaseURI() const;
|
||||
|
@ -189,6 +189,10 @@ ElementSupportsAttributes(const nsIAtom *aTagName, PRUint16 aAttr)
|
||||
PRBool
|
||||
NS_SVG_PassesConditionalProcessingTests(nsIContent *aContent)
|
||||
{
|
||||
if (!aContent->IsNodeOfType(nsINode::eELEMENT)) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
if (!ElementSupportsAttributes(aContent->Tag(), ATTRS_CONDITIONAL)) {
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
@ -63,6 +63,7 @@
|
||||
#include "imgIContainer.h"
|
||||
#include "gfxIImageFrame.h"
|
||||
#include "nsIImage.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsSVGAnimatedPreserveAspectRatio.h"
|
||||
#include "nsSVGPreserveAspectRatio.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
@ -5194,10 +5195,11 @@ public:
|
||||
NS_FORWARD_NSIDOMNODE(nsSVGFEImageElementBase::)
|
||||
NS_FORWARD_NSIDOMELEMENT(nsSVGFEImageElementBase::)
|
||||
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
// nsSVGElement
|
||||
virtual void DidChangeString(PRUint8 aAttrEnum, PRBool aDoSetAttr);
|
||||
|
||||
virtual nsresult AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify);
|
||||
// nsIContent
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
@ -5218,6 +5220,8 @@ private:
|
||||
// Invalidate users of the filter containing this element.
|
||||
void Invalidate();
|
||||
|
||||
nsresult LoadSVGImage(PRBool aForce, PRBool aNotify);
|
||||
|
||||
protected:
|
||||
virtual PRBool OperatesOnSRGB(nsSVGFilterInstance*,
|
||||
PRUint32, Image*) { return PR_TRUE; }
|
||||
@ -5293,25 +5297,25 @@ nsSVGFEImageElement::Init()
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIContent methods:
|
||||
|
||||
nsresult
|
||||
nsSVGFEImageElement::AfterSetAttr(PRInt32 aNamespaceID, nsIAtom* aName,
|
||||
const nsAString* aValue, PRBool aNotify)
|
||||
nsSVGFEImageElement::LoadSVGImage(PRBool aForce, PRBool aNotify)
|
||||
{
|
||||
if (aNamespaceID == kNameSpaceID_XLink && aName == nsGkAtoms::href) {
|
||||
nsAutoString href;
|
||||
if (GetAttr(kNameSpaceID_XLink, nsGkAtoms::href, href)) {
|
||||
// Note: no need to notify here; since we're just now being bound
|
||||
// we don't have any frames or anything yet.
|
||||
LoadImage(href, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
}
|
||||
// resolve href attribute
|
||||
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
|
||||
|
||||
return nsSVGFEImageElementBase::AfterSetAttr(aNamespaceID, aName,
|
||||
aValue, aNotify);
|
||||
nsAutoString href(mStringAttributes[HREF].GetAnimValue());
|
||||
href.Trim(" \t\n\r");
|
||||
|
||||
if (baseURI && !href.IsEmpty())
|
||||
NS_MakeAbsoluteURI(href, href, baseURI);
|
||||
|
||||
return LoadImage(href, aForce, aNotify);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsIContent methods:
|
||||
|
||||
nsresult
|
||||
nsSVGFEImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
nsIContent* aBindingParent,
|
||||
@ -5324,12 +5328,9 @@ nsSVGFEImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
|
||||
// Our base URI may have changed; claim that our URI changed, and the
|
||||
// nsImageLoadingContent will decide whether a new image load is warranted.
|
||||
nsAutoString href;
|
||||
if (GetAttr(kNameSpaceID_XLink, nsGkAtoms::href, href)) {
|
||||
// Note: no need to notify here; since we're just now being bound
|
||||
// we don't have any frames or anything yet.
|
||||
LoadImage(href, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
// Note: no need to notify here; since we're just now being bound
|
||||
// we don't have any frames or anything yet.
|
||||
LoadSVGImage(PR_FALSE, PR_FALSE);
|
||||
|
||||
return rv;
|
||||
}
|
||||
@ -5433,6 +5434,16 @@ nsSVGFEImageElement::GetStringInfo()
|
||||
NS_ARRAY_LENGTH(sStringInfo));
|
||||
}
|
||||
|
||||
void
|
||||
nsSVGFEImageElement::DidChangeString(PRUint8 aAttrEnum, PRBool aDoSetAttr)
|
||||
{
|
||||
nsSVGFEImageElementBase::DidChangeString(aAttrEnum, aDoSetAttr);
|
||||
|
||||
if (aAttrEnum == HREF) {
|
||||
LoadSVGImage(PR_TRUE, PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// imgIDecoderObserver methods
|
||||
|
||||
@ -5655,8 +5666,6 @@ nsSVGFEDisplacementMapElement::Filter(nsSVGFilterInstance *instance,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(instance->GetSurfaceRect().Size() == instance->GetFilterSpaceSize(),
|
||||
"Surface size optimization should have been disabled, see ComputeNeededSourceBBoxes");
|
||||
PRInt32 width = instance->GetSurfaceWidth();
|
||||
PRInt32 height = instance->GetSurfaceHeight();
|
||||
|
||||
|
@ -99,7 +99,7 @@ public:
|
||||
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
|
||||
|
||||
protected:
|
||||
void GetSrc(nsAString& src);
|
||||
nsresult LoadSVGImage(PRBool aForce, PRBool aNotify);
|
||||
|
||||
virtual LengthAttributesInfo GetLengthInfo();
|
||||
virtual StringAttributesInfo GetStringInfo();
|
||||
@ -255,13 +255,6 @@ nsSVGImageElement::DidChangeString(PRUint8 aAttrEnum, PRBool aDoSetAttr)
|
||||
nsSVGImageElementBase::DidChangeString(aAttrEnum, aDoSetAttr);
|
||||
|
||||
if (aAttrEnum == HREF) {
|
||||
nsAutoString href;
|
||||
GetSrc(href);
|
||||
|
||||
#ifdef DEBUG_tor
|
||||
fprintf(stderr, "nsSVGImageElement - URI <%s>\n", ToNewCString(href));
|
||||
#endif
|
||||
|
||||
// If caller is not chrome and dom.disable_image_src_set is true,
|
||||
// prevent setting image.src by exiting early
|
||||
if (nsContentUtils::GetBoolPref("dom.disable_image_src_set") &&
|
||||
@ -269,25 +262,25 @@ nsSVGImageElement::DidChangeString(PRUint8 aAttrEnum, PRBool aDoSetAttr)
|
||||
return;
|
||||
}
|
||||
|
||||
LoadImage(href, PR_TRUE, PR_TRUE);
|
||||
LoadSVGImage(PR_TRUE, PR_TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
void nsSVGImageElement::GetSrc(nsAString& src)
|
||||
nsresult
|
||||
nsSVGImageElement::LoadSVGImage(PRBool aForce, PRBool aNotify)
|
||||
{
|
||||
// resolve href attribute
|
||||
|
||||
nsCOMPtr<nsIURI> baseURI = GetBaseURI();
|
||||
|
||||
nsAutoString relURIStr(mStringAttributes[HREF].GetAnimValue());
|
||||
relURIStr.Trim(" \t\n\r");
|
||||
nsAutoString href(mStringAttributes[HREF].GetAnimValue());
|
||||
href.Trim(" \t\n\r");
|
||||
|
||||
if (baseURI && !relURIStr.IsEmpty())
|
||||
NS_MakeAbsoluteURI(src, relURIStr, baseURI);
|
||||
else
|
||||
src = relURIStr;
|
||||
if (baseURI && !href.IsEmpty())
|
||||
NS_MakeAbsoluteURI(href, href, baseURI);
|
||||
|
||||
return LoadImage(href, aForce, aNotify);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
@ -305,12 +298,9 @@ nsSVGImageElement::BindToTree(nsIDocument* aDocument, nsIContent* aParent,
|
||||
|
||||
// Our base URI may have changed; claim that our URI changed, and the
|
||||
// nsImageLoadingContent will decide whether a new image load is warranted.
|
||||
nsAutoString href;
|
||||
if (GetAttr(kNameSpaceID_XLink, nsGkAtoms::href, href)) {
|
||||
// Note: no need to notify here; since we're just now being bound
|
||||
// we don't have any frames or anything yet.
|
||||
LoadImage(href, PR_FALSE, PR_FALSE);
|
||||
}
|
||||
// Note: no need to notify here; since we're just now being bound
|
||||
// we don't have any frames or anything yet.
|
||||
LoadSVGImage(PR_FALSE, PR_FALSE);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -79,6 +79,7 @@ public:
|
||||
virtual already_AddRefed<nsIURI> GetScriptURI();
|
||||
virtual void GetScriptText(nsAString& text);
|
||||
virtual void GetScriptCharset(nsAString& charset);
|
||||
virtual PRBool GetScriptDeferred();
|
||||
|
||||
// nsScriptElement
|
||||
virtual PRBool HasScriptContent();
|
||||
@ -212,6 +213,12 @@ nsSVGScriptElement::GetScriptCharset(nsAString& charset)
|
||||
charset.Truncate();
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsSVGScriptElement::GetScriptDeferred()
|
||||
{
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// nsScriptElement methods
|
||||
|
||||
|
@ -81,8 +81,7 @@ nsSVGSwitchElement::MaybeInvalidate()
|
||||
PRUint32 count = GetChildCount();
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
nsIContent * child = GetChildAt(i);
|
||||
if (child->IsNodeOfType(nsINode::eELEMENT) &&
|
||||
NS_SVG_PassesConditionalProcessingTests(child)) {
|
||||
if (NS_SVG_PassesConditionalProcessingTests(child)) {
|
||||
|
||||
if (mActiveChild == child) {
|
||||
return;
|
||||
@ -108,8 +107,7 @@ nsSVGSwitchElement::UpdateActiveChild()
|
||||
PRUint32 count = GetChildCount();
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
nsIContent * child = GetChildAt(i);
|
||||
if (child->IsNodeOfType(nsINode::eELEMENT) &&
|
||||
NS_SVG_PassesConditionalProcessingTests(child)) {
|
||||
if (NS_SVG_PassesConditionalProcessingTests(child)) {
|
||||
mActiveChild = child;
|
||||
return;
|
||||
}
|
||||
|
@ -58,8 +58,8 @@ class nsIAtom;
|
||||
class nsIPrincipal;
|
||||
|
||||
#define NS_IXBLSERVICE_IID \
|
||||
{ 0x98b28f4e, 0x698f, 0x4f77, \
|
||||
{ 0xa8, 0x9e, 0x65, 0xf5, 0xd0, 0xde, 0x6a, 0xbf } }
|
||||
{ 0x8d3b37f5, 0xde7e, 0x4595, \
|
||||
{ 0xb8, 0x56, 0xf7, 0x11, 0xe8, 0xe7, 0xb5, 0x59 } }
|
||||
|
||||
class nsIXBLService : public nsISupports
|
||||
{
|
||||
@ -90,6 +90,7 @@ public:
|
||||
|
||||
// Hooks up the global key event handlers to the document root.
|
||||
NS_IMETHOD AttachGlobalKeyHandler(nsPIDOMEventTarget* aTarget)=0;
|
||||
NS_IMETHOD DetachGlobalKeyHandler(nsPIDOMEventTarget* aTarget)=0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -700,6 +700,10 @@ nsXBLService::AttachGlobalKeyHandler(nsPIDOMEventTarget* aTarget)
|
||||
if (!piTarget)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// the listener already exists, so skip this
|
||||
if (contentNode && contentNode->GetProperty(nsGkAtoms::listener))
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMElement> elt(do_QueryInterface(contentNode));
|
||||
|
||||
// Create the key handler
|
||||
@ -720,8 +724,53 @@ nsXBLService::AttachGlobalKeyHandler(nsPIDOMEventTarget* aTarget)
|
||||
target->AddGroupedEventListener(NS_LITERAL_STRING("keypress"), handler,
|
||||
PR_FALSE, systemGroup);
|
||||
|
||||
// Release. Do this so that only the event receiver holds onto the key handler.
|
||||
if (contentNode)
|
||||
return contentNode->SetProperty(nsGkAtoms::listener, handler,
|
||||
nsPropertyTable::SupportsDtorFunc, PR_TRUE);
|
||||
|
||||
// release the handler. The reference will be maintained by the event target,
|
||||
// and, if there is a content node, the property.
|
||||
NS_RELEASE(handler);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//
|
||||
// DetachGlobalKeyHandler
|
||||
//
|
||||
// Removes a key handler added by DeatchGlobalKeyHandler.
|
||||
//
|
||||
NS_IMETHODIMP
|
||||
nsXBLService::DetachGlobalKeyHandler(nsPIDOMEventTarget* aTarget)
|
||||
{
|
||||
nsCOMPtr<nsPIDOMEventTarget> piTarget = aTarget;
|
||||
nsCOMPtr<nsIContent> contentNode(do_QueryInterface(aTarget));
|
||||
if (!contentNode) // detaching is only supported for content nodes
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// Only attach if we're really in a document
|
||||
nsCOMPtr<nsIDocument> doc = contentNode->GetCurrentDoc();
|
||||
if (doc)
|
||||
piTarget = do_QueryInterface(doc);
|
||||
if (!piTarget)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsIDOMEventListener* handler =
|
||||
static_cast<nsIDOMEventListener*>(contentNode->GetProperty(nsGkAtoms::listener));
|
||||
if (!handler)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsCOMPtr<nsIDOMEventGroup> systemGroup;
|
||||
piTarget->GetSystemEventGroup(getter_AddRefs(systemGroup));
|
||||
nsCOMPtr<nsIDOM3EventTarget> target = do_QueryInterface(piTarget);
|
||||
|
||||
target->RemoveGroupedEventListener(NS_LITERAL_STRING("keydown"), handler,
|
||||
PR_FALSE, systemGroup);
|
||||
target->RemoveGroupedEventListener(NS_LITERAL_STRING("keyup"), handler,
|
||||
PR_FALSE, systemGroup);
|
||||
target->RemoveGroupedEventListener(NS_LITERAL_STRING("keypress"), handler,
|
||||
PR_FALSE, systemGroup);
|
||||
|
||||
contentNode->DeleteProperty(nsGkAtoms::listener);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -88,6 +88,7 @@ class nsXBLService : public nsIXBLService,
|
||||
|
||||
// Used by XUL key bindings and for window XBL.
|
||||
NS_IMETHOD AttachGlobalKeyHandler(nsPIDOMEventTarget* aTarget);
|
||||
NS_IMETHOD DetachGlobalKeyHandler(nsPIDOMEventTarget* aTarget);
|
||||
|
||||
NS_DECL_NSIOBSERVER
|
||||
|
||||
|
@ -356,6 +356,13 @@ nsXBLWindowKeyHandler::WalkHandlers(nsIDOMEvent* aKeyEvent, nsIAtom* aEventType)
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIContent> content = do_QueryInterface(el);
|
||||
// skip keysets that are disabled
|
||||
if (content && content->AttrValueIs(kNameSpaceID_None, nsGkAtoms::disabled,
|
||||
nsGkAtoms::_true, eCaseMatters)) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
WalkHandlersInternal(aKeyEvent, aEventType, mHandler);
|
||||
|
||||
nsINativeKeyBindings *nativeBindings;
|
||||
|
@ -764,7 +764,6 @@ txMozillaXMLOutput::startHTMLElement(nsIContent* aElement, PRBool aIsHTML)
|
||||
nsresult
|
||||
txMozillaXMLOutput::endHTMLElement(nsIContent* aElement)
|
||||
{
|
||||
nsresult rv;
|
||||
nsIAtom *atom = aElement->Tag();
|
||||
|
||||
if (mTableState == ADDED_TBODY) {
|
||||
@ -809,10 +808,11 @@ txMozillaXMLOutput::endHTMLElement(nsIContent* aElement)
|
||||
|
||||
aElement->GetAttr(kNameSpaceID_None, txHTMLAtoms::href, value);
|
||||
nsCOMPtr<nsIURI> baseURI;
|
||||
rv = NS_NewURI(getter_AddRefs(baseURI), value, nsnull);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_NewURI(getter_AddRefs(baseURI), value, nsnull);
|
||||
|
||||
doc->SetBaseURI(baseURI); // The document checks if it is legal to set this base
|
||||
if (baseURI) {
|
||||
doc->SetBaseURI(baseURI); // The document checks if it is legal to set this base
|
||||
}
|
||||
}
|
||||
else if (mCreatingNewDocument && atom == txHTMLAtoms::meta) {
|
||||
// handle HTTP-EQUIV data
|
||||
|
@ -167,8 +167,6 @@
|
||||
#define XUL_ELEMENT_CONTAINER_CONTENTS_BUILT \
|
||||
(nsXULElement::eContainerContentsBuilt << XUL_ELEMENT_LAZY_STATE_OFFSET)
|
||||
|
||||
class nsIDocShell;
|
||||
|
||||
// Global object maintenance
|
||||
nsICSSParser* nsXULPrototypeElement::sCSSParser = nsnull;
|
||||
nsIXBLService * nsXULElement::gXBLService = nsnull;
|
||||
@ -2118,6 +2116,36 @@ nsXULElement::GetFrameLoader(nsIFrameLoader **aFrameLoader)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsXULElement::SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner)
|
||||
{
|
||||
nsCOMPtr<nsIContent> otherContent(do_QueryInterface(aOtherOwner));
|
||||
NS_ENSURE_TRUE(otherContent, NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
||||
nsXULElement* otherEl = FromContent(otherContent);
|
||||
NS_ENSURE_TRUE(otherEl, NS_ERROR_NOT_IMPLEMENTED);
|
||||
|
||||
if (otherEl == this) {
|
||||
// nothing to do
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsXULSlots *ourSlots = static_cast<nsXULSlots*>(GetExistingDOMSlots());
|
||||
nsXULSlots *otherSlots =
|
||||
static_cast<nsXULSlots*>(otherEl->GetExistingDOMSlots());
|
||||
if (!ourSlots || !ourSlots->mFrameLoader ||
|
||||
!otherSlots || !otherSlots->mFrameLoader) {
|
||||
// Can't handle swapping when there is nothing to swap... yet.
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
return
|
||||
ourSlots->mFrameLoader->SwapWithOtherLoader(otherSlots->mFrameLoader,
|
||||
ourSlots->mFrameLoader,
|
||||
otherSlots->mFrameLoader);
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsXULElement::GetParentTree(nsIDOMXULMultiSelectControlElement** aTreeElement)
|
||||
{
|
||||
|
@ -625,8 +625,8 @@ public:
|
||||
|
||||
nsresult GetStyle(nsIDOMCSSStyleDeclaration** aStyle);
|
||||
|
||||
|
||||
nsresult GetFrameLoader(nsIFrameLoader** aFrameLoader);
|
||||
nsresult SwapFrameLoaders(nsIFrameLoaderOwner* aOtherOwner);
|
||||
|
||||
virtual void RecompileScriptEventListeners();
|
||||
|
||||
@ -664,7 +664,7 @@ protected:
|
||||
nsXULSlots(PtrBits aFlags);
|
||||
virtual ~nsXULSlots();
|
||||
|
||||
nsCOMPtr<nsIFrameLoader> mFrameLoader;
|
||||
nsRefPtr<nsFrameLoader> mFrameLoader;
|
||||
};
|
||||
|
||||
virtual nsINode::nsSlots* CreateSlots();
|
||||
|
@ -441,6 +441,8 @@ nsXULDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel,
|
||||
|
||||
mChannel = aChannel;
|
||||
|
||||
mHaveInputEncoding = PR_TRUE;
|
||||
|
||||
// Get the URI. Note that this should match nsDocShell::OnLoadingSite
|
||||
nsresult rv =
|
||||
NS_GetFinalChannelURI(aChannel, getter_AddRefs(mDocumentURI));
|
||||
@ -1731,6 +1733,14 @@ nsXULDocument::RemoveSubtreeFromDocument(nsIContent* aElement)
|
||||
// document.
|
||||
nsresult rv;
|
||||
|
||||
if (aElement->NodeInfo()->Equals(nsGkAtoms::keyset, kNameSpaceID_XUL)) {
|
||||
nsCOMPtr<nsIXBLService> xblService(do_GetService("@mozilla.org/xbl;1"));
|
||||
if (xblService) {
|
||||
nsCOMPtr<nsPIDOMEventTarget> piTarget(do_QueryInterface(aElement));
|
||||
xblService->DetachGlobalKeyHandler(piTarget);
|
||||
}
|
||||
}
|
||||
|
||||
// 1. Remove any children from the document.
|
||||
PRUint32 count = aElement->GetChildCount();
|
||||
|
||||
|
@ -945,7 +945,7 @@ morkRow::NewRowCellCursor(morkEnv* ev, mdb_pos inPos)
|
||||
{
|
||||
if ( ev->Good() )
|
||||
{
|
||||
cursor->mCursor_Pos = inPos;
|
||||
cursor->mRowCellCursor_Col = inPos;
|
||||
outCursor = cursor;
|
||||
}
|
||||
else
|
||||
|
@ -1190,12 +1190,10 @@ nsDocShell::SetChromeEventHandler(nsIDOMEventTarget* aChromeEventHandler)
|
||||
// Weak reference. Don't addref.
|
||||
mChromeEventHandler = piTarget;
|
||||
|
||||
NS_ASSERTION(!mScriptGlobal,
|
||||
"SetChromeEventHandler() called after the script global "
|
||||
"object was created! This means that the script global "
|
||||
"object in this docshell won't get the right chrome event "
|
||||
"handler. You really don't want to see this assert, FIX "
|
||||
"YOUR CODE!");
|
||||
nsCOMPtr<nsPIDOMWindow> win(do_QueryInterface(mScriptGlobal));
|
||||
if (win) {
|
||||
win->SetChromeEventHandler(piTarget);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -42,8 +42,8 @@ PEParseRuleWSOnly=Whitespace-only string given to be parsed as rule.
|
||||
PEDeclDropped=Declaration dropped.
|
||||
PEDeclSkipped=Skipped to next declaration.
|
||||
PEUnknownProperty=Unknown property '%1$S'.
|
||||
PEPropertyParsingError=Error in parsing value for property '%1$S'.
|
||||
PEExpectEndProperty=Expected end of value for property but found '%1$S'.
|
||||
PEValueParsingError=Error in parsing value for '%1$S'.
|
||||
PEExpectEndValue=Expected end of value but found '%1$S'.
|
||||
PESkipAtRuleEOF=end of unknown at-rule
|
||||
PEUnknownAtRule=Unrecognized at-rule or error parsing at-rule '%1$S'.
|
||||
PECharsetRuleEOF=charset string in @charset rule
|
||||
@ -127,6 +127,8 @@ PEBadDeclOrRuleEnd2=Expected ';' or '}' to terminate declaration but found '%1$S
|
||||
PEInaccessibleProperty2=Cannot specify value for internal property.
|
||||
PECommentEOF=end of comment
|
||||
SEUnterminatedString=Found unclosed string '%1$S'.
|
||||
PEFontDescExpected=Expected font descriptor but found '%1$S'.
|
||||
PEUnknownFontDesc=Unknown descriptor '%1$S' in @font-face rule.
|
||||
PEMQExpectedExpressionStart=Expected '(' to start media query expression but found '%1$S'.
|
||||
PEMQExpressionEOF=contents of media query expression
|
||||
PEMQExpectedFeatureName=Expected media feature name but found '%1$S'.
|
||||
|
@ -96,6 +96,8 @@ public:
|
||||
return mChromeEventHandler;
|
||||
}
|
||||
|
||||
virtual void SetChromeEventHandler(nsPIDOMEventTarget* aChromeEventHandler) = 0;
|
||||
|
||||
PRBool HasMutationListeners(PRUint32 aMutationEventType) const
|
||||
{
|
||||
const nsPIDOMWindow *win;
|
||||
@ -401,6 +403,10 @@ protected:
|
||||
{
|
||||
}
|
||||
|
||||
void SetChromeEventHandlerInternal(nsPIDOMEventTarget* aChromeEventHandler) {
|
||||
mChromeEventHandler = aChromeEventHandler;
|
||||
}
|
||||
|
||||
// These two variables are special in that they're set to the same
|
||||
// value on both the outer window and the current inner window. Make
|
||||
// sure you keep them in sync!
|
||||
|
@ -44,10 +44,10 @@
|
||||
/*
|
||||
* Key pressed / released / typed listener interface.
|
||||
*/
|
||||
// {F14B6491-E95B-11d2-9E85-0060089FE59B}
|
||||
// {93A5A335-AA51-4d32-977D-3680B7722AD5}
|
||||
#define NS_IDOMCOMPOSITIONLISTENER_IID \
|
||||
{ 0xf14b6491, 0xe95b, 0x11d2, \
|
||||
{ 0x9e, 0x85, 0x0, 0x60, 0x8, 0x9f, 0xe5, 0x9b } }
|
||||
{ 0x93a5a335, 0xaa51, 0x4d32, \
|
||||
{ 0x97, 0x7d, 0x36, 0x80, 0xb7, 0x72, 0x2a, 0xd5 } }
|
||||
|
||||
|
||||
class nsIDOMCompositionListener : public nsIDOMEventListener {
|
||||
@ -59,8 +59,6 @@ public:
|
||||
NS_IMETHOD HandleStartComposition(nsIDOMEvent* aCompositionEvent) = 0;
|
||||
NS_IMETHOD HandleEndComposition(nsIDOMEvent* aCompositionEvent) = 0;
|
||||
NS_IMETHOD HandleQueryComposition(nsIDOMEvent* aCompositionEvent) = 0;
|
||||
NS_IMETHOD HandleQueryReconversion(nsIDOMEvent* aCompositionEvent) = 0;
|
||||
NS_IMETHOD HandleQueryCaretRect(nsIDOMEvent* aCompositionEvent) = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsIDOMCompositionListener,
|
||||
|
@ -428,6 +428,10 @@ enum nsDOMClassInfoID {
|
||||
eDOMClassInfo_Geolocation_id,
|
||||
eDOMClassInfo_Geolocator_id,
|
||||
|
||||
// @font-face in CSS
|
||||
eDOMClassInfo_CSSFontFaceRule_id,
|
||||
eDOMClassInfo_CSSFontFaceStyleDecl_id,
|
||||
|
||||
// WhatWG Video Element
|
||||
#if defined(MOZ_MEDIA)
|
||||
eDOMClassInfo_HTMLVideoElement_id,
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user