Merge mozilla-central into build-system

This commit is contained in:
Kyle Huey 2011-01-26 08:56:56 -05:00
commit 974f7e890a
537 changed files with 17241 additions and 5665 deletions

View File

@ -41,9 +41,8 @@
#include "nsMaiInterfaceText.h"
#include "nsHyperTextAccessible.h"
#include "nsRoleMap.h"
#include "nsString.h"
#include "nsIPersistentProperties2.h"
AtkAttributeSet* ConvertToAtkAttributeSet(nsIPersistentProperties* aAttributes);
@ -374,14 +373,9 @@ getCharacterCountCB(AtkText *aText)
if (!accWrap)
return 0;
nsCOMPtr<nsIAccessibleText> accText;
accWrap->QueryInterface(NS_GET_IID(nsIAccessibleText),
getter_AddRefs(accText));
NS_ENSURE_TRUE(accText, 0);
PRInt32 count = 0;
nsresult rv = accText->GetCharacterCount(&count);
return (NS_FAILED(rv)) ? 0 : static_cast<gint>(count);
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(accWrap));
return textAcc->IsDefunct() ?
0 : static_cast<gint>(textAcc->CharacterCount());
}
gint

View File

@ -54,8 +54,10 @@
NotificationController::NotificationController(nsDocAccessible* aDocument,
nsIPresShell* aPresShell) :
mObservingState(eNotObservingRefresh), mDocument(aDocument),
mPresShell(aPresShell)
mPresShell(aPresShell), mTreeConstructedState(eTreeConstructionPending)
{
// Schedule initial accessible tree construction.
ScheduleProcessing();
}
NotificationController::~NotificationController()
@ -80,6 +82,8 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_BEGIN(NotificationController)
NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mDocument");
cb.NoteXPCOMChild(static_cast<nsIAccessible*>(tmp->mDocument.get()));
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_MEMBER(mHangingChildDocuments,
nsDocAccessible)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_MEMBER(mContentInsertions,
ContentInsertion)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_MEMBER(mEvents, AccEvent)
@ -99,8 +103,16 @@ NotificationController::Shutdown()
mObservingState = eNotObservingRefresh;
}
// Shutdown handling child documents.
PRInt32 childDocCount = mHangingChildDocuments.Length();
for (PRInt32 idx = childDocCount - 1; idx >= 0; idx--)
mHangingChildDocuments[idx]->Shutdown();
mHangingChildDocuments.Clear();
mDocument = nsnull;
mPresShell = nsnull;
mContentInsertions.Clear();
mNotifications.Clear();
mEvents.Clear();
@ -124,11 +136,23 @@ NotificationController::QueueEvent(AccEvent* aEvent)
ScheduleProcessing();
}
void
NotificationController::ScheduleChildDocBinding(nsDocAccessible* aDocument)
{
// Schedule child document binding to the tree.
mHangingChildDocuments.AppendElement(aDocument);
ScheduleProcessing();
}
void
NotificationController::ScheduleContentInsertion(nsAccessible* aContainer,
nsIContent* aStartChildNode,
nsIContent* aEndChildNode)
{
// Ignore content insertions until we constructed accessible tree.
if (mTreeConstructedState == eTreeConstructionPending)
return;
nsRefPtr<ContentInsertion> insertion =
new ContentInsertion(mDocument, aContainer, aStartChildNode, aEndChildNode);
@ -177,6 +201,20 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
// insertions or generic notifications.
mObservingState = eRefreshProcessingForUpdate;
// Initial accessible tree construction.
if (mTreeConstructedState == eTreeConstructionPending) {
// If document is not bound to parent at this point then the document is not
// ready yet (process notifications later).
if (!mDocument->IsBoundToParent())
return;
mTreeConstructedState = eTreeConstructed;
mDocument->CacheChildrenInSubtree(mDocument);
NS_ASSERTION(mContentInsertions.Length() == 0,
"Pending content insertions while initial accessible tree isn't created!");
}
// Process content inserted notifications to update the tree. Process other
// notifications like DOM events and then flush event queue. If any new
// notifications are queued during this processing then they will be processed
@ -197,6 +235,36 @@ NotificationController::WillRefresh(mozilla::TimeStamp aTime)
return;
}
// Bind hanging child documents.
PRUint32 childDocCount = mHangingChildDocuments.Length();
for (PRUint32 idx = 0; idx < childDocCount; idx++) {
nsDocAccessible* childDoc = mHangingChildDocuments[idx];
nsIContent* ownerContent = mDocument->GetDocumentNode()->
FindContentForSubDocument(childDoc->GetDocumentNode());
if (ownerContent) {
nsAccessible* outerDocAcc = mDocument->GetCachedAccessible(ownerContent);
if (outerDocAcc && outerDocAcc->AppendChild(childDoc)) {
if (mDocument->AppendChildDocument(childDoc)) {
// Fire reorder event to notify new accessible document has been
// attached to the tree.
nsRefPtr<AccEvent> reorderEvent =
new AccEvent(nsIAccessibleEvent::EVENT_REORDER, outerDocAcc,
eAutoDetect, AccEvent::eCoalesceFromSameSubtree);
if (reorderEvent)
QueueEvent(reorderEvent);
continue;
}
outerDocAcc->RemoveChild(childDoc);
}
// Failed to bind the child document, destroy it.
childDoc->Shutdown();
}
}
mHangingChildDocuments.Clear();
// Process only currently queued generic notifications.
nsTArray < nsRefPtr<Notification> > notifications;
notifications.SwapElements(mNotifications);

View File

@ -126,6 +126,14 @@ public:
NS_DECL_CYCLE_COLLECTION_NATIVE_CLASS(NotificationController)
/**
* Return true when tree is constructed.
*/
inline bool IsTreeConstructed()
{
return mTreeConstructedState == eTreeConstructed;
}
/**
* Shutdown the notification controller.
*/
@ -136,6 +144,11 @@ public:
*/
void QueueEvent(AccEvent* aEvent);
/**
* Schedule binding the child document to the tree of this document.
*/
void ScheduleChildDocBinding(nsDocAccessible* aDocument);
/**
* Pend accessible tree update for content insertion.
*/
@ -256,6 +269,22 @@ private:
*/
nsIPresShell* mPresShell;
/**
* Indicate whether initial construction of the document's accessible tree
* performed or pending. When the document accessible is created then
* we construct its initial accessible tree.
*/
enum eTreeConstructedState {
eTreeConstructed,
eTreeConstructionPending
};
eTreeConstructedState mTreeConstructedState;
/**
* Child documents that needs to be bound to the tree.
*/
nsTArray<nsRefPtr<nsDocAccessible> > mHangingChildDocuments;
/**
* Storage for content inserted notification information.
*/

View File

@ -429,32 +429,20 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument *aDocument)
PRBool isRootDoc = nsCoreUtils::IsRootDocument(aDocument);
// Ensure the document container node is accessible, otherwise do not create
// document accessible.
nsAccessible *outerDocAcc = nsnull;
if (isRootDoc) {
outerDocAcc = nsAccessNode::GetApplicationAccessible();
} else {
nsIDocument* parentDoc = aDocument->GetParentDocument();
if (!parentDoc)
return nsnull;
nsIContent* ownerContent = parentDoc->FindContentForSubDocument(aDocument);
if (!ownerContent)
return nsnull;
nsDocAccessible* parentDocAcc = nsnull;
if (!isRootDoc) {
// XXXaaronl: ideally we would traverse the presshell chain. Since there's
// no easy way to do that, we cheat and use the document hierarchy.
// GetAccessible() is bad because it doesn't support our concept of multiple
// presshells per doc. It should be changed to use
// GetAccessibleInWeakShell().
outerDocAcc = GetAccService()->GetAccessible(ownerContent);
parentDocAcc = GetDocAccessible(aDocument->GetParentDocument());
NS_ASSERTION(parentDocAcc,
"Can't create an accessible for the document!");
if (!parentDocAcc)
return nsnull;
}
if (!outerDocAcc)
return nsnull;
// We only create root accessibles for the true root, otherwise create a
// doc accessible.
nsCOMPtr<nsIWeakReference> weakShell(do_GetWeakReference(presShell));
@ -466,21 +454,33 @@ nsAccDocManager::CreateDocOrRootAccessible(nsIDocument *aDocument)
if (!docAcc || !mDocAccessibleCache.Put(aDocument, docAcc))
return nsnull;
// Bind the document accessible into tree.
if (!outerDocAcc->AppendChild(docAcc)) {
mDocAccessibleCache.Remove(aDocument);
return nsnull;
}
// Initialize the document accessible. Note, Init() should be called after
// the document accessible is bound to the tree.
// Initialize the document accessible.
if (!docAcc->Init()) {
docAcc->Shutdown();
mDocAccessibleCache.Remove(aDocument);
return nsnull;
}
docAcc->SetRoleMapEntry(nsAccUtils::GetRoleMapEntry(aDocument));
// Bind the document to the tree.
if (isRootDoc) {
nsAccessible* appAcc = nsAccessNode::GetApplicationAccessible();
if (!appAcc->AppendChild(docAcc)) {
docAcc->Shutdown();
return nsnull;
}
// Fire reorder event to notify new accessible document has been attached to
// the tree.
nsRefPtr<AccEvent> reorderEvent =
new AccEvent(nsIAccessibleEvent::EVENT_REORDER, appAcc, eAutoDetect,
AccEvent::eCoalesceFromSameSubtree);
if (reorderEvent)
docAcc->FireDelayedAccessibleEvent(reorderEvent);
} else {
parentDocAcc->BindChildDocument(docAcc);
}
NS_LOG_ACCDOCCREATE("document creation finished", aDocument)
AddListeners(aDocument, isRootDoc);

View File

@ -143,26 +143,14 @@ nsAccessibilityService::Observe(nsISupports *aSubject, const char *aTopic,
// nsIAccessibilityService
void
nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent *aTarget)
nsAccessibilityService::NotifyOfAnchorJumpTo(nsIContent* aTargetNode)
{
nsIDocument *document = aTarget->GetCurrentDoc();
if (!document)
return;
// If the jump target is not accessible then fire an event for nearest
// accessible in parent chain.
nsCOMPtr<nsIWeakReference> weakShell(nsCoreUtils::GetWeakShellFor(aTarget));
nsAccessible* targetAcc = GetAccessibleOrContainer(aTarget, weakShell);
if (!targetAcc)
return;
nsINode* targetNode = targetAcc->GetNode();
// XXX note in rare cases the node could go away before we flush the queue,
// for example if the node becomes inaccessible, or is removed from the DOM.
GetDocAccessible(document)->
FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SCROLLING_START,
targetNode);
nsIDocument* documentNode = aTargetNode->GetCurrentDoc();
if (documentNode) {
nsDocAccessible* document = GetDocAccessible(documentNode);
if (document)
document->HandleAnchorJump(aTargetNode);
}
}
// nsIAccessibilityService
@ -1259,7 +1247,7 @@ nsAccessibilityService::GetAccessibleByRule(nsINode* aNode,
if (aWhatToGet & eGetAccForNode) {
nsAccessible* cachedAcc = GetCachedAccessible(aNode, aWeakShell);
if (cachedAcc && cachedAcc->IsBoundToParent())
if (cachedAcc && (cachedAcc->IsBoundToParent() || cachedAcc->IsDocument()))
return cachedAcc;
}

View File

@ -320,7 +320,8 @@ nsDocAccessible::GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState)
*aState |= nsIAccessibleStates::STATE_FOCUSED;
}
if (!mIsLoaded) {
// Expose state busy until the document is loaded or tree is constructed.
if (!mIsLoaded || !mNotificationController->IsTreeConstructed()) {
*aState |= nsIAccessibleStates::STATE_BUSY;
if (aExtraState) {
*aExtraState |= nsIAccessibleStates::EXT_STATE_STALE;
@ -629,22 +630,7 @@ nsDocAccessible::Init()
return PR_FALSE;
AddEventListeners();
nsDocAccessible* parentDocument = mParent->GetDocAccessible();
if (parentDocument)
parentDocument->AppendChildDocument(this);
// Fire reorder event to notify new accessible document has been created and
// attached to the tree.
nsRefPtr<AccEvent> reorderEvent =
new AccEvent(nsIAccessibleEvent::EVENT_REORDER, mParent, eAutoDetect,
AccEvent::eCoalesceFromSameSubtree);
if (reorderEvent) {
FireDelayedAccessibleEvent(reorderEvent);
return PR_TRUE;
}
return PR_FALSE;
return PR_TRUE;
}
void
@ -1833,6 +1819,23 @@ nsDocAccessible::ProcessPendingEvent(AccEvent* aEvent)
}
}
void
nsDocAccessible::ProcessAnchorJump(nsIContent* aTargetNode)
{
// If the jump target is not accessible then fire an event for nearest
// accessible in parent chain.
nsAccessible* target = GetAccService()->GetAccessibleOrContainer(aTargetNode,
mWeakShell);
if (!target)
return;
// XXX: bug 625699, note in some cases the node could go away before we flush
// the queue, for example if the node becomes inaccessible, or is removed from
// the DOM.
FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_SCROLLING_START,
target->GetNode());
}
void
nsDocAccessible::ProcessContentInserted(nsAccessible* aContainer,
const nsTArray<nsCOMPtr<nsIContent> >* aInsertedContent)

View File

@ -189,6 +189,23 @@ public:
*/
nsresult FireDelayedAccessibleEvent(AccEvent* aEvent);
/**
* Handle anchor jump when page is loaded.
*/
inline void HandleAnchorJump(nsIContent* aTargetNode)
{
HandleNotification<nsDocAccessible, nsIContent>
(this, &nsDocAccessible::ProcessAnchorJump, aTargetNode);
}
/**
* Bind the child document to the tree.
*/
inline void BindChildDocument(nsDocAccessible* aDocument)
{
mNotificationController->ScheduleChildDocBinding(aDocument);
}
/**
* Process the generic notification.
*
@ -390,6 +407,11 @@ protected:
*/
void ProcessPendingEvent(AccEvent* aEvent);
/**
* Process anchor jump notification and fire scrolling end event.
*/
void ProcessAnchorJump(nsIContent* aTargetNode);
/**
* Update the accessible tree for inserted content.
*/

View File

