зеркало из https://github.com/mozilla/gecko-dev.git
Merge mozilla-central to tracemonkey.
This commit is contained in:
Коммит
b1d3530553
3
.hgtags
3
.hgtags
|
@ -63,3 +63,6 @@ a71bd564ebf5bf4f93d13e84114f759c263130b0 MOBILE_MERGE_DONE
|
|||
a71bd564ebf5bf4f93d13e84114f759c263130b0 MOBILE_MERGE_DONE_20110406
|
||||
a95d426422816513477e5863add1b00ac7041dcb AURORA_BASE_20110412
|
||||
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R14
|
||||
9eae975b3d6fb7748fe5a3c0113d449b1c7cc0b2 AURORA_BASE_20110524
|
||||
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R14
|
||||
462c726144bc1fb45b61e774f64ac5d61b4e047c UPDATE_PACKAGING_R14
|
||||
|
|
|
@ -477,7 +477,8 @@ nsRoleMapEntry nsARIAMap::gWAIRoleMap[] =
|
|||
eNoValue,
|
||||
eSwitchAction,
|
||||
eNoLiveAttr,
|
||||
kNoReqStates
|
||||
kNoReqStates,
|
||||
eARIASelectable
|
||||
},
|
||||
{
|
||||
"tablist",
|
||||
|
|
|
@ -55,9 +55,6 @@
|
|||
#include "nsIDOMCSSPrimitiveValue.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMHTMLDocument.h"
|
||||
#include "nsIDOMHTMLElement.h"
|
||||
#include "nsIDOMNSDocument.h"
|
||||
#include "nsIDOMNSHTMLElement.h"
|
||||
#include "nsIDOMWindow.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
@ -135,6 +132,12 @@ void nsAccessNode::LastRelease()
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessNode public
|
||||
|
||||
bool
|
||||
nsAccessNode::IsDefunct() const
|
||||
{
|
||||
return !mContent;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsAccessNode::Init()
|
||||
{
|
||||
|
|
|
@ -120,11 +120,6 @@ public:
|
|||
*/
|
||||
already_AddRefed<nsINode> GetCurrentFocus();
|
||||
|
||||
/**
|
||||
* Returns true when the accessible is defunct.
|
||||
*/
|
||||
virtual PRBool IsDefunct() { return !mContent; }
|
||||
|
||||
/**
|
||||
* Initialize the access node object, add it to the cache.
|
||||
*/
|
||||
|
@ -135,6 +130,11 @@ public:
|
|||
*/
|
||||
virtual void Shutdown();
|
||||
|
||||
/**
|
||||
* Returns true when the accessible is defunct.
|
||||
*/
|
||||
virtual bool IsDefunct() const;
|
||||
|
||||
/**
|
||||
* Return frame for the given access node object.
|
||||
*/
|
||||
|
|
|
@ -107,7 +107,6 @@
|
|||
|
||||
#include "mozilla/FunctionTimer.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
#include "nsImageMapUtils.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessibilityService
|
||||
|
@ -275,8 +274,10 @@ nsAccessibilityService::CreateHTMLImageAccessible(nsIContent* aContent,
|
|||
aContent->GetAttr(kNameSpaceID_None,
|
||||
nsAccessibilityAtoms::usemap,
|
||||
mapElmName);
|
||||
nsCOMPtr<nsIDOMHTMLMapElement> mapElm =
|
||||
nsImageMapUtils::FindImageMap(aContent->GetCurrentDoc(), mapElmName);
|
||||
nsCOMPtr<nsIDOMHTMLMapElement> mapElm;
|
||||
if (nsIDocument* document = aContent->GetCurrentDoc()) {
|
||||
mapElm = do_QueryInterface(document->FindImageMap(mapElmName));
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(aPresShell));
|
||||
nsAccessible* accessible = mapElm ?
|
||||
|
|
|
@ -75,6 +75,7 @@
|
|||
#include "nsIForm.h"
|
||||
#include "nsIFormControl.h"
|
||||
|
||||
#include "nsLayoutUtils.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsIFrame.h"
|
||||
|
@ -88,8 +89,6 @@
|
|||
#include "nsReadableUtils.h"
|
||||
#include "prdtoa.h"
|
||||
#include "nsIAtom.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIURI.h"
|
||||
#include "nsArrayUtils.h"
|
||||
#include "nsIMutableArray.h"
|
||||
|
@ -105,6 +104,9 @@
|
|||
#endif
|
||||
|
||||
#include "mozilla/unused.h"
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -338,22 +340,14 @@ nsAccessible::Description(nsString& aDescription)
|
|||
static PRInt32
|
||||
GetAccessModifierMask(nsIContent* aContent)
|
||||
{
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch =
|
||||
do_GetService(NS_PREFSERVICE_CONTRACTID);
|
||||
if (!prefBranch)
|
||||
return 0;
|
||||
|
||||
// use ui.key.generalAccessKey (unless it is -1)
|
||||
PRInt32 accessKey;
|
||||
nsresult rv = prefBranch->GetIntPref("ui.key.generalAccessKey", &accessKey);
|
||||
if (NS_SUCCEEDED(rv) && accessKey != -1) {
|
||||
switch (accessKey) {
|
||||
case nsIDOMKeyEvent::DOM_VK_SHIFT: return NS_MODIFIER_SHIFT;
|
||||
case nsIDOMKeyEvent::DOM_VK_CONTROL: return NS_MODIFIER_CONTROL;
|
||||
case nsIDOMKeyEvent::DOM_VK_ALT: return NS_MODIFIER_ALT;
|
||||
case nsIDOMKeyEvent::DOM_VK_META: return NS_MODIFIER_META;
|
||||
default: return 0;
|
||||
}
|
||||
switch (Preferences::GetInt("ui.key.generalAccessKey", -1)) {
|
||||
case -1: break;
|
||||
case nsIDOMKeyEvent::DOM_VK_SHIFT: return NS_MODIFIER_SHIFT;
|
||||
case nsIDOMKeyEvent::DOM_VK_CONTROL: return NS_MODIFIER_CONTROL;
|
||||
case nsIDOMKeyEvent::DOM_VK_ALT: return NS_MODIFIER_ALT;
|
||||
case nsIDOMKeyEvent::DOM_VK_META: return NS_MODIFIER_META;
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
// get the docShell to this DOMNode, return 0 on failure
|
||||
|
@ -368,17 +362,17 @@ GetAccessModifierMask(nsIContent* aContent)
|
|||
return 0;
|
||||
|
||||
// determine the access modifier used in this context
|
||||
nsresult rv = NS_ERROR_FAILURE;
|
||||
PRInt32 itemType, accessModifierMask = 0;
|
||||
treeItem->GetItemType(&itemType);
|
||||
switch (itemType) {
|
||||
case nsIDocShellTreeItem::typeChrome:
|
||||
rv = Preferences::GetInt("ui.key.chromeAccess", &accessModifierMask);
|
||||
break;
|
||||
|
||||
case nsIDocShellTreeItem::typeChrome:
|
||||
rv = prefBranch->GetIntPref("ui.key.chromeAccess", &accessModifierMask);
|
||||
break;
|
||||
|
||||
case nsIDocShellTreeItem::typeContent:
|
||||
rv = prefBranch->GetIntPref("ui.key.contentAccess", &accessModifierMask);
|
||||
break;
|
||||
case nsIDocShellTreeItem::typeContent:
|
||||
rv = Preferences::GetInt("ui.key.contentAccess", &accessModifierMask);
|
||||
break;
|
||||
}
|
||||
|
||||
return NS_SUCCEEDED(rv) ? accessModifierMask : 0;
|
||||
|
@ -682,15 +676,7 @@ nsAccessible::IsVisible(PRBool* aIsOffscreen)
|
|||
}
|
||||
|
||||
// The frame intersects the viewport, but we need to check the parent view chain :(
|
||||
nsIDocument* doc = mContent->GetOwnerDoc();
|
||||
if (!doc) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
nsIFrame* frameWithView =
|
||||
frame->HasView() ? frame : frame->GetAncestorWithViewExternal();
|
||||
nsIView* view = frameWithView->GetViewExternal();
|
||||
PRBool isVisible = CheckVisibilityInParentChain(doc, view);
|
||||
bool isVisible = nsCoreUtils::CheckVisibilityInParentChain(frame);
|
||||
if (isVisible && rectVisibility == nsRectVisibility_kVisible) {
|
||||
*aIsOffscreen = PR_FALSE;
|
||||
}
|
||||
|
@ -701,20 +687,23 @@ PRUint64
|
|||
nsAccessible::NativeState()
|
||||
{
|
||||
PRUint64 state = 0;
|
||||
nsEventStates intrinsicState = mContent->IntrinsicState();
|
||||
PRBool disabled = PR_FALSE;
|
||||
if (mContent->IsElement()) {
|
||||
nsEventStates elementState = mContent->AsElement()->State();
|
||||
|
||||
if (intrinsicState.HasState(NS_EVENT_STATE_INVALID))
|
||||
state |= states::INVALID;
|
||||
if (elementState.HasState(NS_EVENT_STATE_INVALID))
|
||||
state |= states::INVALID;
|
||||
|
||||
if (intrinsicState.HasState(NS_EVENT_STATE_REQUIRED))
|
||||
state |= states::REQUIRED;
|
||||
if (elementState.HasState(NS_EVENT_STATE_REQUIRED))
|
||||
state |= states::REQUIRED;
|
||||
|
||||
PRBool disabled = mContent->IsHTML() ?
|
||||
(intrinsicState.HasState(NS_EVENT_STATE_DISABLED)) :
|
||||
(mContent->AttrValueIs(kNameSpaceID_None,
|
||||
nsAccessibilityAtoms::disabled,
|
||||
nsAccessibilityAtoms::_true,
|
||||
eCaseMatters));
|
||||
disabled = mContent->IsHTML() ?
|
||||
(elementState.HasState(NS_EVENT_STATE_DISABLED)) :
|
||||
(mContent->AttrValueIs(kNameSpaceID_None,
|
||||
nsAccessibilityAtoms::disabled,
|
||||
nsAccessibilityAtoms::_true,
|
||||
eCaseMatters));
|
||||
}
|
||||
|
||||
// Set unavailable state based on disabled state, otherwise set focus states
|
||||
if (disabled) {
|
||||
|
@ -1533,15 +1522,20 @@ nsAccessible::State()
|
|||
return states::DEFUNCT;
|
||||
|
||||
PRUint64 state = NativeState();
|
||||
// Apply ARIA states to be sure accessible states will be overriden.
|
||||
// Apply ARIA states to be sure accessible states will be overridden.
|
||||
ApplyARIAState(&state);
|
||||
|
||||
if (mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_PAGETAB) {
|
||||
if (mRoleMapEntry && mRoleMapEntry->role == nsIAccessibleRole::ROLE_PAGETAB &&
|
||||
!(state & states::SELECTED) &&
|
||||
!mContent->AttrValueIs(kNameSpaceID_None,
|
||||
nsAccessibilityAtoms::aria_selected,
|
||||
nsAccessibilityAtoms::_false, eCaseMatters)) {
|
||||
// Special case: for tabs, focused implies selected, unless explicitly
|
||||
// false, i.e. aria-selected="false".
|
||||
if (state & states::FOCUSED) {
|
||||
state |= states::SELECTED;
|
||||
} else {
|
||||
// Expose 'selected' state on ARIA tab if the focus is on internal element
|
||||
// of related tabpanel.
|
||||
// If focus is in a child of the tab panel surely the tab is selected!
|
||||
nsCOMPtr<nsIAccessible> tabPanel = nsRelUtils::
|
||||
GetRelatedAccessible(this, nsIAccessibleRelation::RELATION_LABEL_FOR);
|
||||
|
||||
|
@ -3246,44 +3240,6 @@ nsAccessible::GetFirstAvailableAccessible(nsINode *aStartNode) const
|
|||
return nsnull;
|
||||
}
|
||||
|
||||
PRBool nsAccessible::CheckVisibilityInParentChain(nsIDocument* aDocument, nsIView* aView)
|
||||
{
|
||||
nsIDocument* document = aDocument;
|
||||
nsIView* view = aView;
|
||||
// both view chain and widget chain are broken between chrome and content
|
||||
while (document != nsnull) {
|
||||
while (view != nsnull) {
|
||||
if (view->GetVisibility() == nsViewVisibility_kHide) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
view = view->GetParent();
|
||||
}
|
||||
|
||||
nsIDocument* parentDoc = document->GetParentDocument();
|
||||
if (parentDoc != nsnull) {
|
||||
nsIContent* content = parentDoc->FindContentForSubDocument(document);
|
||||
if (content != nsnull) {
|
||||
nsIPresShell* shell = parentDoc->GetShell();
|
||||
if (!shell) {
|
||||
return PR_FALSE;
|
||||
}
|
||||
nsIFrame* frame = content->GetPrimaryFrame();
|
||||
while (frame != nsnull && !frame->HasView()) {
|
||||
frame = frame->GetParent();
|
||||
}
|
||||
|
||||
if (frame != nsnull) {
|
||||
view = frame->GetViewExternal();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
document = parentDoc;
|
||||
}
|
||||
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsAccessible::GetAttrValue(nsIAtom *aProperty, double *aValue)
|
||||
{
|
||||
|
|
|
@ -518,7 +518,7 @@ protected:
|
|||
* Return true if the children flag is set.
|
||||
*/
|
||||
inline bool IsChildrenFlag(ChildrenFlags aFlag) const
|
||||
{ return (mFlags & kChildrenFlagsMask) == aFlag; }
|
||||
{ return static_cast<ChildrenFlags> (mFlags & kChildrenFlagsMask) == aFlag; }
|
||||
|
||||
/**
|
||||
* Set children flag.
|
||||
|
@ -606,9 +606,6 @@ protected:
|
|||
//////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers
|
||||
|
||||
// Check the visibility across both parent content and chrome
|
||||
PRBool CheckVisibilityInParentChain(nsIDocument* aDocument, nsIView* aView);
|
||||
|
||||
/**
|
||||
* Get the container node for an atomic region, defined by aria-atomic="true"
|
||||
* @return the container node
|
||||
|
|
|
@ -332,8 +332,8 @@ nsApplicationAccessible::GetPlatformVersion(nsAString& aVersion)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessNode public methods
|
||||
|
||||
PRBool
|
||||
nsApplicationAccessible::IsDefunct()
|
||||
bool
|
||||
nsApplicationAccessible::IsDefunct() const
|
||||
{
|
||||
return nsAccessibilityService::IsShutdown();
|
||||
}
|
||||
|
|
|
@ -115,7 +115,7 @@ public:
|
|||
NS_DECL_NSIACCESSIBLEAPPLICATION
|
||||
|
||||
// nsAccessNode
|
||||
virtual PRBool IsDefunct();
|
||||
virtual bool IsDefunct() const;
|
||||
virtual PRBool Init();
|
||||
virtual void Shutdown();
|
||||
virtual bool IsPrimaryForNode() const;
|
||||
|
|
|
@ -141,7 +141,7 @@ nsLinkableAccessible::GetNumActions(PRUint8 *aNumActions)
|
|||
{
|
||||
NS_ENSURE_ARG_POINTER(aNumActions);
|
||||
|
||||
*aNumActions = mActionAcc ? 1 : 0;
|
||||
*aNumActions = (mIsOnclick || mIsLink) ? 1 : 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -228,7 +228,6 @@ nsLinkableAccessible::BindToParent(nsAccessible* aParent,
|
|||
mIsOnclick = PR_FALSE;
|
||||
|
||||
if (nsCoreUtils::HasClickListener(mContent)) {
|
||||
mActionAcc = this;
|
||||
mIsOnclick = PR_TRUE;
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -352,12 +352,15 @@ nsCaretAccessible::GetCaretRect(nsIWidget **aOutWidget)
|
|||
}
|
||||
|
||||
nsPoint offset;
|
||||
// Offset from widget origin to the frame origin, which includes chrome
|
||||
// on the widget.
|
||||
*aOutWidget = frame->GetNearestWidget(offset);
|
||||
NS_ENSURE_TRUE(*aOutWidget, nsIntRect());
|
||||
rect.MoveBy(offset);
|
||||
|
||||
caretRect = rect.ToOutsidePixels(frame->PresContext()->AppUnitsPerDevPixel());
|
||||
caretRect.MoveBy((*aOutWidget)->WidgetToScreenOffset());
|
||||
// ((content screen origin) - (content offset in the widget)) = widget origin on the screen
|
||||
caretRect.MoveBy((*aOutWidget)->WidgetToScreenOffset() - (*aOutWidget)->GetClientOffset());
|
||||
|
||||
// Correct for character size, so that caret always matches the size of the character
|
||||
// This is important for font size transitions, and is necessary because the Gecko caret uses the
|
||||
|
|
|
@ -63,6 +63,7 @@
|
|||
#include "nsPIDOMWindow.h"
|
||||
#include "nsGUIEvent.h"
|
||||
#include "nsIView.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
#include "nsContentCID.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
|
@ -753,6 +754,30 @@ nsCoreUtils::IsColumnHidden(nsITreeColumn *aColumn)
|
|||
nsAccessibilityAtoms::_true, eCaseMatters);
|
||||
}
|
||||
|
||||
bool
|
||||
nsCoreUtils::CheckVisibilityInParentChain(nsIFrame* aFrame)
|
||||
{
|
||||
nsIView* view = aFrame->GetClosestView();
|
||||
if (view && !view->IsEffectivelyVisible())
|
||||
return false;
|
||||
|
||||
nsIPresShell* presShell = aFrame->PresContext()->GetPresShell();
|
||||
while (presShell) {
|
||||
if (!presShell->IsActive()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nsIFrame* rootFrame = presShell->GetRootFrame();
|
||||
presShell = nsnull;
|
||||
if (rootFrame) {
|
||||
nsIFrame* frame = nsLayoutUtils::GetCrossDocParentFrame(rootFrame);
|
||||
if (frame) {
|
||||
presShell = frame->PresContext()->GetPresShell();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsAccessibleDOMStringList
|
||||
|
|
|
@ -367,6 +367,12 @@ public:
|
|||
return aContent->NodeInfo()->Equals(nsAccessibilityAtoms::th) ||
|
||||
aContent->HasAttr(kNameSpaceID_None, nsAccessibilityAtoms::scope);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the visibility across both parent content and chrome.
|
||||
*/
|
||||
static bool CheckVisibilityInParentChain(nsIFrame* aFrame);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -54,8 +54,6 @@
|
|||
#include "nsIDOMCharacterData.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMDocumentType.h"
|
||||
#include "nsIDOMNSDocument.h"
|
||||
#include "nsIDOMNSHTMLDocument.h"
|
||||
#include "nsIDOMXULDocument.h"
|
||||
#include "nsIDOMMutationEvent.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
|
@ -315,12 +313,7 @@ nsDocAccessible::NativeState()
|
|||
}
|
||||
|
||||
nsIFrame* frame = GetFrame();
|
||||
while (frame != nsnull && !frame->HasView()) {
|
||||
frame = frame->GetParent();
|
||||
}
|
||||
|
||||
if (frame == nsnull ||
|
||||
!CheckVisibilityInParentChain(mDocument, frame->GetViewExternal())) {
|
||||
if (!frame || !nsCoreUtils::CheckVisibilityInParentChain(frame)) {
|
||||
state |= states::INVISIBLE | states::OFFSCREEN;
|
||||
}
|
||||
|
||||
|
@ -411,22 +404,24 @@ NS_IMETHODIMP nsDocAccessible::GetURL(nsAString& aURL)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocAccessible::GetTitle(nsAString& aTitle)
|
||||
NS_IMETHODIMP
|
||||
nsDocAccessible::GetTitle(nsAString& aTitle)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNSDocument> domnsDocument(do_QueryInterface(mDocument));
|
||||
if (domnsDocument) {
|
||||
return domnsDocument->GetTitle(aTitle);
|
||||
nsCOMPtr<nsIDOMDocument> domDocument = do_QueryInterface(mDocument);
|
||||
if (!domDocument) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
return domDocument->GetTitle(aTitle);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocAccessible::GetMimeType(nsAString& aMimeType)
|
||||
NS_IMETHODIMP
|
||||
nsDocAccessible::GetMimeType(nsAString& aMimeType)
|
||||
{
|
||||
nsCOMPtr<nsIDOMNSDocument> domnsDocument(do_QueryInterface(mDocument));
|
||||
if (domnsDocument) {
|
||||
return domnsDocument->GetContentType(aMimeType);
|
||||
nsCOMPtr<nsIDOMDocument> domDocument = do_QueryInterface(mDocument);
|
||||
if (!domDocument) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
return domDocument->GetContentType(aMimeType);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsDocAccessible::GetDocType(nsAString& aDocType)
|
||||
|
@ -607,6 +602,12 @@ nsDocAccessible::Init()
|
|||
if (!mNotificationController)
|
||||
return PR_FALSE;
|
||||
|
||||
// Mark the document accessible as loaded if its DOM document was loaded at
|
||||
// this point (this can happen because a11y is started late or DOM document
|
||||
// having no container was loaded.
|
||||
if (mDocument->GetReadyStateEnum() == nsIDocument::READYSTATE_COMPLETE)
|
||||
mIsLoaded = PR_TRUE;
|
||||
|
||||
AddEventListeners();
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
@ -670,8 +671,8 @@ nsDocAccessible::GetFrame() const
|
|||
return root;
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsDocAccessible::IsDefunct()
|
||||
bool
|
||||
nsDocAccessible::IsDefunct() const
|
||||
{
|
||||
return nsHyperTextAccessibleWrap::IsDefunct() || !mDocument;
|
||||
}
|
||||
|
@ -1037,6 +1038,14 @@ nsDocAccessible::AttributeChangedImpl(nsIContent* aContent, PRInt32 aNameSpaceID
|
|||
return;
|
||||
}
|
||||
|
||||
if (aAttribute == nsAccessibilityAtoms::aria_busy) {
|
||||
PRBool isOn = !aContent->AttrValueIs(aNameSpaceID, aAttribute,
|
||||
nsAccessibilityAtoms::_true, eCaseMatters);
|
||||
nsRefPtr<AccEvent> event = new AccStateChangeEvent(aContent, states::BUSY, isOn);
|
||||
FireDelayedAccessibleEvent(event);
|
||||
return;
|
||||
}
|
||||
|
||||
if (aAttribute == nsAccessibilityAtoms::selected ||
|
||||
aAttribute == nsAccessibilityAtoms::aria_selected) {
|
||||
// ARIA or XUL selection
|
||||
|
|
|
@ -108,7 +108,7 @@ public:
|
|||
virtual PRBool Init();
|
||||
virtual void Shutdown();
|
||||
virtual nsIFrame* GetFrame() const;
|
||||
virtual PRBool IsDefunct();
|
||||
virtual bool IsDefunct() const;
|
||||
virtual nsINode* GetNode() const { return mDocument; }
|
||||
virtual nsIDocument* GetDocumentNode() const { return mDocument; }
|
||||
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#define CreateEvent CreateEventA
|
||||
#include "nsIDOMDocument.h"
|
||||
|
||||
#include "States.h"
|
||||
#include "nsAccessibilityService.h"
|
||||
#include "nsApplicationAccessibleWrap.h"
|
||||
|
@ -48,7 +51,6 @@
|
|||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIDocShellTreeNode.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMElement.h"
|
||||
#include "nsIDOMEventListener.h"
|
||||
#include "nsIDOMEventTarget.h"
|
||||
|
@ -57,7 +59,6 @@
|
|||
#include "nsIDOMHTMLInputElement.h"
|
||||
#include "nsIDOMHTMLSelectElement.h"
|
||||
#include "nsIDOMDataContainerEvent.h"
|
||||
#include "nsIDOMNSDocument.h"
|
||||
#include "nsIDOMNSEvent.h"
|
||||
#include "nsIDOMXULMenuListElement.h"
|
||||
#include "nsIDOMXULMultSelectCntrlEl.h"
|
||||
|
@ -76,11 +77,8 @@
|
|||
#include "nsReadableUtils.h"
|
||||
#include "nsRootAccessible.h"
|
||||
#include "nsIDOMNSEventTarget.h"
|
||||
#include "nsIDOMDocumentEvent.h"
|
||||
#include "nsIPrivateDOMEvent.h"
|
||||
#include "nsFocusManager.h"
|
||||
#include "mozilla/dom/Element.h"
|
||||
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
#include "nsXULTreeAccessible.h"
|
||||
|
@ -140,7 +138,7 @@ nsRootAccessible::GetName(nsAString& aName)
|
|||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMNSDocument> document(do_QueryInterface(mDocument));
|
||||
nsCOMPtr<nsIDOMDocument> document = do_QueryInterface(mDocument);
|
||||
return document->GetTitle(aName);
|
||||
}
|
||||
|
||||
|
@ -415,11 +413,11 @@ nsRootAccessible::FireCurrentFocusEvent()
|
|||
return; // No current focus
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDOMDocumentEvent> docEvent = do_QueryInterface(mDocument);
|
||||
if (docEvent) {
|
||||
nsCOMPtr<nsIDOMDocument> domDoc = do_QueryInterface(mDocument);
|
||||
if (domDoc) {
|
||||
nsCOMPtr<nsIDOMEvent> event;
|
||||
if (NS_SUCCEEDED(docEvent->CreateEvent(NS_LITERAL_STRING("Events"),
|
||||
getter_AddRefs(event))) &&
|
||||
if (NS_SUCCEEDED(domDoc->CreateEvent(NS_LITERAL_STRING("Events"),
|
||||
getter_AddRefs(event))) &&
|
||||
NS_SUCCEEDED(event->InitEvent(NS_LITERAL_STRING("focus"), PR_TRUE, PR_TRUE))) {
|
||||
|
||||
nsCOMPtr<nsIPrivateDOMEvent> privateEvent(do_QueryInterface(event));
|
||||
|
|
|
@ -81,7 +81,7 @@ nsHTMLLinkAccessible::NativeState()
|
|||
states |= states::SELECTABLE;
|
||||
}
|
||||
|
||||
nsEventStates state = mContent->IntrinsicState();
|
||||
nsEventStates state = mContent->AsElement()->State();
|
||||
if (state.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED |
|
||||
NS_EVENT_STATE_UNVISITED)) {
|
||||
states |= states::LINKED;
|
||||
|
@ -187,7 +187,7 @@ nsHTMLLinkAccessible::IsLinked()
|
|||
if (IsDefunct())
|
||||
return PR_FALSE;
|
||||
|
||||
nsEventStates state = mContent->IntrinsicState();
|
||||
nsEventStates state = mContent->AsElement()->State();
|
||||
return state.HasAtLeastOneOfStates(NS_EVENT_STATE_VISITED |
|
||||
NS_EVENT_STATE_UNVISITED);
|
||||
}
|
||||
|
|
|
@ -54,11 +54,13 @@
|
|||
#include "nsIDOMNSHTMLElement.h"
|
||||
#include "nsIFrame.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsPIDOMWindow.h"
|
||||
#include "nsIServiceManager.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
/// the accessible library and cached methods
|
||||
HINSTANCE nsAccessNodeWrap::gmAccLib = nsnull;
|
||||
HINSTANCE nsAccessNodeWrap::gmUserLib = nsnull;
|
||||
|
@ -711,22 +713,16 @@ void nsAccessNodeWrap::TurnOffNewTabSwitchingForJawsAndWE()
|
|||
// Check to see if the pref for disallowing CtrlTab is already set.
|
||||
// If so, bail out.
|
||||
// If not, set it.
|
||||
nsCOMPtr<nsIPrefBranch> prefs (do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
if (prefs) {
|
||||
PRBool hasDisallowNewCtrlTabPref = PR_FALSE;
|
||||
nsresult rv = prefs->PrefHasUserValue(CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF,
|
||||
&hasDisallowNewCtrlTabPref);
|
||||
if (NS_SUCCEEDED(rv) && hasDisallowNewCtrlTabPref) {
|
||||
// This pref has been set before. There is no default for it.
|
||||
// Do nothing further, respect the setting that's there.
|
||||
// That way, if noone touches it, it'll stay on after toggled once.
|
||||
// If someone decided to turn it off, we respect that, too.
|
||||
return;
|
||||
}
|
||||
|
||||
// Value has never been set, set it.
|
||||
prefs->SetBoolPref(CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF, PR_TRUE);
|
||||
if (Preferences::HasUserValue(CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF)) {
|
||||
// This pref has been set before. There is no default for it.
|
||||
// Do nothing further, respect the setting that's there.
|
||||
// That way, if noone touches it, it'll stay on after toggled once.
|
||||
// If someone decided to turn it off, we respect that, too.
|
||||
return;
|
||||
}
|
||||
|
||||
// Value has never been set, set it.
|
||||
Preferences::SetBool(CTRLTAB_DISALLOW_FOR_SCREEN_READERS_PREF, PR_TRUE);
|
||||
}
|
||||
|
||||
void nsAccessNodeWrap::DoATSpecificProcessing()
|
||||
|
|
|
@ -58,7 +58,6 @@
|
|||
#include "nsIScrollableFrame.h"
|
||||
#include "nsINameSpaceManager.h"
|
||||
#include "nsINodeInfo.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsRootAccessible.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsTextFormatter.h"
|
||||
|
|
|
@ -50,8 +50,6 @@
|
|||
#include "nsIDOMXULSelectCntrlItemEl.h"
|
||||
#include "nsIDOMXULMultSelectCntrlEl.h"
|
||||
#include "nsIDOMKeyEvent.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIPresShell.h"
|
||||
#include "nsIContent.h"
|
||||
|
@ -59,6 +57,10 @@
|
|||
#include "nsILookAndFeel.h"
|
||||
#include "nsWidgetsCID.h"
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
|
||||
static NS_DEFINE_CID(kLookAndFeelCID, NS_LOOKANDFEEL_CID);
|
||||
|
||||
|
@ -410,10 +412,7 @@ nsXULMenuitemAccessible::GetKeyboardShortcut(nsAString& aAccessKey)
|
|||
// No need to cache pref service, this happens rarely
|
||||
if (gMenuAccesskeyModifier == -1) {
|
||||
// Need to initialize cached global accesskey pref
|
||||
gMenuAccesskeyModifier = 0;
|
||||
nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
if (prefBranch)
|
||||
prefBranch->GetIntPref("ui.key.menuAccessKey", &gMenuAccesskeyModifier);
|
||||
gMenuAccesskeyModifier = Preferences::GetInt("ui.key.menuAccessKey", 0);
|
||||
}
|
||||
|
||||
nsAutoString propertyKey;
|
||||
|
|
|
@ -156,8 +156,8 @@ nsXULTreeAccessible::GetValue(nsAString& aValue)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULTreeAccessible: nsAccessNode implementation
|
||||
|
||||
PRBool
|
||||
nsXULTreeAccessible::IsDefunct()
|
||||
bool
|
||||
nsXULTreeAccessible::IsDefunct() const
|
||||
{
|
||||
return nsAccessibleWrap::IsDefunct() || !mTree || !mTreeView;
|
||||
}
|
||||
|
@ -834,8 +834,8 @@ nsXULTreeItemAccessibleBase::DoAction(PRUint8 aIndex)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULTreeItemAccessibleBase: nsAccessNode implementation
|
||||
|
||||
PRBool
|
||||
nsXULTreeItemAccessibleBase::IsDefunct()
|
||||
bool
|
||||
nsXULTreeItemAccessibleBase::IsDefunct() const
|
||||
{
|
||||
if (nsAccessibleWrap::IsDefunct() || !mTree || !mTreeView || mRow < 0)
|
||||
return PR_TRUE;
|
||||
|
@ -1091,8 +1091,8 @@ nsXULTreeItemAccessible::GetName(nsAString& aName)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULTreeItemAccessible: nsAccessNode implementation
|
||||
|
||||
PRBool
|
||||
nsXULTreeItemAccessible::IsDefunct()
|
||||
bool
|
||||
nsXULTreeItemAccessible::IsDefunct() const
|
||||
{
|
||||
return nsXULTreeItemAccessibleBase::IsDefunct() || !mColumn;
|
||||
}
|
||||
|
|
|
@ -80,7 +80,7 @@ public:
|
|||
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
|
||||
|
||||
// nsAccessNode
|
||||
virtual PRBool IsDefunct();
|
||||
virtual bool IsDefunct() const;
|
||||
virtual void Shutdown();
|
||||
|
||||
// nsAccessible
|
||||
|
@ -201,7 +201,7 @@ public:
|
|||
NS_IMETHOD DoAction(PRUint8 aIndex);
|
||||
|
||||
// nsAccessNode
|
||||
virtual PRBool IsDefunct();
|
||||
virtual bool IsDefunct() const;
|
||||
virtual void Shutdown();
|
||||
virtual bool IsPrimaryForNode() const;
|
||||
|
||||
|
@ -266,7 +266,7 @@ public:
|
|||
NS_IMETHOD GetName(nsAString& aName);
|
||||
|
||||
// nsAccessNode
|
||||
virtual PRBool IsDefunct();
|
||||
virtual bool IsDefunct() const;
|
||||
virtual PRBool Init();
|
||||
virtual void Shutdown();
|
||||
|
||||
|
|
|
@ -1087,8 +1087,8 @@ nsXULTreeGridCellAccessible::IsSelected(PRBool *aIsSelected)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsXULTreeGridCellAccessible: nsAccessNode implementation
|
||||
|
||||
PRBool
|
||||
nsXULTreeGridCellAccessible::IsDefunct()
|
||||
bool
|
||||
nsXULTreeGridCellAccessible::IsDefunct() const
|
||||
{
|
||||
return nsLeafAccessible::IsDefunct() || !mParent || !mTree || !mTreeView ||
|
||||
!mColumn;
|
||||
|
|
|
@ -155,7 +155,7 @@ public:
|
|||
NS_DECL_NSIACCESSIBLETABLECELL
|
||||
|
||||
// nsAccessNode
|
||||
virtual PRBool IsDefunct();
|
||||
virtual bool IsDefunct() const;
|
||||
virtual PRBool Init();
|
||||
virtual bool IsPrimaryForNode() const;
|
||||
|
||||
|
|
|
@ -90,16 +90,14 @@ _TEST_FILES =\
|
|||
test_aria_roles.xul \
|
||||
test_aria_token_attrs.html \
|
||||
test_bug420863.html \
|
||||
$(warning test_childAtPoint.html temporarily disabled) \
|
||||
$(warning test_childAtPoint.xul temporarily disabled) \
|
||||
test_childAtPoint.html \
|
||||
test_childAtPoint.xul \
|
||||
test_descr.html \
|
||||
test_elm_landmarks.html \
|
||||
test_elm_listbox.xul \
|
||||
$(warning test_elm_media.html temporarily disabled) \
|
||||
test_elm_nsApplicationAcc.html \
|
||||
test_elm_plugin.html \
|
||||
test_keys.html \
|
||||
$(warning test_nsIAccessible_comboboxes.xul temporarily disabled) \
|
||||
test_nsIAccessible_selects.html \
|
||||
test_nsIAccessibleDocument.html \
|
||||
test_nsIAccessibleImage.html \
|
||||
|
|
|
@ -52,6 +52,7 @@ _TEST_FILES =\
|
|||
test_general.xul \
|
||||
test_inputs.html \
|
||||
test_link.html \
|
||||
test_media.html \
|
||||
test_tree.xul \
|
||||
test_treegrid.xul \
|
||||
$(NULL)
|
||||
|
|
|
@ -36,9 +36,19 @@
|
|||
ID: "li_clickable3",
|
||||
actionName: "click",
|
||||
events: CLICK_EVENTS
|
||||
},
|
||||
{
|
||||
ID: "onclick_img",
|
||||
actionName: "click",
|
||||
events: CLICK_EVENTS
|
||||
}
|
||||
];
|
||||
|
||||
testActions(actionsArray);
|
||||
|
||||
getAccessible("onclick_img").takeFocus();
|
||||
is(getAccessible("link1").numActions, 1, "links should have one action");
|
||||
is(getAccessible("link2").numActions, 1, "link with onclick handler should have 1 action");
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
@ -58,6 +68,11 @@
|
|||
title="Expose click action if mouseup and mousedown are registered">
|
||||
Mozilla Bug 423409
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=659620"
|
||||
title="hang when trying to edit a page on wikimo with NVDA running">
|
||||
Mozilla Bug 659620
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
|
@ -68,5 +83,11 @@
|
|||
<li id="li_clickable2" onmousedown="">Clickable list item</li>
|
||||
<li id="li_clickable3" onmouseup="">Clickable list item</li>
|
||||
</ul>
|
||||
|
||||
<!-- linkable accessibles -->
|
||||
<img id="onclick_img" onclick="" src="../moz.png">
|
||||
|
||||
<a id="link1" href="www">linkable textleaf accessible</a>
|
||||
<div id="link2" onclick="">linkable textleaf accessible</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -13,15 +13,15 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=483573
|
|||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="common.js"></script>
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="events.js"></script>
|
||||
src="../events.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="actions.js"></script>
|
||||
src="../actions.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="role.js"></script>
|
||||
src="../role.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="states.js"></script>
|
||||
src="../states.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
|
@ -58,49 +58,11 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=483573
|
|||
|
||||
function doTest()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// test the accessible tree
|
||||
|
||||
var accTree = {
|
||||
role: ROLE_GROUPING,
|
||||
children: [
|
||||
{ // start/stop button
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "Play",
|
||||
states: {
|
||||
states: STATE_FOCUSABLE
|
||||
}
|
||||
},
|
||||
{ // buffer bar
|
||||
role: ROLE_PROGRESSBAR
|
||||
},
|
||||
{ // progress bar
|
||||
role: ROLE_PROGRESSBAR
|
||||
},
|
||||
{ // slider of progress bar
|
||||
role: ROLE_SLIDER,
|
||||
name: "0:00 of 0:01 elapsed",
|
||||
states: {
|
||||
states: STATE_FOCUSABLE
|
||||
}
|
||||
},
|
||||
{ // duration label, role="presentation"
|
||||
role: ROLE_NOTHING
|
||||
},
|
||||
{ // mute button
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "Mute",
|
||||
states: {
|
||||
states: STATE_FOCUSABLE
|
||||
}
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("audio", accTree);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// test actions of audio controls
|
||||
|
||||
todo(false, "Focus test are disabled until bug 494175 is fixed.");
|
||||
|
||||
var audioElm = getAccessible("audio");
|
||||
var playBtn = audioElm.firstChild;
|
||||
var scrubber = playBtn.nextSibling.nextSibling.nextSibling;
|
||||
|
@ -112,24 +74,24 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=483573
|
|||
actionName: "press",
|
||||
events: CLICK_EVENTS,
|
||||
eventSeq: [
|
||||
new focusChecker(muteBtn),
|
||||
// new focusChecker(muteBtn),
|
||||
new nameChecker(muteBtn, "Unmute"),
|
||||
]
|
||||
},
|
||||
{
|
||||
ID: scrubber,
|
||||
actionName: "activate",
|
||||
events: null,
|
||||
eventSeq: [
|
||||
new focusChecker(scrubber)
|
||||
]
|
||||
},
|
||||
// {
|
||||
// ID: scrubber,
|
||||
// actionName: "activate",
|
||||
// events: null,
|
||||
// eventSeq: [
|
||||
// new focusChecker(scrubber)
|
||||
// ]
|
||||
// },
|
||||
{
|
||||
ID: playBtn,
|
||||
actionName: "press",
|
||||
events: CLICK_EVENTS,
|
||||
eventSeq: [
|
||||
new focusChecker(playBtn),
|
||||
// new focusChecker(playBtn),
|
||||
new nameChecker(playBtn, "Pause"),
|
||||
]
|
||||
}
|
||||
|
@ -152,7 +114,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=483573
|
|||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<audio id="audio" src="bug461281.ogg"
|
||||
<audio id="audio" src="../bug461281.ogg"
|
||||
controls="true"></audio>
|
||||
|
||||
<div id="eventDump"></div>
|
|
@ -30,11 +30,11 @@
|
|||
var menu1 = document.getElementById("menu_item1");
|
||||
menu1.open = true;
|
||||
|
||||
window.setTimeout(function() {
|
||||
menu1.addEventListener("popupshown", function() {
|
||||
var menu2 = document.getElementById("menu_item2");
|
||||
menu2.open = true;
|
||||
|
||||
window.setTimeout(function() {
|
||||
menu2.addEventListener("popupshown", function() {
|
||||
testGroupAttrs("menu_item1.1", 1, 1);
|
||||
testGroupAttrs("menu_item1.2", 1, 3);
|
||||
testGroupAttrs("menu_item1.4", 2, 3);
|
||||
|
@ -42,9 +42,12 @@
|
|||
testGroupAttrs("menu_item2.1", 1, 2, 1);
|
||||
testGroupAttrs("menu_item2.2", 2, 2, 1);
|
||||
|
||||
menu1.open = false;
|
||||
menu2.open = false;
|
||||
|
||||
SimpleTest.finish();
|
||||
}, 200);
|
||||
}, 200);
|
||||
}, false);
|
||||
}, false);
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// xul:tab
|
||||
|
|
|
@ -93,7 +93,7 @@ function addA11yLoadEvent(aFunc)
|
|||
if (state.value & STATE_BUSY)
|
||||
return waitForDocLoad();
|
||||
|
||||
window.setTimeout(aFunc, 150);
|
||||
window.setTimeout(aFunc, 0);
|
||||
},
|
||||
0
|
||||
);
|
||||
|
|
|
@ -26,35 +26,60 @@
|
|||
*/
|
||||
var gQueue = null;
|
||||
|
||||
// Debug stuff.
|
||||
//gA11yEventDumpID = "eventdump";
|
||||
// gA11yEventDumpToConsole = true;
|
||||
|
||||
function expandNode(aNodeOrID, bExpand)
|
||||
{
|
||||
this.DOMNode = getNode(aNodeOrID);
|
||||
|
||||
this.invoke = function expand_invoke() {
|
||||
this.invoke = function expandNode_invoke() {
|
||||
// Note: this should fire an EVENT_STATE_CHANGE
|
||||
this.DOMNode.setAttribute("aria-expanded", bExpand);
|
||||
};
|
||||
|
||||
this.check = function expand_check() {
|
||||
this.check = function expandNode_check() {
|
||||
testStates(aNodeOrID,
|
||||
bExpand ? STATE_EXPANDED : STATE_COLLAPSED,
|
||||
EXT_STATE_EXPANDABLE);
|
||||
};
|
||||
|
||||
this.getID = function changeValue_getID() {
|
||||
this.getID = function expandNode_getID() {
|
||||
return prettyName(aNodeOrID) + " aria-expanded changed";
|
||||
};
|
||||
}
|
||||
|
||||
function busyify(aNodeOrID, aBusy)
|
||||
{
|
||||
this.DOMNode = getNode(aNodeOrID);
|
||||
|
||||
this.invoke = function busyify_invoke() {
|
||||
this.DOMNode.setAttribute("aria-busy", aBusy);
|
||||
};
|
||||
|
||||
this.check = function busyify_check(event) {
|
||||
testStates(aNodeOrID,
|
||||
(aBusy ? STATE_BUSY : 0), 0,
|
||||
(aBusy ? 0 : STATE_BUSY), 0);
|
||||
};
|
||||
|
||||
this.getID = function busyify_getID() {
|
||||
return prettyName(aNodeOrID) + " aria-busy changed to " + aBusy;
|
||||
};
|
||||
}
|
||||
|
||||
function doTests()
|
||||
{
|
||||
gQueue = new eventQueue(nsIAccessibleEvent.EVENT_STATE_CHANGE);
|
||||
gQueue = new eventQueue(EVENT_STATE_CHANGE);
|
||||
|
||||
gQueue.push(new expandNode("section", true));
|
||||
gQueue.push(new expandNode("section", false));
|
||||
gQueue.push(new expandNode("div", true));
|
||||
gQueue.push(new expandNode("div", false));
|
||||
|
||||
gQueue.push(new busyify("aria_doc", true));
|
||||
gQueue.push(new busyify("aria_doc", false));
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
@ -71,6 +96,11 @@
|
|||
Mozilla Bug 551684
|
||||
</a>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=648133"
|
||||
title="fire state change event for aria-busy"
|
||||
Mozilla Bug 648133
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
|
@ -81,5 +111,7 @@
|
|||
<div id="section" role="section" aria-expanded="false">expandable section</div>
|
||||
<div id="div" aria-expanded="false">expandable native div</div>
|
||||
|
||||
<!-- aria-busy -->
|
||||
<div id="aria_doc" role="document" tabindex="0">A document</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -118,6 +118,25 @@
|
|||
}
|
||||
}
|
||||
|
||||
function makeIFrameVisible(aID)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, this.DOMNode.parentNode)
|
||||
];
|
||||
|
||||
this.invoke = function makeIFrameVisible_invoke()
|
||||
{
|
||||
this.DOMNode.style.visibility = "visible";
|
||||
}
|
||||
|
||||
this.getID = function makeIFrameVisible_getID()
|
||||
{
|
||||
return "The accessible for DOM document loaded before it's shown shouldn't have busy state.";
|
||||
}
|
||||
}
|
||||
|
||||
function openDialogWnd(aURL)
|
||||
{
|
||||
// Get application root accessible.
|
||||
|
@ -224,7 +243,7 @@
|
|||
|
||||
// Debug stuff.
|
||||
// gA11yEventDumpID = "eventdump";
|
||||
// gA11yEventDumpToConsole = true;
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
|
@ -235,12 +254,30 @@
|
|||
gQueue.push(new morphIFrame("iframe", kHide));
|
||||
gQueue.push(new morphIFrame("iframe", kShow));
|
||||
gQueue.push(new morphIFrame("iframe", kRemove));
|
||||
gQueue.push(new makeIFrameVisible("iframe2"));
|
||||
gQueue.push(new openDialogWnd("about:"));
|
||||
gQueue.push(new openWndShutdownDoc());
|
||||
|
||||
gQueue.onFinish = doLastCallTests;
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
function doLastCallTests()
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// makeIFrameVisible() test, part2
|
||||
|
||||
// The document shouldn't have busy state (the DOM document was loaded
|
||||
// before its accessible was created). Do this test lately to make sure
|
||||
// the content of document accessible was created initially, prior to this
|
||||
// the document accessible keeps busy state. The initial creation happens
|
||||
// asynchronously after document creation, there are no events we could
|
||||
// use to catch it.
|
||||
var iframeDoc = getAccessible("iframe2").firstChild;
|
||||
testStates(iframeDoc, 0, 0, STATE_BUSY);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTests);
|
||||
</script>
|
||||
|
@ -268,6 +305,11 @@
|
|||
title="Shutdown document accessible when presshell goes away">
|
||||
Mozilla Bug 571459
|
||||
</a>
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=658185"
|
||||
title="The DOM document loaded before it's shown shouldn't have busy state">
|
||||
Mozilla Bug 658185
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
|
@ -275,6 +317,7 @@
|
|||
</pre>
|
||||
|
||||
<div id="testContainer"><iframe id="iframe"></iframe></div>
|
||||
<div id="testContainer2"><iframe id="iframe2" src="about:" style="visibility: hidden;"></iframe></div>
|
||||
<div id="eventdump"></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -48,6 +48,8 @@ include $(topsrcdir)/config/rules.mk
|
|||
_TEST_FILES =\
|
||||
test_aria.html \
|
||||
test_aria_imgmap.html \
|
||||
test_aria_tabs.html \
|
||||
test_comboboxes.xul \
|
||||
test_doc.html \
|
||||
test_docarticle.html \
|
||||
test_editablebody.html \
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Test ARIA tab accessible selected state</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../states.js"></script>
|
||||
<script type="application/javascript"
|
||||
src="../events.js"></script>
|
||||
|
||||
<script type="application/javascript">
|
||||
function focusARIATab(aID, aIsSelected)
|
||||
{
|
||||
this.DOMNode = getNode(aID);
|
||||
|
||||
this.invoke = function focusARIATab_invoke()
|
||||
{
|
||||
this.DOMNode.focus();
|
||||
}
|
||||
|
||||
this.check = function focusARIATab_check(aEvent)
|
||||
{
|
||||
testStates(this.DOMNode, aIsSelected ? STATE_SELECTED : 0, 0,
|
||||
aIsSelected ? 0 : STATE_SELECTED);
|
||||
}
|
||||
|
||||
this.getID = function focusARIATab_getID()
|
||||
{
|
||||
return "Focused ARIA Tab with aria-selected=" +
|
||||
(aIsSelected ? "true, should" : "false, shouldn't") +
|
||||
" have selected state on " + prettyName(aID);
|
||||
}
|
||||
}
|
||||
|
||||
function focusActiveDescendantTab(aTabID, aTabListID, aIsSelected)
|
||||
{
|
||||
this.DOMNode = getNode(aTabID);
|
||||
this.tabListDOMNode = getNode(aTabListID);
|
||||
|
||||
this.invoke = function focusActiveDescendantTab_invoke()
|
||||
{
|
||||
this.tabListDOMNode.setAttribute("aria-activedescendant", aTabID);
|
||||
this.tabListDOMNode.focus();
|
||||
}
|
||||
|
||||
this.check = function focusActiveDescendantTab_check(aEvent)
|
||||
{
|
||||
testStates(this.DOMNode, aIsSelected ? STATE_SELECTED : 0, 0,
|
||||
aIsSelected ? 0 : STATE_SELECTED);
|
||||
}
|
||||
|
||||
this.getID = function tabActiveDescendant_getID()
|
||||
{
|
||||
return "ARIA Tab with activedescendant " +
|
||||
(aIsSelected ? "should" : "shouldn't") +
|
||||
" have the selected state on " + prettyName(aTabID);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
//gA11yEventDumpToConsole = true;
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
function doTest()
|
||||
{
|
||||
// simple tabs
|
||||
testStates("aria_tab1", 0, 0, STATE_SELECTED);
|
||||
testStates("aria_tab2", STATE_SELECTED);
|
||||
|
||||
// To make sure our focus != selected is truly under test, we need to
|
||||
// make sure our cache of what currently has focus is correct, which
|
||||
// we update asyncronously.
|
||||
gQueue = new eventQueue(EVENT_FOCUS);
|
||||
|
||||
gQueue.push(new focusARIATab("aria_tab1", true));
|
||||
gQueue.push(new focusARIATab("aria_tab3", false));
|
||||
gQueue.push(new focusARIATab("aria_tab2", true));
|
||||
|
||||
// selection through aria-activedescendant
|
||||
// Make sure initially setting it selects the tab.
|
||||
gQueue.push(new focusActiveDescendantTab("aria_tab5", "aria_tablist2", true));
|
||||
|
||||
// Now, make sure if one is selected selection gets transferred properly.
|
||||
gQueue.push(new focusActiveDescendantTab("aria_tab6", "aria_tablist2", true));
|
||||
|
||||
// Now, make sure the focused but explicitly unselected one behaves.
|
||||
gQueue.push(new focusActiveDescendantTab("aria_tab4", "aria_tablist2", false));
|
||||
|
||||
gQueue.invoke(); // SimpleTest.finish() will be called in the end
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=653601"
|
||||
title="aria-selected ignored for ARIA tabs">
|
||||
Mozilla Bug 653601
|
||||
</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
|
||||
<!-- tab -->
|
||||
<div id="aria_tablist" role="tablist">
|
||||
<div id="aria_tab1" role="tab" tabindex="0">unselected tab</div>
|
||||
<div id="aria_tab2" role="tab" tabindex="0" aria-selected="true">selected tab</div>
|
||||
<div id="aria_tab3" role="tab" tabindex="0" aria-selected="false">focused explicitly unselected tab</div>
|
||||
</div>
|
||||
|
||||
<!-- test activeDescendant -->
|
||||
<div id="aria_tablist2" role="tablist" tabindex="0">
|
||||
<div id="aria_tab4" role="tab" aria-selected="false">focused explicitly unselected tab</div>
|
||||
<div id="aria_tab5" role="tab">initially selected tab</div>
|
||||
<div id="aria_tab6" role="tab">later selected tab</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -16,9 +16,9 @@
|
|||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="common.js" />
|
||||
src="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="events.js" />
|
||||
src="../events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
@ -64,6 +64,7 @@
|
|||
//var searchbar = document.getElementById("searchbar");
|
||||
//gQueue.push(new openHideCombobox(searchbar, true));
|
||||
//gQueue.push(new openHideCombobox(searchbar, false));
|
||||
todo(false, "Enable states test for XUL searchbar widget!");
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
|
@ -25,19 +25,19 @@
|
|||
testChildAtPoint(list, 1, 1, true, image.firstChild);
|
||||
|
||||
// ::MustPrune case (in this case childAtPoint doesn't look inside a
|
||||
// button), point is inside of button.
|
||||
var btn = getAccessible("btn");
|
||||
testChildAtPoint(btn, 1, 1, false, btn);
|
||||
testChildAtPoint(btn, 1, 1, true, btn);
|
||||
// textbox), point is inside of textbox.
|
||||
var txt = getAccessible("txt");
|
||||
testChildAtPoint(txt, 1, 1, false, txt);
|
||||
testChildAtPoint(txt, 1, 1, true, txt);
|
||||
|
||||
// ::MustPrune case, point is outside of button accessible but is in
|
||||
// ::MustPrune case, point is outside of textbox accessible but is in
|
||||
// document.
|
||||
testChildAtPoint(btn, -1, 1, false, null);
|
||||
testChildAtPoint(btn, -1, 1, true, null);
|
||||
testChildAtPoint(txt, -1, 1, false, null);
|
||||
testChildAtPoint(txt, -1, 1, true, null);
|
||||
|
||||
// ::MustPrune case, point is outside of root accessible.
|
||||
testChildAtPoint(btn, -10000, 10000, false, null);
|
||||
testChildAtPoint(btn, -10000, 10000, true, null);
|
||||
testChildAtPoint(txt, -10000, 10000, false, null);
|
||||
testChildAtPoint(txt, -10000, 10000, true, null);
|
||||
|
||||
// Not specific case, point is inside of label accessible.
|
||||
var label = getAccessible("label");
|
||||
|
@ -82,7 +82,7 @@
|
|||
|
||||
<span role="label">label1</span><span role="label" id="label">label2</span>
|
||||
|
||||
<span role="button">btn1</span><span role="button" id="btn">btn2</span>
|
||||
<span role="textbox">textbox1</span><span role="textbox" id="txt">textbox2</span>
|
||||
|
||||
<div id="outofflow" style="width: 10px; height: 10px; position: absolute; left: 0px; top: 0px; background-color: yellow;">
|
||||
</div>
|
||||
|
|
|
@ -24,8 +24,7 @@
|
|||
function doTest()
|
||||
{
|
||||
// Initialize the tree
|
||||
var view = new inTreeView();
|
||||
view.mRowCount = 5;
|
||||
var view = new nsTableTreeView(5);
|
||||
|
||||
var tree = getNode("tree");
|
||||
var treeBox = tree.treeBoxObject;
|
||||
|
|
|
@ -30,24 +30,33 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=483573
|
|||
role: ROLE_GROUPING,
|
||||
children: [
|
||||
{ // start/stop button
|
||||
role: ROLE_PUSHBUTTON
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "Play",
|
||||
children: []
|
||||
},
|
||||
{ // buffer bar
|
||||
role: ROLE_PROGRESSBAR
|
||||
role: ROLE_PROGRESSBAR,
|
||||
children: []
|
||||
},
|
||||
{ // progress bar
|
||||
role: ROLE_PROGRESSBAR
|
||||
role: ROLE_PROGRESSBAR,
|
||||
children: []
|
||||
},
|
||||
{ // slider of progress bar
|
||||
role: ROLE_SLIDER
|
||||
role: ROLE_SLIDER,
|
||||
//name: "0:00 of 0:02 elapsed",
|
||||
children: []
|
||||
},
|
||||
{ // mute button
|
||||
role: ROLE_PUSHBUTTON
|
||||
role: ROLE_PUSHBUTTON,
|
||||
name: "Mute",
|
||||
children: []
|
||||
}
|
||||
]
|
||||
};
|
||||
testAccessibleTree("audio", accTree);
|
||||
|
||||
todo(false, "Enable name test for slider. Fail on Linux.");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
src="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="../role.js" />
|
||||
<script type="application/javascript"
|
||||
src="../events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
@ -108,6 +110,11 @@
|
|||
]
|
||||
};
|
||||
|
||||
function test_txc7() {
|
||||
testAccessibleTree("txc7", accTree);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
// XPFE and Toolkit autocomplete widgets differ.
|
||||
var txc7 = document.getElementById("txc7");
|
||||
if ("clearResults" in txc7) {
|
||||
|
@ -139,11 +146,14 @@
|
|||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
);
|
||||
test_txc7();
|
||||
|
||||
} else {
|
||||
SimpleTest.ok(true, "Testing (New) Toolkit autocomplete widget.");
|
||||
|
||||
// Dumb access to trigger popup lazy creation. (See code below.)
|
||||
// Dumb access to trigger popup lazy creation.
|
||||
waitForEvent(EVENT_REORDER, txc7, test_txc7);
|
||||
txc7.popup;
|
||||
|
||||
accTree.children.push(
|
||||
|
@ -161,17 +171,8 @@
|
|||
}
|
||||
]
|
||||
}
|
||||
);
|
||||
);
|
||||
}
|
||||
|
||||
// Delay txc7 test a bit, to let Toolkit popup lazy creation complete.
|
||||
function test_txc7() {
|
||||
testAccessibleTree("txc7", accTree);
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
// SimpleTest.executeSoon() doesn't help here: use setTimeout() with a little delay.
|
||||
setTimeout(test_txc7, 25);
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
|
|
@ -102,51 +102,20 @@ CPPSRCS = nsBrowserApp.cpp
|
|||
LOCAL_INCLUDES += -I$(topsrcdir)/toolkit/xre
|
||||
LOCAL_INCLUDES += -I$(topsrcdir)/xpcom/base
|
||||
|
||||
ifdef BUILD_STATIC_LIBS
|
||||
ifdef _MSC_VER
|
||||
STATIC_COMPONENTS_LINKER_PATH = -LIBPATH:$(DEPTH)/staticlib
|
||||
else
|
||||
STATIC_COMPONENTS_LINKER_PATH = -L$(DEPTH)/staticlib
|
||||
endif
|
||||
LIBS += $(DEPTH)/toolkit/xre/$(LIB_PREFIX)xulapp_s.$(LIB_SUFFIX)
|
||||
else
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
LIBS += $(DIST)/bin/XUL
|
||||
TK_LIBS := $(TK_LIBS)
|
||||
else
|
||||
EXTRA_DSO_LIBS += xul
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
TK_LIBS := $(TK_LIBS)
|
||||
endif
|
||||
|
||||
ifdef MOZ_ENABLE_LIBXUL
|
||||
APP_XPCOM_LIBS = $(XPCOM_GLUE_LDOPTS)
|
||||
else
|
||||
MOZILLA_INTERNAL_API = 1
|
||||
APP_XPCOM_LIBS = $(XPCOM_LIBS)
|
||||
endif
|
||||
|
||||
LIBS += \
|
||||
$(STATIC_COMPONENTS_LINKER_PATH) \
|
||||
$(EXTRA_DSO_LIBS) \
|
||||
$(APP_XPCOM_LIBS) \
|
||||
$(XPCOM_GLUE_LDOPTS) \
|
||||
$(NSPR_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
ifdef BUILD_STATIC_LIBS
|
||||
LIBS += \
|
||||
$(MOZ_JS_LIBS) \
|
||||
$(TK_LIBS) \
|
||||
$(NULL)
|
||||
|
||||
# Add explicit X11 dependency when building against X11 toolkits
|
||||
ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT)))
|
||||
LIBS += $(XLDFLAGS) $(XLIBS) $(ZLIB_LIBS)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifdef MOZ_JPROF
|
||||
LIBS += -ljprof
|
||||
endif
|
||||
|
@ -171,18 +140,6 @@ ifdef _MSC_VER
|
|||
WIN32_EXE_LDFLAGS += -ENTRY:wmainCRTStartup
|
||||
endif
|
||||
|
||||
ifdef BUILD_STATIC_LIBS
|
||||
include $(topsrcdir)/config/static-config.mk
|
||||
|
||||
EXTRA_DEPS += \
|
||||
$(STATIC_EXTRA_DEPS) \
|
||||
$(NULL)
|
||||
DEFINES += $(STATIC_DEFINES)
|
||||
CPPSRCS += $(STATIC_CPPSRCS)
|
||||
EXTRA_DSO_LIBS += $(STATIC_EXTRA_DSO_LIBS)
|
||||
EXTRA_LIBS += $(STATIC_EXTRA_LIBS)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,comctl32 comdlg32 uuid shell32 ole32 oleaut32 version winspool)
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,usp10 msimg32)
|
||||
|
@ -195,9 +152,6 @@ RCFLAGS += -DMOZ_PHOENIX -I$(srcdir)
|
|||
else
|
||||
RCFLAGS += -DMOZ_PHOENIX --include-dir $(srcdir)
|
||||
endif
|
||||
ifdef BUILD_STATIC_LIBS
|
||||
RCFLAGS += -DMOZ_STATIC_BUILD
|
||||
endif
|
||||
ifdef DEBUG
|
||||
RCFLAGS += -DDEBUG
|
||||
endif
|
||||
|
@ -206,9 +160,6 @@ endif
|
|||
ifeq ($(OS_ARCH),OS2)
|
||||
RESFILE=splashos2.res
|
||||
RCFLAGS += -DMOZ_PHOENIX
|
||||
ifdef BUILD_STATIC_LIBS
|
||||
RCFLAGS += -DMOZ_STATIC_BUILD -i $(DIST)/include
|
||||
endif
|
||||
ifdef DEBUG
|
||||
RCFLAGS += -DDEBUG
|
||||
endif
|
||||
|
@ -217,12 +168,6 @@ endif
|
|||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifdef BUILD_STATIC_LIBS
|
||||
include $(topsrcdir)/config/static-rules.mk
|
||||
|
||||
DEFINES += -DIMPL_XREAPI
|
||||
endif
|
||||
|
||||
ifeq ($(MOZ_WIDGET_TOOLKIT),photon)
|
||||
LIBS += -lphexlib
|
||||
endif
|
||||
|
|
|
@ -97,6 +97,11 @@
|
|||
<versionRange minVersion="3.7a1" maxVersion="*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
<versionRange minVersion="3.3.1" maxVersion="*">
|
||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||
<versionRange minVersion="5.0a1" maxVersion="*"/>
|
||||
</targetApplication>
|
||||
</versionRange>
|
||||
</emItem>
|
||||
<emItem id="{E8E88AB0-7182-11DF-904E-6045E0D72085}"/>
|
||||
</emItems>
|
||||
|
|
|
@ -92,6 +92,55 @@
|
|||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>oga</string>
|
||||
<string>ogg</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>document.icns</string>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>audio/ogg</string>
|
||||
</array>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>HTML5 Audio (Ogg)</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>ogv</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>document.icns</string>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>video/ogg</string>
|
||||
</array>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>HTML5 Video (Ogg)</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
</dict>
|
||||
<dict>
|
||||
<key>CFBundleTypeExtensions</key>
|
||||
<array>
|
||||
<string>webm</string>
|
||||
</array>
|
||||
<key>CFBundleTypeIconFile</key>
|
||||
<string>document.icns</string>
|
||||
<key>CFBundleTypeMIMETypes</key>
|
||||
<array>
|
||||
<string>video/webm</string>
|
||||
</array>
|
||||
<key>CFBundleTypeName</key>
|
||||
<string>HTML5 Video (WebM)</string>
|
||||
<key>CFBundleTypeRole</key>
|
||||
<string>Viewer</string>
|
||||
</dict>
|
||||
</array>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>firefox-bin</string>
|
||||
|
|
|
@ -123,7 +123,7 @@ var stringBundle;
|
|||
// and targets
|
||||
let io = Components.classes["@mozilla.org/network/io-service;1"].
|
||||
getService(Components.interfaces.nsIIOService);
|
||||
let source = io.newURI(canvas.toDataURL("image/png", ""), "UTF8", null);
|
||||
let source = io.newURI(canvas.toDataURL("image/png"), "UTF8", null);
|
||||
let target = io.newFileURI(file);
|
||||
|
||||
// prepare to save the canvas data
|
||||
|
|
|
@ -91,6 +91,9 @@ function onBuiltinSurveyLoad() {
|
|||
explanation.innerHTML = "";
|
||||
}
|
||||
drawSurveyForm(task, contentDiv);
|
||||
// Allow surveys to define arbitrary page load handlers - call them
|
||||
// after creating the rest of the page:
|
||||
task.onPageLoad(task, document);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,7 +117,7 @@ function drawSurveyForm(task, contentDiv) {
|
|||
for (let i = 0; i < surveyQuestions.length; i++) {
|
||||
let question = surveyQuestions[i].question;
|
||||
let explanation = surveyQuestions[i].explanation;
|
||||
let elem;
|
||||
let elem, j;
|
||||
|
||||
elem = document.createElement("h3");
|
||||
elem.innerHTML = (i+1) + ". " + question;
|
||||
|
@ -129,7 +132,7 @@ function drawSurveyForm(task, contentDiv) {
|
|||
let choices = surveyQuestions[i].choices;
|
||||
switch (surveyQuestions[i].type) {
|
||||
case MULTIPLE_CHOICE:
|
||||
for (let j = 0; j < choices.length; j++) {
|
||||
for (j = 0; j < choices.length; j++) {
|
||||
let newRadio = document.createElement("input");
|
||||
newRadio.setAttribute("type", "radio");
|
||||
newRadio.setAttribute("name", "answer_to_" + i);
|
||||
|
@ -148,7 +151,7 @@ function drawSurveyForm(task, contentDiv) {
|
|||
case CHECK_BOXES_WITH_FREE_ENTRY:
|
||||
let checkboxName = "answer_to_" + i;
|
||||
// Check boxes:
|
||||
for (let j = 0; j < choices.length; j++) {
|
||||
for (j = 0; j < choices.length; j++) {
|
||||
let newCheck = document.createElement("input");
|
||||
newCheck.setAttribute("type", "checkbox");
|
||||
newCheck.setAttribute("name", checkboxName);
|
||||
|
@ -188,7 +191,7 @@ function drawSurveyForm(task, contentDiv) {
|
|||
inputBox.addEventListener(
|
||||
"keypress", function() {
|
||||
let elements = document.getElementsByName(checkboxName);
|
||||
for (let j = (elements.length - 1); j >= 0; j--) {
|
||||
for (j = (elements.length - 1); j >= 0; j--) {
|
||||
if (elements[j].value == freeformId) {
|
||||
elements[j].checked = true;
|
||||
break;
|
||||
|
@ -213,7 +216,7 @@ function drawSurveyForm(task, contentDiv) {
|
|||
let label = document.createElement("span");
|
||||
label.innerHTML = surveyQuestions[i].min_label;
|
||||
contentDiv.appendChild(label);
|
||||
for (let j = surveyQuestions[i].scale_minimum;
|
||||
for (j = surveyQuestions[i].scale_minimum;
|
||||
j <= surveyQuestions[i].scale_maximum;
|
||||
j++) {
|
||||
let newRadio = document.createElement("input");
|
||||
|
@ -243,7 +246,7 @@ function drawSurveyForm(task, contentDiv) {
|
|||
let freeformId = "freeform_" + i;
|
||||
let radioName = "answer_to_" + i;
|
||||
|
||||
for (let j = 0; j < choices.length; j++) {
|
||||
for (j = 0; j < choices.length; j++) {
|
||||
let newRadio = document.createElement("input");
|
||||
newRadio.setAttribute("type", "radio");
|
||||
newRadio.setAttribute("name", radioName);
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>testpilot@labs.mozilla.com</em:id>
|
||||
<em:version>1.1.1</em:version>
|
||||
<em:version>1.1.2</em:version>
|
||||
<em:type>2</em:type>
|
||||
|
||||
<!-- Target Application this extension can install into,
|
||||
|
@ -13,7 +13,7 @@
|
|||
<Description>
|
||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||
<em:minVersion>3.5</em:minVersion>
|
||||
<em:maxVersion>5.0</em:maxVersion>
|
||||
<em:maxVersion>6.0</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
|
|
|
@ -512,15 +512,15 @@ exports.RemoteExperimentLoader.prototype = {
|
|||
remoteExperiments[filename] = this._loader.require(filename);
|
||||
this._logger.info("Loaded " + filename + " OK.");
|
||||
} catch(e) {
|
||||
/* Turn the load-time errors into strings and store them, so we can display
|
||||
* them on a debug page or include them with a data upload! (Don't store
|
||||
* exception objects directly as that causes garbage collector problems-
|
||||
* aka bug 646122) */
|
||||
let errStr = e.name + " on line " + e.lineNumber + " of file " +
|
||||
e.fileName + ": " + e.message;
|
||||
/* Turn the load-time errors into strings and store them, so we can display
|
||||
* them on a debug page or include them with a data upload! (Don't store
|
||||
* exception objects directly as that causes garbage collector problems-
|
||||
* aka bug 646122) */
|
||||
let errStr = e.name + " on line " + e.lineNumber + " of file " +
|
||||
e.fileName + ": " + e.message;
|
||||
this._loadErrors.push(errStr);
|
||||
this._logger.warn("Error loading " + filename);
|
||||
this._logger.warn(e);
|
||||
this._logger.warn(errStr);
|
||||
}
|
||||
}
|
||||
return remoteExperiments;
|
||||
|
|
|
@ -597,7 +597,7 @@ TestPilotExperiment.prototype = {
|
|||
}
|
||||
}
|
||||
} catch(e) {
|
||||
this._logger.warn("Error in getStudyMetadata: " + e);
|
||||
this._dataStore.logException("getStudyMetadata: " + e);
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
@ -660,6 +660,7 @@ TestPilotExperiment.prototype = {
|
|||
// This method handles all date-related status changes and should be
|
||||
// called periodically.
|
||||
let currentDate = this._now();
|
||||
let self = this;
|
||||
|
||||
// Reset automatically recurring tests:
|
||||
if (this._recursAutomatically &&
|
||||
|
@ -703,7 +704,6 @@ TestPilotExperiment.prototype = {
|
|||
currentDate <= this._endDate) {
|
||||
this._logger.info("Study now starting.");
|
||||
// clear the data before starting.
|
||||
let self = this;
|
||||
this._dataStore.wipeAllData(function() {
|
||||
// Experiment is now in progress.
|
||||
self.changeStatus(TaskConstants.STATUS_IN_PROGRESS, true);
|
||||
|
@ -714,7 +714,6 @@ TestPilotExperiment.prototype = {
|
|||
// What happens when a test finishes:
|
||||
if (this._status < TaskConstants.STATUS_FINISHED &&
|
||||
currentDate > this._endDate) {
|
||||
let self = this;
|
||||
let setDataDeletionDate = true;
|
||||
this._logger.info("Passed End Date - Switched Task Status to Finished");
|
||||
this.changeStatus(TaskConstants.STATUS_FINISHED);
|
||||
|
@ -896,7 +895,6 @@ TestPilotExperiment.prototype = {
|
|||
optOut: function TestPilotExperiment_optOut(reason, callback) {
|
||||
// Regardless of study ID, post the opt-out message to a special
|
||||
// database table of just opt-out messages; include study ID in metadata.
|
||||
let url = Application.prefs.getValue(DATA_UPLOAD_PREF, "") + "opt-out";
|
||||
let logger = this._logger;
|
||||
|
||||
this.onExperimentShutdown();
|
||||
|
@ -909,6 +907,7 @@ TestPilotExperiment.prototype = {
|
|||
if (reason) {
|
||||
// Send us the reason...
|
||||
// (TODO: include metadata?)
|
||||
let url = Application.prefs.getValue(DATA_UPLOAD_PREF, "") + "opt-out";
|
||||
let answer = {id: this._id,
|
||||
reason: reason};
|
||||
let dataString = JSON.stringify(answer);
|
||||
|
@ -924,17 +923,23 @@ TestPilotExperiment.prototype = {
|
|||
if (req.readyState == 4) {
|
||||
if (req.status == 200 || req.status == 201 || req.status == 202) {
|
||||
logger.info("Quit reason posted successfully " + req.responseText);
|
||||
callback(true);
|
||||
if (callback) {
|
||||
callback(true);
|
||||
}
|
||||
} else {
|
||||
logger.warn(req.status + " posting error " + req.responseText);
|
||||
callback(false);
|
||||
if (callback) {
|
||||
callback(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
logger.trace("Sending quit reason.");
|
||||
req.send(dataString);
|
||||
} else {
|
||||
callback(false);
|
||||
if (callback) {
|
||||
callback(false);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -961,6 +966,7 @@ TestPilotBuiltinSurvey.prototype = {
|
|||
this._versionNumber = surveyInfo.versionNumber;
|
||||
this._questions = surveyInfo.surveyQuestions;
|
||||
this._explanation = surveyInfo.surveyExplanation;
|
||||
this._onPageLoad = surveyInfo.onPageLoad;
|
||||
},
|
||||
|
||||
get taskType() {
|
||||
|
@ -988,6 +994,12 @@ TestPilotBuiltinSurvey.prototype = {
|
|||
return this._studyId;
|
||||
},
|
||||
|
||||
onPageLoad: function(task, document) {
|
||||
if (this._onPageLoad) {
|
||||
this._onPageLoad(task, document);
|
||||
}
|
||||
},
|
||||
|
||||
onDetailPageOpened: function TPS_onDetailPageOpened() {
|
||||
if (this._status < TaskConstants.STATUS_IN_PROGRESS) {
|
||||
this.changeStatus( TaskConstants.STATUS_IN_PROGRESS, true );
|
||||
|
@ -1204,4 +1216,4 @@ TestPilotLegacyStudy.prototype = {
|
|||
// TODO test that they don't say "thanks for contributing" if the
|
||||
// user didn't actually complete them...
|
||||
};
|
||||
TestPilotLegacyStudy.prototype.__proto__ = TestPilotTask;
|
||||
TestPilotLegacyStudy.prototype.__proto__ = TestPilotTask;
|
||||
|
|
|
@ -43,8 +43,6 @@ VPATH = @srcdir@
|
|||
include $(DEPTH)/config/autoconf.mk
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
DEFINES += -DFIREFOX_VERSION=$(FIREFOX_VERSION)
|
||||
|
||||
FILES := \
|
||||
install.rdf \
|
||||
$(NULL)
|
||||
|
|
|
@ -70,6 +70,7 @@ pref("extensions.blocklist.interval", 86400);
|
|||
pref("extensions.blocklist.level", 2);
|
||||
pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/3/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/%PING_COUNT%/%TOTAL_PING_COUNT%/%DAYS_SINCE_LAST_PING%/");
|
||||
pref("extensions.blocklist.detailsURL", "https://www.mozilla.com/%LOCALE%/blocklist/");
|
||||
pref("extensions.blocklist.itemURL", "https://addons.mozilla.org/%LOCALE%/%APP%/blocked/%blockID%");
|
||||
|
||||
pref("extensions.update.autoUpdateDefault", true);
|
||||
|
||||
|
@ -901,6 +902,17 @@ pref("dom.ipc.plugins.enabled.x86_64", true);
|
|||
pref("dom.ipc.plugins.enabled", true);
|
||||
#endif
|
||||
|
||||
// This pref governs whether we attempt to work around problems caused by
|
||||
// plugins using OS calls to manipulate the cursor while running out-of-
|
||||
// process. These workarounds all involve intercepting (hooking) certain
|
||||
// OS calls in the plugin process, then arranging to make certain OS calls
|
||||
// in the browser process. Eventually plugins will be required to use the
|
||||
// NPAPI to manipulate the cursor, and these workarounds will be removed.
|
||||
// See bug 621117.
|
||||
#ifdef XP_MACOSX
|
||||
pref("dom.ipc.plugins.nativeCursorSupport", true);
|
||||
#endif
|
||||
|
||||
#ifdef XP_WIN
|
||||
pref("browser.taskbar.previews.enable", false);
|
||||
pref("browser.taskbar.previews.max", 20);
|
||||
|
|
|
@ -72,33 +72,3 @@
|
|||
padding: 0;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#channelSelector {
|
||||
margin-top: 10px;
|
||||
}
|
||||
|
||||
#channelSelectorStart {
|
||||
-moz-margin-start: 0;
|
||||
}
|
||||
|
||||
#channelMenulist {
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.channel-description {
|
||||
margin: 10px 0;
|
||||
}
|
||||
|
||||
#detailsBox,
|
||||
#channelSelector,
|
||||
.channel-description {
|
||||
-moz-transition: opacity 250ms;
|
||||
}
|
||||
|
||||
#contentDeck:not([selectedIndex="0"]) > #detailsBox,
|
||||
#contentDeck:not([selectedIndex="1"]) > #channelSelector,
|
||||
#channelDescriptionDeck:not([selectedIndex="0"]) > #releaseDescription,
|
||||
#channelDescriptionDeck:not([selectedIndex="1"]) > #betaDescription,
|
||||
#channelDescriptionDeck:not([selectedIndex="2"]) > #auroraDescription {
|
||||
opacity: 0;
|
||||
}
|
||||
|
|
|
@ -88,7 +88,9 @@ function init(aEvent)
|
|||
gAppUpdater = new appUpdater();
|
||||
#endif
|
||||
|
||||
gChannelSelector.init();
|
||||
let defaults = Services.prefs.getDefaultBranch("");
|
||||
let channelLabel = document.getElementById("currentChannel");
|
||||
channelLabel.value = defaults.getCharPref("app.update.channel");
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
// it may not be sized at this point, and we need its width to calculate its position
|
||||
|
@ -573,72 +575,3 @@ appUpdater.prototype =
|
|||
}
|
||||
};
|
||||
#endif
|
||||
|
||||
var gChannelSelector = {
|
||||
validChannels: { release: 1, beta: 1, aurora: 1 },
|
||||
|
||||
init: function() {
|
||||
try {
|
||||
this.channelValue = Services.prefs.getCharPref("app.update.desiredChannel");
|
||||
} catch (e) {
|
||||
let defaults = Services.prefs.getDefaultBranch("");
|
||||
this.channelValue = defaults.getCharPref("app.update.channel");
|
||||
}
|
||||
|
||||
// Only show channel selector UI on valid update channels.
|
||||
if (this.channelValue in this.validChannels) {
|
||||
document.getElementById("currentChannelText").hidden = false;
|
||||
this.setChannelLabel(this.channelValue);
|
||||
this.setChannelMenuitem(this.channelValue);
|
||||
}
|
||||
},
|
||||
|
||||
selectChannel: function(aSelectedItem) {
|
||||
document.getElementById("channelDescriptionDeck").selectedPanel =
|
||||
document.getElementById(aSelectedItem.value + "Description");
|
||||
document.getElementById("channelMenulist").setAttribute("aria-describedby",
|
||||
aSelectedItem.value + "Description");
|
||||
},
|
||||
|
||||
cancel: function() {
|
||||
this.setChannelMenuitem(this.channelValue);
|
||||
this.hide();
|
||||
},
|
||||
|
||||
apply: function() {
|
||||
this.channelValue = document.getElementById("channelMenulist").selectedItem.value;
|
||||
this.setChannelLabel(this.channelValue);
|
||||
|
||||
// Change app update channel.
|
||||
Services.prefs.setCharPref("app.update.desiredChannel", this.channelValue);
|
||||
|
||||
// Stop any downloads in progress
|
||||
gAppUpdater.aus.pauseDownload();
|
||||
// App updater will look at app.update.desiredChannel for new channel value
|
||||
// and will clear it when the update is complete.
|
||||
gAppUpdater.isChecking = true;
|
||||
gAppUpdater.checker.checkForUpdates(gAppUpdater.updateCheckListener, true);
|
||||
|
||||
this.hide();
|
||||
},
|
||||
|
||||
show: function() {
|
||||
document.getElementById("contentDeck").selectedPanel =
|
||||
document.getElementById("channelSelector");
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
document.getElementById("contentDeck").selectedPanel =
|
||||
document.getElementById("detailsBox");
|
||||
},
|
||||
|
||||
setChannelLabel: function(aValue) {
|
||||
let channelLabel = document.getElementById("currentChannel");
|
||||
channelLabel.value = document.getElementById(aValue + "Menuitem").label;
|
||||
},
|
||||
|
||||
setChannelMenuitem: function(aValue) {
|
||||
document.getElementById("channelMenulist").selectedItem =
|
||||
document.getElementById(aValue + "Menuitem");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,85 +80,50 @@
|
|||
<label id="distribution" class="text-blurb"/>
|
||||
<label id="distributionId" class="text-blurb"/>
|
||||
|
||||
<!-- Make sure the selectedIndex attribute is always set so that the CSS
|
||||
selectors for transitions work -->
|
||||
<deck id="contentDeck" selectedIndex="0">
|
||||
<vbox id="detailsBox" aria-describedby="communityDesc contributeDesc">
|
||||
<vbox id="updateBox">
|
||||
<vbox id="detailsBox" aria-describedby="communityDesc contributeDesc">
|
||||
<vbox id="updateBox">
|
||||
#ifdef MOZ_UPDATER
|
||||
<deck id="updateDeck" orient="vertical">
|
||||
<hbox id="updateButtonBox" align="center">
|
||||
<button id="updateButton" align="start"
|
||||
oncommand="gAppUpdater.buttonOnCommand();"/>
|
||||
<spacer flex="1"/>
|
||||
</hbox>
|
||||
<hbox id="checkingForUpdates" align="center">
|
||||
<image class="update-throbber"/><label>&update.checkingForUpdates;</label>
|
||||
</hbox>
|
||||
<hbox id="checkingAddonCompat" align="center">
|
||||
<image class="update-throbber"/><label>&update.checkingAddonCompat;</label>
|
||||
</hbox>
|
||||
<hbox id="downloading" align="center">
|
||||
<image class="update-throbber"/><label>&update.downloading.start;</label><label id="downloadStatus"/><label>&update.downloading.end;</label>
|
||||
</hbox>
|
||||
<hbox id="downloadFailed" align="center">
|
||||
<label>&update.failed.start;</label><label id="failedLink" class="text-link">&update.failed.linkText;</label><label>&update.failed.end;</label>
|
||||
</hbox>
|
||||
<hbox id="adminDisabled" align="center">
|
||||
<label>&update.adminDisabled;</label>
|
||||
</hbox>
|
||||
<hbox id="noUpdatesFound" align="center">
|
||||
<label>&update.noUpdatesFound;</label>
|
||||
</hbox>
|
||||
<hbox id="manualUpdate" align="center">
|
||||
<label>&update.manual.start;</label><label id="manualLink" class="text-link"/><label>&update.manual.end;</label>
|
||||
</hbox>
|
||||
</deck>
|
||||
#endif
|
||||
</vbox>
|
||||
|
||||
<description class="text-blurb" id="currentChannelText" hidden="true">
|
||||
&channel.description.start;<label id="currentChannel"/>&channel.description.end;<label id="channelChangeLink" class="text-link" onclick="gChannelSelector.show();">&channel.change;</label>
|
||||
</description>
|
||||
<description class="text-blurb" id="communityDesc">
|
||||
&community.start2;<label class="text-link" href="http://www.mozilla.org/">&community.mozillaLink;</label>&community.middle2;<label class="text-link" href="about:credits">&community.creditsLink;</label>&community.end2;
|
||||
</description>
|
||||
<description class="text-blurb" id="contributeDesc">
|
||||
&contribute.start;<label class="text-link" href="http://www.mozilla.org/contribute/">&contribute.getInvolvedLink;</label>&contribute.end;
|
||||
</description>
|
||||
</vbox>
|
||||
|
||||
<vbox id="channelSelector">
|
||||
<hbox pack="start" align="center">
|
||||
<label id="channelSelectorStart">&channel.selector.start;</label>
|
||||
<menulist id="channelMenulist" onselect="gChannelSelector.selectChannel(this.selectedItem);" aria-labelledby="channelSelectorStart channelMenulist channelSelectorEnd">
|
||||
<menupopup>
|
||||
<menuitem id="releaseMenuitem" label="Release" value="release"/>
|
||||
<menuitem id="betaMenuitem" label="Beta" value="beta"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="auroraMenuitem" label="Aurora" value="aurora"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<label id="channelSelectorEnd">&channel.selector.end;</label>
|
||||
</hbox>
|
||||
|
||||
<deck id="channelDescriptionDeck" selectedIndex="0">
|
||||
<description id="releaseDescription" class="channel-description">&channel.release.description;</description>
|
||||
<description id="betaDescription" class="channel-description">&channel.beta.description;</description>
|
||||
<description id="auroraDescription" class="channel-description">&channel.aurora.description;</description>
|
||||
<deck id="updateDeck" orient="vertical">
|
||||
<hbox id="updateButtonBox" align="center">
|
||||
<button id="updateButton" align="start"
|
||||
oncommand="gAppUpdater.buttonOnCommand();"/>
|
||||
<spacer flex="1"/>
|
||||
</hbox>
|
||||
<hbox id="checkingForUpdates" align="center">
|
||||
<image class="update-throbber"/><label>&update.checkingForUpdates;</label>
|
||||
</hbox>
|
||||
<hbox id="checkingAddonCompat" align="center">
|
||||
<image class="update-throbber"/><label>&update.checkingAddonCompat;</label>
|
||||
</hbox>
|
||||
<hbox id="downloading" align="center">
|
||||
<image class="update-throbber"/><label>&update.downloading.start;</label><label id="downloadStatus"/><label>&update.downloading.end;</label>
|
||||
</hbox>
|
||||
<hbox id="downloadFailed" align="center">
|
||||
<label>&update.failed.start;</label><label id="failedLink" class="text-link">&update.failed.linkText;</label><label>&update.failed.end;</label>
|
||||
</hbox>
|
||||
<hbox id="adminDisabled" align="center">
|
||||
<label>&update.adminDisabled;</label>
|
||||
</hbox>
|
||||
<hbox id="noUpdatesFound" align="center">
|
||||
<label>&update.noUpdatesFound;</label>
|
||||
</hbox>
|
||||
<hbox id="manualUpdate" align="center">
|
||||
<label>&update.manual.start;</label><label id="manualLink" class="text-link"/><label>&update.manual.end;</label>
|
||||
</hbox>
|
||||
</deck>
|
||||
|
||||
<hbox id="channelSelectorButtons" pack="end">
|
||||
#ifdef XP_UNIX
|
||||
<button oncommand="gChannelSelector.cancel();" label="&channel.selector.cancelButton;"/>
|
||||
<button oncommand="gChannelSelector.apply();" label="&channel.selector.applyButton;"/>
|
||||
#else
|
||||
<button oncommand="gChannelSelector.apply();" label="&channel.selector.applyButton;"/>
|
||||
<button oncommand="gChannelSelector.cancel();" label="&channel.selector.cancelButton;"/>
|
||||
#endif
|
||||
</hbox>
|
||||
</vbox>
|
||||
</deck>
|
||||
|
||||
<description class="text-blurb" id="currentChannelText">
|
||||
&channel.description.start;<label id="currentChannel"/>&channel.description.end;
|
||||
</description>
|
||||
<description class="text-blurb" id="communityDesc">
|
||||
&community.start2;<label class="text-link" href="http://www.mozilla.org/">&community.mozillaLink;</label>&community.middle2;<label class="text-link" href="about:credits">&community.creditsLink;</label>&community.end2;
|
||||
</description>
|
||||
<description class="text-blurb" id="contributeDesc">
|
||||
&contribute.start;<label class="text-link" href="http://www.mozilla.org/contribute/">&contribute.getInvolvedLink;</label>&contribute.end;
|
||||
</description>
|
||||
</vbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
<vbox id="bottomBox">
|
||||
|
|
|
@ -201,6 +201,10 @@
|
|||
label="&errorConsoleCmd.label;"
|
||||
key="key_errorConsole"
|
||||
oncommand="toJavaScriptConsole();"/>
|
||||
<menuseparator id="appmenu_devToolsEndSeparator"/>
|
||||
<menuitem id="appmenu_getMoreDevtools"
|
||||
label="&getMoreDevtoolsCmd.label;"
|
||||
oncommand="openUILinkIn('https://addons.mozilla.org/firefox/collections/mozilla/webdeveloper/', 'tab');"/>
|
||||
<menuseparator/>
|
||||
#define ID_PREFIX appmenu_developer_
|
||||
#define OMIT_ACCESSKEYS
|
||||
|
|
|
@ -567,6 +567,11 @@
|
|||
accesskey="&errorConsoleCmd.accesskey;"
|
||||
key="key_errorConsole"
|
||||
oncommand="toJavaScriptConsole();"/>
|
||||
<menuseparator id="devToolsEndSeparator"/>
|
||||
<menuitem id="getMoreDevtools"
|
||||
label="&getMoreDevtoolsCmd.label;"
|
||||
accesskey="&getMoreDevtoolsCmd.accesskey;"
|
||||
oncommand="openUILinkIn('https://addons.mozilla.org/firefox/collections/mozilla/webdeveloper/', 'tab');"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
<menuitem id="menu_pageInfo"
|
||||
|
|
|
@ -328,7 +328,7 @@ let gSyncUI = {
|
|||
// Show the day-of-week and time (HH:MM) of last sync
|
||||
let lastSyncDate = new Date(lastSync).toLocaleFormat("%a %H:%M");
|
||||
let lastSyncLabel =
|
||||
this._stringBundle.formatStringFromName("lastSync.label", [lastSyncDate], 1);
|
||||
this._stringBundle.formatStringFromName("lastSync2.label", [lastSyncDate], 1);
|
||||
|
||||
syncButton.setAttribute("tooltiptext", lastSyncLabel);
|
||||
},
|
||||
|
|
|
@ -48,6 +48,7 @@ let TabView = {
|
|||
PREF_STARTUP_PAGE: "browser.startup.page",
|
||||
PREF_RESTORE_ENABLED_ONCE: "browser.panorama.session_restore_enabled_once",
|
||||
VISIBILITY_IDENTIFIER: "tabview-visibility",
|
||||
GROUPS_IDENTIFIER: "tabview-groups",
|
||||
|
||||
// ----------
|
||||
get windowTitle() {
|
||||
|
@ -95,14 +96,21 @@ let TabView = {
|
|||
// ___ visibility
|
||||
let sessionstore =
|
||||
Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||
let data = sessionstore.getWindowValue(window, this.VISIBILITY_IDENTIFIER);
|
||||
|
||||
let data = sessionstore.getWindowValue(window, this.VISIBILITY_IDENTIFIER);
|
||||
if (data && data == "true") {
|
||||
this.show();
|
||||
} else {
|
||||
let self = this;
|
||||
try {
|
||||
data = sessionstore.getWindowValue(window, this.GROUPS_IDENTIFIER);
|
||||
if (data) {
|
||||
let parsedData = JSON.parse(data);
|
||||
this.updateGroupNumberBroadcaster(parsedData.totalNumber || 0);
|
||||
}
|
||||
} catch (e) { }
|
||||
|
||||
// if a tab is changed from hidden to unhidden and the iframe is not
|
||||
let self = this;
|
||||
// if a tab is changed from hidden to unhidden and the iframe is not
|
||||
// initialized, load the iframe and setup the tab.
|
||||
this._tabShowEventListener = function (event) {
|
||||
if (!self._window)
|
||||
|
@ -380,6 +388,14 @@ let TabView = {
|
|||
document.persist(toolbar.id, "currentset");
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: updateGroupNumberBroadcaster
|
||||
// Updates the group number broadcaster.
|
||||
updateGroupNumberBroadcaster: function TabView_updateGroupNumberBroadcaster(number) {
|
||||
let groupsNumber = document.getElementById("tabviewGroupsNumber");
|
||||
groupsNumber.setAttribute("groups", number);
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: enableSessionRestore
|
||||
// Enables automatic session restore when the browser is started. Does
|
||||
|
|
|
@ -496,3 +496,7 @@ statuspanel[label=""] {
|
|||
width: 100%;
|
||||
-moz-box-align: end;
|
||||
}
|
||||
|
||||
.panel-inner-arrowcontentfooter[footertype="promobox"] {
|
||||
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#promobox");
|
||||
}
|
||||
|
|
|
@ -261,10 +261,10 @@ function UpdateBackForwardCommands(aWebNavigation) {
|
|||
function SetClickAndHoldHandlers() {
|
||||
var timer;
|
||||
|
||||
function timerCallback(aButton) {
|
||||
function openMenu(aButton) {
|
||||
cancelHold(aButton);
|
||||
aButton.firstChild.hidden = false;
|
||||
aButton.open = true;
|
||||
timer = null;
|
||||
}
|
||||
|
||||
function mousedownHandler(aEvent) {
|
||||
|
@ -276,7 +276,29 @@ function SetClickAndHoldHandlers() {
|
|||
// Prevent the menupopup from opening immediately
|
||||
aEvent.currentTarget.firstChild.hidden = true;
|
||||
|
||||
timer = setTimeout(timerCallback, 500, aEvent.currentTarget);
|
||||
aEvent.currentTarget.addEventListener("mouseout", mouseoutHandler, false);
|
||||
aEvent.currentTarget.addEventListener("mouseup", mouseupHandler, false);
|
||||
timer = setTimeout(openMenu, 500, aEvent.currentTarget);
|
||||
}
|
||||
|
||||
function mouseoutHandler(aEvent) {
|
||||
let buttonRect = aEvent.currentTarget.getBoundingClientRect();
|
||||
if (aEvent.clientX >= buttonRect.left &&
|
||||
aEvent.clientX <= buttonRect.right &&
|
||||
aEvent.clientY >= buttonRect.bottom)
|
||||
openMenu(aEvent.currentTarget);
|
||||
else
|
||||
cancelHold(aEvent.currentTarget);
|
||||
}
|
||||
|
||||
function mouseupHandler(aEvent) {
|
||||
cancelHold(aEvent.currentTarget);
|
||||
}
|
||||
|
||||
function cancelHold(aButton) {
|
||||
clearTimeout(timer);
|
||||
aButton.removeEventListener("mouseout", mouseoutHandler, false);
|
||||
aButton.removeEventListener("mouseup", mouseupHandler, false);
|
||||
}
|
||||
|
||||
function clickHandler(aEvent) {
|
||||
|
@ -292,17 +314,8 @@ function SetClickAndHoldHandlers() {
|
|||
}
|
||||
}
|
||||
|
||||
function stopTimer(aEvent) {
|
||||
if (timer) {
|
||||
clearTimeout(timer);
|
||||
timer = null;
|
||||
}
|
||||
}
|
||||
|
||||
function _addClickAndHoldListenersOnElement(aElm) {
|
||||
aElm.addEventListener("mousedown", mousedownHandler, true);
|
||||
aElm.addEventListener("mouseup", stopTimer, false);
|
||||
aElm.addEventListener("mouseout", stopTimer, false);
|
||||
aElm.addEventListener("click", clickHandler, true);
|
||||
}
|
||||
|
||||
|
@ -2244,7 +2257,11 @@ function loadURI(uri, referrer, postData, allowThirdPartyFixup)
|
|||
}
|
||||
}
|
||||
|
||||
function getShortcutOrURI(aURL, aPostDataRef) {
|
||||
function getShortcutOrURI(aURL, aPostDataRef, aMayInheritPrincipal) {
|
||||
// Initialize outparam to false
|
||||
if (aMayInheritPrincipal)
|
||||
aMayInheritPrincipal.value = false;
|
||||
|
||||
var shortcutURL = null;
|
||||
var keyword = aURL;
|
||||
var param = "";
|
||||
|
@ -2316,6 +2333,11 @@ function getShortcutOrURI(aURL, aPostDataRef) {
|
|||
return aURL;
|
||||
}
|
||||
|
||||
// This URL came from a bookmark, so it's safe to let it inherit the current
|
||||
// document's principal.
|
||||
if (aMayInheritPrincipal)
|
||||
aMayInheritPrincipal.value = true;
|
||||
|
||||
return shortcutURL;
|
||||
}
|
||||
|
||||
|
@ -2860,7 +2882,7 @@ var PrintPreviewListener = {
|
|||
this._printPreviewTab = null;
|
||||
},
|
||||
_toggleAffectedChrome: function () {
|
||||
gNavToolbox.hidden = gInPrintPreviewMode;
|
||||
gNavToolbox.collapsed = gInPrintPreviewMode;
|
||||
|
||||
if (gInPrintPreviewMode)
|
||||
this._hideChrome();
|
||||
|
@ -2951,11 +2973,7 @@ function FillInHTMLTooltip(tipElement)
|
|||
var titleText = null;
|
||||
var XLinkTitleText = null;
|
||||
var SVGTitleText = null;
|
||||
#ifdef MOZ_SVG
|
||||
var lookingForSVGTitle = true;
|
||||
#else
|
||||
var lookingForSVGTitle = false;
|
||||
#endif // MOZ_SVG
|
||||
var direction = tipElement.ownerDocument.dir;
|
||||
|
||||
// If the element is invalid per HTML5 Forms specifications and has no title,
|
||||
|
@ -2976,11 +2994,8 @@ function FillInHTMLTooltip(tipElement)
|
|||
titleText = tipElement.getAttribute("title");
|
||||
if ((tipElement instanceof HTMLAnchorElement && tipElement.href) ||
|
||||
(tipElement instanceof HTMLAreaElement && tipElement.href) ||
|
||||
(tipElement instanceof HTMLLinkElement && tipElement.href)
|
||||
#ifdef MOZ_SVG
|
||||
|| (tipElement instanceof SVGAElement && tipElement.hasAttributeNS(XLinkNS, "href"))
|
||||
#endif // MOZ_SVG
|
||||
) {
|
||||
(tipElement instanceof HTMLLinkElement && tipElement.href) ||
|
||||
(tipElement instanceof SVGAElement && tipElement.hasAttributeNS(XLinkNS, "href"))) {
|
||||
XLinkTitleText = tipElement.getAttributeNS(XLinkNS, "title");
|
||||
}
|
||||
if (lookingForSVGTitle &&
|
||||
|
@ -3333,7 +3348,7 @@ const BrowserSearch = {
|
|||
var win = getTopWin();
|
||||
if (win) {
|
||||
// If there's an open browser window, it should handle this command
|
||||
win.focus()
|
||||
win.focus();
|
||||
win.BrowserSearch.webSearch();
|
||||
} else {
|
||||
// If there are no open browser windows, open a new one
|
||||
|
@ -3343,7 +3358,7 @@ const BrowserSearch = {
|
|||
Services.obs.removeObserver(observer, "browser-delayed-startup-finished");
|
||||
}
|
||||
}
|
||||
win = window.openDialog("chrome://browser/content/", "_blank",
|
||||
win = window.openDialog(getBrowserURL(), "_blank",
|
||||
"chrome,all,dialog=no", "about:blank");
|
||||
Services.obs.addObserver(observer, "browser-delayed-startup-finished", false);
|
||||
}
|
||||
|
@ -7673,12 +7688,6 @@ var gIdentityHandler = {
|
|||
icon_label = this.getEffectiveHost();
|
||||
}
|
||||
|
||||
// We need a port number for all lookups. If one hasn't been specified, use
|
||||
// the https default
|
||||
var lookupHost = this._lastLocation.host;
|
||||
if (lookupHost.indexOf(':') < 0)
|
||||
lookupHost += ":443";
|
||||
|
||||
// Verifier is either the CA Org, for a normal cert, or a special string
|
||||
// for certs that are trusted because of a security exception.
|
||||
var tooltip = gNavigatorBundle.getFormattedString("identity.identified.verifier",
|
||||
|
@ -7688,7 +7697,12 @@ var gIdentityHandler = {
|
|||
// thing here in terms of converting _lastLocation.port from string to int, but
|
||||
// the overrideService doesn't like undefined ports, so make sure we have
|
||||
// something in the default case (bug 432241).
|
||||
if (this._overrideService.hasMatchingOverride(this._lastLocation.hostname,
|
||||
// .hostname can return an empty string in some exceptional cases -
|
||||
// hasMatchingOverride does not handle that, so avoid calling it.
|
||||
// Updating the tooltip value in those cases isn't critical.
|
||||
// FIXME: Fixing bug 646690 would probably makes this check unnecessary
|
||||
if (this._lastLocation.hostname &&
|
||||
this._overrideService.hasMatchingOverride(this._lastLocation.hostname,
|
||||
(this._lastLocation.port || 443),
|
||||
iData.cert, {}, {}))
|
||||
tooltip = gNavigatorBundle.getString("identity.identified.verified_by_you");
|
||||
|
|
|
@ -177,6 +177,7 @@
|
|||
|
||||
<panel id="editBookmarkPanel"
|
||||
type="arrow"
|
||||
footertype="promobox"
|
||||
orient="vertical"
|
||||
ignorekeys="true"
|
||||
hidden="true"
|
||||
|
@ -337,8 +338,13 @@
|
|||
|
||||
<menupopup id="placesContext"/>
|
||||
|
||||
<panel id="notification-popup" type="arrow" position="after_start"
|
||||
hidden="true" orient="vertical"/>
|
||||
<panel id="notification-popup"
|
||||
type="arrow"
|
||||
footertype="promobox"
|
||||
position="after_start"
|
||||
hidden="true"
|
||||
orient="vertical"
|
||||
role="alert"/>
|
||||
|
||||
<!-- Popup for site identity information -->
|
||||
<panel id="identity-popup"
|
||||
|
|
|
@ -626,7 +626,6 @@ function grabAll(elem)
|
|||
if (elem instanceof HTMLImageElement)
|
||||
addImage(elem.src, gStrings.mediaImg,
|
||||
(elem.hasAttribute("alt")) ? elem.alt : gStrings.notSet, elem, false);
|
||||
#ifdef MOZ_SVG
|
||||
else if (elem instanceof SVGImageElement) {
|
||||
try {
|
||||
// Note: makeURLAbsolute will throw if either the baseURI is not a valid URI
|
||||
|
@ -635,7 +634,6 @@ function grabAll(elem)
|
|||
addImage(href, gStrings.mediaImg, "", elem, false);
|
||||
} catch (e) { }
|
||||
}
|
||||
#endif
|
||||
#ifdef MOZ_MEDIA
|
||||
else if (elem instanceof HTMLVideoElement) {
|
||||
addImage(elem.currentSrc, gStrings.mediaVideo, "", elem, false);
|
||||
|
@ -841,9 +839,7 @@ function makePreview(row)
|
|||
|
||||
var imageText;
|
||||
if (!isBG &&
|
||||
#ifdef MOZ_SVG
|
||||
!(item instanceof SVGImageElement) &&
|
||||
#endif
|
||||
!(gDocument instanceof ImageDocument)) {
|
||||
imageText = item.title || item.alt;
|
||||
|
||||
|
@ -941,9 +937,7 @@ function makePreview(row)
|
|||
|
||||
if ((item instanceof HTMLLinkElement || item instanceof HTMLInputElement ||
|
||||
item instanceof HTMLImageElement ||
|
||||
#ifdef MOZ_SVG
|
||||
item instanceof SVGImageElement ||
|
||||
#endif
|
||||
(item instanceof HTMLObjectElement && /^image\//.test(mimeType)) || isBG) && isProtocolAllowed) {
|
||||
newImage.setAttribute("src", url);
|
||||
physWidth = newImage.width || 0;
|
||||
|
@ -963,12 +957,10 @@ function makePreview(row)
|
|||
newImage.height = newImage.naturalHeight;
|
||||
}
|
||||
|
||||
#ifdef MOZ_SVG
|
||||
if (item instanceof SVGImageElement) {
|
||||
newImage.width = item.width.baseVal.value;
|
||||
newImage.height = item.height.baseVal.value;
|
||||
}
|
||||
#endif
|
||||
|
||||
width = newImage.width;
|
||||
height = newImage.height;
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
id="wizard"
|
||||
title="&addDevice.title.label;"
|
||||
windowtype="Sync:AddDevice"
|
||||
persist="screenX screenY"
|
||||
onwizardnext="return gSyncAddDevice.onWizardAdvance();"
|
||||
onwizardback="return gSyncAddDevice.onWizardBack();"
|
||||
onwizardcancel="gSyncAddDevice.onWizardCancel();"
|
||||
|
|
|
@ -55,6 +55,7 @@
|
|||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
id="change-dialog"
|
||||
windowtype="Weave:ChangeSomething"
|
||||
persist="screenX screenY"
|
||||
onwizardnext="Change.onLoad()"
|
||||
onwizardfinish="return Change.onDialogAccept();">
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@
|
|||
<head>
|
||||
<title>&syncKey.page.title;</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
|
||||
<meta name="robots" content="noindex"/>
|
||||
<style type="text/css">
|
||||
#synckey { font-size: 150% }
|
||||
footer { font-size: 70% }
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
]>
|
||||
<dialog id="quotaDialog"
|
||||
windowtype="Sync:ViewQuota"
|
||||
persist="screenX screenY width height"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
onload="gSyncQuota.init()"
|
||||
|
|
|
@ -64,6 +64,7 @@ const RECAPTCHA_DOMAIN = "https://www.google.com";
|
|||
Cu.import("resource://services-sync/main.js");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/PlacesUtils.jsm");
|
||||
Cu.import("resource://gre/modules/PluralForm.jsm");
|
||||
|
||||
var gSyncSetup = {
|
||||
|
@ -822,7 +823,9 @@ var gSyncSetup = {
|
|||
if (this._case1Setup)
|
||||
break;
|
||||
|
||||
let places_db = Weave.Svc.History.DBConnection;
|
||||
let places_db = PlacesUtils.history
|
||||
.QueryInterface(Ci.nsPIPlacesDatabase)
|
||||
.DBConnection;
|
||||
if (Weave.Engines.get("history").enabled) {
|
||||
let daysOfHistory = 0;
|
||||
let stm = places_db.createStatement(
|
||||
|
@ -853,7 +856,7 @@ var gSyncSetup = {
|
|||
"FROM moz_bookmarks b " +
|
||||
"LEFT JOIN moz_bookmarks t ON " +
|
||||
"b.parent = t.id WHERE b.type = 1 AND t.parent <> :tag");
|
||||
stm.params.tag = Weave.Svc.Bookmark.tagsFolder;
|
||||
stm.params.tag = PlacesUtils.tagsFolderId;
|
||||
if (stm.executeStep())
|
||||
bookmarks = stm.row.bookmarks;
|
||||
// Support %S for historical reasons (see bug 600141)
|
||||
|
@ -867,7 +870,7 @@ var gSyncSetup = {
|
|||
}
|
||||
|
||||
if (Weave.Engines.get("passwords").enabled) {
|
||||
let logins = Weave.Svc.Login.getAllLogins({});
|
||||
let logins = Services.logins.getAllLogins({});
|
||||
// Support %S for historical reasons (see bug 600141)
|
||||
document.getElementById("passwordCount").value =
|
||||
PluralForm.get(logins.length,
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
]>
|
||||
<wizard id="accountSetup" title="&accountSetupTitle.label;"
|
||||
windowtype="Weave:AccountSetup"
|
||||
persist="screenX screenY"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
onwizardnext="return gSyncSetup.onWizardAdvance()"
|
||||
|
|
|
@ -55,8 +55,8 @@ let gSyncUtils = {
|
|||
else if (thisDocEl.id == "BrowserPreferences" && !thisDocEl.instantApply)
|
||||
openUILinkIn(url, "window");
|
||||
else if (document.documentElement.id == "change-dialog")
|
||||
Weave.Svc.WinMediator.getMostRecentWindow("navigator:browser")
|
||||
.openUILinkIn(url, "tab");
|
||||
Services.wm.getMostRecentWindow("navigator:browser")
|
||||
.openUILinkIn(url, "tab");
|
||||
else
|
||||
openUILinkIn(url, "tab");
|
||||
},
|
||||
|
@ -69,7 +69,7 @@ let gSyncUtils = {
|
|||
|
||||
openChange: function openChange(type, duringSetup) {
|
||||
// Just re-show the dialog if it's already open
|
||||
let openedDialog = Weave.Svc.WinMediator.getMostRecentWindow("Sync:" + type);
|
||||
let openedDialog = Services.wm.getMostRecentWindow("Sync:" + type);
|
||||
if (openedDialog != null) {
|
||||
openedDialog.focus();
|
||||
return;
|
||||
|
@ -78,8 +78,8 @@ let gSyncUtils = {
|
|||
// Open up the change dialog
|
||||
let changeXUL = "chrome://browser/content/syncGenericChange.xul";
|
||||
let changeOpt = "centerscreen,chrome,resizable=no";
|
||||
Weave.Svc.WinWatcher.activeWindow.openDialog(changeXUL, "", changeOpt,
|
||||
type, duringSetup);
|
||||
Services.ww.activeWindow.openDialog(changeXUL, "", changeOpt,
|
||||
type, duringSetup);
|
||||
},
|
||||
|
||||
changePassword: function () {
|
||||
|
|
|
@ -95,7 +95,7 @@
|
|||
<property name="visibleTabs" readonly="true">
|
||||
<getter><![CDATA[
|
||||
return Array.filter(this.tabs, function(tab) {
|
||||
return !tab.hidden && this._removingTabs.indexOf(tab) == -1;
|
||||
return !tab.hidden && !tab.closing;
|
||||
}, this);
|
||||
]]></getter>
|
||||
</property>
|
||||
|
@ -208,7 +208,7 @@
|
|||
//
|
||||
// Fixing bug 630826 could make that happen automatically.
|
||||
// Fixing bug 630830 could avoid the ugly hack below.
|
||||
|
||||
|
||||
let closeMenuItem = document.getElementById("menu_close");
|
||||
let parentPopup = closeMenuItem.parentNode;
|
||||
let nextItem = closeMenuItem.nextSibling;
|
||||
|
@ -963,6 +963,10 @@
|
|||
// if the tab is a blank one.
|
||||
oldBrowser._urlbarFocused = (gURLBar && gURLBar.focused);
|
||||
if (newBrowser._urlbarFocused && gURLBar) {
|
||||
|
||||
// Explicitly close the popup if the URL bar retains focus
|
||||
gURLBar.closePopup();
|
||||
|
||||
if (!window.fullScreen) {
|
||||
gURLBar.focus();
|
||||
break;
|
||||
|
@ -999,7 +1003,7 @@
|
|||
<method name="_tabAttrModified">
|
||||
<parameter name="aTab"/>
|
||||
<body><![CDATA[
|
||||
if (this._removingTabs.indexOf(aTab) > -1)
|
||||
if (aTab.closing)
|
||||
return;
|
||||
|
||||
// This event should be dispatched when any of these attributes change:
|
||||
|
@ -1330,9 +1334,9 @@
|
|||
flags |= Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL;
|
||||
try {
|
||||
b.loadURIWithFlags(aURI, flags, aReferrerURI, aCharset, aPostData);
|
||||
|
||||
} catch (ex) {
|
||||
Cu.reportError(ex);
|
||||
}
|
||||
catch (ex) { }
|
||||
}
|
||||
|
||||
// We start our browsers out as inactive, and then maintain
|
||||
|
@ -1455,7 +1459,7 @@
|
|||
// Handle requests for synchronously removing an already
|
||||
// asynchronously closing tab.
|
||||
if (!animate &&
|
||||
this._removingTabs.indexOf(aTab) > -1) {
|
||||
aTab.closing) {
|
||||
this._endRemoveTab(aTab);
|
||||
return;
|
||||
}
|
||||
|
@ -1509,7 +1513,7 @@
|
|||
<parameter name="aCloseWindowFastpath"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
if (this._removingTabs.indexOf(aTab) > -1 || this._windowIsClosing)
|
||||
if (aTab.closing || this._windowIsClosing)
|
||||
return false;
|
||||
|
||||
var browser = this.getBrowserForTab(aTab);
|
||||
|
@ -1539,6 +1543,7 @@
|
|||
newTab = true;
|
||||
}
|
||||
|
||||
aTab.closing = true;
|
||||
this._removingTabs.push(aTab);
|
||||
if (newTab)
|
||||
this.addTab("about:blank", {skipAnimation: true});
|
||||
|
@ -1707,7 +1712,7 @@
|
|||
|
||||
if (aTab.owner &&
|
||||
!aTab.owner.hidden &&
|
||||
this._removingTabs.indexOf(aTab.owner) == -1 &&
|
||||
!aTab.owner.closing &&
|
||||
Services.prefs.getBoolPref("browser.tabs.selectOwnerOnClose")) {
|
||||
this.selectedTab = aTab.owner;
|
||||
return;
|
||||
|
@ -1718,7 +1723,7 @@
|
|||
let numTabs = remainingTabs.length;
|
||||
if (numTabs == 0 || numTabs == 1 && remainingTabs[0] == aTab) {
|
||||
remainingTabs = Array.filter(this.tabs, function(tab) {
|
||||
return this._removingTabs.indexOf(tab) == -1;
|
||||
return !tab.closing;
|
||||
}, this);
|
||||
}
|
||||
|
||||
|
@ -1933,7 +1938,7 @@
|
|||
<body>
|
||||
<![CDATA[
|
||||
if (!aTab.hidden && !aTab.pinned && !aTab.selected &&
|
||||
this._removingTabs.indexOf(aTab) == -1) {
|
||||
!aTab.closing) {
|
||||
aTab.setAttribute("hidden", "true");
|
||||
this.tabContainer.adjustTabstrip();
|
||||
let event = document.createEvent("Events");
|
||||
|
@ -2948,8 +2953,7 @@
|
|||
<body><![CDATA[
|
||||
var numPinned = this.tabbrowser._numPinnedTabs;
|
||||
var doPosition = this.getAttribute("overflow") == "true" &&
|
||||
numPinned > 0 &&
|
||||
numPinned < this.tabbrowser.visibleTabs.length;
|
||||
numPinned > 0;
|
||||
|
||||
if (doPosition) {
|
||||
this.setAttribute("positionpinnedtabs", "true");
|
||||
|
@ -3077,7 +3081,7 @@
|
|||
var tab = this._getDragTargetTab(event);
|
||||
if (window.getComputedStyle(this, null).direction == "ltr") {
|
||||
for (let i = tab ? tab._tPos : 0; i < tabs.length; i++)
|
||||
if (event.screenX < tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2)
|
||||
if (event.screenX < tabs[i].boxObject.screenX + tabs[i].boxObject.width / 2)
|
||||
return i;
|
||||
} else {
|
||||
for (let i = tab ? tab._tPos : 0; i < tabs.length; i++)
|
||||
|
@ -3171,7 +3175,7 @@
|
|||
<parameter name="aTab"/>
|
||||
<body>
|
||||
<![CDATA[
|
||||
return this.tabbrowser._removingTabs.indexOf(aTab) == -1;
|
||||
return !aTab.closing;
|
||||
]]>
|
||||
</body>
|
||||
</method>
|
||||
|
@ -3194,7 +3198,7 @@
|
|||
|
||||
if (tab.getAttribute("fadein") == "true")
|
||||
this._handleNewTab(tab);
|
||||
else if (this.tabbrowser._removingTabs.indexOf(tab) > -1)
|
||||
else if (tab.closing)
|
||||
this.tabbrowser._endRemoveTab(tab);
|
||||
]]></handler>
|
||||
|
||||
|
@ -3337,7 +3341,7 @@
|
|||
var scrollRect = tabStrip.scrollClientRect;
|
||||
var rect = this.getBoundingClientRect();
|
||||
var minMargin = scrollRect.left - rect.left;
|
||||
var maxMargin = Math.min(minMargin + scrollRect.width,
|
||||
var maxMargin = Math.min(minMargin + scrollRect.width,
|
||||
scrollRect.right);
|
||||
if (!ltr)
|
||||
[minMargin, maxMargin] = [this.clientWidth - maxMargin,
|
||||
|
@ -3635,6 +3639,7 @@
|
|||
<field name="mOverCloseButton">false</field>
|
||||
<field name="mCorrespondingMenuitem">null</field>
|
||||
<field name="_fullyOpen">false</field>
|
||||
<field name="closing">false</field>
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
|
@ -3746,7 +3751,7 @@
|
|||
continue;
|
||||
if (curTabBO.screenX >= tabstripBO.screenX &&
|
||||
curTabBO.screenX + curTabBO.width <= tabstripBO.screenX + tabstripBO.width)
|
||||
this.childNodes[i].setAttribute("tabIsVisible", "true");
|
||||
this.childNodes[i].setAttribute("tabIsVisible", "true");
|
||||
else
|
||||
this.childNodes[i].removeAttribute("tabIsVisible");
|
||||
}
|
||||
|
@ -3757,7 +3762,7 @@
|
|||
<parameter name="aTab"/>
|
||||
<body><![CDATA[
|
||||
var menuItem = document.createElementNS(
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul",
|
||||
"menuitem");
|
||||
|
||||
menuItem.setAttribute("class", "menuitem-iconic alltabs-item menuitem-with-favicon");
|
||||
|
|
|
@ -2032,7 +2032,7 @@ let GroupItems = {
|
|||
if (UI.shouldLoadFavIcon(xulTab.linkedBrowser))
|
||||
iconUrl = UI.getFavIconUrlForTab(xulTab);
|
||||
else
|
||||
iconUrl = Utils.defaultFaviconURL;
|
||||
iconUrl = gFavIconService.defaultFavicon.spec;
|
||||
|
||||
return iconUrl;
|
||||
},
|
||||
|
@ -2107,7 +2107,9 @@ let GroupItems = {
|
|||
|
||||
let activeGroupId = this._activeGroupItem ? this._activeGroupItem.id : null;
|
||||
Storage.saveGroupItemsData(
|
||||
gWindow, { nextID: this.nextID, activeGroupId: activeGroupId });
|
||||
gWindow,
|
||||
{ nextID: this.nextID, activeGroupId: activeGroupId,
|
||||
totalNumber: this.groupItems.length });
|
||||
},
|
||||
|
||||
// ----------
|
||||
|
|
|
@ -608,7 +608,7 @@ iQClass.prototype = {
|
|||
});
|
||||
|
||||
this.css({
|
||||
'-moz-transition-property': 'all', // TODO: just animate the properties we're changing
|
||||
'-moz-transition-property': Object.keys(css).join(", "),
|
||||
'-moz-transition-duration': (duration / 1000) + 's',
|
||||
'-moz-transition-timing-function': easing
|
||||
});
|
||||
|
|
|
@ -57,10 +57,7 @@ let AllTabs = {
|
|||
get tabs() {
|
||||
// Get tabs from each browser window and flatten them into one array
|
||||
return Array.concat.apply(null, browserWindows.map(function(browserWindow) {
|
||||
let removingTabs = browserWindow.gBrowser._removingTabs;
|
||||
return Array.filter(browserWindow.gBrowser.tabs, function (tab) {
|
||||
return removingTabs.indexOf(tab) == -1;
|
||||
});
|
||||
return Array.filter(browserWindow.gBrowser.tabs, function (tab) !tab.closing);
|
||||
}));
|
||||
},
|
||||
|
||||
|
|
|
@ -490,8 +490,6 @@ Subscribable.prototype = {
|
|||
// Class: Utils
|
||||
// Singelton with common utility functions.
|
||||
let Utils = {
|
||||
defaultFaviconURL: "chrome://mozapps/skin/places/defaultFavicon.png",
|
||||
|
||||
// ----------
|
||||
// Function: toString
|
||||
// Prints [Utils] for debug use
|
||||
|
|
|
@ -47,8 +47,6 @@ let Storage = {
|
|||
GROUPS_DATA_IDENTIFIER: "tabview-groups",
|
||||
TAB_DATA_IDENTIFIER: "tabview-tab",
|
||||
UI_DATA_IDENTIFIER: "tabview-ui",
|
||||
CACHE_CLIENT_IDENTIFIER: "tabview-cache",
|
||||
CACHE_PREFIX: "moz-panorama:",
|
||||
|
||||
// ----------
|
||||
// Function: toString
|
||||
|
@ -64,28 +62,12 @@ let Storage = {
|
|||
this._sessionStore =
|
||||
Cc["@mozilla.org/browser/sessionstore;1"].
|
||||
getService(Ci.nsISessionStore);
|
||||
|
||||
// Create stream-based cache session for tabview
|
||||
let cacheService =
|
||||
Cc["@mozilla.org/network/cache-service;1"].
|
||||
getService(Ci.nsICacheService);
|
||||
this._cacheSession = cacheService.createSession(
|
||||
this.CACHE_CLIENT_IDENTIFIER, Ci.nsICache.STORE_ON_DISK, true);
|
||||
this.StringInputStream = Components.Constructor(
|
||||
"@mozilla.org/io/string-input-stream;1", "nsIStringInputStream",
|
||||
"setData");
|
||||
this.StorageStream = Components.Constructor(
|
||||
"@mozilla.org/storagestream;1", "nsIStorageStream",
|
||||
"init");
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: uninit
|
||||
uninit: function Storage_uninit () {
|
||||
this._sessionStore = null;
|
||||
this._cacheSession = null;
|
||||
this.StringInputStream = null;
|
||||
this.StorageStream = null;
|
||||
},
|
||||
|
||||
// ----------
|
||||
|
@ -114,137 +96,6 @@ let Storage = {
|
|||
}
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: _openCacheEntry
|
||||
// Opens a cache entry for the given <url> and requests access <access>.
|
||||
// Calls <successCallback>(entry) when the entry was successfully opened with
|
||||
// requested access rights. Otherwise calls <errorCallback>().
|
||||
_openCacheEntry: function Storage__openCacheEntry(url, access, successCallback, errorCallback) {
|
||||
let onCacheEntryAvailable = function (entry, accessGranted, status) {
|
||||
if (entry && access == accessGranted && Components.isSuccessCode(status)) {
|
||||
successCallback(entry);
|
||||
} else {
|
||||
entry && entry.close();
|
||||
errorCallback();
|
||||
}
|
||||
}
|
||||
|
||||
let key = this.CACHE_PREFIX + url;
|
||||
|
||||
// switch to synchronous mode if parent window is about to close
|
||||
if (UI.isDOMWindowClosing) {
|
||||
let entry = this._cacheSession.openCacheEntry(key, access, true);
|
||||
let status = Components.results.NS_OK;
|
||||
onCacheEntryAvailable(entry, entry.accessGranted, status);
|
||||
} else {
|
||||
let listener = new CacheListener(onCacheEntryAvailable);
|
||||
this._cacheSession.asyncOpenCacheEntry(key, access, listener);
|
||||
}
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: saveThumbnail
|
||||
// Saves the <imageData> to the cache using the given <url> as key.
|
||||
// Calls <callback>(status) when finished (passing true or false indicating
|
||||
// whether the operation succeeded).
|
||||
saveThumbnail: function Storage_saveThumbnail(url, imageData, callback) {
|
||||
Utils.assert(url, "url");
|
||||
Utils.assert(imageData, "imageData");
|
||||
Utils.assert(typeof callback == "function", "callback arg must be a function");
|
||||
|
||||
let self = this;
|
||||
let StringInputStream = this.StringInputStream;
|
||||
|
||||
let onCacheEntryAvailable = function (entry) {
|
||||
let outputStream = entry.openOutputStream(0);
|
||||
|
||||
let cleanup = function () {
|
||||
outputStream.close();
|
||||
entry.close();
|
||||
}
|
||||
|
||||
// switch to synchronous mode if parent window is about to close
|
||||
if (UI.isDOMWindowClosing) {
|
||||
outputStream.write(imageData, imageData.length);
|
||||
cleanup();
|
||||
callback(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// asynchronous mode
|
||||
let inputStream = new StringInputStream(imageData, imageData.length);
|
||||
gNetUtil.asyncCopy(inputStream, outputStream, function (result) {
|
||||
cleanup();
|
||||
inputStream.close();
|
||||
callback(Components.isSuccessCode(result));
|
||||
});
|
||||
}
|
||||
|
||||
let onCacheEntryUnavailable = function () {
|
||||
callback(false);
|
||||
}
|
||||
|
||||
this._openCacheEntry(url, Ci.nsICache.ACCESS_WRITE,
|
||||
onCacheEntryAvailable, onCacheEntryUnavailable);
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: loadThumbnail
|
||||
// Asynchrously loads image data from the cache using the given <url> as key.
|
||||
// Calls <callback>(status, data) when finished, passing true or false
|
||||
// (indicating whether the operation succeeded) and the retrieved image data.
|
||||
loadThumbnail: function Storage_loadThumbnail(url, callback) {
|
||||
Utils.assert(url, "url");
|
||||
Utils.assert(typeof callback == "function", "callback arg must be a function");
|
||||
|
||||
let self = this;
|
||||
|
||||
let onCacheEntryAvailable = function (entry) {
|
||||
let imageChunks = [];
|
||||
let nativeInputStream = entry.openInputStream(0);
|
||||
|
||||
const CHUNK_SIZE = 0x10000; // 65k
|
||||
const PR_UINT32_MAX = 0xFFFFFFFF;
|
||||
let storageStream = new self.StorageStream(CHUNK_SIZE, PR_UINT32_MAX, null);
|
||||
let storageOutStream = storageStream.getOutputStream(0);
|
||||
|
||||
let cleanup = function () {
|
||||
nativeInputStream.close();
|
||||
storageStream.close();
|
||||
storageOutStream.close();
|
||||
entry.close();
|
||||
}
|
||||
|
||||
gNetUtil.asyncCopy(nativeInputStream, storageOutStream, function (result) {
|
||||
// cancel if parent window has already been closed
|
||||
if (typeof UI == "undefined") {
|
||||
cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
let imageData = null;
|
||||
let isSuccess = Components.isSuccessCode(result);
|
||||
|
||||
if (isSuccess) {
|
||||
let storageInStream = storageStream.newInputStream(0);
|
||||
imageData = gNetUtil.readInputStreamToString(storageInStream,
|
||||
storageInStream.available());
|
||||
storageInStream.close();
|
||||
}
|
||||
|
||||
cleanup();
|
||||
callback(isSuccess, imageData);
|
||||
});
|
||||
}
|
||||
|
||||
let onCacheEntryUnavailable = function () {
|
||||
callback(false);
|
||||
}
|
||||
|
||||
this._openCacheEntry(url, Ci.nsICache.ACCESS_READ,
|
||||
onCacheEntryAvailable, onCacheEntryUnavailable);
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: saveTab
|
||||
// Saves the data for a single tab.
|
||||
|
@ -255,16 +106,9 @@ let Storage = {
|
|||
let imageData = data.imageData;
|
||||
// Remove imageData from payload
|
||||
delete data.imageData;
|
||||
if (imageData != null) {
|
||||
this.saveThumbnail(data.url, imageData, function (status) {
|
||||
if (status) {
|
||||
// Notify subscribers
|
||||
tab._tabViewTabItem._sendToSubscribers("savedCachedImageData");
|
||||
} else {
|
||||
Utils.log("Error while saving thumbnail: " + e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (imageData != null)
|
||||
ThumbnailStorage.saveThumbnail(tab, imageData);
|
||||
}
|
||||
|
||||
this._sessionStore.setTabValue(tab, this.TAB_DATA_IDENTIFIER,
|
||||
|
@ -292,18 +136,13 @@ let Storage = {
|
|||
}
|
||||
|
||||
if (existingData) {
|
||||
this.loadThumbnail(existingData.url, function (status, imageData) {
|
||||
if (status) {
|
||||
ThumbnailStorage.loadThumbnail(
|
||||
tab, existingData.url,
|
||||
function(status, imageData) {
|
||||
callback(imageData);
|
||||
|
||||
// Notify subscribers
|
||||
tab._tabViewTabItem._sendToSubscribers("loadedCachedImageData");
|
||||
} else {
|
||||
Utils.log("Error while loading thumbnail");
|
||||
}
|
||||
});
|
||||
);
|
||||
}
|
||||
|
||||
return existingData;
|
||||
},
|
||||
|
||||
|
@ -409,26 +248,3 @@ let Storage = {
|
|||
}
|
||||
};
|
||||
|
||||
// ##########
|
||||
// Class: CacheListener
|
||||
// Generic CacheListener for feeding to asynchronous cache calls.
|
||||
// Calls <callback>(entry, access, status) when the requested cache entry
|
||||
// is available.
|
||||
function CacheListener(callback) {
|
||||
Utils.assert(typeof callback == "function", "callback arg must be a function");
|
||||
this.callback = callback;
|
||||
};
|
||||
|
||||
CacheListener.prototype = {
|
||||
// ----------
|
||||
// Function: toString
|
||||
// Prints [CacheListener] for debug use
|
||||
toString: function CacheListener_toString() {
|
||||
return "[CacheListener]";
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsICacheListener]),
|
||||
onCacheEntryAvailable: function (entry, access, status) {
|
||||
this.callback(entry, access, status);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1558,6 +1558,6 @@ TabCanvas.prototype = {
|
|||
// ----------
|
||||
// Function: toImageData
|
||||
toImageData: function TabCanvas_toImageData() {
|
||||
return this.canvas.toDataURL("image/png", "");
|
||||
return this.canvas.toDataURL("image/png");
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
|
||||
Cu.import("resource:///modules/tabview/AllTabs.jsm");
|
||||
Cu.import("resource:///modules/tabview/utils.jsm");
|
||||
|
@ -50,5 +51,6 @@ var gTabViewFrame = gWindow.document.getElementById("tab-view");
|
|||
#include tabitems.js
|
||||
#include drag.js
|
||||
#include trench.js
|
||||
#include thumbnailStorage.js
|
||||
#include ui.js
|
||||
#include search.js
|
||||
|
|
|
@ -0,0 +1,373 @@
|
|||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is thumbnailStorage.js.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* the Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Raymond Lee <raymond@appcoast.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
||||
* in which case the provisions of the GPL or the LGPL are applicable instead
|
||||
* of those above. If you wish to allow use of your version of this file only
|
||||
* under the terms of either the GPL or the LGPL, and not to allow others to
|
||||
* use your version of this file under the terms of the MPL, indicate your
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// **********
|
||||
// Title: thumbnailStorage.js
|
||||
|
||||
// ##########
|
||||
// Class: ThumbnailStorage
|
||||
// Singleton for persistent storage of thumbnail data.
|
||||
let ThumbnailStorage = {
|
||||
CACHE_CLIENT_IDENTIFIER: "tabview-cache",
|
||||
CACHE_PREFIX: "moz-panorama:",
|
||||
PREF_DISK_CACHE_SSL: "browser.cache.disk_cache_ssl",
|
||||
|
||||
// Holds the cache session reference
|
||||
_cacheSession: null,
|
||||
|
||||
// Holds the string input stream reference
|
||||
_stringInputStream: null,
|
||||
|
||||
// Holds the storage stream reference
|
||||
_storageStream: null,
|
||||
|
||||
// Holds the progress listener reference
|
||||
_progressListener: null,
|
||||
|
||||
// Used to keep track of disk_cache_ssl preference
|
||||
enablePersistentHttpsCaching: null,
|
||||
|
||||
// Used to keep track of browsers whose thumbs we shouldn't save
|
||||
excludedBrowsers: [],
|
||||
|
||||
// ----------
|
||||
// Function: toString
|
||||
// Prints [ThumbnailStorage] for debug use.
|
||||
toString: function ThumbnailStorage_toString() {
|
||||
return "[ThumbnailStorage]";
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: init
|
||||
// Should be called when UI is initialized.
|
||||
init: function ThumbnailStorage_init() {
|
||||
// Create stream-based cache session for tabview
|
||||
let cacheService =
|
||||
Cc["@mozilla.org/network/cache-service;1"].
|
||||
getService(Ci.nsICacheService);
|
||||
this._cacheSession = cacheService.createSession(
|
||||
this.CACHE_CLIENT_IDENTIFIER, Ci.nsICache.STORE_ON_DISK, true);
|
||||
this._stringInputStream = Components.Constructor(
|
||||
"@mozilla.org/io/string-input-stream;1", "nsIStringInputStream",
|
||||
"setData");
|
||||
this._storageStream = Components.Constructor(
|
||||
"@mozilla.org/storagestream;1", "nsIStorageStream",
|
||||
"init");
|
||||
|
||||
// store the preference value
|
||||
this.enablePersistentHttpsCaching =
|
||||
Services.prefs.getBoolPref(this.PREF_DISK_CACHE_SSL);
|
||||
|
||||
Services.prefs.addObserver(this.PREF_DISK_CACHE_SSL, this, false);
|
||||
|
||||
let self = this;
|
||||
// tabs are already loaded before UI is initialized so cache-control
|
||||
// values are unknown. We add browsers with https to the list for now.
|
||||
gBrowser.browsers.forEach(function(browser) {
|
||||
let checkAndAddToList = function(browserObj) {
|
||||
if (!self.enablePersistentHttpsCaching &&
|
||||
browserObj.currentURI.schemeIs("https"))
|
||||
self.excludedBrowsers.push(browserObj);
|
||||
};
|
||||
if (browser.contentDocument.readyState != "complete" ||
|
||||
browser.webProgress.isLoadingDocument) {
|
||||
browser.addEventListener("load", function() {
|
||||
browser.removeEventListener("load", arguments.callee, true);
|
||||
checkAndAddToList(browser);
|
||||
}, true);
|
||||
} else {
|
||||
checkAndAddToList(browser);
|
||||
}
|
||||
});
|
||||
gBrowser.addTabsProgressListener(this);
|
||||
},
|
||||
|
||||
// Function: uninit
|
||||
// Should be called when window is unloaded.
|
||||
uninit: function ThumbnailStorage_uninit() {
|
||||
gBrowser.removeTabsProgressListener(this);
|
||||
Services.prefs.removeObserver(this.PREF_DISK_CACHE_SSL, this);
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: _openCacheEntry
|
||||
// Opens a cache entry for the given <url> and requests access <access>.
|
||||
// Calls <successCallback>(entry) when the entry was successfully opened with
|
||||
// requested access rights. Otherwise calls <errorCallback>().
|
||||
_openCacheEntry: function ThumbnailStorage__openCacheEntry(url, access, successCallback, errorCallback) {
|
||||
let onCacheEntryAvailable = function(entry, accessGranted, status) {
|
||||
if (entry && access == accessGranted && Components.isSuccessCode(status)) {
|
||||
successCallback(entry);
|
||||
} else {
|
||||
entry && entry.close();
|
||||
errorCallback();
|
||||
}
|
||||
}
|
||||
|
||||
let key = this.CACHE_PREFIX + url;
|
||||
|
||||
// switch to synchronous mode if parent window is about to close
|
||||
if (UI.isDOMWindowClosing) {
|
||||
let entry = this._cacheSession.openCacheEntry(key, access, true);
|
||||
let status = Cr.NS_OK;
|
||||
onCacheEntryAvailable(entry, entry.accessGranted, status);
|
||||
} else {
|
||||
let listener = new CacheListener(onCacheEntryAvailable);
|
||||
this._cacheSession.asyncOpenCacheEntry(key, access, listener);
|
||||
}
|
||||
},
|
||||
|
||||
// Function: _shouldSaveThumbnail
|
||||
// Checks whether to save tab's thumbnail or not.
|
||||
_shouldSaveThumbnail : function ThumbnailStorage__shouldSaveThumbnail(tab) {
|
||||
return (this.excludedBrowsers.indexOf(tab.linkedBrowser) == -1);
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: saveThumbnail
|
||||
// Saves the <imageData> to the cache using the given <url> as key.
|
||||
// Calls <callback>(status, data) when finished, passing true or false
|
||||
// (indicating whether the operation succeeded).
|
||||
saveThumbnail: function ThumbnailStorage_saveThumbnail(tab, imageData, callback) {
|
||||
Utils.assert(tab, "tab");
|
||||
Utils.assert(imageData, "imageData");
|
||||
|
||||
if (!this._shouldSaveThumbnail(tab)) {
|
||||
tab._tabViewTabItem._sendToSubscribers("deniedToCacheImageData");
|
||||
if (callback)
|
||||
callback(false);
|
||||
return;
|
||||
}
|
||||
|
||||
let self = this;
|
||||
|
||||
let completed = function(status) {
|
||||
if (callback)
|
||||
callback(status);
|
||||
|
||||
if (status) {
|
||||
// Notify subscribers
|
||||
tab._tabViewTabItem._sendToSubscribers("savedCachedImageData");
|
||||
} else {
|
||||
Utils.log("Error while saving thumbnail: " + e);
|
||||
}
|
||||
};
|
||||
|
||||
let onCacheEntryAvailable = function(entry) {
|
||||
let outputStream = entry.openOutputStream(0);
|
||||
|
||||
let cleanup = function() {
|
||||
outputStream.close();
|
||||
entry.close();
|
||||
}
|
||||
|
||||
// switch to synchronous mode if parent window is about to close
|
||||
if (UI.isDOMWindowClosing) {
|
||||
outputStream.write(imageData, imageData.length);
|
||||
cleanup();
|
||||
completed(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// asynchronous mode
|
||||
let inputStream = new self._stringInputStream(imageData, imageData.length);
|
||||
gNetUtil.asyncCopy(inputStream, outputStream, function (result) {
|
||||
cleanup();
|
||||
inputStream.close();
|
||||
completed(Components.isSuccessCode(result));
|
||||
});
|
||||
}
|
||||
|
||||
let onCacheEntryUnavailable = function() {
|
||||
completed(false);
|
||||
}
|
||||
|
||||
this._openCacheEntry(tab.linkedBrowser.currentURI.spec,
|
||||
Ci.nsICache.ACCESS_WRITE, onCacheEntryAvailable,
|
||||
onCacheEntryUnavailable);
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: loadThumbnail
|
||||
// Asynchrously loads image data from the cache using the given <url> as key.
|
||||
// Calls <callback>(status, data) when finished, passing true or false
|
||||
// (indicating whether the operation succeeded) and the retrieved image data.
|
||||
loadThumbnail: function ThumbnailStorage_loadThumbnail(tab, url, callback) {
|
||||
Utils.assert(tab, "tab");
|
||||
Utils.assert(url, "url");
|
||||
Utils.assert(typeof callback == "function", "callback arg must be a function");
|
||||
|
||||
let self = this;
|
||||
|
||||
let completed = function(status, imageData) {
|
||||
callback(status, imageData);
|
||||
|
||||
if (status) {
|
||||
// Notify subscribers
|
||||
tab._tabViewTabItem._sendToSubscribers("loadedCachedImageData");
|
||||
} else {
|
||||
Utils.log("Error while loading thumbnail");
|
||||
}
|
||||
}
|
||||
|
||||
let onCacheEntryAvailable = function(entry) {
|
||||
let imageChunks = [];
|
||||
let nativeInputStream = entry.openInputStream(0);
|
||||
|
||||
const CHUNK_SIZE = 0x10000; // 65k
|
||||
const PR_UINT32_MAX = 0xFFFFFFFF;
|
||||
let storageStream = new self._storageStream(CHUNK_SIZE, PR_UINT32_MAX, null);
|
||||
let storageOutStream = storageStream.getOutputStream(0);
|
||||
|
||||
let cleanup = function () {
|
||||
nativeInputStream.close();
|
||||
storageStream.close();
|
||||
storageOutStream.close();
|
||||
entry.close();
|
||||
}
|
||||
|
||||
gNetUtil.asyncCopy(nativeInputStream, storageOutStream, function (result) {
|
||||
// cancel if parent window has already been closed
|
||||
if (typeof UI == "undefined") {
|
||||
cleanup();
|
||||
return;
|
||||
}
|
||||
|
||||
let imageData = null;
|
||||
let isSuccess = Components.isSuccessCode(result);
|
||||
|
||||
if (isSuccess) {
|
||||
let storageInStream = storageStream.newInputStream(0);
|
||||
imageData = gNetUtil.readInputStreamToString(storageInStream,
|
||||
storageInStream.available());
|
||||
storageInStream.close();
|
||||
}
|
||||
|
||||
cleanup();
|
||||
completed(isSuccess, imageData);
|
||||
});
|
||||
}
|
||||
|
||||
let onCacheEntryUnavailable = function() {
|
||||
completed(false);
|
||||
}
|
||||
|
||||
this._openCacheEntry(url, Ci.nsICache.ACCESS_READ,
|
||||
onCacheEntryAvailable, onCacheEntryUnavailable);
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: observe
|
||||
// Implements the observer interface.
|
||||
observe: function ThumbnailStorage_observe(subject, topic, data) {
|
||||
this.enablePersistentHttpsCaching =
|
||||
Services.prefs.getBoolPref(this.PREF_DISK_CACHE_SSL);
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Implements progress listener interface.
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
|
||||
Ci.nsISupportsWeakReference,
|
||||
Ci.nsISupports]),
|
||||
|
||||
onStateChange: function ThumbnailStorage_onStateChange(
|
||||
browser, webProgress, request, flag, status) {
|
||||
if (flag & Ci.nsIWebProgressListener.STATE_START &&
|
||||
flag & Ci.nsIWebProgressListener.STATE_IS_WINDOW) {
|
||||
// ensure the dom window is the top one
|
||||
if (webProgress.DOMWindow.parent == webProgress.DOMWindow) {
|
||||
let index = this.excludedBrowsers.indexOf(browser);
|
||||
if (index != -1)
|
||||
this.excludedBrowsers.splice(index, 1);
|
||||
}
|
||||
}
|
||||
if (flag & Ci.nsIWebProgressListener.STATE_STOP &&
|
||||
flag & Ci.nsIWebProgressListener.STATE_IS_WINDOW) {
|
||||
// ensure the dom window is the top one
|
||||
if (webProgress.DOMWindow.parent == webProgress.DOMWindow &&
|
||||
request && request instanceof Ci.nsIHttpChannel) {
|
||||
request.QueryInterface(Ci.nsIHttpChannel);
|
||||
|
||||
let inhibitPersistentThumb = false;
|
||||
if (request.isNoStoreResponse()) {
|
||||
inhibitPersistentThumb = true;
|
||||
} else if (!this.enablePersistentHttpsCaching &&
|
||||
request.URI.schemeIs("https")) {
|
||||
let cacheControlHeader;
|
||||
try {
|
||||
cacheControlHeader = request.getResponseHeader("Cache-Control");
|
||||
} catch(e) {
|
||||
// this error would occur when "Cache-Control" doesn't exist in
|
||||
// the eaders
|
||||
}
|
||||
if (cacheControlHeader && !(/public/i).test(cacheControlHeader))
|
||||
inhibitPersistentThumb = true;
|
||||
}
|
||||
|
||||
if (inhibitPersistentThumb &&
|
||||
this.excludedBrowsers.indexOf(browser) == -1)
|
||||
this.excludedBrowsers.push(browser);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ##########
|
||||
// Class: CacheListener
|
||||
// Generic CacheListener for feeding to asynchronous cache calls.
|
||||
// Calls <callback>(entry, access, status) when the requested cache entry
|
||||
// is available.
|
||||
function CacheListener(callback) {
|
||||
Utils.assert(typeof callback == "function", "callback arg must be a function");
|
||||
this.callback = callback;
|
||||
};
|
||||
|
||||
CacheListener.prototype = {
|
||||
// ----------
|
||||
// Function: toString
|
||||
// Prints [CacheListener] for debug use
|
||||
toString: function CacheListener_toString() {
|
||||
return "[CacheListener]";
|
||||
},
|
||||
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsICacheListener]),
|
||||
onCacheEntryAvailable: function CacheListener_onCacheEntryAvailable(
|
||||
entry, access, status) {
|
||||
this.callback(entry, access, status);
|
||||
}
|
||||
};
|
||||
|
|
@ -157,6 +157,9 @@ let UI = {
|
|||
// initialize the direction of the page
|
||||
this._initPageDirection();
|
||||
|
||||
// ___ thumbnail storage
|
||||
ThumbnailStorage.init();
|
||||
|
||||
// ___ storage
|
||||
Storage.init();
|
||||
let data = Storage.readUIData(gWindow);
|
||||
|
@ -278,7 +281,7 @@ let UI = {
|
|||
// initialized.
|
||||
let event = document.createEvent("Events");
|
||||
event.initEvent("tabviewframeinitialized", true, false);
|
||||
dispatchEvent(event);
|
||||
dispatchEvent(event);
|
||||
} catch(e) {
|
||||
Utils.log(e);
|
||||
} finally {
|
||||
|
@ -286,6 +289,8 @@ let UI = {
|
|||
}
|
||||
},
|
||||
|
||||
// Function: uninit
|
||||
// Should be called when window is unloaded.
|
||||
uninit: function UI_uninit() {
|
||||
// call our cleanup functions
|
||||
this._cleanupFunctions.forEach(function(func) {
|
||||
|
@ -297,6 +302,7 @@ let UI = {
|
|||
TabItems.uninit();
|
||||
GroupItems.uninit();
|
||||
Storage.uninit();
|
||||
ThumbnailStorage.uninit();
|
||||
|
||||
this._removeTabActionHandlers();
|
||||
this._currentTab = null;
|
||||
|
@ -680,22 +686,22 @@ let UI = {
|
|||
// don't reenter Panorama due to all of the session restore tab
|
||||
// manipulation (which otherwise we might). When transitioning away from
|
||||
// PB, we reenter Panorama if we had been there directly before PB.
|
||||
function pbObserver(aSubject, aTopic, aData) {
|
||||
if (aTopic == "private-browsing") {
|
||||
function pbObserver(subject, topic, data) {
|
||||
if (topic == "private-browsing") {
|
||||
// We could probably do this in private-browsing-change-granted, but
|
||||
// this seems like a nicer spot, right in the middle of the process.
|
||||
if (aData == "enter") {
|
||||
if (data == "enter") {
|
||||
// If we are in Tab View, exit.
|
||||
self._privateBrowsing.wasInTabView = self.isTabViewVisible();
|
||||
if (self.isTabViewVisible())
|
||||
self.goToTab(gBrowser.selectedTab);
|
||||
}
|
||||
} else if (aTopic == "private-browsing-change-granted") {
|
||||
if (aData == "enter" || aData == "exit") {
|
||||
self._privateBrowsing.transitionMode = aData;
|
||||
} else if (topic == "private-browsing-change-granted") {
|
||||
if (data == "enter" || data == "exit") {
|
||||
self._privateBrowsing.transitionMode = data;
|
||||
self.storageBusy();
|
||||
}
|
||||
} else if (aTopic == "private-browsing-transition-complete") {
|
||||
} else if (topic == "private-browsing-transition-complete") {
|
||||
// We use .transitionMode here, as aData is empty.
|
||||
if (self._privateBrowsing.transitionMode == "exit" &&
|
||||
self._privateBrowsing.wasInTabView)
|
||||
|
@ -749,8 +755,7 @@ let UI = {
|
|||
if (gBrowser.tabs.length > 1) {
|
||||
// Don't return to TabView if there are any app tabs
|
||||
for (let a = 0; a < gBrowser._numPinnedTabs; a++) {
|
||||
let theTab = gBrowser.tabs[a];
|
||||
if (gBrowser._removingTabs.indexOf(theTab) == -1)
|
||||
if (!gBrowser.tabs[a].closing)
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -956,12 +961,11 @@ let UI = {
|
|||
|
||||
// ----------
|
||||
updateTabButton: function UI__updateTabButton() {
|
||||
let groupsNumber = gWindow.document.getElementById("tabviewGroupsNumber");
|
||||
let exitButton = document.getElementById("exit-button");
|
||||
let numberOfGroups = GroupItems.groupItems.length;
|
||||
|
||||
groupsNumber.setAttribute("groups", numberOfGroups);
|
||||
exitButton.setAttribute("groups", numberOfGroups);
|
||||
gTabView.updateGroupNumberBroadcaster(numberOfGroups);
|
||||
},
|
||||
|
||||
// ----------
|
||||
|
@ -991,20 +995,28 @@ let UI = {
|
|||
[
|
||||
#ifdef XP_UNIX
|
||||
"quitApplication",
|
||||
#else
|
||||
"redo",
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
"preferencesCmdMac", "minimizeWindow",
|
||||
"preferencesCmdMac", "minimizeWindow", "hideThisAppCmdMac",
|
||||
#endif
|
||||
"newNavigator", "newNavigatorTab", "find"
|
||||
].forEach(function(key) {
|
||||
"newNavigator", "newNavigatorTab", "undo", "cut", "copy", "paste",
|
||||
"selectAll", "find"
|
||||
].forEach(function(key) {
|
||||
let element = gWindow.document.getElementById("key_" + key);
|
||||
keys[key] = element.getAttribute("key").toLocaleLowerCase().charCodeAt(0);
|
||||
});
|
||||
|
||||
// for key combinations with shift key, the charCode of upper case letters
|
||||
// are different to the lower case ones so need to handle them differently.
|
||||
["closeWindow", "tabview", "undoCloseTab", "undoCloseWindow",
|
||||
"privatebrowsing"].forEach(function(key) {
|
||||
[
|
||||
#ifdef XP_UNIX
|
||||
"redo",
|
||||
#endif
|
||||
"closeWindow", "tabview", "undoCloseTab", "undoCloseWindow",
|
||||
"privatebrowsing"
|
||||
].forEach(function(key) {
|
||||
let element = gWindow.document.getElementById("key_" + key);
|
||||
keys[key] = element.getAttribute("key").toLocaleUpperCase().charCodeAt(0);
|
||||
});
|
||||
|
@ -1031,6 +1043,10 @@ let UI = {
|
|||
Keys.meta = true;
|
||||
|
||||
function processBrowserKeys(evt) {
|
||||
// let any keys with alt to pass through
|
||||
if (evt.altKey)
|
||||
return;
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
if (evt.metaKey) {
|
||||
#else
|
||||
|
@ -1039,36 +1055,43 @@ let UI = {
|
|||
let preventDefault = true;
|
||||
if (evt.shiftKey) {
|
||||
switch (evt.charCode) {
|
||||
case self._browserKeys.privatebrowsing:
|
||||
case self._browserKeys.undoCloseTab:
|
||||
case self._browserKeys.undoCloseWindow:
|
||||
case self._browserKeys.closeWindow:
|
||||
preventDefault = false;
|
||||
break;
|
||||
case self._browserKeys.tabview:
|
||||
self.exit();
|
||||
break;
|
||||
#ifdef XP_UNIX
|
||||
case self._browserKeys.redo:
|
||||
#endif
|
||||
case self._browserKeys.closeWindow:
|
||||
case self._browserKeys.undoCloseTab:
|
||||
case self._browserKeys.undoCloseWindow:
|
||||
case self._browserKeys.privatebrowsing:
|
||||
preventDefault = false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (evt.charCode) {
|
||||
case self._browserKeys.find:
|
||||
self.enableSearch();
|
||||
break;
|
||||
case self._browserKeys.newNavigator:
|
||||
case self._browserKeys.newNavigatorTab:
|
||||
preventDefault = false;
|
||||
break;
|
||||
#ifdef XP_UNIX
|
||||
case self._browserKeys.quitApplication:
|
||||
preventDefault = false;
|
||||
break;
|
||||
#else
|
||||
case self._browserKeys.redo:
|
||||
#endif
|
||||
#ifdef XP_MACOSX
|
||||
case self._browserKeys.preferencesCmdMac:
|
||||
case self._browserKeys.minimizeWindow:
|
||||
case self._browserKeys.hideThisAppCmdMac:
|
||||
#endif
|
||||
case self._browserKeys.newNavigator:
|
||||
case self._browserKeys.newNavigatorTab:
|
||||
case self._browserKeys.undo:
|
||||
case self._browserKeys.cut:
|
||||
case self._browserKeys.copy:
|
||||
case self._browserKeys.paste:
|
||||
case self._browserKeys.selectAll:
|
||||
preventDefault = false;
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (preventDefault) {
|
||||
|
|
|
@ -112,7 +112,7 @@ _BROWSER_FILES = \
|
|||
browser_bug416661.js \
|
||||
browser_bug417483.js \
|
||||
browser_bug419612.js \
|
||||
browser_bug420160.js \
|
||||
browser_identity_UI.js \
|
||||
browser_bug422590.js \
|
||||
browser_bug424101.js \
|
||||
browser_bug427559.js \
|
||||
|
@ -170,7 +170,10 @@ _BROWSER_FILES = \
|
|||
browser_bug616836.js \
|
||||
browser_bug623893.js \
|
||||
browser_bug624734.js \
|
||||
browser_bug647886.js \
|
||||
browser_bug655584.js \
|
||||
browser_findbarClose.js \
|
||||
browser_keywordBookmarklets.js \
|
||||
browser_contextSearchTabPosition.js \
|
||||
browser_ctrlTab.js \
|
||||
browser_customize_popupNotification.js \
|
||||
|
@ -231,7 +234,6 @@ _BROWSER_FILES = \
|
|||
browser_visibleTabs_bookmarkAllPages.js \
|
||||
browser_visibleTabs_bookmarkAllTabs.js \
|
||||
browser_visibleTabs_tabPreview.js \
|
||||
browser_webdev_menu.js \
|
||||
bug592338.html \
|
||||
disablechrome.html \
|
||||
discovery.html \
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
var listener = {
|
||||
testFunction: null,
|
||||
|
||||
handleEvent: function (e) {
|
||||
this.testFunction();
|
||||
}
|
||||
}
|
||||
|
||||
/* Tests for correct behaviour of getEffectiveHost on identity handler */
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
ok(gIdentityHandler, "gIdentityHandler should exist");
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", listener, true);
|
||||
listener.testFunction = testNormalDomain;
|
||||
content.location = "http://test1.example.org/";
|
||||
}
|
||||
|
||||
// Greek IDN for 'example.test'.
|
||||
var idnDomain = "\u03C0\u03B1\u03C1\u03AC\u03B4\u03B5\u03B9\u03B3\u03BC\u03B1.\u03B4\u03BF\u03BA\u03B9\u03BC\u03AE";
|
||||
|
||||
function testNormalDomain() {
|
||||
is(gIdentityHandler._lastLocation.host, 'test1.example.org', "Identity handler is getting the full location");
|
||||
is(gIdentityHandler.getEffectiveHost(), 'example.org', "getEffectiveHost should return example.org for test1.example.org");
|
||||
|
||||
listener.testFunction = testIDNDomain;
|
||||
content.location = "http://sub1." + idnDomain + "/";
|
||||
}
|
||||
|
||||
function testIDNDomain() {
|
||||
is(gIdentityHandler._lastLocation.host, "sub1." + idnDomain, "Identity handler is getting the full location");
|
||||
is(gIdentityHandler.getEffectiveHost(), idnDomain, "getEffectiveHost should return the IDN base domain in UTF-8");
|
||||
|
||||
listener.testFunction = testNormalDomainWithPort;
|
||||
content.location = "http://sub1.test1.example.org:8000/";
|
||||
}
|
||||
|
||||
function testNormalDomainWithPort() {
|
||||
is(gIdentityHandler._lastLocation.host, 'sub1.test1.example.org:8000', "Identity handler is getting port information");
|
||||
is(gIdentityHandler.getEffectiveHost(), 'example.org', "getEffectiveHost should return example.org for sub1.test1.example.org:8000");
|
||||
|
||||
listener.testFunction = testIPWithPort;
|
||||
content.location = "http://127.0.0.1:8888/";
|
||||
}
|
||||
|
||||
function testIPWithPort() {
|
||||
is(gIdentityHandler.getEffectiveHost(), '127.0.0.1', "getEffectiveHost should return 127.0.0.1 for 127.0.0.1:8888");
|
||||
gBrowser.selectedBrowser.removeEventListener("load", listener, true);
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
|
@ -31,7 +31,7 @@ function test() {
|
|||
|
||||
content.location =
|
||||
"data:text/html," +
|
||||
"<style type='text/css'>#test-image,#not-test-image {background-image: url('about:logo?c');}</style>" +
|
||||
"<style type='text/css'>%23test-image,%23not-test-image {background-image: url('about:logo?c');}</style>" +
|
||||
"<img src='about:logo?b' height=300 width=350 alt=2 id='not-test-image'>" +
|
||||
"<img src='about:logo?b' height=300 width=350 alt=2>" +
|
||||
"<img src='about:logo?a' height=200 width=250>" +
|
||||
|
|
|
@ -44,6 +44,7 @@ function test() {
|
|||
// Verify that about:addons loads
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
let browser = blanktab.linkedBrowser;
|
||||
is(browser.currentURI.spec, "about:addons", "about:addons should load into blank tab.");
|
||||
gBrowser.removeTab(blanktab);
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedBrowser.addEventListener("load", function () {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
|
||||
content.history.pushState({}, "2", "2.html");
|
||||
|
||||
testBackButton();
|
||||
}, true);
|
||||
|
||||
loadURI("http://example.com");
|
||||
}
|
||||
|
||||
function testBackButton() {
|
||||
var backButton = document.getElementById("back-button");
|
||||
var rect = backButton.getBoundingClientRect();
|
||||
|
||||
info("waiting for the history menu to open");
|
||||
|
||||
backButton.addEventListener("popupshown", function (event) {
|
||||
backButton.removeEventListener("popupshown", arguments.callee, false);
|
||||
|
||||
ok(true, "history menu opened");
|
||||
event.target.hidePopup();
|
||||
finish();
|
||||
}, false);
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(backButton, {type: "mousedown"});
|
||||
EventUtils.synthesizeMouse(backButton, rect.width / 2, rect.height, {type: "mouseup"});
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
// Bug 655584 - awesomebar suggestions don't update after tab is closed
|
||||
|
||||
function test() {
|
||||
var tab1 = gBrowser.addTab();
|
||||
var tab2 = gBrowser.addTab();
|
||||
|
||||
// When urlbar in a new tab is focused, and a tab switch occurs,
|
||||
// the urlbar popup should be closed
|
||||
gBrowser.selectedTab = tab2;
|
||||
gURLBar.focus(); // focus the urlbar in the tab we will switch to
|
||||
gBrowser.selectedTab = tab1;
|
||||
gURLBar.openPopup();
|
||||
gBrowser.selectedTab = tab2;
|
||||
ok(!gURLBar.popupOpen, "urlbar focused in tab to switch to, close popup");
|
||||
|
||||
// cleanup
|
||||
gBrowser.removeCurrentTab();
|
||||
gBrowser.removeCurrentTab();
|
||||
}
|
|
@ -11,9 +11,10 @@ function getPostDataString(aIS) {
|
|||
return dataLines[dataLines.length-1];
|
||||
}
|
||||
|
||||
function keywordResult(aURL, aPostData) {
|
||||
function keywordResult(aURL, aPostData, aIsUnsafe) {
|
||||
this.url = aURL;
|
||||
this.postData = aPostData;
|
||||
this.isUnsafe = aIsUnsafe;
|
||||
}
|
||||
|
||||
function keyWordData() {}
|
||||
|
@ -52,20 +53,20 @@ var testData = [
|
|||
new keywordResult("http://bmget-nosearch/", null)],
|
||||
|
||||
[new searchKeywordData("searchget", "http://searchget/?search={searchTerms}", null, "foo4"),
|
||||
new keywordResult("http://searchget/?search=foo4", null)],
|
||||
new keywordResult("http://searchget/?search=foo4", null, true)],
|
||||
|
||||
[new searchKeywordData("searchpost", "http://searchpost/", "search={searchTerms}", "foo5"),
|
||||
new keywordResult("http://searchpost/", "search=foo5")],
|
||||
new keywordResult("http://searchpost/", "search=foo5", true)],
|
||||
|
||||
[new searchKeywordData("searchpostget", "http://searchpostget/?search1={searchTerms}", "search2={searchTerms}", "foo6"),
|
||||
new keywordResult("http://searchpostget/?search1=foo6", "search2=foo6")],
|
||||
new keywordResult("http://searchpostget/?search1=foo6", "search2=foo6", true)],
|
||||
|
||||
// Bookmark keywords that don't take parameters should not be activated if a
|
||||
// parameter is passed (bug 420328).
|
||||
[new bmKeywordData("bmget-noparam", "http://bmget-noparam/", null, "foo7"),
|
||||
new keywordResult(null, null)],
|
||||
new keywordResult(null, null, true)],
|
||||
[new bmKeywordData("bmpost-noparam", "http://bmpost-noparam/", "not_a=param", "foo8"),
|
||||
new keywordResult(null, null)],
|
||||
new keywordResult(null, null, true)],
|
||||
|
||||
// Test escaping (%s = escaped, %S = raw)
|
||||
// UTF-8 default
|
||||
|
@ -82,6 +83,12 @@ var testData = [
|
|||
// Explicitly-defined ISO-8859-1
|
||||
[new bmKeywordData("bmget-escaping2", "http://bmget/?esc=%s&raw=%S&mozcharset=ISO-8859-1", null, "+/@"),
|
||||
new keywordResult("http://bmget/?esc=%2B%2F%40&raw=+/@", null)],
|
||||
|
||||
// Test using a non-bmKeywordData object, to test the behavior of
|
||||
// getShortcutOrURI for non-keywords (setupKeywords only adds keywords for
|
||||
// bmKeywordData objects)
|
||||
[{keyword: "http://gavinsharp.com"},
|
||||
new keywordResult(null, null, true)]
|
||||
];
|
||||
|
||||
function test() {
|
||||
|
@ -94,12 +101,14 @@ function test() {
|
|||
var query = data.keyword;
|
||||
if (data.searchWord)
|
||||
query += " " + data.searchWord;
|
||||
var url = getShortcutOrURI(query, postData);
|
||||
var mayInheritPrincipal = {};
|
||||
var url = getShortcutOrURI(query, postData, mayInheritPrincipal);
|
||||
|
||||
// null result.url means we should expect the same query we sent in
|
||||
var expected = result.url || query;
|
||||
is(url, expected, "got correct URL for " + data.keyword);
|
||||
is(getPostDataString(postData.value), result.postData, "got correct postData for " + data.keyword);
|
||||
is(mayInheritPrincipal.value, !result.isUnsafe, "got correct mayInheritPrincipal for " + data.keyword);
|
||||
}
|
||||
|
||||
cleanupKeywords();
|
||||
|
|
|
@ -0,0 +1,113 @@
|
|||
/* Tests for correct behaviour of getEffectiveHost on identity handler */
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
ok(gIdentityHandler, "gIdentityHandler should exist");
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", checkResult, true);
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
// Greek IDN for 'example.test'.
|
||||
var idnDomain = "\u03C0\u03B1\u03C1\u03AC\u03B4\u03B5\u03B9\u03B3\u03BC\u03B1.\u03B4\u03BF\u03BA\u03B9\u03BC\u03AE";
|
||||
var tests = [
|
||||
{
|
||||
name: "normal domain",
|
||||
location: "http://test1.example.org/",
|
||||
host: "test1.example.org",
|
||||
effectiveHost: "example.org"
|
||||
},
|
||||
{
|
||||
name: "view-source",
|
||||
location: "view-source:http://example.com/",
|
||||
// TODO: these should not be blank, bug 646690
|
||||
host: "",
|
||||
effectiveHost: ""
|
||||
},
|
||||
{
|
||||
name: "normal HTTPS",
|
||||
location: "https://example.com/",
|
||||
host: "example.com",
|
||||
effectiveHost: "example.com",
|
||||
isHTTPS: true
|
||||
},
|
||||
{
|
||||
name: "IDN subdomain",
|
||||
location: "http://sub1." + idnDomain + "/",
|
||||
host: "sub1." + idnDomain,
|
||||
effectiveHost: idnDomain
|
||||
},
|
||||
{
|
||||
name: "subdomain with port",
|
||||
location: "http://sub1.test1.example.org:8000/",
|
||||
host: "sub1.test1.example.org:8000",
|
||||
effectiveHost: "example.org"
|
||||
},
|
||||
{
|
||||
name: "subdomain HTTPS",
|
||||
location: "https://test1.example.com",
|
||||
host: "test1.example.com",
|
||||
effectiveHost: "example.com",
|
||||
isHTTPS: true
|
||||
},
|
||||
{
|
||||
name: "view-source HTTPS",
|
||||
location: "view-source:https://example.com/",
|
||||
// TODO: these should not be blank, bug 646690
|
||||
host: "",
|
||||
effectiveHost: "",
|
||||
isHTTPS: true
|
||||
},
|
||||
{
|
||||
name: "IP address",
|
||||
location: "http://127.0.0.1:8888/",
|
||||
host: "127.0.0.1:8888",
|
||||
effectiveHost: "127.0.0.1"
|
||||
},
|
||||
]
|
||||
|
||||
let gCurrentTest, gCurrentTestIndex = -1;
|
||||
// Go through the tests in both directions, to add additional coverage for
|
||||
// transitions between different states.
|
||||
let gForward = true;
|
||||
function nextTest() {
|
||||
if (gForward)
|
||||
gCurrentTestIndex++;
|
||||
else
|
||||
gCurrentTestIndex--;
|
||||
|
||||
if (gCurrentTestIndex == tests.length) {
|
||||
// Went too far, reverse
|
||||
gCurrentTestIndex--;
|
||||
gForward = false;
|
||||
}
|
||||
|
||||
if (gCurrentTestIndex == -1) {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", checkResult, true);
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
gCurrentTest = tests[gCurrentTestIndex];
|
||||
gTestDesc = "#" + gCurrentTestIndex + " (" + gCurrentTest.name + ")";
|
||||
if (!gForward)
|
||||
gTestDesc += " (second time)";
|
||||
content.location = gCurrentTest.location;
|
||||
}
|
||||
|
||||
function checkResult() {
|
||||
if (gCurrentTest.isHTTPS) {
|
||||
// Check that the effective host is displayed in the UI
|
||||
let label = document.getElementById("identity-icon-label");
|
||||
is(label.value, gCurrentTest.effectiveHost, "effective host is displayed in identity icon label for test " + gTestDesc);
|
||||
}
|
||||
|
||||
// Sanity check other values, and the value of gIdentityHandler.getEffectiveHost()
|
||||
is(gIdentityHandler._lastLocation.host, gCurrentTest.host, "host matches for test " + gTestDesc);
|
||||
is(gIdentityHandler.getEffectiveHost(), gCurrentTest.effectiveHost, "effectiveHost matches for test " + gTestDesc);
|
||||
|
||||
executeSoon(nextTest);
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let bmFolder = Application.bookmarks.menu.addFolder("keyword-test");
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
|
||||
registerCleanupFunction (function () {
|
||||
bmFolder.remove();
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
|
||||
let bm = bmFolder.addBookmark("bookmarklet", makeURI("javascript:1;"));
|
||||
bm.keyword = "bm";
|
||||
|
||||
addPageShowListener(function () {
|
||||
let originalPrincipal = gBrowser.contentPrincipal;
|
||||
|
||||
// Enter bookmarklet keyword in the URL bar
|
||||
gURLBar.value = "bm";
|
||||
gURLBar.focus();
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
|
||||
addPageShowListener(function () {
|
||||
ok(gBrowser.contentPrincipal.equals(originalPrincipal), "javascript bookmarklet should inherit principal");
|
||||
finish();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function addPageShowListener(func) {
|
||||
gBrowser.selectedBrowser.addEventListener("pageshow", function loadListener() {
|
||||
gBrowser.selectedBrowser.removeEventListener("pageshow", loadListener, false);
|
||||
func();
|
||||
});
|
||||
}
|
|
@ -9,30 +9,46 @@ function test() {
|
|||
|
||||
let urls = [
|
||||
"javascript:'foopy';",
|
||||
"data:text/html,<script>document.write(document.domain);</script>"
|
||||
"data:text/html,<body>hi"
|
||||
];
|
||||
|
||||
function urlEnter(url) {
|
||||
gURLBar.value = url;
|
||||
gURLBar.focus();
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
}
|
||||
|
||||
function urlClick(url) {
|
||||
gURLBar.value = url;
|
||||
gURLBar.focus();
|
||||
let goButton = document.getElementById("urlbar-go-button");
|
||||
EventUtils.synthesizeMouseAtCenter(goButton, {});
|
||||
}
|
||||
|
||||
function nextTest() {
|
||||
let url = urls.shift();
|
||||
if (url)
|
||||
testURL(url, nextTest);
|
||||
if (url) {
|
||||
testURL(url, urlEnter, function () {
|
||||
testURL(url, urlClick, nextTest);
|
||||
});
|
||||
}
|
||||
else
|
||||
finish();
|
||||
}
|
||||
|
||||
function testURL(newURL, func) {
|
||||
function testURL(url, loadFunc, endFunc) {
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
registerCleanupFunction(function () {
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
addPageShowListener(function () {
|
||||
let pagePrincipal = gBrowser.contentPrincipal;
|
||||
gURLBar.value = newURL;
|
||||
gURLBar.handleCommand();
|
||||
loadFunc(url);
|
||||
|
||||
addPageShowListener(function () {
|
||||
ok(!gBrowser.contentPrincipal.equals(pagePrincipal), "load of " + newURL + " produced a page with a different principal");
|
||||
func();
|
||||
ok(!gBrowser.contentPrincipal.equals(pagePrincipal),
|
||||
"load of " + url + " by " + loadFunc.name + " should produce a page with a different principal");
|
||||
endFunc();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -54,6 +54,9 @@ function test() {
|
|||
|
||||
testVal("<http://sub.>mozilla.org<:666/file.ext>");
|
||||
|
||||
testVal("<http://>[fe80::222:19ff:fe11:8c76]</file.ext>");
|
||||
testVal("<http://user:pass@>[fe80::222:19ff:fe11:8c76]<:666/file.ext>");
|
||||
|
||||
testVal("mailto:admin@mozilla.org");
|
||||
testVal("gopher://mozilla.org/");
|
||||
testVal("about:config");
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function menuTest()
|
||||
{
|
||||
gBrowser.selectedBrowser.removeEventListener("load", menuTest, true);
|
||||
|
||||
let menuContents = [
|
||||
"menu_pageinspect",
|
||||
"webConsole",
|
||||
"menu_scratchpad",
|
||||
"menu_pageSource",
|
||||
"javascriptConsole"
|
||||
];
|
||||
|
||||
let menu = document.getElementById("webDeveloperMenu");
|
||||
ok(menu, "we have the menu");
|
||||
|
||||
let popup = menu.firstChild;
|
||||
is(popup.id, "menuWebDeveloperPopup", "menu first child is menuWebDeveloperPopup");
|
||||
|
||||
is(popup.childNodes.length, menuContents.length, "popup childNodes.length matches");
|
||||
|
||||
for(let a = 0; a < popup.children.length; a++) {
|
||||
isnot(menuContents.indexOf(popup.children[a].id), -1, "menuitem " + popup.children[a].id + " in popup");
|
||||
};
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", menuTest, true);
|
||||
|
||||
content.location = "data:text/html,<title>Web Developer Menu Test</title>" +
|
||||
"<p>testing the Web Developer Menu";
|
||||
}
|
||||
|
|
@ -18,12 +18,27 @@ function test() {
|
|||
waitForExplicitFinish();
|
||||
|
||||
ok(gFindBar.hidden, "Find bar should not be visible");
|
||||
|
||||
run_test_1();
|
||||
nextTest();
|
||||
}
|
||||
|
||||
function run_test_1() {
|
||||
load("about:config", function() {
|
||||
let urls = [
|
||||
"about:config",
|
||||
"about:addons",
|
||||
"about:permissions"
|
||||
];
|
||||
|
||||
function nextTest() {
|
||||
let url = urls.shift();
|
||||
if (url) {
|
||||
testFindDisabled(url, nextTest);
|
||||
} else {
|
||||
// Make sure the find bar is re-enabled after disabled page is closed.
|
||||
testFindEnabled("about:blank", finish);
|
||||
}
|
||||
}
|
||||
|
||||
function testFindDisabled(url, cb) {
|
||||
load(url, function() {
|
||||
ok(gFindBar.hidden, "Find bar should not be visible");
|
||||
EventUtils.synthesizeKey("/", {}, gTab.linkedBrowser.contentWindow);
|
||||
ok(gFindBar.hidden, "Find bar should not be visible");
|
||||
|
@ -33,31 +48,16 @@ function run_test_1() {
|
|||
"Find command should be disabled");
|
||||
|
||||
gBrowser.removeTab(gTab);
|
||||
run_test_2();
|
||||
cb();
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_2() {
|
||||
load("about:addons", function() {
|
||||
ok(gFindBar.hidden, "Find bar should not be visible");
|
||||
EventUtils.synthesizeKey("/", {}, gTab.linkedBrowser.contentWindow);
|
||||
ok(gFindBar.hidden, "Find bar should not be visible");
|
||||
EventUtils.synthesizeKey("f", { accelKey: true });
|
||||
ok(gFindBar.hidden, "Find bar should not be visible");
|
||||
ok(document.getElementById("cmd_find").getAttribute("disabled"),
|
||||
"Find command should be disabled");
|
||||
|
||||
gBrowser.removeTab(gTab);
|
||||
run_test_3();
|
||||
});
|
||||
}
|
||||
|
||||
function run_test_3() {
|
||||
load("about:blank", function() {
|
||||
function testFindEnabled(url, cb) {
|
||||
load(url, function() {
|
||||
ok(!document.getElementById("cmd_find").getAttribute("disabled"),
|
||||
"Find command should not be disabled");
|
||||
|
||||
gBrowser.removeTab(gTab);
|
||||
finish();
|
||||
cb();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,8 +113,10 @@ _BROWSER_FILES = \
|
|||
browser_tabview_bug626368.js \
|
||||
browser_tabview_bug626525.js \
|
||||
browser_tabview_bug626791.js \
|
||||
browser_tabview_bug627239.js \
|
||||
browser_tabview_bug627288.js \
|
||||
browser_tabview_bug627736.js \
|
||||
browser_tabview_bug628061.js \
|
||||
browser_tabview_bug628165.js \
|
||||
browser_tabview_bug628270.js \
|
||||
browser_tabview_bug629189.js \
|
||||
|
|
|
@ -15,12 +15,12 @@ function test() {
|
|||
}
|
||||
|
||||
// very long page that produces black bars at the right
|
||||
let html1 = '<html><body style="background-color: #00f;">' +
|
||||
'<div style="background: #fff; width: 95%; height: 10000px; ' +
|
||||
let html1 = '<html><body style="background-color: %2300f;">' +
|
||||
'<div style="background: %23fff; width: 95%; height: 10000px; ' +
|
||||
' margin: 0 auto;"></div></body></html>';
|
||||
|
||||
// very short page that produces black bars at the bottom
|
||||
let html2 = '<html><body style="background-color: #00f;"></body></html>';
|
||||
let html2 = '<html><body style="background-color: %2300f;"></body></html>';
|
||||
|
||||
let tests = [{
|
||||
url: 'data:text/html,' + html1,
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const fi = Cc["@mozilla.org/browser/favicon-service;1"].
|
||||
getService(Ci.nsIFaviconService);
|
||||
|
||||
let newTab;
|
||||
|
||||
function test() {
|
||||
|
@ -27,7 +30,7 @@ function onTabViewWindowLoaded() {
|
|||
is($icon.data("xulTab"), newTab,
|
||||
"The app tab icon has the right tab reference")
|
||||
// check to see whether it's showing the default one or not.
|
||||
is($icon.attr("src"), contentWindow.Utils.defaultFaviconURL,
|
||||
is($icon.attr("src"), fi.defaultFavicon.spec,
|
||||
"The icon is showing the default fav icon for blank tab");
|
||||
|
||||
let errorHandler = function(event) {
|
||||
|
@ -37,7 +40,7 @@ function onTabViewWindowLoaded() {
|
|||
// fired, a delay is used here to avoid the test code run before the browser
|
||||
// code.
|
||||
executeSoon(function() {
|
||||
is($icon.attr("src"), contentWindow.Utils.defaultFaviconURL,
|
||||
is($icon.attr("src"), fi.defaultFavicon.spec,
|
||||
"The icon is showing the default fav icon");
|
||||
|
||||
// clean up
|
||||
|
|
|
@ -2,8 +2,9 @@
|
|||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
let url = "http://non.existant/url";
|
||||
let url = "http://www.example.com/";
|
||||
let cw;
|
||||
let tab = gBrowser.tabs[0];
|
||||
|
||||
let finishTest = function () {
|
||||
is(1, gBrowser.tabs.length, "there is one tab, only");
|
||||
|
@ -14,7 +15,7 @@ function test() {
|
|||
waitForExplicitFinish();
|
||||
|
||||
let testErroneousLoading = function () {
|
||||
cw.Storage.loadThumbnail(url, function (status, data) {
|
||||
cw.ThumbnailStorage.loadThumbnail(tab, url, function (status, data) {
|
||||
ok(!status, "thumbnail entry failed to load");
|
||||
is(null, data, "no thumbnail data received");
|
||||
next();
|
||||
|
@ -25,11 +26,11 @@ function test() {
|
|||
let saved = false;
|
||||
let data = "thumbnail-data-asynchronous";
|
||||
|
||||
cw.Storage.saveThumbnail(url, data, function (status) {
|
||||
cw.ThumbnailStorage.saveThumbnail(tab, data, function (status) {
|
||||
ok(status, "thumbnail entry was saved");
|
||||
ok(saved, "thumbnail was saved asynchronously");
|
||||
|
||||
cw.Storage.loadThumbnail(url, function (status, imageData) {
|
||||
cw.ThumbnailStorage.loadThumbnail(tab, url, function (status, imageData) {
|
||||
ok(status, "thumbnail entry was loaded");
|
||||
is(imageData, data, "valid thumbnail data received");
|
||||
next();
|
||||
|
@ -46,11 +47,11 @@ function test() {
|
|||
cw.UI.isDOMWindowClosing = true;
|
||||
registerCleanupFunction(function () cw.UI.isDOMWindowClosing = false);
|
||||
|
||||
cw.Storage.saveThumbnail(url, data, function (status) {
|
||||
cw.ThumbnailStorage.saveThumbnail(tab, data, function (status) {
|
||||
ok(status, "thumbnail entry was saved");
|
||||
ok(!saved, "thumbnail was saved synchronously");
|
||||
|
||||
cw.Storage.loadThumbnail(url, function (status, imageData) {
|
||||
cw.ThumbnailStorage.loadThumbnail(tab, url, function (status, imageData) {
|
||||
ok(status, "thumbnail entry was loaded");
|
||||
is(imageData, data, "valid thumbnail data received");
|
||||
|
||||
|
@ -72,10 +73,13 @@ function test() {
|
|||
hideTabView(finishTest);
|
||||
}
|
||||
|
||||
showTabView(function () {
|
||||
registerCleanupFunction(function () TabView.hide());
|
||||
cw = TabView.getContentWindow();
|
||||
tab.linkedBrowser.loadURI(url);
|
||||
afterAllTabsLoaded(function() {
|
||||
showTabView(function () {
|
||||
registerCleanupFunction(function () TabView.hide());
|
||||
cw = TabView.getContentWindow();
|
||||
|
||||
next();
|
||||
next();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -19,15 +19,6 @@ function test() {
|
|||
is(gBrowser.visibleTabs.length, numTabs, 'There should be ' + numTabs + ' visible tabs');
|
||||
}
|
||||
|
||||
let restoreTab = function (callback) {
|
||||
let tab = undoCloseTab(0);
|
||||
|
||||
tab._tabViewTabItem.addSubscriber(tab, 'reconnected', function () {
|
||||
tab._tabViewTabItem.removeSubscriber(tab, 'reconnected');
|
||||
afterAllTabsLoaded(callback);
|
||||
});
|
||||
}
|
||||
|
||||
let next = function () {
|
||||
while (gBrowser.tabs.length-1)
|
||||
gBrowser.removeTab(gBrowser.tabs[1]);
|
||||
|
@ -86,7 +77,7 @@ function test() {
|
|||
let tab = gBrowser.loadOneTab('http://mochi.test:8888/#1', {inBackground: true});
|
||||
gBrowser.selectedTab = tab;
|
||||
|
||||
let continueTest = function () {
|
||||
afterAllTabsLoaded(function () {
|
||||
tab.linkedBrowser.loadURI('http://mochi.test:8888/#2');
|
||||
|
||||
afterAllTabsLoaded(function () {
|
||||
|
@ -106,13 +97,7 @@ function test() {
|
|||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// The executeSoon() call is really needed here because there's probably
|
||||
// some callback waiting to be fired after gBrowser.loadOneTab(). After
|
||||
// that the browser is in a state where loadURI() will create a new entry
|
||||
// in the session history (that is vital for back/forward functionality).
|
||||
afterAllTabsLoaded(function () executeSoon(continueTest));
|
||||
});
|
||||
}
|
||||
|
||||
// ----------
|
||||
|
@ -156,45 +141,30 @@ function test() {
|
|||
|
||||
// ----------
|
||||
function loadTabView(callback) {
|
||||
window.addEventListener('tabviewshown', function () {
|
||||
window.removeEventListener('tabviewshown', arguments.callee, false);
|
||||
|
||||
hideTabView(function () {
|
||||
window.removeEventListener('tabviewhidden', arguments.callee, false);
|
||||
callback();
|
||||
});
|
||||
}, false);
|
||||
|
||||
TabView.show();
|
||||
}
|
||||
|
||||
// ----------
|
||||
function hideTabView(callback) {
|
||||
if (!TabView.isVisible())
|
||||
return callback();
|
||||
|
||||
window.addEventListener('tabviewhidden', function () {
|
||||
window.removeEventListener('tabviewhidden', arguments.callee, false);
|
||||
callback();
|
||||
}, false);
|
||||
|
||||
TabView.hide();
|
||||
showTabView(function () {
|
||||
hideTabView(callback);
|
||||
});
|
||||
}
|
||||
|
||||
// ----------
|
||||
function enterAndLeavePrivateBrowsing(callback) {
|
||||
togglePrivateBrowsing(function () {
|
||||
togglePrivateBrowsing(callback);
|
||||
});
|
||||
}
|
||||
|
||||
// ----------
|
||||
function togglePrivateBrowsing(callback) {
|
||||
let topic = "private-browsing-transition-complete";
|
||||
|
||||
function pbObserver(aSubject, aTopic, aData) {
|
||||
if (aTopic != "private-browsing-transition-complete")
|
||||
if (aTopic != topic)
|
||||
return;
|
||||
|
||||
if (pb.privateBrowsingEnabled)
|
||||
pb.privateBrowsingEnabled = false;
|
||||
else {
|
||||
Services.obs.removeObserver(pbObserver, "private-browsing-transition-complete");
|
||||
afterAllTabsLoaded(function () executeSoon(callback));
|
||||
}
|
||||
Services.obs.removeObserver(pbObserver, topic, false);
|
||||
afterAllTabsLoaded(callback);
|
||||
}
|
||||
|
||||
Services.obs.addObserver(pbObserver, "private-browsing-transition-complete", false);
|
||||
pb.privateBrowsingEnabled = true;
|
||||
Services.obs.addObserver(pbObserver, topic, false);
|
||||
pb.privateBrowsingEnabled = !pb.privateBrowsingEnabled;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
let contentWindow;
|
||||
let enablePersistentHttpsCaching;
|
||||
let newTab;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
newTab = gBrowser.addTab();
|
||||
|
||||
HttpRequestObserver.register();
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
HttpRequestObserver.unregister();
|
||||
if (gBrowser.tabs[1])
|
||||
gBrowser.removeTab(gBrowser.tabs[1]);
|
||||
hideTabView(function () {});
|
||||
|
||||
contentWindow.ThumbnailStorage.enablePersistentHttpsCaching =
|
||||
enablePersistentHttpsCaching;
|
||||
});
|
||||
|
||||
showTabView(function() {
|
||||
contentWindow = TabView.getContentWindow();
|
||||
test1();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function test1() {
|
||||
// page with cache-control: no-store, should not save thumbnail
|
||||
HttpRequestObserver.cacheControlValue = "no-store";
|
||||
newTab.linkedBrowser.loadURI("http://www.example.com/browser/browser/base/content/test/tabview/dummy_page.html");
|
||||
|
||||
afterAllTabsLoaded(function() {
|
||||
let tabItem = newTab._tabViewTabItem;
|
||||
|
||||
ok(!contentWindow.ThumbnailStorage._shouldSaveThumbnail(newTab),
|
||||
"Should not save the thumbnail for tab");
|
||||
|
||||
tabItem.addSubscriber(tabItem, "deniedToCacheImageData", function() {
|
||||
tabItem.removeSubscriber(tabItem, "deniedToCacheImageData");
|
||||
test2();
|
||||
});
|
||||
tabItem.save(true);
|
||||
HttpRequestObserver.cacheControlValue = null;
|
||||
});
|
||||
}
|
||||
|
||||
function test2() {
|
||||
// page with cache-control: private, should save thumbnail
|
||||
HttpRequestObserver.cacheControlValue = "private";
|
||||
|
||||
newTab.linkedBrowser.loadURI("http://www.example.com/");
|
||||
afterAllTabsLoaded(function() {
|
||||
let tabItem = newTab._tabViewTabItem;
|
||||
|
||||
ok(contentWindow.ThumbnailStorage._shouldSaveThumbnail(newTab),
|
||||
"Should save the thumbnail for tab");
|
||||
|
||||
tabItem.addSubscriber(tabItem, "savedCachedImageData", function() {
|
||||
tabItem.removeSubscriber(tabItem, "savedCachedImageData");
|
||||
test3();
|
||||
});
|
||||
tabItem.save(true);
|
||||
});
|
||||
}
|
||||
|
||||
function test3() {
|
||||
// page with cache-control: private with https caching enabled, should save thumbnail
|
||||
HttpRequestObserver.cacheControlValue = "private";
|
||||
|
||||
enablePersistentHttpsCaching =
|
||||
contentWindow.ThumbnailStorage.enablePersistentHttpsCaching;
|
||||
contentWindow.ThumbnailStorage.enablePersistentHttpsCaching = true;
|
||||
|
||||
newTab.linkedBrowser.loadURI("https://example.com/browser/browser/base/content/test/tabview/dummy_page.html");
|
||||
afterAllTabsLoaded(function() {
|
||||
let tabItem = newTab._tabViewTabItem;
|
||||
|
||||
ok(contentWindow.ThumbnailStorage._shouldSaveThumbnail(newTab),
|
||||
"Should save the thumbnail for tab");
|
||||
|
||||
tabItem.addSubscriber(tabItem, "savedCachedImageData", function() {
|
||||
tabItem.removeSubscriber(tabItem, "savedCachedImageData");
|
||||
|
||||
test4();
|
||||
});
|
||||
tabItem.save(true);
|
||||
});
|
||||
}
|
||||
|
||||
function test4() {
|
||||
// page with cache-control: public with https caching disabled, should save thumbnail
|
||||
HttpRequestObserver.cacheControlValue = "public";
|
||||
|
||||
contentWindow.ThumbnailStorage.enablePersistentHttpsCaching = false;
|
||||
|
||||
newTab.linkedBrowser.loadURI("https://example.com/browser/browser/base/content/test/tabview/");
|
||||
afterAllTabsLoaded(function() {
|
||||
let tabItem = newTab._tabViewTabItem;
|
||||
|
||||
ok(contentWindow.ThumbnailStorage._shouldSaveThumbnail(newTab),
|
||||
"Should save the thumbnail for tab");
|
||||
|
||||
tabItem.addSubscriber(tabItem, "savedCachedImageData", function() {
|
||||
tabItem.removeSubscriber(tabItem, "savedCachedImageData");
|
||||
|
||||
test5();
|
||||
});
|
||||
tabItem.save(true);
|
||||
});
|
||||
}
|
||||
|
||||
function test5() {
|
||||
// page with cache-control: private with https caching disabled, should not save thumbnail
|
||||
HttpRequestObserver.cacheControlValue = "private";
|
||||
|
||||
newTab.linkedBrowser.loadURI("https://example.com/");
|
||||
afterAllTabsLoaded(function() {
|
||||
let tabItem = newTab._tabViewTabItem;
|
||||
|
||||
ok(!contentWindow.ThumbnailStorage._shouldSaveThumbnail(newTab),
|
||||
"Should not the thumbnail for tab");
|
||||
|
||||
tabItem.addSubscriber(tabItem, "deniedToCacheImageData", function() {
|
||||
tabItem.removeSubscriber(tabItem, "deniedToCacheImageData");
|
||||
|
||||
hideTabView(function () {
|
||||
gBrowser.removeTab(gBrowser.tabs[1]);
|
||||
finish();
|
||||
});
|
||||
});
|
||||
tabItem.save(true);
|
||||
});
|
||||
}
|
||||
|
||||
let HttpRequestObserver = {
|
||||
cacheControlValue: null,
|
||||
|
||||
observe: function(subject, topic, data) {
|
||||
if (topic == "http-on-examine-response" && this.cacheControlValue) {
|
||||
let httpChannel = subject.QueryInterface(Ci.nsIHttpChannel);
|
||||
httpChannel.setResponseHeader("Cache-Control", this.cacheControlValue, false);
|
||||
}
|
||||
},
|
||||
|
||||
register: function() {
|
||||
Services.obs.addObserver(this, "http-on-examine-response", false);
|
||||
},
|
||||
|
||||
unregister: function() {
|
||||
Services.obs.removeObserver(this, "http-on-examine-response");
|
||||
}
|
||||
};
|
|
@ -0,0 +1,37 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||
|
||||
let state = {
|
||||
windows: [{
|
||||
tabs: [{
|
||||
entries: [{ url: "about:blank" }],
|
||||
hidden: true,
|
||||
extData: {"tabview-tab": '{"url":"about:blank","groupID":1,"bounds":{"left":20,"top":20,"width":20,"height":20}}'}
|
||||
},{
|
||||
entries: [{ url: "about:blank" }],
|
||||
hidden: false,
|
||||
extData: {"tabview-tab": '{"url":"about:blank","groupID":2,"bounds":{"left":20,"top":20,"width":20,"height":20}}'},
|
||||
}],
|
||||
selected: 2,
|
||||
extData: {
|
||||
"tabview-groups": '{"nextID":3,"activeGroupId":2, "totalNumber":2}',
|
||||
"tabview-group":
|
||||
'{"1":{"bounds":{"left":15,"top":5,"width":280,"height":232},"id":1},' +
|
||||
'"2":{"bounds":{"left":309,"top":5,"width":267,"height":226},"id":2}}'
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
newWindowWithState(state, function(win) {
|
||||
registerCleanupFunction(function() win.close());
|
||||
|
||||
is(win.document.getElementById("tabviewGroupsNumber").getAttribute("groups"),
|
||||
"2", "There are two groups");
|
||||
waitForFocus(finish);
|
||||
});
|
||||
}
|
|
@ -7,17 +7,18 @@ var prefsBranch = Cc["@mozilla.org/preferences-service;1"].
|
|||
|
||||
function animateZoom() prefsBranch.getBoolPref("animate_zoom");
|
||||
|
||||
function registerCleanupFunction() {
|
||||
prefsBranch.setUserPref("animate_zoom", true);
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
let charsetArg = "charset=" + window.content.document.characterSet;
|
||||
let win = window.openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no",
|
||||
"about:blank", charsetArg, null, null, true);
|
||||
|
||||
|
||||
registerCleanupFunction(function() {
|
||||
prefsBranch.setBoolPref("animate_zoom", true);
|
||||
win.close();
|
||||
});
|
||||
|
||||
ok(animateZoom(), "By default, we animate on zoom.");
|
||||
prefsBranch.setBoolPref("animate_zoom", false);
|
||||
ok(!animateZoom(), "animate_zoom = false");
|
||||
|
@ -29,27 +30,24 @@ function test() {
|
|||
let tabViewWindow = null;
|
||||
let transitioned = 0;
|
||||
|
||||
let onShown = function() {
|
||||
win.removeEventListener("tabviewshown", onShown, false);
|
||||
|
||||
ok(!transitioned, "There should be no transitions");
|
||||
win.close();
|
||||
|
||||
finish();
|
||||
};
|
||||
|
||||
let initCallback = function() {
|
||||
tabViewWindow = win.TabView._window;
|
||||
function onTransitionEnd(event) {
|
||||
transitioned++;
|
||||
tabViewWindow.Utils.log(transitioned);
|
||||
info(transitioned);
|
||||
}
|
||||
tabViewWindow.document.addEventListener("transitionend", onTransitionEnd, false);
|
||||
|
||||
win.TabView.show();
|
||||
showTabView(function() {
|
||||
ok(!transitioned, "There should be no transitions");
|
||||
|
||||
tabViewWindow.document.removeEventListener(
|
||||
"transitionend", onTransitionEnd, false);
|
||||
|
||||
finish();
|
||||
}, win);
|
||||
};
|
||||
|
||||
win.addEventListener("tabviewshown", onShown, false);
|
||||
win.TabView._initFrame(initCallback);
|
||||
}
|
||||
win.addEventListener("load", onLoad, false);
|
||||
|
|
|
@ -31,7 +31,9 @@ function onTabViewWindowLoaded() {
|
|||
|
||||
is(groupItem.getChildren().length, 1, "The new group has a tab item");
|
||||
// start the tests
|
||||
testUndoGroup(contentWindow, groupItem);
|
||||
waitForFocus(function() {
|
||||
testUndoGroup(contentWindow, groupItem);
|
||||
}, contentWindow);
|
||||
};
|
||||
window.addEventListener("tabviewhidden", onTabViewHidden, false);
|
||||
window.addEventListener("tabviewshown", onTabViewShown, false);
|
||||
|
@ -80,7 +82,7 @@ function testUndoGroup(contentWindow, groupItem) {
|
|||
});
|
||||
|
||||
let closeButton = groupItem.container.getElementsByClassName("close");
|
||||
ok(closeButton, "Group item close button exists");
|
||||
ok(closeButton[0], "Group item close button exists");
|
||||
EventUtils.sendMouseEvent({ type: "click" }, closeButton[0], contentWindow);
|
||||
}
|
||||
|
||||
|
@ -129,6 +131,6 @@ function testCloseUndoGroup(contentWindow, groupItem) {
|
|||
});
|
||||
|
||||
let closeButton = groupItem.container.getElementsByClassName("close");
|
||||
ok(closeButton, "Group item close button exists");
|
||||
ok(closeButton[0], "Group item close button exists");
|
||||
EventUtils.sendMouseEvent({ type: "click" }, closeButton[0], contentWindow);
|
||||
}
|
||||
|
|
|
@ -105,7 +105,7 @@ function afterAllTabsLoaded(callback, win) {
|
|||
this.removeEventListener("load", onLoad, true);
|
||||
stillToLoad--;
|
||||
if (!stillToLoad)
|
||||
callback();
|
||||
executeSoon(callback);
|
||||
}
|
||||
|
||||
for (let a = 0; a < win.gBrowser.tabs.length; a++) {
|
||||
|
@ -301,3 +301,21 @@ function newWindowWithState(state, callback) {
|
|||
afterAllTabsLoaded(function () callback(win), win);
|
||||
});
|
||||
}
|
||||
|
||||
// ----------
|
||||
function restoreTab(callback, index, win) {
|
||||
win = win || window;
|
||||
|
||||
let tab = win.undoCloseTab(index || 0);
|
||||
let tabItem = tab._tabViewTabItem;
|
||||
|
||||
if (tabItem._reconnected) {
|
||||
afterAllTabsLoaded(callback, win);
|
||||
return;
|
||||
}
|
||||
|
||||
tab._tabViewTabItem.addSubscriber(tab, "reconnected", function onReconnected() {
|
||||
tab._tabViewTabItem.removeSubscriber(tab, "reconnected");
|
||||
afterAllTabsLoaded(callback, win);
|
||||
});
|
||||
}
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче