mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 00:01:50 +00:00
Merge from mozilla-central.
This commit is contained in:
commit
394bc589f0
2
CLOBBER
2
CLOBBER
@ -15,4 +15,4 @@
|
||||
#
|
||||
# Note: The description below will be part of the error message shown to users.
|
||||
#
|
||||
Bug 755724 - Move browser application in a subdirectory
|
||||
Bug 836654 - IndexedDB test failures without clobber
|
||||
|
@ -9,16 +9,11 @@ VPATH = @srcdir@
|
||||
|
||||
LIBRARY_NAME = AccessibleMarshal
|
||||
MODULE = accessibility
|
||||
XPIDL_MODULE = accessibility-msaa
|
||||
GRE_MODULE = 1
|
||||
DEFFILE = $(win_srcdir)/AccessibleMarshal.def
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
XPIDLSRCS = \
|
||||
nsIWinAccessNode.idl \
|
||||
$(NULL)
|
||||
|
||||
DEFINES += -DREGISTER_PROXY_DLL
|
||||
|
||||
GARBAGE += $(MIDL_GENERATED_FILES) done_gen dlldata.c
|
||||
|
@ -1,20 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
%{C++
|
||||
#include "guiddef.h"
|
||||
%}
|
||||
|
||||
[ref] native MSCOMIIDRef(IID);
|
||||
|
||||
[uuid(63efe9c5-2610-4d2f-861b-e4ddfe1b70d9)]
|
||||
interface nsIWinAccessNode : nsISupports
|
||||
{
|
||||
voidPtr queryNativeInterface([const] in MSCOMIIDRef aIID);
|
||||
};
|
||||
|
@ -272,6 +272,16 @@ aria::MapToState(EStateRule aRule, dom::Element* aElement, uint64_t* aState)
|
||||
return true;
|
||||
}
|
||||
|
||||
case eARIAReadonlyOrEditableIfDefined:
|
||||
{
|
||||
static const TokenTypeData data(
|
||||
nsGkAtoms::aria_readonly, eBoolType,
|
||||
0, states::READONLY, states::EDITABLE);
|
||||
|
||||
MapTokenType(aElement, aState, data);
|
||||
return true;
|
||||
}
|
||||
|
||||
case eARIARequired:
|
||||
{
|
||||
static const TokenTypeData data(
|
||||
|
@ -39,6 +39,7 @@ enum EStateRule
|
||||
eARIAPressed,
|
||||
eARIAReadonly,
|
||||
eARIAReadonlyOrEditable,
|
||||
eARIAReadonlyOrEditableIfDefined,
|
||||
eARIARequired,
|
||||
eARIASelectable,
|
||||
eReadonlyUntilEditable,
|
||||
|
@ -53,7 +53,7 @@ AccEvent::CreateXPCOMObject()
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// AccEvent cycle collection
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_NATIVE_1(AccEvent, mAccessible)
|
||||
NS_IMPL_CYCLE_COLLECTION_1(AccEvent, mAccessible)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(AccEvent, AddRef)
|
||||
NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AccEvent, Release)
|
||||
|
@ -178,7 +178,7 @@ static nsRoleMapEntry sWAIRoleMaps[] =
|
||||
eSelect | eTable,
|
||||
states::FOCUSABLE,
|
||||
eARIAMultiSelectable,
|
||||
eARIAReadonly
|
||||
eARIAReadonlyOrEditable
|
||||
},
|
||||
{ // gridcell
|
||||
&nsGkAtoms::gridcell,
|
||||
@ -190,7 +190,7 @@ static nsRoleMapEntry sWAIRoleMaps[] =
|
||||
eTableCell,
|
||||
kNoReqStates,
|
||||
eARIASelectable,
|
||||
eARIAReadonly
|
||||
eARIAReadonlyOrEditableIfDefined
|
||||
},
|
||||
{ // group
|
||||
&nsGkAtoms::group,
|
||||
|
@ -15,7 +15,6 @@
|
||||
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIPersistentProperties2.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsPoint.h"
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "RootAccessible.h"
|
||||
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
@ -82,14 +81,13 @@ nsAccessNode::Shutdown()
|
||||
RootAccessible*
|
||||
nsAccessNode::RootAccessible() const
|
||||
{
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
|
||||
nsCoreUtils::GetDocShellTreeItemFor(GetNode());
|
||||
NS_ASSERTION(docShellTreeItem, "No docshell tree item for mContent");
|
||||
if (!docShellTreeItem) {
|
||||
nsCOMPtr<nsIDocShell> docShell = nsCoreUtils::GetDocShellFor(GetNode());
|
||||
NS_ASSERTION(docShell, "No docshell for mContent");
|
||||
if (!docShell) {
|
||||
return nullptr;
|
||||
}
|
||||
nsCOMPtr<nsIDocShellTreeItem> root;
|
||||
docShellTreeItem->GetRootTreeItem(getter_AddRefs(root));
|
||||
docShell->GetRootTreeItem(getter_AddRefs(root));
|
||||
NS_ASSERTION(root, "No root content tree item");
|
||||
if (!root) {
|
||||
return nullptr;
|
||||
|
@ -38,7 +38,6 @@
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
#include "nsITreeBoxObject.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsITreeColumns.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -380,7 +379,7 @@ nsIntPoint
|
||||
nsCoreUtils::GetScreenCoordsForWindow(nsINode *aNode)
|
||||
{
|
||||
nsIntPoint coords(0, 0);
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem(GetDocShellTreeItemFor(aNode));
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem(GetDocShellFor(aNode));
|
||||
if (!treeItem)
|
||||
return coords;
|
||||
|
||||
@ -396,18 +395,15 @@ nsCoreUtils::GetScreenCoordsForWindow(nsINode *aNode)
|
||||
return coords;
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDocShellTreeItem>
|
||||
nsCoreUtils::GetDocShellTreeItemFor(nsINode *aNode)
|
||||
already_AddRefed<nsIDocShell>
|
||||
nsCoreUtils::GetDocShellFor(nsINode *aNode)
|
||||
{
|
||||
if (!aNode)
|
||||
return nullptr;
|
||||
|
||||
nsCOMPtr<nsISupports> container = aNode->OwnerDoc()->GetContainer();
|
||||
nsIDocShellTreeItem *docShellTreeItem = nullptr;
|
||||
if (container)
|
||||
CallQueryInterface(container, &docShellTreeItem);
|
||||
|
||||
return docShellTreeItem;
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
|
||||
return docShell.forget();
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -17,7 +17,7 @@
|
||||
|
||||
class nsRange;
|
||||
class nsIFrame;
|
||||
class nsIDocShellTreeItem;
|
||||
class nsIDocShell;
|
||||
class nsITreeColumn;
|
||||
class nsITreeBoxObject;
|
||||
class nsIWidget;
|
||||
@ -176,10 +176,9 @@ public:
|
||||
static nsIntPoint GetScreenCoordsForWindow(nsINode *aNode);
|
||||
|
||||
/**
|
||||
* Return document shell tree item for the given DOM node.
|
||||
* Return document shell for the given DOM node.
|
||||
*/
|
||||
static already_AddRefed<nsIDocShellTreeItem>
|
||||
GetDocShellTreeItemFor(nsINode *aNode);
|
||||
static already_AddRefed<nsIDocShell> GetDocShellFor(nsINode *aNode);
|
||||
|
||||
/**
|
||||
* Return true if the given document is root document.
|
||||
|
@ -48,6 +48,19 @@ nsTextEquivUtils::GetNameFromSubtree(Accessible* aAccessible,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsTextEquivUtils::GetTextEquivFromSubtree(Accessible* aAccessible,
|
||||
nsString& aTextEquiv)
|
||||
{
|
||||
aTextEquiv.Truncate();
|
||||
|
||||
uint32_t nameRule = GetRoleRule(aAccessible->Role());
|
||||
if (nameRule & eNameFromSubtreeIfReqRule) {
|
||||
AppendFromAccessibleChildren(aAccessible, &aTextEquiv);
|
||||
aTextEquiv.CompressWhitespace();
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTextEquivUtils::GetTextEquivFromIDRefs(Accessible* aAccessible,
|
||||
nsIAtom *aIDRefsAttr,
|
||||
|
@ -53,6 +53,14 @@ public:
|
||||
static nsresult GetNameFromSubtree(Accessible* aAccessible,
|
||||
nsAString& aName);
|
||||
|
||||
/**
|
||||
* Calculates text equivalent from the subtree. Similar to GetNameFromSubtree.
|
||||
* The difference it returns not empty result for things like HTML p, i.e.
|
||||
* if the role has eNameFromSubtreeIfReq rule.
|
||||
*/
|
||||
static void GetTextEquivFromSubtree(Accessible* aAccessible,
|
||||
nsString& aTextEquiv);
|
||||
|
||||
/**
|
||||
* Calculates text equivalent for the given accessible from its IDRefs
|
||||
* attribute (like aria-labelledby or aria-describedby).
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include "RootAccessible.h"
|
||||
#include "States.h"
|
||||
#include "StyleInfo.h"
|
||||
#include "TableAccessible.h"
|
||||
#include "TableCellAccessible.h"
|
||||
#include "TreeWalker.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
@ -1597,6 +1599,22 @@ Accessible::ApplyARIAState(uint64_t* aState) const
|
||||
if (aria::MapToState(mRoleMapEntry->attributeMap1, element, aState) &&
|
||||
aria::MapToState(mRoleMapEntry->attributeMap2, element, aState))
|
||||
aria::MapToState(mRoleMapEntry->attributeMap3, element, aState);
|
||||
|
||||
// ARIA gridcell inherits editable/readonly states from the grid until it's
|
||||
// overridden.
|
||||
if (mRoleMapEntry->Is(nsGkAtoms::gridcell) &&
|
||||
!(*aState & (states::READONLY | states::EDITABLE))) {
|
||||
const TableCellAccessible* cell = AsTableCell();
|
||||
if (cell) {
|
||||
TableAccessible* table = cell->Table();
|
||||
if (table) {
|
||||
Accessible* grid = table->AsAccessible();
|
||||
uint64_t gridState = 0;
|
||||
grid->ApplyARIAState(&gridState);
|
||||
*aState |= (gridState & (states::READONLY | states::EDITABLE));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -1652,7 +1670,7 @@ Accessible::Value(nsString& aValue)
|
||||
}
|
||||
|
||||
if (option)
|
||||
nsTextEquivUtils::GetNameFromSubtree(option, aValue);
|
||||
nsTextEquivUtils::GetTextEquivFromSubtree(option, aValue);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -514,6 +514,8 @@ public:
|
||||
virtual TableAccessible* AsTable() { return nullptr; }
|
||||
|
||||
virtual TableCellAccessible* AsTableCell() { return nullptr; }
|
||||
const TableCellAccessible* AsTableCell() const
|
||||
{ return const_cast<Accessible*>(this)->AsTableCell(); }
|
||||
|
||||
bool IsTableRow() const { return HasGenericType(eTableRow); }
|
||||
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsICommandManager.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsIDOMAttr.h"
|
||||
#include "nsIDOMCharacterData.h"
|
||||
@ -185,14 +184,13 @@ DocAccessible::Name(nsString& aName)
|
||||
role
|
||||
DocAccessible::NativeRole()
|
||||
{
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
|
||||
nsCoreUtils::GetDocShellTreeItemFor(mDocumentNode);
|
||||
if (docShellTreeItem) {
|
||||
nsCOMPtr<nsIDocShell> docShell = nsCoreUtils::GetDocShellFor(mDocumentNode);
|
||||
if (docShell) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
|
||||
docShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
|
||||
docShell->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
|
||||
int32_t itemType;
|
||||
docShellTreeItem->GetItemType(&itemType);
|
||||
if (sameTypeRoot == docShellTreeItem) {
|
||||
docShell->GetItemType(&itemType);
|
||||
if (sameTypeRoot == docShell) {
|
||||
// Root of content or chrome tree
|
||||
if (itemType == nsIDocShellTreeItem::typeChrome)
|
||||
return roles::CHROME_WINDOW;
|
||||
|
@ -1482,9 +1482,8 @@ HyperTextAccessible::GetEditor() const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
|
||||
nsCoreUtils::GetDocShellTreeItemFor(mContent);
|
||||
nsCOMPtr<nsIEditingSession> editingSession(do_GetInterface(docShellTreeItem));
|
||||
nsCOMPtr<nsIDocShell> docShell = nsCoreUtils::GetDocShellFor(mContent);
|
||||
nsCOMPtr<nsIEditingSession> editingSession(do_GetInterface(docShell));
|
||||
if (!editingSession)
|
||||
return nullptr; // No editing session interface
|
||||
|
||||
|
@ -108,11 +108,10 @@ RootAccessible::GetChromeFlags()
|
||||
// Return the flag set for the top level window as defined
|
||||
// by nsIWebBrowserChrome::CHROME_WINDOW_[FLAGNAME]
|
||||
// Not simple: nsIXULWindow is not just a QI from nsIDOMWindow
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem =
|
||||
nsCoreUtils::GetDocShellTreeItemFor(mDocumentNode);
|
||||
NS_ENSURE_TRUE(treeItem, 0);
|
||||
nsCOMPtr<nsIDocShell> docShell = nsCoreUtils::GetDocShellFor(mDocumentNode);
|
||||
NS_ENSURE_TRUE(docShell, 0);
|
||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||
treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
|
||||
docShell->GetTreeOwner(getter_AddRefs(treeOwner));
|
||||
NS_ENSURE_TRUE(treeOwner, 0);
|
||||
nsCOMPtr<nsIXULWindow> xulWin(do_GetInterface(treeOwner));
|
||||
if (!xulWin) {
|
||||
|
@ -45,18 +45,7 @@ nsAccessNodeWrap::~nsAccessNodeWrap()
|
||||
// nsISupports methods
|
||||
//-----------------------------------------------------
|
||||
|
||||
NS_IMPL_ISUPPORTS_INHERITED1(nsAccessNodeWrap, nsAccessNode, nsIWinAccessNode)
|
||||
|
||||
//-----------------------------------------------------
|
||||
// nsIWinAccessNode methods
|
||||
//-----------------------------------------------------
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsAccessNodeWrap::QueryNativeInterface(REFIID aIID, void** aInstancePtr)
|
||||
{
|
||||
// XXX Wrong for E_NOINTERFACE
|
||||
return static_cast<nsresult>(QueryInterface(aIID, aInstancePtr));
|
||||
}
|
||||
NS_IMPL_ISUPPORTS_INHERITED0(nsAccessNodeWrap, nsAccessNode)
|
||||
|
||||
STDMETHODIMP nsAccessNodeWrap::QueryInterface(REFIID iid, void** ppv)
|
||||
{
|
||||
@ -88,15 +77,14 @@ nsAccessNodeWrap::QueryService(REFGUID guidService, REFIID iid, void** ppv)
|
||||
if (iid != IID_IAccessible)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellTreeItem =
|
||||
nsCoreUtils::GetDocShellTreeItemFor(mContent);
|
||||
if (!docShellTreeItem)
|
||||
nsCOMPtr<nsIDocShell> docShell = nsCoreUtils::GetDocShellFor(mContent);
|
||||
if (!docShell)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
// Walk up the parent chain without crossing the boundary at which item
|
||||
// types change, preventing us from walking up out of tab content.
|
||||
nsCOMPtr<nsIDocShellTreeItem> root;
|
||||
docShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(root));
|
||||
docShell->GetSameTypeRootTreeItem(getter_AddRefs(root));
|
||||
if (!root)
|
||||
return E_UNEXPECTED;
|
||||
|
||||
@ -122,12 +110,12 @@ nsAccessNodeWrap::QueryService(REFGUID guidService, REFIID iid, void** ppv)
|
||||
// Can get to IAccessibleApplication from any node via QS
|
||||
if (guidService == IID_IAccessibleApplication ||
|
||||
(Compatibility::IsJAWS() && iid == IID_IAccessibleApplication)) {
|
||||
ApplicationAccessible* applicationAcc = ApplicationAcc();
|
||||
ApplicationAccessibleWrap* applicationAcc =
|
||||
static_cast<ApplicationAccessibleWrap*>(ApplicationAcc());
|
||||
if (!applicationAcc)
|
||||
return E_NOINTERFACE;
|
||||
|
||||
nsresult rv = applicationAcc->QueryNativeInterface(iid, ppv);
|
||||
return NS_SUCCEEDED(rv) ? S_OK : E_NOINTERFACE;
|
||||
return applicationAcc->QueryInterface(iid, ppv);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIAccessible.h"
|
||||
#include "nsIAccessibleEvent.h"
|
||||
#include "nsIWinAccessNode.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsAccessNode.h"
|
||||
@ -55,12 +54,10 @@ namespace a11y {
|
||||
#endif
|
||||
|
||||
class nsAccessNodeWrap : public nsAccessNode,
|
||||
public nsIWinAccessNode,
|
||||
public IServiceProvider
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIWINACCESSNODE
|
||||
|
||||
public: // construction, destruction
|
||||
nsAccessNodeWrap(nsIContent* aContent, DocAccessible* aDoc);
|
||||
|
@ -43,59 +43,6 @@ nsWinUtils::GetComputedStyleDeclaration(nsIContent* aContent)
|
||||
return cssDecl.forget();
|
||||
}
|
||||
|
||||
HRESULT
|
||||
nsWinUtils::ConvertToIA2Array(nsIArray *aGeckoArray, IUnknown ***aIA2Array,
|
||||
long *aIA2ArrayLen)
|
||||
{
|
||||
*aIA2Array = NULL;
|
||||
*aIA2ArrayLen = 0;
|
||||
|
||||
if (!aGeckoArray)
|
||||
return S_FALSE;
|
||||
|
||||
uint32_t length = 0;
|
||||
nsresult rv = aGeckoArray->GetLength(&length);
|
||||
if (NS_FAILED(rv))
|
||||
return GetHRESULT(rv);
|
||||
|
||||
if (length == 0)
|
||||
return S_FALSE;
|
||||
|
||||
*aIA2Array =
|
||||
static_cast<IUnknown**>(::CoTaskMemAlloc((length) * sizeof(IUnknown*)));
|
||||
if (!*aIA2Array)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
uint32_t idx = 0;
|
||||
for (; idx < length; ++idx) {
|
||||
nsCOMPtr<nsIWinAccessNode> winAccessNode =
|
||||
do_QueryElementAt(aGeckoArray, idx, &rv);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
void *instancePtr = NULL;
|
||||
nsresult rv = winAccessNode->QueryNativeInterface(IID_IUnknown,
|
||||
&instancePtr);
|
||||
if (NS_FAILED(rv))
|
||||
break;
|
||||
|
||||
(*aIA2Array)[idx] = static_cast<IUnknown*>(instancePtr);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
for (uint32_t idx2 = 0; idx2 < idx; idx2++) {
|
||||
(*aIA2Array)[idx2]->Release();
|
||||
(*aIA2Array)[idx2] = NULL;
|
||||
}
|
||||
|
||||
::CoTaskMemFree(*aIA2Array);
|
||||
return GetHRESULT(rv);
|
||||
}
|
||||
|
||||
*aIA2ArrayLen = length;
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsWinUtils::MaybeStartWindowEmulation()
|
||||
{
|
||||
|
@ -30,13 +30,6 @@ public:
|
||||
static already_AddRefed<nsIDOMCSSStyleDeclaration>
|
||||
GetComputedStyleDeclaration(nsIContent* aContent);
|
||||
|
||||
/**
|
||||
* Convert nsIArray array of accessible objects to an array of IUnknown*
|
||||
* objects used in IA2 methods.
|
||||
*/
|
||||
static HRESULT ConvertToIA2Array(nsIArray *aCollection,
|
||||
IUnknown ***aAccessibles, long *aCount);
|
||||
|
||||
/**
|
||||
* Start window emulation if presence of specific AT is detected.
|
||||
*/
|
||||
|
@ -10,7 +10,6 @@
|
||||
#include "AccessibleHyperlink_i.c"
|
||||
|
||||
#include "AccessibleWrap.h"
|
||||
#include "nsIWinAccessNode.h"
|
||||
|
||||
using namespace mozilla::a11y;
|
||||
|
||||
|
@ -45,17 +45,12 @@ ia2AccessibleHypertext::get_hyperlink(long aLinkIndex,
|
||||
return CO_E_OBJNOTCONNECTED;
|
||||
|
||||
Accessible* hyperLink = hyperText->GetLinkAt(aLinkIndex);
|
||||
nsCOMPtr<nsIWinAccessNode> winAccessNode(do_QueryObject(hyperLink));
|
||||
if (!winAccessNode)
|
||||
if (!hyperText)
|
||||
return E_FAIL;
|
||||
|
||||
void *instancePtr = NULL;
|
||||
nsresult rv = winAccessNode->QueryNativeInterface(IID_IAccessibleHyperlink,
|
||||
&instancePtr);
|
||||
if (NS_FAILED(rv))
|
||||
return E_FAIL;
|
||||
|
||||
*aHyperlink = static_cast<IAccessibleHyperlink*>(instancePtr);
|
||||
*aHyperlink =
|
||||
static_cast<IAccessibleHyperlink*>(static_cast<AccessibleWrap*>(hyperLink));
|
||||
(*aHyperlink)->AddRef();
|
||||
return S_OK;
|
||||
|
||||
A11Y_TRYBLOCK_END
|
||||
|
@ -163,7 +163,11 @@ ia2AccessibleRelation::get_target(long aTargetIndex, IUnknown **aTarget)
|
||||
if (aTargetIndex < 0 || (uint32_t)aTargetIndex >= mTargets.Length() || !aTarget)
|
||||
return E_INVALIDARG;
|
||||
|
||||
mTargets[aTargetIndex]->QueryNativeInterface(IID_IUnknown, (void**) aTarget);
|
||||
AccessibleWrap* target =
|
||||
static_cast<AccessibleWrap*>(mTargets[aTargetIndex].get());
|
||||
*aTarget = static_cast<IAccessible*>(target);
|
||||
(*aTarget)->AddRef();
|
||||
|
||||
return S_OK;
|
||||
|
||||
A11Y_TRYBLOCK_END
|
||||
|
@ -171,6 +171,7 @@
|
||||
testName("ctrlvalue_scrollbar:input", "foo 5 baz");
|
||||
testName("ctrlvalue_slider:input", "foo 5 baz");
|
||||
testName("ctrlvalue_spinbutton:input", "foo 5 baz");
|
||||
testName("ctrlvalue_combobox:input", "foo 5 baz");
|
||||
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
@ -270,6 +271,11 @@
|
||||
title="Text is jammed with control's text in name computation">
|
||||
Bug 823927
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=835666"
|
||||
title="ARIA combobox selected value is not a part of name computation">
|
||||
Bug 835666
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
@ -505,6 +511,20 @@
|
||||
baz
|
||||
</label>
|
||||
|
||||
<input type="checkbox" id="ctrlvalue_combobox:input">
|
||||
<label for="ctrlvalue_combobox:input">
|
||||
foo
|
||||
<div role="combobox">
|
||||
<div role="textbox"></div>
|
||||
<ul role="listbox" style="list-style-type: none;">
|
||||
<li role="option">1</li>
|
||||
<li role="option" aria-selected="true">5</li>
|
||||
<li role="option">3</li>
|
||||
</ul>
|
||||
</div>
|
||||
baz
|
||||
</label>
|
||||
|
||||
<!-- a label with a nested control in the start, middle and end -->
|
||||
<form>
|
||||
<!-- at the start (without and with whitespaces) -->
|
||||
|
@ -110,6 +110,20 @@
|
||||
// aria-readonly
|
||||
testStates("aria_readonly_textbox", STATE_READONLY);
|
||||
|
||||
// readonly/editable on grid and gridcell
|
||||
testStates("aria_grid_default", 0, EXT_STATE_EDITABLE,
|
||||
STATE_READONLY, 0);
|
||||
testStates("aria_grid_default_cell_readonly", STATE_READONLY, 0,
|
||||
0, EXT_STATE_EDITABLE);
|
||||
testStates("aria_grid_default_cell_inherited", 0, EXT_STATE_EDITABLE,
|
||||
STATE_READONLY, 0);
|
||||
testStates("aria_grid_readonly", STATE_READONLY, 0,
|
||||
0, EXT_STATE_EDITABLE);
|
||||
testStates("aria_grid_readonly_cell_editable", 0, EXT_STATE_EDITABLE,
|
||||
STATE_READONLY, 0);
|
||||
testStates("aria_grid_readonly_cell_inherited", STATE_READONLY, 0,
|
||||
0, EXT_STATE_EDITABLE);
|
||||
|
||||
// aria-selectable
|
||||
testStates("aria_selectable_listitem", STATE_SELECTABLE | STATE_SELECTED);
|
||||
|
||||
@ -230,6 +244,11 @@
|
||||
title="fix default horizontal / vertical state of role=scrollbar and ensure only one of horizontal / vertical states is exposed">
|
||||
Mozilla Bug 762876
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=835121
|
||||
title="ARIA grid should be editable by default">
|
||||
Mozilla Bug 835121
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
@ -265,7 +284,26 @@
|
||||
<div id="aria_multiline_textbox" role="textbox" aria-multiline="true"></div>
|
||||
<div id="aria_multiselectable_listbox" role="listbox" aria-multiselectable="true"></div>
|
||||
<div id="aria_pressed_button" role="button" aria-pressed="true">Button</div>
|
||||
<div id="aria_readonly_textbox" role="textbox" aria-readonly="true">This text should be readonly</div>
|
||||
|
||||
<div id="aria_readonly_textbox"
|
||||
role="textbox" aria-readonly="true">This text should be readonly</div>
|
||||
|
||||
<div id="aria_grid_default" role="grid">
|
||||
<div role="row">
|
||||
<div id="aria_grid_default_cell_readonly"
|
||||
role="gridcell" aria-readonly="true">gridcell1</div>
|
||||
<div id="aria_grid_default_cell_inherited"
|
||||
role="gridcell">gridcell2</div>
|
||||
</div>
|
||||
|
||||
<div id="aria_grid_readonly" role="grid" aria-readonly="true">
|
||||
<div role="row">
|
||||
<div id="aria_grid_readonly_cell_editable"
|
||||
role="gridcell" aria-readonly="false">gridcell1</div>
|
||||
<div id="aria_grid_readonly_cell_inherited"
|
||||
role="gridcell">gridcell2</div>
|
||||
</div>
|
||||
|
||||
<div role="listbox">
|
||||
<div id="aria_selectable_listitem" role="option" aria-selected="true">Item1</div>
|
||||
</div>
|
||||
@ -313,7 +351,7 @@
|
||||
<a id="aria_application_link" role="application" href="foo">app</a>
|
||||
<a id="aria_main_link" role="main" href="foo">main</a>
|
||||
<a id="aria_navigation_link" role="navigation" href="foo">nav</a>
|
||||
|
||||
|
||||
<!-- landmarks: anchors -->
|
||||
<a id="aria_application_anchor" role="application" name="app_anchor">app</a>
|
||||
<a id="aria_main_anchor" role="main" name="main_anchor">main</a>
|
||||
|
@ -11,13 +11,9 @@ include $(topsrcdir)/config/config.mk
|
||||
|
||||
TEST_DIRS += test
|
||||
|
||||
COMMONJS_FILES = \
|
||||
source/lib/toolkit \
|
||||
source/lib/sdk \
|
||||
$(NULL)
|
||||
|
||||
COMMONJS_DEST = $(FINAL_TARGET)/modules/commonjs
|
||||
INSTALL_TARGETS += COMMONJS
|
||||
libs::
|
||||
$(PYTHON) $(srcdir)/copy_source.py $(topsrcdir) $(srcdir)/source/lib $(FINAL_TARGET)/modules/commonjs >copy_source.mk
|
||||
$(MAKE) -f copy_source.mk libs
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
|
46
addon-sdk/copy_source.py
Normal file
46
addon-sdk/copy_source.py
Normal file
@ -0,0 +1,46 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
if len(sys.argv) != 4:
|
||||
print >> sys.stderr, "Usage: copy_source.py " \
|
||||
"<topsrcdir> <source directory> <target directory>"
|
||||
sys.exit(1)
|
||||
|
||||
topsrcdir = sys.argv[1]
|
||||
source_dir = sys.argv[2]
|
||||
target_dir = sys.argv[3]
|
||||
|
||||
print """
|
||||
DEPTH = ..
|
||||
topsrcdir = %(topsrcdir)s
|
||||
srcdir = %(topsrcdir)s/addon-sdk
|
||||
VPATH = %(topsrcdir)s/addon-sdk
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
""" % {'topsrcdir': topsrcdir}
|
||||
|
||||
real_source = source_dir.replace('/', os.sep)
|
||||
if not os.path.exists(real_source):
|
||||
print >> sys.stderr, "Error: Missing source file %s" % real_source
|
||||
sys.exit(1)
|
||||
elif not os.path.isdir(real_source):
|
||||
print >> sys.stderr, "Error: Source %s is not a directory" % real_source
|
||||
sys.exit(1)
|
||||
for dirpath, dirnames, filenames in os.walk(real_source):
|
||||
if not filenames:
|
||||
continue
|
||||
dirpath = dirpath.replace(os.sep, '/')
|
||||
relative = dirpath[len(source_dir):]
|
||||
varname = "COMMONJS%s" % relative.replace('/', '_')
|
||||
print "%s_FILES = \\" % varname
|
||||
for name in filenames:
|
||||
print " %s/%s \\" % (dirpath, name)
|
||||
print " $(NULL)"
|
||||
print "%s_DEST = %s%s" % (varname, target_dir, relative)
|
||||
print "INSTALL_TARGETS += %s\n" % varname
|
||||
|
||||
print "include $(topsrcdir)/config/rules.mk"
|
@ -38,8 +38,8 @@ Bugs
|
||||
|
||||
* file a bug: https://bugzilla.mozilla.org/enter_bug.cgi?product=Add-on%20SDK
|
||||
|
||||
|
||||
Style Guidelines
|
||||
--------------------
|
||||
|
||||
* https://github.com/mozilla/addon-sdk/wiki/Coding-style-guide
|
||||
* https://github.com/mozilla/addon-sdk/wiki/Coding-style-guide
|
||||
|
||||
|
@ -18,7 +18,7 @@
|
||||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>18.0</em:minVersion>
|
||||
<em:maxVersion>21.0a1</em:maxVersion>
|
||||
<em:maxVersion>20.*</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
|
@ -1,7 +1,6 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
"use strict";
|
||||
|
||||
module.metadata = {
|
||||
@ -14,7 +13,7 @@ const { ns } = require("./core/namespace");
|
||||
const { validateOptions, getTypeOf } = require("./deprecated/api-utils");
|
||||
const { URL } = require("./url");
|
||||
const { WindowTracker, browserWindowIterator } = require("./deprecated/window-utils");
|
||||
const { isBrowser } = require("./window/utils");
|
||||
const { isBrowser, getInnerId } = require("./window/utils");
|
||||
const { Ci } = require("chrome");
|
||||
const { MatchPattern } = require("./page-mod/match-pattern");
|
||||
const { Worker } = require("./content/worker");
|
||||
@ -325,11 +324,11 @@ function hasMatchingContext(contexts, popupNode) {
|
||||
}
|
||||
|
||||
// Gets the matched context from any worker for this item. If there is no worker
|
||||
// or no matched context then returns null.
|
||||
// or no matched context then returns false.
|
||||
function getCurrentWorkerContext(item, popupNode) {
|
||||
let worker = getItemWorkerForWindow(item, popupNode.ownerDocument.defaultView);
|
||||
if (!worker)
|
||||
return null;
|
||||
if (!worker || !worker.anyContextListeners())
|
||||
return true;
|
||||
return worker.getMatchedContext(popupNode);
|
||||
}
|
||||
|
||||
@ -346,18 +345,10 @@ function isItemVisible(item, popupNode, defaultVisibility) {
|
||||
return false;
|
||||
|
||||
let context = getCurrentWorkerContext(item, popupNode);
|
||||
if (typeof(context) === "string")
|
||||
if (typeof(context) === "string" && context != "")
|
||||
item.label = context;
|
||||
|
||||
return context !== false;
|
||||
}
|
||||
|
||||
// Destroys any item's content scripts workers associated with the given window
|
||||
function destroyItemWorkerForWindow(item, window) {
|
||||
let worker = internal(item).workerMap.get(window);
|
||||
if (worker)
|
||||
worker.destroy();
|
||||
internal(item).workerMap.delete(window);
|
||||
return !!context;
|
||||
}
|
||||
|
||||
// Gets the item's content script worker for a window, creating one if necessary
|
||||
@ -367,7 +358,8 @@ function getItemWorkerForWindow(item, window) {
|
||||
if (!item.contentScript && !item.contentScriptFile)
|
||||
return null;
|
||||
|
||||
let worker = internal(item).workerMap.get(window);
|
||||
let id = getInnerId(window);
|
||||
let worker = internal(item).workerMap.get(id);
|
||||
|
||||
if (worker)
|
||||
return worker;
|
||||
@ -380,11 +372,11 @@ function getItemWorkerForWindow(item, window) {
|
||||
emit(item, "message", msg);
|
||||
},
|
||||
onDetach: function() {
|
||||
destroyItemWorkerForWindow(item, window);
|
||||
internal(item).workerMap.delete(id);
|
||||
}
|
||||
});
|
||||
|
||||
internal(item).workerMap.set(window, worker);
|
||||
internal(item).workerMap.set(id, worker);
|
||||
|
||||
return worker;
|
||||
}
|
||||
@ -463,8 +455,8 @@ let LabelledItem = Class({
|
||||
},
|
||||
|
||||
destroy: function destroy() {
|
||||
for (let [window] of internal(this).workerMap)
|
||||
destroyItemWorkerForWindow(this, window);
|
||||
for (let [,worker] of internal(this).workerMap)
|
||||
worker.destroy();
|
||||
|
||||
BaseItem.prototype.destroy.call(this);
|
||||
},
|
||||
@ -645,6 +637,12 @@ when(function() {
|
||||
// App specific UI code lives here, it should handle populating the context
|
||||
// menu and passing clicks etc. through to the items.
|
||||
|
||||
function countVisibleItems(nodes) {
|
||||
return Array.reduce(nodes, function(sum, node) {
|
||||
return node.hidden ? sum : sum + 1;
|
||||
}, 0);
|
||||
}
|
||||
|
||||
let MenuWrapper = Class({
|
||||
initialize: function initialize(winWrapper, items, contextMenu) {
|
||||
this.winWrapper = winWrapper;
|
||||
@ -654,11 +652,17 @@ let MenuWrapper = Class({
|
||||
this.populated = false;
|
||||
this.menuMap = new Map();
|
||||
|
||||
this.contextMenu.addEventListener("popupshowing", this, false);
|
||||
// updateItemVisibilities will run first, updateOverflowState will run after
|
||||
// all other instances of this module have run updateItemVisibilities
|
||||
this._updateItemVisibilities = this.updateItemVisibilities.bind(this);
|
||||
this.contextMenu.addEventListener("popupshowing", this._updateItemVisibilities, true);
|
||||
this._updateOverflowState = this.updateOverflowState.bind(this);
|
||||
this.contextMenu.addEventListener("popupshowing", this._updateOverflowState, false);
|
||||
},
|
||||
|
||||
destroy: function destroy() {
|
||||
this.contextMenu.removeEventListener("popupshowing", this, false);
|
||||
this.contextMenu.removeEventListener("popupshowing", this._updateOverflowState, false);
|
||||
this.contextMenu.removeEventListener("popupshowing", this._updateItemVisibilities, true);
|
||||
|
||||
if (!this.populated)
|
||||
return;
|
||||
@ -693,7 +697,7 @@ let MenuWrapper = Class({
|
||||
},
|
||||
|
||||
get overflowItems() {
|
||||
return this.contextMenu.querySelectorAll("." + OVERFLOW_ITEM_CLASS + " > ." + ITEM_CLASS);
|
||||
return this.contextMenu.querySelectorAll("." + OVERFLOW_ITEM_CLASS);
|
||||
},
|
||||
|
||||
getXULNodeForItem: function getXULNodeForItem(item) {
|
||||
@ -741,31 +745,11 @@ let MenuWrapper = Class({
|
||||
|
||||
let menu = item.parentMenu;
|
||||
if (menu === this.items) {
|
||||
// Insert into the overflow popup if it exists, otherwise the normal
|
||||
// context menu
|
||||
menupopup = this.overflowPopup;
|
||||
|
||||
// If there isn't already an overflow menu then check if we need to
|
||||
// create one, otherwise use the main context menu
|
||||
if (!menupopup) {
|
||||
if (!menupopup)
|
||||
menupopup = this.contextMenu;
|
||||
let toplevel = this.topLevelItems;
|
||||
|
||||
if (toplevel.length >= MenuManager.overflowThreshold) {
|
||||
// Create the overflow menu and move everything there
|
||||
let overflowMenu = this.window.document.createElement("menu");
|
||||
overflowMenu.setAttribute("class", OVERFLOW_MENU_CLASS);
|
||||
overflowMenu.setAttribute("label", OVERFLOW_MENU_LABEL);
|
||||
this.contextMenu.insertBefore(overflowMenu, this.separator.nextSibling);
|
||||
|
||||
menupopup = this.window.document.createElement("menupopup");
|
||||
menupopup.setAttribute("class", OVERFLOW_POPUP_CLASS);
|
||||
overflowMenu.appendChild(menupopup);
|
||||
|
||||
for (let xulNode of toplevel) {
|
||||
menupopup.appendChild(xulNode);
|
||||
this.updateXULClass(xulNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
let xulNode = this.getXULNodeForItem(menu);
|
||||
@ -839,7 +823,7 @@ let MenuWrapper = Class({
|
||||
xulNode.setAttribute("value", item.data);
|
||||
|
||||
let self = this;
|
||||
xulNode.addEventListener("click", function(event) {
|
||||
xulNode.addEventListener("command", function(event) {
|
||||
// Only care about clicks directly on this item
|
||||
if (event.target !== xulNode)
|
||||
return;
|
||||
@ -932,30 +916,18 @@ let MenuWrapper = Class({
|
||||
}
|
||||
}
|
||||
else if (parent == this.overflowPopup) {
|
||||
// If there are no more items then remove the overflow menu and separator
|
||||
if (parent.childNodes.length == 0) {
|
||||
// It's possible that this add-on had all the items in the overflow
|
||||
// menu and they're now all gone, so remove the separator and overflow
|
||||
// menu directly
|
||||
|
||||
let separator = this.separator;
|
||||
separator.parentNode.removeChild(separator);
|
||||
this.contextMenu.removeChild(parent.parentNode);
|
||||
}
|
||||
else if (parent.childNodes.length <= MenuManager.overflowThreshold) {
|
||||
// Otherwise if the overflow menu is empty enough move everything in
|
||||
// the overflow menu back to top level and remove the overflow menu
|
||||
|
||||
while (parent.firstChild) {
|
||||
let node = parent.firstChild;
|
||||
this.contextMenu.insertBefore(node, parent.parentNode);
|
||||
this.updateXULClass(node);
|
||||
}
|
||||
this.contextMenu.removeChild(parent.parentNode);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
handleEvent: function handleEvent(event) {
|
||||
// Recurses through all the items owned by this module and sets their hidden
|
||||
// state
|
||||
updateItemVisibilities: function updateItemVisibilities(event) {
|
||||
try {
|
||||
if (event.type != "popupshowing")
|
||||
return;
|
||||
@ -970,28 +942,77 @@ let MenuWrapper = Class({
|
||||
this.populate(this.items);
|
||||
}
|
||||
|
||||
let separator = this.separator;
|
||||
let popup = this.overflowMenu;
|
||||
|
||||
let popupNode = event.target.triggerNode;
|
||||
if (this.setVisibility(this.items, popupNode, PageContext().isCurrent(popupNode))) {
|
||||
// Some of this instance's items are visible so make sure the separator
|
||||
// and if necessary the overflow popup are visible
|
||||
separator.hidden = false;
|
||||
if (popup)
|
||||
popup.hidden = false;
|
||||
this.setVisibility(this.items, popupNode, PageContext().isCurrent(popupNode));
|
||||
}
|
||||
catch (e) {
|
||||
console.exception(e);
|
||||
}
|
||||
},
|
||||
|
||||
// Counts the number of visible items across all modules and makes sure they
|
||||
// are in the right place between the top level context menu and the overflow
|
||||
// menu
|
||||
updateOverflowState: function updateOverflowState(event) {
|
||||
try {
|
||||
if (event.type != "popupshowing")
|
||||
return;
|
||||
if (event.target != this.contextMenu)
|
||||
return;
|
||||
|
||||
// The main items will be in either the top level context menu or the
|
||||
// overflow menu at this point. Count the visible ones and if they are in
|
||||
// the wrong place move them
|
||||
let toplevel = this.topLevelItems;
|
||||
let overflow = this.overflowItems;
|
||||
let visibleCount = countVisibleItems(toplevel) +
|
||||
countVisibleItems(overflow);
|
||||
|
||||
if (visibleCount == 0) {
|
||||
let separator = this.separator;
|
||||
if (separator)
|
||||
separator.hidden = true;
|
||||
let overflowMenu = this.overflowMenu;
|
||||
if (overflowMenu)
|
||||
overflowMenu.hidden = true;
|
||||
}
|
||||
else if (visibleCount > MenuManager.overflowThreshold) {
|
||||
this.separator.hidden = false;
|
||||
let overflowPopup = this.overflowPopup;
|
||||
if (overflowPopup)
|
||||
overflowPopup.parentNode.hidden = false;
|
||||
|
||||
if (toplevel.length > 0) {
|
||||
// The overflow menu shouldn't exist here but let's play it safe
|
||||
if (!overflowPopup) {
|
||||
let overflowMenu = this.window.document.createElement("menu");
|
||||
overflowMenu.setAttribute("class", OVERFLOW_MENU_CLASS);
|
||||
overflowMenu.setAttribute("label", OVERFLOW_MENU_LABEL);
|
||||
this.contextMenu.insertBefore(overflowMenu, this.separator.nextSibling);
|
||||
|
||||
overflowPopup = this.window.document.createElement("menupopup");
|
||||
overflowPopup.setAttribute("class", OVERFLOW_POPUP_CLASS);
|
||||
overflowMenu.appendChild(overflowPopup);
|
||||
}
|
||||
|
||||
for (let xulNode of toplevel) {
|
||||
overflowPopup.appendChild(xulNode);
|
||||
this.updateXULClass(xulNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
// We need to test whether any other instance has visible items.
|
||||
// Get all the highest level items and see if any are visible.
|
||||
let anyVisible = (Array.some(this.topLevelItems, function(item) !item.hidden)) ||
|
||||
(Array.some(this.overflowItems, function(item) !item.hidden));
|
||||
|
||||
// If any were visible make sure the separator and if necessary the
|
||||
// overflow popup are visible, otherwise hide them
|
||||
separator.hidden = !anyVisible;
|
||||
if (popup)
|
||||
popup.hidden = !anyVisible;
|
||||
this.separator.hidden = false;
|
||||
|
||||
if (overflow.length > 0) {
|
||||
// Move all the overflow nodes out of the overflow menu and position
|
||||
// them immediately before it
|
||||
for (let xulNode of overflow) {
|
||||
this.contextMenu.insertBefore(xulNode, xulNode.parentNode.parentNode);
|
||||
this.updateXULClass(xulNode);
|
||||
}
|
||||
this.contextMenu.removeChild(this.overflowMenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
|
@ -57,7 +57,11 @@ const TabTrait = Trait.compose(EventEmitter, {
|
||||
},
|
||||
destroy: function destroy() {
|
||||
this._removeAllListeners();
|
||||
this._browser.removeEventListener(EVENTS.ready.dom, this._onReady, true);
|
||||
if (this._tab) {
|
||||
this._browser.removeEventListener(EVENTS.ready.dom, this._onReady, true);
|
||||
this._tab = null;
|
||||
TABS.splice(TABS.indexOf(this), 1);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@ -98,35 +102,35 @@ const TabTrait = Trait.compose(EventEmitter, {
|
||||
/**
|
||||
* Unique id for the tab, actually maps to tab.linkedPanel but with some munging.
|
||||
*/
|
||||
get id() getTabId(this._tab),
|
||||
get id() this._tab ? getTabId(this._tab) : undefined,
|
||||
|
||||
/**
|
||||
* The title of the page currently loaded in the tab.
|
||||
* Changing this property changes an actual title.
|
||||
* @type {String}
|
||||
*/
|
||||
get title() getTabTitle(this._tab),
|
||||
set title(title) setTabTitle(this._tab, title),
|
||||
get title() this._tab ? getTabTitle(this._tab) : undefined,
|
||||
set title(title) this._tab && setTabTitle(this._tab, title),
|
||||
|
||||
/**
|
||||
* Returns the MIME type that the document loaded in the tab is being
|
||||
* rendered as.
|
||||
* @type {String}
|
||||
*/
|
||||
get contentType() getTabContentType(this._tab),
|
||||
get contentType() this._tab ? getTabContentType(this._tab) : undefined,
|
||||
|
||||
/**
|
||||
* Location of the page currently loaded in this tab.
|
||||
* Changing this property will loads page under under the specified location.
|
||||
* @type {String}
|
||||
*/
|
||||
get url() getTabURL(this._tab),
|
||||
set url(url) setTabURL(this._tab, url),
|
||||
get url() this._tab ? getTabURL(this._tab) : undefined,
|
||||
set url(url) this._tab && setTabURL(this._tab, url),
|
||||
/**
|
||||
* URI of the favicon for the page currently loaded in this tab.
|
||||
* @type {String}
|
||||
*/
|
||||
get favicon() getFaviconURIForLocation(this.url),
|
||||
get favicon() this._tab ? getFaviconURIForLocation(this.url) : undefined,
|
||||
/**
|
||||
* The CSS style for the tab
|
||||
*/
|
||||
@ -137,23 +141,30 @@ const TabTrait = Trait.compose(EventEmitter, {
|
||||
* @type {Number}
|
||||
*/
|
||||
get index()
|
||||
this._window.gBrowser.getBrowserIndexForDocument(this._contentDocument),
|
||||
set index(value) this._window.gBrowser.moveTabTo(this._tab, value),
|
||||
this._tab ?
|
||||
this._window.gBrowser.getBrowserIndexForDocument(this._contentDocument) :
|
||||
undefined,
|
||||
set index(value)
|
||||
this._tab && this._window.gBrowser.moveTabTo(this._tab, value),
|
||||
/**
|
||||
* Thumbnail data URI of the page currently loaded in this tab.
|
||||
* @type {String}
|
||||
*/
|
||||
getThumbnail: function getThumbnail()
|
||||
getThumbnailURIForWindow(this._contentWindow),
|
||||
this._tab ? getThumbnailURIForWindow(this._contentWindow) : undefined,
|
||||
/**
|
||||
* Whether or not tab is pinned (Is an app-tab).
|
||||
* @type {Boolean}
|
||||
*/
|
||||
get isPinned() this._tab.pinned,
|
||||
get isPinned() this._tab ? this._tab.pinned : undefined,
|
||||
pin: function pin() {
|
||||
if (!this._tab)
|
||||
return;
|
||||
this._window.gBrowser.pinTab(this._tab);
|
||||
},
|
||||
unpin: function unpin() {
|
||||
if (!this._tab)
|
||||
return;
|
||||
this._window.gBrowser.unpinTab(this._tab);
|
||||
},
|
||||
|
||||
@ -162,6 +173,8 @@ const TabTrait = Trait.compose(EventEmitter, {
|
||||
* @type {Worker}
|
||||
*/
|
||||
attach: function attach(options) {
|
||||
if (!this._tab)
|
||||
return;
|
||||
// BUG 792946 https://bugzilla.mozilla.org/show_bug.cgi?id=792946
|
||||
// TODO: fix this circular dependency
|
||||
let { Worker } = require('./worker');
|
||||
@ -175,12 +188,16 @@ const TabTrait = Trait.compose(EventEmitter, {
|
||||
* we would like to return instance before firing a 'TabActivated' event.
|
||||
*/
|
||||
activate: defer(function activate() {
|
||||
if (!this._tab)
|
||||
return;
|
||||
activateTab(this._tab);
|
||||
}),
|
||||
/**
|
||||
* Close the tab
|
||||
*/
|
||||
close: function close(callback) {
|
||||
if (!this._tab)
|
||||
return;
|
||||
if (callback)
|
||||
this.once(EVENTS.close.name, callback);
|
||||
this._window.gBrowser.removeTab(this._tab);
|
||||
@ -189,6 +206,8 @@ const TabTrait = Trait.compose(EventEmitter, {
|
||||
* Reload the tab
|
||||
*/
|
||||
reload: function reload() {
|
||||
if (!this._tab)
|
||||
return;
|
||||
this._window.gBrowser.reloadTab(this._tab);
|
||||
}
|
||||
});
|
||||
|
@ -86,6 +86,9 @@ const WindowLoader = Trait.compose({
|
||||
this._onLoad(window)
|
||||
}
|
||||
}
|
||||
else {
|
||||
this.__window = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
__window: null,
|
||||
|
@ -196,3 +196,4 @@ def replace_file(env_root, dest_path, file_contents, must_rewrite_links):
|
||||
if must_rewrite_links and dest_path.endswith(".html"):
|
||||
file_contents = rewrite_links(env_root, get_sdk_docs_path(env_root), file_contents, dest_path)
|
||||
open(dest_path, "w").write(file_contents)
|
||||
|
||||
|
@ -169,7 +169,7 @@ def gen_manifest(template_root_dir, target_cfg, jid,
|
||||
ta_desc.appendChild(elem)
|
||||
|
||||
elem = dom.createElement("em:maxVersion")
|
||||
elem.appendChild(dom.createTextNode("21.0a1"))
|
||||
elem.appendChild(dom.createTextNode("20.*"))
|
||||
ta_desc.appendChild(elem)
|
||||
|
||||
if target_cfg.get("homepage"):
|
||||
|
@ -3,8 +3,10 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
'use strict';
|
||||
|
||||
let { Cc, Ci } = require("chrome");
|
||||
|
||||
let {Cc,Ci} = require("chrome");
|
||||
const { Loader } = require('sdk/test/loader');
|
||||
const timer = require("sdk/timers");
|
||||
|
||||
@ -480,6 +482,52 @@ exports.testURLContextRemove = function (test) {
|
||||
});
|
||||
};
|
||||
|
||||
// Loading a new page in the same tab should correctly start a new worker for
|
||||
// any content scripts
|
||||
exports.testPageReload = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let item = loader.cm.Item({
|
||||
label: "Item",
|
||||
contentScript: "var doc = document; self.on('context', function(node) doc.body.getAttribute('showItem') == 'true');"
|
||||
});
|
||||
|
||||
test.withTestDoc(function (window, doc) {
|
||||
// Set a flag on the document that the item uses
|
||||
doc.body.setAttribute("showItem", "true");
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
// With the attribute true the item should be visible in the menu
|
||||
test.checkMenu([item], [], []);
|
||||
test.hideMenu(function() {
|
||||
let browser = this.tabBrowser.getBrowserForTab(this.tab)
|
||||
test.delayedEventListener(browser, "load", function() {
|
||||
test.delayedEventListener(browser, "load", function() {
|
||||
window = browser.contentWindow;
|
||||
doc = window.document;
|
||||
|
||||
// Set a flag on the document that the item uses
|
||||
doc.body.setAttribute("showItem", "false");
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
// In the new document with the attribute false the item should be
|
||||
// hidden, but if the contentScript hasn't been reloaded it will
|
||||
// still see the old value
|
||||
test.checkMenu([item], [item], []);
|
||||
|
||||
test.done();
|
||||
});
|
||||
}, true);
|
||||
browser.loadURI(TEST_DOC_URL, null, null);
|
||||
}, true);
|
||||
// Required to make sure we load a new page in history rather than
|
||||
// just reloading the current page which would unload it
|
||||
browser.loadURI("about:blank", null, null);
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Closing a page after it's been used with a worker should cause the worker
|
||||
// to be destroyed
|
||||
@ -555,6 +603,143 @@ exports.testContentContextNoMatch = function (test) {
|
||||
};
|
||||
|
||||
|
||||
// Content contexts that return undefined should cause their items to be absent
|
||||
// from the menu.
|
||||
exports.testContentContextUndefined = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let item = new loader.cm.Item({
|
||||
label: "item",
|
||||
contentScript: 'self.on("context", function () {});'
|
||||
});
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
test.checkMenu([item], [item], []);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Content contexts that return an empty string should cause their items to be
|
||||
// absent from the menu and shouldn't wipe the label
|
||||
exports.testContentContextEmptyString = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let item = new loader.cm.Item({
|
||||
label: "item",
|
||||
contentScript: 'self.on("context", function () "");'
|
||||
});
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
test.checkMenu([item], [item], []);
|
||||
test.assertEqual(item.label, "item", "Label should still be correct");
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// If any content contexts returns true then their items should be present in
|
||||
// the menu.
|
||||
exports.testMultipleContentContextMatch1 = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let item = new loader.cm.Item({
|
||||
label: "item",
|
||||
contentScript: 'self.on("context", function () true); ' +
|
||||
'self.on("context", function () false);',
|
||||
onMessage: function() {
|
||||
test.fail("Should not have called the second context listener");
|
||||
}
|
||||
});
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
test.checkMenu([item], [], []);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// If any content contexts returns true then their items should be present in
|
||||
// the menu.
|
||||
exports.testMultipleContentContextMatch2 = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let item = new loader.cm.Item({
|
||||
label: "item",
|
||||
contentScript: 'self.on("context", function () false); ' +
|
||||
'self.on("context", function () true);'
|
||||
});
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
test.checkMenu([item], [], []);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// If any content contexts returns a string then their items should be present
|
||||
// in the menu.
|
||||
exports.testMultipleContentContextString1 = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let item = new loader.cm.Item({
|
||||
label: "item",
|
||||
contentScript: 'self.on("context", function () "new label"); ' +
|
||||
'self.on("context", function () false);'
|
||||
});
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
test.checkMenu([item], [], []);
|
||||
test.assertEqual(item.label, "new label", "Label should have changed");
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// If any content contexts returns a string then their items should be present
|
||||
// in the menu.
|
||||
exports.testMultipleContentContextString2 = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let item = new loader.cm.Item({
|
||||
label: "item",
|
||||
contentScript: 'self.on("context", function () false); ' +
|
||||
'self.on("context", function () "new label");'
|
||||
});
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
test.checkMenu([item], [], []);
|
||||
test.assertEqual(item.label, "new label", "Label should have changed");
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// If many content contexts returns a string then the first should take effect
|
||||
exports.testMultipleContentContextString3 = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let item = new loader.cm.Item({
|
||||
label: "item",
|
||||
contentScript: 'self.on("context", function () "new label 1"); ' +
|
||||
'self.on("context", function () "new label 2");'
|
||||
});
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
test.checkMenu([item], [], []);
|
||||
test.assertEqual(item.label, "new label 1", "Label should have changed");
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Content contexts that return true should cause their items to be present
|
||||
// in the menu when context clicking an active element.
|
||||
exports.testContentContextMatchActiveElement = function (test) {
|
||||
@ -631,6 +816,44 @@ exports.testContentContextNoMatchActiveElement = function (test) {
|
||||
};
|
||||
|
||||
|
||||
// Content contexts that return undefined should cause their items to be absent
|
||||
// from the menu when context clicking an active element.
|
||||
exports.testContentContextNoMatchActiveElement = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let items = [
|
||||
new loader.cm.Item({
|
||||
label: "item 1",
|
||||
contentScript: 'self.on("context", function () {});'
|
||||
}),
|
||||
new loader.cm.Item({
|
||||
label: "item 2",
|
||||
context: undefined,
|
||||
contentScript: 'self.on("context", function () {});'
|
||||
}),
|
||||
// These items will always be hidden by the declarative usage of PageContext
|
||||
new loader.cm.Item({
|
||||
label: "item 3",
|
||||
context: loader.cm.PageContext(),
|
||||
contentScript: 'self.on("context", function () {});'
|
||||
}),
|
||||
new loader.cm.Item({
|
||||
label: "item 4",
|
||||
context: [loader.cm.PageContext()],
|
||||
contentScript: 'self.on("context", function () {});'
|
||||
})
|
||||
];
|
||||
|
||||
test.withTestDoc(function (window, doc) {
|
||||
test.showMenu(doc.getElementById("image"), function (popup) {
|
||||
test.checkMenu(items, items, []);
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Content contexts that return a string should cause their items to be present
|
||||
// in the menu and the items' labels to be updated.
|
||||
exports.testContentContextMatchString = function (test) {
|
||||
@ -799,7 +1022,7 @@ exports.testUnload = function (test) {
|
||||
|
||||
|
||||
// Using multiple module instances to add items without causing overflow should
|
||||
// work OK. Assumes OVERFLOW_THRESH_DEFAULT <= 2.
|
||||
// work OK. Assumes OVERFLOW_THRESH_DEFAULT >= 2.
|
||||
exports.testMultipleModulesAdd = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader0 = test.newLoader();
|
||||
@ -1164,7 +1387,6 @@ exports.testMultipleModulesOrderOverflow = function (test) {
|
||||
|
||||
// Same again
|
||||
test.checkMenu([item0, item2, item1, item3], [], []);
|
||||
prefs.set(OVERFLOW_THRESH_PREF, OVERFLOW_THRESH_DEFAULT);
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
@ -1172,6 +1394,401 @@ exports.testMultipleModulesOrderOverflow = function (test) {
|
||||
};
|
||||
|
||||
|
||||
// Checks that if a module's items are all hidden then the overflow menu doesn't
|
||||
// get hidden
|
||||
exports.testMultipleModulesOverflowHidden = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader0 = test.newLoader();
|
||||
let loader1 = test.newLoader();
|
||||
|
||||
let prefs = loader0.loader.require("preferences-service");
|
||||
prefs.set(OVERFLOW_THRESH_PREF, 0);
|
||||
|
||||
// Use each module to add an item, then unload each module in turn.
|
||||
let item0 = new loader0.cm.Item({ label: "item 0" });
|
||||
let item1 = new loader1.cm.Item({
|
||||
label: "item 1",
|
||||
context: loader1.cm.SelectorContext("a")
|
||||
});
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
// One should be hidden
|
||||
test.checkMenu([item0, item1], [item1], []);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Checks that if a module's items are all hidden then the overflow menu doesn't
|
||||
// get hidden (reverse order to above)
|
||||
exports.testMultipleModulesOverflowHidden2 = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader0 = test.newLoader();
|
||||
let loader1 = test.newLoader();
|
||||
|
||||
let prefs = loader0.loader.require("preferences-service");
|
||||
prefs.set(OVERFLOW_THRESH_PREF, 0);
|
||||
|
||||
// Use each module to add an item, then unload each module in turn.
|
||||
let item0 = new loader0.cm.Item({
|
||||
label: "item 0",
|
||||
context: loader0.cm.SelectorContext("a")
|
||||
});
|
||||
let item1 = new loader1.cm.Item({ label: "item 1" });
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
// One should be hidden
|
||||
test.checkMenu([item0, item1], [item0], []);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Checks that we don't overflow if there are more items than the overflow
|
||||
// threshold but not all of them are visible
|
||||
exports.testOverflowIgnoresHidden = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let prefs = loader.loader.require("preferences-service");
|
||||
prefs.set(OVERFLOW_THRESH_PREF, 2);
|
||||
|
||||
let allItems = [
|
||||
new loader.cm.Item({
|
||||
label: "item 0"
|
||||
}),
|
||||
new loader.cm.Item({
|
||||
label: "item 1"
|
||||
}),
|
||||
new loader.cm.Item({
|
||||
label: "item 2",
|
||||
context: loader.cm.SelectorContext("a")
|
||||
})
|
||||
];
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
// One should be hidden
|
||||
test.checkMenu(allItems, [allItems[2]], []);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Checks that we don't overflow if there are more items than the overflow
|
||||
// threshold but not all of them are visible
|
||||
exports.testOverflowIgnoresHiddenMultipleModules1 = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader0 = test.newLoader();
|
||||
let loader1 = test.newLoader();
|
||||
|
||||
let prefs = loader0.loader.require("preferences-service");
|
||||
prefs.set(OVERFLOW_THRESH_PREF, 2);
|
||||
|
||||
let allItems = [
|
||||
new loader0.cm.Item({
|
||||
label: "item 0"
|
||||
}),
|
||||
new loader0.cm.Item({
|
||||
label: "item 1"
|
||||
}),
|
||||
new loader1.cm.Item({
|
||||
label: "item 2",
|
||||
context: loader1.cm.SelectorContext("a")
|
||||
}),
|
||||
new loader1.cm.Item({
|
||||
label: "item 3",
|
||||
context: loader1.cm.SelectorContext("a")
|
||||
})
|
||||
];
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
// One should be hidden
|
||||
test.checkMenu(allItems, [allItems[2], allItems[3]], []);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Checks that we don't overflow if there are more items than the overflow
|
||||
// threshold but not all of them are visible
|
||||
exports.testOverflowIgnoresHiddenMultipleModules2 = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader0 = test.newLoader();
|
||||
let loader1 = test.newLoader();
|
||||
|
||||
let prefs = loader0.loader.require("preferences-service");
|
||||
prefs.set(OVERFLOW_THRESH_PREF, 2);
|
||||
|
||||
let allItems = [
|
||||
new loader0.cm.Item({
|
||||
label: "item 0"
|
||||
}),
|
||||
new loader0.cm.Item({
|
||||
label: "item 1",
|
||||
context: loader0.cm.SelectorContext("a")
|
||||
}),
|
||||
new loader1.cm.Item({
|
||||
label: "item 2"
|
||||
}),
|
||||
new loader1.cm.Item({
|
||||
label: "item 3",
|
||||
context: loader1.cm.SelectorContext("a")
|
||||
})
|
||||
];
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
// One should be hidden
|
||||
test.checkMenu(allItems, [allItems[1], allItems[3]], []);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Checks that we don't overflow if there are more items than the overflow
|
||||
// threshold but not all of them are visible
|
||||
exports.testOverflowIgnoresHiddenMultipleModules3 = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader0 = test.newLoader();
|
||||
let loader1 = test.newLoader();
|
||||
|
||||
let prefs = loader0.loader.require("preferences-service");
|
||||
prefs.set(OVERFLOW_THRESH_PREF, 2);
|
||||
|
||||
let allItems = [
|
||||
new loader0.cm.Item({
|
||||
label: "item 0",
|
||||
context: loader0.cm.SelectorContext("a")
|
||||
}),
|
||||
new loader0.cm.Item({
|
||||
label: "item 1",
|
||||
context: loader0.cm.SelectorContext("a")
|
||||
}),
|
||||
new loader1.cm.Item({
|
||||
label: "item 2"
|
||||
}),
|
||||
new loader1.cm.Item({
|
||||
label: "item 3"
|
||||
})
|
||||
];
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
// One should be hidden
|
||||
test.checkMenu(allItems, [allItems[0], allItems[1]], []);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Tests that we transition between overflowing to non-overflowing to no items
|
||||
// and back again
|
||||
exports.testOverflowTransition = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let prefs = loader.loader.require("preferences-service");
|
||||
prefs.set(OVERFLOW_THRESH_PREF, 2);
|
||||
|
||||
let pItems = [
|
||||
new loader.cm.Item({
|
||||
label: "item 0",
|
||||
context: loader.cm.SelectorContext("p")
|
||||
}),
|
||||
new loader.cm.Item({
|
||||
label: "item 1",
|
||||
context: loader.cm.SelectorContext("p")
|
||||
})
|
||||
];
|
||||
|
||||
let aItems = [
|
||||
new loader.cm.Item({
|
||||
label: "item 2",
|
||||
context: loader.cm.SelectorContext("a")
|
||||
}),
|
||||
new loader.cm.Item({
|
||||
label: "item 3",
|
||||
context: loader.cm.SelectorContext("a")
|
||||
})
|
||||
];
|
||||
|
||||
let allItems = pItems.concat(aItems);
|
||||
|
||||
test.withTestDoc(function (window, doc) {
|
||||
test.showMenu(doc.getElementById("link"), function (popup) {
|
||||
// The menu should contain all items and will overflow
|
||||
test.checkMenu(allItems, [], []);
|
||||
popup.hidePopup();
|
||||
|
||||
test.showMenu(doc.getElementById("text"), function (popup) {
|
||||
// Only contains hald the items and will not overflow
|
||||
test.checkMenu(allItems, aItems, []);
|
||||
popup.hidePopup();
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
// None of the items will be visible
|
||||
test.checkMenu(allItems, allItems, []);
|
||||
popup.hidePopup();
|
||||
|
||||
test.showMenu(doc.getElementById("text"), function (popup) {
|
||||
// Only contains hald the items and will not overflow
|
||||
test.checkMenu(allItems, aItems, []);
|
||||
popup.hidePopup();
|
||||
|
||||
test.showMenu(doc.getElementById("link"), function (popup) {
|
||||
// The menu should contain all items and will overflow
|
||||
test.checkMenu(allItems, [], []);
|
||||
popup.hidePopup();
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
// None of the items will be visible
|
||||
test.checkMenu(allItems, allItems, []);
|
||||
popup.hidePopup();
|
||||
|
||||
test.showMenu(doc.getElementById("link"), function (popup) {
|
||||
// The menu should contain all items and will overflow
|
||||
test.checkMenu(allItems, [], []);
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// An item's command listener should work.
|
||||
exports.testItemCommand = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let item = new loader.cm.Item({
|
||||
label: "item",
|
||||
data: "item data",
|
||||
contentScript: 'self.on("click", function (node, data) {' +
|
||||
' self.postMessage({' +
|
||||
' tagName: node.tagName,' +
|
||||
' data: data' +
|
||||
' });' +
|
||||
'});',
|
||||
onMessage: function (data) {
|
||||
test.assertEqual(this, item, "`this` inside onMessage should be item");
|
||||
test.assertEqual(data.tagName, "HTML", "node should be an HTML element");
|
||||
test.assertEqual(data.data, item.data, "data should be item data");
|
||||
test.done();
|
||||
}
|
||||
});
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
test.checkMenu([item], [], []);
|
||||
let elt = test.getItemElt(popup, item);
|
||||
|
||||
// create a command event
|
||||
let evt = elt.ownerDocument.createEvent('Event');
|
||||
evt.initEvent('command', true, true);
|
||||
elt.dispatchEvent(evt);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// A menu's click listener should work and receive bubbling 'command' events from
|
||||
// sub-items appropriately. This also tests menus and ensures that when a CSS
|
||||
// selector context matches the clicked node's ancestor, the matching ancestor
|
||||
// is passed to listeners as the clicked node.
|
||||
exports.testMenuCommand = function (test) {
|
||||
// Create a top-level menu, submenu, and item, like this:
|
||||
// topMenu -> submenu -> item
|
||||
// Click the item and make sure the click bubbles.
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let item = new loader.cm.Item({
|
||||
label: "submenu item",
|
||||
data: "submenu item data",
|
||||
context: loader.cm.SelectorContext("a"),
|
||||
});
|
||||
|
||||
let submenu = new loader.cm.Menu({
|
||||
label: "submenu",
|
||||
context: loader.cm.SelectorContext("a"),
|
||||
items: [item]
|
||||
});
|
||||
|
||||
let topMenu = new loader.cm.Menu({
|
||||
label: "top menu",
|
||||
contentScript: 'self.on("click", function (node, data) {' +
|
||||
' let Ci = Components["interfaces"];' +
|
||||
' self.postMessage({' +
|
||||
' tagName: node.tagName,' +
|
||||
' data: data' +
|
||||
' });' +
|
||||
'});',
|
||||
onMessage: function (data) {
|
||||
test.assertEqual(this, topMenu, "`this` inside top menu should be menu");
|
||||
test.assertEqual(data.tagName, "A", "Clicked node should be anchor");
|
||||
test.assertEqual(data.data, item.data,
|
||||
"Clicked item data should be correct");
|
||||
test.done();
|
||||
},
|
||||
items: [submenu],
|
||||
context: loader.cm.SelectorContext("a")
|
||||
});
|
||||
|
||||
test.withTestDoc(function (window, doc) {
|
||||
test.showMenu(doc.getElementById("span-link"), function (popup) {
|
||||
test.checkMenu([topMenu], [], []);
|
||||
let topMenuElt = test.getItemElt(popup, topMenu);
|
||||
let topMenuPopup = topMenuElt.firstChild;
|
||||
let submenuElt = test.getItemElt(topMenuPopup, submenu);
|
||||
let submenuPopup = submenuElt.firstChild;
|
||||
let itemElt = test.getItemElt(submenuPopup, item);
|
||||
|
||||
// create a command event
|
||||
let evt = itemElt.ownerDocument.createEvent('Event');
|
||||
evt.initEvent('command', true, true);
|
||||
itemElt.dispatchEvent(evt);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Click listeners should work when multiple modules are loaded.
|
||||
exports.testItemCommandMultipleModules = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader0 = test.newLoader();
|
||||
let loader1 = test.newLoader();
|
||||
|
||||
let item0 = loader0.cm.Item({
|
||||
label: "loader 0 item",
|
||||
contentScript: 'self.on("click", self.postMessage);',
|
||||
onMessage: function () {
|
||||
test.fail("loader 0 item should not emit click event");
|
||||
}
|
||||
});
|
||||
let item1 = loader1.cm.Item({
|
||||
label: "loader 1 item",
|
||||
contentScript: 'self.on("click", self.postMessage);',
|
||||
onMessage: function () {
|
||||
test.pass("loader 1 item clicked as expected");
|
||||
test.done();
|
||||
}
|
||||
});
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
test.checkMenu([item0, item1], [], []);
|
||||
let item1Elt = test.getItemElt(popup, item1);
|
||||
|
||||
// create a command event
|
||||
let evt = item1Elt.ownerDocument.createEvent('Event');
|
||||
evt.initEvent('command', true, true);
|
||||
item1Elt.dispatchEvent(evt);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
// An item's click listener should work.
|
||||
exports.testItemClick = function (test) {
|
||||
test = new TestHelper(test);
|
||||
@ -1526,6 +2143,7 @@ exports.testDrawImageOnClickNode = function (test) {
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
// Setting an item's label before the menu is ever shown should correctly change
|
||||
// its label.
|
||||
exports.testSetLabelBeforeShow = function (test) {
|
||||
@ -1589,7 +2207,6 @@ exports.testSetLabelBeforeShowOverflow = function (test) {
|
||||
|
||||
test.showMenu(null, function (popup) {
|
||||
test.checkMenu(items, [], []);
|
||||
prefs.set(OVERFLOW_THRESH_PREF, OVERFLOW_THRESH_DEFAULT);
|
||||
test.done();
|
||||
});
|
||||
};
|
||||
@ -1617,7 +2234,6 @@ exports.testSetLabelAfterShowOverflow = function (test) {
|
||||
test.assertEqual(items[0].label, "z");
|
||||
test.showMenu(null, function (popup) {
|
||||
test.checkMenu(items, [], []);
|
||||
prefs.set(OVERFLOW_THRESH_PREF, OVERFLOW_THRESH_DEFAULT);
|
||||
test.done();
|
||||
});
|
||||
});
|
||||
@ -2090,6 +2706,8 @@ exports.testSubItemDefaultVisible = function (test) {
|
||||
});
|
||||
};
|
||||
|
||||
// Tests that the click event on sub menuitem
|
||||
// tiggers the click event for the sub menuitem and the parent menu
|
||||
exports.testSubItemClick = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
@ -2145,6 +2763,68 @@ exports.testSubItemClick = function (test) {
|
||||
});
|
||||
};
|
||||
|
||||
// Tests that the command event on sub menuitem
|
||||
// tiggers the click event for the sub menuitem and the parent menu
|
||||
exports.testSubItemCommand = function (test) {
|
||||
test = new TestHelper(test);
|
||||
let loader = test.newLoader();
|
||||
|
||||
let state = 0;
|
||||
|
||||
let items = [
|
||||
loader.cm.Menu({
|
||||
label: "menu 1",
|
||||
items: [
|
||||
loader.cm.Item({
|
||||
label: "subitem 1",
|
||||
data: "foobar",
|
||||
contentScript: 'self.on("click", function (node, data) {' +
|
||||
' self.postMessage({' +
|
||||
' tagName: node.tagName,' +
|
||||
' data: data' +
|
||||
' });' +
|
||||
'});',
|
||||
onMessage: function(msg) {
|
||||
test.assertEqual(msg.tagName, "HTML", "should have seen the right node");
|
||||
test.assertEqual(msg.data, "foobar", "should have seen the right data");
|
||||
test.assertEqual(state, 0, "should have seen the event at the right time");
|
||||
state++;
|
||||
}
|
||||
})
|
||||
],
|
||||
contentScript: 'self.on("click", function (node, data) {' +
|
||||
' self.postMessage({' +
|
||||
' tagName: node.tagName,' +
|
||||
' data: data' +
|
||||
' });' +
|
||||
'});',
|
||||
onMessage: function(msg) {
|
||||
test.assertEqual(msg.tagName, "HTML", "should have seen the right node");
|
||||
test.assertEqual(msg.data, "foobar", "should have seen the right data");
|
||||
test.assertEqual(state, 1, "should have seen the event at the right time");
|
||||
state++
|
||||
|
||||
test.done();
|
||||
}
|
||||
})
|
||||
];
|
||||
|
||||
test.withTestDoc(function (window, doc) {
|
||||
test.showMenu(null, function (popup) {
|
||||
test.checkMenu(items, [], []);
|
||||
|
||||
let topMenuElt = test.getItemElt(popup, items[0]);
|
||||
let topMenuPopup = topMenuElt.firstChild;
|
||||
let itemElt = test.getItemElt(topMenuPopup, items[0].items[0]);
|
||||
|
||||
// create a command event
|
||||
let evt = itemElt.ownerDocument.createEvent('Event');
|
||||
evt.initEvent('command', true, true);
|
||||
itemElt.dispatchEvent(evt);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Tests that opening a context menu for an outer frame when an inner frame
|
||||
// has a selection doesn't activate the SelectionContext
|
||||
exports.testSelectionInInnerFrameNoMatch = function (test) {
|
||||
@ -2249,6 +2929,8 @@ function TestHelper(test) {
|
||||
this.browserWindow = Cc["@mozilla.org/appshell/window-mediator;1"].
|
||||
getService(Ci.nsIWindowMediator).
|
||||
getMostRecentWindow("navigator:browser");
|
||||
this.overflowThreshValue = require("sdk/preferences/service").
|
||||
get(OVERFLOW_THRESH_PREF, OVERFLOW_THRESH_DEFAULT);
|
||||
}
|
||||
|
||||
TestHelper.prototype = {
|
||||
@ -2351,6 +3033,9 @@ TestHelper.prototype = {
|
||||
let mainNodes = this.browserWindow.document.querySelectorAll("#contentAreaContextMenu > ." + ITEM_CLASS);
|
||||
let overflowNodes = this.browserWindow.document.querySelectorAll("." + OVERFLOW_POPUP_CLASS + " > ." + ITEM_CLASS);
|
||||
|
||||
this.test.assert(mainNodes.length == 0 || overflowNodes.length == 0,
|
||||
"Should only see nodes at the top level or in overflow");
|
||||
|
||||
let overflow = this.overflowSubmenu;
|
||||
if (this.shouldOverflow(total)) {
|
||||
this.test.assert(overflow && !overflow.hidden,
|
||||
@ -2361,12 +3046,15 @@ TestHelper.prototype = {
|
||||
else {
|
||||
this.test.assert(!overflow || overflow.hidden,
|
||||
"overflow menu should not be present");
|
||||
this.test.assertEqual(overflowNodes.length, 0,
|
||||
"should be no items in the overflow context menu");
|
||||
// When visible nodes == 0 they could be in overflow or top level
|
||||
if (total > 0) {
|
||||
this.test.assertEqual(overflowNodes.length, 0,
|
||||
"should be no items in the overflow context menu");
|
||||
}
|
||||
}
|
||||
|
||||
let nodes = this.shouldOverflow(total) ? overflowNodes : mainNodes;
|
||||
|
||||
// Iterate over wherever the nodes have ended up
|
||||
let nodes = mainNodes.length ? mainNodes : overflowNodes;
|
||||
this.checkNodes(nodes, presentItems, absentItems, removedItems)
|
||||
let pos = 0;
|
||||
},
|
||||
@ -2382,6 +3070,11 @@ TestHelper.prototype = {
|
||||
if (removedItems.indexOf(item) >= 0)
|
||||
continue;
|
||||
|
||||
if (nodes.length <= pos) {
|
||||
this.test.assert(false, "Not enough nodes");
|
||||
return;
|
||||
}
|
||||
|
||||
let hidden = absentItems.indexOf(item) >= 0;
|
||||
|
||||
this.checkItemElt(nodes[pos], item);
|
||||
@ -2432,12 +3125,16 @@ TestHelper.prototype = {
|
||||
|
||||
// Call to finish the test.
|
||||
done: function () {
|
||||
const self = this;
|
||||
function commonDone() {
|
||||
this.closeTab();
|
||||
|
||||
while (this.loaders.length) {
|
||||
this.loaders[0].unload();
|
||||
}
|
||||
|
||||
require("sdk/preferences/service").set(OVERFLOW_THRESH_PREF, self.overflowThreshValue);
|
||||
|
||||
this.test.done();
|
||||
}
|
||||
|
||||
|
@ -5,23 +5,19 @@
|
||||
const port = 8099;
|
||||
const file = require("sdk/io/file");
|
||||
const { pathFor } = require("sdk/system");
|
||||
const { Loader } = require("sdk/test/loader");
|
||||
const options = require("@test/options");
|
||||
|
||||
const loader = Loader(module);
|
||||
const httpd = loader.require("sdk/test/httpd");
|
||||
if (options.parseable || options.verbose)
|
||||
loader.sandbox("sdk/test/httpd").DEBUG = true;
|
||||
|
||||
exports.testBasicHTTPServer = function(test) {
|
||||
let basePath = pathFor("TmpD");
|
||||
// Use the profile directory for the temporary file as that will be deleted
|
||||
// when tests are complete
|
||||
let basePath = pathFor("ProfD");
|
||||
let filePath = file.join(basePath, 'test-httpd.txt');
|
||||
let content = "This is the HTTPD test file.\n";
|
||||
let fileStream = file.open(filePath, 'w');
|
||||
fileStream.write(content);
|
||||
fileStream.close();
|
||||
|
||||
let srv = httpd.startServerAsync(port, basePath);
|
||||
let { startServerAsync } = require("sdk/test/httpd");
|
||||
let srv = startServerAsync(port, basePath);
|
||||
|
||||
test.waitUntilDone();
|
||||
|
||||
@ -45,7 +41,8 @@ exports.testBasicHTTPServer = function(test) {
|
||||
exports.testDynamicServer = function (test) {
|
||||
let content = "This is the HTTPD test file.\n";
|
||||
|
||||
let srv = httpd.startServerAsync(port);
|
||||
let { startServerAsync } = require("sdk/test/httpd");
|
||||
let srv = startServerAsync(port);
|
||||
|
||||
// See documentation here:
|
||||
//http://doxygen.db48x.net/mozilla/html/interfacensIHttpServer.html#a81fc7e7e29d82aac5ce7d56d0bedfb3a
|
||||
|
@ -1029,3 +1029,4 @@ if (require("sdk/system/xul-app").is("Fennec")) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -28,3 +28,4 @@ exports.testIsActiveDefault = function(test) {
|
||||
test.assertEqual(pb.isActive, false,
|
||||
'pb.isActive returns false when private browsing isn\'t supported');
|
||||
};
|
||||
|
||||
|
@ -15,7 +15,9 @@ if (options.parseable || options.verbose)
|
||||
loader.sandbox("sdk/test/httpd").DEBUG = true;
|
||||
const { startServerAsync } = httpd;
|
||||
|
||||
const basePath = pathFor("TmpD")
|
||||
// Use the profile directory for the temporary files as that will be deleted
|
||||
// when tests are complete
|
||||
const basePath = pathFor("ProfD")
|
||||
const port = 8099;
|
||||
|
||||
|
||||
|
@ -109,6 +109,28 @@ function step3(assert, done) {
|
||||
});
|
||||
}
|
||||
|
||||
exports["test behavior on close"] = function(assert, done) {
|
||||
|
||||
tabs.open({
|
||||
url: "about:mozilla",
|
||||
onReady: function(tab) {
|
||||
assert.equal(tab.url, "about:mozilla", "Tab has the expected url");
|
||||
assert.equal(tab.index, 1, "Tab has the expected index");
|
||||
tab.close(function () {
|
||||
assert.equal(tab.url, undefined,
|
||||
"After being closed, tab attributes are undefined (url)");
|
||||
assert.equal(tab.index, undefined,
|
||||
"After being closed, tab attributes are undefined (index)");
|
||||
// Ensure that we can call destroy multiple times without throwing
|
||||
tab.destroy();
|
||||
tab.destroy();
|
||||
|
||||
done();
|
||||
});
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
if (require("sdk/system/xul-app").is("Fennec")) {
|
||||
module.exports = {
|
||||
"test Unsupported Test": function UnsupportedTest (assert) {
|
||||
|
@ -546,17 +546,19 @@ pref("ui.showHideScrollbars", 1);
|
||||
// background.
|
||||
pref("dom.ipc.processPriorityManager.enabled", true);
|
||||
pref("dom.ipc.processPriorityManager.backgroundGracePeriodMS", 1000);
|
||||
pref("dom.ipc.processPriorityManager.temporaryPriorityMS", 5000);
|
||||
pref("dom.ipc.processPriorityManager.temporaryPriorityLockMS", 5000);
|
||||
|
||||
// Kernel parameters for how processes are killed on low-memory.
|
||||
pref("gonk.systemMemoryPressureRecoveryPollMS", 5000);
|
||||
pref("hal.processPriorityManager.gonk.masterOomScoreAdjust", 0);
|
||||
pref("hal.processPriorityManager.gonk.masterKillUnderMB", 1);
|
||||
pref("hal.processPriorityManager.gonk.foregroundOomScoreAdjust", 67);
|
||||
pref("hal.processPriorityManager.gonk.foregroundHighOomScoreAdjust", 67);
|
||||
pref("hal.processPriorityManager.gonk.foregroundHighKillUnderMB", 3);
|
||||
pref("hal.processPriorityManager.gonk.foregroundOomScoreAdjust", 134);
|
||||
pref("hal.processPriorityManager.gonk.foregroundKillUnderMB", 4);
|
||||
pref("hal.processPriorityManager.gonk.backgroundPerceivableOomScoreAdjust", 134);
|
||||
pref("hal.processPriorityManager.gonk.backgroundPerceivableOomScoreAdjust", 200);
|
||||
pref("hal.processPriorityManager.gonk.backgroundPerceivableKillUnderMB", 5);
|
||||
pref("hal.processPriorityManager.gonk.backgroundHomescreenOomScoreAdjust", 200);
|
||||
pref("hal.processPriorityManager.gonk.backgroundHomescreenOomScoreAdjust", 267);
|
||||
pref("hal.processPriorityManager.gonk.backgroundHomescreenKillUnderMB", 5);
|
||||
pref("hal.processPriorityManager.gonk.backgroundOomScoreAdjust", 400);
|
||||
pref("hal.processPriorityManager.gonk.backgroundKillUnderMB", 8);
|
||||
@ -564,6 +566,7 @@ pref("hal.processPriorityManager.gonk.notifyLowMemUnderMB", 10);
|
||||
|
||||
// Niceness values (i.e., CPU priorities) for B2G processes.
|
||||
pref("hal.processPriorityManager.gonk.masterNice", 0);
|
||||
pref("hal.processPriorityManager.gonk.foregroundHighNice", 0);
|
||||
pref("hal.processPriorityManager.gonk.foregroundNice", 1);
|
||||
pref("hal.processPriorityManager.gonk.backgroundPerceivableNice", 10);
|
||||
pref("hal.processPriorityManager.gonk.backgroundHomescreenNice", 20);
|
||||
@ -577,6 +580,11 @@ pref("dom.ipc.processPrelaunch.enabled", true);
|
||||
pref("dom.ipc.processPrelaunch.delayMs", 5000);
|
||||
#endif
|
||||
|
||||
// When a process receives a system message, we hold a CPU wake lock on its
|
||||
// behalf for this many seconds, or until it handles the system message,
|
||||
// whichever comes first.
|
||||
pref("dom.ipc.systemMessageCPULockTimeoutSec", 30);
|
||||
|
||||
// Ignore the "dialog=1" feature in window.open.
|
||||
pref("dom.disable_window_open_dialog_feature", true);
|
||||
|
||||
|
@ -526,7 +526,8 @@ var shell = {
|
||||
url: msg.uri,
|
||||
manifestURL: msg.manifest,
|
||||
isActivity: (msg.type == 'activity'),
|
||||
target: msg.target
|
||||
target: msg.target,
|
||||
expectingSystemMessage: true
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -129,7 +129,6 @@
|
||||
#ifdef ACCESSIBILITY
|
||||
#ifdef XP_WIN32
|
||||
@BINPATH@/AccessibleMarshal.dll
|
||||
@BINPATH@/components/accessibility-msaa.xpt
|
||||
#endif
|
||||
@BINPATH@/components/accessibility.xpt
|
||||
#endif
|
||||
|
@ -119,10 +119,6 @@ ifeq ($(OS_ARCH),WINNT) #{
|
||||
#
|
||||
ifndef GNU_CC #{
|
||||
LDFLAGS += /HEAP:0x40000
|
||||
ifeq ($(OS_TEST),x86_64) #{
|
||||
# set stack to 2MB on x64 build. See bug 582910
|
||||
LDFLAGS += -STACK:2097152
|
||||
endif #}
|
||||
endif #}
|
||||
endif #}
|
||||
|
||||
|
@ -8,6 +8,11 @@ var gPluginHandler = {
|
||||
PLUGIN_SCRIPTED_STATE_FIRED: 1,
|
||||
PLUGIN_SCRIPTED_STATE_DONE: 2,
|
||||
|
||||
getPluginUI: function (plugin, className) {
|
||||
return plugin.ownerDocument.
|
||||
getAnonymousElementByAttribute(plugin, "class", className);
|
||||
},
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
get CrashSubmit() {
|
||||
delete this.CrashSubmit;
|
||||
@ -304,10 +309,19 @@ var gPluginHandler = {
|
||||
let browser = gBrowser.getBrowserForDocument(objLoadingContent.ownerDocument.defaultView.top.document);
|
||||
let pluginPermission = Services.perms.testPermission(browser.currentURI, permissionString);
|
||||
|
||||
let isFallbackTypeValid =
|
||||
objLoadingContent.pluginFallbackType >= Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY &&
|
||||
objLoadingContent.pluginFallbackType <= Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE;
|
||||
|
||||
if (objLoadingContent.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW) {
|
||||
// checking if play preview is subject to CTP rules
|
||||
let playPreviewInfo = pluginHost.getPlayPreviewInfo(objLoadingContent.actualType);
|
||||
isFallbackTypeValid = !playPreviewInfo.ignoreCTP;
|
||||
}
|
||||
|
||||
return !objLoadingContent.activated &&
|
||||
pluginPermission != Ci.nsIPermissionManager.DENY_ACTION &&
|
||||
objLoadingContent.pluginFallbackType >= Ci.nsIObjectLoadingContent.PLUGIN_CLICK_TO_PLAY &&
|
||||
objLoadingContent.pluginFallbackType <= Ci.nsIObjectLoadingContent.PLUGIN_VULNERABLE_NO_UPDATE;
|
||||
isFallbackTypeValid;
|
||||
},
|
||||
|
||||
activatePlugins: function PH_activatePlugins(aContentWindow) {
|
||||
@ -400,11 +414,16 @@ var gPluginHandler = {
|
||||
},
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
// Callback for user clicking "submit a report" link
|
||||
submitReport : function(pluginDumpID, browserDumpID) {
|
||||
// The crash reporter wants a DOM element it can append an IFRAME to,
|
||||
// which it uses to submit a form. Let's just give it gBrowser.
|
||||
this.CrashSubmit.submit(pluginDumpID);
|
||||
submitReport: function submitReport(pluginDumpID, browserDumpID, plugin) {
|
||||
let keyVals = {};
|
||||
if (plugin) {
|
||||
let userComment = this.getPluginUI(plugin, "submitComment").value.trim();
|
||||
if (userComment)
|
||||
keyVals.PluginUserComment = userComment;
|
||||
if (this.getPluginUI(plugin, "submitURLOptIn").checked)
|
||||
keyVals.PluginContentURL = plugin.ownerDocument.URL;
|
||||
}
|
||||
this.CrashSubmit.submit(pluginDumpID, { extraExtraKeyVals: keyVals });
|
||||
if (browserDumpID)
|
||||
this.CrashSubmit.submit(browserDumpID);
|
||||
},
|
||||
@ -472,6 +491,21 @@ var gPluginHandler = {
|
||||
|
||||
_handlePlayPreviewEvent: function PH_handlePlayPreviewEvent(aPlugin) {
|
||||
let doc = aPlugin.ownerDocument;
|
||||
let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
|
||||
let pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
let pluginInfo = this._getPluginInfo(aPlugin);
|
||||
let playPreviewInfo = pluginHost.getPlayPreviewInfo(pluginInfo.mimetype);
|
||||
|
||||
if (!playPreviewInfo.ignoreCTP) {
|
||||
// if click-to-play rules used, play plugin at once if plugins were
|
||||
// activated for this window
|
||||
if (browser._clickToPlayAllPluginsActivated ||
|
||||
browser._clickToPlayPluginsActivated.get(pluginInfo.pluginName)) {
|
||||
objLoadingContent.playPlugin();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
let previewContent = doc.getAnonymousElementByAttribute(aPlugin, "class", "previewPluginContent");
|
||||
let iframe = previewContent.getElementsByClassName("previewPluginContentFrame")[0];
|
||||
if (!iframe) {
|
||||
@ -483,9 +517,7 @@ var gPluginHandler = {
|
||||
// Force a style flush, so that we ensure our binding is attached.
|
||||
aPlugin.clientTop;
|
||||
}
|
||||
let pluginInfo = this._getPluginInfo(aPlugin);
|
||||
let playPreviewUri = "data:application/x-moz-playpreview;," + pluginInfo.mimetype;
|
||||
iframe.src = playPreviewUri;
|
||||
iframe.src = playPreviewInfo.redirectURL;
|
||||
|
||||
// MozPlayPlugin event can be dispatched from the extension chrome
|
||||
// code to replace the preview content with the native plugin
|
||||
@ -503,6 +535,10 @@ var gPluginHandler = {
|
||||
if (iframe)
|
||||
previewContent.removeChild(iframe);
|
||||
}, true);
|
||||
|
||||
if (!playPreviewInfo.ignoreCTP) {
|
||||
gPluginHandler._showClickToPlayNotification(browser);
|
||||
}
|
||||
},
|
||||
|
||||
reshowClickToPlayNotification: function PH_reshowClickToPlayNotification() {
|
||||
@ -911,11 +947,16 @@ var gPluginHandler = {
|
||||
}
|
||||
else { // doPrompt
|
||||
status = "please";
|
||||
// XXX can we make the link target actually be blank?
|
||||
let pleaseLink = doc.getAnonymousElementByAttribute(
|
||||
plugin, "class", "pleaseSubmitLink");
|
||||
this.addLinkClickCallback(pleaseLink, "submitReport",
|
||||
pluginDumpID, browserDumpID);
|
||||
this.getPluginUI(plugin, "submitButton").addEventListener("click",
|
||||
function (event) {
|
||||
if (event.button != 0 || !event.isTrusted)
|
||||
return;
|
||||
this.submitReport(pluginDumpID, browserDumpID, plugin);
|
||||
pref.setBoolPref("", optInCB.checked);
|
||||
}.bind(this));
|
||||
let optInCB = this.getPluginUI(plugin, "submitURLOptIn");
|
||||
let pref = Services.prefs.getBranch("dom.ipc.plugins.reportCrashURL");
|
||||
optInCB.checked = pref.getBoolPref("");
|
||||
}
|
||||
|
||||
// If we don't have a minidumpID, we can't (or didn't) submit anything.
|
||||
@ -926,8 +967,6 @@ var gPluginHandler = {
|
||||
|
||||
statusDiv.setAttribute("status", status);
|
||||
|
||||
let bottomLinks = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgBottomLinks");
|
||||
bottomLinks.style.display = "block";
|
||||
let helpIcon = doc.getAnonymousElementByAttribute(plugin, "class", "helpIcon");
|
||||
this.addLinkClickCallback(helpIcon, "openHelpPage");
|
||||
|
||||
@ -964,7 +1003,7 @@ var gPluginHandler = {
|
||||
}
|
||||
#endif
|
||||
|
||||
let crashText = doc.getAnonymousElementByAttribute(plugin, "class", "msg msgCrashed");
|
||||
let crashText = doc.getAnonymousElementByAttribute(plugin, "class", "msgCrashedText");
|
||||
crashText.textContent = messageString;
|
||||
|
||||
let browser = gBrowser.getBrowserForDocument(doc.defaultView.top.document);
|
||||
@ -974,21 +1013,32 @@ var gPluginHandler = {
|
||||
|
||||
let notificationBox = gBrowser.getNotificationBox(browser);
|
||||
|
||||
let isShowing = true;
|
||||
|
||||
// Is the <object>'s size too small to hold what we want to show?
|
||||
if (this.isTooSmall(plugin, overlay)) {
|
||||
// Hide the overlay's contents. Use visibility style, so that it
|
||||
// doesn't collapse down to 0x0.
|
||||
// First try hiding the crash report submission UI.
|
||||
statusDiv.removeAttribute("status");
|
||||
|
||||
if (this.isTooSmall(plugin, overlay)) {
|
||||
// Hide the overlay's contents. Use visibility style, so that it doesn't
|
||||
// collapse down to 0x0.
|
||||
overlay.style.visibility = "hidden";
|
||||
// If another plugin on the page was large enough to show our UI, we
|
||||
// don't want to show a notification bar.
|
||||
if (!doc.mozNoPluginCrashedNotification)
|
||||
showNotificationBar(pluginDumpID, browserDumpID);
|
||||
isShowing = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (isShowing) {
|
||||
// If a previous plugin on the page was too small and resulted in adding a
|
||||
// notification bar, then remove it because this plugin instance it big
|
||||
// enough to serve as in-content notification.
|
||||
hideNotificationBar();
|
||||
doc.mozNoPluginCrashedNotification = true;
|
||||
} else {
|
||||
// If a previous plugin on the page was too small and resulted in
|
||||
// adding a notification bar, then remove it because this plugin
|
||||
// instance it big enough to serve as in-content notification.
|
||||
hideNotificationBar();
|
||||
doc.mozNoPluginCrashedNotification = true;
|
||||
// If another plugin on the page was large enough to show our UI, we don't
|
||||
// want to show a notification bar.
|
||||
if (!doc.mozNoPluginCrashedNotification)
|
||||
showNotificationBar(pluginDumpID, browserDumpID);
|
||||
}
|
||||
|
||||
function hideNotificationBar() {
|
||||
|
@ -994,6 +994,9 @@ let gGestureSupport = {
|
||||
let contentElement = content.document.body.firstElementChild;
|
||||
if (!contentElement)
|
||||
return;
|
||||
// If we're currently snapping, cancel that snap
|
||||
if (contentElement.classList.contains("completeRotation"))
|
||||
this._clearCompleteRotation();
|
||||
|
||||
this.rotation = Math.round(this.rotation + aEvent.delta);
|
||||
contentElement.style.transform = "rotate(" + this.rotation + "deg)";
|
||||
@ -1036,8 +1039,11 @@ let gGestureSupport = {
|
||||
this.rotation < transitionRotation)
|
||||
transitionRotation -= 90;
|
||||
|
||||
contentElement.classList.add("completeRotation");
|
||||
contentElement.addEventListener("transitionend", this._clearCompleteRotation);
|
||||
// Only add the completeRotation class if it is is necessary
|
||||
if (transitionRotation != this.rotation) {
|
||||
contentElement.classList.add("completeRotation");
|
||||
contentElement.addEventListener("transitionend", this._clearCompleteRotation);
|
||||
}
|
||||
|
||||
contentElement.style.transform = "rotate(" + transitionRotation + "deg)";
|
||||
this.rotation = transitionRotation;
|
||||
@ -1094,8 +1100,14 @@ let gGestureSupport = {
|
||||
* Removes the transition rule by removing the completeRotation class
|
||||
*/
|
||||
_clearCompleteRotation: function() {
|
||||
this.classList.remove("completeRotation");
|
||||
this.removeEventListener("transitionend", this._clearCompleteRotation);
|
||||
let contentElement = content.document &&
|
||||
content.document instanceof ImageDocument &&
|
||||
content.document.body &&
|
||||
content.document.body.firstElementChild;
|
||||
if (!contentElement)
|
||||
return;
|
||||
contentElement.classList.remove("completeRotation");
|
||||
contentElement.removeEventListener("transitionend", this._clearCompleteRotation);
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -265,7 +265,6 @@
|
||||
class="social-panel"
|
||||
type="arrow"
|
||||
hidden="true"
|
||||
consumeoutsideclicks="false"
|
||||
noautofocus="true"/>
|
||||
<panel id="social-flyout-panel"
|
||||
class="social-panel"
|
||||
|
@ -186,6 +186,7 @@ _BROWSER_FILES = \
|
||||
browser_plugins_added_dynamically.js \
|
||||
browser_CTPScriptPlugin.js \
|
||||
browser_pluginplaypreview.js \
|
||||
browser_pluginplaypreview2.js \
|
||||
browser_private_browsing_window.js \
|
||||
browser_relatedTabs.js \
|
||||
browser_sanitize-passwordDisabledHosts.js \
|
||||
@ -222,6 +223,7 @@ _BROWSER_FILES = \
|
||||
browser_urlbarRevert.js \
|
||||
browser_urlbarStop.js \
|
||||
browser_urlbarTrimURLs.js \
|
||||
browser_urlbar_search_healthreport.js \
|
||||
browser_urlHighlight.js \
|
||||
browser_visibleFindSelection.js \
|
||||
browser_visibleTabs.js \
|
||||
@ -301,6 +303,8 @@ _BROWSER_FILES = \
|
||||
browser_pageInfo_plugins.js \
|
||||
browser_pageInfo.js \
|
||||
feed_tab.html \
|
||||
browser_pluginCrashCommentAndURL.js \
|
||||
pluginCrashCommentAndURL.html \
|
||||
$(NULL)
|
||||
|
||||
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
|
154
browser/base/content/test/browser_pluginCrashCommentAndURL.js
Normal file
154
browser/base/content/test/browser_pluginCrashCommentAndURL.js
Normal file
@ -0,0 +1,154 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
const CRASH_URL = "http://example.com/browser/browser/base/content/test/pluginCrashCommentAndURL.html";
|
||||
|
||||
const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs";
|
||||
|
||||
function test() {
|
||||
// Crashing the plugin takes up a lot of time, so extend the test timeout.
|
||||
requestLongerTimeout(runs.length);
|
||||
waitForExplicitFinish();
|
||||
|
||||
// The test harness sets MOZ_CRASHREPORTER_NO_REPORT, which disables plugin
|
||||
// crash reports. This test needs them enabled. The test also needs a mock
|
||||
// report server, and fortunately one is already set up by toolkit/
|
||||
// crashreporter/test/Makefile.in. Assign its URL to MOZ_CRASHREPORTER_URL,
|
||||
// which CrashSubmit.jsm uses as a server override.
|
||||
let env = Cc["@mozilla.org/process/environment;1"].
|
||||
getService(Components.interfaces.nsIEnvironment);
|
||||
let noReport = env.get("MOZ_CRASHREPORTER_NO_REPORT");
|
||||
let serverURL = env.get("MOZ_CRASHREPORTER_URL");
|
||||
env.set("MOZ_CRASHREPORTER_NO_REPORT", "");
|
||||
env.set("MOZ_CRASHREPORTER_URL", SERVER_URL);
|
||||
|
||||
let tab = gBrowser.loadOneTab("about:blank", { inBackground: false });
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
browser.addEventListener("PluginCrashed", onCrash, false);
|
||||
Services.obs.addObserver(onSubmitStatus, "crash-report-status", false);
|
||||
|
||||
registerCleanupFunction(function cleanUp() {
|
||||
env.set("MOZ_CRASHREPORTER_NO_REPORT", noReport);
|
||||
env.set("MOZ_CRASHREPORTER_URL", serverURL);
|
||||
gBrowser.selectedBrowser.removeEventListener("PluginCrashed", onCrash,
|
||||
false);
|
||||
Services.obs.removeObserver(onSubmitStatus, "crash-report-status");
|
||||
gBrowser.removeCurrentTab();
|
||||
});
|
||||
|
||||
doNextRun();
|
||||
}
|
||||
|
||||
let runs = [
|
||||
{
|
||||
shouldSubmissionUIBeVisible: true,
|
||||
comment: "",
|
||||
urlOptIn: false,
|
||||
},
|
||||
{
|
||||
shouldSubmissionUIBeVisible: true,
|
||||
comment: "a test comment",
|
||||
urlOptIn: true,
|
||||
},
|
||||
{
|
||||
width: 300,
|
||||
height: 300,
|
||||
shouldSubmissionUIBeVisible: false,
|
||||
},
|
||||
];
|
||||
|
||||
let currentRun = null;
|
||||
|
||||
function doNextRun() {
|
||||
try {
|
||||
if (!runs.length) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
currentRun = runs.shift();
|
||||
let args = ["width", "height"].reduce(function (memo, arg) {
|
||||
if (arg in currentRun)
|
||||
memo[arg] = currentRun[arg];
|
||||
return memo;
|
||||
}, {});
|
||||
gBrowser.loadURI(CRASH_URL + "?" +
|
||||
encodeURIComponent(JSON.stringify(args)));
|
||||
// And now wait for the crash.
|
||||
}
|
||||
catch (err) {
|
||||
failWithException(err);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
function onCrash() {
|
||||
try {
|
||||
let plugin = gBrowser.contentDocument.getElementById("plugin");
|
||||
let elt = gPluginHandler.getPluginUI.bind(gPluginHandler, plugin);
|
||||
let style =
|
||||
gBrowser.contentWindow.getComputedStyle(elt("msg msgPleaseSubmit"));
|
||||
is(style.display,
|
||||
currentRun.shouldSubmissionUIBeVisible ? "block" : "none",
|
||||
"Submission UI visibility should be correct");
|
||||
if (!currentRun.shouldSubmissionUIBeVisible) {
|
||||
// Done with this run.
|
||||
doNextRun();
|
||||
return;
|
||||
}
|
||||
elt("submitComment").value = currentRun.comment;
|
||||
elt("submitURLOptIn").checked = currentRun.urlOptIn;
|
||||
elt("submitButton").click();
|
||||
// And now wait for the submission status notification.
|
||||
}
|
||||
catch (err) {
|
||||
failWithException(err);
|
||||
doNextRun();
|
||||
}
|
||||
}
|
||||
|
||||
function onSubmitStatus(subj, topic, data) {
|
||||
try {
|
||||
// Wait for success or failed, doesn't matter which.
|
||||
if (data != "success" && data != "failed")
|
||||
return;
|
||||
|
||||
let extra = getPropertyBagValue(subj.QueryInterface(Ci.nsIPropertyBag),
|
||||
"extra");
|
||||
ok(extra instanceof Ci.nsIPropertyBag, "Extra data should be property bag");
|
||||
|
||||
let val = getPropertyBagValue(extra, "PluginUserComment");
|
||||
if (currentRun.comment)
|
||||
is(val, currentRun.comment,
|
||||
"Comment in extra data should match comment in textbox");
|
||||
else
|
||||
ok(val === undefined,
|
||||
"Comment should be absent from extra data when textbox is empty");
|
||||
|
||||
val = getPropertyBagValue(extra, "PluginContentURL");
|
||||
if (currentRun.urlOptIn)
|
||||
is(val, gBrowser.currentURI.spec,
|
||||
"URL in extra data should match browser URL when opt-in checked");
|
||||
else
|
||||
ok(val === undefined,
|
||||
"URL should be absent from extra data when opt-in not checked");
|
||||
}
|
||||
catch (err) {
|
||||
failWithException(err);
|
||||
}
|
||||
doNextRun();
|
||||
}
|
||||
|
||||
function getPropertyBagValue(bag, key) {
|
||||
try {
|
||||
var val = bag.getProperty(key);
|
||||
}
|
||||
catch (e if e.result == Cr.NS_ERROR_FAILURE) {}
|
||||
return val;
|
||||
}
|
||||
|
||||
function failWithException(err) {
|
||||
ok(false, "Uncaught exception: " + err + "\n" + err.stack);
|
||||
}
|
@ -111,7 +111,7 @@ function registerPlayPreview(mimeType, targetUrl) {
|
||||
};
|
||||
|
||||
var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
ph.registerPlayPreviewMimeType(mimeType);
|
||||
ph.registerPlayPreviewMimeType(mimeType, true); // ignoring CTP rules
|
||||
|
||||
var factory = new StreamConverterFactory();
|
||||
factory.register(OverlayStreamConverter);
|
||||
|
173
browser/base/content/test/browser_pluginplaypreview2.js
Normal file
173
browser/base/content/test/browser_pluginplaypreview2.js
Normal file
@ -0,0 +1,173 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
var rootDir = getRootDirectory(gTestPath);
|
||||
const gTestRoot = rootDir;
|
||||
|
||||
var gTestBrowser = null;
|
||||
var gNextTest = null;
|
||||
var gNextTestSkip = 0;
|
||||
var gPlayPreviewPluginActualEvents = 0;
|
||||
var gPlayPreviewPluginExpectedEvents = 1;
|
||||
|
||||
var gPlayPreviewRegistration = null;
|
||||
|
||||
function registerPlayPreview(mimeType, targetUrl) {
|
||||
var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
|
||||
ph.registerPlayPreviewMimeType(mimeType, false, targetUrl);
|
||||
|
||||
return (gPlayPreviewRegistration = {
|
||||
unregister: function() {
|
||||
ph.unregisterPlayPreviewMimeType(mimeType);
|
||||
gPlayPreviewRegistration = null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function unregisterPlayPreview() {
|
||||
gPlayPreviewRegistration.unregister();
|
||||
}
|
||||
|
||||
Components.utils.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
registerCleanupFunction(function() {
|
||||
if (gPlayPreviewRegistration)
|
||||
gPlayPreviewRegistration.unregister();
|
||||
Services.prefs.clearUserPref("plugins.click_to_play");
|
||||
});
|
||||
|
||||
var newTab = gBrowser.addTab();
|
||||
gBrowser.selectedTab = newTab;
|
||||
gTestBrowser = gBrowser.selectedBrowser;
|
||||
gTestBrowser.addEventListener("load", pageLoad, true);
|
||||
gTestBrowser.addEventListener("PluginBindingAttached", handleBindingAttached, true, true);
|
||||
|
||||
Services.prefs.setBoolPref("plugins.click_to_play", true);
|
||||
|
||||
registerPlayPreview('application/x-test', 'about:');
|
||||
prepareTest(test1a, gTestRoot + "plugin_test.html", 1);
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
gTestBrowser.removeEventListener("load", pageLoad, true);
|
||||
gTestBrowser.removeEventListener("PluginBindingAttached", handleBindingAttached, true, true);
|
||||
gBrowser.removeCurrentTab();
|
||||
window.focus();
|
||||
finish();
|
||||
}
|
||||
|
||||
function handleBindingAttached(evt) {
|
||||
if (evt.target instanceof Ci.nsIObjectLoadingContent &&
|
||||
evt.target.pluginFallbackType == Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW)
|
||||
gPlayPreviewPluginActualEvents++;
|
||||
}
|
||||
|
||||
function pageLoad() {
|
||||
// The plugin events are async dispatched and can come after the load event
|
||||
// This just allows the events to fire before we then go on to test the states
|
||||
|
||||
// iframe might triggers load event as well, making sure we skip some to let
|
||||
// all iframes on the page be loaded as well
|
||||
if (gNextTestSkip) {
|
||||
gNextTestSkip--;
|
||||
return;
|
||||
}
|
||||
executeSoon(gNextTest);
|
||||
}
|
||||
|
||||
function prepareTest(nextTest, url, skip) {
|
||||
gNextTest = nextTest;
|
||||
gNextTestSkip = skip;
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
|
||||
// Tests a page with normal play preview registration (1/2)
|
||||
function test1a() {
|
||||
var notificationBox = gBrowser.getNotificationBox(gTestBrowser);
|
||||
ok(!notificationBox.getNotificationWithValue("missing-plugins"), "Test 1a, Should not have displayed the missing plugin notification");
|
||||
ok(!notificationBox.getNotificationWithValue("blocked-plugins"), "Test 1a, Should not have displayed the blocked plugin notification");
|
||||
|
||||
var pluginInfo = getTestPlugin();
|
||||
ok(pluginInfo, "Should have a test plugin");
|
||||
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
is(objLoadingContent.pluginFallbackType, Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 1a, plugin fallback type should be PLUGIN_PLAY_PREVIEW");
|
||||
ok(!objLoadingContent.activated, "Test 1a, Plugin should not be activated");
|
||||
|
||||
var overlay = doc.getAnonymousElementByAttribute(plugin, "class", "previewPluginContent");
|
||||
ok(overlay, "Test 1a, the overlay div is expected");
|
||||
|
||||
var iframe = overlay.getElementsByClassName("previewPluginContentFrame")[0];
|
||||
ok(iframe && iframe.localName == "iframe", "Test 1a, the overlay iframe is expected");
|
||||
var iframeHref = iframe.contentWindow.location.href;
|
||||
ok(iframeHref == "about:", "Test 1a, the overlay about: content is expected");
|
||||
|
||||
var rect = iframe.getBoundingClientRect();
|
||||
ok(rect.width == 200, "Test 1a, Plugin with id=" + plugin.id + " overlay rect should have 200px width before being replaced by actual plugin");
|
||||
ok(rect.height == 200, "Test 1a, Plugin with id=" + plugin.id + " overlay rect should have 200px height before being replaced by actual plugin");
|
||||
|
||||
var e = overlay.ownerDocument.createEvent("CustomEvent");
|
||||
e.initCustomEvent("MozPlayPlugin", true, true, null);
|
||||
overlay.dispatchEvent(e);
|
||||
var condition = function() objLoadingContent.activated;
|
||||
waitForCondition(condition, test1b, "Test 1a, Waited too long for plugin to stop play preview");
|
||||
}
|
||||
|
||||
// Tests that activating via MozPlayPlugin through the notification works (part 2/2)
|
||||
function test1b() {
|
||||
var plugin = gTestBrowser.contentDocument.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.activated, "Test 1b, Plugin should be activated");
|
||||
|
||||
is(gPlayPreviewPluginActualEvents, gPlayPreviewPluginExpectedEvents,
|
||||
"There should be exactly one PluginPlayPreview event");
|
||||
|
||||
unregisterPlayPreview();
|
||||
|
||||
prepareTest(test2, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
// Tests a page with a working plugin in it -- the mime type was just unregistered.
|
||||
function test2() {
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.pluginFallbackType != Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 2, plugin fallback type should not be PLUGIN_PLAY_PREVIEW");
|
||||
ok(!objLoadingContent.activated, "Test 2, Plugin should not be activated");
|
||||
|
||||
registerPlayPreview('application/x-unknown', 'about:');
|
||||
|
||||
prepareTest(test3, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
// Tests a page with a working plugin in it -- diffent play preview type is reserved.
|
||||
function test3() {
|
||||
var doc = gTestBrowser.contentDocument;
|
||||
var plugin = doc.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.pluginFallbackType != Ci.nsIObjectLoadingContent.PLUGIN_PLAY_PREVIEW, "Test 3, plugin fallback type should not be PLUGIN_PLAY_PREVIEW");
|
||||
ok(!objLoadingContent.activated, "Test 3, Plugin should not be activated");
|
||||
|
||||
unregisterPlayPreview();
|
||||
|
||||
registerPlayPreview('application/x-test', 'about:');
|
||||
Services.prefs.setBoolPref("plugins.click_to_play", false);
|
||||
prepareTest(test4, gTestRoot + "plugin_test.html");
|
||||
}
|
||||
|
||||
// Tests a page with a working plugin in it -- click-to-play is off
|
||||
function test4() {
|
||||
var plugin = gTestBrowser.contentDocument.getElementById("test");
|
||||
var objLoadingContent = plugin.QueryInterface(Ci.nsIObjectLoadingContent);
|
||||
ok(objLoadingContent.activated, "Test 4, Plugin should be activated");
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
@ -0,0 +1,62 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
if (!("@mozilla.org/datareporting/service;1" in Cc)) {
|
||||
ok(true, "Firefox Health Report is not enabled.");
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
let reporter = Cc["@mozilla.org/datareporting/service;1"]
|
||||
.getService()
|
||||
.wrappedJSObject
|
||||
.healthReporter;
|
||||
ok(reporter, "Health Reporter available.");
|
||||
reporter.onInit().then(function onInit() {
|
||||
let provider = reporter.getProvider("org.mozilla.searches");
|
||||
ok(provider, "Searches provider is available.");
|
||||
let m = provider.getMeasurement("counts", 1);
|
||||
|
||||
m.getValues().then(function onData(data) {
|
||||
let now = new Date();
|
||||
let oldCount = 0;
|
||||
|
||||
// This will need changed if default search engine is not Google.
|
||||
let field = "google.urlbar";
|
||||
|
||||
if (data.days.hasDay(now)) {
|
||||
let day = data.days.getDay(now);
|
||||
if (day.has(field)) {
|
||||
oldCount = day.get(field);
|
||||
}
|
||||
}
|
||||
|
||||
let tab = gBrowser.addTab();
|
||||
gBrowser.selectedTab = tab;
|
||||
|
||||
gURLBar.value = "firefox health report";
|
||||
gURLBar.handleCommand();
|
||||
|
||||
executeSoon(function afterSearch() {
|
||||
gBrowser.removeTab(tab);
|
||||
|
||||
m.getValues().then(function onData(data) {
|
||||
ok(data.days.hasDay(now), "FHR has data for today.");
|
||||
let day = data.days.getDay(now);
|
||||
ok(day.has(field), "FHR has url bar count for today.");
|
||||
|
||||
let newCount = day.get(field);
|
||||
|
||||
is(newCount, oldCount + 1, "Exactly one search has been recorded.");
|
||||
finish();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
27
browser/base/content/test/pluginCrashCommentAndURL.html
Normal file
27
browser/base/content/test/pluginCrashCommentAndURL.html
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
|
||||
<script type="text/javascript">
|
||||
function crash() {
|
||||
var plugin = document.getElementById("plugin");
|
||||
var argStr = decodeURIComponent(window.location.search.substr(1));
|
||||
if (argStr) {
|
||||
var args = JSON.parse(argStr);
|
||||
for (var key in args)
|
||||
plugin.setAttribute(key, args[key]);
|
||||
}
|
||||
try {
|
||||
plugin.crash();
|
||||
}
|
||||
catch (err) {}
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
<body onload="crash();">
|
||||
<embed id="plugin" type="application/x-test"
|
||||
width="400" height="400"
|
||||
drawmode="solid" color="FF00FFFF">
|
||||
</embed>
|
||||
</body>
|
||||
</html>
|
@ -290,8 +290,33 @@ BrowserGlue.prototype = {
|
||||
case "profile-before-change":
|
||||
this._onProfileShutdown();
|
||||
break;
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
case "keyword-search":
|
||||
// This is very similar to code in
|
||||
// browser.js:BrowserSearch.recordSearchInHealthReport(). The code could
|
||||
// be consolidated if there is will. We need the observer in
|
||||
// nsBrowserGlue to prevent double counting.
|
||||
let reporter = Cc["@mozilla.org/datareporting/service;1"]
|
||||
.getService()
|
||||
.wrappedJSObject
|
||||
.healthReporter;
|
||||
|
||||
if (!reporter) {
|
||||
return;
|
||||
}
|
||||
|
||||
reporter.onInit().then(function record() {
|
||||
try {
|
||||
reporter.getProvider("org.mozilla.searches").recordSearch(data,
|
||||
"urlbar");
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
});
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
// initialization (called on application startup)
|
||||
_init: function BG__init() {
|
||||
@ -322,6 +347,9 @@ BrowserGlue.prototype = {
|
||||
os.addObserver(this, "defaultURIFixup-using-keyword-pref", false);
|
||||
os.addObserver(this, "handle-xul-text-link", false);
|
||||
os.addObserver(this, "profile-before-change", false);
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
os.addObserver(this, "keyword-search", false);
|
||||
#endif
|
||||
},
|
||||
|
||||
// cleanup (called on application shutdown)
|
||||
@ -353,6 +381,9 @@ BrowserGlue.prototype = {
|
||||
os.removeObserver(this, "defaultURIFixup-using-keyword-pref");
|
||||
os.removeObserver(this, "handle-xul-text-link");
|
||||
os.removeObserver(this, "profile-before-change");
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
os.removeObserver(this, "keyword-search");
|
||||
#endif
|
||||
},
|
||||
|
||||
_onAppDefaults: function BG__onAppDefaults() {
|
||||
|
@ -3,6 +3,7 @@
|
||||
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
|
||||
ac_add_options --enable-update-packaging
|
||||
ac_add_options --with-l10n-base=../../l10n-central
|
||||
ac_add_options --enable-metro
|
||||
|
||||
export MOZILLA_OFFICIAL=1
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource:///modules/devtools/gDevTools.jsm");
|
||||
Cu.import("resource:///modules/devtools/ProfilerController.jsm");
|
||||
Cu.import("resource:///modules/devtools/ProfilerHelpers.jsm");
|
||||
Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js");
|
||||
@ -14,10 +15,11 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["ProfilerPanel"];
|
||||
|
||||
XPCOMUtils.defineLazyGetter(this, "DebuggerServer", function () {
|
||||
Cu.import("resource://gre/modules/devtools/dbg-server.jsm");
|
||||
return DebuggerServer;
|
||||
});
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DebuggerServer",
|
||||
"resource://gre/modules/devtools/dbg-server.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "Services",
|
||||
"resource://gre/modules/Services.jsm");
|
||||
|
||||
/**
|
||||
* An instance of a profile UI. Profile UI consists of
|
||||
@ -105,6 +107,9 @@ function ProfileUI(uid, panel) {
|
||||
break;
|
||||
case "enabled":
|
||||
this.emit("enabled");
|
||||
break;
|
||||
case "displaysource":
|
||||
this.panel.displaySource(event.data.data);
|
||||
}
|
||||
}.bind(this));
|
||||
}
|
||||
@ -219,6 +224,7 @@ ProfilerPanel.prototype = {
|
||||
_uid: null,
|
||||
_activeUid: null,
|
||||
_runningUid: null,
|
||||
_browserWin: null,
|
||||
|
||||
get activeProfile() {
|
||||
return this.profiles.get(this._activeUid);
|
||||
@ -228,6 +234,21 @@ ProfilerPanel.prototype = {
|
||||
this._activeUid = profile.uid;
|
||||
},
|
||||
|
||||
get browserWindow() {
|
||||
if (this._browserWin) {
|
||||
return this._browserWin;
|
||||
}
|
||||
|
||||
let win = this.window.top;
|
||||
let type = win.document.documentElement.getAttribute("windowtype");
|
||||
|
||||
if (type !== "navigator:browser") {
|
||||
win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||
}
|
||||
|
||||
return this._browserWin = win;
|
||||
},
|
||||
|
||||
/**
|
||||
* Open a debug connection and, on success, switch to the newly created
|
||||
* profile.
|
||||
@ -416,6 +437,48 @@ ProfilerPanel.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Open file specified in data in either a debugger or view-source.
|
||||
*
|
||||
* @param object data
|
||||
* An object describing the file. It must have three properties:
|
||||
* - uri
|
||||
* - line
|
||||
* - isChrome (chrome files are opened via view-source)
|
||||
*/
|
||||
displaySource: function PP_displaySource(data, onOpen=function() {}) {
|
||||
let win = this.window;
|
||||
let panelWin, timeout;
|
||||
|
||||
function onSourceShown(event) {
|
||||
if (event.detail.url !== data.uri) {
|
||||
return;
|
||||
}
|
||||
|
||||
panelWin.removeEventListener("Debugger:SourceShown", onSourceShown, false);
|
||||
panelWin.editor.setCaretPosition(data.line - 1);
|
||||
onOpen();
|
||||
}
|
||||
|
||||
if (data.isChrome) {
|
||||
return void this.browserWindow.gViewSourceUtils.
|
||||
viewSource(data.uri, null, this.document, data.line);
|
||||
}
|
||||
|
||||
gDevTools.showToolbox(this.target, "jsdebugger").then(function (toolbox) {
|
||||
let dbg = toolbox.getCurrentPanel();
|
||||
panelWin = dbg.panelWin;
|
||||
|
||||
let view = dbg.panelWin.DebuggerView;
|
||||
if (view.Source && view.Sources.selectedValue === data.uri) {
|
||||
return void view.editor.setCaretPosition(data.line - 1);
|
||||
}
|
||||
|
||||
panelWin.addEventListener("Debugger:SourceShown", onSourceShown, false);
|
||||
panelWin.DebuggerView.Sources.preferredSource = data.uri;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Cleanup.
|
||||
*/
|
||||
|
@ -15,15 +15,19 @@ var gInstanceUID;
|
||||
* - stop, when user wants to stop profiling.
|
||||
* - disabled, when the profiler was disabled
|
||||
* - enabled, when the profiler was enabled
|
||||
* - displaysource, when user wants to display source
|
||||
* @param object data (optional)
|
||||
* Additional data to send to the parent page.
|
||||
*/
|
||||
function notifyParent(status) {
|
||||
function notifyParent(status, data={}) {
|
||||
if (!gInstanceUID) {
|
||||
gInstanceUID = window.location.search.substr(1);
|
||||
}
|
||||
|
||||
window.parent.postMessage({
|
||||
uid: gInstanceUID,
|
||||
status: status
|
||||
status: status,
|
||||
data: data
|
||||
}, "*");
|
||||
}
|
||||
|
||||
@ -197,7 +201,7 @@ function enterFinishedProfileUI() {
|
||||
|
||||
var currentBreadcrumb = gSampleFilters;
|
||||
gBreadcrumbTrail.add({
|
||||
title: "Complete Profile",
|
||||
title: gStrings["Complete Profile"],
|
||||
enterCallback: function () {
|
||||
gSampleFilters = [];
|
||||
filtersChanged();
|
||||
|
@ -466,7 +466,8 @@ TreeView.prototype = {
|
||||
'<span class="resourceIcon" data-resource="' + node.library + '"></span> ' +
|
||||
'<span class="functionName">' + nodeName + '</span>' +
|
||||
'<span class="libraryName">' + libName + '</span>' +
|
||||
'<input type="button" value="Focus Callstack" title="Focus Callstack" class="focusCallstackButton" tabindex="-1">';
|
||||
(nodeName === '(total)' ? '' :
|
||||
'<input type="button" value="Focus Callstack" title="Focus Callstack" class="focusCallstackButton" tabindex="-1">');
|
||||
},
|
||||
_resolveChildren: function TreeView__resolveChildren(div, childrenCollapsedValue) {
|
||||
while (div.pendingExpand != null && div.pendingExpand.length > 0) {
|
||||
|
@ -169,8 +169,12 @@ function ProfileTreeManager() {
|
||||
self._onContextMenuClick(e);
|
||||
});
|
||||
this.treeView.addEventListener("focusCallstackButtonClicked", function (frameData) {
|
||||
var focusedCallstack = self._getCallstackUpTo(frameData);
|
||||
focusOnCallstack(focusedCallstack, frameData.name);
|
||||
// NOTE: Not in the original Cleopatra source code.
|
||||
notifyParent("displaysource", {
|
||||
line: frameData.scriptLocation.lineInformation,
|
||||
uri: frameData.scriptLocation.scriptURI,
|
||||
isChrome: /^otherhost_*/.test(frameData.library)
|
||||
});
|
||||
});
|
||||
this._container = document.createElement("div");
|
||||
this._container.className = "tree";
|
||||
@ -1566,7 +1570,8 @@ function focusOnSymbol(focusSymbol, name) {
|
||||
}
|
||||
|
||||
function focusOnCallstack(focusedCallstack, name, overwriteCallstack) {
|
||||
var invertCallback = gInvertCallstack;
|
||||
var invertCallstack = gInvertCallstack;
|
||||
|
||||
if (overwriteCallstack != null) {
|
||||
invertCallstack = overwriteCallstack;
|
||||
}
|
||||
|
@ -10,12 +10,21 @@ relativesrcdir = @relativesrcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MOCHITEST_BROWSER_FILES = \
|
||||
MOCHITEST_BROWSER_TESTS = \
|
||||
browser_profiler_run.js \
|
||||
browser_profiler_controller.js \
|
||||
browser_profiler_profiles.js \
|
||||
browser_profiler_remote.js \
|
||||
browser_profiler_bug_830664_multiple_profiles.js \
|
||||
browser_profiler_bug_834878_source_buttons.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
MOCHITEST_BROWSER_PAGES = \
|
||||
mock_profiler_bug_834878_page.html \
|
||||
mock_profiler_bug_834878_script.js \
|
||||
$(NULL)
|
||||
|
||||
MOCHITEST_BROWSER_FILES_PARTS = MOCHITEST_BROWSER_TESTS MOCHITEST_BROWSER_PAGES
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -0,0 +1,29 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const BASE = "http://example.com/browser/browser/devtools/profiler/test/";
|
||||
const URL = BASE + "mock_profiler_bug_834878_page.html";
|
||||
const SCRIPT = BASE + "mock_profiler_bug_834878_script.js";
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
setUp(URL, function onSetUp(tab, browser, panel) {
|
||||
panel.once("profileCreated", function () {
|
||||
let data = { uri: SCRIPT, line: 5, isChrome: false };
|
||||
|
||||
panel.displaySource(data, function onOpen() {
|
||||
let target = TargetFactory.forTab(tab);
|
||||
let dbg = gDevTools.getToolbox(target).getPanel("jsdebugger");
|
||||
let view = dbg.panelWin.DebuggerView;
|
||||
|
||||
is(view.Sources.selectedValue, data.uri, "URI is different");
|
||||
is(view.editor.getCaretPosition().line, data.line - 1, "Line is different");
|
||||
|
||||
tearDown(tab);
|
||||
});
|
||||
});
|
||||
|
||||
panel.createProfile();
|
||||
});
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
<!-- Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ -->
|
||||
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='utf-8'/>
|
||||
<title>Profiler Script Linking Test</title>
|
||||
<script type="text/javascript" src="mock_profiler_bug_834878_script.js">
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,7 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function main() {
|
||||
console.log("Hello, World!");
|
||||
return 0;
|
||||
}
|
@ -139,7 +139,6 @@
|
||||
#ifdef ACCESSIBILITY
|
||||
#ifdef XP_WIN32
|
||||
@BINPATH@/AccessibleMarshal.dll
|
||||
@BINPATH@/components/accessibility-msaa.xpt
|
||||
#endif
|
||||
@BINPATH@/components/accessibility.xpt
|
||||
#endif
|
||||
|
@ -6,6 +6,37 @@
|
||||
; to launch the Win8 metro browser or desktop browser.
|
||||
!define DELEGATE_EXECUTE_HANDLER_ID {5100FEC1-212B-4BF5-9BF8-3E650FD794A3}
|
||||
|
||||
; Does metro registration for the command execute handler
|
||||
Function RegisterCEH
|
||||
!ifdef MOZ_METRO
|
||||
${If} ${AtLeastWin8}
|
||||
${CleanupMetroBrowserHandlerValues} ${DELEGATE_EXECUTE_HANDLER_ID}
|
||||
${AddMetroBrowserHandlerValues} ${DELEGATE_EXECUTE_HANDLER_ID} \
|
||||
"$INSTDIR\CommandExecuteHandler.exe" \
|
||||
$AppUserModelID \
|
||||
"FirefoxURL" \
|
||||
"FirefoxHTML"
|
||||
${EndIf}
|
||||
!endif
|
||||
FunctionEnd
|
||||
|
||||
; If MOZ_METRO is defined and we're at least win8, then we should re-create
|
||||
; the start menu shortcut so that the Metro browser is accessible.
|
||||
; This is also for zip builds who won't have a start menu shortcut yet.
|
||||
Function CreateStartMenuTile
|
||||
!ifdef MOZ_METRO
|
||||
Delete "$SMPROGRAMS\${BrandFullName}.lnk"
|
||||
CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}"
|
||||
${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk"
|
||||
ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \
|
||||
"$INSTDIR"
|
||||
${If} "$AppUserModelID" != ""
|
||||
ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "$AppUserModelID" "true"
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
!endif
|
||||
FunctionEnd
|
||||
|
||||
!macro PostUpdate
|
||||
${CreateShortcutsLog}
|
||||
|
||||
@ -23,6 +54,10 @@
|
||||
; Win7 taskbar and start menu link maintenance
|
||||
Call FixShortcutAppModelIDs
|
||||
|
||||
; Win8 specific registration
|
||||
Call RegisterCEH
|
||||
Call CreateStartMenuTile
|
||||
|
||||
ClearErrors
|
||||
WriteRegStr HKLM "Software\Mozilla" "${BrandShortName}InstallerTest" "Write Test"
|
||||
${If} ${Errors}
|
||||
@ -342,16 +377,7 @@
|
||||
|
||||
${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" \
|
||||
"true"
|
||||
!ifdef MOZ_METRO
|
||||
${If} ${AtLeastWin8}
|
||||
${CleanupMetroBrowserHandlerValues} ${DELEGATE_EXECUTE_HANDLER_ID}
|
||||
${AddMetroBrowserHandlerValues} ${DELEGATE_EXECUTE_HANDLER_ID} \
|
||||
"$INSTDIR\CommandExecuteHandler.exe" \
|
||||
$AppUserModelID \
|
||||
"FirefoxURL" \
|
||||
"FirefoxHTML"
|
||||
${EndIf}
|
||||
!endif
|
||||
Call RegisterCEH
|
||||
|
||||
; An empty string is used for the 4th & 5th params because the following
|
||||
; protocol handlers already have a display name and the additional keys
|
||||
@ -1149,20 +1175,7 @@ Function SetAsDefaultAppUserHKCU
|
||||
${SetStartMenuInternet} "HKCU"
|
||||
${FixShellIconHandler} "HKCU"
|
||||
${FixClassKeys} ; Does not use SHCTX
|
||||
; If MOZ_METRO is defined and we're at least win8, then we should re-create
|
||||
; the start menu shortcut so that the Metro browser is accessible.
|
||||
; This is also for zip builds who won't have a start menu shortcut yet.
|
||||
!ifdef MOZ_METRO
|
||||
Delete "$SMPROGRAMS\${BrandFullName}.lnk"
|
||||
CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}"
|
||||
${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk"
|
||||
ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \
|
||||
"$INSTDIR"
|
||||
${If} "$AppUserModelID" != ""
|
||||
ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "$AppUserModelID" "true"
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
!endif
|
||||
Call CreateStartMenuTile
|
||||
${EndIf}
|
||||
|
||||
${SetHandlers}
|
||||
|
@ -18,7 +18,7 @@ profiler.label=Profiler
|
||||
# LOCALIZATION NOTE (profiler.commandkey, profiler.accesskey)
|
||||
# Used for the menuitem in the tool menu
|
||||
profiler.commandkey=Y
|
||||
profiler.accesskey=Y
|
||||
profiler.accesskey=P
|
||||
|
||||
# LOCALIZATION NOTE (profiler.tooltip):
|
||||
# This string is displayed in the tooltip of the tab when the profiler is
|
||||
|
@ -5,6 +5,10 @@
|
||||
|
||||
#include "CEHHelper.h"
|
||||
|
||||
#ifdef SHOW_CONSOLE
|
||||
#include <io.h> // _open_osfhandle
|
||||
#endif
|
||||
|
||||
HANDLE sCon;
|
||||
LPCWSTR metroDX10Available = L"MetroD3DAvailable";
|
||||
|
||||
|
@ -21,7 +21,7 @@ extern LPCWSTR metroDX10Available;
|
||||
void Log(const wchar_t *fmt, ...);
|
||||
|
||||
#if defined(SHOW_CONSOLE)
|
||||
static void SetupConsole();
|
||||
void SetupConsole();
|
||||
#endif
|
||||
|
||||
bool IsDX10Available();
|
||||
|
@ -146,7 +146,7 @@ public:
|
||||
|
||||
#ifdef SHOW_CONSOLE
|
||||
Log(L"SetSelection param count: %d", count);
|
||||
for (int idx = 0; idx < count; idx++) {
|
||||
for (DWORD idx = 0; idx < count; idx++) {
|
||||
IShellItem* item = NULL;
|
||||
if (SUCCEEDED(aArray->GetItemAt(idx, &item))) {
|
||||
LPWSTR str = NULL;
|
||||
|
@ -56,13 +56,13 @@ fi
|
||||
CLANG_CC=
|
||||
CLANG_CXX=
|
||||
if test "$GCC" = yes; then
|
||||
if test "`$CC -v 2>&1 | grep -c 'clang version'`" != "0"; then
|
||||
if test "`$CC -v 2>&1 | grep -c 'clang version\|Apple.*clang'`" != "0"; then
|
||||
CLANG_CC=1
|
||||
fi
|
||||
fi
|
||||
|
||||
if test "$GXX" = yes; then
|
||||
if test "`$CXX -v 2>&1 | grep -c 'clang version'`" != "0"; then
|
||||
if test "`$CXX -v 2>&1 | grep -c 'clang version\|Apple.*clang'`" != "0"; then
|
||||
CLANG_CXX=1
|
||||
fi
|
||||
fi
|
||||
|
@ -533,6 +533,10 @@ user_pref("network.activity.blipIntervalMilliseconds", 250);
|
||||
// Don't allow the Data Reporting service to prompt for policy acceptance.
|
||||
user_pref("datareporting.policy.dataSubmissionPolicyBypassAcceptance", true);
|
||||
|
||||
// Point Firefox Health Report at a local server. We don't care if it actually
|
||||
// works. It just can't hit the default production endpoint.
|
||||
user_pref("datareporting.healthreport.documentServerURI", "http://%(server)s/healthreport/");
|
||||
|
||||
// Make sure CSS error reporting is enabled for tests
|
||||
user_pref("layout.css.report_errors", true);
|
||||
""" % { "server" : self.webServer + ":" + str(self.httpPort) }
|
||||
@ -1290,4 +1294,5 @@ user_pref("camino.use_system_proxy_settings", false); // Camino-only, harmless t
|
||||
|
||||
def elf_arm(self, filename):
|
||||
data = open(filename, 'rb').read(20)
|
||||
return data[:4] == "\x7fELF" and ord(data[18]) == 40 # EM_ARM
|
||||
return data[:4] == "\x7fELF" and ord(data[18]) == 40 # EM_ARM
|
||||
|
||||
|
@ -40,7 +40,6 @@
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIPrompt.h"
|
||||
#include "nsIWindowWatcher.h"
|
||||
#include "nsIConsoleService.h"
|
||||
|
@ -589,6 +589,13 @@ endif
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef _MSC_VER
|
||||
ifeq ($(CPU_ARCH),x86_64)
|
||||
# set stack to 2MB on x64 build. See bug 582910
|
||||
WIN32_EXE_LDFLAGS += -STACK:2097152
|
||||
endif
|
||||
endif
|
||||
|
||||
# If we're building a component on MSVC, we don't want to generate an
|
||||
# import lib, because that import lib will collide with the name of a
|
||||
# static version of the same library.
|
||||
|
@ -267,6 +267,14 @@ class SectionFinder(object):
|
||||
syms.append((tmp[-1], tmp[0]))
|
||||
return syms
|
||||
|
||||
def print_command(out, args):
|
||||
print >>out, "Executing: " + " ".join(args)
|
||||
for tmp in [f for f in args.tmp if os.path.isfile(f)]:
|
||||
print >>out, tmp + ":"
|
||||
with open(tmp) as file:
|
||||
print >>out, "".join([" " + l for l in file.readlines()])
|
||||
out.flush()
|
||||
|
||||
def main():
|
||||
parser = OptionParser()
|
||||
parser.add_option("--depend", dest="depend", metavar="FILE",
|
||||
@ -302,15 +310,15 @@ def main():
|
||||
args.makelist()
|
||||
|
||||
if options.verbose:
|
||||
print >>sys.stderr, "Executing: " + " ".join(args)
|
||||
for tmp in [f for f in args.tmp if os.path.isfile(f)]:
|
||||
print >>sys.stderr, tmp + ":"
|
||||
with open(tmp) as file:
|
||||
print >>sys.stderr, "".join([" " + l for l in file.readlines()])
|
||||
sys.stderr.flush()
|
||||
ret = subprocess.call(args)
|
||||
if ret:
|
||||
exit(ret)
|
||||
print_command(sys.stderr, args)
|
||||
proc = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
|
||||
(stdout, stderr) = proc.communicate()
|
||||
if proc.returncode and not options.verbose:
|
||||
print_command(sys.stderr, args)
|
||||
sys.stderr.write(stdout)
|
||||
sys.stderr.flush()
|
||||
if proc.returncode:
|
||||
exit(proc.returncode)
|
||||
if not options.depend:
|
||||
return
|
||||
ensureParentDir(options.depend)
|
||||
|
@ -32,8 +32,3 @@ ifneq (,$(filter OS2 WINNT,$(OS_ARCH))) # {
|
||||
else # } {
|
||||
$(RM) -f $(DIST)/sdk/lib/$(LIB_PREFIX)nspr4.$(LIB_SUFFIX) $(DIST)/sdk/lib/$(LIB_PREFIX)plc4.$(LIB_SUFFIX) $(DIST)/sdk/lib/$(LIB_PREFIX)plds4.$(LIB_SUFFIX)
|
||||
endif # }
|
||||
|
||||
install::
|
||||
$(MAKE) -C $(DEPTH)/nsprpub install DESTDIR=$(DESTDIR) libdir=$(mozappdir) includedir=$(includedir)/nspr
|
||||
$(RM) -f $(addprefix $(DESTDIR)$(mozappdir)/$(LIB_PREFIX), $(addsuffix .$(LIB_SUFFIX), nspr4 plds4 plc4))
|
||||
$(RM) -f $(addprefix $(DESTDIR)$(bindir)/,nspr-config compile-et.pl prerr.properties)
|
||||
|
@ -1,10 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
TIERS += nspr
|
||||
|
||||
ifndef MOZ_NATIVE_NSPR
|
||||
tier_nspr_staticdirs += nsprpub
|
||||
tier_nspr_dirs += config/nspr
|
||||
endif
|
@ -18,7 +18,7 @@ interface nsINode;
|
||||
* @version 1.0
|
||||
*/
|
||||
|
||||
[scriptable, uuid(12cf5a4d-fffb-4f2f-9cec-c65195661d76)]
|
||||
[scriptable, builtinclass, uuid(12cf5a4d-fffb-4f2f-9cec-c65195661d76)]
|
||||
interface nsISelection : nsISupports
|
||||
{
|
||||
/**
|
||||
|
@ -31,7 +31,7 @@ struct ScrollAxis;
|
||||
native nsDirection(nsDirection);
|
||||
native ScrollAxis(nsIPresShell::ScrollAxis);
|
||||
|
||||
[scriptable, uuid(2e44b10f-7d6d-4bf4-92e2-f9551d22f422)]
|
||||
[scriptable, builtinclass, uuid(2e44b10f-7d6d-4bf4-92e2-f9551d22f422)]
|
||||
interface nsISelectionPrivate : nsISelection
|
||||
{
|
||||
const short ENDOFPRECEDINGLINE=0;
|
||||
|
@ -89,7 +89,6 @@
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIEditorIMESupport.h"
|
||||
#include "nsIEditorDocShell.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsIControllers.h"
|
||||
|
@ -88,7 +88,6 @@
|
||||
#include "nsGenericHTMLElement.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIEditorIMESupport.h"
|
||||
#include "nsIEditorDocShell.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsContentCreatorFunctions.h"
|
||||
#include "nsIControllers.h"
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include "nsCCUncollectableMarker.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include "nsIDocument.h"
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include "nsStyleLinkElement.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsILoadContext.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsCPrefetchService.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsNetUtil.h"
|
||||
@ -807,22 +806,18 @@ nsContentSink::PrefetchHref(const nsAString &aHref,
|
||||
|
||||
nsCOMPtr<nsIDocShell> docshell = mDocShell;
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem, parentItem;
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentItem;
|
||||
do {
|
||||
uint32_t appType = 0;
|
||||
nsresult rv = docshell->GetAppType(&appType);
|
||||
if (NS_FAILED(rv) || appType == nsIDocShell::APP_TYPE_MAIL)
|
||||
return; // do not prefetch from mailnews
|
||||
treeItem = do_QueryInterface(docshell);
|
||||
if (treeItem) {
|
||||
treeItem->GetParent(getter_AddRefs(parentItem));
|
||||
if (parentItem) {
|
||||
treeItem = parentItem;
|
||||
docshell = do_QueryInterface(treeItem);
|
||||
if (!docshell) {
|
||||
NS_ERROR("cannot get a docshell from a treeItem!");
|
||||
return;
|
||||
}
|
||||
docshell->GetParent(getter_AddRefs(parentItem));
|
||||
if (parentItem) {
|
||||
docshell = do_QueryInterface(parentItem);
|
||||
if (!docshell) {
|
||||
NS_ERROR("cannot get a docshell from a treeItem!");
|
||||
return;
|
||||
}
|
||||
}
|
||||
} while (parentItem);
|
||||
|
@ -41,7 +41,6 @@
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIJSContextStack.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsParserCIID.h"
|
||||
#include "nsIParser.h"
|
||||
#include "nsIFragmentContentSink.h"
|
||||
@ -160,7 +159,6 @@
|
||||
#include "nsICharsetDetectionObserver.h"
|
||||
#include "nsIPlatformCharset.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIEditorDocShell.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "nsIParserService.h"
|
||||
#include "nsIDOMScriptObjectFactory.h"
|
||||
@ -6123,15 +6121,15 @@ nsContentUtils::CheckCCWrapperTraversal(void* aScriptObjectHolder,
|
||||
DebugWrapperTraversalCallback callback(wrapper);
|
||||
|
||||
aTracer->Traverse(aScriptObjectHolder, callback);
|
||||
NS_ASSERTION(callback.mFound,
|
||||
"Cycle collection participant didn't traverse to preserved "
|
||||
"wrapper! This will probably crash.");
|
||||
MOZ_ASSERT(callback.mFound,
|
||||
"Cycle collection participant didn't traverse to preserved "
|
||||
"wrapper! This will probably crash.");
|
||||
|
||||
callback.mFound = false;
|
||||
aTracer->Trace(aScriptObjectHolder, DebugWrapperTraceCallback, &callback);
|
||||
NS_ASSERTION(callback.mFound,
|
||||
"Cycle collection participant didn't trace preserved wrapper! "
|
||||
"This will probably crash.");
|
||||
MOZ_ASSERT(callback.mFound,
|
||||
"Cycle collection participant didn't trace preserved wrapper! "
|
||||
"This will probably crash.");
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -6802,14 +6800,14 @@ nsIEditor*
|
||||
nsContentUtils::GetHTMLEditor(nsPresContext* aPresContext)
|
||||
{
|
||||
nsCOMPtr<nsISupports> container = aPresContext->GetContainer();
|
||||
nsCOMPtr<nsIEditorDocShell> editorDocShell(do_QueryInterface(container));
|
||||
nsCOMPtr<nsIDocShell> docShell(do_QueryInterface(container));
|
||||
bool isEditable;
|
||||
if (!editorDocShell ||
|
||||
NS_FAILED(editorDocShell->GetEditable(&isEditable)) || !isEditable)
|
||||
if (!docShell ||
|
||||
NS_FAILED(docShell->GetEditable(&isEditable)) || !isEditable)
|
||||
return nullptr;
|
||||
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
editorDocShell->GetEditor(getter_AddRefs(editor));
|
||||
docShell->GetEditor(getter_AddRefs(editor));
|
||||
return editor;
|
||||
}
|
||||
|
||||
|
@ -34,12 +34,11 @@
|
||||
#include "nsICharsetConverterManager.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIEnumerator.h"
|
||||
#include "nsIParserService.h"
|
||||
#include "nsIScriptContext.h"
|
||||
#include "nsIScriptGlobalObject.h"
|
||||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsISelection.h"
|
||||
#include "mozilla/Selection.h"
|
||||
#include "nsISelectionPrivate.h"
|
||||
#include "nsITransferable.h" // for kUnicodeMime
|
||||
#include "nsContentUtils.h"
|
||||
@ -49,7 +48,6 @@
|
||||
#include "nsIFrame.h"
|
||||
#include "nsStringBuffer.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsIEditorDocShell.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIHTMLEditor.h"
|
||||
#include "nsIDocShell.h"
|
||||
@ -344,17 +342,14 @@ IsInvisibleBreak(nsINode *aNode) {
|
||||
if (window) {
|
||||
nsIDocShell *docShell = window->GetDocShell();
|
||||
if (docShell) {
|
||||
nsCOMPtr<nsIEditorDocShell> editorDocShell = do_QueryInterface(docShell);
|
||||
if (editorDocShell) {
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
editorDocShell->GetEditor(getter_AddRefs(editor));
|
||||
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(editor);
|
||||
if (htmlEditor) {
|
||||
bool isVisible = false;
|
||||
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aNode);
|
||||
htmlEditor->BreakIsVisible(domNode, &isVisible);
|
||||
return !isVisible;
|
||||
}
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
docShell->GetEditor(getter_AddRefs(editor));
|
||||
nsCOMPtr<nsIHTMLEditor> htmlEditor = do_QueryInterface(editor);
|
||||
if (htmlEditor) {
|
||||
bool isVisible = false;
|
||||
nsCOMPtr<nsIDOMNode> domNode = do_QueryInterface(aNode);
|
||||
htmlEditor->BreakIsVisible(domNode, &isVisible);
|
||||
return !isVisible;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1348,19 +1343,17 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection)
|
||||
|
||||
nsCOMPtr<nsIDOMRange> range;
|
||||
nsCOMPtr<nsIDOMNode> commonParent;
|
||||
int32_t count = 0;
|
||||
|
||||
nsresult rv = aSelection->GetRangeCount(&count);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
Selection* selection = static_cast<Selection*>(aSelection);
|
||||
uint32_t rangeCount = selection->GetRangeCount();
|
||||
|
||||
// if selection is uninitialized return
|
||||
if (!count)
|
||||
if (!rangeCount)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
// we'll just use the common parent of the first range. Implicit assumption
|
||||
// here that multi-range selections are table cell selections, in which case
|
||||
// the common parent is somewhere in the table and we don't really care where.
|
||||
rv = aSelection->GetRangeAt(0, getter_AddRefs(range));
|
||||
nsresult rv = aSelection->GetRangeAt(0, getter_AddRefs(range));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!range)
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
@ -1412,25 +1405,10 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection)
|
||||
//NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_NewDomSelection(getter_AddRefs(mSelection));
|
||||
NS_ENSURE_TRUE(mSelection, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsISelectionPrivate> privSelection( do_QueryInterface(aSelection) );
|
||||
NS_ENSURE_TRUE(privSelection, NS_ERROR_FAILURE);
|
||||
|
||||
// get selection range enumerator
|
||||
nsCOMPtr<nsIEnumerator> enumerator;
|
||||
rv = privSelection->GetEnumerator(getter_AddRefs(enumerator));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
|
||||
|
||||
// loop thru the ranges in the selection
|
||||
enumerator->First();
|
||||
nsCOMPtr<nsISupports> currentItem;
|
||||
while (static_cast<nsresult>(NS_ENUMERATOR_FALSE) == enumerator->IsDone())
|
||||
{
|
||||
rv = enumerator->CurrentItem(getter_AddRefs(currentItem));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
NS_ENSURE_TRUE(currentItem, NS_ERROR_FAILURE);
|
||||
|
||||
range = do_QueryInterface(currentItem);
|
||||
for (uint32_t rangeIdx = 0; rangeIdx < rangeCount; ++rangeIdx) {
|
||||
range = selection->GetRangeAt(rangeIdx);
|
||||
NS_ENSURE_TRUE(range, NS_ERROR_FAILURE);
|
||||
nsCOMPtr<nsIDOMRange> myRange;
|
||||
range->CloneRange(getter_AddRefs(myRange));
|
||||
@ -1442,8 +1420,6 @@ nsHTMLCopyEncoder::SetSelection(nsISelection* aSelection)
|
||||
|
||||
rv = mSelection->AddRange(myRange);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
enumerator->Next();
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
|
@ -28,8 +28,6 @@
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIWebProgress.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIDocShellTreeNode.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
#include "nsIDocShellLoadInfo.h"
|
||||
#include "nsIDOMApplicationRegistry.h"
|
||||
@ -55,7 +53,6 @@
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIXULWindow.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIEditorDocShell.h"
|
||||
#include "nsIMozBrowserFrame.h"
|
||||
#include "nsIPermissionManager.h"
|
||||
|
||||
@ -99,6 +96,7 @@
|
||||
#endif
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::hal;
|
||||
using namespace mozilla::dom;
|
||||
using namespace mozilla::dom::ipc;
|
||||
using namespace mozilla::layers;
|
||||
@ -853,26 +851,22 @@ nsFrameLoader::Show(int32_t marginWidth, int32_t marginHeight,
|
||||
if (designMode.EqualsLiteral("on")) {
|
||||
// Hold on to the editor object to let the document reattach to the
|
||||
// same editor object, instead of creating a new one.
|
||||
nsCOMPtr<nsIEditorDocShell> editorDocshell = do_QueryInterface(mDocShell);
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
nsresult rv = editorDocshell->GetEditor(getter_AddRefs(editor));
|
||||
nsresult rv = mDocShell->GetEditor(getter_AddRefs(editor));
|
||||
NS_ENSURE_SUCCESS(rv, false);
|
||||
|
||||
doc->SetDesignMode(NS_LITERAL_STRING("off"));
|
||||
doc->SetDesignMode(NS_LITERAL_STRING("on"));
|
||||
} else {
|
||||
// Re-initialize the presentation for contenteditable documents
|
||||
nsCOMPtr<nsIEditorDocShell> editorDocshell = do_QueryInterface(mDocShell);
|
||||
if (editorDocshell) {
|
||||
bool editable = false,
|
||||
hasEditingSession = false;
|
||||
editorDocshell->GetEditable(&editable);
|
||||
editorDocshell->GetHasEditingSession(&hasEditingSession);
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
editorDocshell->GetEditor(getter_AddRefs(editor));
|
||||
if (editable && hasEditingSession && editor) {
|
||||
editor->PostCreate();
|
||||
}
|
||||
bool editable = false,
|
||||
hasEditingSession = false;
|
||||
mDocShell->GetEditable(&editable);
|
||||
mDocShell->GetHasEditingSession(&hasEditingSession);
|
||||
nsCOMPtr<nsIEditor> editor;
|
||||
mDocShell->GetEditor(getter_AddRefs(editor));
|
||||
if (editable && hasEditingSession && editor) {
|
||||
editor->PostCreate();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1030,12 +1024,9 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
// To avoid having to mess with session history, avoid swapping
|
||||
// frameloaders that don't correspond to root same-type docshells,
|
||||
// unless both roots have session history disabled.
|
||||
nsCOMPtr<nsIDocShellTreeItem> ourTreeItem = do_QueryInterface(ourDocshell);
|
||||
nsCOMPtr<nsIDocShellTreeItem> otherTreeItem =
|
||||
do_QueryInterface(otherDocshell);
|
||||
nsCOMPtr<nsIDocShellTreeItem> ourRootTreeItem, otherRootTreeItem;
|
||||
ourTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(ourRootTreeItem));
|
||||
otherTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(otherRootTreeItem));
|
||||
ourDocshell->GetSameTypeRootTreeItem(getter_AddRefs(ourRootTreeItem));
|
||||
otherDocshell->GetSameTypeRootTreeItem(getter_AddRefs(otherRootTreeItem));
|
||||
nsCOMPtr<nsIWebNavigation> ourRootWebnav =
|
||||
do_QueryInterface(ourRootTreeItem);
|
||||
nsCOMPtr<nsIWebNavigation> otherRootWebnav =
|
||||
@ -1050,7 +1041,7 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
ourRootWebnav->GetSessionHistory(getter_AddRefs(ourHistory));
|
||||
otherRootWebnav->GetSessionHistory(getter_AddRefs(otherHistory));
|
||||
|
||||
if ((ourRootTreeItem != ourTreeItem || otherRootTreeItem != otherTreeItem) &&
|
||||
if ((ourRootTreeItem != ourDocshell || otherRootTreeItem != otherDocshell) &&
|
||||
(ourHistory || otherHistory)) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
@ -1060,8 +1051,8 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
// the code below needs to be audited as it assumes identical types.
|
||||
int32_t ourType = nsIDocShellTreeItem::typeChrome;
|
||||
int32_t otherType = nsIDocShellTreeItem::typeChrome;
|
||||
ourTreeItem->GetItemType(&ourType);
|
||||
otherTreeItem->GetItemType(&otherType);
|
||||
ourDocshell->GetItemType(&ourType);
|
||||
otherDocshell->GetItemType(&otherType);
|
||||
if (ourType != otherType) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
@ -1071,21 +1062,21 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
// nsIDocShellTreeItem::typeContent then all of our descendants are the same
|
||||
// type as us.
|
||||
if (ourType != nsIDocShellTreeItem::typeContent &&
|
||||
(!AllDescendantsOfType(ourTreeItem, ourType) ||
|
||||
!AllDescendantsOfType(otherTreeItem, otherType))) {
|
||||
(!AllDescendantsOfType(ourDocshell, ourType) ||
|
||||
!AllDescendantsOfType(otherDocshell, otherType))) {
|
||||
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));
|
||||
ourDocshell->GetTreeOwner(getter_AddRefs(ourOwner));
|
||||
otherDocshell->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));
|
||||
ourDocshell->GetParent(getter_AddRefs(ourParentItem));
|
||||
otherDocshell->GetParent(getter_AddRefs(otherParentItem));
|
||||
if (!ourParentItem || !otherParentItem) {
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
@ -1163,25 +1154,25 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
// Fire pageshow events on still-loading pages, and then fire pagehide
|
||||
// events. Note that we do NOT fire these in the normal way, but just fire
|
||||
// them on the chrome event handlers.
|
||||
FirePageShowEvent(ourTreeItem, ourChromeEventHandler, false);
|
||||
FirePageShowEvent(otherTreeItem, otherChromeEventHandler, false);
|
||||
FirePageHideEvent(ourTreeItem, ourChromeEventHandler);
|
||||
FirePageHideEvent(otherTreeItem, otherChromeEventHandler);
|
||||
FirePageShowEvent(ourDocshell, ourChromeEventHandler, false);
|
||||
FirePageShowEvent(otherDocshell, otherChromeEventHandler, false);
|
||||
FirePageHideEvent(ourDocshell, ourChromeEventHandler);
|
||||
FirePageHideEvent(otherDocshell, otherChromeEventHandler);
|
||||
|
||||
nsIFrame* ourFrame = ourContent->GetPrimaryFrame();
|
||||
nsIFrame* otherFrame = otherContent->GetPrimaryFrame();
|
||||
if (!ourFrame || !otherFrame) {
|
||||
mInSwap = aOther->mInSwap = false;
|
||||
FirePageShowEvent(ourTreeItem, ourChromeEventHandler, true);
|
||||
FirePageShowEvent(otherTreeItem, otherChromeEventHandler, true);
|
||||
FirePageShowEvent(ourDocshell, ourChromeEventHandler, true);
|
||||
FirePageShowEvent(otherDocshell, otherChromeEventHandler, true);
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
nsSubDocumentFrame* ourFrameFrame = do_QueryFrame(ourFrame);
|
||||
if (!ourFrameFrame) {
|
||||
mInSwap = aOther->mInSwap = false;
|
||||
FirePageShowEvent(ourTreeItem, ourChromeEventHandler, true);
|
||||
FirePageShowEvent(otherTreeItem, otherChromeEventHandler, true);
|
||||
FirePageShowEvent(ourDocshell, ourChromeEventHandler, true);
|
||||
FirePageShowEvent(otherDocshell, otherChromeEventHandler, true);
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
@ -1189,31 +1180,31 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
rv = ourFrameFrame->BeginSwapDocShells(otherFrame);
|
||||
if (NS_FAILED(rv)) {
|
||||
mInSwap = aOther->mInSwap = false;
|
||||
FirePageShowEvent(ourTreeItem, ourChromeEventHandler, true);
|
||||
FirePageShowEvent(otherTreeItem, otherChromeEventHandler, true);
|
||||
FirePageShowEvent(ourDocshell, ourChromeEventHandler, true);
|
||||
FirePageShowEvent(otherDocshell, otherChromeEventHandler, true);
|
||||
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);
|
||||
ourParentItem->RemoveChild(ourDocshell);
|
||||
otherParentItem->RemoveChild(otherDocshell);
|
||||
if (ourType == nsIDocShellTreeItem::typeContent) {
|
||||
ourOwner->ContentShellRemoved(ourTreeItem);
|
||||
otherOwner->ContentShellRemoved(otherTreeItem);
|
||||
ourOwner->ContentShellRemoved(ourDocshell);
|
||||
otherOwner->ContentShellRemoved(otherDocshell);
|
||||
}
|
||||
|
||||
ourParentItem->AddChild(otherTreeItem);
|
||||
otherParentItem->AddChild(ourTreeItem);
|
||||
ourParentItem->AddChild(otherDocshell);
|
||||
otherParentItem->AddChild(ourDocshell);
|
||||
|
||||
// Restore the correct chrome event handlers.
|
||||
ourDocshell->SetChromeEventHandler(otherChromeEventHandler);
|
||||
otherDocshell->SetChromeEventHandler(ourChromeEventHandler);
|
||||
// Restore the correct treeowners
|
||||
// (and also chrome event handlers for content frames only).
|
||||
SetTreeOwnerAndChromeEventHandlerOnDocshellTree(ourTreeItem, otherOwner,
|
||||
SetTreeOwnerAndChromeEventHandlerOnDocshellTree(ourDocshell, otherOwner,
|
||||
ourType == nsIDocShellTreeItem::typeContent ? otherChromeEventHandler : nullptr);
|
||||
SetTreeOwnerAndChromeEventHandlerOnDocshellTree(otherTreeItem, ourOwner,
|
||||
SetTreeOwnerAndChromeEventHandlerOnDocshellTree(otherDocshell, ourOwner,
|
||||
ourType == nsIDocShellTreeItem::typeContent ? ourChromeEventHandler : nullptr);
|
||||
|
||||
// Switch the owner content before we start calling AddTreeItemToTreeOwner.
|
||||
@ -1222,8 +1213,8 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
SetOwnerContent(otherContent);
|
||||
aOther->SetOwnerContent(ourContent);
|
||||
|
||||
AddTreeItemToTreeOwner(ourTreeItem, otherOwner, otherParentType, nullptr);
|
||||
aOther->AddTreeItemToTreeOwner(otherTreeItem, ourOwner, ourParentType,
|
||||
AddTreeItemToTreeOwner(ourDocshell, otherOwner, otherParentType, nullptr);
|
||||
aOther->AddTreeItemToTreeOwner(otherDocshell, ourOwner, ourParentType,
|
||||
nullptr);
|
||||
|
||||
// SetSubDocumentFor nulls out parent documents on the old child doc if a
|
||||
@ -1307,8 +1298,8 @@ nsFrameLoader::SwapWithOtherLoader(nsFrameLoader* aOther,
|
||||
ourParentDocument->FlushPendingNotifications(Flush_Layout);
|
||||
otherParentDocument->FlushPendingNotifications(Flush_Layout);
|
||||
|
||||
FirePageShowEvent(ourTreeItem, otherChromeEventHandler, true);
|
||||
FirePageShowEvent(otherTreeItem, ourChromeEventHandler, true);
|
||||
FirePageShowEvent(ourDocshell, otherChromeEventHandler, true);
|
||||
FirePageShowEvent(otherDocshell, ourChromeEventHandler, true);
|
||||
|
||||
mInSwap = aOther->mInSwap = false;
|
||||
return NS_OK;
|
||||
@ -1360,13 +1351,12 @@ nsFrameLoader::Destroy()
|
||||
|
||||
// Let the tree owner know we're gone.
|
||||
if (mIsTopLevelContent) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> ourItem = do_QueryInterface(mDocShell);
|
||||
if (ourItem) {
|
||||
if (mDocShell) {
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentItem;
|
||||
ourItem->GetParent(getter_AddRefs(parentItem));
|
||||
mDocShell->GetParent(getter_AddRefs(parentItem));
|
||||
nsCOMPtr<nsIDocShellTreeOwner> owner = do_GetInterface(parentItem);
|
||||
if (owner) {
|
||||
owner->ContentShellRemoved(ourItem);
|
||||
owner->ContentShellRemoved(mDocShell);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1569,8 +1559,7 @@ nsFrameLoader::MaybeCreateDocShell()
|
||||
}
|
||||
|
||||
// Get the frame name and tell the docshell about it.
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
|
||||
NS_ENSURE_TRUE(docShellAsItem, NS_ERROR_FAILURE);
|
||||
NS_ENSURE_TRUE(mDocShell, NS_ERROR_FAILURE);
|
||||
nsAutoString frameName;
|
||||
|
||||
int32_t namespaceID = mOwnerContent->GetNameSpaceID();
|
||||
@ -1586,7 +1575,7 @@ nsFrameLoader::MaybeCreateDocShell()
|
||||
}
|
||||
|
||||
if (!frameName.IsEmpty()) {
|
||||
docShellAsItem->SetName(frameName.get());
|
||||
mDocShell->SetName(frameName.get());
|
||||
}
|
||||
|
||||
// If our container is a web-shell, inform it that it has a new
|
||||
@ -1610,7 +1599,7 @@ nsFrameLoader::MaybeCreateDocShell()
|
||||
parentAsItem->GetTreeOwner(getter_AddRefs(parentTreeOwner));
|
||||
NS_ENSURE_STATE(parentTreeOwner);
|
||||
mIsTopLevelContent =
|
||||
AddTreeItemToTreeOwner(docShellAsItem, parentTreeOwner, parentType,
|
||||
AddTreeItemToTreeOwner(mDocShell, parentTreeOwner, parentType,
|
||||
parentAsNode);
|
||||
|
||||
// Make sure all shells have links back to the content element
|
||||
@ -1734,19 +1723,16 @@ nsFrameLoader::CheckForRecursiveLoad(nsIURI* aURI)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> treeItem = do_QueryInterface(mDocShell);
|
||||
NS_ASSERTION(treeItem, "docshell must be a treeitem!");
|
||||
|
||||
// Check that we're still in the docshell tree.
|
||||
nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
|
||||
treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
|
||||
mDocShell->GetTreeOwner(getter_AddRefs(treeOwner));
|
||||
NS_WARN_IF_FALSE(treeOwner,
|
||||
"Trying to load a new url to a docshell without owner!");
|
||||
NS_ENSURE_STATE(treeOwner);
|
||||
|
||||
|
||||
int32_t ourType;
|
||||
rv = treeItem->GetItemType(&ourType);
|
||||
rv = mDocShell->GetItemType(&ourType);
|
||||
if (NS_SUCCEEDED(rv) && ourType != nsIDocShellTreeItem::typeContent) {
|
||||
// No need to do recursion-protection here XXXbz why not?? Do we really
|
||||
// trust people not to screw up with non-content docshells?
|
||||
@ -1756,7 +1742,7 @@ nsFrameLoader::CheckForRecursiveLoad(nsIURI* aURI)
|
||||
// Bug 8065: Don't exceed some maximum depth in content frames
|
||||
// (MAX_DEPTH_CONTENT_FRAMES)
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentAsItem;
|
||||
treeItem->GetSameTypeParent(getter_AddRefs(parentAsItem));
|
||||
mDocShell->GetSameTypeParent(getter_AddRefs(parentAsItem));
|
||||
int32_t depth = 0;
|
||||
while (parentAsItem) {
|
||||
++depth;
|
||||
@ -1775,7 +1761,7 @@ nsFrameLoader::CheckForRecursiveLoad(nsIURI* aURI)
|
||||
|
||||
// Bug 136580: Check for recursive frame loading
|
||||
int32_t matchCount = 0;
|
||||
treeItem->GetSameTypeParent(getter_AddRefs(parentAsItem));
|
||||
mDocShell->GetSameTypeParent(getter_AddRefs(parentAsItem));
|
||||
while (parentAsItem) {
|
||||
// Check the parent URI with the URI we're loading
|
||||
nsCOMPtr<nsIWebNavigation> parentAsNav(do_QueryInterface(parentAsItem));
|
||||
@ -2060,19 +2046,9 @@ nsFrameLoader::TryRemoteBrowser()
|
||||
context.SetTabContextForBrowserFrame(containingApp, scrollingBehavior);
|
||||
}
|
||||
|
||||
mRemoteBrowser = ContentParent::CreateBrowserOrApp(context);
|
||||
nsCOMPtr<nsIDOMElement> ownerElement = do_QueryInterface(mOwnerContent);
|
||||
mRemoteBrowser = ContentParent::CreateBrowserOrApp(context, ownerElement);
|
||||
if (mRemoteBrowser) {
|
||||
nsCOMPtr<nsIDOMElement> element = do_QueryInterface(mOwnerContent);
|
||||
mRemoteBrowser->SetOwnerElement(element);
|
||||
|
||||
// If we're an app, send the frame element's mozapptype down to the child
|
||||
// process. This ends up in TabChild::GetAppType().
|
||||
if (ownApp) {
|
||||
nsAutoString appType;
|
||||
mOwnerContent->GetAttr(kNameSpaceID_None, nsGkAtoms::mozapptype, appType);
|
||||
mRemoteBrowser->SendSetAppType(appType);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> rootItem;
|
||||
parentAsItem->GetRootTreeItem(getter_AddRefs(rootItem));
|
||||
nsCOMPtr<nsIDOMWindow> rootWin = do_GetInterface(rootItem);
|
||||
@ -2481,14 +2457,12 @@ nsFrameLoader::AttributeChanged(nsIDocument* aDocument,
|
||||
// Notify our enclosing chrome that our type has changed. We only do this
|
||||
// if our parent is chrome, since in all other cases we're random content
|
||||
// subframes and the treeowner shouldn't worry about us.
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> docShellAsItem(do_QueryInterface(mDocShell));
|
||||
if (!docShellAsItem) {
|
||||
if (!mDocShell) {
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShellTreeItem> parentItem;
|
||||
docShellAsItem->GetParent(getter_AddRefs(parentItem));
|
||||
mDocShell->GetParent(getter_AddRefs(parentItem));
|
||||
if (!parentItem) {
|
||||
return;
|
||||
}
|
||||
@ -2516,18 +2490,18 @@ nsFrameLoader::AttributeChanged(nsIDocument* aDocument,
|
||||
if (!is_primary) {
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
if (pm)
|
||||
pm->HidePopupsInDocShell(docShellAsItem);
|
||||
pm->HidePopupsInDocShell(mDocShell);
|
||||
}
|
||||
#endif
|
||||
|
||||
parentTreeOwner->ContentShellRemoved(docShellAsItem);
|
||||
parentTreeOwner->ContentShellRemoved(mDocShell);
|
||||
if (value.LowerCaseEqualsLiteral("content") ||
|
||||
StringBeginsWith(value, NS_LITERAL_STRING("content-"),
|
||||
nsCaseInsensitiveStringComparator())) {
|
||||
bool is_targetable = is_primary ||
|
||||
value.LowerCaseEqualsLiteral("content-targetable");
|
||||
|
||||
parentTreeOwner->ContentShellAdded(docShellAsItem, is_primary,
|
||||
parentTreeOwner->ContentShellAdded(mDocShell, is_primary,
|
||||
is_targetable, value);
|
||||
}
|
||||
}
|
||||
|
@ -342,6 +342,7 @@ GK_ATOM(events, "events")
|
||||
GK_ATOM(excludeResultPrefixes, "exclude-result-prefixes")
|
||||
GK_ATOM(excludes, "excludes")
|
||||
GK_ATOM(expr, "expr")
|
||||
GK_ATOM(expectingSystemMessage, "expecting-system-message")
|
||||
GK_ATOM(extends, "extends")
|
||||
GK_ATOM(extensionElementPrefixes, "extension-element-prefixes")
|
||||
GK_ATOM(face, "face")
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include "nsIScriptElement.h"
|
||||
#include "nsAttrName.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIEditorDocShell.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIHTMLEditor.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
@ -58,7 +58,6 @@
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
#include "nsIDOMNodeList.h"
|
||||
#include "nsIDOMUserDataHandler.h"
|
||||
#include "nsIEditorDocShell.h"
|
||||
#include "nsIEditor.h"
|
||||
#include "nsIEditorIMESupport.h"
|
||||
#include "nsIFrame.h"
|
||||
|
@ -9,7 +9,6 @@
|
||||
#include "nsINode.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsISecurityEventSink.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsContentUtils.h"
|
||||
@ -61,12 +60,11 @@ public:
|
||||
// set the approriate flag to true if we are about to load Mixed Active
|
||||
// Content.
|
||||
nsCOMPtr<nsIDocShell> docShell = NS_CP_GetDocShellFromContext(mContext);
|
||||
nsCOMPtr<nsIDocShellTreeItem> currentDocShellTreeItem(do_QueryInterface(docShell));
|
||||
if (!currentDocShellTreeItem) {
|
||||
if (!docShell) {
|
||||
return NS_OK;
|
||||
}
|
||||
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
|
||||
currentDocShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
|
||||
docShell->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
|
||||
NS_ASSERTION(sameTypeRoot, "No document shell root tree item from document shell tree item!");
|
||||
|
||||
// now get the document from sameTypeRoot
|
||||
@ -368,10 +366,8 @@ nsMixedContentBlocker::ShouldLoad(uint32_t aContentType,
|
||||
}
|
||||
|
||||
// Get the root document from the docshell
|
||||
nsCOMPtr<nsIDocShellTreeItem> currentDocShellTreeItem(do_QueryInterface(docShell));
|
||||
NS_ASSERTION(currentDocShellTreeItem, "No DocShellTreeItem from docshell");
|
||||
nsCOMPtr<nsIDocShellTreeItem> sameTypeRoot;
|
||||
currentDocShellTreeItem->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
|
||||
docShell->GetSameTypeRootTreeItem(getter_AddRefs(sameTypeRoot));
|
||||
NS_ASSERTION(sameTypeRoot, "No document shell root tree item from document shell tree item!");
|
||||
nsCOMPtr<nsIDocument> rootDoc = do_GetInterface(sameTypeRoot);
|
||||
NS_ASSERTION(rootDoc, "No root document from document shell root tree item.");
|
||||
|
@ -1758,26 +1758,20 @@ nsObjectLoadingContent::LoadObject(bool aNotify,
|
||||
}
|
||||
}
|
||||
|
||||
// Items resolved as Image/Document will not be checked for previews, as well
|
||||
// as invalid plugins (they will not have the mContentType set).
|
||||
if ((mType == eType_Null || mType == eType_Plugin) && ShouldPreview()) {
|
||||
// If plugin preview exists, we shall use it
|
||||
LOG(("OBJLC [%p]: Using plugin preview", this));
|
||||
mType = eType_Null;
|
||||
fallbackType = eFallbackPlayPreview;
|
||||
}
|
||||
|
||||
// If we're a plugin but shouldn't start yet, load fallback with
|
||||
// reason click-to-play instead
|
||||
// reason click-to-play instead. Items resolved as Image/Document
|
||||
// will not be checked for previews, as well as invalid plugins
|
||||
// (they will not have the mContentType set).
|
||||
FallbackType clickToPlayReason;
|
||||
if (mType == eType_Plugin && !ShouldPlay(clickToPlayReason)) {
|
||||
if ((mType == eType_Null || mType == eType_Plugin) &&
|
||||
!ShouldPlay(clickToPlayReason)) {
|
||||
LOG(("OBJLC [%p]: Marking plugin as click-to-play", this));
|
||||
mType = eType_Null;
|
||||
fallbackType = clickToPlayReason;
|
||||
}
|
||||
|
||||
if (!mActivated && mType == eType_Plugin) {
|
||||
// Object passed ShouldPlay and !ShouldPreview, so it should be considered
|
||||
// Object passed ShouldPlay, so it should be considered
|
||||
// activated until it changes content type
|
||||
LOG(("OBJLC [%p]: Object implicitly activated", this));
|
||||
mActivated = true;
|
||||
@ -2649,18 +2643,6 @@ nsObjectLoadingContent::CancelPlayPreview()
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
nsObjectLoadingContent::ShouldPreview()
|
||||
{
|
||||
if (mPlayPreviewCanceled || mActivated)
|
||||
return false;
|
||||
|
||||
nsRefPtr<nsPluginHost> pluginHost =
|
||||
already_AddRefed<nsPluginHost>(nsPluginHost::GetInst());
|
||||
|
||||
return pluginHost->IsPluginPlayPreviewForType(mContentType.get());
|
||||
}
|
||||
|
||||
bool
|
||||
nsObjectLoadingContent::ShouldPlay(FallbackType &aReason)
|
||||
{
|
||||
@ -2671,6 +2653,25 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason)
|
||||
nsRefPtr<nsPluginHost> pluginHost =
|
||||
already_AddRefed<nsPluginHost>(nsPluginHost::GetInst());
|
||||
|
||||
nsCOMPtr<nsIPluginPlayPreviewInfo> playPreviewInfo;
|
||||
bool isPlayPreviewSpecified = NS_SUCCEEDED(pluginHost->GetPlayPreviewInfo(
|
||||
mContentType, getter_AddRefs(playPreviewInfo)));
|
||||
bool ignoreCTP = false;
|
||||
if (isPlayPreviewSpecified) {
|
||||
playPreviewInfo->GetIgnoreCTP(&ignoreCTP);
|
||||
}
|
||||
if (isPlayPreviewSpecified && !mPlayPreviewCanceled && !mActivated &&
|
||||
ignoreCTP) {
|
||||
// play preview in ignoreCTP mode is shown even if the native plugin
|
||||
// is not present/installed
|
||||
aReason = eFallbackPlayPreview;
|
||||
return false;
|
||||
}
|
||||
// at this point if it's not a plugin, we let it play/fallback
|
||||
if (mType != eType_Plugin) {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool isCTP;
|
||||
nsresult rv = pluginHost->IsPluginClickToPlayForType(mContentType, &isCTP);
|
||||
if (NS_FAILED(rv)) {
|
||||
@ -2735,6 +2736,12 @@ nsObjectLoadingContent::ShouldPlay(FallbackType &aReason)
|
||||
allowPerm = permission == nsIPermissionManager::ALLOW_ACTION;
|
||||
}
|
||||
|
||||
if (aReason == eFallbackClickToPlay && isPlayPreviewSpecified &&
|
||||
!mPlayPreviewCanceled && !ignoreCTP) {
|
||||
// play preview in click-to-play mode is shown instead of standard CTP UI
|
||||
aReason = eFallbackPlayPreview;
|
||||
}
|
||||
|
||||
return allowPerm;
|
||||
}
|
||||
|
||||
|
@ -301,11 +301,6 @@ class nsObjectLoadingContent : public nsImageLoadingContent
|
||||
*/
|
||||
bool ShouldPlay(FallbackType &aReason);
|
||||
|
||||
/**
|
||||
* If the object should display preview content for the current mContentType
|
||||
*/
|
||||
bool ShouldPreview();
|
||||
|
||||
/**
|
||||
* Helper to check if our current URI passes policy
|
||||
*
|
||||
|
@ -43,8 +43,6 @@
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIDocShellTreeNode.h"
|
||||
#include "nsIXPConnect.h"
|
||||
#include "nsDisplayList.h"
|
||||
|
||||
|
@ -11,8 +11,6 @@
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeNode.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsCSSParser.h"
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include "nsCRT.h"
|
||||
#include "nsIScriptObjectPrincipal.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIScriptContext.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsDOMEvent.h"
|
||||
#include "nsGkAtoms.h"
|
||||
#include "nsIEditorDocShell.h"
|
||||
#include "nsIFormControl.h"
|
||||
#include "nsIComboboxControlFrame.h"
|
||||
#include "nsIScrollableFrame.h"
|
||||
@ -33,8 +32,6 @@
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsPIWindowRoot.h"
|
||||
#include "nsIEnumerator.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIDocShellTreeNode.h"
|
||||
#include "nsIWebNavigation.h"
|
||||
#include "nsIContentViewer.h"
|
||||
#include <algorithm>
|
||||
|
@ -11,7 +11,6 @@
|
||||
#include "nsISupports.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIEditorDocShell.h"
|
||||
#include "nsIContent.h"
|
||||
#include "nsIDocument.h"
|
||||
#include "nsPresContext.h"
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "AudioStream.h"
|
||||
#include "VideoFrameContainer.h"
|
||||
#include "mozilla/CORSMode.h"
|
||||
#include "nsDOMMediaStream.h"
|
||||
#include "DOMMediaStream.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "nsTimeRanges.h"
|
||||
#include "nsIDOMWakeLock.h"
|
||||
@ -54,6 +54,7 @@ public:
|
||||
typedef mozilla::MetadataTags MetadataTags;
|
||||
typedef mozilla::AudioStream AudioStream;
|
||||
typedef mozilla::MediaDecoder MediaDecoder;
|
||||
typedef mozilla::DOMMediaStream DOMMediaStream;
|
||||
|
||||
mozilla::CORSMode GetCORSMode() {
|
||||
return mCORSMode;
|
||||
@ -368,7 +369,7 @@ protected:
|
||||
/**
|
||||
* Initialize the media element for playback of aStream
|
||||
*/
|
||||
void SetupSrcMediaStreamPlayback(nsDOMMediaStream* aStream);
|
||||
void SetupSrcMediaStreamPlayback(DOMMediaStream* aStream);
|
||||
/**
|
||||
* Stop playback on mSrcStream.
|
||||
*/
|
||||
@ -381,7 +382,7 @@ protected:
|
||||
* When aFinishWhenEnded is false, ending playback does not finish the stream.
|
||||
* The stream will never finish.
|
||||
*/
|
||||
already_AddRefed<nsDOMMediaStream> CaptureStreamInternal(bool aFinishWhenEnded);
|
||||
already_AddRefed<DOMMediaStream> CaptureStreamInternal(bool aFinishWhenEnded);
|
||||
|
||||
/**
|
||||
* Create a decoder for the given aMIMEType. Returns null if we
|
||||
@ -639,17 +640,17 @@ protected:
|
||||
|
||||
// Holds a reference to the DOM wrapper for the MediaStream that has been
|
||||
// set in the src attribute.
|
||||
nsRefPtr<nsDOMMediaStream> mSrcAttrStream;
|
||||
nsRefPtr<DOMMediaStream> mSrcAttrStream;
|
||||
|
||||
// Holds a reference to the DOM wrapper for the MediaStream that we're
|
||||
// actually playing.
|
||||
// At most one of mDecoder and mSrcStream can be non-null.
|
||||
nsRefPtr<nsDOMMediaStream> mSrcStream;
|
||||
nsRefPtr<DOMMediaStream> mSrcStream;
|
||||
|
||||
// Holds references to the DOM wrappers for the MediaStreams that we're
|
||||
// writing to.
|
||||
struct OutputMediaStream {
|
||||
nsRefPtr<nsDOMMediaStream> mStream;
|
||||
nsRefPtr<DOMMediaStream> mStream;
|
||||
bool mFinishWhenEnded;
|
||||
};
|
||||
nsTArray<OutputMediaStream> mOutputStreams;
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include "nsMappedAttributes.h"
|
||||
#include "nsRuleData.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIEditorDocShell.h"
|
||||
#include "nsRuleWalker.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
|
||||
@ -476,12 +475,12 @@ HTMLBodyElement::GetAssociatedEditor()
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISupports> container = presContext->GetContainer();
|
||||
nsCOMPtr<nsIEditorDocShell> editorDocShell = do_QueryInterface(container);
|
||||
if (!editorDocShell) {
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container);
|
||||
if (!docShell) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
editorDocShell->GetEditor(getter_AddRefs(editor));
|
||||
docShell->GetEditor(getter_AddRefs(editor));
|
||||
return editor.forget();
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user