@ -282,13 +282,13 @@ nsHyperTextAccessible::GetPosAndText(PRInt32& aStartOffset, PRInt32& aEndOffset,
nsAccessible **aEndAcc)
{
if (aStartOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT) {
GetCharacterCount(&aStartOffset);
aStartOffset = CharacterCount();
}
if (aStartOffset == nsIAccessibleText::TEXT_OFFSET_CARET) {
GetCaretOffset(&aStartOffset);
}
if (aEndOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT) {
GetCharacterCount(&aEndOffset);
aEndOffset = CharacterCount();
}
if (aEndOffset == nsIAccessibleText::TEXT_OFFSET_CARET) {
GetCaretOffset(&aEndOffset);
@ -492,14 +492,7 @@ NS_IMETHODIMP nsHyperTextAccessible::GetCharacterCount(PRInt32 *aCharacterCount)
if (IsDefunct())
return NS_ERROR_FAILURE;
PRInt32 childCount = GetChildCount();
for (PRInt32 childIdx = 0; childIdx < childCount; childIdx++) {
nsAccessible *childAcc = mChildren[childIdx];
PRInt32 textLength = nsAccUtils::TextLength(childAcc);
NS_ENSURE_TRUE(textLength >= 0, nsnull);
*aCharacterCount += textLength;
}
*aCharacterCount = CharacterCount();
return NS_OK;
}
@ -874,7 +867,7 @@ nsresult nsHyperTextAccessible::GetTextHelper(EGetTextType aType, nsAccessibleTe
}
if (aOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT) {
GetCharacterCount(&aOffset);
aOffset = CharacterCount();
}
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET) {
GetCaretOffset(&aOffset);
@ -958,8 +951,7 @@ nsresult nsHyperTextAccessible::GetTextHelper(EGetTextType aType, nsAccessibleTe
nsnull, getter_AddRefs(startAcc));
if (!startFrame) {
PRInt32 textLength;
GetCharacterCount(&textLength);
PRInt32 textLength = CharacterCount();
if (aBoundaryType == BOUNDARY_LINE_START && aOffset > 0 && aOffset == textLength) {
// Asking for start of line, while on last character
if (startAcc)
@ -1023,8 +1015,7 @@ nsresult nsHyperTextAccessible::GetTextHelper(EGetTextType aType, nsAccessibleTe
// that the first character is in
return GetTextHelper(eGetAfter, aBoundaryType, aOffset, aStartOffset, aEndOffset, aText);
}
PRInt32 textLength;
GetCharacterCount(&textLength);
PRInt32 textLength = CharacterCount();
if (finalEndOffset < textLength) {
// This happens sometimes when current character at finalStartOffset
// is an embedded object character representing another hypertext, that
@ -1419,8 +1410,7 @@ NS_IMETHODIMP nsHyperTextAccessible::SetAttributes(PRInt32 aStartPos, PRInt32 aE
NS_IMETHODIMP nsHyperTextAccessible::SetTextContents(const nsAString &aText)
{
PRInt32 numChars;
GetCharacterCount(&numChars);
PRInt32 numChars = CharacterCount();
if (numChars == 0 || NS_SUCCEEDED(DeleteText(0, numChars))) {
return InsertText(aText, 0);
}

View File

@ -91,7 +91,7 @@ public:
virtual void InvalidateChildren();
// nsHyperTextAccessible
// nsHyperTextAccessible (static helper method)
// Convert content offset to rendered text offset
static nsresult ContentToRenderedOffset(nsIFrame *aFrame, PRInt32 aContentOffset,
@ -101,6 +101,9 @@ public:
static nsresult RenderedToContentOffset(nsIFrame *aFrame, PRUint32 aRenderedOffset,
PRInt32 *aContentOffset);
//////////////////////////////////////////////////////////////////////////////
// HyperLinkAccessible
/**
* Return link count within this hypertext accessible.
*/
@ -134,6 +137,9 @@ public:
return child ? GetLinkIndex(child) : -1;
}
//////////////////////////////////////////////////////////////////////////////
// nsHyperTextAccessible: DOM point to text offset conversions.
/**
* Turn a DOM Node and offset into a character offset into this hypertext.
* Will look for closest match when the DOM node does not have an accessible
@ -192,6 +198,17 @@ public:
nsIDOMNode **aEndNode,
PRInt32 *aEndOffset);
//////////////////////////////////////////////////////////////////////////////
// TextAccessible
/**
* Return character count within the hypertext accessible.
*/
inline PRUint32 CharacterCount()
{
return GetChildOffset(GetChildCount());
}
/**
* Return text offset of the given child accessible within hypertext
* accessible.

View File

@ -1,13 +1,12 @@
#import "mozAccessible.h"
#import "nsIAccessibleText.h"
#import "nsIAccessibleEditableText.h"
#import "nsHyperTextAccessible.h"
@interface mozTextAccessible : mozAccessible
{
// both of these are the same old mGeckoAccessible, but already
// QI'd for us, to the right type, for convenience.
nsIAccessibleText *mGeckoTextAccessible; // strong
nsHyperTextAccessible *mGeckoTextAccessible; // strong
nsIAccessibleEditableText *mGeckoEditableTextAccessible; // strong
}
@end

View File

@ -164,12 +164,7 @@ extern const NSString *kTopLevelUIElementAttribute; // NSAccessibilityTopLevel
{
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_RETURN;
if (mGeckoTextAccessible) {
PRInt32 charCount = 0;
mGeckoTextAccessible->GetCharacterCount(&charCount);
return charCount;
}
return 0;
return mGeckoTextAccessible ? mGeckoTextAccessible->CharacterCount() : 0;
NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0);
}

View File

@ -43,23 +43,7 @@
#include "Accessible2.h"
#include "AccessibleText_i.c"
#include "nsIAccessible.h"
#include "nsIAccessibleText.h"
#include "nsIAccessibleTypes.h"
#include "nsIWinAccessNode.h"
#include "nsAccessNodeWrap.h"
#include "nsAccessibleWrap.h"
#include "nsCOMPtr.h"
#include "nsIPersistentProperties2.h"
#include "nsString.h"
#define GET_NSIACCESSIBLETEXT \
nsCOMPtr<nsIAccessibleText> textAcc(do_QueryObject(this));\
NS_ASSERTION(textAcc,\
"Subclass of CAccessibleText doesn't implement nsIAccessibleText");\
if (!textAcc)\
return E_FAIL;\
#include "nsHyperTextAccessible.h"
// IUnknown
@ -87,8 +71,7 @@ STDMETHODIMP
CAccessibleText::addSelection(long aStartOffset, long aEndOffset)
{
__try {
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
nsresult rv = textAcc->AddSelection(aStartOffset, aEndOffset);
return GetHRESULT(rv);
@ -108,7 +91,7 @@ __try {
*aEndOffset = 0;
*aTextAttributes = NULL;
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
PRInt32 startOffset = 0, endOffset = 0;
nsCOMPtr<nsIPersistentProperties> attributes;
@ -138,7 +121,7 @@ CAccessibleText::get_caretOffset(long *aOffset)
__try {
*aOffset = -1;
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
PRInt32 offset = 0;
nsresult rv = textAcc->GetCaretOffset(&offset);
@ -164,7 +147,7 @@ __try {
*aWidth = 0;
*aHeight = 0;
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
PRUint32 geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
@ -192,7 +175,7 @@ CAccessibleText::get_nSelections(long *aNSelections)
__try {
*aNSelections = 0;
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
PRInt32 selCount = 0;
nsresult rv = textAcc->GetSelectionCount(&selCount);
@ -214,7 +197,7 @@ CAccessibleText::get_offsetAtPoint(long aX, long aY,
__try {
*aOffset = 0;
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
PRUint32 geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :
@ -240,7 +223,7 @@ __try {
*aStartOffset = 0;
*aEndOffset = 0;
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
PRInt32 startOffset = 0, endOffset = 0;
nsresult rv = textAcc->GetSelectionBounds(aSelectionIndex,
@ -262,7 +245,7 @@ CAccessibleText::get_text(long aStartOffset, long aEndOffset, BSTR *aText)
__try {
*aText = NULL;
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
nsAutoString text;
nsresult rv = textAcc->GetText(aStartOffset, aEndOffset, text);
@ -290,7 +273,9 @@ __try {
*aEndOffset = 0;
*aText = NULL;
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
if (textAcc->IsDefunct())
return E_FAIL;
nsresult rv = NS_OK;
nsAutoString text;
@ -298,7 +283,7 @@ __try {
if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
startOffset = 0;
textAcc->GetCharacterCount(&endOffset);
endOffset = textAcc->CharacterCount();
rv = textAcc->GetText(startOffset, endOffset, text);
} else {
nsAccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType);
@ -335,7 +320,9 @@ __try {
*aEndOffset = 0;
*aText = NULL;
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
if (textAcc->IsDefunct())
return E_FAIL;
nsresult rv = NS_OK;
nsAutoString text;
@ -343,7 +330,7 @@ __try {
if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
startOffset = 0;
textAcc->GetCharacterCount(&endOffset);
endOffset = textAcc->CharacterCount();
rv = textAcc->GetText(startOffset, endOffset, text);
} else {
nsAccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType);
@ -380,7 +367,9 @@ __try {
*aEndOffset = 0;
*aText = NULL;
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
if (textAcc->IsDefunct())
return E_FAIL;
nsresult rv = NS_OK;
nsAutoString text;
@ -388,7 +377,7 @@ __try {
if (aBoundaryType == IA2_TEXT_BOUNDARY_ALL) {
startOffset = 0;
textAcc->GetCharacterCount(&endOffset);
endOffset = textAcc->CharacterCount();
rv = textAcc->GetText(startOffset, endOffset, text);
} else {
nsAccessibleTextBoundary boundaryType = GetGeckoTextBoundary(aBoundaryType);
@ -418,7 +407,7 @@ STDMETHODIMP
CAccessibleText::removeSelection(long aSelectionIndex)
{
__try {
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
nsresult rv = textAcc->RemoveSelection(aSelectionIndex);
return GetHRESULT(rv);
@ -431,7 +420,7 @@ STDMETHODIMP
CAccessibleText::setCaretOffset(long aOffset)
{
__try {
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
nsresult rv = textAcc->SetCaretOffset(aOffset);
return GetHRESULT(rv);
@ -445,7 +434,7 @@ CAccessibleText::setSelection(long aSelectionIndex, long aStartOffset,
long aEndOffset)
{
__try {
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
nsresult rv = textAcc->SetSelectionBounds(aSelectionIndex,
aStartOffset, aEndOffset);
@ -461,14 +450,11 @@ CAccessibleText::get_nCharacters(long *aNCharacters)
__try {
*aNCharacters = 0;
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
if (textAcc->IsDefunct())
return E_FAIL;
PRInt32 charCount = 0;
nsresult rv = textAcc->GetCharacterCount(&charCount);
if (NS_FAILED(rv))
return GetHRESULT(rv);
*aNCharacters = charCount;
*aNCharacters = textAcc->CharacterCount();
return S_OK;
} __except(nsAccessNodeWrap::FilterA11yExceptions(::GetExceptionCode(), GetExceptionInformation())) { }
@ -480,7 +466,7 @@ CAccessibleText::scrollSubstringTo(long aStartIndex, long aEndIndex,
enum IA2ScrollType aScrollType)
{
__try {
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
nsresult rv = textAcc->ScrollSubstringTo(aStartIndex, aEndIndex, aScrollType);
return GetHRESULT(rv);
@ -495,7 +481,7 @@ CAccessibleText::scrollSubstringToPoint(long aStartIndex, long aEndIndex,
long aX, long aY)
{
__try {
GET_NSIACCESSIBLETEXT
nsRefPtr<nsHyperTextAccessible> textAcc(do_QueryObject(this));
PRUint32 geckoCoordType = (aCoordType == IA2_COORDTYPE_SCREEN_RELATIVE) ?
nsIAccessibleCoordinateType::COORDTYPE_SCREEN_RELATIVE :

View File

@ -430,7 +430,7 @@ function eventQueue(aEventType)
msg += " unexpected";
msg += ": event type: " + this.getEventTypeAsString(idx) +
", target: " + prettyName(this.getEventTarget(idx));
", target: " + this.getEventTargetDescr(idx);
gLogger.logToConsole(msg);
gLogger.logToDOM(msg, true);
@ -487,6 +487,12 @@ function eventQueue(aEventType)
return this.mEventSeq[aIdx].target;
}
this.getEventTargetDescr = function eventQueue_getEventTargetDescr(aIdx)
{
var descr = this.mEventSeq[aIdx].targetDescr;
return descr ? descr : "no target description";
}
this.getEventPhase = function eventQueue_getEventPhase(aIdx)
{
var eventItem = this.mEventSeq[aIdx];
@ -895,6 +901,16 @@ function invokerChecker(aEventType, aTargetOrFunc, aTargetFuncArg)
return this.mTarget;
}
this.__defineGetter__("targetDescr", invokerChecker_targetDescrGetter);
function invokerChecker_targetDescrGetter()
{
if (typeof this.mTarget == "function")
return this.mTarget.toSource() + this.mTargetFuncArg;
return prettyName(this.mTarget);
}
this.mTarget = aTargetOrFunc;
this.mTargetFuncArg = aTargetFuncArg;
}

View File

@ -2,20 +2,38 @@
<head>
<title>Accessible events testing for document</title>
<script>
const STATE_BUSY = Components.interfaces.nsIAccessibleStates.STATE_BUSY;
var gRetrieval = null;
function waitForDocLoad()
{
if (!gRetrieval) {
gRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
getService(Components.interfaces.nsIAccessibleRetrieval);
}
var accDoc = gRetrieval.getAccessibleFor(document);
var state = {};
accDoc.getState(state, {});
if (state.value & STATE_BUSY) {
window.setTimeout(waitForDocLoad, 0);
return;
}
hideIFrame();
}
function hideIFrame()
{
var iframe = document.getElementById("iframe");
var accRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
getService(Components.interfaces.nsIAccessibleRetrieval);
accRetrieval.getAccessibleFor(iframe.contentDocument);
gRetrieval.getAccessibleFor(iframe.contentDocument);
iframe.style.display = 'none';
}
</script>
</head>
<body onload="hideIFrame();">
<body onload="waitForDocLoad();">
<iframe id="iframe"></iframe>
</body>
</html>

View File

@ -197,6 +197,10 @@
this.invoker.iframeDoc = iframe.contentDocument;
return iframe;
},
get targetDescr()
{
return "inner iframe of docload_wnd.html document";
},
invoker: thisObj
};

View File

@ -53,6 +53,7 @@
var gScrollHandler = {
handleEvent: function gScrollHandler_handleEvent(aEvent) {
if (aEvent.DOMNode.getAttribute("name") == "link1") {
ok(true, "scrolling start event was handled on link1");
unregisterA11yEventListener(EVENT_SCROLLING_START, this);
SimpleTest.finish();
}

View File

@ -107,11 +107,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=428248
href="https://bugzilla.mozilla.org/show_bug.cgi?id=418368">
Mozilla Bug 418368
</a><br>
<a target="_blank"
title="Cache links within hypertext accessible"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=572394">
Mozilla Bug 572394
</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">

View File

@ -106,6 +106,11 @@
</head>
<body>
<a target="_blank"
title="Cache links within hypertext accessible"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=572394">
Mozilla Bug 572394
</a>
<a target="_blank"
title="Text offsets don't get updated when text of first child text accessible is changed"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=625009">

View File

@ -11,6 +11,21 @@ const BOUNDARY_ATTRIBUTE_RANGE = nsIAccessibleText.BOUNDARY_ATTRIBUTE_RANGE;
const kTodo = 1;
const kOk = 2;
/**
* Test characterCount for the given array of accessibles.
*
* @param aCount [in] the expected character count
* @param aIDs [in] array of accessible identifiers to test
*/
function testCharacterCount(aIDs, aCount)
{
for (var i = 1; i < aIDs.length; i++) {
var textacc = getAccessible(aIDs[i], [nsIAccessibleText]);
is(textacc.characterCount, aCount,
"Wrong character count for " + prettyName(aIDs[i]));
}
}
function testText(aIDs, aStartOffset, aEndOffset, aText)
{
for (var i = 0; i < aIDs.length; i++)

View File

@ -17,7 +17,9 @@
function doTest()
{
testText([getNode("iframe").contentDocument], 0, 14, "outbody inbody");
var iframeDoc = [ getNode("iframe").contentDocument ];
testCharacterCount(iframeDoc, 15);
testText(iframeDoc, 0, 15, "outbody inbody ");
SimpleTest.finish();
}

View File

@ -16,14 +16,19 @@
function doTest()
{
var IDs = ["input", "div", "textarea"];
// __h__e__l__l__o__ __m__y__ __f__r__i__e__n__d__
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
////////////////////////////////////////////////////////////////////////
// characterCount
testCharacterCount(["input", "div"], 15);
testCharacterCount(["textarea"], 16);
////////////////////////////////////////////////////////////////////////
// getText
var IDs = ["input", "div", "textarea"];
testText(IDs, 0, 1, "h");
testText(IDs, 1, 3, "el");
testText(IDs, 14, 15, "d");

View File

@ -18,15 +18,20 @@
function doTest()
{
// Tests for elements rendering the original sring
var IDs = ["input", "div", "editable", "textarea"];
// __B__r__a__v__e__ __S__i__r__ __ __R__o__b__i__n__ __ __ __r__a__n
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
////////////////////////////////////////////////////////////////////////
// characterCount
testCharacterCount(["input", "div", "editable"], 22);
testCharacterCount(["textarea"], 23);
////////////////////////////////////////////////////////////////////////
// getText
var IDs = ["input", "div", "editable", "textarea"];
testText(IDs, 0, 1, "B");
testText(IDs, 5, 6, " ");
testText(IDs, 9, 11, " ");

View File

@ -56,6 +56,9 @@
<emItem id="{3f963a5b-e555-4543-90e2-c3908898db71}">
<versionRange minVersion=" " maxVersion="8.5"/>
</emItem>
<emItem id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
<versionRange minVersion="1.1b1" maxVersion="1.1b1"/>
</emItem>
<emItem id="{4B3803EA-5230-4DC3-A7FC-33638F3D3542}">
<versionRange minVersion="1.2" maxVersion="1.2">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
@ -64,8 +67,11 @@
</versionRange>
</emItem>
<emItem id="{8CE11043-9A15-4207-A565-0C94C42D590D}"/>
<emItem id="{AB2CE124-6272-4b12-94A9-7303C7397BD1}">
<versionRange severity="1"/>
</emItem>
<emItem id="{B13721C7-F507-4982-B2E5-502A71474FED}">
<versionRange minVersion=" " maxVersion="3.3.0.3970" severity="1"/>
<versionRange severity="1"/>
</emItem>
<emItem id="{E8E88AB0-7182-11DF-904E-6045E0D72085}"/>
</emItems>

View File

@ -40,6 +40,8 @@ topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
DISTROEXT = $(call core_abspath,$(DIST))/bin/distribution/extensions
include $(DEPTH)/config/autoconf.mk
DIRS = {972ce4c6-7e08-4474-a285-3208198ce6fd}
@ -51,11 +53,13 @@ EXTENSIONS = \
testpilot@labs.mozilla.com \
$(NULL)
define _INSTALL_EXTENSIONS
$(PYTHON) $(topsrcdir)/config/nsinstall.py $(wildcard $(srcdir)/$(dir)/*) $(DIST)/bin/extensions/$(dir)
define _INSTALL_EXTENSION
cd $(srcdir)/$(dir) && \
$(ZIP) -r9XD $(DISTROEXT)/$(dir).xpi *
endef # do not remove the blank line!
libs::
$(foreach dir,$(EXTENSIONS),$(_INSTALL_EXTENSIONS))
$(NSINSTALL) -D $(DISTROEXT)
$(foreach dir,$(EXTENSIONS),$(_INSTALL_EXTENSION))
endif

View File

@ -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.0.3</em:version>
<em:version>1.0.4</em:version>
<em:type>2</em:type>
<!-- Target Application this extension can install into,

View File

@ -687,22 +687,28 @@ let TestPilotSetup = {
},
_experimentRequirementsAreMet: function TPS__requirementsMet(experiment) {
// Returns true if we we meet the requirements to run this experiment
// (e.g. meet the minimum Test Pilot version and Firefox version)
// false if not.
// If the experiment doesn't specify minimum versions, attempt to run it.
/* Returns true if we we meet the requirements to run this experiment
* (e.g. meet the minimum Test Pilot version and Firefox version)
* false if not.
* Default is always to run the study - return true UNLESS the study
* specifies a requirement that we don't meet. */
let logger = this._logger;
try {
let minTpVer, minFxVer, expName;
if (experiment.experimentInfo) {
minTpVer = experiment.experimentInfo.minTPVersion;
minFxVer = experiment.experimentInfo.minFXVersion;
expName = experiment.experimentInfo.testName;
} else if (experiment.surveyInfo) {
minTpVer = experiment.surveyInfo.minTPVersion;
minFxVer = experiment.surveyInfo.minFXVersion;
expName = experiment.surveyInfo.surveyName;
let minTpVer, minFxVer, expName, runOrNotFunc;
/* Could be an experiment, which specifies experimentInfo, or survey,
* which specifies surveyInfo. */
let info = experiment.experimentInfo ?
experiment.experimentInfo :
experiment.surveyInfo;
if (!info) {
// If neither one is supplied, study lacks metadata required to run
logger.warn("Study lacks minimum metadata to run.");
return false;
}
minTpVer = info.minTPVersion;
minFxVer = info.minFXVersion;
expName = info.testName;
runOrNotFunc = info.runOrNotFunc;
// Minimum test pilot version:
if (minTpVer && this._isNewerThanMe(minTpVer)) {
@ -728,6 +734,12 @@ let TestPilotSetup = {
logger.warn("Because it requires Firefox version " + minFxVer);
return false;
}
/* The all-purpose, arbitrary code "Should this study run?" function - if
* provided, use its return value. */
if (runOrNotFunc) {
return runOrNotFunc();
}
} catch (e) {
logger.warn("Error in requirements check " + e);
}

View File

@ -59,7 +59,7 @@ pref("extensions.logging.enabled", false);
// Preferences for AMO integration
pref("extensions.getAddons.cache.enabled", true);
pref("extensions.getAddons.maxResults", 15);
pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/guid:%IDS%?src=firefox");
pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%&tMain=%TIME_MAIN%&tFirstPaint=%TIME_FIRST_PAINT%&tSessionRestored=%TIME_SESSION_RESTORED%");
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/%APP%/search?q=%TERMS%");
pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%?src=firefox");
pref("extensions.webservice.discoverURL", "https://services.addons.mozilla.org/%LOCALE%/%APP%/discovery/%VERSION%/%OS%");
@ -244,8 +244,8 @@ pref("browser.aboutHomeSnippets.updateUrl", "http://snippets.mozilla.com/%STARTP
pref("browser.enable_automatic_image_resizing", true);
pref("browser.chrome.site_icons", true);
pref("browser.chrome.favicons", true);
pref("browser.warnOnQuit", true);
pref("browser.warnOnRestart", true);
pref("browser.warnOnQuit", false);
pref("browser.warnOnRestart", false);
pref("browser.fullscreen.autohide", true);
pref("browser.fullscreen.animateUp", 1);
@ -539,9 +539,6 @@ pref("alerts.totalOpenTime", 4000);
pref("browser.xul.error_pages.enabled", true);
pref("browser.xul.error_pages.expert_bad_cert", false);
// Work Offline is best manually managed by the user.
pref("network.manage-offline-status", false);
// We want to make sure mail URLs are handled externally...
pref("network.protocol-handler.external.mailto", true); // for mail
pref("network.protocol-handler.external.news", true); // for news

View File

@ -39,17 +39,20 @@
# ***** END LICENSE BLOCK *****
<menupopup id="appmenu-popup"
onpopupshowing="if (event.target == this) {
updateEditUIVisibility();
#ifdef MOZ_SERVICES_SYNC
onpopupshowing="updateEditUIVisibility();gSyncUI.updateUI();">
#else
onpopupshowing="updateEditUIVisibility();">
gSyncUI.updateUI();
#endif
return;
}
if (event.target.parentNode.parentNode.parentNode.parentNode == this)
this._currentPopup = event.target;">
<hbox>
<vbox id="appmenuPrimaryPane">
<splitmenu id="appmenu_newTab"
label="&tabCmd.label;"
command="cmd_newNavigatorTab"
key="key_newNavigatorTab">
command="cmd_newNavigatorTab">
<menupopup>
<menuitem id="appmenu_newTab_popup"
label="&tabCmd.label;"
@ -116,8 +119,7 @@
<splitmenu id="appmenu_print"
iconic="true"
label="&printCmd.label;"
command="cmd_print"
key="printKb">
command="cmd_print">
<menupopup>
<menuitem id="appmenu_print_popup"
class="menuitem-iconic"
@ -203,8 +205,7 @@
<splitmenu id="appmenu_bookmarks"
iconic="true"
label="&bookmarksMenu.label;"
command="Browser:ShowAllBookmarks"
key="manBookmarkKb">
command="Browser:ShowAllBookmarks">
<menupopup id="appmenu_bookmarksPopup"
placespopup="true"
context="placesContext"
@ -267,8 +268,7 @@
<splitmenu id="appmenu_history"
iconic="true"
label="&historyMenu.label;"
command="Browser:ShowAllHistory"
key="showAllHistoryKb">
command="Browser:ShowAllHistory">
<menupopup id="appmenu_historyMenupopup"
placespopup="true"
oncommand="this.parentNode._placesView._onCommand(event);"

View File

@ -348,10 +348,8 @@ var PlacesCommandHook = {
if (starIcon && isElementVisible(starIcon)) {
// Make sure the bookmark properties dialog hangs toward the middle of
// the location bar in RTL builds
var position = (getComputedStyle(gNavToolbox, "").direction == "rtl") ?
'bottomcenter topleft' : 'bottomcenter topright';
if (aShowEditUI)
StarUI.showEditBookmarkPopup(itemId, starIcon, position);
StarUI.showEditBookmarkPopup(itemId, starIcon, "bottomcenter topright");
return;
}
}

View File

@ -117,8 +117,6 @@
<command id="Browser:PrevTab" oncommand="gBrowser.tabContainer.advanceSelectedTab(-1, true);"/>
<command id="Browser:ShowAllTabs" oncommand="allTabs.open();"/>
<command id="Browser:ToggleTabView" oncommand="TabView.toggle();"/>
<command id="Browser:ShowTabView" oncommand="TabView.show();"/>
<command id="Browser:HideTabView" oncommand="TabView.hide();"/>
<command id="cmd_fullZoomReduce" oncommand="FullZoom.reduce()"/>
<command id="cmd_fullZoomEnlarge" oncommand="FullZoom.enlarge()"/>
<command id="cmd_fullZoomReset" oncommand="FullZoom.reset()"/>

View File

@ -249,6 +249,7 @@ let gSyncUI = {
},
onStartOver: function SUI_onStartOver() {
Weave.Notifications.removeAll();
this.updateUI();
},

View File

@ -155,13 +155,18 @@ splitmenu {
-moz-binding: url("chrome://browser/content/urlbarBindings.xml#splitmenu");
}
.split-menuitem-item {
.splitmenu-menuitem {
-moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem");
list-style-image: inherit;
-moz-image-region: inherit;
}
.split-menuitem-menu > .menu-text,
.split-menuitem-menu > .menu-accel-container {
.splitmenu-menuitem[iconic="true"] {
-moz-binding: url("chrome://global/content/bindings/menu.xml#menuitem-iconic");
}
.splitmenu-menu > .menu-text,
:-moz-any(.splitmenu-menu, .splitmenu-menuitem) > .menu-accel-container {
display: none;
}
@ -279,7 +284,7 @@ panel[noactions] > richlistbox > richlistitem[type~="action"] > .ac-url-box > .a
visibility: visible;
}
#urlbar:not([actiontype]) > #urlbar-display {
#urlbar:not([actiontype]) > #urlbar-display-box {
display: none;
}

View File

@ -719,11 +719,11 @@ const gXPInstallObserver = {
options.installs = installInfo.installs;
options.contentWindow = browser.contentWindow;
options.sourceURI = browser.currentURI;
options.eventCallback = function(aNotification, aEvent) {
options.eventCallback = function(aEvent) {
if (aEvent != "removed")
return;
aNotification.options.contentWindow = null;
aNotification.options.sourceURI = null;
options.contentWindow = null;
options.sourceURI = null;
};
PopupNotifications.show(browser, notificationID, messageString, anchorID,
null, null, options);
@ -1736,7 +1736,8 @@ function nonBrowserWindowStartup()
'Browser:SendLink', 'cmd_pageSetup', 'cmd_print', 'cmd_find', 'cmd_findAgain',
'viewToolbarsMenu', 'viewSidebarMenuMenu', 'Browser:Reload',
'viewFullZoomMenu', 'pageStyleMenu', 'charsetMenu', 'View:PageSource', 'View:FullScreen',
'viewHistorySidebar', 'Browser:AddBookmarkAs', 'View:PageInfo', 'Tasks:InspectPage'];
'viewHistorySidebar', 'Browser:AddBookmarkAs', 'View:PageInfo', 'Tasks:InspectPage',
'Browser:ToggleTabView'];
var element;
for (var id in disabledItems)
@ -3542,6 +3543,12 @@ function BrowserToolboxCustomizeDone(aToolboxChanged) {
#ifndef XP_MACOSX
updateEditUIVisibility();
#endif
// Hacky: update the PopupNotifications' object's reference to the iconBox,
// if it already exists, since it may have changed if the URL bar was
// added/removed.
if (!__lookupGetter__("PopupNotifications"))
PopupNotifications.iconBox = document.getElementById("notification-popup-box");
}
PlacesToolbarHelper.customizeDone();
@ -4319,6 +4326,21 @@ var XULBrowserWindow = {
document.documentElement.setAttribute("disablechrome", "true");
else
document.documentElement.removeAttribute("disablechrome");
// Disable find commands in documents that ask for them to be disabled.
let docElt = content.document.documentElement;
let disableFind = aLocationURI &&
(docElt && docElt.getAttribute("disablefastfind") == "true") &&
(aLocationURI.schemeIs("about") || aLocationURI.schemeIs("chrome"));
let findCommands = [document.getElementById("cmd_find"),
document.getElementById("cmd_findAgain"),
document.getElementById("cmd_findPrevious")];
findCommands.forEach(function (elt) {
if (disableFind)
elt.setAttribute("disabled", "true");
else
elt.removeAttribute("disabled");
});
}
UpdateBackForwardCommands(gBrowser.webNavigation);

View File

@ -571,7 +571,9 @@
</hbox>
</hbox>
</box>
<label id="urlbar-display" value="&urlbar.switchToTab.label;"/>
<box id="urlbar-display-box" align="center">
<label id="urlbar-display" value="&urlbar.switchToTab.label;"/>
</box>
<hbox id="urlbar-icons">
<image id="page-report-button"
class="urlbar-icon"

View File

@ -79,6 +79,9 @@ let Change = {
this._firstBox = document.getElementById("textBox1");
this._secondBox = document.getElementById("textBox2");
this._dialog.getButton("finish").disabled = true;
this._dialog.getButton("back").hidden = true;
this._stringBundle =
Services.strings.createBundle("chrome://browser/locale/syncGenericChange.properties");
@ -87,34 +90,35 @@ let Change = {
case "ResetPassphrase":
document.getElementById("textBox1Row").hidden = true;
document.getElementById("textBox2Row").hidden = true;
let passphraseLabel = document.getElementById("passphraseLabel");
passphraseLabel.value = this._str("new.synckey.label");
document.getElementById("passphraseLabel").value
= this._str("new.synckey.label");
document.getElementById("passphraseSpacer").hidden = false;
if (this._updatingPassphrase) {
document.getElementById("passphraseBackupButtons").hidden = true;
document.getElementById("generatePassphraseButton").hidden = true;
document.getElementById("passphraseHelpBox").hidden = false;
document.title = this._str("new.synckey.title");
introText.textContent = this._str("new.synckey2.introText");
this._dialog.getButton("accept")
.setAttribute("label", this._str("new.synckey.acceptButton"));
this._dialog.getButton("finish").label
= this._str("new.synckey.acceptButton");
}
else {
document.getElementById("generatePassphraseButton").hidden = false;
document.getElementById("generatePassphraseButton").hidden = false;
this._passphraseBox.setAttribute("readonly", "true");
let pp = Weave.Service.passphrase;
if (Weave.Utils.isPassphrase(pp))
pp = Weave.Utils.hyphenatePassphrase(pp);
document.getElementById("passphraseBox").value = pp;
this._passphraseBox.value = pp;
this._passphraseBox.focus();
document.title = this._str("change.synckey.title");
introText.innerHTML = this._str("change.synckey.introText");
introText2.innerHTML = this._str("change.synckey.introText2");
warningText.innerHTML = this._str("change.synckey2.warningText");
this._dialog.getButton("accept")
.setAttribute("label", this._str("change.synckey.acceptButton"));
introText.textContent = this._str("change.synckey.introText2");
warningText.textContent = this._str("change.synckey2.warningText");
this._dialog.getButton("finish").label
= this._str("change.synckey.acceptButton");
}
break;
case "ChangePassword":
document.getElementById("passphraseRow").hidden = true;
document.getElementById("passphraseBackupButtons").hidden = true;
let box1label = document.getElementById("textBox1Label");
let box2label = document.getElementById("textBox2Label");
box1label.value = this._str("new.password.label");
@ -122,8 +126,8 @@ let Change = {
if (this._currentPasswordInvalid) {
document.title = this._str("new.password.title");
introText.textContent = this._str("new.password.introText");
this._dialog.getButton("accept")
.setAttribute("label", this._str("new.password.acceptButton"));
this._dialog.getButton("finish").label
= this._str("new.password.acceptButton");
document.getElementById("textBox2Row").hidden = true;
}
else {
@ -131,11 +135,13 @@ let Change = {
box2label.value = this._str("new.password.confirm");
introText.textContent = this._str("change.password2.introText");
warningText.textContent = this._str("change.password.warningText");
this._dialog.getButton("accept")
.setAttribute("label", this._str("change.password.acceptButton"));
this._dialog.getButton("finish").label
= this._str("change.password.acceptButton");
}
break;
}
document.getElementById("change-page")
.setAttribute("label", document.title);
},
_clearStatus: function _clearStatus() {
@ -153,8 +159,8 @@ let Change = {
this._statusIcon.setAttribute("status", state);
let error = state == "error";
this._dialog.getButton("cancel").setAttribute("disabled", !error);
this._dialog.getButton("accept").setAttribute("disabled", !error);
this._dialog.getButton("cancel").disabled = !error;
this._dialog.getButton("finish").disabled = !error;
document.getElementById("printSyncKeyButton").disabled = !error;
document.getElementById("saveSyncKeyButton").disabled = !error;
@ -176,9 +182,8 @@ let Change = {
doGeneratePassphrase: function () {
let passphrase = Weave.Utils.generatePassphrase();
let el = document.getElementById("passphraseBox");
el.value = Weave.Utils.hyphenatePassphrase(passphrase);
this._dialog.getButton("accept").disabled = false;
this._passphraseBox.value = Weave.Utils.hyphenatePassphrase(passphrase);
this._dialog.getButton("finish").disabled = false;
},
doChangePassphrase: function Change_doChangePassphrase() {
@ -251,7 +256,7 @@ let Change = {
this._updateStatusWithString(errorString, "error");
this._statusRow.hidden = valid;
this._dialog.getButton("accept").disabled = !valid;
this._dialog.getButton("finish").disabled = !valid;
},
_str: function Change__string(str) {

View File

@ -40,6 +40,7 @@
# ***** END LICENSE BLOCK *****
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/syncSetup.css" type="text/css"?>
<?xml-stylesheet href="chrome://browser/skin/syncCommon.css" type="text/css"?>
<!DOCTYPE window [
@ -50,15 +51,12 @@
%syncBrandDTD;
%syncSetupDTD;
]>
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
<wizard xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
id="change-dialog"
windowtype="Weave:ChangeSomething"
buttons="accept,cancel"
onload="Change.onLoad()"
buttondisabledaccept="true"
ondialogaccept="return Change.onDialogAccept();"
defaultButton="accept">
onwizardnext="Change.onLoad()"
onwizardfinish="return Change.onDialogAccept();">
<script type="application/javascript"
src="chrome://browser/content/syncGenericChange.js"/>
@ -67,55 +65,65 @@
<script type="application/javascript"
src="chrome://global/content/printUtils.js"/>
<hbox align="top">
<image id="syncIcon"/>
<spacer style="width: 1em"/>
<description flex="1">
<html:p id="introText"/>
<html:p id="introText2"/>
<wizardpage id="change-page"
label="">
<description id="introText">
</description>
</hbox>
<separator class="thin"/>
<vbox>
<grid>
<columns>
<column align="right"/>
<column flex="3"/>
<column flex="1"/>
</columns>
<rows>
<row id="textBox1Row" align="center">
<label id="textBox1Label" control="textBox1"/>
<textbox id="textBox1" type="password" oninput="Change.validate()"/>
<spacer/>
</row>
<row id="textBox2Row" align="center">
<label id="textBox2Label" control="textBox2"/>
<textbox id="textBox2" type="password" oninput="Change.validate()"/>
<spacer/>
</row>
<row id="passphraseRow" align="center">
<separator class="thin"/>
<groupbox>
<grid>
<columns>
<column align="right"/>
<column flex="3"/>
<column flex="1"/>
</columns>
<rows>
<row id="textBox1Row" align="center">
<label id="textBox1Label" control="textBox1"/>
<textbox id="textBox1" type="password" oninput="Change.validate()"/>
<spacer/>
</row>
<row id="textBox2Row" align="center">
<label id="textBox2Label" control="textBox2"/>
<textbox id="textBox2" type="password" oninput="Change.validate()"/>
<spacer/>
</row>
</rows>
</grid>
<vbox id="passphraseRow">
<hbox flex="1">
<label id="passphraseLabel" control="passphraseBox"/>
<textbox id="passphraseBox"
onfocus="this.select()"
oninput="Change.validate()"/>
<spacer flex="1"/>
<label id="generatePassphraseButton"
hidden="true"
value="&syncKeyGenerate.label;"
class="text-link inline-link"
onclick="event.stopPropagation();
Change.doGeneratePassphrase();"/>
</row>
</rows>
</grid>
</hbox>
<textbox id="passphraseBox"
flex="1"
onfocus="this.select()"
oninput="Change.validate()"/>
</vbox>
<vbox id="feedback" pack="center">
<hbox id="statusRow" align="center">
<image id="statusIcon" class="statusIcon"/>
<label id="status" class="status" value=" "/>
</hbox>
</vbox>
<vbox id="feedback" pack="center">
<hbox id="statusRow" align="center">
<image id="statusIcon" class="statusIcon"/>
<label id="status" class="status" value=" "/>
</hbox>
</vbox>
</groupbox>
<hbox id="passphraseBackupButtons" pack="center">
<separator class="thin"/>
<hbox id="passphraseBackupButtons"
hidden="true"
pack="center">
<button id="printSyncKeyButton"
label="&button.syncKeyBackup.print.label;"
accesskey="&button.syncKeyBackup.print.accesskey;"
@ -126,8 +134,24 @@
oncommand="gSyncUtils.passphraseSave('passphraseBox');"/>
</hbox>
<description>
<html:p class="data" id="warningText"/>
<vbox id="passphraseHelpBox"
hidden="true">
<description>
&existingSyncKey.description;
<label class="text-link"
href="https://services.mozilla.com/sync/help/manual-setup">
&addDevice.showMeHow.label;
</label>
</description>
</vbox>
<spacer id="passphraseSpacer"
flex="1"
hidden="true"/>
<description id="warningText" class="data">
</description>
</vbox>
</dialog>
<spacer flex="1"/>
</wizardpage>
</wizard>

View File

@ -880,9 +880,9 @@ var gSyncSetup = {
// if no property string is passed in, we clear label/style
_setFeedback: function (element, success, string) {
element.hidden = success || !string;
let class = success ? "success" : "error";
let classname = success ? "success" : "error";
let image = element.getElementsByAttribute("class", "statusIcon")[0];
image.setAttribute("status", class);
image.setAttribute("status", classname);
let label = element.getElementsByAttribute("class", "status")[0];
label.value = string;
},

View File

@ -320,7 +320,7 @@
<label class="text-link"
value="&resetPassword.label;"
onclick="gSyncUtils.resetPassword(); return false;"/>
</row>
</row>
<row align="center">
<label control="existingServer"
value="&server.label;"/>
@ -370,11 +370,14 @@
<description>
&existingSyncKey.description;
<label class="text-link"
value="&addDevice.showMeHow.label;"
href="https://services.mozilla.com/sync/help/manual-setup"/>
href="https://services.mozilla.com/sync/help/manual-setup">
&addDevice.showMeHow.label;
</label>
<spacer id="passphraseHelpSpacer"/>
<label class="text-link"
value="&resetSyncKey.label;"
onclick="gSyncUtils.resetPassphrase(); return false;"/>
onclick="gSyncUtils.resetPassphrase(); return false;">
&resetSyncKey.label;
</label>
</description>
</vbox>
</wizardpage>

View File

@ -77,7 +77,7 @@ let gSyncUtils = {
// Open up the change dialog
let changeXUL = "chrome://browser/content/syncGenericChange.xul";
let changeOpt = "centerscreen,chrome,dialog,modal,resizable=no";
let changeOpt = "centerscreen,chrome,resizable=no";
Weave.Svc.WinWatcher.activeWindow.openDialog(changeXUL, "", changeOpt, type);
},

View File

@ -182,7 +182,8 @@
if (!window.gShowPageResizers)
return;
var show = document.getElementById("addon-bar").collapsed;
var show = document.getElementById("addon-bar").collapsed &&
window.windowState == window.STATE_NORMAL;
for (let i = 0; i < this.browsers.length; i++) {
this.browsers[i].showWindowResizer = show;
}
@ -2864,6 +2865,7 @@
this._handleTabSelect();
this.mTabstripWidth = width;
}
this.tabbrowser.updateWindowResizers();
break;
}
]]></body>

View File

@ -24,6 +24,7 @@
* Michael Yoshitaka Erlewine <mitcho@mitcho.com>
* Ehsan Akhgari <ehsan@mozilla.com>
* Raymond Lee <raymond@appcoast.com>
* Tim Taubert <tim.taubert@gmx.de>
*
* 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
@ -491,6 +492,8 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
this.adjustTitleSize();
UI.clearShouldResizeItems();
this._updateDebugBounds();
this.setTrenches(rect);
@ -564,7 +567,6 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// Function: closeAll
// Closes the groupItem and all of its children.
closeAll: function GroupItem_closeAll() {
let closeCenter = this.getBounds().center();
if (this._children.length > 0) {
this._children.forEach(function(child) {
iQ(child.container).hide();
@ -585,6 +587,16 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
if (!this.locked.close)
this.close();
}
this._makeClosestTabActive();
},
// ----------
// Function: _makeClosestTabActive
// Make the closest tab external to this group active.
// Used when closing the group.
_makeClosestTabActive: function GroupItem__makeClosestTabActive() {
let closeCenter = this.getBounds().center();
// Find closest tab to make active
let closestTabItem = UI.getClosestTab(closeCenter);
UI.setActiveTab(closestTabItem);
@ -638,6 +650,20 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
this._cancelFadeAwayUndoButtonTimer();
// When the last non-empty groupItem is closed and there are no orphan or
// pinned tabs then create a new group with a blank tab.
let remainingGroups = GroupItems.groupItems.filter(function (groupItem) {
return (groupItem != self && groupItem.getChildren().length);
});
if (!gBrowser._numPinnedTabs && !GroupItems.getOrphanedTabs().length &&
!remainingGroups.length) {
let emptyGroups = GroupItems.groupItems.filter(function (groupItem) {
return (groupItem != self && !groupItem.getChildren().length);
});
let group = (emptyGroups.length ? emptyGroups[0] : GroupItems.newGroup());
group.newTab();
}
// when "TabClose" event is fired, the browser tab is about to close and our
// item "close" event is fired. And then, the browser tab gets closed.
// In other words, the group "close" event is fired before all browser
@ -926,6 +952,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
!options.dontClose) {
if (!GroupItems.getUnclosableGroupItemId()) {
this.close();
this._makeClosestTabActive();
} else {
// this.close(); this line is causing the leak but the leak doesn't happen after re-enabling it
}
@ -1478,8 +1505,15 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
addTab: drag.info.item.parent != self,
animate: true});
}
// remove the item from its parent if that's not the current groupItem.
// this may occur when dragging too quickly so the out event is not fired.
var groupItem = drag.info.item.parent;
if (groupItem && self !== groupItem)
groupItem.remove(drag.info.$el, {dontClose: true});
if (dropIndex !== false)
options = {index: dropIndex}
options = {index: dropIndex};
this.add(drag.info.$el, options);
GroupItems.setActiveGroupItem(this);
dropIndex = false;
@ -1556,34 +1590,21 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// Reorders the tabs in the tab bar based on the arrangment of the tabs
// shown in the groupItem.
reorderTabsBasedOnTabItemOrder: function GroupItem_reorderTabsBasedOnTabItemOrder() {
let targetIndices = null;
let indices;
let tabs = this._children.map(function (tabItem) tabItem.tab);
let self = this;
this._children.some(function(tabItem, index) {
// if no targetIndices, or it was reset, recompute
if (!targetIndices) {
let currentIndices = [tabItem.tab._tPos for each (tabItem in self._children)];
targetIndices = currentIndices.concat().sort();
// if no resorting is required, we're done!
if (currentIndices == targetIndices)
return true;
}
// Compute a target range for this tab's index
let originalIndex = tabItem.tab._tPos;
let targetRange = new Range(index ? targetIndices[index - 1] : -1,
targetIndices[index + 1] || Infinity);
tabs.forEach(function (tab, index) {
if (!indices)
indices = tabs.map(function (tab) tab._tPos);
// If the originalIndex of this tab is not within its target,
// let's move it to the targetIndex.
if (!targetRange.contains(originalIndex)) {
let targetIndex = targetIndices[index];
gBrowser.moveTabTo(tabItem.tab, targetIndex);
// force recomputing targetIndices
targetIndices = null;
let start = index ? indices[index - 1] + 1 : 0;
let end = index + 1 < indices.length ? indices[index + 1] - 1 : Infinity;
let targetRange = new Range(start, end);
if (!targetRange.contains(tab._tPos)) {
gBrowser.moveTabTo(tab, start);
indices = null;
}
return false;
});
},
@ -1676,6 +1697,14 @@ let GroupItems = {
this.groupItems = null;
},
// ----------
// Function: newGroup
// Creates a new empty group.
newGroup: function () {
let bounds = new Rect(20, 20, 250, 200);
return new GroupItem([], {bounds: bounds, immediately: true});
},
// ----------
// Function: pauseArrange
// Bypass arrange() calls and collect for resolution in
@ -1909,7 +1938,6 @@ let GroupItems = {
let groupItemsData = Storage.readGroupItemsData(gWindow);
let groupItemData = Storage.readGroupItemData(gWindow);
this.reconstitute(groupItemsData, groupItemData);
this.killNewTabGroup(); // temporary?
return (groupItemsData && !Utils.isEmptyObject(groupItemsData));
},
@ -2316,21 +2344,6 @@ let GroupItems = {
}
},
// ----------
// Function: killNewTabGroup
// Removes the New Tab Group, which is now defunct. See bug 575851 and comments therein.
killNewTabGroup: function GroupItems_killNewTabGroup() {
// not localized as the original "New Tabs" group title was never localized
// to begin with
let newTabGroupTitle = "New Tabs";
this.groupItems.forEach(function(groupItem) {
if (groupItem.getTitle() == newTabGroupTitle && groupItem.locked.title) {
groupItem.removeAll();
groupItem.close();
}
});
},
// ----------
// Function: removeHiddenGroups
// Removes all hidden groups' data and its browser tabs.

View File

@ -509,8 +509,9 @@ function hideSearch(event){
iQ("#searchbutton").css({ opacity:.8 });
let mainWindow = gWindow.document.getElementById("main-window");
mainWindow.setAttribute("activetitlebarcolor", "#C4C4C4");
#ifdef XP_MACOSX
UI.setTitlebarColors(true);
#endif
performSearch();
SearchEventHandler.switchToBeforeMode();
@ -550,8 +551,10 @@ function ensureSearchShown(){
if (!isSearchEnabled()) {
$searchShade.show();
$search.show();
var mainWindow = gWindow.document.getElementById("main-window");
mainWindow.setAttribute("activetitlebarcolor", "#717171");
#ifdef XP_MACOSX
UI.setTitlebarColors({active: "#717171", inactive: "#EDEDED"});
#endif
$searchbox[0].focus();
$searchbox[0].val = '0';

View File

@ -24,6 +24,7 @@
* Michael Yoshitaka Erlewine <mitcho@mitcho.com>
* Ehsan Akhgari <ehsan@mozilla.com>
* Raymond Lee <raymond@appcoast.com>
* Tim Taubert <tim.taubert@gmx.de>
*
* 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
@ -62,7 +63,7 @@ function TabItem(tab, options) {
var $div = iQ('<div>')
.addClass('tab')
.html("<div class='thumb'>" +
"<img class='cached-thumb' style='display:none'/><canvas moz-opaque='true'/></div>" +
"<img class='cached-thumb' style='display:none'/><canvas moz-opaque/></div>" +
"<div class='favicon'><img/></div>" +
"<span class='tab-title'>&nbsp;</span>"
)
@ -496,6 +497,8 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
this._hasBeenDrawn = true;
}
UI.clearShouldResizeItems();
this._updateDebugBounds();
rect = this.getBounds(); // ensure that it's a <Rect>
@ -806,7 +809,7 @@ let TabItems = {
this.minTabHeight = this.minTabWidth * this.tabHeight / this.tabWidth;
let $canvas = iQ("<canvas>")
.attr('moz-opaque', true);
.attr('moz-opaque', '');
$canvas.appendTo(iQ("body"));
$canvas.hide();
this.tempCanvas = $canvas[0];
@ -901,8 +904,6 @@ let TabItems = {
);
if (shouldDefer) {
if (!this.reconnectingPaused() && !tab._tabViewTabItem._reconnected)
this._reconnect(tab._tabViewTabItem);
if (this._tabsWaitingForUpdate.indexOf(tab) == -1)
this._tabsWaitingForUpdate.push(tab);
this.startHeartbeat();
@ -1017,6 +1018,9 @@ let TabItems = {
Utils.assertThrow(tab._tabViewTabItem, "should already be linked");
// note that it's ok to unlink an app tab; see .handleTabUnpin
if (tab._tabViewTabItem == GroupItems.getActiveOrphanTab())
GroupItems.setActiveOrphanTab(null);
this.unregister(tab._tabViewTabItem);
tab._tabViewTabItem._sendToSubscribers("close");
iQ(tab._tabViewTabItem.container).remove();

View File

@ -25,6 +25,7 @@
* Ehsan Akhgari <ehsan@mozilla.com>
* Raymond Lee <raymond@appcoast.com>
* Sean Dunn <seanedunn@yahoo.com>
* Tim Taubert <tim.taubert@gmx.de>
*
* 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
@ -200,11 +201,6 @@ let UI = {
}
});
iQ(window).bind("beforeunload", function() {
Array.forEach(gBrowser.tabs, function(tab) {
gBrowser.showTab(tab);
});
});
iQ(window).bind("unload", function() {
self.uninit();
});
@ -342,13 +338,15 @@ let UI = {
item.parent.remove(item);
groupItem.add(item, {immediately: true});
});
GroupItems.setActiveGroupItem(groupItem);
if (firstTime) {
gPrefBranch.setBoolPref("experienced_first_run", true);
// ensure that the first run pref is flushed to the file, in case a crash
// or force quit happens before the pref gets flushed automatically.
Services.prefs.savePrefFile(null);
/* DISABLED BY BUG 626754. To be reenabled via bug 626926.
let url = gPrefBranch.getCharPref("welcome_url");
let newTab = gBrowser.loadOneTab(url, {inBackground: true});
let newTabItem = newTab._tabViewTabItem;
@ -360,11 +358,11 @@ let UI = {
let welcomeBounds = new Rect(UI.rtl ? pageBounds.left : box.right, box.top,
welcomeWidth, welcomeWidth * aspect);
newTabItem.setBounds(welcomeBounds, true);
GroupItems.setActiveGroupItem(groupItem);
// Remove the newly created welcome-tab from the tab bar
if (!this.isTabViewVisible())
GroupItems._updateTabBar();
*/
}
},
@ -476,7 +474,7 @@ let UI = {
gBrowser.updateTitlebar();
#ifdef XP_MACOSX
this._setActiveTitleColor(true);
this.setTitlebarColors(true);
#endif
let event = document.createEvent("Events");
event.initEvent("tabviewshown", true, false);
@ -553,7 +551,7 @@ let UI = {
gBrowser.updateTitlebar();
#ifdef XP_MACOSX
this._setActiveTitleColor(false);
this.setTitlebarColors(false);
#endif
let event = document.createEvent("Events");
event.initEvent("tabviewhidden", true, false);
@ -564,19 +562,27 @@ let UI = {
#ifdef XP_MACOSX
// ----------
// Function: _setActiveTitleColor
// Function: setTitlebarColors
// Used on the Mac to make the title bar match the gradient in the rest of the
// TabView UI.
//
// Parameters:
// set - true for the special TabView color, false for the normal color.
_setActiveTitleColor: function UI__setActiveTitleColor(set) {
// colors - (bool or object) true for the special TabView color, false for
// the normal color, and an object with "active" and "inactive"
// properties to specify directly.
setTitlebarColors: function UI_setTitlebarColors(colors) {
// Mac Only
var mainWindow = gWindow.document.getElementById("main-window");
if (set)
if (colors === true) {
mainWindow.setAttribute("activetitlebarcolor", "#C4C4C4");
else
mainWindow.setAttribute("inactivetitlebarcolor", "#EDEDED");
} else if (colors && "active" in colors && "inactive" in colors) {
mainWindow.setAttribute("activetitlebarcolor", colors.active);
mainWindow.setAttribute("inactivetitlebarcolor", colors.inactive);
} else {
mainWindow.removeAttribute("activetitlebarcolor");
mainWindow.removeAttribute("inactivetitlebarcolor");
}
},
#endif
@ -1202,16 +1208,21 @@ let UI = {
if (!this._pageBounds)
return;
// If TabView isn't focused and is not showing, don't perform a resize.
// This resize really slows things down.
// Here are reasons why we *won't* resize:
// 1. Panorama isn't visible (in which case we will resize when we do display)
// 2. the screen dimensions haven't changed
// 3. everything on the screen fits and nothing feels cramped
if (!force && !this.isTabViewVisible())
return;
var oldPageBounds = new Rect(this._pageBounds);
var newPageBounds = Items.getPageBounds();
let oldPageBounds = new Rect(this._pageBounds);
let newPageBounds = Items.getPageBounds();
if (newPageBounds.equals(oldPageBounds))
return;
if (!this.shouldResizeItems())
return;
var items = Items.getTopLevelItems();
// compute itemBounds: the union of all the top-level items' bounds.
@ -1279,6 +1290,58 @@ let UI = {
this._pageBounds = Items.getPageBounds();
this._save();
},
// ----------
// Function: shouldResizeItems
// Returns whether we should resize the items on the screen, based on whether
// the top-level items fit in the screen or not and whether they feel
// "cramped" or not.
// These computations may be done using cached values. The cache can be
// cleared with UI.clearShouldResizeItems().
shouldResizeItems: function UI_shouldResizeItems() {
let newPageBounds = Items.getPageBounds();
// If we don't have cached cached values...
if (this._minimalRect === undefined || this._feelsCramped === undefined) {
// Loop through every top-level Item for two operations:
// 1. check if it is feeling "cramped" due to squishing (a technical term),
// 2. union its bounds with the minimalRect
let feelsCramped = false;
let minimalRect = new Rect(0, 0, 1, 1);
Items.getTopLevelItems()
.forEach(function UI_shouldResizeItems_checkItem(item) {
let bounds = new Rect(item.getBounds());
feelsCramped = feelsCramped || (item.userSize &&
(item.userSize.x > bounds.width || item.userSize.y > bounds.height));
bounds.inset(-Trenches.defaultRadius, -Trenches.defaultRadius);
minimalRect = minimalRect.union(bounds);
});
// ensure the minimalRect extends to, but not beyond, the origin
minimalRect.left = 0;
minimalRect.top = 0;
this._minimalRect = minimalRect;
this._feelsCramped = feelsCramped;
}
return this._minimalRect.width > newPageBounds.width ||
this._minimalRect.height > newPageBounds.height ||
this._feelsCramped;
},
// ----------
// Function: clearShouldResizeItems
// Clear the cache of whether we should resize the items on the Panorama
// screen, forcing a recomputation on the next UI.shouldResizeItems()
// call.
clearShouldResizeItems: function UI_clearShouldResizeItems() {
delete this._minimalRect;
delete this._feelsCramped;
},
// ----------
// Function: exit
@ -1302,14 +1365,17 @@ let UI = {
let unhiddenGroups = GroupItems.groupItems.filter(function(groupItem) {
return (!groupItem.hidden && groupItem.getChildren().length > 0);
});
// no visible groups, no orphaned tabs and no apps tabs, open a new group
// with a blank tab
if (unhiddenGroups.length == 0 && GroupItems.getOrphanedTabs().length == 0 &&
gBrowser._numPinnedTabs == 0) {
let box = new Rect(20, 20, 250, 200);
let groupItem = new GroupItem([], { bounds: box, immediately: true });
groupItem.newTab();
return;
// no pinned tabs, no visible groups and no orphaned tabs: open a new
// group. open a blank tab and return
if (!unhiddenGroups.length && !GroupItems.getOrphanedTabs().length) {
let emptyGroups = GroupItems.groupItems.filter(function (groupItem) {
return (!groupItem.hidden && !groupItem.getChildren().length);
});
let group = (emptyGroups.length ? emptyGroups[0] : GroupItems.newGroup());
if (!gBrowser._numPinnedTabs) {
group.newTab();
return;
}
}
// If there's an active TabItem, zoom into it. If not (for instance when the

View File

@ -170,6 +170,7 @@ _BROWSER_FILES = \
browser_bug624734.js \
browser_contextSearchTabPosition.js \
browser_ctrlTab.js \
browser_customize_popupNotification.js \
browser_disablechrome.js \
browser_discovery.js \
browser_duplicateIDs.js \

View File

@ -110,14 +110,6 @@ function test_blocked_install() {
"software on your computer.",
"Should have seen the right message");
// Click on Allow
EventUtils.synthesizeMouse(notification.button, 20, 10, {});
// Notification should have changed to progress notification
ok(PopupNotifications.isPanelOpen, "Notification should still be open");
notification = aPanel.childNodes[0];
is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
// Wait for the install confirmation dialog
wait_for_install_dialog(function(aWindow) {
// Wait for the complete notification
@ -140,6 +132,15 @@ function test_blocked_install() {
aWindow.document.documentElement.acceptDialog();
});
// Click on Allow
EventUtils.synthesizeMouse(notification.button, 20, 10, {});
// Notification should have changed to progress notification
ok(PopupNotifications.isPanelOpen, "Notification should still be open");
notification = aPanel.childNodes[0];
is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
});
var triggers = encodeURIComponent(JSON.stringify({
@ -705,15 +706,6 @@ function test_cancel_restart() {
notification = aPanel.childNodes[0];
is(notification.id, "addon-install-cancelled-notification", "Should have seen the cancelled notification");
// Restart the download
EventUtils.synthesizeMouse(notification.button, 20, 10, {});
// Should be back to a progress notification
ok(PopupNotifications.isPanelOpen, "Notification should still be open");
is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
notification = aPanel.childNodes[0];
is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
// Wait for the install confirmation dialog
wait_for_install_dialog(function(aWindow) {
// Wait for the complete notification
@ -737,6 +729,16 @@ function test_cancel_restart() {
aWindow.document.documentElement.acceptDialog();
});
// Restart the download
EventUtils.synthesizeMouse(notification.button, 20, 10, {});
// Should be back to a progress notification
ok(PopupNotifications.isPanelOpen, "Notification should still be open");
is(PopupNotifications.panel.childNodes.length, 1, "Should be only one notification");
notification = aPanel.childNodes[0];
is(notification.id, "addon-progress-notification", "Should have seen the progress notification");
});
});

View File

@ -0,0 +1,29 @@
/*
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
*/
function test() {
waitForExplicitFinish();
var newWin = openDialog(location, "", "chrome,all,dialog=no", "about:blank");
registerCleanupFunction(function () {
newWin.close();
});
newWin.addEventListener("load", function test_win_onLoad() {
// Remove the URL bar
newWin.gURLBar.parentNode.removeChild(newWin.gURLBar);
waitForFocus(function () {
let PN = newWin.PopupNotifications;
try {
let notification = PN.show(newWin.gBrowser.selectedBrowser, "some-notification", "Some message");
ok(notification, "showed the notification");
ok(PN.isPanelOpen, "panel is open");
is(PN.panel.anchorNode, newWin.gBrowser.selectedTab, "notification is correctly anchored to the tab");
} catch (ex) {
ok(false, "threw exception: " + ex);
}
finish();
}, newWin);
}, false);
}

View File

@ -58,6 +58,7 @@ function cleanUp() {
var gActiveListeners = {};
var gActiveObservers = {};
var gShownState = {};
function runNextTest() {
let nextTest = tests[gTestIndex];
@ -91,6 +92,7 @@ function runNextTest() {
info("[Test #" + gTestIndex + "] popup showing");
});
doOnPopupEvent("popupshown", function () {
gShownState[gTestIndex] = true;
info("[Test #" + gTestIndex + "] popup shown");
nextTest.onShown(this);
});
@ -101,6 +103,11 @@ function runNextTest() {
nextTest.onHidden :
[nextTest.onHidden];
doOnPopupEvent("popuphidden", function () {
if (!gShownState[gTestIndex]) {
// This is expected to happen for test 9, so let's not treat it as a failure.
info("Popup from test " + gTestIndex + " was hidden before its popupshown fired");
}
let onHidden = onHiddenArray.shift();
info("[Test #" + gTestIndex + "] popup hidden (" + onHiddenArray.length + " hides remaining)");
onHidden.call(nextTest, this);

View File

@ -4,45 +4,60 @@
var gTab = null;
function cleanUp() {
gBrowser.removeTab(gTab);
finish();
}
// function borrowed from browser_bug386835.js
function load(tab, url, cb) {
tab.linkedBrowser.addEventListener("load", function (event) {
event.currentTarget.removeEventListener("load", arguments.callee, true);
function load(url, cb) {
gTab = gBrowser.addTab(url);
gBrowser.addEventListener("load", function (event) {
gBrowser.removeEventListener("load", arguments.callee, true);
// Trigger onLocationChange by switching tabs.
gBrowser.selectedTab = gTab;
cb();
}, true);
tab.linkedBrowser.loadURI(url);
}
function test() {
waitForExplicitFinish();
gTab = gBrowser.selectedTab = gBrowser.addTab();
ok(gFindBar.hidden, "Find bar should not be visible");
run_test_1();
}
function run_test_1() {
load(gTab, "about:config", function() {
load("about:config", 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_2();
});
}
function run_test_2() {
load(gTab, "about:addons", function() {
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");
cleanUp();
gBrowser.removeTab(gTab);
run_test_3();
});
}
function run_test_3() {
load("about:blank", function() {
ok(!document.getElementById("cmd_find").getAttribute("disabled"),
"Find command should not be disabled");
gBrowser.removeTab(gTab);
finish();
});
}

View File

@ -72,6 +72,7 @@ _BROWSER_FILES = \
browser_tabview_bug598600.js \
browser_tabview_bug599626.js \
browser_tabview_bug600645.js \
browser_tabview_bug600812.js \
browser_tabview_bug604098.js \
browser_tabview_bug606657.js \
browser_tabview_bug606905.js \
@ -79,12 +80,17 @@ _BROWSER_FILES = \
browser_tabview_bug608184.js \
browser_tabview_bug608158.js \
browser_tabview_bug610242.js \
browser_tabview_bug613541.js \
browser_tabview_bug616729.js \
browser_tabview_bug616967.js \
browser_tabview_bug618828.js \
browser_tabview_bug619937.js \
browser_tabview_bug622835.js \
browser_tabview_bug622872.js \
browser_tabview_bug624265.js \
browser_tabview_bug624953.js \
browser_tabview_bug625269.js \
browser_tabview_bug627736.js \
browser_tabview_dragdrop.js \
browser_tabview_exit_button.js \
browser_tabview_expander.js \

View File

@ -83,10 +83,10 @@ function onTabViewWindowHidden() {
is(moves, 1, "Only one move should be necessary for this basic move.");
is(originalTab._tPos, 1, "Original tab is in position 0");
is(newTabs[0]._tPos, 2, "Robots is in position 1");
is(newTabs[1]._tPos, 3, "Mozilla is in position 2");
is(newTabs[2]._tPos, 0, "Credits is in position 3");
is(newTabs[2]._tPos, 0, "Credits is in position 0");
is(originalTab._tPos, 1, "Original tab is in position 1");
is(newTabs[0]._tPos, 2, "Robots is in position 2");
is(newTabs[1]._tPos, 3, "Mozilla is in position 3");
gBrowser.removeTab(newTabs[0]);
gBrowser.removeTab(newTabs[1]);

View File

@ -11,14 +11,15 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Weave.
* The Original Code is a test for bug 600812.
*
* The Initial Developer of the Original Code is Mozilla.
* Portions created by the Initial Developer are Copyright (C) 2009
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Jono DiCarlo <jdicarlo@mozilla.com>
* Tim Taubert <tim.taubert@gmx.de>
*
* 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
@ -34,25 +35,45 @@
*
* ***** END LICENSE BLOCK ***** */
const EXPORTED_SYMBOLS = ['TabSetRecord'];
function test() {
let cw;
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cr = Components.results;
const Cu = Components.utils;
let createGroupItem = function () {
let bounds = new cw.Rect(20, 20, 150, 150);
let groupItem = new cw.GroupItem([], {bounds: bounds, immediately: true});
Cu.import("resource://services-sync/base_records/crypto.js");
Cu.import("resource://services-sync/util.js");
cw.GroupItems.setActiveGroupItem(groupItem);
gBrowser.loadOneTab('about:blank', {inBackground: true});
const TABS_TTL = 604800; // 7 days
return groupItem;
}
function TabSetRecord(collection, id) {
CryptoWrapper.call(this, collection, id);
let testVeryQuickDragAndDrop = function () {
let sourceGroup = cw.GroupItems.groupItems[0];
let targetGroup = createGroupItem();
sourceGroup.pushAway(true);
targetGroup.pushAway(true);
let sourceTab = sourceGroup.getChild(0).container;
EventUtils.synthesizeMouseAtCenter(sourceTab, {type: 'mousedown'}, cw);
let targetTab = targetGroup.getChild(0).container;
EventUtils.synthesizeMouseAtCenter(targetTab, {type: 'mousemove'}, cw);
EventUtils.synthesizeMouseAtCenter(targetTab, {type: 'mouseup'}, cw);
is(targetGroup.getChildren().length, 2, 'target group has two tabs');
is(cw.GroupItems.groupItems.length, 1, 'sourceGroup was closed');
isnot(cw.GroupItems.groupItems[0], sourceGroup, 'sourceGroup was closed');
targetGroup.getChild(0).close();
hideTabView(finish);
}
waitForExplicitFinish();
showTabView(function () {
cw = TabView.getContentWindow();
afterAllTabsLoaded(testVeryQuickDragAndDrop);
});
}
TabSetRecord.prototype = {
__proto__: CryptoWrapper.prototype,
_logName: "Record.Tabs",
ttl: TABS_TTL
};
Utils.deferGetSet(TabSetRecord, "cleartext", ["clientName", "tabs"]);

View File

@ -0,0 +1,396 @@
/* ***** 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 a test for bug 613541.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Tim Taubert <tim.taubert@gmx.de>
*
* 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 ***** */
function test() {
let cw;
let currentTest;
let getGroupItem = function (index) {
return cw.GroupItems.groupItems[index];
}
let createGroupItem = function (numTabs) {
let bounds = new cw.Rect(20, 20, 200, 200);
let groupItem = new cw.GroupItem([], {bounds: bounds, immediately: true});
cw.GroupItems.setActiveGroupItem(groupItem);
for (let i=0; i<numTabs || 0; i++)
gBrowser.loadOneTab('about:blank', {inBackground: true});
return groupItem;
}
let hideGroupItem = function (groupItem, callback) {
groupItem.addSubscriber(groupItem, 'groupHidden', function () {
groupItem.removeSubscriber(groupItem, 'groupHidden');
callback();
});
groupItem.closeAll();
}
let closeGroupItem = function (groupItem, callback) {
afterAllTabsLoaded(function () {
hideGroupItem(groupItem, function () {
groupItem.closeHidden();
callback();
});
});
}
let tests = [];
let next = function () {
let test = tests.shift();
if (test) {
// check that the previous test left things as expected
if (currentTest) {
currentTest += ' (post-check)';
assertTabViewIsHidden();
assertNumberOfGroupItems(1);
assertNumberOfTabs(1);
}
currentTest = test.name;
showTabView(test.func);
} else
hideTabView(finish);
}
let assertTabViewIsHidden = function () {
ok(!TabView.isVisible(), currentTest + ': tabview is hidden');
}
let assertNumberOfGroupItems = function (num) {
is(cw.GroupItems.groupItems.length, num, currentTest + ': number of groupItems is equal to ' + num);
}
let assertNumberOfTabs = function (num) {
is(gBrowser.tabs.length, num, currentTest + ': number of tabs is equal to ' + num);
}
let assertGroupItemRemoved = function (groupItem) {
is(cw.GroupItems.groupItems.indexOf(groupItem), -1, currentTest + ': groupItem was removed');
}
let assertGroupItemExists = function (groupItem) {
isnot(cw.GroupItems.groupItems.indexOf(groupItem), -1, currentTest + ': groupItem still exists');
}
// setup: 1 non-empty group
// action: close the group
// expected: new group with blank tab is created and zoomed into
let testSingleGroup1 = function () {
let groupItem = getGroupItem(0);
closeGroupItem(groupItem, function () {
assertNumberOfGroupItems(1);
assertGroupItemRemoved(groupItem);
whenTabViewIsHidden(next);
});
}
// setup: 1 non-empty group
// action: hide the group, exit panorama
// expected: new group with blank tab is created and zoomed into
let testSingleGroup2 = function () {
let groupItem = getGroupItem(0);
hideGroupItem(groupItem, function () {
hideTabView(function () {
assertNumberOfGroupItems(1);
assertGroupItemRemoved(groupItem);
next();
});
});
}
// setup: 2 non-empty groups
// action: close one group
// expected: nothing should happen
let testNonEmptyGroup1 = function () {
let groupItem = getGroupItem(0);
let newGroupItem = createGroupItem(1);
assertNumberOfGroupItems(2);
closeGroupItem(groupItem, function () {
assertNumberOfGroupItems(1);
assertGroupItemExists(newGroupItem);
hideTabView(next);
});
}
// setup: 2 non-empty groups
// action: hide one group, exit panorama
// expected: nothing should happen
let testNonEmptyGroup2 = function () {
let groupItem = getGroupItem(0);
let newGroupItem = createGroupItem(1);
assertNumberOfGroupItems(2);
hideGroupItem(groupItem, function () {
hideTabView(function () {
assertNumberOfGroupItems(1);
assertGroupItemRemoved(groupItem);
assertGroupItemExists(newGroupItem);
next();
});
});
}
// setup: 1 pinned tab, 1 empty group
// action: exit panorama
// expected: nothing should happen
let testPinnedTab1 = function () {
gBrowser.pinTab(gBrowser.selectedTab);
let groupItem = getGroupItem(0);
hideTabView(function () {
assertNumberOfGroupItems(1);
assertGroupItemExists(groupItem);
gBrowser.unpinTab(gBrowser.selectedTab);
next();
});
}
// setup: 1 pinned tab
// action: exit panorama
// expected: new blank group is created
let testPinnedTab2 = function () {
gBrowser.pinTab(gBrowser.selectedTab);
getGroupItem(0).close();
hideTabView(function () {
assertNumberOfTabs(1);
assertNumberOfGroupItems(1);
gBrowser.unpinTab(gBrowser.selectedTab);
next();
});
}
// setup: 1 pinned tab, 1 empty group, 1 non-empty group
// action: close non-empty group
// expected: nothing should happen
let testPinnedTab3 = function () {
gBrowser.pinTab(gBrowser.selectedTab);
let groupItem = getGroupItem(0);
let newGroupItem = createGroupItem(1);
assertNumberOfGroupItems(2);
closeGroupItem(newGroupItem, function () {
assertNumberOfGroupItems(1);
assertGroupItemExists(groupItem);
gBrowser.unpinTab(gBrowser.selectedTab);
hideTabView(next);
});
}
// setup: 1 pinned tab, 1 empty group, 1 non-empty group
// action: hide non-empty group, exit panorama
// expected: nothing should happen
let testPinnedTab4 = function () {
gBrowser.pinTab(gBrowser.selectedTab);
let groupItem = getGroupItem(0);
let newGroupItem = createGroupItem(1);
assertNumberOfGroupItems(2);
hideGroupItem(newGroupItem, function () {
hideTabView(function () {
assertNumberOfGroupItems(1);
assertGroupItemExists(groupItem);
assertGroupItemRemoved(newGroupItem);
gBrowser.unpinTab(gBrowser.selectedTab);
next();
});
});
}
// setup: 1 orphan tab
// action: exit panorama
// expected: nothing should happen
let testOrphanTab1 = function () {
let groupItem = getGroupItem(0);
let tabItem = groupItem.getChild(0);
groupItem.remove(tabItem);
hideTabView(function () {
assertNumberOfGroupItems(0);
createGroupItem().add(tabItem);
next();
});
}
// setup: 1 orphan tab, 1 non-empty group
// action: close the group
// expected: nothing should happen
let testOrphanTab2 = function () {
let groupItem = getGroupItem(0);
let tabItem = groupItem.getChild(0);
groupItem.remove(tabItem);
assertNumberOfGroupItems(0);
let newGroupItem = createGroupItem(1);
assertNumberOfGroupItems(1);
closeGroupItem(newGroupItem, function () {
assertNumberOfGroupItems(0);
createGroupItem().add(tabItem);
hideTabView(next);
});
}
// setup: 1 orphan tab, 1 non-empty group
// action: hide the group, exit panorama
// expected: nothing should happen
let testOrphanTab3 = function () {
let groupItem = getGroupItem(0);
let tabItem = groupItem.getChild(0);
groupItem.remove(tabItem);
assertNumberOfGroupItems(0);
let newGroupItem = createGroupItem(1);
assertNumberOfGroupItems(1);
hideGroupItem(newGroupItem, function () {
hideTabView(function () {
assertNumberOfGroupItems(0);
createGroupItem().add(tabItem);
next();
});
});
}
// setup: 1 non-empty group, 1 empty group
// action: close non-empty group
// expected: empty group is re-used, new tab is created and zoomed into
let testEmptyGroup1 = function () {
let groupItem = getGroupItem(0);
let newGroupItem = createGroupItem(0);
assertNumberOfGroupItems(2);
closeGroupItem(groupItem, function () {
assertNumberOfGroupItems(1);
assertGroupItemExists(newGroupItem);
whenTabViewIsHidden(next);
});
}
// setup: 1 non-empty group, 1 empty group
// action: hide non-empty group, exit panorama
// expected: empty group is re-used, new tab is created and zoomed into
let testEmptyGroup2 = function () {
let groupItem = getGroupItem(0);
let newGroupItem = createGroupItem(0);
assertNumberOfGroupItems(2);
hideGroupItem(groupItem, function () {
hideTabView(function () {
assertNumberOfGroupItems(1);
assertGroupItemRemoved(groupItem);
assertGroupItemExists(newGroupItem);
next();
});
});
}
// setup: 1 hidden group, 1 non-empty group
// action: close non-empty group
// expected: nothing should happen
let testHiddenGroup1 = function () {
let groupItem = getGroupItem(0);
let hiddenGroupItem = createGroupItem(1);
assertNumberOfGroupItems(2);
hideGroupItem(hiddenGroupItem, function () {
closeGroupItem(groupItem, function () {
assertNumberOfGroupItems(1);
assertGroupItemRemoved(groupItem);
assertGroupItemExists(hiddenGroupItem);
hideTabView(next);
});
});
}
// setup: 1 hidden group, 1 non-empty group
// action: hide non-empty group, exit panorama
// expected: new group with blank tab is created and zoomed into
let testHiddenGroup2 = function () {
let groupItem = getGroupItem(0);
let hiddenGroupItem = createGroupItem(1);
assertNumberOfGroupItems(2);
hideGroupItem(hiddenGroupItem, function () {
hideGroupItem(groupItem, function () {
hideTabView(function () {
assertNumberOfGroupItems(1);
assertGroupItemRemoved(groupItem);
assertGroupItemRemoved(hiddenGroupItem);
next();
});
});
});
}
tests.push({name: 'testSingleGroup1', func: testSingleGroup1});
tests.push({name: 'testSingleGroup2', func: testSingleGroup2});
tests.push({name: 'testNonEmptyGroup1', func: testNonEmptyGroup1});
tests.push({name: 'testNonEmptyGroup2', func: testNonEmptyGroup2});
tests.push({name: 'testPinnedTab1', func: testPinnedTab1});
tests.push({name: 'testPinnedTab2', func: testPinnedTab2});
tests.push({name: 'testPinnedTab3', func: testPinnedTab3});
tests.push({name: 'testPinnedTab4', func: testPinnedTab4});
tests.push({name: 'testOrphanTab1', func: testOrphanTab1});
tests.push({name: 'testOrphanTab2', func: testOrphanTab2});
tests.push({name: 'testOrphanTab3', func: testOrphanTab3});
tests.push({name: 'testEmptyGroup1', func: testEmptyGroup1});
tests.push({name: 'testEmptyGroup2', func: testEmptyGroup2});
tests.push({name: 'testHiddenGroup1', func: testHiddenGroup1});
tests.push({name: 'testHiddenGroup2', func: testHiddenGroup2}),
waitForExplicitFinish();
showTabView(function () {
cw = TabView.getContentWindow();
next();
});
}

View File

@ -0,0 +1,157 @@
/* ***** 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 a test for bug 616729.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Tim Taubert <tim.taubert@gmx.de>
*
* 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 ***** */
function test() {
let cw;
let createGroupItem = function () {
let bounds = new cw.Rect(20, 20, 400, 200);
let groupItem = new cw.GroupItem([], {bounds: bounds, immediately: true});
cw.GroupItems.setActiveGroupItem(groupItem);
for (let i=0; i<5; i++)
gBrowser.loadOneTab('about:blank', {inBackground: true});
return groupItem;
}
let assertCorrectItemOrder = function (items) {
for (let i=1; i<items.length; i++) {
if (items[i-1].tab._tPos > items[i].tab._tPos) {
ok(false, 'tabs were correctly reordered');
break;
}
}
}
let testVariousTabOrders = function () {
let groupItem = createGroupItem();
let [tab1, tab2, tab3, tab4, tab5] = groupItem.getChildren();
// prepare tests
let tests = [];
tests.push([tab1, tab2, tab3, tab4, tab5]);
tests.push([tab5, tab4, tab3, tab2, tab1]);
tests.push([tab1, tab2, tab3, tab4]);
tests.push([tab4, tab3, tab2, tab1]);
tests.push([tab1, tab2, tab3]);
tests.push([tab1, tab2, tab3]);
tests.push([tab1, tab3, tab2]);
tests.push([tab2, tab1, tab3]);
tests.push([tab2, tab3, tab1]);
tests.push([tab3, tab1, tab2]);
tests.push([tab3, tab2, tab1]);
tests.push([tab1, tab2]);
tests.push([tab2, tab1]);
tests.push([tab1]);
// test reordering of empty groups - removes the last tab and causes
// the groupItem to close
tests.push([]);
while (tests.length) {
let test = tests.shift();
// prepare
let items = groupItem.getChildren();
while (test.length < items.length)
items[items.length-1].close();
let orig = cw.Utils.copy(items);
items.sort(function (a, b) test.indexOf(a) - test.indexOf(b));
// order and check
groupItem.reorderTabsBasedOnTabItemOrder();
assertCorrectItemOrder(items);
// revert to original item order
items.sort(function (a, b) orig.indexOf(a) - orig.indexOf(b));
groupItem.reorderTabsBasedOnTabItemOrder();
}
testMoveBetweenGroups();
}
let testMoveBetweenGroups = function () {
let groupItem = createGroupItem();
let groupItem2 = createGroupItem();
afterAllTabsLoaded(function () {
// move item from group1 to group2
let child = groupItem.getChild(2);
groupItem.remove(child);
groupItem2.add(child, {index: 3});
groupItem2.reorderTabsBasedOnTabItemOrder();
assertCorrectItemOrder(groupItem.getChildren());
assertCorrectItemOrder(groupItem2.getChildren());
// move item from group2 to group1
child = groupItem2.getChild(1);
groupItem2.remove(child);
groupItem.add(child, {index: 1});
groupItem.reorderTabsBasedOnTabItemOrder();
assertCorrectItemOrder(groupItem.getChildren());
assertCorrectItemOrder(groupItem2.getChildren());
// cleanup
groupItem.addSubscriber(groupItem, 'groupHidden', function () {
groupItem.removeSubscriber(groupItem, 'groupHidden');
groupItem.closeHidden();
groupItem2.closeAll();
});
groupItem2.addSubscriber(groupItem, 'groupHidden', function () {
groupItem2.removeSubscriber(groupItem, 'groupHidden');
groupItem2.closeHidden();
hideTabView(finish);
});
groupItem.closeAll();
});
}
waitForExplicitFinish();
showTabView(function () {
cw = TabView.getContentWindow();
afterAllTabsLoaded(testVariousTabOrders);
});
}

View File

@ -0,0 +1,156 @@
/* ***** 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 bug 622872 test.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Michael Yoshitaka Erlewine <mitcho@mitcho.com>
* 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 ***** */
function test() {
waitForExplicitFinish();
newWindowWithTabView(part1);
}
// PART 1:
// 1. Create a new tab (called newTab)
// 2. Orphan it. Activate this orphan tab.
// 3. Zoom into it.
function part1(win) {
ok(win.TabView.isVisible(), "Tab View is visible");
let contentWindow = win.document.getElementById("tab-view").contentWindow;
is(win.gBrowser.tabs.length, 1, "In the beginning, there was one tab.");
let [originalTab] = win.gBrowser.visibleTabs;
let originalGroup = contentWindow.GroupItems.getActiveGroupItem();
ok(originalGroup.getChildren().some(function(child) {
return child == originalTab._tabViewTabItem;
}),"The current active group is the one with the original tab in it.");
// Create a new tab and orphan it
let newTab = win.gBrowser.loadOneTab("about:mozilla", {inBackground: true});
let newTabItem = newTab._tabViewTabItem;
ok(originalGroup.getChildren().some(function(child) child == newTabItem),"The new tab was made in the current group");
contentWindow.GroupItems.getActiveGroupItem().remove(newTabItem);
ok(!originalGroup.getChildren().some(function(child) child == newTabItem),"The new tab was orphaned");
newTabItem.pushAway();
// activate this tab item
contentWindow.UI.setActiveTab(newTabItem);
// PART 2: close this orphan tab (newTab)
let part2 = function part2() {
win.removeEventListener("tabviewhidden", part2, false);
is(win.gBrowser.selectedTab, newTab, "We zoomed into that new tab.");
ok(!win.TabView.isVisible(), "Tab View is hidden, because we're looking at the new tab");
newTab.addEventListener("TabClose", function() {
newTab.removeEventListener("TabClose", arguments.callee, false);
win.addEventListener("tabviewshown", part3, false);
executeSoon(function() { win.TabView.toggle(); });
}, false);
win.gBrowser.removeTab(newTab);
}
let secondNewTab;
// PART 3: now back in Panorama, open a new tab via the "new tab" menu item (or equivalent)
// We call this secondNewTab.
let part3 = function part3() {
win.removeEventListener("tabviewshown", part3, false);
ok(win.TabView.isVisible(), "Tab View is visible.");
is(win.gBrowser.tabs.length, 1, "Only one tab again.");
is(win.gBrowser.tabs[0], originalTab, "That one tab is the original tab.");
let groupItems = contentWindow.GroupItems.groupItems;
is(groupItems.length, 1, "Only one group");
ok(!contentWindow.GroupItems.getActiveOrphanTab(), "There is no active orphan tab.");
ok(win.TabView.isVisible(), "Tab View is visible.");
win.gBrowser.tabContainer.addEventListener("TabSelect", function() {
win.gBrowser.tabContainer.removeEventListener("TabSelect", arguments.callee, false);
executeSoon(part4);
}, false);
win.document.getElementById("cmd_newNavigatorTab").doCommand();
}
// PART 4: verify it opened in the original group, and go back into Panorama
let part4 = function part4() {
ok(!win.TabView.isVisible(), "Tab View is hidden");
is(win.gBrowser.tabs.length, 2, "There are two tabs total now.");
is(win.gBrowser.visibleTabs.length, 2, "We're looking at both of them.");
let foundOriginalTab = false;
// we can't use forEach because win.gBrowser.tabs is only array-like.
for (let i = 0; i < win.gBrowser.tabs.length; i++) {
let tab = win.gBrowser.tabs[i];
if (tab === originalTab)
foundOriginalTab = true;
else
secondNewTab = tab;
}
ok(foundOriginalTab, "One of those tabs is the original tab.");
ok(secondNewTab, "We found another tab... this is secondNewTab");
is(win.gBrowser.selectedTab, secondNewTab, "This second new tab is what we're looking at.");
win.addEventListener("tabviewshown", part5, false);
win.TabView.toggle();
}
// PART 5: make sure we only have one group with both tabs now, and finish.
let part5 = function part5() {
win.removeEventListener("tabviewshown", part5, false);
is(win.gBrowser.tabs.length, 2, "There are of course still two tabs.");
let groupItems = contentWindow.GroupItems.groupItems;
is(groupItems.length, 1, "There is one group now");
is(groupItems[0], originalGroup, "It's the original group.");
is(originalGroup.getChildren().length, 2, "It has two children.");
// finish!
win.close();
finish();
}
// Okay, all set up now. Let's get this party started!
afterAllTabItemsUpdated(function() {
win.addEventListener("tabviewhidden", part2, false);
win.TabView.toggle();
}, win);
}

View File

@ -0,0 +1,111 @@
/* ***** 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 bug 625269 test.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Michael Yoshitaka Erlewine <mitcho@mitcho.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 ***** */
function test() {
waitForExplicitFinish();
newWindowWithTabView(onTabViewWindowLoaded);
}
function onTabViewWindowLoaded(win) {
win.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
ok(win.TabView.isVisible(), "Tab View is visible");
let contentWindow = win.document.getElementById("tab-view").contentWindow;
let [originalTab] = win.gBrowser.visibleTabs;
let currentGroup = contentWindow.GroupItems.getActiveGroupItem();
currentGroup.setSize(600, 600, true);
currentGroup.setUserSize();
let down1 = function down1(resized) {
checkResized(currentGroup, 50, 50, false, "A little bigger", up1, contentWindow, win);
};
let up1 = function up1(resized) {
checkResized(currentGroup, -400, -400, true, "Much smaller", down2, contentWindow, win);
}
let down2 = function down2(resized) {
checkResized(currentGroup, 400, 400, undefined,
"Bigger after much smaller: TODO (bug 625668): the group should be resized!",
up2, contentWindow, win);
};
let up2 = function up2(resized) {
checkResized(currentGroup, -400, -400, undefined,
"Much smaller: TODO (bug 625668): the group should be resized!",
down3, contentWindow, win);
}
let down3 = function down3(resized) {
// reset the usersize of the group, so this should clear the "cramped" feeling.
currentGroup.setSize(100,100,true);
currentGroup.setUserSize();
checkResized(currentGroup, 400, 400, false,
"After clearing the cramp",
up3, contentWindow, win);
};
let up3 = function up3(resized) {
win.close();
finish();
}
// start by making it a little smaller.
checkResized(currentGroup, -50, -50, false, "A little smaller", down1, contentWindow, win);
}
function simulateResizeBy(xDiff, yDiff, win) {
win = win || window;
win.resizeBy(xDiff, yDiff);
}
function checkResized(item, xDiff, yDiff, expectResized, note, callback, contentWindow, win) {
let originalBounds = new contentWindow.Rect(item.getBounds());
simulateResizeBy(xDiff, yDiff, win);
let newBounds = item.getBounds();
let resized = !newBounds.equals(originalBounds);
if (expectResized !== undefined)
is(resized, expectResized, note + ": The group should " +
(expectResized ? "" : "not ") + "be resized");
callback(resized);
}

View File

@ -0,0 +1,95 @@
/* ***** 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 Panorama bug 627736 (post-group close focus) test.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Michael Yoshitaka Erlewine <mitcho@mitcho.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 ***** */
function test() {
waitForExplicitFinish();
newWindowWithTabView(onTabViewWindowLoaded);
}
function onTabViewWindowLoaded(win) {
ok(win.TabView.isVisible(), "Tab View is visible");
let contentWindow = win.document.getElementById("tab-view").contentWindow;
let [originalTab] = win.gBrowser.visibleTabs;
let originalGroup = contentWindow.GroupItems.getActiveGroupItem();
// open a group with a tab, and close either the group or the tab.
function openAndClose(groupOrTab, callback) {
// let's create a group with a tab.
let group = new contentWindow.GroupItem([], {
immediately: true,
bounds: {left: 20, top: 20, width: 400, height: 400}
});
contentWindow.GroupItems.setActiveGroupItem(group);
win.gBrowser.loadOneTab('about:blank', {inBackground: true});
is(group.getChildren().length, 1, "The group has one child now.");
let tab = group.getChild(0);
function check() {
if (groupOrTab == 'group') {
group.removeSubscriber(group, "groupHidden", check);
group.closeHidden();
} else
tab.removeSubscriber(tab, "tabRemoved", check);
is(contentWindow.GroupItems.getActiveGroupItem(), originalGroup,
"The original group is active.");
is(contentWindow.UI.getActiveTab(), originalTab._tabViewTabItem,
"The original tab is active");
callback();
}
if (groupOrTab == 'group') {
group.addSubscriber(group, "groupHidden", check);
group.closeAll();
} else {
tab.addSubscriber(tab, "tabRemoved", check);
tab.close();
}
}
// PHASE 1: create a group with a tab and close the group.
openAndClose("group", function postPhase1() {
// PHASE 2: create a group with a tab and close the tab.
openAndClose("tab", function postPhase2() {
win.close();
finish();
});
});
}

View File

@ -60,14 +60,16 @@ function experienced() {
function checkFirstRun(win) {
let contentWindow = win.document.getElementById("tab-view").contentWindow;
is(win.gBrowser.tabs.length, 2, "There should be two tabs");
// Welcome tab disabled by bug 626754. To be fixed via bug 626926.
todo_is(win.gBrowser.tabs.length, 2, "There should be two tabs");
let groupItems = contentWindow.GroupItems.groupItems;
is(groupItems.length, 1, "There should be one group");
is(groupItems[0].getChildren().length, 1, "...with one child");
let orphanTabCount = contentWindow.GroupItems.getOrphanedTabs().length;
is(orphanTabCount, 1, "There should also be an orphaned tab");
// Welcome tab disabled by bug 626754. To be fixed via bug 626926.
todo_is(orphanTabCount, 1, "There should also be an orphaned tab");
ok(experienced(), "we're now experienced");
}

View File

@ -783,7 +783,8 @@
overLink.style.maxWidth = maxWidth + "px";
}
this._originLabel.value = this.value;
var action = this._parseActionUrl(this._value);
this._originLabel.value = action ? action.param : this._value;
]]></body>
</method>
@ -1298,27 +1299,85 @@
<binding id="splitmenu">
<content>
<xul:menuitem anonid="item" flex="1"
class="menuitem-tooltip split-menuitem-item"
xbl:inherits="label,key"/>
<xul:menu anonid="menu" class="split-menuitem-menu"
<xul:hbox anonid="menuitem" flex="1"
class="splitmenu-menuitem"
xbl:inherits="iconic,label,disabled,onclick=oncommand,_moz-menuactive=active"/>
<xul:menu anonid="menu" class="splitmenu-menu"
xbl:inherits="disabled"
oncommand="event.stopPropagation();">
<children includes="menupopup"/>
</xul:menu>
</content>
<implementation>
<constructor><![CDATA[
if (this.getAttribute("iconic") == "true") {
this.item.classList.remove("menuitem-tooltip");
this.item.classList.add("menuitem-iconic-tooltip");
this.item.classList.add("menuitem-iconic");
}
]]></constructor>
<field name="item" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "item");
<field name="menuitem" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "menuitem");
</field>
<field name="menu" readonly="true">
document.getAnonymousElementByAttribute(this, "anonid", "menu");
</field>
<field name="_menuDelay">600</field>
<field name="_parentMenupopup"><![CDATA[
let node = this.parentNode;
while (node) {
if (node.localName == "menupopup")
break;
node = node.parentNode;
}
node;
]]></field>
</implementation>
<handlers>
<handler event="mouseover"><![CDATA[
if (this.getAttribute("active") != "true" &&
this.getAttribute("disabled") != "true") {
if (this._parentMenupopup._currentPopup)
this._parentMenupopup._currentPopup.hidePopup();
this.setAttribute("active", "true");
let self = this;
setTimeout(function () {
if (self.getAttribute("active") == "true")
self.menu.open = true;
}, this._menuDelay);
}
]]></handler>
<handler event="mouseout"><![CDATA[
if (this.menu.open)
return;
let node = event.relatedTarget;
while (node) {
if (node == this)
return;
node = node.parentNode;
}
this.removeAttribute("active");
]]></handler>
<handler event="popuphidden"><![CDATA[
if (event.target == this.firstChild)
this.removeAttribute("active");
]]></handler>
<handler event="click" phase="capturing"><![CDATA[
let node = event.originalTarget;
while (true) {
if (node == this.menuitem)
break;
if (node == this)
return;
node = node.parentNode;
}
this._parentMenupopup.hidePopup();
]]></handler>
</handlers>
</binding>
<binding id="menuitem-tooltip" extends="chrome://global/content/bindings/menu.xml#menuitem">
@ -1342,5 +1401,5 @@
]]></constructor>
</implementation>
</binding>
</bindings>

View File

@ -146,9 +146,9 @@ BrowserGlue.prototype = {
// delays are in seconds
const MAX_DELAY = 300;
let delay = 3;
let enum = Services.wm.getEnumerator("navigator:browser");
while (enum.hasMoreElements()) {
delay += enum.getNext().gBrowser.tabs.length;
let browserEnum = Services.wm.getEnumerator("navigator:browser");
while (browserEnum.hasMoreElements()) {
delay += browserEnum.getNext().gBrowser.tabs.length;
}
delay = delay <= MAX_DELAY ? delay : MAX_DELAY;

View File

@ -167,7 +167,7 @@ SessionStartup.prototype = {
win.tabs.every(function (tab) tab.pinned)))
Services.obs.addObserver(this, "domwindowopened", true);
Services.obs.addObserver(this, "browser:purge-session-history", true);
Services.obs.addObserver(this, "sessionstore-windows-restored", true);
}
},
@ -198,6 +198,14 @@ SessionStartup.prototype = {
window.removeEventListener("load", arguments.callee, false);
}, false);
break;
case "sessionstore-windows-restored":
Services.obs.removeObserver(this, "sessionstore-windows-restored");
// We only want to start listening for the purge notification after we've
// sessionstore has finished its initial startup. That way we won't observe
// the purge notification & clear the old session before sessionstore loads
// it (in the case of a crash).
Services.obs.addObserver(this, "browser:purge-session-history", true);
break;
case "browser:purge-session-history":
// reset all state on sanitization
this._iniString = null;

View File

@ -769,41 +769,36 @@ SessionStoreService.prototype = {
if (closedWindowState) {
let newWindowState;
#ifndef XP_MACOSX
if (!this._doResumeSession()) {
#endif
// We want to split the window up into pinned tabs and unpinned tabs.
// Pinned tabs should be restored. If there are any remaining tabs,
// they should be added back to _closedWindows.
// We'll cheat a little bit and reuse _prepDataForDeferredRestore
// even though it wasn't built exactly for this.
let [appTabsState, normalTabsState] =
this._prepDataForDeferredRestore(JSON.stringify({ windows: [closedWindowState] }));
#ifdef XP_MACOSX
// We want to split the window up into pinned tabs and unpinned tabs.
// Pinned tabs should be restored. If there are any remaining tabs,
// they should be added back to _closedWindows.
// We'll cheat a little bit and reuse _prepDataForDeferredRestore
// even though it wasn't built exactly for this.
let [appTabsState, normalTabsState] =
this._prepDataForDeferredRestore(JSON.stringify({ windows: [closedWindowState] }));
// These are our pinned tabs, which we should restore
if (appTabsState.windows.length) {
newWindowState = appTabsState.windows[0];
delete newWindowState.__lastSessionWindowID;
}
// In case there were no unpinned tabs, remove the window from _closedWindows
if (!normalTabsState.windows.length) {
this._closedWindows.splice(closedWindowIndex, 1);
}
// Or update _closedWindows with the modified state
else {
delete normalTabsState.windows[0].__lastSessionWindowID;
this._closedWindows[closedWindowIndex] = normalTabsState.windows[0];
}
#ifndef XP_MACOSX
// These are our pinned tabs, which we should restore
if (appTabsState.windows.length) {
newWindowState = appTabsState.windows[0];
delete newWindowState.__lastSessionWindowID;
}
else {
// If we're just restoring the window, make sure it gets removed from
// _closedWindows.
// In case there were no unpinned tabs, remove the window from _closedWindows
if (!normalTabsState.windows.length) {
this._closedWindows.splice(closedWindowIndex, 1);
newWindowState = closedWindowState;
delete newWindowState.hidden;
}
// Or update _closedWindows with the modified state
else {
delete normalTabsState.windows[0].__lastSessionWindowID;
this._closedWindows[closedWindowIndex] = normalTabsState.windows[0];
}
#else
// If we're just restoring the window, make sure it gets removed from
// _closedWindows.
this._closedWindows.splice(closedWindowIndex, 1);
newWindowState = closedWindowState;
delete newWindowState.hidden;
#endif
if (newWindowState) {
// Ensure that the window state isn't hidden
@ -1513,6 +1508,7 @@ SessionStoreService.prototype = {
// data even when we shouldn't (e.g. Back, different anchor)
if (history && browser.__SS_data &&
browser.__SS_data.entries[history.index] &&
browser.__SS_data.entries[history.index].url == browser.currentURI.spec &&
history.index < this._sessionhistory_max_entries - 1 && !aFullData) {
tabData = browser.__SS_data;
tabData.index = history.index + 1;

View File

@ -137,6 +137,7 @@ _BROWSER_TEST_FILES = \
browser_615394-SSWindowState_events.js \
browser_618151.js \
browser_623779.js \
browser_625257.js \
$(NULL)
ifneq ($(OS_ARCH),Darwin)

View File

@ -21,7 +21,14 @@ function closeFirstWin(win) {
win.BrowserTryToCloseWindow();
ok(win.closed, "window closed");
openWinWithCb(checkSecondWin, URIS_NORMAL_B, URIS_PINNED.concat(URIS_NORMAL_B));
// The second check will be platform dependent. After bug 592833, Win/Linux
// will restore all tabs from the last close window while OSX will just
// reopen pinned tabs.
let expectedURIs = URIS_PINNED.concat(URIS_NORMAL_B);
if (!navigator.platform.match(/Mac/))
expectedURIs = expectedURIs.concat(URIS_NORMAL_A);
openWinWithCb(checkSecondWin, URIS_NORMAL_B, expectedURIs);
}
function checkSecondWin(win) {

View File

@ -344,7 +344,7 @@ function test_undoCloseWindow() {
function firstWindowObserver(aSubject, aTopic, aData) {
if (aTopic == "domwindowopened") {
newWindow = aSubject.QueryInterface(Ci.nsIDOMWindow);
Services.ww.unregisterNotification(windowObserver);
Services.ww.unregisterNotification(firstWindowObserver);
}
}
Services.ww.registerNotification(firstWindowObserver);

View File

@ -0,0 +1,121 @@
/* ***** 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 sessionstore test code.
*
* The Initial Developer of the Original Code is
* Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Mehdi Mulani <mmmulani@uwaterloo.ca>
*
* 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 *****/
// This tests that a tab which is closed while loading is not lost.
// Specifically, that session store does not rely on an invalid cache when
// constructing data for a tab which is loading.
let ss = Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
// The newly created tab which we load a URL into and try closing/undoing.
let tab;
// This test steps through the following parts:
// 1. Tab has been created is loading URI_TO_LOAD.
// 2. Before URI_TO_LOAD finishes loading, browser.currentURI has changed and
// tab is scheduled to be removed.
// 3. After the tab has been closed, undoCloseTab() has been called and the tab
// should fully load.
const URI_TO_LOAD = "about:home";
function test() {
waitForExplicitFinish();
gBrowser.addTabsProgressListener(tabsListener);
tab = gBrowser.addTab();
tab.linkedBrowser.addEventListener("load", firstOnLoad, true);
gBrowser.tabContainer.addEventListener("TabClose", onTabClose, true);
}
function firstOnLoad(aEvent) {
tab.linkedBrowser.removeEventListener("load", firstOnLoad, true);
let uri = aEvent.target.location;
is(uri, "about:blank", "first load should be for about:blank");
// Trigger a save state.
ss.getBrowserState();
is(gBrowser.tabs[1], tab, "newly created tab should exist by now");
ok(tab.linkedBrowser.__SS_data, "newly created tab should be in save state");
tab.linkedBrowser.loadURI(URI_TO_LOAD);
}
let tabsListener = {
onLocationChange: function onLocationChange(aBrowser) {
gBrowser.removeTabsProgressListener(tabsListener);
is(aBrowser.currentURI.spec, URI_TO_LOAD,
"should occur after about:blank load and be loading next page");
// Since we are running in the context of tabs listeners, we do not
// want to disrupt other tabs listeners.
executeSoon(function() {
gBrowser.removeTab(tab);
});
}
};
function onTabClose(aEvent) {
gBrowser.tabContainer.removeEventListener("TabClose", onTabClose, true);
is(tab.linkedBrowser.currentURI.spec, URI_TO_LOAD,
"should only remove when loading page");
executeSoon(function() {
tab = ss.undoCloseTab(window, 0);
tab.linkedBrowser.addEventListener("load", secondOnLoad, true);
});
}
function secondOnLoad(aEvent) {
let uri = aEvent.target.location;
is(uri, URI_TO_LOAD, "should load page from undoCloseTab");
done();
}
function done() {
tab.linkedBrowser.removeEventListener("load", secondOnLoad, true);
gBrowser.removeTab(tab);
executeSoon(finish);
}

View File

@ -1 +1 @@
4.0b10pre
4.0b11pre

View File

@ -703,10 +703,10 @@ Application.prototype = {
get windows() {
var win = [];
var enum = Utilities.windowMediator.getEnumerator("navigator:browser");
var browserEnum = Utilities.windowMediator.getEnumerator("navigator:browser");
while (enum.hasMoreElements())
win.push(new Window(enum.getNext()));
while (browserEnum.hasMoreElements())
win.push(new Window(browserEnum.getNext()));
return win;
},

View File

@ -421,7 +421,7 @@
@BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/icon.png
@BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/preview.png
#if MOZ_UPDATE_CHANNEL == beta
@BINPATH@/extensions/testpilot@labs.mozilla.com/*
@BINPATH@/distribution/extensions/testpilot@labs.mozilla.com.xpi
#endif
@BINPATH@/chrome/toolkit@JAREXT@
@BINPATH@/chrome/toolkit.manifest

View File

@ -87,6 +87,9 @@ defaults/profile/extensions/installed-extensions.txt
defaults/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/
defaults/profile/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
defaults/profile/search.rdf
#if MOZ_UPDATE_CHANNEL != beta
distribution/extensions/testpilot@labs.mozilla.com.xpi
#endif
extensions/talkback@mozilla.org/
extensions/talkback@mozilla.org/chrome.manifest
extensions/talkback@mozilla.org/components/@DLL_PREFIX@qfaservices@DLL_SUFFIX@
@ -94,6 +97,122 @@ extensions/talkback@mozilla.org/components/qfaservices.xpt
extensions/talkback@mozilla.org/install.rdf
extensions/{641d8d09-7dda-4850-8228-ac0ab65e2ac9}/
extensions/{641d8d09-7dda-4850-8228-ac0ab65e2ac9}/install.rdf
extensions/testpilot@labs.mozilla.com/chrome.manifest
extensions/testpilot@labs.mozilla.com/components/TestPilot.js
extensions/testpilot@labs.mozilla.com/content/all-studies-window.js
extensions/testpilot@labs.mozilla.com/content/all-studies-window.xul
extensions/testpilot@labs.mozilla.com/content/browser.css
extensions/testpilot@labs.mozilla.com/content/browser.js
extensions/testpilot@labs.mozilla.com/content/debug.html
extensions/testpilot@labs.mozilla.com/content/experiment-page.js
extensions/testpilot@labs.mozilla.com/content/feedback-browser.xul
extensions/testpilot@labs.mozilla.com/content/flot/jquery.colorhelpers.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.colorhelpers.min.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.crosshair.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.crosshair.min.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.image.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.image.min.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.min.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.navigate.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.navigate.min.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.selection.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.selection.min.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.stack.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.stack.min.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.threshold.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.flot.threshold.min.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.js
extensions/testpilot@labs.mozilla.com/content/flot/jquery.min.js
extensions/testpilot@labs.mozilla.com/content/raw-data-dialog.js
extensions/testpilot@labs.mozilla.com/content/raw-data-dialog.xul
extensions/testpilot@labs.mozilla.com/content/screen.css
extensions/testpilot@labs.mozilla.com/content/status-quit.html
extensions/testpilot@labs.mozilla.com/content/status.html
extensions/testpilot@labs.mozilla.com/content/survey-generator.js
extensions/testpilot@labs.mozilla.com/content/take-survey.html
extensions/testpilot@labs.mozilla.com/content/tp-browser.xul
extensions/testpilot@labs.mozilla.com/content/welcome-page.js
extensions/testpilot@labs.mozilla.com/content/welcome.html
extensions/testpilot@labs.mozilla.com/content/window-utils.js
extensions/testpilot@labs.mozilla.com/defaults/preferences/preferences.js
extensions/testpilot@labs.mozilla.com/install.rdf
extensions/testpilot@labs.mozilla.com/instrument/chrome.manifest
extensions/testpilot@labs.mozilla.com/instrument/install.rdf
extensions/testpilot@labs.mozilla.com/instrument/instrument.jsm
extensions/testpilot@labs.mozilla.com/instrument/instrument.xul
extensions/testpilot@labs.mozilla.com/modules/dbutils.js
extensions/testpilot@labs.mozilla.com/modules/experiment_data_store.js
extensions/testpilot@labs.mozilla.com/modules/extension-update.js
extensions/testpilot@labs.mozilla.com/modules/feedback.js
extensions/testpilot@labs.mozilla.com/modules/jar-code-store.js
extensions/testpilot@labs.mozilla.com/modules/lib/cuddlefish.js
extensions/testpilot@labs.mozilla.com/modules/lib/memory.js
extensions/testpilot@labs.mozilla.com/modules/lib/observer-service.js
extensions/testpilot@labs.mozilla.com/modules/lib/plain-text-console.js
extensions/testpilot@labs.mozilla.com/modules/lib/preferences-service.js
extensions/testpilot@labs.mozilla.com/modules/lib/securable-module.js
extensions/testpilot@labs.mozilla.com/modules/lib/timer.js
extensions/testpilot@labs.mozilla.com/modules/lib/traceback.js
extensions/testpilot@labs.mozilla.com/modules/lib/unit-test.js
extensions/testpilot@labs.mozilla.com/modules/lib/unload.js
extensions/testpilot@labs.mozilla.com/modules/lib/url.js
extensions/testpilot@labs.mozilla.com/modules/log4moz.js
extensions/testpilot@labs.mozilla.com/modules/metadata.js
extensions/testpilot@labs.mozilla.com/modules/Observers.js
extensions/testpilot@labs.mozilla.com/modules/remote-experiment-loader.js
extensions/testpilot@labs.mozilla.com/modules/setup.js
extensions/testpilot@labs.mozilla.com/modules/string_sanitizer.js
extensions/testpilot@labs.mozilla.com/modules/tasks.js
extensions/testpilot@labs.mozilla.com/skin/all/badge-default.png
extensions/testpilot@labs.mozilla.com/skin/all/bg.jpg
extensions/testpilot@labs.mozilla.com/skin/all/css/screen-standalone.css
extensions/testpilot@labs.mozilla.com/skin/all/dino_32x32.png
extensions/testpilot@labs.mozilla.com/skin/all/images/bg-status.jpg
extensions/testpilot@labs.mozilla.com/skin/all/images/callout.png
extensions/testpilot@labs.mozilla.com/skin/all/images/callout_continue.png
extensions/testpilot@labs.mozilla.com/skin/all/images/data1.jpg
extensions/testpilot@labs.mozilla.com/skin/all/images/data2.jpg
extensions/testpilot@labs.mozilla.com/skin/all/images/home_comments.png
extensions/testpilot@labs.mozilla.com/skin/all/images/home_computer.png
extensions/testpilot@labs.mozilla.com/skin/all/images/home_continue.png
extensions/testpilot@labs.mozilla.com/skin/all/images/home_quit.png
extensions/testpilot@labs.mozilla.com/skin/all/images/home_results.png
extensions/testpilot@labs.mozilla.com/skin/all/images/home_twitter.png
extensions/testpilot@labs.mozilla.com/skin/all/images/home_upcoming.png
extensions/testpilot@labs.mozilla.com/skin/all/logo.png
extensions/testpilot@labs.mozilla.com/skin/all/mozilla-logo.png
extensions/testpilot@labs.mozilla.com/skin/all/status-completed.png
extensions/testpilot@labs.mozilla.com/skin/all/status-ejected.png
extensions/testpilot@labs.mozilla.com/skin/all/status-missed.png
extensions/testpilot@labs.mozilla.com/skin/all/testpilot_16x16.png
extensions/testpilot@labs.mozilla.com/skin/all/testPilot_200x200.png
extensions/testpilot@labs.mozilla.com/skin/all/testpilot_32x32.png
extensions/testpilot@labs.mozilla.com/skin/all/tp-completedstudies-32x32.png
extensions/testpilot@labs.mozilla.com/skin/all/tp-currentstudies-32x32.png
extensions/testpilot@labs.mozilla.com/skin/all/tp-generic-32x32.png
extensions/testpilot@labs.mozilla.com/skin/all/tp-learned-32x32.png
extensions/testpilot@labs.mozilla.com/skin/all/tp-results-48x48.png
extensions/testpilot@labs.mozilla.com/skin/all/tp-settings-32x32.png
extensions/testpilot@labs.mozilla.com/skin/all/tp-study-48x48.png
extensions/testpilot@labs.mozilla.com/skin/all/tp-submit-48x48.png
extensions/testpilot@labs.mozilla.com/skin/linux/close_button.png
extensions/testpilot@labs.mozilla.com/skin/linux/feedback-frown-16x16.png
extensions/testpilot@labs.mozilla.com/skin/linux/feedback-smile-16x16.png
extensions/testpilot@labs.mozilla.com/skin/linux/feedback.css
extensions/testpilot@labs.mozilla.com/skin/mac/close_button.png
extensions/testpilot@labs.mozilla.com/skin/mac/feedback-frown-16x16.png
extensions/testpilot@labs.mozilla.com/skin/mac/feedback-smile-16x16.png
extensions/testpilot@labs.mozilla.com/skin/mac/feedback.css
extensions/testpilot@labs.mozilla.com/skin/mac/notification-tail-down.png
extensions/testpilot@labs.mozilla.com/skin/mac/notification-tail-up.png
extensions/testpilot@labs.mozilla.com/skin/win/close_button.png
extensions/testpilot@labs.mozilla.com/skin/win/feedback-frown-16x16.png
extensions/testpilot@labs.mozilla.com/skin/win/feedback-smile-16x16.png
extensions/testpilot@labs.mozilla.com/skin/win/feedback.css
extensions/testpilot@labs.mozilla.com/skin/win/notification-tail-down.png
extensions/testpilot@labs.mozilla.com/skin/win/notification-tail-up.png
extensions/testpilot@labs.mozilla.com/tests/test_data_store.js
greprefs/all.js
greprefs/security-prefs.js
greprefs/xpinstall.js

View File

@ -54,13 +54,17 @@ RequestExecutionLevel user
!addplugindir ./
Var TmpVal
Var StartMenuDir
Var InstallType
Var AddStartMenuSC
Var AddQuickLaunchSC
Var AddDesktopSC
Var PageName
; By defining NO_STARTMENU_DIR an installer that doesn't provide an option for
; an application's Start Menu PROGRAMS directory and doesn't define the
; StartMenuDir variable can use the common InstallOnInitCommon macro.
!define NO_STARTMENU_DIR
; On Vista and above attempt to elevate Standard Users in addition to users that
; are a member of the Administrators group.
!define NONADMIN_ELEVATE
@ -95,19 +99,18 @@ VIAddVersionKey "OriginalFilename" "setup.exe"
; Must be inserted before other macros that use logging
!insertmacro _LoggingCommon
; Most commonly used macros for managing shortcuts
!insertmacro _LoggingShortcutsCommon
!insertmacro AddDDEHandlerValues
!insertmacro ChangeMUIHeaderImage
!insertmacro CheckForFilesInUse
!insertmacro CleanUpdatesDir
!insertmacro CopyFilesFromDir
!insertmacro CreateRegKey
!insertmacro FindSMProgramsDir
!insertmacro GetPathFromString
!insertmacro GetParent
!insertmacro IsHandlerForInstallDir
!insertmacro LogDesktopShortcut
!insertmacro LogQuickLaunchShortcut
!insertmacro LogStartMenuShortcut
!insertmacro ManualCloseAppPrompt
!insertmacro RegCleanAppHandler
!insertmacro RegCleanMain
@ -178,12 +181,6 @@ Page custom preOptions leaveOptions
; Custom Shortcuts Page
Page custom preShortcuts leaveShortcuts
; Start Menu Folder Page Configuration
!define MUI_PAGE_CUSTOMFUNCTION_PRE preStartMenu
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE leaveStartMenu
!define MUI_STARTMENUPAGE_NODISABLE
!insertmacro MUI_PAGE_STARTMENU Application $StartMenuDir
; Custom Summary Page
Page custom preSummary leaveSummary
@ -274,7 +271,7 @@ Section "-Application" APP_IDX
ClearErrors
; Default for creating Start Menu folder and shortcuts
; Default for creating Start Menu shortcut
; (1 = create, 0 = don't create)
${If} $AddStartMenuSC == ""
StrCpy $AddStartMenuSC "1"
@ -382,15 +379,16 @@ Section "-Application" APP_IDX
; Create shortcuts
${LogHeader} "Adding Shortcuts"
!insertmacro MUI_STARTMENU_WRITE_BEGIN Application
; Remove the start menu shortcuts and directory if the SMPROGRAMS section
; exists in the shortcuts_log.ini and the SMPROGRAMS. The installer's shortcut
; creation code will create the shortcut in the root of the Start Menu
; Programs directory.
${RemoveStartMenuDir}
; Always add the relative path to the application's Start Menu directory and
; the application's shortcuts to the shortcuts log ini file. The
; DeleteShortcuts macro will do the right thing on uninstall if they don't
; exist.
${LogSMProgramsDirRelPath} "$StartMenuDir"
${LogSMProgramsShortcut} "${BrandFullName}.lnk"
${LogSMProgramsShortcut} "${BrandFullName} ($(SAFE_MODE)).lnk"
; Always add the application's shortcuts to the shortcuts log ini file. The
; DeleteShortcuts macro will do the right thing on uninstall if the
; shortcuts don't exist.
${LogStartMenuShortcut} "${BrandFullName}.lnk"
${LogQuickLaunchShortcut} "${BrandFullName}.lnk"
${LogDesktopShortcut} "${BrandFullName}.lnk"
@ -399,22 +397,19 @@ Section "-Application" APP_IDX
; since this will either add it for the user if unelevated or All Users if
; elevated.
${If} $AddStartMenuSC == 1
${Unless} ${FileExists} "$SMPROGRAMS\$StartMenuDir"
CreateDirectory "$SMPROGRAMS\$StartMenuDir"
${LogMsg} "Added Start Menu Directory: $SMPROGRAMS\$StartMenuDir"
${EndUnless}
CreateShortCut "$SMPROGRAMS\$StartMenuDir\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
ApplicationID::Set "$SMPROGRAMS\$StartMenuDir\${BrandFullName}.lnk" "${AppUserModelID}"
CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" \
"" "$INSTDIR\${FileMainEXE}" 0
ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \
"$INSTDIR"
ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "${AppUserModelID}"
${LogMsg} "Added Shortcut: $SMPROGRAMS\$StartMenuDir\${BrandFullName}.lnk"
CreateShortCut "$SMPROGRAMS\$StartMenuDir\${BrandFullName} ($(SAFE_MODE)).lnk" "$INSTDIR\${FileMainEXE}" "-safe-mode" "$INSTDIR\${FileMainEXE}" 0
ApplicationID::Set "$SMPROGRAMS\$StartMenuDir\${BrandFullName} ($(SAFE_MODE)).lnk" "${AppUserModelID}"
${LogMsg} "Added Shortcut: $SMPROGRAMS\$StartMenuDir\${BrandFullName} ($(SAFE_MODE)).lnk"
${EndIf}
!insertmacro MUI_STARTMENU_WRITE_END
${If} $AddDesktopSC == 1
CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" \
"" "$INSTDIR\${FileMainEXE}" 0
ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" \
"$INSTDIR"
ApplicationID::Set "$DESKTOP\${BrandFullName}.lnk" "${AppUserModelID}"
${LogMsg} "Added Shortcut: $DESKTOP\${BrandFullName}.lnk"
${EndIf}
@ -523,8 +518,6 @@ Function CustomAbort
GetFunctionAddress $0 AbortSurveyDirectory
${ElseIf} "$PageName" == "Shortcuts"
GetFunctionAddress $0 AbortSurveyShortcuts
${ElseIf} "$PageName" == "StartMenu"
GetFunctionAddress $0 AbortSurveyStartMenu
${ElseIf} "$PageName" == "Summary"
GetFunctionAddress $0 AbortSurveySummary
${EndIf}
@ -564,19 +557,18 @@ Function AbortSurveyShortcuts
ExecShell "open" "${AbortSurveyURL}step4"
FunctionEnd
Function AbortSurveyStartMenu
ExecShell "open" "${AbortSurveyURL}step5"
FunctionEnd
Function AbortSurveySummary
ExecShell "open" "${AbortSurveyURL}step6"
ExecShell "open" "${AbortSurveyURL}step5"
FunctionEnd
################################################################################
# Helper Functions
Function AddQuickLaunchShortcut
CreateShortCut "$QUICKLAUNCH\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
CreateShortCut "$QUICKLAUNCH\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" \
"" "$INSTDIR\${FileMainEXE}" 0
ShellLink::SetShortCutWorkingDirectory "$QUICKLAUNCH\${BrandFullName}.lnk" \
"$INSTDIR"
ApplicationID::Set "$QUICKLAUNCH\${BrandFullName}.lnk" "${AppUserModelID}"
FunctionEnd
@ -746,49 +738,6 @@ Function leaveShortcuts
${MUI_INSTALLOPTIONS_READ} $AddStartMenuSC "shortcuts.ini" "Field 3" "State"
${MUI_INSTALLOPTIONS_READ} $AddQuickLaunchSC "shortcuts.ini" "Field 4" "State"
; If Start Menu shortcuts won't be created call CheckExistingInstall here
; since leaveStartMenu will not be called.
${If} $AddStartMenuSC != 1
${AndIf} $InstallType == ${INSTALLTYPE_CUSTOM}
Call CheckExistingInstall
${EndIf}
FunctionEnd
Function preStartMenu
StrCpy $PageName "StartMenu"
; With the Unicode installer the path to the application's Start Menu
; directory relative to the Start Menu's Programs directory is written to the
; shortcuts log ini file and is used to set the default Start Menu directory.
${GetSMProgramsDirRelPath} $0
${If} "$0" != ""
StrCpy $StartMenuDir "$0"
${Else}
; Prior to the Unicode installer the path to the application's Start Menu
; directory relative to the Start Menu's Programs directory was written to
; the registry and use this value to set the default Start Menu directory.
ClearErrors
ReadRegStr $0 HKLM "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Main" "Start Menu Folder"
${If} ${Errors}
; Use the FindSMProgramsDir macro to find a previously used path to the
; application's Start Menu directory relative to the Start Menu's Programs
; directory in the uninstall log and use this value to set the default
; Start Menu directory.
${FindSMProgramsDir} $0
${If} "$0" != ""
StrCpy $StartMenuDir "$0"
${EndIf}
${Else}
StrCpy $StartMenuDir "$0"
${EndUnless}
${EndIf}
${CheckCustomCommon}
${If} $AddStartMenuSC != 1
Abort
${EndIf}
FunctionEnd
Function leaveStartMenu
${If} $InstallType == ${INSTALLTYPE_CUSTOM}
Call CheckExistingInstall
${EndIf}

View File

@ -78,6 +78,10 @@
${EndIf}
${EndIf}
; Migrate the application's Start Menu directory to a single shortcut in the
; root of the Start Menu Programs directory.
${MigrateStartMenuShortcut}
${RemoveDeprecatedKeys}
${SetAppKeys}
@ -126,20 +130,39 @@
${If} "$0" == ""
ShellLink::GetShortCutTarget "$DESKTOP\${BrandFullName}.lnk"
Pop $0
; Needs to handle short paths
${GetLongPath} "$0" $0
${If} "$0" == "$INSTDIR\${FileMainEXE}"
Delete "$DESKTOP\${BrandFullName}.lnk"
${EndIf}
${EndIf}
${EndIf}
SetShellVarContext all ; Set $SMPROGRAMS to All Users
${Unless} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk"
SetShellVarContext current ; Set $SMPROGRAMS to the current user's Start
; Menu Programs directory
${EndUnless}
${If} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk"
ShellLink::GetShortCutArgs "$SMPROGRAMS\${BrandFullName}.lnk"
Pop $0
${If} "$0" == ""
ShellLink::GetShortCutTarget "$SMPROGRAMS\${BrandFullName}.lnk"
Pop $0
${GetLongPath} "$0" $0
${If} "$0" == "$INSTDIR\${FileMainEXE}"
Delete "$SMPROGRAMS\${BrandFullName}.lnk"
${EndIf}
${EndIf}
${EndIf}
${If} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk"
ShellLink::GetShortCutArgs "$QUICKLAUNCH\${BrandFullName}.lnk"
Pop $0
${If} "$0" == ""
ShellLink::GetShortCutTarget "$QUICKLAUNCH\${BrandFullName}.lnk"
Pop $0
; Needs to handle short paths
${GetLongPath} "$0" $0
${If} "$0" == "$INSTDIR\${FileMainEXE}"
Delete "$QUICKLAUNCH\${BrandFullName}.lnk"
${EndIf}
@ -154,24 +177,51 @@
${StrFilter} "${FileMainEXE}" "+" "" "" $0
StrCpy $R1 "Software\Clients\StartMenuInternet\$0\InstallInfo"
WriteRegDWORD HKLM "$R1" "IconsVisible" 1
SetShellVarContext all ; Set $DESKTOP to All Users
${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
ApplicationID::Set "$DESKTOP\${BrandFullName}.lnk" "${AppUserModelID}"
CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" \
"" "$INSTDIR\${FileMainEXE}" 0
ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR"
ApplicationID::Set "$DESKTOP\${BrandFullName}.lnk" "${AppUserModelID}"
${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
SetShellVarContext current ; Set $DESKTOP to the current user's desktop
${Unless} ${FileExists} "$DESKTOP\${BrandFullName}.lnk"
CreateShortCut "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
CreateShortCut "$DESKTOP\${BrandFullName}.lnk" \
"$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" \
"$INSTDIR"
ApplicationID::Set "$DESKTOP\${BrandFullName}.lnk" "${AppUserModelID}"
ShellLink::SetShortCutWorkingDirectory "$DESKTOP\${BrandFullName}.lnk" "$INSTDIR"
${EndUnless}
${EndUnless}
${EndUnless}
SetShellVarContext all ; Set $DESKTOP to All Users
${Unless} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk"
CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" \
"$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \
"$INSTDIR"
ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "${AppUserModelID}"
${Unless} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk"
SetShellVarContext current ; Set $SMPROGRAMS to the current user's Start
; Menu Programs directory
${Unless} ${FileExists} "$SMPROGRAMS\${BrandFullName}.lnk"
CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" \
"$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \
"$INSTDIR"
ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" "${AppUserModelID}"
${EndUnless}
${EndUnless}
${EndUnless}
${Unless} ${FileExists} "$QUICKLAUNCH\${BrandFullName}.lnk"
CreateShortCut "$QUICKLAUNCH\${BrandFullName}.lnk" "$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
CreateShortCut "$QUICKLAUNCH\${BrandFullName}.lnk" \
"$INSTDIR\${FileMainEXE}" "" "$INSTDIR\${FileMainEXE}" 0
ShellLink::SetShortCutWorkingDirectory "$QUICKLAUNCH\${BrandFullName}.lnk" \
"$INSTDIR"
ApplicationID::Set "$QUICKLAUNCH\${BrandFullName}.lnk" "${AppUserModelID}"
ShellLink::SetShortCutWorkingDirectory "$QUICKLAUNCH\${BrandFullName}.lnk" "$INSTDIR"
${EndUnless}
!macroend
!define ShowShortcuts "!insertmacro ShowShortcuts"
@ -612,29 +662,114 @@
!macroend
!define RemoveDeprecatedFiles "!insertmacro RemoveDeprecatedFiles"
; Adds a shortcut to the root of the Start Menu Programs directory if the
; application's Start Menu Programs directory exists with a shortcut pointing to
; this installation directory. This will also remove the old shortcuts and the
; application's Start Menu Programs directory by calling the RemoveStartMenuDir
; macro.
!macro MigrateStartMenuShortcut
${GetShortcutsLogPath} $0
${If} ${FileExists} "$0"
ClearErrors
ReadINIStr $5 "$0" "SMPROGRAMS" "RelativePathToDir"
${Unless} ${Errors}
ClearErrors
ReadINIStr $1 "$0" "STARTMENU" "Shortcut0"
${If} ${Errors}
; The STARTMENU ini section doesn't exist.
${LogStartMenuShortcut} "${BrandFullName}.lnk"
${GetLongPath} "$SMPROGRAMS" $2
${GetLongPath} "$2\$5" $1
${If} "$1" != ""
ClearErrors
ReadINIStr $3 "$0" "SMPROGRAMS" "Shortcut0"
${Unless} ${Errors}
${If} ${FileExists} "$1\$3"
ShellLink::GetShortCutTarget "$1\$3"
Pop $4
${If} "$INSTDIR\${FileMainEXE}" == "$4"
CreateShortCut "$SMPROGRAMS\${BrandFullName}.lnk" \
"$INSTDIR\${FileMainEXE}" "" \
"$INSTDIR\${FileMainEXE}" 0
ShellLink::SetShortCutWorkingDirectory "$SMPROGRAMS\${BrandFullName}.lnk" \
"$INSTDIR"
ApplicationID::Set "$SMPROGRAMS\${BrandFullName}.lnk" \
"${AppUserModelID}"
${EndIf}
${EndIf}
${EndUnless}
${EndIf}
${EndIf}
; Remove the application's Start Menu Programs directory, shortcuts, and
; ini section.
${RemoveStartMenuDir}
${EndUnless}
${EndIf}
!macroend
!define MigrateStartMenuShortcut "!insertmacro MigrateStartMenuShortcut"
; Removes the application's start menu directory along with its shortcuts if
; they exist and if they exist creates a start menu shortcut in the root of the
; start menu directory (bug 598779). If the application's start menu directory
; is not empty after removing the shortucts the directory will not be removed
; since these additional items were not created by the installer (uses SHCTX).
!macro RemoveStartMenuDir
${GetShortcutsLogPath} $0
${If} ${FileExists} "$0"
; Delete Start Menu Programs shortcuts, directory if it is empty, and
; parent directories if they are empty up to but not including the start
; menu directory.
${GetLongPath} "$SMPROGRAMS" $1
ClearErrors
ReadINIStr $2 "$0" "SMPROGRAMS" "RelativePathToDir"
${Unless} ${Errors}
${GetLongPath} "$1\$2" $2
${If} "$2" != ""
; Delete shortucts in the Start Menu Programs directory.
StrCpy $3 0
${Do}
ClearErrors
ReadINIStr $4 "$0" "SMPROGRAMS" "Shortcut$3"
; Stop if there are no more entries
${If} ${Errors}
${ExitDo}
${EndIf}
${If} ${FileExists} "$2\$4"
ShellLink::GetShortCutTarget "$2\$4"
Pop $5
${If} "$INSTDIR\${FileMainEXE}" == "$5"
Delete "$2\$4"
${EndIf}
${EndIf}
IntOp $3 $3 + 1 ; Increment the counter
${Loop}
; Delete Start Menu Programs directory and parent directories
${Do}
; Stop if the current directory is the start menu directory
${If} "$1" == "$2"
${ExitDo}
${EndIf}
ClearErrors
RmDir "$2"
; Stop if removing the directory failed
${If} ${Errors}
${ExitDo}
${EndIf}
${GetParent} "$2" $2
${Loop}
${EndIf}
DeleteINISec "$0" "SMPROGRAMS"
${EndUnless}
${EndIf}
!macroend
!define RemoveStartMenuDir "!insertmacro RemoveStartMenuDir"
; Creates the shortcuts log ini file with the appropriate entries if it doesn't
; already exist.
!macro CreateShortcutsLog
${GetShortcutsLogPath} $0
${Unless} ${FileExists} "$0"
; Default to ${BrandFullName} for the Start Menu Folder
StrCpy $TmpVal "${BrandFullName}"
; Prior to Firefox 3.1 the Start Menu directory was written to the registry and
; this value can be used to set the Start Menu directory.
ClearErrors
ReadRegStr $0 SHCTX "Software\Mozilla\${BrandFullNameInternal}\${AppVersion} (${AB_CD})\Main" "Start Menu Folder"
${If} ${Errors}
${FindSMProgramsDir} $0
${If} "$0" != ""
StrCpy $TmpVal "$0"
${EndIf}
${Else}
StrCpy $TmpVal "$0"
${EndUnless}
${LogSMProgramsDirRelPath} "$TmpVal"
${LogSMProgramsShortcut} "${BrandFullName}.lnk"
${LogSMProgramsShortcut} "${BrandFullName} ($(SAFE_MODE)).lnk"
${LogStartMenuShortcut} "${BrandFullName}.lnk"
${LogQuickLaunchShortcut} "${BrandFullName}.lnk"
${LogDesktopShortcut} "${BrandFullName}.lnk"
${EndUnless}

View File

@ -87,16 +87,15 @@ Var TmpVal
VIAddVersionKey "FileDescription" "${BrandShortName} Helper"
VIAddVersionKey "OriginalFilename" "helper.exe"
; Most commonly used macros for managing shortcuts
!insertmacro _LoggingShortcutsCommon
!insertmacro AddDDEHandlerValues
!insertmacro CleanVirtualStore
!insertmacro ElevateUAC
!insertmacro FindSMProgramsDir
!insertmacro GetLongPath
!insertmacro GetPathFromString
!insertmacro IsHandlerForInstallDir
!insertmacro LogDesktopShortcut
!insertmacro LogQuickLaunchShortcut
!insertmacro LogStartMenuShortcut
!insertmacro RegCleanAppHandler
!insertmacro RegCleanMain
!insertmacro RegCleanUninstall

View File

@ -312,17 +312,6 @@ endif
# Set the permissions that the folders will have in ftp once uploaded
chmod -vR 775 $(UPLOAD_DIR)
l10n-upload-%: AB_CD=$*
l10n-upload-%:
$(PYTHON) $(topsrcdir)/build/upload.py --base-path $(DIST) "$(DIST)/$(PACKAGE)" $(DIST)/$(LANGPACK)
ifdef MOZ_MAKE_COMPLETE_MAR
$(PYTHON) $(topsrcdir)/build/upload.py --base-path $(DIST) $(DIST)/$(COMPLETE_MAR) $(call QUOTED_WILDCARD,$(wildcard $(DIST)/$(PARTIAL_MAR)))
endif
ifneq (,$(filter WINNT WINCE,$(OS_ARCH)))
$(PYTHON) $(topsrcdir)/build/upload.py --base-path $(DIST) "$(INSTALLER_PACKAGE)"
endif
merge-%:
ifdef LOCALE_MERGEDIR
$(RM) -rf $(LOCALE_MERGEDIR)

View File

@ -86,8 +86,6 @@
% override chrome://global/locale/netError.dtd chrome://browser/locale/netError.dtd
% override chrome://global/locale/appstrings.properties chrome://browser/locale/appstrings.properties
% override chrome://mozapps/locale/downloads/settingsChange.dtd chrome://browser/locale/downloads/settingsChange.dtd
#if MOZ_UPDATE_CHANNEL == beta
% locale testpilot @AB_CD@ %locale/feedback/
locale/feedback/main.dtd (%feedback/main.dtd)
locale/feedback/main.properties (%feedback/main.properties)
#endif

View File

@ -1,6 +1,7 @@
af
ak
ar
ast
be
bg
bn-BD
@ -8,6 +9,7 @@ bn-IN
br
ca
cs
cy
da
de
el

View File

@ -943,17 +943,19 @@ toolbar[iconsize="small"] #feed-button {
-moz-margin-start: 0;
}
#urlbar-display {
margin-top: -2px;
margin-bottom: -2px;
padding-top: 3px;
padding-bottom: 2px;
-moz-padding-end: 3px;
color: GrayText;
#urlbar-display-box {
margin-top: -1px;
margin-bottom: -1px;
-moz-border-end: 1px solid #AAA;
-moz-margin-end: 3px;
}
#urlbar-display {
margin-top: 0;
margin-bottom: 0;
color: GrayText;
}
#PopupAutoComplete,
#PopupAutoCompleteRichResult {
direction: ltr !important;
@ -1120,14 +1122,6 @@ toolbar[iconsize="small"] #feed-button {
min-width: 280px;
}
/* Invalid form popup */
#invalid-form-popup {
-moz-appearance: none;
background-color: #fffcd6;
border: 1px solid #dad8b6;
font-weight: bold;
}
/* Notification popup */
#notification-popup {
min-width: 280px;

View File

@ -78,7 +78,6 @@ browser.jar:
skin/classic/browser/tabbrowser/tab.png (tabbrowser/tab.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
skin/classic/browser/tabview/edit-light.png (tabview/edit-light.png)
skin/classic/browser/tabview/edit.png (tabview/edit.png)
skin/classic/browser/tabview/new-tab.png (tabview/new-tab.png)
skin/classic/browser/tabview/search.png (tabview/search.png)
skin/classic/browser/tabview/stack-expander.png (tabview/stack-expander.png)

View File

@ -105,6 +105,10 @@ description > .text-link:focus {
text-align: center;
}
#passphraseHelpSpacer {
width: 0.5em;
}
#add-device-throbber > image,
#login-throbber > image {
list-style-image: url("chrome://global/skin/icons/loading_16.png");

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 B

View File

@ -501,8 +501,10 @@ html[dir=rtl] .resizer {
cursor: se-resize;
width: 12px;
height: 12px;
right: 1px;
bottom: 1px;
padding-right: 3px;
padding-bottom: 3px;
right: -2px;
bottom: -2px;
}
html[dir=rtl] .iq-resizable-se {

View File

@ -757,28 +757,22 @@ toolbar[mode="icons"] #zoom-in-button {
width: 7em;
min-width: 7em;
-moz-appearance: none;
border: 0;
box-shadow: 0 1px rgba(255, 255, 255, 0.2);
box-shadow: 0 1px rgba(255, 255, 255, 0.2), inset 0 1px #d6d6d6;
margin: 0 4px;
padding: 0;
border: 1px solid transparent;
background: -moz-linear-gradient(#D6D6D6, #D6D6D6 1px, #F7F7F7 1px, #F7F7F7 2px, #FFF 2px, #FFF),
-moz-linear-gradient(rgba(0,0,0,.5), rgba(0,0,0,.2));
background-origin: padding-box, border-box;
background-clip: padding-box, border-box;
border: 1px solid;
border-color: #626262 #787878 #8c8c8c;
background-clip: padding-box;
}
#urlbar:-moz-window-inactive,
.searchbar-textbox:-moz-window-inactive {
background-image: -moz-linear-gradient(#D6D6D6, #D6D6D6 1px, #F7F7F7 1px, #F7F7F7 2px, #FFF 2px, #FFF),
-moz-linear-gradient(@toolbarbuttonInactiveBorderColor@, @toolbarbuttonInactiveBorderColor@);
border-color: @toolbarbuttonInactiveBorderColor@;
}
#urlbar[focused="true"],
.searchbar-textbox[focused="true"] {
background-color: -moz-mac-focusring;
background-image: -moz-linear-gradient(#D6D6D6, #D6D6D6 1px, #F7F7F7 1px, #F7F7F7 2px, #FFF 2px, #FFF),
-moz-linear-gradient(rgba(0,0,0,.1), rgba(0,0,0,.1));
border-color: -moz-mac-focusring;
box-shadow: @focusRingShadow@;
}
@ -892,17 +886,17 @@ toolbar[mode="icons"] #zoom-in-button {
max-width: 20em;
}
#urlbar-display {
margin-top: -3px;
margin-bottom: -2px;
padding-top: 3px;
padding-bottom: 2px;
-moz-padding-end: 3px;
color: GrayText;
#urlbar-display-box {
-moz-border-end: 1px solid #AAA;
-moz-margin-end: 3px;
}
#urlbar-display {
margin-top: 0;
margin-bottom: 0;
color: GrayText;
}
#PopupAutoCompleteRichResult {
direction: ltr !important;
margin-top: 2px;
@ -1427,12 +1421,12 @@ sidebarheader {
-moz-border-end: 1px solid #404040;
min-width: 1px;
width: 1px;
background-image: none !important;
}
background-image: none !important;
}
#sidebar-title {
color: #535f6d;
font-weight: bold;
font-weight: bold;
}
#sidebar-throbber[loading="true"] {

View File

@ -117,7 +117,6 @@ browser.jar:
skin/classic/browser/tabbrowser/tab-top-selected-active.png (tabbrowser/tab-top-selected-active.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
skin/classic/browser/tabview/edit-light.png (tabview/edit-light.png)
skin/classic/browser/tabview/edit.png (tabview/edit.png)
skin/classic/browser/tabview/new-tab.png (tabview/new-tab.png)
skin/classic/browser/tabview/search.png (tabview/search.png)
skin/classic/browser/tabview/stack-expander.png (tabview/stack-expander.png)

View File

@ -104,6 +104,10 @@ description > .text-link:focus {
text-align: center;
}
#passphraseHelpSpacer {
width: 0.5em;
}
#add-device-throbber > image,
#login-throbber > image {
list-style-image: url("chrome://global/skin/icons/loading_16.png");

Binary file not shown.

Before

Width:  |  Height:  |  Size: 464 B

After

Width:  |  Height:  |  Size: 520 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 691 B

After

Width:  |  Height:  |  Size: 611 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 B

After

Width:  |  Height:  |  Size: 291 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 B

View File

@ -7,7 +7,11 @@ body {
}
#bg {
background: -moz-linear-gradient(top,#C4C4C4,#9E9E9E);
background: -moz-linear-gradient(#C4C4C4,#9E9E9E);
}
#bg:-moz-window-inactive {
background: -moz-linear-gradient(rgb(237,237,237),rgb(216,216,216));
}
/* Tabs
@ -132,7 +136,7 @@ html[dir=rtl] .expander {
width: 94.5%;
white-space: nowrap;
overflow: hidden;
text-shadow: 0 1px rgba(255, 255, 255, 0.6);
text-shadow: 0 1px rgba(255, 255, 255, 0.6);
}
.stacked {
@ -419,7 +423,7 @@ input.name:focus {
input.name:-moz-placeholder {
font-style: italic !important;
color: transparent;
color: transparent;
background-image: url(chrome://browser/skin/tabview/edit-light.png);
background-image-opacity: .1;
background-repeat: no-repeat;
@ -493,8 +497,10 @@ html[dir=rtl] .resizer {
cursor: se-resize;
width: 12px;
height: 12px;
right: 1px;
bottom: 1px;
padding-right: 3px;
padding-bottom: 3px;
right: -2px;
bottom: -2px;
}
html[dir=rtl] .iq-resizable-se {
@ -540,6 +546,10 @@ html[dir=rtl] .iq-resizable-se {
height: 100%;
}
#searchshade:-moz-window-inactive {
background: -moz-linear-gradient(rgba(237,237,237,.42),rgba(216,216,216,.42));
}
#search{
width: 100%;
height: 100%;
@ -558,6 +568,11 @@ html[dir=rtl] .iq-resizable-se {
font-size: 14px;
}
#searchbox:-moz-window-inactive {
background-color: #BBBBBB;
box-shadow: 0px 1px 0px rgba(255,255,255,.1), 0px -1px 0px rgba(0,0,0,0.3), 0px 0px 13px rgba(0,0,0,.2);
}
#actions {
width: 29px;
text-align: center;

View File

@ -121,22 +121,22 @@
text-shadow: 0 0 .5em white, 0 0 .5em white, 0 1px 0 rgba(255,255,255,.4);
}
#main-window[sizemode="normal"] #navigator-toolbox:not([inFullscreen="true"])::after,
#main-window[sizemode="normal"] #navigator-toolbox[tabsontop="true"] > toolbar:not(#toolbar-menubar):not(#TabsToolbar):not([inFullscreen="true"]):not(:-moz-lwtheme) {
border-left: 1px solid @glassToolbarBorderColor@;
border-right: 1px solid @glassToolbarBorderColor@;
background-clip: padding-box;
}
#navigator-toolbox[tabsontop="false"],
#main-window[disablechrome] #navigator-toolbox[tabsontop="true"],
#navigator-toolbox > toolbar {
border-color: @glassToolbarBorderColor@ !important;
background-clip: padding-box;
}
#main-window[sizemode="normal"]:not([disablechrome]) #navigator-toolbox[tabsontop="true"] {
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
#navigator-toolbox[tabsontop="false"]::after,
#main-window[disablechrome] #navigator-toolbox[tabsontop="true"]::after {
background-color: @glassToolbarBorderColor@;
}
#main-window[sizemode="normal"] #browser-border-start,
#main-window[sizemode="normal"] #browser-border-end {
#main-window[sizemode="normal"]:not([inFullscreen="true"]) #browser-border-start,
#main-window[sizemode="normal"]:not([inFullscreen="true"]) #browser-border-end {
display: -moz-box;
background-color: @glassToolbarBorderColor@;
width: 1px;
@ -231,6 +231,12 @@
color: black;
text-shadow: white -1px -1px .35em, white -1px 1px .35em, white 1px 1px .35em, white 1px -1px .35em;
}
#tab-view:-moz-lwtheme {
background-image: url("chrome://browser/skin/tabview/grain.png"),
-moz-linear-gradient(rgba(255,255,255,0), #CCD9EA 200px, #C7D5E7);
background-attachment: fixed;
}
}
@media not all and (-moz-windows-compositor) {

View File

@ -67,7 +67,14 @@
-moz-appearance: none;
background-color: transparent;
border-top: none;
border-bottom: 1px solid ThreeDShadow;
}
#navigator-toolbox::after {
content: "";
display: -moz-box;
-moz-box-ordinal-group: 101; /* tabs toolbar is 100 */
height: 1px;
background-color: ThreeDShadow;
}
#navigator-toolbox > toolbar:not(:-moz-lwtheme) {
@ -219,7 +226,7 @@
-moz-margin-start: .5em;
}
.split-menuitem-menu {
.splitmenu-menu {
-moz-box-pack: end;
}
@ -669,12 +676,10 @@ menuitem.bookmark-item {
.toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
.toolbarbutton-1 > .toolbarbutton-icon {
-moz-margin-end: 0;
width: 18px;
height: 18px;
}
toolbar[iconsize="small"] .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
toolbar[iconsize="small"] .toolbarbutton-1 > .toolbarbutton-icon {
#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button > .toolbarbutton-icon,
#nav-bar .toolbarbutton-1 > .toolbarbutton-icon {
margin: 1px;
width: 16px;
height: 16px;
@ -1130,17 +1135,19 @@ html|*.urlbar-input:-moz-lwtheme:-moz-placeholder,
-moz-box-align: stretch;
}
#urlbar-display {
#urlbar-display-box {
margin-top: -2px;
margin-bottom: -2px;
padding-top: 3px;
padding-bottom: 2px;
-moz-padding-end: 3px;
color: GrayText;
-moz-border-end: 1px solid #AAA;
-moz-margin-end: 3px;
}
#urlbar-display {
margin-top: 0;
margin-bottom: 0;
color: GrayText;
}
/* over-link in location bar */
.urlbar-origin-label {

View File

@ -94,7 +94,6 @@ browser.jar:
skin/classic/browser/tabbrowser/tab-arrow-left.png (tabbrowser/tab-arrow-left.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
skin/classic/browser/tabview/edit-light.png (tabview/edit-light.png)
skin/classic/browser/tabview/edit.png (tabview/edit.png)
skin/classic/browser/tabview/grain.png (tabview/grain.png)
skin/classic/browser/tabview/new-tab.png (tabview/new-tab.png)
skin/classic/browser/tabview/search.png (tabview/search.png)
@ -209,7 +208,6 @@ browser.jar:
skin/classic/aero/browser/tabbrowser/tab-arrow-left.png (tabbrowser/tab-arrow-left.png)
skin/classic/aero/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
skin/classic/aero/browser/tabview/edit-light.png (tabview/edit-light.png)
skin/classic/aero/browser/tabview/edit.png (tabview/edit.png)
skin/classic/aero/browser/tabview/grain.png (tabview/grain.png)
skin/classic/aero/browser/tabview/new-tab.png (tabview/new-tab.png)
skin/classic/aero/browser/tabview/search.png (tabview/search.png)

View File

@ -105,6 +105,10 @@ description > .text-link:focus {
text-align: center;
}
#passphraseHelpSpacer {
width: 0.5em;
}
#add-device-throbber > image,
#login-throbber > image {
list-style-image: url("chrome://global/skin/icons/loading_16.png");

Binary file not shown.

Before

Width:  |  Height:  |  Size: 238 B

View File

@ -5,7 +5,7 @@ body {
line-height: 16px;
}
#bg {
#bg:not(:-moz-system-metric(windows-compositor)) {
background: url("chrome://browser/skin/tabview/grain.png") repeat scroll center top,
-moz-linear-gradient(center top , #CCD9EA, #C7D5E7) repeat scroll 0 0 transparent;
}
@ -520,8 +520,10 @@ html[dir=rtl] .resizer {
cursor: se-resize;
width: 12px;
height: 12px;
right: 1px;
bottom: 1px;
padding-right: 3px;
padding-bottom: 3px;
right: -2px;
bottom: -2px;
}
html[dir=rtl] .iq-resizable-se {

View File

@ -339,6 +339,7 @@ user_pref("dom.disable_open_during_load", false);
user_pref("dom.max_script_run_time", 0); // no slow script dialogs
user_pref("dom.max_chrome_script_run_time", 0);
user_pref("dom.popup_maximum", -1);
user_pref("dom.send_after_paint_to_content", true);
user_pref("dom.successive_dialog_time_limit", 0);
user_pref("signed.applets.codebase_principal_support", true);
user_pref("security.warn_submit_insecure", false);

View File

@ -81,11 +81,7 @@ genpgocert.py: genpgocert.py.in
$(PYTHON) $(topsrcdir)/config/Preprocessor.py \
$(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ > $@
profileserver.py: profileserver.py.in
$(PYTHON) $(topsrcdir)/config/Preprocessor.py $^ > $@
chmod +x $@
GARBAGE += profileserver.py genpgocert.py
GARBAGE += genpgocert.py
libs:: $(_PGO_FILES)
$(INSTALL) $^ $(_PROFILE_DIR)

View File

@ -16,7 +16,7 @@
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# Mozilla Foundation.
# the Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 1998
# the Initial Developer. All Rights Reserved.
#

View File

@ -45,6 +45,10 @@ include $(DEPTH)/config/autoconf.mk
MODULE = build
ifeq ($(USE_ELF_HACK)$(HOST_OS_ARCH)$(OS_ARCH)$(OS_TARGET),1LinuxLinuxLinux)
DIRS = elfhack
endif
include $(topsrcdir)/config/rules.mk
libs:: $(srcdir)/run-mozilla.sh

View File

@ -0,0 +1,112 @@
#
# ***** 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 elfhack
#
# The Initial Developer of the Original Code is
# Mozilla Foundation
# Portions created by the Initial Developer are Copyright (C) 2010
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Mike Hommey <mh@glandium.org>
#
# Alternatively, the contents of this file may be used under the terms of
# either of the GNU General Public License Version 2 or later (the "GPL"),
# 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 *****
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
INTERNAL_TOOLS = 1
HOST_PROGRAM = elfhack
NO_DIST_INSTALL = 1
HOST_CPPSRCS = \
elf.cpp \
elfhack.cpp \
$(NULL)
OS_CXXFLAGS += -fexceptions
ifneq (,$(filter %86,$(TARGET_CPU)))
CPU := x86
else
CPU := $(TARGET_CPU)
endif
CSRCS := \
inject/$(CPU).c \
inject/$(CPU)-noinit.c \
$(NULL)
libs:: $(CSRCS:.c=.$(OBJ_SUFFIX))
ifndef CROSS_COMPILE
test$(DLL_SUFFIX): test.$(OBJ_SUFFIX) elfhack $(CSRCS:.c=.$(OBJ_SUFFIX))
$(MKSHLIB) $<
rm -f $@.bak
$(CURDIR)/elfhack -b $@
# Fail if the backup file doesn't exist
[ -f "$@.bak" ]
# Fail if the new library doesn't contain less relocations
[ $$(objdump -R $@.bak | wc -l) -gt $$(objdump -R $@ | wc -l) ]
dummy: dummy.$(OBJ_SUFFIX) test$(DLL_SUFFIX)
$(CC) -o $@ $^
libs:: dummy
# Will either crash or return exit code 1 if elfhack is broken
LD_LIBRARY_PATH=$(CURDIR) $(CURDIR)/dummy
CSRCS += test.c dummy.c
GARBAGE += dummy test$(DLL_SUFFIX) test$(DLL_SUFFIX).bak
endif
inject:
$(NSINSTALL) -D $@
inject/%.c: inject.c | inject
cp $< $@
GARBAGE_DIRS += inject
inject/%.$(OBJ_SUFFIX): DEFINES += -DBITS=$(if $(HAVE_64BIT_OS),64,32)
inject/$(CPU)-noinit.$(OBJ_SUFFIX): DEFINES += -DNOINIT
# need this to suppress errors due to /usr/include/linux/byteorder/swab.h
# on mozilla buildbots
OS_CXXFLAGS := $(filter-out -pedantic,$(OS_CXXFLAGS))
# Avoid building as thumb code, this is not supported yet
COMMA := ,
OS_CFLAGS := $(filter-out -mthumb -Wa$(COMMA)-mthumb,$(OS_CFLAGS))
include $(topsrcdir)/config/rules.mk

Some files were not shown because too many files have changed in this diff Show More