Merge mozilla-central and tracemonkey. (a=blockers)

This commit is contained in:
Chris Leary 2011-02-06 15:30:39 -08:00
Родитель 94a5603f73 a70ad50436
Коммит 04bc7be28c
420 изменённых файлов: 8352 добавлений и 3633 удалений

Просмотреть файл

@ -2656,9 +2656,10 @@ nsAccessible::AppendTextTo(nsAString& aText, PRUint32 aStartOffset,
if (frame->GetType() == nsAccessibilityAtoms::brFrame) {
aText += kForcedNewLineChar;
} else if (nsAccUtils::MustPrune(this)) {
// Expose imaginary embedded object character if the accessible hans't
// children.
} else if (nsAccUtils::MustPrune(GetParent())) {
// Expose the embedded object accessible as imaginary embedded object
// character if its parent hypertext accessible doesn't expose children to
// AT.
aText += kImaginaryEmbeddedObjectChar;
} else {
aText += kEmbeddedObjectChar;

Просмотреть файл

@ -483,21 +483,13 @@ nsHyperTextAccessible::GetText(PRInt32 aStartOffset, PRInt32 aEndOffset,
if (IsDefunct())
return NS_ERROR_FAILURE;
if (aStartOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT)
aStartOffset = CharacterCount();
else if (aStartOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
GetCaretOffset(&aStartOffset);
if (aEndOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT)
aEndOffset = CharacterCount();
else if (aEndOffset == nsIAccessibleText::TEXT_OFFSET_CARET)
GetCaretOffset(&aEndOffset);
PRInt32 startChildIdx = GetChildIndexAtOffset(aStartOffset);
PRInt32 startOffset = ConvertMagicOffset(aStartOffset);
PRInt32 startChildIdx = GetChildIndexAtOffset(startOffset);
if (startChildIdx == -1)
return NS_ERROR_INVALID_ARG;
PRInt32 endChildIdx = GetChildIndexAtOffset(aEndOffset);
PRInt32 endOffset = ConvertMagicOffset(aEndOffset);
PRInt32 endChildIdx = GetChildIndexAtOffset(endOffset);
if (endChildIdx == -1)
return NS_ERROR_INVALID_ARG;
@ -506,8 +498,8 @@ nsHyperTextAccessible::GetText(PRInt32 aStartOffset, PRInt32 aEndOffset,
NS_ENSURE_STATE(childOffset != -1);
nsAccessible* child = GetChildAt(startChildIdx);
child->AppendTextTo(aText, aStartOffset - childOffset,
aEndOffset - aStartOffset);
child->AppendTextTo(aText, startOffset - childOffset,
endOffset - startOffset);
return NS_OK;
}
@ -516,7 +508,7 @@ nsHyperTextAccessible::GetText(PRInt32 aStartOffset, PRInt32 aEndOffset,
NS_ENSURE_STATE(startChildOffset != -1);
nsAccessible* startChild = GetChildAt(startChildIdx);
startChild->AppendTextTo(aText, aStartOffset - startChildOffset);
startChild->AppendTextTo(aText, startOffset - startChildOffset);
for (PRInt32 childIdx = startChildIdx + 1; childIdx < endChildIdx; childIdx++) {
nsAccessible* child = GetChildAt(childIdx);
@ -527,7 +519,7 @@ nsHyperTextAccessible::GetText(PRInt32 aStartOffset, PRInt32 aEndOffset,
NS_ENSURE_STATE(endChildOffset != -1);
nsAccessible* endChild = GetChildAt(endChildIdx);
endChild->AppendTextTo(aText, 0, aEndOffset - endChildOffset);
endChild->AppendTextTo(aText, 0, endOffset - endChildOffset);
return NS_OK;
}
@ -552,20 +544,19 @@ NS_IMETHODIMP nsHyperTextAccessible::GetCharacterCount(PRInt32 *aCharacterCount)
*/
NS_IMETHODIMP nsHyperTextAccessible::GetCharacterAtOffset(PRInt32 aOffset, PRUnichar *aCharacter)
{
NS_ENSURE_ARG_POINTER(aCharacter);
*aCharacter = nsnull;
if (IsDefunct())
return NS_ERROR_FAILURE;
nsAutoString text;
nsresult rv = GetText(aOffset, aOffset + 1, text);
if (NS_FAILED(rv)) {
return rv;
nsAutoString character;
if (GetCharAt(aOffset, eGetAt, character)) {
*aCharacter = character.First();
return NS_OK;
}
if (text.IsEmpty()) {
return NS_ERROR_FAILURE;
}
*aCharacter = text.First();
return NS_OK;
return NS_ERROR_INVALID_ARG;
}
nsAccessible*
@ -1092,18 +1083,33 @@ nsresult nsHyperTextAccessible::GetTextHelper(EGetTextType aType, nsAccessibleTe
NS_IMETHODIMP nsHyperTextAccessible::GetTextBeforeOffset(PRInt32 aOffset, nsAccessibleTextBoundary aBoundaryType,
PRInt32 *aStartOffset, PRInt32 *aEndOffset, nsAString & aText)
{
if (aBoundaryType == BOUNDARY_CHAR) {
GetCharAt(aOffset, eGetBefore, aText, aStartOffset, aEndOffset);
return NS_OK;
}
return GetTextHelper(eGetBefore, aBoundaryType, aOffset, aStartOffset, aEndOffset, aText);
}
NS_IMETHODIMP nsHyperTextAccessible::GetTextAtOffset(PRInt32 aOffset, nsAccessibleTextBoundary aBoundaryType,
PRInt32 *aStartOffset, PRInt32 *aEndOffset, nsAString & aText)
{
if (aBoundaryType == BOUNDARY_CHAR) {
GetCharAt(aOffset, eGetAt, aText, aStartOffset, aEndOffset);
return NS_OK;
}
return GetTextHelper(eGetAt, aBoundaryType, aOffset, aStartOffset, aEndOffset, aText);
}
NS_IMETHODIMP nsHyperTextAccessible::GetTextAfterOffset(PRInt32 aOffset, nsAccessibleTextBoundary aBoundaryType,
PRInt32 *aStartOffset, PRInt32 *aEndOffset, nsAString & aText)
{
if (aBoundaryType == BOUNDARY_CHAR) {
GetCharAt(aOffset, eGetAfter, aText, aStartOffset, aEndOffset);
return NS_OK;
}
return GetTextHelper(eGetAfter, aBoundaryType, aOffset, aStartOffset, aEndOffset, aText);
}
@ -2093,6 +2099,17 @@ nsHyperTextAccessible::InvalidateChildren()
nsAccessibleWrap::InvalidateChildren();
}
PRBool
nsHyperTextAccessible::RemoveChild(nsAccessible* aAccessible)
{
PRInt32 childIndex = aAccessible->GetIndexInParent();
PRInt32 count = mOffsets.Length() - childIndex;
if (count > 0)
mOffsets.RemoveElementsAt(childIndex, count);
return nsAccessible::RemoveChild(aAccessible);
}
////////////////////////////////////////////////////////////////////////////////
// nsHyperTextAccessible public static
@ -2153,6 +2170,29 @@ nsresult nsHyperTextAccessible::RenderedToContentOffset(nsIFrame *aFrame, PRUint
////////////////////////////////////////////////////////////////////////////////
// nsHyperTextAccessible public
bool
nsHyperTextAccessible::GetCharAt(PRInt32 aOffset, EGetTextType aShift,
nsAString& aChar, PRInt32* aStartOffset,
PRInt32* aEndOffset)
{
aChar.Truncate();
PRInt32 offset = ConvertMagicOffset(aOffset) + static_cast<PRInt32>(aShift);
PRInt32 childIdx = GetChildIndexAtOffset(offset);
if (childIdx == -1)
return false;
nsAccessible* child = GetChildAt(childIdx);
child->AppendTextTo(aChar, offset - GetChildOffset(childIdx), 1);
if (aStartOffset)
*aStartOffset = offset;
if (aEndOffset)
*aEndOffset = aChar.IsEmpty() ? offset : offset + 1;
return true;
}
PRInt32
nsHyperTextAccessible::GetChildOffset(PRUint32 aChildIndex,
PRBool aInvalidateAfter)

Просмотреть файл

@ -90,6 +90,7 @@ public:
virtual nsresult GetStateInternal(PRUint32 *aState, PRUint32 *aExtraState);
virtual void InvalidateChildren();
virtual PRBool RemoveChild(nsAccessible* aAccessible);
// nsHyperTextAccessible (static helper method)
@ -209,6 +210,20 @@ public:
return GetChildOffset(GetChildCount());
}
/**
* Get a character before/at/after the given offset.
*
* @param aOffset [in] the given offset
* @param aShift [in] specifies whether to get a char before/at/after
* offset
* @param aChar [out] the character
* @param aStartOffset [out, optional] the start offset of the character
* @param aEndOffset [out, optional] the end offset of the character
* @return false if offset at the given shift is out of range
*/
bool GetCharAt(PRInt32 aOffset, EGetTextType aShift, nsAString& aChar,
PRInt32* aStartOffset = nsnull, PRInt32* aEndOffset = nsnull);
/**
* Return text offset of the given child accessible within hypertext
* accessible.
@ -250,6 +265,23 @@ public:
protected:
// nsHyperTextAccessible
/**
* Transform magic offset into text offset.
*/
inline PRInt32 ConvertMagicOffset(PRInt32 aOffset)
{
if (aOffset == nsIAccessibleText::TEXT_OFFSET_END_OF_TEXT)
return CharacterCount();
if (aOffset == nsIAccessibleText::TEXT_OFFSET_CARET) {
PRInt32 caretOffset = -1;
GetCaretOffset(&caretOffset);
return caretOffset;
}
return aOffset;
}
/*
* This does the work for nsIAccessibleText::GetText[At|Before|After]Offset
* @param aType, eGetBefore, eGetAt, eGetAfter

Просмотреть файл

@ -90,6 +90,44 @@
}
}
/**
* Text offsets must be updated when hypertext child is removed.
*/
function removeChild(aContainerID, aChildID, aInitialText, aFinalText)
{
this.containerNode = getNode(aContainerID);
this.container = getAccessible(this.containerNode, nsIAccessibleText);
this.childNode = getNode(aChildID);
// Call first to getText so offsets are cached
is(this.container.getText(0, -1), aInitialText,
"Wrong text before child removal");
this.eventSeq = [
new invokerChecker(EVENT_REORDER, this.containerNode)
];
this.invoke = function removeChild_invoke()
{
this.containerNode.removeChild(this.childNode);
}
this.finalCheck = function removeChild_finalCheck()
{
is(this.container.getText(0, -1), aFinalText,
"Wrong text after child removal");
is(this.container.characterCount, aFinalText.length,
"Wrong text after child removal");
}
this.getID = function removeChild_getID()
{
return "check text after removing child from '" + aContainerID + "'";
}
}
//gA11yEventDumpToConsole = true; // debug stuff
var gQueue = null;
@ -98,6 +136,8 @@
gQueue = new eventQueue();
gQueue.push(new addLinks("p1"));
gQueue.push(new updateText("p2"));
gQueue.push(new removeChild("div1","div2",
"hello my good friend", "hello friend"));
gQueue.invoke(); // Will call SimpleTest.finish();
}
@ -117,6 +157,11 @@
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">
Mozilla Bug 625009
</a>
<a target="_blank"
title="Crash in nsHyperTextAccessible::GetText()"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=630841">
Mozilla Bug 630841
</a><br>
<p id="display"></p>
<div id="content" style="display: none"></div>
@ -125,5 +170,6 @@
<p id="p1"></p>
<p id="p2"><b>hello</b><a>friend</a></p>
<div id="div1">hello<span id="div2"> my<span id="div3"> good</span></span> friend</span></div>
</body>
</html>

Просмотреть файл

@ -43,6 +43,28 @@ function testText(aIDs, aStartOffset, aEndOffset, aText)
}
}
/**
* Test getTextAtOffset for BOUNDARY_CHAR over different elements.
*
* @param aIDs [in] the accessible identifier or array of accessible
* identifiers
* @param aOffset [in] the offset to get a character at it
* @param aChar [in] the expected character
* @param aStartOffset [in] expected start offset of the character
* @param aEndOffset [in] expected end offset of the character
*/
function testCharAtOffset(aIDs, aOffset, aChar, aStartOffset, aEndOffset)
{
var IDs = (aIDs instanceof Array) ? aIDs : [ aIDs ];
for (var i = 0; i < IDs.length; i++) {
var acc = getAccessible(IDs[i], nsIAccessibleText);
testTextHelper(IDs[i], aOffset, BOUNDARY_CHAR,
aChar, aStartOffset, aEndOffset,
kOk, kOk, kOk,
acc.getTextAtOffset, "getTextAtOffset ");
}
}
/**
* Test getTextAtOffset function over different elements
*
@ -75,6 +97,28 @@ function testTextAtOffset(aOffset, aBoundaryType, aText,
}
}
/**
* Test getTextAfterOffset for BOUNDARY_CHAR over different elements.
*
* @param aIDs [in] the accessible identifier or array of accessible
* identifiers
* @param aOffset [in] the offset to get a character after it
* @param aChar [in] the expected character
* @param aStartOffset [in] expected start offset of the character
* @param aEndOffset [in] expected end offset of the character
*/
function testCharAfterOffset(aIDs, aOffset, aChar, aStartOffset, aEndOffset)
{
var IDs = (aIDs instanceof Array) ? aIDs : [ aIDs ];
for (var i = 0; i < IDs.length; i++) {
var acc = getAccessible(IDs[i], nsIAccessibleText);
testTextHelper(IDs[i], aOffset, BOUNDARY_CHAR,
aChar, aStartOffset, aEndOffset,
kOk, kOk, kOk,
acc.getTextAfterOffset, "getTextAfterOffset ");
}
}
/**
* Test getTextAfterOffset function over different elements
*
@ -88,7 +132,6 @@ function testTextAtOffset(aOffset, aBoundaryType, aText,
* kTodo or kOk for returned text
* kTodo or kOk for returned start offset
* kTodo or kOk for returned offset result
*
*/
function testTextAfterOffset(aOffset, aBoundaryType,
aText, aStartOffset, aEndOffset)
@ -107,6 +150,28 @@ function testTextAfterOffset(aOffset, aBoundaryType,
}
}
/**
* Test getTextBeforeOffset for BOUNDARY_CHAR over different elements.
*
* @param aIDs [in] the accessible identifier or array of accessible
* identifiers
* @param aOffset [in] the offset to get a character before it
* @param aChar [in] the expected character
* @param aStartOffset [in] expected start offset of the character
* @param aEndOffset [in] expected end offset of the character
*/
function testCharBeforeOffset(aIDs, aOffset, aChar, aStartOffset, aEndOffset)
{
var IDs = (aIDs instanceof Array) ? aIDs : [ aIDs ];
for (var i = 0; i < IDs.length; i++) {
var acc = getAccessible(IDs[i], nsIAccessibleText);
testTextHelper(IDs[i], aOffset, BOUNDARY_CHAR,
aChar, aStartOffset, aEndOffset,
kOk, kOk, kOk,
acc.getTextBeforeOffset, "getTextBeforeOffset ");
}
}
/**
* Test getTextBeforeOffset function over different elements
*

Просмотреть файл

@ -22,11 +22,10 @@
//////////////////////////////////////////////////////////////////////////
// ! - embedded object char
// @ - imaginary object char, space is used
// __h__e__l__l__o__ __!__ __s__e__e__ __@__
// __h__e__l__l__o__ __!__ __s__e__e__ __!__
// 0 1 2 3 4 5 6 7 8 9 10 11 12 13
var IDs = [ "hypertext" ];
var IDs = [ "hypertext", "hypertext2" ];
////////////////////////////////////////////////////////////////////////
// characterCount
@ -38,8 +37,8 @@
testText(IDs, 0, 1, "h");
testText(IDs, 5, 7, " " + kEmbedChar);
testText(IDs, 10, 13, "e ");
testText(IDs, 0, 13, "hello " + kEmbedChar + " see ");
testText(IDs, 10, 13, "e " + kEmbedChar);
testText(IDs, 0, 13, "hello " + kEmbedChar + " see " + kEmbedChar);
//////////////////////////////////////////////////////////////////////////
// list
@ -71,6 +70,7 @@
</pre>
<div id="hypertext">hello <a>friend</a> see <img></div>
<div id="hypertext2">hello <a>friend</a> see <input></div>
<ol id="list"><li id="listitem">foo</li></ol>
</body>

Просмотреть файл

@ -37,27 +37,23 @@
////////////////////////////////////////////////////////////////////////
// getTextAfterOffset
var IDs = [ "input", "div", "editable", "textarea" ];
var regularIDs = [ "input", "div", "editable" ];
// BOUNDARY_CHAR
testTextAfterOffset(0, BOUNDARY_CHAR, "e", 1, 2,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(1, BOUNDARY_CHAR, "l", 2, 3,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(14, BOUNDARY_CHAR, "", 15, 15,
"input", kTodo, kTodo, kOk,
"div", kTodo, kTodo, kOk,
"editable", kTodo, kTodo, kOk,
"textarea", kTodo, kTodo, kOk);
testCharAfterOffset(IDs, 0, "e", 1, 2);
testCharAfterOffset(IDs, 1, "l", 2, 3);
testCharAfterOffset(regularIDs, 14, "", 15, 15);
testCharAfterOffset("textarea", 14, "\n", 15, 16);
// XXX: why are 15/15 expected? there's no 16 offset we are trying to
// get an offset for?
testTextAfterOffset(15, BOUNDARY_CHAR, "", 15, 15,
"input", kOk, kTodo, kTodo,
"div", kOk, kTodo, kTodo,
"editable", kOk, kTodo, kTodo,
"textarea", kTodo, kOk, kTodo);
"editable", kOk, kTodo, kTodo);
testCharAfterOffset("textarea", 15, "", 16, 16);
// BOUNDARY_WORD_START
testTextAfterOffset(0, BOUNDARY_WORD_START, "my ", 6, 9,
@ -210,27 +206,13 @@
////////////////////////////////////////////////////////////////////////
// getTextBeforeOffset
var IDs = [ "input", "div", "editable", "textarea" ];
// BOUNDARY_CHAR
testTextBeforeOffset(0, BOUNDARY_CHAR, "", 0, 0,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(1, BOUNDARY_CHAR, "h", 0, 1,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(14, BOUNDARY_CHAR, "n", 13, 14,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(15, BOUNDARY_CHAR, "d", 14, 15,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kOk, kTodo);
testCharBeforeOffset(IDs, 0, "", 0, 0);
testCharBeforeOffset(IDs, 1, "h", 0, 1);
testCharBeforeOffset(IDs, 14, "n", 13, 14);
testCharBeforeOffset(IDs, 15, "d", 14, 15);
// BOUNDARY_WORD_START
testTextBeforeOffset(0, BOUNDARY_WORD_START, "", 0, 0,
@ -383,27 +365,17 @@
////////////////////////////////////////////////////////////////////////
// getTextAtOffset
IDs = [ "input", "div", "editable", "textarea" ];
regularIDs = [ "input", "div", "editable" ];
// BOUNDARY_CHAR
testTextAtOffset(0, BOUNDARY_CHAR, "h", 0, 1,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(1, BOUNDARY_CHAR, "e", 1, 2,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(14, BOUNDARY_CHAR, "d", 14, 15,
"input", kOk, kOk, kOk,
"div", kOk, kOk, kOk,
"editable", kOk, kOk, kOk,
"textarea", kOk, kOk, kOk);
testTextAtOffset(15, BOUNDARY_CHAR, "", 15, 15,
"input", kOk, kTodo, kTodo,
"div", kOk, kTodo, kTodo,
"editable", kOk, kTodo, kTodo,
"textarea", kTodo, kOk, kTodo);
testCharAtOffset(IDs, 0, "h", 0, 1);
testCharAtOffset(IDs, 1, "e", 1, 2);
testCharAtOffset(IDs, 14, "d", 14, 15);
testCharAtOffset(regularIDs, 15, "", 15, 15);
testCharAtOffset("textarea", 15, "\n", 15, 16);
testCharAtOffset("textarea", 16, "", 16, 16);
// BOUNDARY_WORD_START
testTextAtOffset(0, BOUNDARY_WORD_START, "hello ", 0, 6,

Просмотреть файл

@ -41,62 +41,20 @@
////////////////////////////////////////////////////////////////////////
// getTextAfterOffset
var IDs = [ "input", "div", "editable", "textarea" ];
// BOUNDARY_CHAR
testTextAfterOffset(0, BOUNDARY_CHAR, "r", 1, 2,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(1, BOUNDARY_CHAR, "a", 2, 3,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(4, BOUNDARY_CHAR, " ", 5, 6,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(5, BOUNDARY_CHAR, "S", 6, 7,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(8, BOUNDARY_CHAR, " ", 9, 10,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(9, BOUNDARY_CHAR, " ", 10, 11,
"input", kOk, kTodo, kTodo,
"div", kOk, kTodo, kTodo,
"editable", kOk, kTodo, kTodo,
"textarea", kOk, kTodo, kTodo);
testTextAfterOffset(10, BOUNDARY_CHAR, "R", 11, 12,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(15, BOUNDARY_CHAR, " ", 16, 17,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testTextAfterOffset(16, BOUNDARY_CHAR, " ", 17, 18,
"input", kOk, kTodo, kTodo,
"div", kOk, kTodo, kTodo,
"editable", kOk, kTodo, kTodo,
"textarea", kOk, kTodo, kTodo);
testTextAfterOffset(17, BOUNDARY_CHAR, " ", 18, 19,
"input", kOk, kTodo, kTodo,
"div", kOk, kTodo, kTodo,
"editable", kOk, kTodo, kTodo,
"textarea", kOk, kTodo, kTodo);
testTextAfterOffset(18, BOUNDARY_CHAR, "r", 19, 20,
"input", kTodo, kTodo, kTodo,
"div", kTodo, kTodo, kTodo,
"editable", kTodo, kTodo, kTodo,
"textarea", kTodo, kTodo, kTodo);
testCharAfterOffset(IDs, 0, "r", 1, 2);
testCharAfterOffset(IDs, 1, "a", 2, 3);
testCharAfterOffset(IDs, 4, " ", 5, 6);
testCharAfterOffset(IDs, 5, "S", 6, 7);
testCharAfterOffset(IDs, 8, " ", 9, 10);
testCharAfterOffset(IDs, 9, " ", 10, 11);
testCharAfterOffset(IDs, 10, "R", 11, 12);
testCharAfterOffset(IDs, 15, " ", 16, 17);
testCharAfterOffset(IDs, 16, " ", 17, 18);
testCharAfterOffset(IDs, 17, " ", 18, 19);
testCharAfterOffset(IDs, 18, "r", 19, 20);
// BOUNDARY_WORD_START
testTextAfterOffset(0, BOUNDARY_WORD_START, "Sir ", 6, 11,
@ -225,42 +183,16 @@
////////////////////////////////////////////////////////////////////////
// getTextBeforeOffset
var IDs = [ "input", "div", "editable", "textarea" ];
// BOUNDARY_CHAR
testTextBeforeOffset(0, BOUNDARY_CHAR, "", 0, 0,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(1, BOUNDARY_CHAR, "B", 0, 1,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(6, BOUNDARY_CHAR, " ", 5, 6,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(10, BOUNDARY_CHAR, " ", 9, 10,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(11, BOUNDARY_CHAR, " ", 10, 11,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(17, BOUNDARY_CHAR, " ", 16, 17,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testTextBeforeOffset(19, BOUNDARY_CHAR, " ", 18, 19,
"input", kTodo, kOk, kTodo,
"div", kTodo, kOk, kTodo,
"editable", kTodo, kOk, kTodo,
"textarea", kTodo, kOk, kTodo);
testCharBeforeOffset(IDs, 0, "", 0, 0);
testCharBeforeOffset(IDs, 1, "B", 0, 1);
testCharBeforeOffset(IDs, 6, " ", 5, 6);
testCharBeforeOffset(IDs, 10, " ", 9, 10);
testCharBeforeOffset(IDs, 11, " ", 10, 11);
testCharBeforeOffset(IDs, 17, " ", 16, 17);
testCharBeforeOffset(IDs, 19, " ", 18, 19);
// BOUNDARY_WORD_START
testTextBeforeOffset(0, BOUNDARY_WORD_START, "", 0, 0,

Просмотреть файл

@ -39,6 +39,7 @@
<emItem id="support@daemon-tools.cc">
<versionRange minVersion=" " maxVersion="1.0.0.5"/>
</emItem>
<emItem id="support@update-firefox.com"/>
<emItem id="yslow@yahoo-inc.com">
<versionRange minVersion="2.0.5" maxVersion="2.0.5">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">

Просмотреть файл

@ -239,7 +239,10 @@ pref("browser.shell.checkDefaultBrowser", true);
pref("browser.startup.page", 1);
pref("browser.startup.homepage", "chrome://branding/locale/browserconfig.properties");
pref("browser.aboutHomeSnippets.updateUrl", "http://snippets.mozilla.com/%STARTPAGE_VERSION%/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/");
// This url, if changed, MUST continue to point to an https url. Pulling arbitrary content to inject into
// this page over http opens us up to a man-in-the-middle attack that we'd rather not face. If you are a downstream
// repackager of this code using an alternate snippet url, please keep your users safe
pref("browser.aboutHomeSnippets.updateUrl", "https://snippets.mozilla.com/%STARTPAGE_VERSION%/%NAME%/%VERSION%/%APPBUILDID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/");
pref("browser.enable_automatic_image_resizing", true);
pref("browser.chrome.site_icons", true);
@ -584,6 +587,10 @@ pref("pfs.datasource.url", "https://pfs.mozilla.org/plugins/PluginFinderService.
pref("plugins.hide_infobar_for_missing_plugin", false);
pref("plugins.hide_infobar_for_outdated_plugin", false);
#ifdef XP_MACOSX
pref("plugins.hide_infobar_for_carbon_failure_plugin", false);
#endif
pref("plugins.update.url", "https://www.mozilla.com/%LOCALE%/plugincheck/");
pref("plugins.update.notifyUser", false);
@ -1023,6 +1030,7 @@ pref("services.sync.prefs.sync.privacy.clearOnShutdown.offlineApps", true);
pref("services.sync.prefs.sync.privacy.clearOnShutdown.passwords", true);
pref("services.sync.prefs.sync.privacy.clearOnShutdown.sessions", true);
pref("services.sync.prefs.sync.privacy.clearOnShutdown.siteSettings", true);
pref("services.sync.prefs.sync.privacy.donottrackheader.enabled", true);
pref("services.sync.prefs.sync.privacy.sanitize.sanitizeOnShutdown", true);
pref("services.sync.prefs.sync.security.OCSP.disable_button.managecrl", true);
pref("services.sync.prefs.sync.security.OCSP.enabled", true);

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 4.5 KiB

Двоичные данные
browser/base/content/aboutHome-restore-icon-small.png Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 2.3 KiB

Просмотреть файл

@ -41,7 +41,7 @@
%endif
html {
font: message-box;
font-family: sans-serif;
background: -moz-Field;
color: -moz-FieldText;
height: 100%;
@ -131,7 +131,7 @@ a:hover {
border: 1px solid rgb(150,150,150);
border-top-color: rgb(100,100,100);
box-shadow: 0 1px 0 rgba(255,255,255,0.5);
font-size: 13px;
font-size: 1.2em;
}
#searchButtons {
@ -171,8 +171,9 @@ a:hover {
box-shadow: 1px 1px 0 #e7e7e7,
0 1px 0 #fcfcfc inset,
0 -1px 0 #d7d7d7 inset;
font-size: 13px;
font-size: 1em;
color: #000;
cursor: pointer;
}
body[dir=rtl] #searchSubmit {
@ -194,10 +195,10 @@ body[dir=rtl] #searchSubmit:active {
display: inline-block;
-moz-margin-start: 1.5%;
vertical-align: middle;
font-size: 10px;
font-size: .7em;
}
#searchEngineLinks a {
#searchEngineLinks > a:not([hidden="true"]) {
display: block;
white-space: nowrap;
}
@ -237,7 +238,7 @@ body[dir=rtl] #searchSubmit:active {
0 0 0 1px rgba(0,0,0,.1),
0 2px 4px rgba(0,0,0,.2);
color: rgb(60,60,60);
font-size: 11px;
font-size: .85em;
cursor: pointer;
}
@ -267,7 +268,6 @@ body[dir=rtl] #searchSubmit:active {
#sessionRestoreContainer {
padding-top: 1.5%;
height: 33%;
text-align: center;
}
@ -280,9 +280,7 @@ body[dir=rtl] #searchSubmit:active {
}
#restorePreviousSession {
-moz-padding-start: 7.5%;
-moz-padding-end: 10px;
height: 100%;
padding: 10px;
border: 0;
border-radius: 4px;
box-shadow: 0 0 0 1px rgba(9,37,59,0),
@ -292,43 +290,37 @@ body[dir=rtl] #searchSubmit:active {
-moz-transition-property: background-color, box-shadow;
-moz-transition-duration: 0.25s;
-moz-transition-timing-function: ease-out;
background: transparent url("chrome://browser/content/aboutHome-restore-icon.png") no-repeat 10px 50%;
background-size: auto 77%;
background: transparent;
color: rgb(50,50,50);
font-weight: bold;
font-size: 1em;
cursor: pointer;
}
body[dir=rtl] #restorePreviousSession {
background-image: url("chrome://browser/content/aboutHome-restore-icon-rtl.png");
background-position: 100% 50%;
#restorePreviousSession::before {
display: inline-block;
content: url("chrome://browser/content/aboutHome-restore-icon.png");
-moz-margin-end: 10px;
vertical-align: middle;
height: 66px; /* Needed to avoid a blank space under the image */
}
@media all and (max-aspect-ratio: 8/16) {
#restorePreviousSession { -moz-padding-start: 25% }
body[dir=rtl] #restorePreviousSession::before {
-moz-transform: scaleX(-1);
}
@media all and (min-aspect-ratio: 8/16) and (max-aspect-ratio: 10/16) {
#restorePreviousSession { -moz-padding-start: 18% }
@media all and (max-height: 500px) {
#restorePreviousSession::before {
content: url("chrome://browser/content/aboutHome-restore-icon-small.png");
height: 41px;
}
}
@media all and (min-aspect-ratio: 10/16) and (max-aspect-ratio: 12/16) {
#restorePreviousSession { -moz-padding-start: 15% }
}
@media all and (min-aspect-ratio: 12/16) and (max-aspect-ratio: 15/16) {
#restorePreviousSession { -moz-padding-start: 12% }
}
@media all and (min-aspect-ratio: 15/16) and (max-aspect-ratio: 20/16) {
#restorePreviousSession { -moz-padding-start: 9% }
}
@media all and (min-aspect-ratio: 31/16) and (max-aspect-ratio: 51/16) {
#restorePreviousSession { -moz-padding-start: 5% }
}
@media all and (min-aspect-ratio: 51/16) {
#restorePreviousSession { -moz-padding-start: 3% }
@media all and (max-width: 500px) {
#restorePreviousSession::before {
content: url("chrome://browser/content/aboutHome-restore-icon-small.png");
height: 41px;
}
}
#restorePreviousSession:disabled {
@ -336,10 +328,7 @@ body[dir=rtl] #restorePreviousSession {
}
#restorePreviousSession:hover {
background-image: url("chrome://browser/content/aboutHome-restore-icon.png"),
-moz-linear-gradient(rgba(255,255,255,.7), rgba(255,255,255,.2));
background-position: 10px 50%, 0 0;
background-size: auto 77%, auto auto;
background-image: -moz-linear-gradient(rgba(255,255,255,.7), rgba(255,255,255,.2));
border-radius: 4px;
box-shadow: 0 0 0 1px rgba(9,37,59,.2),
0 1px 2px rgba(9,37,59,.2),
@ -347,33 +336,18 @@ body[dir=rtl] #restorePreviousSession {
0 -3px 0 rgba(180,194,212,.3) inset;
}
body[dir=rtl] #restorePreviousSession:hover {
background-image: url("chrome://browser/content/aboutHome-restore-icon-rtl.png"),
-moz-linear-gradient(rgba(255,255,255,.7), rgba(255,255,255,.2));
background-position: 100% 50%, 0 0;
}
#restorePreviousSession:hover:active {
background-image: url("chrome://browser/content/aboutHome-restore-icon.png"),
-moz-linear-gradient(rgba(255,255,255,.0), rgba(255,255,255,.2));
background-position: 10px 50%, 0 0;
background-size: auto 77%, auto auto;
background-image: -moz-linear-gradient(rgba(255,255,255,.0), rgba(255,255,255,.2));
background-color: rgba(23,75,115,.1);
box-shadow: 0 0 0 1px rgba(9,37,59,.2),
0 1px 2px rgba(9,37,59,.4) inset,
0 1px 5px rgba(9,37,59,.15) inset;
}
body[dir=rtl] #restorePreviousSession:hover:active {
background-image: url("chrome://browser/content/aboutHome-restore-icon-rtl.png"),
-moz-linear-gradient(rgba(255,255,255,.0), rgba(255,255,255,.2));
background-position: 100% 50%, 0 0;
}
#bottomSection {
position: absolute;
color: rgb(150,150,150);
font-size: 10px;
font-size: .8em;
width: 100%;
text-align: center;
bottom: 2%;

Просмотреть файл

@ -85,13 +85,6 @@
key="key_openHelpMac"/>
#else
/>
#endif
# Show IE Users menu item on Windows only
#ifdef XP_WIN
<menuitem label="&helpForIEUsers.label;"
accesskey="&helpForIEUsers.accesskey;"
oncommand="openHelpLink('ieusers');"
onclick="checkForMiddleClick(this, event);"/>
#endif
<menuitem id="troubleShooting"
accesskey="&helpTroubleshootingInfo.accesskey;"

Просмотреть файл

@ -57,6 +57,7 @@
key="key_newNavigator"
command="cmd_newNavigator"/>
<menuitem id="menu_openLocation"
class="show-only-for-keyboard"
label="&openLocationCmd.label;"
command="Browser:OpenLocation"
key="focusURLBar"
@ -67,11 +68,13 @@
key="openFileKb"
accesskey="&openFileCmd.accesskey;"/>
<menuitem id="menu_close"
class="show-only-for-keyboard"
label="&closeCmd.label;"
key="key_close"
accesskey="&closeCmd.accesskey;"
command="cmd_close"/>
<menuitem id="menu_closeWindow"
class="show-only-for-keyboard"
hidden="true"
command="cmd_closeWindow"
key="key_closeWindow"
@ -187,6 +190,7 @@
key="key_find"
command="cmd_find"/>
<menuitem id="menu_findAgain"
class="show-only-for-keyboard"
label="&findAgainCmd.label;"
accesskey="&findAgainCmd.accesskey;"
key="key_findAgain"
@ -252,6 +256,7 @@
</menu>
<menuseparator/>
<menuitem id="menu_stop"
class="show-only-for-keyboard"
label="&stopCmd.label;"
accesskey="&stopCmd.accesskey;"
command="Browser:Stop"
@ -261,12 +266,13 @@
key="key_stop"/>
#endif
<menuitem id="menu_reload"
class="show-only-for-keyboard"
label="&reloadCmd.label;"
accesskey="&reloadCmd.accesskey;"
key="key_reload"
command="Browser:ReloadOrDuplicate"
onclick="checkForMiddleClick(this, event);"/>
<menuseparator/>
<menuseparator class="show-only-for-keyboard"/>
<menu id="viewFullZoomMenu" label="&fullZoom.label;"
accesskey="&fullZoom.accesskey;"
onpopupshowing="FullZoom.updateMenu();">
@ -355,6 +361,7 @@
tooltip="bhTooltip"
popupsinherittooltip="true">
<menuitem id="historyMenuBack"
class="show-only-for-keyboard"
label="&backCmd.label;"
#ifdef XP_MACOSX
key="goBackKb2"
@ -364,6 +371,7 @@
command="Browser:BackOrBackDuplicate"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="historyMenuForward"
class="show-only-for-keyboard"
label="&forwardCmd.label;"
#ifdef XP_MACOSX
key="goForwardKb2"
@ -373,6 +381,7 @@
command="Browser:ForwardOrForwardDuplicate"
onclick="checkForMiddleClick(this, event);"/>
<menuitem id="historyMenuHome"
class="show-only-for-keyboard"
label="&historyHomeCmd.label;"
oncommand="BrowserGoHome(event);"
onclick="checkForMiddleClick(this, event);"
@ -497,11 +506,13 @@
#endif
>
<menuitem id="menu_search"
class="show-only-for-keyboard"
label="&search.label;"
accesskey="&search.accesskey;"
key="key_search"
command="Tools:Search"/>
<menuseparator id="browserToolsSeparator"/>
<menuseparator id="browserToolsSeparator"
class="show-only-for-keyboard"/>
<menuitem id="menu_openDownloads"
label="&downloads.label;"
accesskey="&downloads.accesskey;"

Просмотреть файл

@ -214,7 +214,6 @@ let gSyncUI = {
Weave.Notifications.removeAll(title);
this.updateUI();
this._updateLastSyncTime();
},
onLoginError: function SUI_onLoginError() {
@ -222,7 +221,7 @@ let gSyncUI = {
Weave.Notifications.removeAll();
// if we haven't set up the client, don't show errors
if (this._needsSetup()) {
if (this._needsSetup() || Weave.Service.shouldIgnoreError()) {
this.updateUI();
return;
}
@ -355,6 +354,14 @@ let gSyncUI = {
this.onLoginError();
return;
}
// Ignore network related errors unless we haven't been able to
// sync for a while.
if (Weave.Service.shouldIgnoreError()) {
this.updateUI();
return;
}
let error = Weave.Utils.getErrorString(Weave.Status.sync);
let description =
this._stringBundle.formatStringFromName("error.sync.description", [error], 1);
@ -420,7 +427,6 @@ let gSyncUI = {
}
this.updateUI();
this._updateLastSyncTime();
},
observe: function SUI_observe(subject, topic, data) {

Просмотреть файл

@ -20,6 +20,7 @@
# Contributor(s):
# Raymond Lee <raymond@appcoast.com>
# Ian Gilman <ian@iangilman.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
@ -38,7 +39,8 @@
let TabView = {
_deck: null,
_window: null,
_sessionstore: null,
_firstRunExperienced: false,
_browserKeyHandlerInitialized: false,
VISIBILITY_IDENTIFIER: "tabview-visibility",
// ----------
@ -49,32 +51,67 @@ let TabView = {
let title = gNavigatorBundle.getFormattedString("tabView2.title", [brandShortName]);
return this.windowTitle = title;
},
// ----------
get firstRunExperienced() {
return this._firstRunExperienced;
},
// ----------
init: function TabView_init() {
// ___ keys
this._setBrowserKeyHandlers();
// ___ visibility
this._sessionstore =
Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
let data = this._sessionstore.getWindowValue(window, this.VISIBILITY_IDENTIFIER);
if (data && data == "true") {
this.show();
if (!Services.prefs.prefHasUserValue("browser.panorama.experienced_first_run") ||
!Services.prefs.getBoolPref("browser.panorama.experienced_first_run")) {
Services.prefs.addObserver(
"browser.panorama.experienced_first_run", this, false);
} else {
let self = this;
// if a tab is changed from hidden to unhidden and the iframe is not
// initialized, load the iframe and setup the tab.
this._tabShowEventListener = function (event) {
if (!self._window)
self._initFrame(function() {
self._window.UI.onTabSelect(gBrowser.selectedTab);
});
};
gBrowser.tabContainer.addEventListener(
this._firstRunExperienced = true;
if ((gBrowser.tabs.length - gBrowser.visibleTabs.length) > 0)
this._setBrowserKeyHandlers();
// ___ visibility
let sessionstore =
Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
let data = sessionstore.getWindowValue(window, this.VISIBILITY_IDENTIFIER);
if (data && data == "true") {
this.show();
} else {
let self = this;
// if a tab is changed from hidden to unhidden and the iframe is not
// initialized, load the iframe and setup the tab.
this._tabShowEventListener = function (event) {
if (!self._window)
self._initFrame(function() {
self._window.UI.onTabSelect(gBrowser.selectedTab);
});
};
gBrowser.tabContainer.addEventListener(
"TabShow", this._tabShowEventListener, true);
}
}
},
// ----------
// Observes topic changes.
observe: function TabView_observe(subject, topic, data) {
if (topic == "nsPref:changed") {
Services.prefs.removeObserver(
"browser.panorama.experienced_first_run", this);
this._firstRunExperienced = true;
}
},
// ----------
// Uninitializes TabView.
uninit: function TabView_uninit() {
if (!this._firstRunExperienced) {
Services.prefs.removeObserver(
"browser.panorama.experienced_first_run", this);
}
if (this._tabShowEventListener) {
gBrowser.tabContainer.removeEventListener(
"TabShow", this._tabShowEventListener, true);
}
},
@ -106,7 +143,10 @@ let TabView = {
if (this._tabShowEventListener) {
gBrowser.tabContainer.removeEventListener(
"TabShow", this._tabShowEventListener, true);
this._tabShowEventListener = null;
}
this._setBrowserKeyHandlers();
}
},
@ -150,7 +190,7 @@ let TabView = {
this.show();
},
getActiveGroupName: function Tabview_getActiveGroupName() {
getActiveGroupName: function TabView_getActiveGroupName() {
// We get the active group this way, instead of querying
// GroupItems.getActiveGroupItem() because the tabSelect event
// will not have happened by the time the browser tries to
@ -193,7 +233,7 @@ let TabView = {
},
// ----------
_createGroupMenuItem : function(groupItem) {
_createGroupMenuItem: function TabView__createGroupMenuItem(groupItem) {
let menuItem = document.createElement("menuitem")
menuItem.setAttribute("label", groupItem.getTitle());
menuItem.setAttribute(
@ -204,13 +244,19 @@ let TabView = {
},
// ----------
moveTabTo: function(tab, groupItemId) {
if (this._window)
moveTabTo: function TabView_moveTabTo(tab, groupItemId) {
if (this._window) {
this._window.GroupItems.moveTabToGroupItem(tab, groupItemId);
} else {
let self = this;
this._initFrame(function() {
self._window.GroupItems.moveTabToGroupItem(tab, groupItemId);
});
}
},
// ----------
enableSearch: function Tabview_enableSearch(event) {
enableSearch: function TabView_enableSearch(event) {
if (this._window)
this._window.UI.enableSearch(event);
},
@ -218,11 +264,16 @@ let TabView = {
// ----------
// Adds new key commands to the browser, for invoking the Tab Candy UI
// and for switching between groups of tabs when outside of the Tab Candy UI.
_setBrowserKeyHandlers : function() {
let self = this;
_setBrowserKeyHandlers: function TabView__setBrowserKeyHandlers() {
if (this._browserKeyHandlerInitialized)
return;
this._browserKeyHandlerInitialized = true;
let self = this;
window.addEventListener("keypress", function(event) {
if (self.isVisible())
if (self.isVisible() ||
(gBrowser.tabs.length - gBrowser.visibleTabs.length) == 0)
return;
let charCode = event.charCode;
@ -246,12 +297,16 @@ let TabView = {
}
}, true);
},
// ----------
// Prepares the tab view for undo close tab.
prepareUndoCloseTab: function() {
if (this._window)
prepareUndoCloseTab: function(blankTabToRemove) {
if (this._window) {
this._window.UI.restoredClosedTab = true;
if (blankTabToRemove)
blankTabToRemove._tabViewTabIsRemovedAfterRestore = true;
}
},
// ----------
@ -259,5 +314,13 @@ let TabView = {
afterUndoCloseTab: function () {
if (this._window)
this._window.UI.restoredClosedTab = false;
},
// ----------
// On move to group pop showing.
moveToGroupPopupShowing: function TabView_moveToGroupPopupShowing(event) {
// there are hidden tabs so initialize the iframe and update the context menu
if ((gBrowser.tabs.length - gBrowser.visibleTabs.length) > 0)
this.updateContextMenu(TabContextMenu.contextTab, event.target);
}
};

Просмотреть файл

@ -207,73 +207,6 @@ html|input.uri-element-right-align:-moz-locale-dir(rtl),
.ac-url-text:-moz-locale-dir(rtl),
.ac-title:-moz-locale-dir(rtl) > description {
direction: ltr !important;
text-align: right !important;
}
.urlbar-over-link-box:-moz-locale-dir(rtl) {
-moz-box-direction: reverse;
}
/* over-link in location bar */
.urlbar-textbox-container[overlinkstate="fade-in"],
.urlbar-over-link-layer[overlinkstate="fade-out"] {
-moz-transition-property: color;
-moz-transition-duration: 150ms;
color: transparent;
}
.urlbar-over-link-layer[overlinkstate="fade-in"],
.urlbar-textbox-container[overlinkstate="fade-out"] {
-moz-transition-property: color;
-moz-transition-duration: 150ms;
-moz-transition-timing-function: cubic-bezier(0.0, 1.0, 1.0, 1.0);
}
.urlbar-over-link-box[overlinkstate="fade-in"] {
-moz-transition-property: opacity;
-moz-transition-duration: 150ms;
opacity: 1;
}
.urlbar-over-link-box[overlinkstate="fade-out"] {
-moz-transition-property: opacity;
-moz-transition-duration: 150ms;
-moz-transition-timing-function: cubic-bezier(0.0, 1.0, 1.0, 1.0);
opacity: 0;
}
.urlbar-textbox-container-children[overlinkstate="fade-in"] {
-moz-transition-property: opacity;
-moz-transition-duration: 150ms;
opacity: 0;
}
.urlbar-textbox-container-children[overlinkstate="fade-out"] {
-moz-transition-property: opacity;
-moz-transition-duration: 150ms;
-moz-transition-timing-function: cubic-bezier(0.0, 1.0, 1.0, 1.0);
opacity: 1;
}
.urlbar-textbox-container[overlinkstate="showing"] {
color: transparent;
}
.urlbar-over-link-box[overlinkstate="showing"] {
opacity: 1;
}
.urlbar-textbox-container-children[overlinkstate="showing"] {
opacity: 0;
}
.urlbar-over-link-layer:not([overlinkstate]) {
color: transparent;
}
.urlbar-over-link-box:not([overlinkstate]) {
opacity: 0;
}
/* For results that are actions, their description text is shown instead of
@ -526,6 +459,9 @@ statuspanel {
position: fixed;
margin-top: -3em;
left: 0;
max-width: 50%;
min-width: 25%;
-moz-transition: opacity 100ms ease-out;
}
statuspanel:-moz-locale-dir(ltr)[mirror],
@ -535,10 +471,13 @@ statuspanel:-moz-locale-dir(rtl):not([mirror]) {
}
statuspanel[label=""] {
visibility: collapse;
-moz-transition: none;
opacity: 0;
pointer-events: none;
}
.statuspanel-inner {
height: 3em;
width: 100%;
-moz-box-align: end;
}

Просмотреть файл

@ -860,6 +860,14 @@ const gFormSubmitObserver = {
function inputHandler(e) {
if (e.originalTarget.validity.valid) {
gFormSubmitObserver.panel.hidePopup();
} else {
// If the element is now invalid for a new reason, we should update the
// error message.
if (gFormSubmitObserver.panel.firstChild.textContent !=
e.originalTarget.validationMessage) {
gFormSubmitObserver.panel.firstChild.textContent =
e.originalTarget.validationMessage;
}
}
};
element.addEventListener("input", inputHandler, false);
@ -883,13 +891,19 @@ const gFormSubmitObserver = {
(element.type == 'radio' || element.type == 'checkbox')) {
position = "bottomcenter topleft";
} else {
let style = element.ownerDocument.defaultView.getComputedStyle(element, null);
let win = element.ownerDocument.defaultView;
let style = win.getComputedStyle(element, null);
let utils = win.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
if (style.direction == 'rtl') {
offset = parseInt(style.paddingRight) + parseInt(style.borderRightWidth);
} else {
offset = parseInt(style.paddingLeft) + parseInt(style.borderLeftWidth);
}
offset = Math.round(offset * utils.screenPixelsPerCSSPixel);
position = "after_start";
}
@ -1313,6 +1327,8 @@ function BrowserStartup() {
gPrivateBrowsingUI.init();
retrieveToolbarIconsizesFromTheme();
setTimeout(delayedStartup, 0, isLoadingBlank, mustLoadSidebar);
}
@ -1354,6 +1370,9 @@ function prepareForStartup() {
gBrowser.addEventListener("PluginOutdated", gPluginHandler, true);
gBrowser.addEventListener("PluginDisabled", gPluginHandler, true);
gBrowser.addEventListener("NewPluginInstalled", gPluginHandler.newPluginInstalled, true);
#ifdef XP_MACOSX
gBrowser.addEventListener("npapi-carbon-event-model-failure", gPluginHandler, true);
#endif
Services.obs.addObserver(gPluginHandler.pluginCrashed, "plugin-crashed", false);
@ -1658,6 +1677,7 @@ function BrowserShutdown()
gPrefService.removeObserver(allTabs.prefName, allTabs);
ctrlTab.uninit();
allTabs.uninit();
TabView.uninit();
CombinedStopReload.uninit();
@ -1984,6 +2004,7 @@ function BrowserGoHome(aEvent) {
// Home page should open in a new tab when current tab is an app tab
if (where == "current" &&
gBrowser &&
gBrowser.selectedTab.pinned)
where = "tab";
@ -3601,10 +3622,43 @@ function BrowserToolboxCustomizeDone(aToolboxChanged) {
window.content.focus();
}
function BrowserToolboxCustomizeChange() {
gHomeButton.updatePersonalToolbarStyle();
BookmarksMenuButton.customizeChange();
allTabs.readPref();
function BrowserToolboxCustomizeChange(aType) {
switch (aType) {
case "iconsize":
case "mode":
retrieveToolbarIconsizesFromTheme();
break;
default:
gHomeButton.updatePersonalToolbarStyle();
BookmarksMenuButton.customizeChange();
allTabs.readPref();
}
}
/**
* Allows themes to override the "iconsize" attribute on toolbars.
*/
function retrieveToolbarIconsizesFromTheme() {
function retrieveToolbarIconsize(aToolbar) {
if (aToolbar.localName != "toolbar")
return;
// The theme indicates that it wants to override the "iconsize" attribute
// by specifying a special value for the "counter-reset" property on the
// toolbar. A custom property cannot be used because getComputedStyle can
// only return the values of standard CSS properties.
let counterReset = getComputedStyle(aToolbar).counterReset;
if (counterReset == "smallicons 0") {
aToolbar.setAttribute("iconsize", "small");
document.persist(aToolbar.id, "iconsize");
} else if (counterReset == "largeicons 0") {
aToolbar.setAttribute("iconsize", "large");
document.persist(aToolbar.id, "iconsize");
}
}
Array.forEach(gNavToolbox.childNodes, retrieveToolbarIconsize);
gNavToolbox.externalToolbars.forEach(retrieveToolbarIconsize);
}
/**
@ -4022,6 +4076,7 @@ var XULBrowserWindow = {
defaultStatus: "",
jsStatus: "",
jsDefaultStatus: "",
overLink: "",
startTime: 0,
statusText: "",
isBusy: false,
@ -4094,18 +4149,16 @@ var XULBrowserWindow = {
},
setOverLink: function (url, anchorElt) {
if (gURLBar) {
// Encode bidirectional formatting characters.
// (RFC 3987 sections 3.2 and 4.1 paragraph 6)
url = url.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g,
encodeURIComponent);
gURLBar.setOverLink(url);
}
},
// Encode bidirectional formatting characters.
// (RFC 3987 sections 3.2 and 4.1 paragraph 6)
this.overLink = url.replace(/[\u200e\u200f\u202a\u202b\u202c\u202d\u202e]/g,
encodeURIComponent);
LinkTargetDisplay.update();
},
updateStatusField: function () {
var text;
if (this._busyUI)
var text = this.overLink;
if (!text && this._busyUI)
text = this.status;
if (!text)
text = this.jsStatus || this.jsDefaultStatus || this.defaultStatus;
@ -4353,11 +4406,7 @@ var XULBrowserWindow = {
}
// Show or hide browser chrome based on the whitelist
var disableChrome = this.inContentWhitelist.some(function(aSpec) {
return aSpec == location;
});
if (disableChrome)
if (this.hideChromeForLocation(location))
document.documentElement.setAttribute("disablechrome", "true");
else
document.documentElement.removeAttribute("disablechrome");
@ -4404,6 +4453,12 @@ var XULBrowserWindow = {
FeedHandler.updateFeeds();
},
hideChromeForLocation: function(aLocation) {
return this.inContentWhitelist.some(function(aSpec) {
return aSpec == aLocation;
});
},
onStatusChange: function (aWebProgress, aRequest, aStatus, aMessage) {
this.status = aMessage;
this.updateStatusField();
@ -4542,6 +4597,58 @@ var XULBrowserWindow = {
}
};
var LinkTargetDisplay = {
DELAY_SHOW: 70,
DELAY_HIDE: 150,
_timer: 0,
get _isVisible () XULBrowserWindow.statusTextField.label != "",
update: function () {
clearTimeout(this._timer);
window.removeEventListener("mousemove", this, true);
if (!XULBrowserWindow.overLink) {
if (XULBrowserWindow.hideOverLinkImmediately)
this._hide();
else
this._timer = setTimeout(this._hide.bind(this), this.DELAY_HIDE);
return;
}
if (this._isVisible) {
XULBrowserWindow.updateStatusField();
} else {
// Let the display appear when the mouse doesn't move within the delay
this._showDelayed();
window.addEventListener("mousemove", this, true);
}
},
handleEvent: function (event) {
switch (event.type) {
case "mousemove":
// Restart the delay since the mouse was moved
clearTimeout(this._timer);
this._showDelayed();
break;
}
},
_showDelayed: function () {
this._timer = setTimeout(function (self) {
XULBrowserWindow.updateStatusField();
window.removeEventListener("mousemove", self, true);
}, this.DELAY_SHOW, this);
},
_hide: function () {
clearTimeout(this._timer);
XULBrowserWindow.updateStatusField();
}
};
var CombinedStopReload = {
init: function () {
if (this._initialized)
@ -6515,6 +6622,7 @@ var gPluginHandler = {
handleEvent : function(event) {
let self = gPluginHandler;
let plugin = event.target;
let hideBarPrefName;
// We're expecting the target to be a plugin.
if (!(plugin instanceof Ci.nsIObjectLoadingContent))
@ -6534,7 +6642,7 @@ var gPluginHandler = {
/* FALLTHRU */
case "PluginBlocklisted":
case "PluginOutdated":
let hideBarPrefName = event.type == "PluginOutdated" ?
hideBarPrefName = event.type == "PluginOutdated" ?
"plugins.hide_infobar_for_outdated_plugin" :
"plugins.hide_infobar_for_missing_plugin";
if (gPrefService.getBoolPref(hideBarPrefName))
@ -6542,7 +6650,15 @@ var gPluginHandler = {
self.pluginUnavailable(plugin, event.type);
break;
#ifdef XP_MACOSX
case "npapi-carbon-event-model-failure":
hideBarPrefName = "plugins.hide_infobar_for_carbon_failure_plugin";
if (gPrefService.getBoolPref(hideBarPrefName))
return;
self.pluginUnavailable(plugin, event.type);
break;
#endif
case "PluginDisabled":
self.addLinkClickCallback(plugin, "managePlugins");
break;
@ -6600,8 +6716,7 @@ var gPluginHandler = {
openHelpLink("plugin-crashed", false);
},
// event listener for missing/blocklisted/outdated plugins.
// event listener for missing/blocklisted/outdated/carbonFailure plugins.
pluginUnavailable: function (plugin, eventType) {
let browser = gBrowser.getBrowserForDocument(plugin.ownerDocument
.defaultView.top.document);
@ -6646,6 +6761,23 @@ var gPluginHandler = {
}
}
#ifdef XP_MACOSX
function carbonFailurePluginsRestartBrowser()
{
// Notify all windows that an application quit has been requested.
let cancelQuit = Cc["@mozilla.org/supports-PRBool;1"].
createInstance(Ci.nsISupportsPRBool);
Services.obs.notifyObservers(cancelQuit, "quit-application-requested", null);
// Something aborted the quit process.
if (cancelQuit.data)
return;
let as = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
as.quit(Ci.nsIAppStartup.eRestarti386 | Ci.nsIAppStartup.eRestart | Ci.nsIAppStartup.eAttemptQuit);
}
#endif
let notifications = {
PluginBlocklisted : {
barID : "blocked-plugins",
@ -6685,9 +6817,36 @@ var gPluginHandler = {
popup : null,
callback : showPluginsMissing
}],
}
},
#ifdef XP_MACOSX
"npapi-carbon-event-model-failure" : {
barID : "carbon-failure-plugins",
iconURL : "chrome://mozapps/skin/plugins/notifyPluginGeneric.png",
message : gNavigatorBundle.getString("carbonFailurePluginsMessage.title"),
buttons: [{
label : gNavigatorBundle.getString("carbonFailurePluginsMessage.restartButton.label"),
accessKey : gNavigatorBundle.getString("carbonFailurePluginsMessage.restartButton.accesskey"),
popup : null,
callback : carbonFailurePluginsRestartBrowser
}],
}
#endif
};
#ifdef XP_MACOSX
if (eventType == "npapi-carbon-event-model-failure") {
let carbonFailureNotification =
notificationBox.getNotificationWithValue("carbon-failure-plugins");
if (carbonFailureNotification)
carbonFailureNotification.close();
let macutils = Cc["@mozilla.org/xpcom/mac-utils;1"].getService(Ci.nsIMacUtils);
// if this is not a Universal build, just follow PluginNotFound path
if (!macutils.isUniversalBinary)
eventType = "PluginNotFound";
}
#endif
if (eventType == "PluginBlocklisted") {
if (blockedNotification || missingNotification)
return;
@ -7130,7 +7289,7 @@ function undoCloseTab(aIndex) {
var ss = Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
if (ss.getClosedTabCount(window) > (aIndex || 0)) {
TabView.prepareUndoCloseTab();
TabView.prepareUndoCloseTab(blankTabToRemove);
tab = ss.undoCloseTab(window, aIndex || 0);
TabView.afterUndoCloseTab();
@ -8304,7 +8463,8 @@ var TabContextMenu = {
PlacesCommandHook.updateBookmarkAllTabsCommand();
// Hide "Move to Group" if it's a pinned tab.
document.getElementById("context_tabViewMenu").hidden = this.contextTab.pinned;
document.getElementById("context_tabViewMenu").hidden =
(this.contextTab.pinned || !TabView.firstRunExperienced);
}
};

Просмотреть файл

@ -125,7 +125,7 @@
<menu id="context_tabViewMenu" label="&moveToGroup.label;"
accesskey="&moveToGroup.accesskey;">
<menupopup id="context_tabViewMenuPopup"
onpopupshowing="if (event.target == this) TabView.updateContextMenu(TabContextMenu.contextTab, this);">
onpopupshowing="if (event.target == this) TabView.moveToGroupPopupShowing(event);">
<menuseparator id="context_tabViewNamedGroups" hidden="true"/>
<menuitem id="context_tabViewNewGroup" label="&moveToNewGroup.label;"
oncommand="TabView.moveTabTo(TabContextMenu.contextTab, null);"/>
@ -467,6 +467,8 @@
defaultmode="icons" mode="icons"
#ifdef WINCE
defaulticonsize="small" iconsize="small"
#else
iconsize="large"
#endif
tabsontop="true"
persist="tabsontop">
@ -1000,7 +1002,7 @@
<toolbarbutton id="addonbar-closebutton"
tooltiptext="&addonBarCloseButton.tooltip;"
oncommand="setToolbarVisibility(this.parentNode, false);"/>
<statusbar id="status-bar"/>
<statusbar id="status-bar" ordinal="1000"/>
</toolbar>
</vbox>

Просмотреть файл

@ -73,6 +73,7 @@ let Change = {
// load some other elements & info from the window
this._dialog = document.getElementById("change-dialog");
this._dialogType = window.arguments[0];
this._duringSetup = window.arguments[1];
this._status = document.getElementById("status");
this._statusIcon = document.getElementById("statusIcon");
this._statusRow = document.getElementById("statusRow");
@ -115,6 +116,9 @@ let Change = {
warningText.textContent = this._str("change.synckey2.warningText");
this._dialog.getButton("finish").label
= this._str("change.synckey.acceptButton");
if (this._duringSetup) {
this._dialog.getButton("finish").disabled = false;
}
}
break;
case "ChangePassword":

Просмотреть файл

@ -23,6 +23,7 @@
* Mike Connor <mconnor@mozilla.com>
* Philipp von Weitershausen <philipp@weitershausen.de>
* Paul OShannessy <paul@oshannessy.com>
* Richard Newman <rnewman@mozilla.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
@ -144,9 +145,42 @@ var gSyncSetup = {
this.wizard.pageIndex = EXISTING_ACCOUNT_CONNECT_PAGE;
},
resetPassphrase: function resetPassphrase() {
// Apply the existing form fields so that
// Weave.Service.changePassphrase() has the necessary credentials.
Weave.Service.account = document.getElementById("existingAccountName").value;
Weave.Service.password = document.getElementById("existingPassword").value;
// Generate a new passphrase so that Weave.Service.login() will
// actually do something.
let passphrase = Weave.Utils.generatePassphrase();
Weave.Service.passphrase = passphrase;
// Only open the dialog if username + password are actually correct.
Weave.Service.login();
if ([Weave.LOGIN_FAILED_INVALID_PASSPHRASE,
Weave.LOGIN_FAILED_NO_PASSPHRASE,
Weave.LOGIN_SUCCEEDED].indexOf(Weave.Status.login) == -1) {
return;
}
// Hide any errors about the passphrase, we know it's not right.
let feedback = document.getElementById("existingPassphraseFeedbackRow");
feedback.hidden = true;
let el = document.getElementById("existingPassphrase");
el.value = Weave.Utils.hyphenatePassphrase(passphrase);
// changePassphrase() will sync, make sure we set the "firstSync" pref
// according to the user's pref.
Weave.Svc.Prefs.reset("firstSync");
this.setupInitialSync();
gSyncUtils.resetPassphrase(true);
},
onResetPassphrase: function () {
document.getElementById("existingPassphrase").value =
Weave.Utils.hyphenatePassphrase(Weave.Service.passphrase);
this.checkFields();
this.wizard.advance();
},
@ -248,7 +282,8 @@ var gSyncSetup = {
checkAccount: function() {
delete this._checkAccountTimer;
let value = document.getElementById("weaveEmail").value;
let value = Weave.Utils.normalizeAccount(
document.getElementById("weaveEmail").value);
if (!value) {
this.status.email = false;
this.checkFields();
@ -415,7 +450,8 @@ var gSyncSetup = {
feedback.hidden = false;
let password = document.getElementById("weavePassword").value;
let email = document.getElementById("weaveEmail").value;
let email = Weave.Utils.normalizeAccount(
document.getElementById("weaveEmail").value);
let challenge = getField("challenge");
let response = getField("response");
@ -440,7 +476,8 @@ var gSyncSetup = {
this.captchaBrowser.loadURI(Weave.Service.miscAPI + "captcha_html");
break;
case EXISTING_ACCOUNT_LOGIN_PAGE:
Weave.Service.account = document.getElementById("existingAccountName").value;
Weave.Service.account = Weave.Utils.normalizeAccount(
document.getElementById("existingAccountName").value);
Weave.Service.password = document.getElementById("existingPassword").value;
let pp = document.getElementById("existingPassphrase").value;
Weave.Service.passphrase = Weave.Utils.normalizePassphrase(pp);
@ -901,7 +938,6 @@ var gSyncSetup = {
this._setFeedback(element, success, str);
},
onStateChange: function(webProgress, request, stateFlags, status) {
// We're only looking for the end of the frame load
if ((stateFlags & Ci.nsIWebProgressListener.STATE_STOP) == 0)

Просмотреть файл

@ -375,7 +375,7 @@
</label>
<spacer id="passphraseHelpSpacer"/>
<label class="text-link"
onclick="gSyncUtils.resetPassphrase(); return false;">
onclick="gSyncSetup.resetPassphrase(); return false;">
&resetSyncKey.label;
</label>
</description>

Просмотреть файл

@ -67,7 +67,7 @@ let gSyncUtils = {
input.value = Weave.Clients.localName;
},
openChange: function openChange(type) {
openChange: function openChange(type, duringSetup) {
// Just re-show the dialog if it's already open
let openedDialog = Weave.Svc.WinMediator.getMostRecentWindow("Sync:" + type);
if (openedDialog != null) {
@ -78,7 +78,8 @@ let gSyncUtils = {
// Open up the change dialog
let changeXUL = "chrome://browser/content/syncGenericChange.xul";
let changeOpt = "centerscreen,chrome,resizable=no";
Weave.Svc.WinWatcher.activeWindow.openDialog(changeXUL, "", changeOpt, type);
Weave.Svc.WinWatcher.activeWindow.openDialog(changeXUL, "", changeOpt,
type, duringSetup);
},
changePassword: function () {
@ -86,9 +87,9 @@ let gSyncUtils = {
this.openChange("ChangePassword");
},
resetPassphrase: function () {
resetPassphrase: function (duringSetup) {
if (Weave.Utils.ensureMPUnlocked())
this.openChange("ResetPassphrase");
this.openChange("ResetPassphrase", duringSetup);
},
updatePassphrase: function () {

Просмотреть файл

@ -2622,7 +2622,7 @@
</resources>
<content>
<xul:hbox align="start">
<xul:hbox align="end">
<xul:image class="tab-drop-indicator" anonid="tab-drop-indicator" collapsed="true"/>
</xul:hbox>
<xul:arrowscrollbox anonid="arrowscrollbox" orient="horizontal" flex="1"
@ -3221,7 +3221,6 @@
ind.style.MozTransform = "translate(" + Math.round(newMargin) + "px)";
ind.style.MozMarginStart = (-ind.clientWidth) + "px";
ind.style.marginTop = (-ind.clientHeight) + "px";
]]></handler>
<handler event="drop"><![CDATA[
@ -3707,8 +3706,12 @@
<implementation>
<property name="label">
<setter>
if (!this.label)
if (!this.label) {
this.removeAttribute("mirror");
this.style.minWidth = "";
} else {
this.style.minWidth = getComputedStyle(this).width;
}
this.setAttribute("label", val);
return val;
</setter>
@ -3716,15 +3719,20 @@
return this.getAttribute("label");
</getter>
</property>
<method name="_mirror">
<body>
if (this.hasAttribute("mirror"))
this.removeAttribute("mirror");
else
this.setAttribute("mirror", "true");
</body>
</method>
</implementation>
<handlers>
<handler event="mouseover">
if (this.hasAttribute("mirror"))
this.removeAttribute("mirror");
else
this.setAttribute("mirror", "true");
</handler>
<handler event="mouseover" action="this._mirror();"/>
<handler event="dragover" action="this._mirror();"/>
</handlers>
</binding>

Просмотреть файл

@ -26,6 +26,7 @@
* Raymond Lee <raymond@appcoast.com>
* Tim Taubert <tim.taubert@gmx.de>
* Sean Dunn <seanedunn@yahoo.com>
* Mihai Sucan <mihai.sucan@gmail.com>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
@ -188,10 +189,17 @@ function GroupItem(listOfEls, options) {
this.$title
.blur(function() {
self._titleFocused = false;
self.$titleShield.show();
})
.focus(function() {
(self.$title)[0].select();
if (!self._titleFocused) {
(self.$title)[0].select();
self._titleFocused = true;
}
})
.mousedown(function(e) {
e.stopPropagation();
})
.keydown(handleKeyDown)
.keyup(handleKeyUp);
@ -219,9 +227,12 @@ function GroupItem(listOfEls, options) {
.hide();
// ___ app tabs: create app tab tray and populate it
let appTabTrayContainer = iQ("<div/>")
.addClass("appTabTrayContainer")
.appendTo($container);
this.$appTabTray = iQ("<div/>")
.addClass("appTabTray")
.appendTo($container);
.appendTo(appTabTrayContainer);
AllTabs.tabs.forEach(function(xulTab) {
if (xulTab.pinned && xulTab.ownerDocument.defaultView == gWindow)
@ -368,6 +379,74 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
this.$titleShield.css(css);
},
// ----------
// Function: adjustAppTabTray
// Used to adjust the appTabTray size, to split the appTabIcons across
// multiple columns when needed - if the groupItem size is too small.
//
// Parameters:
// arrangeGroup - rearrange the groupItem if the number of appTab columns
// changes. If true, then this.arrange() is called, otherwise not.
adjustAppTabTray: function GroupItem_adjustAppTabTray(arrangeGroup) {
let icons = iQ(".appTabIcon", this.$appTabTray);
let container = iQ(this.$appTabTray[0].parentNode);
if (!icons.length) {
// There are no icons, so hide the appTabTray if needed.
if (parseInt(container.css("width")) != 0) {
this.$appTabTray.css("-moz-column-count", 0);
this.$appTabTray.css("height", 0);
container.css("width", 0);
container.css("height", 0);
if (container.hasClass("appTabTrayContainerTruncated"))
container.removeClass("appTabTrayContainerTruncated");
if (arrangeGroup)
this.arrange();
}
return;
}
let iconBounds = iQ(icons[0]).bounds();
let boxBounds = this.getBounds();
let contentHeight = boxBounds.height -
parseInt(container.css("top")) -
this.$resizer.height();
let rows = Math.floor(contentHeight / iconBounds.height);
let columns = Math.ceil(icons.length / rows);
let columnsGap = parseInt(this.$appTabTray.css("-moz-column-gap"));
let iconWidth = iconBounds.width + columnsGap;
let maxColumns = Math.floor((boxBounds.width * 0.20) / iconWidth);
if (columns > maxColumns)
container.addClass("appTabTrayContainerTruncated");
else if (container.hasClass("appTabTrayContainerTruncated"))
container.removeClass("appTabTrayContainerTruncated");
// Need to drop the -moz- prefix when Gecko makes it obsolete.
// See bug 629452.
if (parseInt(this.$appTabTray.css("-moz-column-count")) != columns)
this.$appTabTray.css("-moz-column-count", columns);
if (parseInt(this.$appTabTray.css("height")) != contentHeight) {
this.$appTabTray.css("height", contentHeight + "px");
container.css("height", contentHeight + "px");
}
let fullTrayWidth = iconWidth * columns - columnsGap;
if (parseInt(this.$appTabTray.css("width")) != fullTrayWidth)
this.$appTabTray.css("width", fullTrayWidth + "px");
let trayWidth = iconWidth * Math.min(columns, maxColumns) - columnsGap;
if (parseInt(container.css("width")) != trayWidth) {
container.css("width", trayWidth + "px");
// Rearrange the groupItem if the width changed.
if (arrangeGroup)
this.arrange();
}
},
// ----------
// Function: getContentBounds
// Returns a <Rect> for the groupItem's content area (which doesn't include the title, etc).
@ -377,7 +456,11 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
box.top += titleHeight;
box.height -= titleHeight;
var appTabTrayWidth = this.$appTabTray.width();
let appTabTrayContainer = iQ(this.$appTabTray[0].parentNode);
var appTabTrayWidth = appTabTrayContainer.width();
if (appTabTrayWidth)
appTabTrayWidth += parseInt(appTabTrayContainer.css(UI.rtl ? "left" : "right"));
box.width -= appTabTrayWidth;
if (UI.rtl) {
box.left += appTabTrayWidth;
@ -446,6 +529,10 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
var offset = new Point(rect.left - this.bounds.left, rect.top - this.bounds.top);
this.bounds = new Rect(rect);
// Make sure the AppTab icons fit the new groupItem size.
if (css.width || css.height)
this.adjustAppTabTray();
// ___ Deal with children
if (css.width || css.height) {
this.arrange({animate: !immediately}); //(immediately ? 'sometimes' : true)});
@ -673,6 +760,22 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
group.newTab();
}
this.destroy();
},
// ----------
// Function: destroy
// Close all tabs linked to children (tabItems), removes all children and
// close the groupItem.
//
// Parameters:
// options - An object with optional settings for this call.
//
// Options:
// immediately - (bool) if true, no animation will be used
destroy: function GroupItem_destroy(options) {
let self = this;
// 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
@ -703,7 +806,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
this.$undoContainer.fadeOut(function() { self._unhide() });
} else {
this.close();
this.close(options);
}
},
@ -842,8 +945,10 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
$el = iQ(a);
item = Items.item($el);
}
Utils.assertThrow(!item.parent || item.parent == this,
"shouldn't already be in another groupItem");
// safeguard to remove the item from its previous group
if (item.parent && item.parent !== this)
item.parent.remove(item);
item.removeTrenches();
@ -961,6 +1066,11 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
if (typeof item.setResizable == 'function')
item.setResizable(true, options.immediately);
// if a blank tab is selected while restoring a tab the blank tab gets
// removed. we need to keep the group alive for the restored tab.
if (item.tab._tabViewTabIsRemovedAfterRestore)
options.dontClose = true;
let closed = options.dontClose ? false : this.closeIfEmpty();
if (closed)
this._makeClosestTabActive();
@ -1024,11 +1134,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
});
// adjust the tray
let columnWidth = $appTab.width();
if (parseInt(this.$appTabTray.css("width")) != columnWidth) {
this.$appTabTray.css({width: columnWidth});
this.arrange();
}
this.adjustAppTabTray(true);
},
// ----------
@ -1044,10 +1150,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
});
// adjust the tray
if (!iQ(".appTabIcon", this.$appTabTray).length) {
this.$appTabTray.css({width: 0});
this.arrange();
}
this.adjustAppTabTray(true);
xulTab.removeEventListener("error", this._onAppTabError, false);
},
@ -1450,6 +1553,13 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// Create new tab and zoom in on it after a double click
container.mousedown(function(e) {
if (!Utils.isLeftClick(e))
return;
// clicking in the title bar shouldn't create new tabs
if (self.$titlebar[0] == e.target || self.$titlebar.contains(e.target))
return;
if (Date.now() - self._lastClick <= UI.DBLCLICK_INTERVAL &&
(self._lastClickPositions.x - UI.DBLCLICK_OFFSET) <= e.clientX &&
(self._lastClickPositions.x + UI.DBLCLICK_OFFSET) >= e.clientX &&
@ -1525,12 +1635,6 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
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};
this.add(drag.info.$el, options);
@ -1892,7 +1996,6 @@ let GroupItems = {
// ----------
// Function: reconstitute
// Restores to stored state, creating groupItems as needed.
// If no data, sets up blank slate (including "new tabs" groupItem).
reconstitute: function GroupItems_reconstitute(groupItemsData, groupItemData) {
try {
let activeGroupId;
@ -1910,7 +2013,7 @@ let GroupItems = {
let data = groupItemData[id];
if (this.groupItemStorageSanity(data)) {
let groupItem = this.groupItem(data.id);
if (groupItem) {
if (groupItem && !groupItem.hidden) {
groupItem.userSize = data.userSize;
groupItem.setTitle(data.title);
groupItem.setBounds(data.bounds, true);
@ -1930,7 +2033,7 @@ let GroupItems = {
}
toClose.forEach(function(groupItem) {
groupItem.close({immediately: true});
groupItem.destroy({immediately: true});
});
}

Просмотреть файл

@ -21,6 +21,7 @@
* Ian Gilman <ian@iangilman.com>
* Aza Raskin <aza@mozilla.com>
* Michael Yoshitaka Erlewine <mitcho@mitcho.com>
* Tim Taubert <tim.taubert@gmx.de>
*
* This file incorporates work from:
* jQuery JavaScript Library v1.4.2: http://code.jquery.com/jquery-1.4.2.js
@ -293,6 +294,30 @@ iQClass.prototype = {
return iQ(ret);
},
// ----------
// Function: contains
// Check to see if a given DOM node descends from the receiver.
contains: function iQClass_contains(selector) {
Utils.assert(this.length == 1, 'does not yet support multi-objects (or null objects)');
// fast path when querySelector() can be used
if ('string' == typeof selector)
return null != this[0].querySelector(selector);
let object = iQ(selector);
Utils.assert(object.length <= 1, 'does not yet support multi-objects');
let elem = object[0];
if (!elem || !elem.parentNode)
return false;
do {
elem = elem.parentNode;
} while (elem && this[0] != elem);
return this[0] == elem;
},
// ----------
// Function: remove
// Removes the receiver from the DOM.

Просмотреть файл

@ -359,6 +359,8 @@ SearchEventHandlerClass.prototype = {
(event.keyCode >= event.DOM_VK_F1 &&
event.keyCode <= event.DOM_VK_SCROLL_LOCK) ||
event.keyCode == event.DOM_VK_META ||
event.keyCode == 91 || // 91 = left windows key
event.keyCode == 92 || // 92 = right windows key
(!event.keyCode && !event.charCode)) {
return;
}

Просмотреть файл

@ -706,6 +706,8 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// The scaleCheat of 2 here is a clever way to speed up the zoom-out
// code. See getZoomTransform() below.
let transform = this.getZoomTransform(2);
TabItems.pausePainting();
$canvas.css({
'-moz-transform': transform.transform,
'-moz-transform-origin': transform.transformOrigin
@ -808,7 +810,7 @@ let TabItems = {
// 150 pixels is an empirical size, below which FF's drawWindow()
// algorithm breaks down
this.tempCanvas.width = 150;
this.tempCanvas.height = 150;
this.tempCanvas.height = 112;
this.tabsProgressListener = {
onStateChange: function(browser, webProgress, request, stateFlags, status) {
@ -1103,6 +1105,7 @@ let TabItems = {
// three times before TabItems will start updating thumbnails again.
resumePainting: function TabItems_resumePainting() {
this.paintingPaused--;
Utils.assert(this.paintingPaused > -1, "paintingPaused should not go below zero");
if (!this.isPaintingPaused())
this.startHeartbeat();
},
@ -1281,69 +1284,97 @@ TabCanvas.prototype = {
if (!w || !h)
return;
let fromWin = this.tab.linkedBrowser.contentWindow;
if (fromWin == null) {
Utils.log('null fromWin in paint');
if (!this.tab.linkedBrowser.contentWindow) {
Utils.log('no tab.linkedBrowser.contentWindow in TabCanvas.paint()');
return;
}
let ctx = this.canvas.getContext("2d");
let tempCanvas = TabItems.tempCanvas;
let bgColor = '#fff';
if (w < tempCanvas.width) {
// Small draw case where nearest-neighbor algorithm breaks down in Windows
// First draw to a larger canvas (150px wide), and then draw that image
// to the destination canvas.
var tempCtx = tempCanvas.getContext("2d");
let canvW = tempCanvas.width;
let canvH = (h/w) * canvW;
var scaler = canvW/fromWin.innerWidth;
tempCtx.save();
tempCtx.clearRect(0,0,tempCanvas.width,tempCanvas.height);
tempCtx.scale(scaler, scaler);
try{
tempCtx.drawWindow(fromWin, fromWin.scrollX, fromWin.scrollY,
canvW/scaler, canvH/scaler, "#fff");
} catch(e) {
let tempCtx = tempCanvas.getContext("2d");
this._drawWindow(tempCtx, tempCanvas.width, tempCanvas.height, bgColor);
// Now copy to tabitem canvas.
try {
this._fillCanvasBackground(ctx, w, h, bgColor);
ctx.drawImage(tempCanvas, 0, 0, w, h);
} catch (e) {
Utils.error('paint', e);
}
tempCtx.restore();
// Now copy to tabitem canvas. No save/restore necessary.
var destCtx = this.canvas.getContext("2d");
try{
// the tempcanvas is square, so draw it as a square.
destCtx.drawImage(tempCanvas, 0, 0, w, w);
} catch(e) {
Utils.error('paint', e);
}
}
} else {
// General case where nearest neighbor algorithm looks good
// Draw directly to the destination canvas
var ctx = this.canvas.getContext("2d");
var scaler = w/fromWin.innerWidth;
// TODO: Potentially only redraw the dirty rect? (Is it worth it?)
ctx.save();
ctx.scale(scaler, scaler);
try{
ctx.drawWindow(fromWin, fromWin.scrollX, fromWin.scrollY,
w/scaler, h/scaler, "#fff",
Ci.nsIDOMCanvasRenderingContext2D.DRAWWINDOW_DO_NOT_FLUSH);
} catch(e) {
Utils.error('paint', e);
}
ctx.restore();
this._drawWindow(ctx, w, h, bgColor);
}
},
// ----------
// Function: _fillCanvasBackground
// Draws a rectangle of <width>x<height> with color <bgColor> to the given
// canvas context.
_fillCanvasBackground: function TabCanvas__fillCanvasBackground(ctx, width, height, bgColor) {
ctx.fillStyle = bgColor;
ctx.fillRect(0, 0, width, height);
},
// ----------
// Function: _drawWindow
// Draws contents of the tabs' browser window to the given canvas context.
_drawWindow: function TabCanvas__drawWindow(ctx, width, height, bgColor) {
this._fillCanvasBackground(ctx, width, height, bgColor);
let rect = this._calculateClippingRect(width, height);
let scaler = width / rect.width;
ctx.save();
ctx.scale(scaler, scaler);
try {
let win = this.tab.linkedBrowser.contentWindow;
ctx.drawWindow(win, rect.left, rect.top, rect.width, rect.height,
bgColor, ctx.DRAWWINDOW_DO_NOT_FLUSH);
} catch (e) {
Utils.error('paint', e);
}
ctx.restore();
},
// ----------
// Function: _calculateClippingRect
// Calculate the clipping rect that will be projected to the tab's
// thumbnail canvas.
_calculateClippingRect: function TabCanvas__calculateClippingRect(origWidth, origHeight) {
let win = this.tab.linkedBrowser.contentWindow;
// TODO BUG 631593: retrieve actual scrollbar width
// 25px is supposed to be width of the vertical scrollbar
let maxWidth = win.innerWidth - 25;
let maxHeight = win.innerHeight;
let height = Math.min(maxHeight, Math.floor(origHeight * maxWidth / origWidth));
let width = Math.floor(origWidth * height / origHeight);
// very short pages in combination with a very wide browser window force us
// to extend the clipping rect and add some empty space around the thumb
let factor = 0.7;
if (width < maxWidth * factor) {
width = maxWidth * factor;
height = Math.floor(origHeight * width / origWidth);
}
let left = win.scrollX + Math.max(0, Math.round((maxWidth - width) / 2));
let top = win.scrollY;
return new Rect(left, top, width, height);
},
// ----------
// Function: toImageData
toImageData: function TabCanvas_toImageData() {

Просмотреть файл

@ -101,7 +101,7 @@ body {
position: absolute;
}
.appTabTray {
.appTabTrayContainer {
position: absolute;
}

Просмотреть файл

@ -418,7 +418,7 @@ let UI = {
let self = this;
this._activeTab.addSubscriber(this, "close", function(closedTabItem) {
if (self._activeTab == closedTabItem)
self._activeTab = null;
self.setActiveTab(null);
});
this._activeTab.makeActive();
@ -731,14 +731,21 @@ let UI = {
let closingLastOfGroup = (groupItem &&
groupItem._children.length == 1 &&
groupItem._children[0].tab == tab);
// 2) Take care of the case where you've closed the last tab in
// an un-named groupItem, which means that the groupItem is gone (null) and
// there are no visible tabs.
let closingUnnamedGroup = (groupItem == null &&
gBrowser.visibleTabs.length <= 1);
if (closingLastOfGroup || closingUnnamedGroup) {
// 3) When a blank tab is active while restoring a closed tab the
// blank tab gets removed. The active group is not closed as this is
// where the restored tab goes. So do not show the TabView.
let closingBlankTabAfterRestore =
(tab && tab._tabViewTabIsRemovedAfterRestore);
if ((closingLastOfGroup || closingUnnamedGroup) &&
!closingBlankTabAfterRestore) {
// for the tab focus event to pick up.
self._closedLastVisibleTab = true;
self.showTabView();
@ -781,6 +788,10 @@ let UI = {
TabItems.handleTabUnpin(tab);
GroupItems.removeAppTab(tab);
let groupItem = tab._tabViewTabItem.parent;
if (groupItem)
self.setReorderTabItemsOnShow(groupItem);
};
// Actually register the above handlers

Просмотреть файл

@ -232,7 +232,6 @@ _BROWSER_FILES = \
browser_tabMatchesInAwesomebar.js \
file_bug550565_popup.html \
file_bug550565_favicon.ico \
browser_overLinkInLocationBar.js \
browser_aboutHome.js \
app_bug575561.html \
app_subframe_bug575561.html \
@ -252,6 +251,10 @@ else
_BROWSER_FILES += \
browser_customize.js \
$(NULL)
# TODO: Activate after carbon test plugin lands, bug 628651
# browser_maconly_carbon_mismatch_plugin.js \
endif
ifneq (gtk2,$(MOZ_WIDGET_TOOLKIT))

Просмотреть файл

@ -53,7 +53,7 @@ function test1() {
checkPopupHide();
// Clean-up
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
gBrowser.removeTab(gBrowser.selectedTab);
// Next test
executeSoon(test2);
@ -84,7 +84,7 @@ function test2()
checkPopupMessage(doc);
// Clean-up and next test.
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
gBrowser.removeTab(gBrowser.selectedTab);
executeSoon(test3);
}, false);
@ -118,7 +118,7 @@ function test3()
checkPopupMessage(doc);
// Clean-up and next test.
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
gBrowser.removeTab(gBrowser.selectedTab);
executeSoon(test4a);
}, false);
@ -157,7 +157,7 @@ function test4a()
checkPopupHide();
// Clean-up and next test.
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
gBrowser.removeTab(gBrowser.selectedTab);
executeSoon(test4b);
});
}, false);
@ -197,7 +197,7 @@ function test4b()
checkPopupShow();
// Clean-up and next test.
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
gBrowser.removeTab(gBrowser.selectedTab);
executeSoon(test5);
});
}, false);
@ -237,7 +237,7 @@ function test5()
checkPopupHide();
// Clean-up and next test.
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
gBrowser.removeTab(gBrowser.selectedTab);
executeSoon(test6);
});
}, false);
@ -276,7 +276,7 @@ function test6()
checkPopupHide();
// Clean-up and next test.
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
gBrowser.removeTab(gBrowser.selectedTab);
executeSoon(test7);
});
}, false);
@ -316,8 +316,8 @@ function test7()
checkPopupHide();
// Clean-up and next test.
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
gBrowser.removeTab(gBrowser.selectedTab);
gBrowser.removeTab(gBrowser.selectedTab);
executeSoon(test8);
});
}, false);
@ -353,7 +353,7 @@ function test8()
// Clean-up
Services.obs.removeObserver(gObserver, "invalidformsubmit");
gObserver.notifyInvalidSubmit = function () {};
gBrowser.removeTab(tab, {animate: false});
gBrowser.removeTab(tab);
// Next test
executeSoon(test9);
@ -395,8 +395,56 @@ function test9()
"The panel should show the author defined error message");
// Clean-up and next test.
gBrowser.removeTab(gBrowser.selectedTab, {animate: false});
executeSoon(finish);
gBrowser.removeTab(gBrowser.selectedTab);
executeSoon(test10);
}, false);
tab.linkedBrowser.addEventListener("load", function(aEvent) {
tab.linkedBrowser.removeEventListener("load", arguments.callee, true);
gBrowser.contentDocument.getElementById('s').click();
}, true);
gBrowser.selectedTab = tab;
gBrowser.selectedTab.linkedBrowser.loadURI(uri);
}
/**
* In this test, we check that the message is correctly updated when it changes.
*/
function test10()
{
let uri = "data:text/html,<iframe name='t'></iframe><form target='t' action='data:text/html,'><input type='email' required id='i'><input id='s' type='submit'></form>";
let tab = gBrowser.addTab();
gInvalidFormPopup.addEventListener("popupshown", function() {
gInvalidFormPopup.removeEventListener("popupshown", arguments.callee, false);
let doc = gBrowser.contentDocument;
let input = doc.getElementById('i');
is(doc.activeElement, input, "First invalid element should be focused");
checkPopupShow();
is(gInvalidFormPopup.firstChild.textContent, input.validationMessage,
"The panel should show the current validation message");
input.addEventListener('input', function() {
input.removeEventListener('input', arguments.callee, false);
executeSoon(function() {
// Now, the element suffers from another error, the message should have
// been updated.
is(gInvalidFormPopup.firstChild.textContent, input.validationMessage,
"The panel should show the current validation message");
// Clean-up and next test.
gBrowser.removeTab(gBrowser.selectedTab);
executeSoon(finish);
});
}, false);
EventUtils.synthesizeKey('f', {});
}, false);
tab.linkedBrowser.addEventListener("load", function(aEvent) {

Просмотреть файл

@ -0,0 +1,54 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
let tab, browser;
function tearDown()
{
while (gBrowser.tabs.length > 1) {
gBrowser.removeCurrentTab();
}
}
registerCleanupFunction(tearDown);
function addTab(aURL)
{
gBrowser.selectedTab = gBrowser.addTab();
content.location = aURL;
tab = gBrowser.selectedTab;
browser = gBrowser.getBrowserForTab(tab);
}
function onLoad() {
executeSoon(function (){
browser.removeEventListener("npapi-carbon-event-model-failure",
arguments.callee, false);
let notificationBox = gBrowser.getNotificationBox();
let notificationBar = notificationBox.getNotificationWithValue("carbon-failure-plugins");
ok(notificationBar, "Carbon Error plugin notification bar was found");
finish();
});
}
function test() {
try {
let abi = Services.appinfo.XPCOMABI;
if (!abi.match(/64/)) {
todo(false, "canceling test, wrong platform");
return;
}
let macutils = Cc["@mozilla.org/xpcom/mac-utils;1"].getService(Ci.nsIMacUtils);
if (!macutils.isUniversalBinary) {
todo(false, "canceling test, not a universal build")
return;
}
}
catch (e) {
return;
}
waitForExplicitFinish();
addTab('data:text/html,<h1>Plugin carbon mismatch test</h1><embed id="test" style="width: 100px; height: 100px" type="application/x-test-carbon">');
gBrowser.addEventListener("npapi-carbon-event-model-failure", onLoad, false);
}

Просмотреть файл

@ -1,264 +0,0 @@
/* ***** 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 browser test code.
*
* The Initial Developer of the Original Code is
* the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Drew Willcoxon <adw@mozilla.com> (Original Author)
*
* 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 the "over-link" that appears in the location bar when the user
* mouses over a link. See bug 587908.
*/
var gTestIter;
// TESTS //////////////////////////////////////////////////////////////////////
let gTests = [
function smokeTestGenerator() {
// Make sure the location bar is not focused.
gBrowser.contentWindow.focus();
if (ensureOverLinkHidden())
yield;
setOverLinkWait("http://example.com/");
yield;
checkURLBar(true);
setOverLinkWait("");
yield;
checkURLBar(false);
},
function hostPathLabels() {
updateOverLink("http://example.com/");
hostLabelIs("http://example.com/");
pathLabelIs("");
updateOverLink("http://example.com/foo");
hostLabelIs("http://example.com/");
pathLabelIs("foo");
updateOverLink("javascript:popup('http://example.com/')");
hostLabelIs("");
pathLabelIs("javascript:popup('http://example.com/')");
updateOverLink("javascript:popup('http://example.com/foo')");
hostLabelIs("");
pathLabelIs("javascript:popup('http://example.com/foo')");
updateOverLink("about:home");
hostLabelIs("");
pathLabelIs("about:home");
}
];
function test() {
waitForExplicitFinish();
runNextTest();
}
function runNextTest() {
let nextTest = gTests.shift();
if (nextTest) {
dump("Running next test: " + nextTest.name + "\n");
gTestIter = nextTest();
// If the test is a generator, advance it. Otherwise, we just ran the test.
if (gTestIter)
cont();
else
runNextTest();
}
else
finish();
}
// HELPERS ////////////////////////////////////////////////////////////////////
/**
* Advances the test iterator. When all iterations have completed, the entire
* suite is finish()ed.
*/
function cont() {
try {
gTestIter.next();
}
catch (err if err instanceof StopIteration) {
runNextTest();
}
catch (err) {
// Depending on who calls us, sometimes exceptions are eaten by event
// handlers... Make sure we fail.
ok(false, "Exception: " + err);
throw err;
}
}
/**
* Asserts that the location bar looks like it should.
*
* @param shouldShowOverLink
* True if you expect the over-link to be showing and false otherwise.
*/
function checkURLBar(shouldShowOverLink) {
let overLink = window.getComputedStyle(gURLBar._overLinkBox, null);
let origin = window.getComputedStyle(gURLBar._originLabel, null);
let editLayer = window.getComputedStyle(gURLBar._textboxContainer, null);
if (shouldShowOverLink) {
isnot(origin.color, "transparent",
"Origin color in over-link layer should not be transparent");
is(overLink.opacity, 1, "Over-link should be opaque");
is(editLayer.color, "transparent",
"Edit layer color should be transparent");
}
else {
is(origin.color, "transparent",
"Origin color in over-link layer should be transparent");
is(overLink.opacity, 0, "Over-link should be transparent");
isnot(editLayer.color, "transparent",
"Edit layer color should not be transparent");
}
}
/**
* Sets the over-link. This assumes that str will cause the over-link to fade
* in or out. When its transition has finished, the test iterator is
* incremented, so you should yield after calling.
*
* @param str
* The over-link will be set to this string or cleared if this is falsey.
*/
function setOverLinkWait(str) {
dump("Setting over-link and waiting: " + str + "\n");
let overLink = gURLBar._overLinkBox;
let opacity = window.getComputedStyle(overLink, null).opacity;
dump("Opacity is " + opacity + "\n");
ok(str || opacity != 0,
"Test assumption: either showing or if hiding, not already hidden");
ok(!str || opacity != 1,
"Test assumption: either hiding or if showing, not already shown");
overLink.addEventListener("transitionend", function onTrans(event) {
dump("transitionend received: " + (event.target == overLink) + " " +
event.propertyName + "\n");
if (event.target == overLink && event.propertyName == "opacity") {
dump("target transitionend received\n");
overLink.removeEventListener("transitionend", onTrans, false);
cont();
}
}, false);
gURLBar.setOverLink(str);
}
/**
* Sets the over-link but unlike setOverLinkWait does not assume that a
* transition will occur and therefore does not wait.
*
* @param str
* The over-link will be set to this string or cleared if this is falsey.
*/
function setOverLink(str) {
dump("Setting over-link but not waiting: " + str + "\n");
let overLink = gURLBar._overLinkBox;
let opacity = window.getComputedStyle(overLink, null).opacity;
dump("Opacity is " + opacity + "\n");
ok(str || opacity == 0,
"Test assumption: either showing or if hiding, already hidden");
ok(!str || opacity == 1,
"Test assumption: either hiding or if showing, already shown");
gURLBar.setOverLink(str);
}
/**
* Calls gURLBar._updateOverLink(str), which updates the over-link but does not
* change its visibility.
*
* @param str
* The over-link will be set to this string. Note that setting this to
* falsey doesn't make sense for this function.
*/
function updateOverLink(str) {
gURLBar._updateOverLink(str);
}
/**
* If the over-link is hidden, returns false. Otherwise, hides the overlink and
* returns true. When the overlink is hidden, the test iterator is incremented,
* so if this function returns true, you should yield after calling.
*
* @return True if you should yield and calling and false if not.
*/
function ensureOverLinkHidden() {
dump("Ensuring over-link is hidden" + "\n");
let overLink = gURLBar._overLinkBox;
let opacity = window.getComputedStyle(overLink, null).opacity;
dump("Opacity is " + opacity + "\n");
if (opacity == 0)
return false;
setOverLinkWait("");
return true;
}
/**
* Asserts that the over-link host label is a given string.
*
* @param str
* The host label should be this string.
*/
function hostLabelIs(str) {
let host = gURLBar._overLinkHostLabel;
is(host.value, str, "Over-link host label should be correct");
}
/**
* Asserts that the over-link path label is a given string.
*
* @param str
* The path label should be this string.
*/
function pathLabelIs(str) {
let path = gURLBar._overLinkPathLabel;
is(path.value, str, "Over-link path label should be correct");
}

Просмотреть файл

@ -57,6 +57,7 @@ _BROWSER_FILES = \
browser_tabview_bug589324.js \
browser_tabview_bug590606.js \
browser_tabview_bug591706.js \
browser_tabview_bug594958.js \
browser_tabview_bug595191.js \
browser_tabview_bug595436.js \
browser_tabview_bug595518.js \
@ -65,6 +66,7 @@ _BROWSER_FILES = \
browser_tabview_bug595804.js \
browser_tabview_bug595930.js \
browser_tabview_bug595943.js \
browser_tabview_bug595965.js \
browser_tabview_bug596781.js \
browser_tabview_bug597248.js \
browser_tabview_bug597360.js \
@ -79,11 +81,13 @@ _BROWSER_FILES = \
browser_tabview_bug608037.js \
browser_tabview_bug608184.js \
browser_tabview_bug608158.js \
browser_tabview_bug608405.js \
browser_tabview_bug610242.js \
browser_tabview_bug612470.js \
browser_tabview_bug613541.js \
browser_tabview_bug616729.js \
browser_tabview_bug616967.js \
browser_tabview_bug618816.js \
browser_tabview_bug618828.js \
browser_tabview_bug619937.js \
browser_tabview_bug622835.js \
@ -91,13 +95,20 @@ _BROWSER_FILES = \
browser_tabview_bug624265.js \
browser_tabview_bug624931.js \
browser_tabview_bug624727.js \
browser_tabview_bug624847.js \
browser_tabview_bug624953.js \
browser_tabview_bug625269.js \
browser_tabview_bug625424.js \
browser_tabview_bug626368.js \
browser_tabview_bug626525.js \
browser_tabview_bug627288.js \
browser_tabview_bug627736.js \
browser_tabview_bug628165.js \
browser_tabview_bug628270.js \
browser_tabview_bug629195.js \
browser_tabview_bug630102.js \
browser_tabview_bug630157.js \
browser_tabview_bug631662.js \
browser_tabview_dragdrop.js \
browser_tabview_exit_button.js \
browser_tabview_expander.js \

Просмотреть файл

@ -0,0 +1,149 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
let win;
let cw;
let getGroupItem = function (index) {
return cw.GroupItems.groupItems[index];
}
let newWindow = function (callback) {
newWindowWithTabView(function (tvwin) {
registerCleanupFunction(function () {
if (!tvwin.closed)
tvwin.close();
});
win = tvwin;
cw = win.TabView.getContentWindow();
callback();
});
}
let finishTest = function () {
win.close();
finish();
}
// very long page that produces black bars at the right
let html1 = '<html><body style="background-color: #00f;">' +
'<div style="background: #fff; width: 95%; height: 10000px; ' +
' margin: 0 auto;"></div></body></html>';
// very short page that produces black bars at the bottom
let html2 = '<html><body style="background-color: #00f;"></body></html>';
let tests = [{
url: 'data:text/html,' + html1,
colors: [
{right: [255, 255, 255], bottom: [255, 255, 255]},
{right: [255, 255, 255], bottom: [255, 255, 255]},
{right: [255, 255, 255], bottom: [255, 255, 255]}
]
}, {
url: 'about:blank',
colors: [
{right: [255, 255, 255], bottom: [255, 255, 255]},
{right: [255, 255, 255], bottom: [255, 255, 255]},
{right: [255, 255, 255], bottom: [255, 255, 255]}
]
}, {
url: 'data:text/html,' + html2,
colors: [
{right: [0, 0, 255], bottom: [0, 0, 255]},
{right: [0, 0, 255], bottom: [0, 0, 255]},
{right: [0, 0, 255], bottom: [0, 0, 255]}
]
}];
let next = function () {
if (!tests.length) {
finishTest();
return;
}
let test = tests.shift();
let tab = win.gBrowser.tabs[0];
tab.linkedBrowser.addEventListener('load', function onLoad() {
tab.linkedBrowser.removeEventListener('load', onLoad, true);
checkUrl(test);
}, true);
tab.linkedBrowser.loadURI(test.url);
}
let checkUrl = function (test) {
let sizes = [[-400, 0], [800, -200], [-400, 200]];
let nextSize = function () {
if (!sizes.length) {
next();
return;
}
let size = sizes.shift();
let colors = test.colors.shift();
let groupItem = getGroupItem(0);
let checkWithSmallItemSize = function () {
groupItem.setSize(150, 150, true);
groupItem.setUserSize();
afterAllTabItemsUpdated(function () {
checkPixelColors(test.url, colors, nextSize);
}, win);
}
let checkWithNormalItemSize = function () {
groupItem.setSize(300, 300, true);
groupItem.setUserSize();
afterAllTabItemsUpdated(function () {
checkPixelColors(test.url, colors, checkWithSmallItemSize);
}, win);
}
win.resizeBy.apply(win, size);
checkWithNormalItemSize();
}
nextSize();
}
let checkPixelColors = function (url, colors, callback) {
let tab = win.gBrowser.tabs[0];
let $canvas = tab._tabViewTabItem.$canvas;
let width = $canvas.width();
let height = $canvas.height();
let ctx = $canvas[0].getContext("2d");
afterAllTabItemsUpdated(function () {
checkPixelColor(ctx, url, colors.bottom, Math.floor(width / 4), height - 1, 'bottom');
checkPixelColor(ctx, url, colors.right, width - 1, Math.floor(height / 4), 'right');
callback();
}, win);
}
let checkPixelColor = function (ctx, url, color, x, y, edge) {
let data = ctx.getImageData(x, y, 1, 1).data;
let check = (data[0] == color[0] && data[1] == color[1] && data[2] == color[2]);
ok(check, url + ': ' + edge + ' edge color matches pixel value');
}
waitForExplicitFinish();
newWindow(next);
}
// ---------
function newWindowWithTabView(callback) {
let win = window.openDialog(getBrowserURL(), "_blank",
"chrome,all,dialog=no,height=600,width=800");
win.addEventListener("load", function onLoad() {
win.removeEventListener("load", onLoad, false);
showTabView(function () callback(win), win);
}, false);
}

Просмотреть файл

@ -0,0 +1,138 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*
* Contributor(s):
* Mihai Sucan <mihai.sucan@gmail.com>
* Raymond Lee <raymond@appcoast.com>
* Ian Gilman <ian@iangilman.com>
*/
function test() {
waitForExplicitFinish();
newWindowWithTabView(onTabViewShown);
}
function onTabViewShown(win) {
let TabView = win.TabView;
let gBrowser = win.gBrowser;
let document = win.document;
ok(TabView.isVisible(), "Tab View is visible");
let contentWindow = document.getElementById("tab-view").contentWindow;
let iQ = contentWindow.iQ;
// establish initial state
is(contentWindow.GroupItems.groupItems.length, 1,
"we start with one group (the default)");
is(gBrowser.tabs.length, 1, "we start with one tab");
let originalTab = gBrowser.tabs[0];
// create a group
let box = new contentWindow.Rect(20, 20, 210, 200);
let groupItem = new contentWindow.GroupItem([],
{ bounds: box, title: "test1" });
is(contentWindow.GroupItems.groupItems.length, 2, "we now have two groups");
contentWindow.GroupItems.setActiveGroupItem(groupItem);
// create a tab
let xulTabs = [];
xulTabs.push(gBrowser.loadOneTab("about:blank"));
is(gBrowser.tabs.length, 2, "we now have two tabs");
is(groupItem._children.length, 1, "the new tab was added to the group");
// make sure the group has no app tabs
is(appTabCount(groupItem), 0, "there are no app tab icons");
let tray = groupItem.$appTabTray;
let trayContainer = iQ(tray[0].parentNode);
is(parseInt(trayContainer.css("width")), 0,
"$appTabTray container is not visible");
// pin the tab, make sure the TabItem goes away and the icon comes on
gBrowser.pinTab(xulTabs[0]);
is(groupItem._children.length, 0,
"the app tab's TabItem was removed from the group");
is(appTabCount(groupItem), 1, "there's now one app tab icon");
is(tray.css("-moz-column-count"), 1,
"$appTabTray column count is 1");
isnot(parseInt(trayContainer.css("width")), 0,
"$appTabTray container is visible");
let iconHeight = iQ(iQ(".appTabIcon", tray)[0]).height();
let trayHeight = parseInt(trayContainer.css("height"));
let rows = Math.floor(trayHeight / iconHeight);
let icons = rows * 2;
// add enough tabs to have two columns
for (let i = 1; i < icons; i++) {
xulTabs.push(gBrowser.loadOneTab("about:blank"));
gBrowser.pinTab(xulTabs[i]);
}
is(appTabCount(groupItem), icons, "number of app tab icons is correct");
is(tray.css("-moz-column-count"), 2,
"$appTabTray column count is 2");
ok(!trayContainer.hasClass("appTabTrayContainerTruncated"),
"$appTabTray container does not have .appTabTrayContainerTruncated");
// add one more tab
xulTabs.push(gBrowser.loadOneTab("about:blank"));
gBrowser.pinTab(xulTabs[xulTabs.length-1]);
is(tray.css("-moz-column-count"), 3,
"$appTabTray column count is 3");
ok(trayContainer.hasClass("appTabTrayContainerTruncated"),
"$appTabTray container hasClass .appTabTrayContainerTruncated");
// remove all but one app tabs
for (let i = 1; i < xulTabs.length; i++)
gBrowser.removeTab(xulTabs[i]);
is(tray.css("-moz-column-count"), 1,
"$appTabTray column count is 1");
is(appTabCount(groupItem), 1, "there's now one app tab icon");
ok(!trayContainer.hasClass("appTabTrayContainerTruncated"),
"$appTabTray container does not have .appTabTrayContainerTruncated");
// unpin the last remaining tab
gBrowser.unpinTab(xulTabs[0]);
is(parseInt(trayContainer.css("width")), 0,
"$appTabTray container is not visible");
is(appTabCount(groupItem), 0, "there are no app tab icons");
is(groupItem._children.length, 1, "the normal tab shows in the group");
gBrowser.removeTab(xulTabs[0]);
// close the group
groupItem.close();
hideTabView(function() {
ok(!TabView.isVisible(), "Tab View is hidden");
is(contentWindow.GroupItems.groupItems.length, 1,
"we finish with one group");
is(gBrowser.tabs.length, 1, "we finish with one tab");
win.close();
executeSoon(finish);
}, win);
}
function appTabCount(groupItem) {
return groupItem.container.getElementsByClassName("appTabIcon").length;
}

Просмотреть файл

@ -0,0 +1,54 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
let cw;
let createGroupItem = function () {
let bounds = new cw.Rect(20, 20, 200, 200);
let groupItem = new cw.GroupItem([], {bounds: bounds, immediately: true});
cw.GroupItems.setActiveGroupItem(groupItem);
gBrowser.loadOneTab('about:blank', {inBackground: true});
return groupItem;
}
let finishTest = function () {
ok(!TabView.isVisible(), 'cleanup: tabview is hidden');
is(gBrowser.tabs.length, 1, 'cleanup: there is one tab, only');
is(cw.GroupItems.groupItems.length, 1, 'cleanup: there is one group, only');
finish();
}
let testAddChildFromAnotherGroup = function () {
let sourceGroup = cw.GroupItems.groupItems[0];
let targetGroup = createGroupItem();
afterAllTabsLoaded(function () {
// check setup
is(sourceGroup.getChildren().length, 1, 'setup: source group has one child');
is(targetGroup.getChildren().length, 1, 'setup: target group has one child');
let tabItem = sourceGroup.getChild(0);
targetGroup.add(tabItem);
// check state after adding tabItem to targetGroup
is(tabItem.parent, targetGroup, 'tabItem changed groups');
is(cw.GroupItems.groupItems.length, 1, 'source group was closed automatically');
is(targetGroup.getChildren().length, 2, 'target group has now two children');
// cleanup and finish
tabItem.close();
hideTabView(finishTest);
});
}
waitForExplicitFinish();
showTabView(function () {
cw = TabView.getContentWindow();
testAddChildFromAnotherGroup();
});
}

Просмотреть файл

@ -0,0 +1,47 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
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});
let groupItemId = groupItem.id;
registerCleanupFunction(function() {
let groupItem = cw.GroupItems.groupItem(groupItemId);
if (groupItem)
groupItem.close();
});
return groupItem;
}
let testFocusTitle = function () {
let title = 'title';
let groupItem = createGroupItem();
groupItem.setTitle(title);
let target = groupItem.$titleShield[0];
EventUtils.synthesizeMouseAtCenter(target, {}, cw);
let input = groupItem.$title[0];
is(input.selectionStart, 0, 'the whole text is selected');
is(input.selectionEnd, title.length, 'the whole text is selected');
EventUtils.synthesizeMouseAtCenter(input, {}, cw);
is(input.selectionStart, title.length, 'caret is at the rightmost position and no text is selected');
is(input.selectionEnd, title.length, 'caret is at the rightmost position and no text is selected');
groupItem.close();
hideTabView(finish);
}
waitForExplicitFinish();
showTabView(function () {
cw = TabView.getContentWindow();
testFocusTitle();
});
}

Просмотреть файл

@ -0,0 +1,127 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
let cw;
let groupItemId;
let prefix = 'start';
let assertTabViewIsHidden = function () {
ok(!TabView.isVisible(), prefix + ': tabview is hidden');
}
let assertNumberOfGroups = function (num) {
is(cw.GroupItems.groupItems.length, num, prefix + ': there should be ' + num + ' groups');
}
let assertNumberOfTabs = function (num) {
is(gBrowser.visibleTabs.length, num, prefix + ': there should be ' + num + ' tabs');
}
let assertNumberOfPinnedTabs = function (num) {
is(gBrowser._numPinnedTabs, num, prefix + ': there should be ' + num + ' pinned tabs');
}
let assertGroupItemPreserved = function () {
is(cw.GroupItems.groupItems[0].id, groupItemId, prefix + ': groupItem was preserved');
}
let assertValidPrerequisites = function () {
assertNumberOfTabs(1);
assertNumberOfGroups(1);
assertNumberOfPinnedTabs(0);
assertTabViewIsHidden();
}
let createTab = function (url) {
return gBrowser.loadOneTab(url || 'http://mochi.test:8888/', {inBackground: true});
}
let createBlankTab = function () {
return createTab('about:blank');
}
let restoreTab = function (callback) {
let tab = undoCloseTab(0);
if (tab._tabViewTabItem._reconnected) {
afterAllTabsLoaded(callback);
return;
}
tab._tabViewTabItem.addSubscriber(tab, 'reconnected', function () {
tab._tabViewTabItem.removeSubscriber(tab, 'reconnected');
afterAllTabsLoaded(callback);
});
}
let finishTest = function () {
prefix = 'finish';
assertValidPrerequisites();
finish();
}
let testUndoCloseWithSelectedBlankTab = function () {
prefix = 'unpinned';
let tab = createTab();
assertNumberOfTabs(2);
afterAllTabsLoaded(function () {
gBrowser.removeTab(tab);
assertNumberOfTabs(1);
assertNumberOfPinnedTabs(0);
restoreTab(function () {
prefix = 'unpinned-restored';
assertValidPrerequisites();
assertGroupItemPreserved();
createBlankTab();
afterAllTabsLoaded(testUndoCloseWithSelectedBlankPinnedTab);
});
});
}
let testUndoCloseWithSelectedBlankPinnedTab = function () {
prefix = 'pinned';
assertNumberOfTabs(2);
afterAllTabsLoaded(function () {
gBrowser.removeTab(gBrowser.tabs[0]);
gBrowser.pinTab(gBrowser.tabs[0]);
registerCleanupFunction(function () {
let tab = gBrowser.tabs[0];
if (tab.pinned)
gBrowser.unpinTab(tab);
});
assertNumberOfTabs(1);
assertNumberOfPinnedTabs(1);
restoreTab(function () {
prefix = 'pinned-restored';
assertValidPrerequisites();
assertGroupItemPreserved();
createBlankTab();
gBrowser.removeTab(gBrowser.tabs[0]);
afterAllTabsLoaded(finishTest);
});
});
}
waitForExplicitFinish();
registerCleanupFunction(function () TabView.hide());
showTabView(function () {
hideTabView(function () {
cw = TabView.getContentWindow();
groupItemId = cw.GroupItems.groupItems[0].id;
assertValidPrerequisites();
testUndoCloseWithSelectedBlankTab();
});
});
}

Просмотреть файл

@ -0,0 +1,160 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let prefsBranch;
let currentActiveGroupItemId;
function test() {
waitForExplicitFinish();
// disable the first run pref
prefsBranch = Services.prefs.getBranch("browser.panorama.");
prefsBranch.setBoolPref("experienced_first_run", false);
let win =
window.openDialog(getBrowserURL(), "_blank", "all,dialog=no", "about:blank");
let onLoad = function() {
win.removeEventListener("load", onLoad, false);
let theObserver = function(subject, topic, data) {
Services.obs.removeObserver(
theObserver, "browser-delayed-startup-finished");
test1(win);
}
Services.obs.addObserver(
theObserver, "browser-delayed-startup-finished", false);
};
win.addEventListener("load", onLoad, false);
}
// check whether tha menu is hidden when the "experienced_first_run" pref is
// false
function test1(win) {
is(win.gBrowser.tabs.length - win.gBrowser.visibleTabs.length, 0,
"There are no hidden tabs")
let originalTab = win.gBrowser.visibleTabs[0];
openTabContextPopup(win, originalTab);
ok(win.document.getElementById("context_tabViewMenu").hidden,
"The menu should be hidden");
closeTabContextPopup(win);
executeSoon(function() {
ok(!win.TabView.getContentWindow(), "The tab view iframe is not loaded");
test2(win);
});
}
// press the next group key combination and check whether the iframe has loaded or not
function test2(win) {
goToNextGroup(win);
// give it a delay so we can ensure the iframe has not been loaded
executeSoon(function() {
ok(!win.TabView.getContentWindow(),
"The tab view iframe is not loaded after pressing the next group key combination");
test3(win);
});
}
// first run has happened, open the tab context menupopup and the tabview menu,
// move a tab to another group including iframe initialization. Then,
// use the key combination to change to the next group.
function test3(win) {
prefsBranch.setBoolPref("experienced_first_run", true);
let newTab = win.gBrowser.addTab("about:blank");
// open the tab context menupopup and the tabview menupopup
openTabContextPopup(win, newTab);
win.document.getElementById("context_tabViewMenuPopup").openPopup(
win.document.getElementById("context_tabViewMenu"), "end_after", 0, 0,
true, false);
ok(!win.document.getElementById("context_tabViewMenu").hidden,
"The menu should be visible now");
is(win.gBrowser.tabs.length - win.gBrowser.visibleTabs.length, 0,
"There are no hidden tabs")
ok(!win.TabView.getContentWindow(),
"The tab view iframe is not loaded after opening tab context menu");
let onTabViewFrameInitialized = function() {
win.removeEventListener(
"tabviewframeinitialized", onTabViewFrameInitialized, false);
let contentWindow = win.document.getElementById("tab-view").contentWindow;
// show the tab view to ensure groups are created before checking.
let onTabViewShown = function() {
win.removeEventListener("tabviewshown", onTabViewShown, false);
ok(win.TabView.isVisible(), "Tab View is visible");
is(contentWindow.GroupItems.groupItems.length, 2,
"There are two group items");
is(contentWindow.GroupItems.groupItems[0].getChildren().length, 1,
"There should be one tab item in the first group");
is(contentWindow.GroupItems.groupItems[1].getChildren().length, 1,
"There should be one tab item in the second group");
// simulate the next group key combination
currentActiveGroupItemId =
contentWindow.GroupItems.getActiveGroupItem().id;
win.addEventListener("tabviewhidden", onTabViewHidden, false);
win.TabView.toggle();
};
let onTabViewHidden = function() {
win.removeEventListener("tabviewhidden", onTabViewHidden, false);
goToNextGroup(win);
isnot(contentWindow.GroupItems.getActiveGroupItem().id,
currentActiveGroupItemId, "Just switched to another group");
// close the window and finish it
win.close();
finish();
};
win.addEventListener("tabviewshown", onTabViewShown, false);
// give it a delay to ensure everything is loaded.
executeSoon(function() { win.TabView.toggle(); });
};
win.addEventListener(
"tabviewframeinitialized", onTabViewFrameInitialized, false);
// move the tab to another group using the menu item
win.document.getElementById("context_tabViewNewGroup").doCommand();
// close popups
win.document.getElementById("context_tabViewMenuPopup").hidePopup();
closeTabContextPopup(win);
}
function openTabContextPopup(win, tab) {
win.document.popupNode = tab;
win.document.getElementById("tabContextMenu").openPopup(
tab, "end_after", 0, 0, true, false);
}
function closeTabContextPopup(win) {
win.document.getElementById("tabContextMenu").hidePopup();
}
function goToNextGroup(win) {
let utils =
win.QueryInterface(Ci.nsIInterfaceRequestor).
getInterface(Ci.nsIDOMWindowUtils);
const masks = Ci.nsIDOMNSEvent;
let mval = 0;
mval |= masks.CONTROL_MASK;
utils.sendKeyEvent("keypress", 0, 96, mval);
}

Просмотреть файл

@ -1,52 +1,20 @@
/* ***** 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 628165.
*
* 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):
* 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 ***** */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
let cw;
let sendWindowsKey = function () {
let testEnableSearchWithWindowsKey = function () {
let utils = cw.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils);
utils.sendKeyEvent('keydown', 0, 0, 0);
}
let testEnableSearchWithWindowsKey = function () {
sendWindowsKey();
ok(!cw.isSearchEnabled(), 'search is not enabled');
// we test 0, for Linux, and 91 (left) and 92 (right) for windows
let keyCodes = [0, 91, 92];
keyCodes.forEach(function(keyCode) {
utils.sendKeyEvent("keydown", keyCode, 0, 0);
ok(!cw.isSearchEnabled(), "search is not enabled with keyCode: " + keyCode);
});
hideTabView(finish);
}

Просмотреть файл

@ -0,0 +1,113 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
let cw;
let prefix = 'start';
let createGroupItem = function () {
let bounds = new cw.Rect(20, 20, 200, 200);
let groupItem = new cw.GroupItem([], {bounds: bounds, immediately: true});
cw.GroupItems.setActiveGroupItem(groupItem);
gBrowser.loadOneTab('http://mochi.test:8888/', {inBackground: true});
gBrowser.loadOneTab('http://mochi.test:8888/', {inBackground: true});
let groupItemId = groupItem.id;
registerCleanupFunction(function() {
let groupItem = cw.GroupItems.groupItem(groupItemId);
if (groupItem)
groupItem.close();
});
}
let getGroupItem = function (index) {
return cw.GroupItems.groupItems[index];
}
let restoreTab = function (callback) {
let tab = undoCloseTab(0);
if (tab._tabViewTabItem._reconnected) {
callback();
return;
}
tab._tabViewTabItem.addSubscriber(tab, 'reconnected', function () {
tab._tabViewTabItem.removeSubscriber(tab, 'reconnected');
afterAllTabsLoaded(callback);
});
}
let activateFirstGroupItem = function () {
let activeTabItem = getGroupItem(0).getChild(0);
cw.GroupItems.updateActiveGroupItemAndTabBar(activeTabItem);
}
let assertTabViewIsHidden = function () {
ok(!TabView.isVisible(), prefix + ': tabview is hidden');
}
let assertNumberOfGroups = function (num) {
is(cw.GroupItems.groupItems.length, num, prefix + ': there are ' + num + ' groups');
}
let assertNumberOfTabs = function (num) {
is(gBrowser.visibleTabs.length, num, prefix + ': there are ' + num + ' tabs');
}
let assertNumberOfPinnedTabs = function (num) {
is(gBrowser._numPinnedTabs, num, prefix + ': there are ' + num + ' pinned tabs');
}
let assertNumberOfTabsInGroup = function (groupItem, num) {
is(groupItem.getChildren().length, num, prefix + ': there are ' + num + ' tabs in the group');
}
let assertValidPrerequisites = function () {
assertNumberOfTabs(1);
assertNumberOfGroups(1);
assertNumberOfPinnedTabs(0);
}
let finishTest = function () {
prefix = 'finish';
assertValidPrerequisites();
assertTabViewIsHidden();
finish();
}
let testRestoreTabFromInactiveGroup = function () {
prefix = 'restore';
activateFirstGroupItem();
let groupItem = getGroupItem(1);
let tabItem = groupItem.getChild(0);
gBrowser.removeTab(tabItem.tab);
assertNumberOfTabsInGroup(groupItem, 1);
restoreTab(function () {
assertNumberOfTabsInGroup(groupItem, 2);
activateFirstGroupItem();
gBrowser.removeTab(gBrowser.tabs[1]);
gBrowser.removeTab(gBrowser.tabs[1]);
finishTest();
});
}
waitForExplicitFinish();
assertTabViewIsHidden();
registerCleanupFunction(function () TabView.hide());
showTabView(function () {
hideTabView(function () {
cw = TabView.getContentWindow();
assertValidPrerequisites();
createGroupItem();
afterAllTabsLoaded(testRestoreTabFromInactiveGroup);
});
});
}

Просмотреть файл

@ -0,0 +1,126 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let win;
let contentWindow;
let originalTab;
function test() {
waitForExplicitFinish();
setup();
}
function setup() {
win = window.openDialog(getBrowserURL(), "_blank",
"chrome,all,dialog=no,height=800,width=800");
let onLoad = function() {
win.removeEventListener("load", onLoad, false);
originalTab = win.gBrowser.visibleTabs[0];
win.gBrowser.addTab();
win.gBrowser.pinTab(originalTab);
let onTabViewShown = function() {
win.removeEventListener("tabviewshown", onTabViewShown, false);
ok(win.TabView.isVisible(), "Tab View is visible");
contentWindow = win.document.getElementById("tab-view").contentWindow;
is(contentWindow.GroupItems.groupItems.length, 1, "There is one group");
is(contentWindow.GroupItems.groupItems[0].getChildren().length, 1,
"The group has only one tab item");
// show the undo close group button
let group = contentWindow.GroupItems.groupItems[0];
group.closeAll();
group.addSubscriber(group, "groupHidden", function() {
group.removeSubscriber(group, "groupHidden");
restore(group.id);
});
};
win.addEventListener("tabviewshown", onTabViewShown, false);
win.TabView.toggle();
}
win.addEventListener("load", onLoad, false);
}
function restore(groupId) {
// window state ready
let handleSSWindowStateReady = function() {
win.removeEventListener("SSWindowStateReady", handleSSWindowStateReady, false);
executeSoon(function() {
is(contentWindow.GroupItems.groupItems.length, 1, "There is one group");
let group = contentWindow.GroupItems.groupItems[0];
ok(!group.hidden, "The group is visible");
is(group.getChildren().length, 2, "This group has two tab items");
// check the position of the group item and the tab items.
let tabItemOne = group.getChildren()[0];
let tabItemTwo = group.getChildren()[1];
let groupBounds = group.getBounds();
let tabItemOneBounds = tabItemOne.getBounds();
let tabItemTwoBounds = tabItemTwo.getBounds();
ok(groupBounds.left < tabItemOneBounds.left &&
(groupBounds.right) > (tabItemOneBounds.right) &&
groupBounds.top < tabItemOneBounds.top &&
(groupBounds.bottom) > (tabItemOneBounds.bottom),
"Tab item one is within the group");
ok(groupBounds.left < tabItemOneBounds.left &&
(groupBounds.right) > (tabItemTwoBounds.right) &&
groupBounds.top < tabItemOneBounds.top &&
(groupBounds.bottom) > (tabItemTwoBounds.bottom),
"Tab item two is within the group");
win.close();
finish();
});
}
win.addEventListener("SSWindowStateReady", handleSSWindowStateReady, false);
// simulate restoring previous session (one group and two tab items)
const DUMMY_PAGE_URL = "http://example.com/";
let newState = {
windows: [{
tabs: [{
entries: [{ url: DUMMY_PAGE_URL }],
index: 2,
hidden: false,
attributes: {},
extData: {
"tabview-tab":
'{"bounds":{"left":208,"top":54,"width":205,"height":169},' +
'"userSize":null,"url":"' + DUMMY_PAGE_URL + '","groupID":' +
groupId + ',"imageData":null,"title":null}'
}}, {
entries: [{ url: DUMMY_PAGE_URL }],
index: 1,
hidden: false,
attributes: {},
extData: {
"tabview-tab":
'{"bounds":{"left":429,"top":54,"width":205,"height":169},' +
'"userSize":null,"url":"' + DUMMY_PAGE_URL + '","groupID":' +
groupId + ',"imageData":null,"title":null}'
}
}],
extData: {
"tabview-groups": '{"nextID":' + (groupId + 1) + ',"activeGroupId":' + groupId + '}',
"tabview-group":
'{"' + groupId + '":{"bounds":{"left":202,"top":30,"width":455,"height":249},' +
'"userSize":null,"locked":{},"title":"","id":' + groupId +'}}',
"tabview-ui": '{"pageBounds":{"left":0,"top":0,"width":788,"height":548}}'
}, sizemode:"normal"
}]
};
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
ss.setWindowState(win, JSON.stringify(newState), false);
}

Просмотреть файл

@ -0,0 +1,64 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
waitForExplicitFinish();
let originalTab = gBrowser.visibleTabs[0];
let newTab1 = gBrowser.addTab("about:blank", { skipAnimation: true });
let newTab2 = gBrowser.addTab("about:blank", { skipAnimation: true });
gBrowser.pinTab(newTab1);
let contentWindow;
let partOne = function() {
window.removeEventListener("tabviewshown", partOne, false);
contentWindow = document.getElementById("tab-view").contentWindow;
is(contentWindow.GroupItems.groupItems.length, 1, "There is only one group item");
let groupItem = contentWindow.GroupItems.groupItems[0];
let tabItems = groupItem.getChildren();
is(tabItems.length, 2, "There are two tab items in that group item");
is(tabItems[0].tab, originalTab, "The first tab item is linked to the first tab");
is(tabItems[1].tab, newTab2, "The second tab item is linked to the second tab");
window.addEventListener("tabviewhidden", partTwo, false);
TabView.toggle();
};
let partTwo = function() {
window.removeEventListener("tabviewhidden", partTwo, false);
gBrowser.unpinTab(newTab1);
window.addEventListener("tabviewshown", partThree, false);
TabView.toggle();
};
let partThree = function() {
window.removeEventListener("tabviewshown", partThree, false);
let tabItems = contentWindow.GroupItems.groupItems[0].getChildren();
is(tabItems.length, 3, "There are three tab items in that group item");
is(tabItems[0].tab, gBrowser.visibleTabs[0], "The first tab item is linked to the first tab");
is(tabItems[1].tab, gBrowser.visibleTabs[1], "The second tab item is linked to the second tab");
is(tabItems[2].tab, gBrowser.visibleTabs[2], "The third tab item is linked to the third tab");
window.addEventListener("tabviewhidden", endGame, false);
TabView.toggle();
};
let endGame = function() {
window.removeEventListener("tabviewhidden", endGame, false);
gBrowser.removeTab(newTab1);
gBrowser.removeTab(newTab2);
finish();
};
window.addEventListener("tabviewshown", partOne, false);
TabView.toggle();
}

Просмотреть файл

@ -0,0 +1,84 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
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});
let groupItemId = groupItem.id;
registerCleanupFunction(function() {
let groupItem = cw.GroupItems.groupItem(groupItemId);
if (groupItem)
groupItem.close();
});
return groupItem;
}
let assertNumberOfGroups = function (num) {
is(cw.GroupItems.groupItems.length, num, 'there should be ' + num + ' groups');
}
let assertNumberOfTabs = function (num) {
is(gBrowser.tabs.length, num, 'there should be ' + num + ' tabs');
}
let simulateDoubleClick = function (target, button) {
for (let i=0; i<2; i++)
EventUtils.synthesizeMouseAtCenter(target, {button: button || 0}, cw);
}
let finishTest = function () {
let tabItem = gBrowser.tabs[0]._tabViewTabItem;
cw.GroupItems.updateActiveGroupItemAndTabBar(tabItem);
gBrowser.removeTab(gBrowser.tabs[1]);
assertNumberOfGroups(1);
assertNumberOfTabs(1);
finish();
}
let testDoubleClick = function () {
let groupItem = createGroupItem();
assertNumberOfGroups(2);
assertNumberOfTabs(1);
// simulate double click on group title
let input = groupItem.$title[0];
simulateDoubleClick(input);
assertNumberOfTabs(1);
// simulate double click on title bar
let titlebar = groupItem.$titlebar[0];
simulateDoubleClick(titlebar);
assertNumberOfTabs(1);
// simulate double click with middle mouse button
let container = groupItem.container;
simulateDoubleClick(container, 1);
assertNumberOfTabs(1);
// simulate double click with right mouse button
simulateDoubleClick(container, 2);
assertNumberOfTabs(1);
// simulate double click with left mouse button
let container = groupItem.container;
simulateDoubleClick(container);
assertNumberOfTabs(2);
whenTabViewIsHidden(finishTest);
}
waitForExplicitFinish();
registerCleanupFunction(function () TabView.hide());
showTabView(function () {
cw = TabView.getContentWindow();
testDoubleClick();
});
}

Просмотреть файл

@ -0,0 +1,75 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
let cw;
let prefix;
let timestamp;
let storeTimestamp = function () {
timestamp = cw.TabItems._lastUpdateTime;
}
let checkTimestamp = function () {
is(timestamp, cw.TabItems._lastUpdateTime, prefix +
": tabs were not updated");
}
let actionAddTab = function () {
storeTimestamp();
gBrowser.addTab("about:home");
afterAllTabsLoaded(function () {
checkTimestamp();
next();
});
}
let actionMoveTab = function () {
storeTimestamp();
gBrowser.moveTabTo(gBrowser.tabs[0], 1);
gBrowser.moveTabTo(gBrowser.tabs[1], 0);
checkTimestamp();
next();
}
let actionSelectTab = function () {
storeTimestamp();
gBrowser.selectedTab = gBrowser.tabs[1]
gBrowser.selectedTab = gBrowser.tabs[0]
checkTimestamp();
next();
}
let actionRemoveTab = function () {
storeTimestamp();
gBrowser.removeTab(gBrowser.tabs[1]);
checkTimestamp();
next();
}
let actions = [
{name: "add", func: actionAddTab},
{name: "move", func: actionMoveTab},
{name: "select", func: actionSelectTab},
{name: "remove", func: actionRemoveTab}
];
let next = function () {
let action = actions.shift();
if (action) {
prefix = action.name;
action.func();
} else {
finish();
}
}
waitForExplicitFinish();
showTabView(function () {
cw = TabView.getContentWindow();
hideTabView(next);
});
}

Просмотреть файл

@ -52,53 +52,29 @@
<binding id="urlbar" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete">
<content sizetopopup="pref">
<xul:hbox class="urlbar-frontcap-and-textbox" flex="1">
<xul:hbox class="urlbar-frontcap">
<children includes="image|deck|stack|box">
<xul:image class="autocomplete-icon" allowevents="true"/>
</children>
<children includes="image|deck|stack|box">
<xul:image class="autocomplete-icon" allowevents="true"/>
</children>
<xul:hbox anonid="textbox-container"
class="autocomplete-textbox-container urlbar-textbox-container"
flex="1" xbl:inherits="focused">
<xul:hbox anonid="textbox-input-box"
class="textbox-input-box urlbar-input-box"
flex="1" xbl:inherits="tooltiptext=inputtooltiptext">
<children/>
<html:input anonid="input"
class="autocomplete-textbox urlbar-input textbox-input uri-element-right-align"
flex="1" allowevents="true"
xbl:inherits="tooltiptext=inputtooltiptext,onfocus,onblur,value,type,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey"/>
</xul:hbox>
<xul:stack anonid="stack" class="urlbar-stack" flex="1">
<xul:scrollbox class="urlbar-over-link-layer" flex="1"
xbl:inherits="overlinkstate" align="center">
<xul:label anonid="origin-label" class="urlbar-origin-label" flex="1"
crop="end"/>
<xul:hbox anonid="over-link-box" class="urlbar-over-link-box"
xbl:inherits="overlinkstate" align="center">
<xul:label anonid="over-link-host-label"
class="urlbar-over-link-host-label uri-element-right-align"/>
<xul:label anonid="over-link-path-label"
class="urlbar-over-link-path-label uri-element-right-align" flex="1"/>
</xul:hbox>
</xul:scrollbox>
<xul:hbox anonid="textbox-container"
class="autocomplete-textbox-container urlbar-textbox-container"
flex="1" xbl:inherits="focused,overlinkstate">
<xul:hbox anonid="textbox-input-box"
class="textbox-input-box urlbar-input-box"
flex="1" xbl:inherits="tooltiptext=inputtooltiptext">
<xul:hbox class="urlbar-textbox-container-children"
xbl:inherits="overlinkstate">
<children/>
</xul:hbox>
<html:input anonid="input"
class="autocomplete-textbox urlbar-input textbox-input uri-element-right-align"
flex="1" allowevents="true"
xbl:inherits="tooltiptext=inputtooltiptext,onfocus,onblur,value,type,maxlength,disabled,size,readonly,placeholder,tabindex,accesskey"/>
</xul:hbox>
<xul:hbox class="urlbar-textbox-container-children"
xbl:inherits="overlinkstate">
<children includes="hbox"/>
</xul:hbox>
</xul:hbox>
</xul:stack>
<xul:dropmarker anonid="historydropmarker"
class="autocomplete-history-dropmarker urlbar-history-dropmarker"
allowevents="true"
xbl:inherits="open,enablehistory,parentfocused=focused"/>
<xul:popupset anonid="popupset"
class="autocomplete-result-popupset"/>
<children includes="hbox"/>
</xul:hbox>
<xul:dropmarker anonid="historydropmarker"
class="autocomplete-history-dropmarker urlbar-history-dropmarker"
allowevents="true"
xbl:inherits="open,enablehistory,parentfocused=focused"/>
<xul:popupset anonid="popupset"
class="autocomplete-result-popupset"/>
<children includes="toolbarbutton"/>
</content>
@ -123,7 +99,6 @@
this.inputField.addEventListener("mouseout", this, false);
this.inputField.addEventListener("overflow", this, false);
this.inputField.addEventListener("underflow", this, false);
this._overLinkBox.addEventListener("transitionend", this, false);
const kXULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var textBox = document.getAnonymousElementByAttribute(this,
@ -167,7 +142,6 @@
this.inputField.removeEventListener("mouseout", this, false);
this.inputField.removeEventListener("overflow", this, false);
this.inputField.removeEventListener("underflow", this, false);
this._overLinkBox.removeEventListener("transitionend", this, false);
]]></destructor>
<field name="_value"></field>
@ -192,7 +166,6 @@
<method name="onBeforeValueSet">
<parameter name="aValue"/>
<body><![CDATA[
this._hideOverLink();
this._value = aValue;
var returnValue = aValue;
var action = this._parseActionUrl(aValue);
@ -550,12 +523,6 @@
this._contentIsCropped = false;
this._hideURLTooltip();
break;
case "transitionend":
if (aEvent.target == this._overLinkBox &&
aEvent.propertyName == "opacity") {
this._overLinkTransitioning = false;
}
break;
}
]]></body>
</method>
@ -594,200 +561,6 @@
]]></body>
</method>
<field name="_stack" readonly="true"><![CDATA[
document.getAnonymousElementByAttribute(this, "anonid", "stack");
]]></field>
<field name="_originLabel" readonly="true"><![CDATA[
document.getAnonymousElementByAttribute(this, "anonid", "origin-label");
]]></field>
<field name="_overLinkBox" readonly="true"><![CDATA[
document.getAnonymousElementByAttribute(this, "anonid",
"over-link-box");
]]></field>
<field name="_overLinkHostLabel" readonly="true"><![CDATA[
document.getAnonymousElementByAttribute(this, "anonid",
"over-link-host-label");
]]></field>
<field name="_overLinkPathLabel" readonly="true"><![CDATA[
document.getAnonymousElementByAttribute(this, "anonid",
"over-link-path-label");
]]></field>
<field name="_textboxContainer" readonly="true"><![CDATA[
document.getAnonymousElementByAttribute(this, "anonid",
"textbox-container");
]]></field>
<field name="_overLinkIntervalDelay" readonly="true"><![CDATA[
100
]]></field>
<field name="_overLinkInterval"><![CDATA[
null
]]></field>
<method name="setOverLink">
<parameter name="aURL"/>
<body><![CDATA[
// NOTE: This method is called many times in a row very quickly when
// the user mouses over a bookmarks menu, tabs menu, or long list of
// links in a page, or leaves the cursor over a page with many links
// while scrolling. Therefore it's important that it be fast. Don't
// regress performance when you modify it!
// Hide the over-link immediately if necessary.
if ((!aURL && (XULBrowserWindow.hideOverLinkImmediately ||
this._hideOverLinkImmediately)) ||
this.focused) {
this._clearOverLinkInterval();
this._setOverLinkState(null);
return;
}
// Update and show it immediately if it's in transition.
if (aURL && this._overLinkTransitioning) {
this._clearOverLinkInterval();
this._updateOverLink(aURL);
this._setOverLinkState("showing");
return;
}
this._overLinkURL = aURL;
this._seenNewOverLink = true;
// If the user is continually mousing over links, make this method
// basically a no-op.
if (this._overLinkInterval)
return;
// Otherwise, the user has just moused over or focused a single link.
// Start the interval and signal that we should potentially show the
// over-link the first time it fires by unsetting _seenNewOverLink.
this._seenNewOverLink = false;
this._overLinkInterval = setInterval(this._overLinkIntervalCallback,
this._overLinkIntervalDelay,
this);
]]></body>
</method>
<method name="_overLinkIntervalCallback">
<parameter name="self"/>
<body><![CDATA[
// If the user is still mousing over links, bail out early.
if (self._seenNewOverLink) {
self._seenNewOverLink = false;
return;
}
// Otherwise, the user has stopped over a link. Clear the interval
// and update the over-link.
self._clearOverLinkInterval();
if (self._overLinkURL) {
self._updateOverLink(self._overLinkURL);
self._setOverLinkState("fade-in");
}
else {
self._setOverLinkState("fade-out");
}
]]></body>
</method>
<method name="_hideOverLink">
<body><![CDATA[
this._hideOverLinkImmediately = true;
this.setOverLink("");
this._hideOverLinkImmediately = false;
]]></body>
</method>
<method name="_clearOverLinkInterval">
<body><![CDATA[
if (this._overLinkInterval) {
clearInterval(this._overLinkInterval);
this._overLinkInterval = null;
}
]]></body>
</method>
<method name="_setOverLinkState">
<parameter name="aVal"/>
<body><![CDATA[
switch (aVal) {
case "fade-in":
var style = window.getComputedStyle(this._overLinkBox);
this._overLinkTransitioning = style.opacity != 1;
this.setAttribute("overlinkstate", aVal);
break;
case "fade-out":
style = window.getComputedStyle(this._overLinkBox);
this._overLinkTransitioning = style.opacity != 0;
this.setAttribute("overlinkstate", aVal);
break;
case "showing":
this._overLinkTransitioning = false;
this.setAttribute("overlinkstate", aVal);
break;
default:
this._overLinkTransitioning = false;
this.removeAttribute("overlinkstate");
break;
}
]]></body>
</method>
<method name="_updateOverLink">
<parameter name="aURL"/>
<body><![CDATA[
// Get the width of the bar before we go modifying it.
var barWidth = this._stack.boxObject.width;
// Determine the pre-path and path of the over-link. Include the
// path's leading slash in the pre-path so that if the path is
// truncated its leading slash is visible.
var re = new RegExp("^([a-z0-9+.-]+://[^/]+/)(.*)$");
var match = re.exec(aURL);
var host = match ? match[1] : "";
var path = match ? match[2] : aURL;
var overLink = this._overLinkBox;
var overLinkHost = this._overLinkHostLabel;
var overLinkPath = this._overLinkPathLabel;
overLinkHost.value = host;
overLinkPath.value = path;
// Remove restrictions on the over-link's width.
overLinkHost.flex = 0;
overLinkHost.crop = "none";
overLinkPath.crop = "none";
overLink.style.minWidth = "";
overLink.style.maxWidth = "";
// Cap the width of the over-link to 2/3 of the location bar's.
var maxWidth = barWidth * 0.67;
var overLinkWidth = overLinkHost.boxObject.width +
overLinkPath.boxObject.width;
if (overLinkWidth > maxWidth) {
// If the host is wider than the cap and therefore the path is not
// visible at all, crop the host at the end.
if (overLinkHost.boxObject.width > maxWidth) {
overLinkHost.flex = 1;
overLinkHost.crop = "end";
}
overLinkPath.crop = host ? "start" : "end";
overLink.style.minWidth = maxWidth + "px";
overLink.style.maxWidth = maxWidth + "px";
}
var action = this._parseActionUrl(this._value);
this._originLabel.value = action ? action.param : this._value;
]]></body>
</method>
<field name="_numNoActionsKeys"><![CDATA[
0
]]></field>
@ -860,7 +633,6 @@
]]></handler>
<handler event="focus" phase="capturing"><![CDATA[
this._hideOverLink();
this._hideURLTooltip();
]]></handler>

Просмотреть файл

@ -21,7 +21,7 @@ browser.jar:
* content/browser/aboutHome.js (content/aboutHome.js)
* content/browser/aboutHome.css (content/aboutHome.css)
content/browser/aboutHome-restore-icon.png (content/aboutHome-restore-icon.png)
content/browser/aboutHome-restore-icon-rtl.png (content/aboutHome-restore-icon-rtl.png)
content/browser/aboutHome-restore-icon-small.png (content/aboutHome-restore-icon-small.png)
content/browser/aboutRobots-icon.png (content/aboutRobots-icon.png)
content/browser/aboutRobots-widget-left.png (content/aboutRobots-widget-left.png)
* content/browser/browser.css (content/browser.css)

Просмотреть файл

@ -248,9 +248,18 @@ DirectoryProvider::GetFiles(const char *aKey, nsISimpleEnumerator* *aResult)
nsCOMArray<nsIFile> baseFiles;
/**
* We want to preserve the following order, since the search service loads
* engines in first-loaded-wins order.
* - extension search plugin locations (prepended below using
* NS_NewUnionEnumerator)
* - distro search plugin locations
* - user search plugin locations (profile)
* - app search plugin location (shipped engines)
*/
AppendDistroSearchDirs(dirSvc, baseFiles);
AppendFileKey(NS_APP_SEARCH_DIR, dirSvc, baseFiles);
AppendFileKey(NS_APP_USER_SEARCH_DIR, dirSvc, baseFiles);
AppendFileKey(NS_APP_SEARCH_DIR, dirSvc, baseFiles);
nsCOMPtr<nsISimpleEnumerator> baseEnum;
rv = NS_NewArrayEnumerator(getter_AddRefs(baseEnum), baseFiles);

Просмотреть файл

@ -57,6 +57,8 @@ PlacesViewBase.prototype = {
_viewElt: null,
get viewElt() this._viewElt,
get controllers() this._viewElt.controllers,
// The xul element that represents the root container.
_rootElt: null,

Просмотреть файл

@ -1584,20 +1584,22 @@ function goUpdatePlacesCommands() {
function doGetPlacesControllerForCommand(aCommand)
{
// A context menu may be built for non-focusable views. Thus, we first try
// to look for a view associated with document.popupNode
let popupNode = document.popupNode;
if (popupNode) {
let view = PlacesUIUtils.getViewForNode(popupNode);
if (view && view._contextMenuShown)
return view.controllers.getControllerForCommand(aCommand);
}
// When we're not building a context menu, only focusable views
// are possible. Thus, we can safely use the command dispatcher.
let controller = top.document.commandDispatcher
.getControllerForCommand(aCommand);
if (controller)
return controller;
// If building commands for a context menu, look for an element in the
// current popup.
let element = document.popupNode;
if (element) {
let view = PlacesUIUtils.getViewForNode(element);
if (view && view._contextMenuShown)
return view.viewElt.controllers.getControllerForCommand(aCommand);
}
return null;
}

Просмотреть файл

@ -665,15 +665,19 @@
]]></body>
</method>
<field name="_contextMenuShown">false</field>
<method name="buildContextMenu">
<parameter name="aPopup"/>
<body><![CDATA[
this._contextMenuShown = true;
return this.controller.buildContextMenu(aPopup);
]]></body>
</method>
<method name="destroyContextMenu">
<parameter name="aPopup"/>
this._contextMenuShown = false;
<body/>
</method>
</implementation>

Просмотреть файл

@ -72,6 +72,7 @@ _BROWSER_TEST_FILES = \
frameRight.html \
browser_toolbar_migration.js \
browser_library_batch_delete.js \
browser_555547.js \
$(NULL)
libs:: $(_BROWSER_TEST_FILES)

Просмотреть файл

@ -0,0 +1,59 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
function test() {
waitForExplicitFinish();
let sidebarBox = document.getElementById("sidebar-box");
is(sidebarBox.hidden, true, "The sidebar should be hidden");
// Uncollapse the personal toolbar if needed.
let toolbar = document.getElementById("PersonalToolbar");
let wasCollapsed = toolbar.collapsed;
if (wasCollapsed)
setToolbarVisibility(toolbar, true);
let sidebar = document.getElementById("sidebar");
sidebar.addEventListener("load", function() {
sidebar.removeEventListener("load", arguments.callee, true);
let tree = sidebar.contentDocument.getElementById("bookmarks-view");
// The Places view is build on load, so we enqueue our test.
executeSoon(function() {
// Focus the tree and check if its controller is returned.
tree.focus();
let controller = doGetPlacesControllerForCommand("placesCmd_copy");
let treeController = tree.controllers
.getControllerForCommand("placesCmd_copy");
ok(controller == treeController, "tree controller was returned");
// Open the context menu for a toolbar item, and check if the toolbar's
// controller is returned.
let toolbarItems = document.getElementById("PlacesToolbarItems");
EventUtils.synthesizeMouse(toolbarItems.childNodes[0],
4, 4, { type: "contextmenu", button: 2 },
window);
controller = doGetPlacesControllerForCommand("placesCmd_copy");
let toolbarController = document.getElementById("PlacesToolbar")
.controllers
.getControllerForCommand("placesCmd_copy");
ok(controller == toolbarController, "the toolbar controller was returned");
document.getElementById("placesContext").hidePopup();
// Now that the context menu is closed, try to get the tree controller again.
tree.focus();
controller = doGetPlacesControllerForCommand("placesCmd_copy");
ok(controller == treeController, "tree controller was returned");
toggleSidebar();
if (wasCollapsed)
setToolbarVisibility(toolbar, false);
finish();
});
}, true);
toggleSidebar("viewBookmarksSidebar", true);
}

Просмотреть файл

@ -2472,7 +2472,21 @@ SessionStoreService.prototype = {
}
}
if (aTabs.length > 0) {
if (!this._isWindowLoaded(aWindow)) {
// from now on, the data will come from the actual window
delete this._statesToRestore[aWindow.__SS_restoreID];
delete aWindow.__SS_restoreID;
delete this._windows[aWindow.__SSi]._restoring;
}
if (aTabs.length == 0) {
// this is normally done in restoreHistory() but as we're returning early
// here we need to take care of it.
this._sendWindowStateEvent(aWindow, "Ready");
return;
}
if (aTabs.length > 1) {
// Load hidden tabs last, by pushing them to the end of the list
let unhiddenTabs = aTabs.length;
for (let t = 0; t < unhiddenTabs; ) {
@ -2505,13 +2519,13 @@ SessionStoreService.prototype = {
aTabData = aTabData.splice(firstVisibleTab, maxVisibleTabs).concat(aTabData);
aSelectTab -= firstVisibleTab;
}
}
// make sure to restore the selected tab first (if any)
if (aSelectTab-- && aTabs[aSelectTab]) {
aTabs.unshift(aTabs.splice(aSelectTab, 1)[0]);
aTabData.unshift(aTabData.splice(aSelectTab, 1)[0]);
tabbrowser.selectedTab = aTabs[0];
}
// make sure to restore the selected tab first (if any)
if (aSelectTab-- && aTabs[aSelectTab]) {
aTabs.unshift(aTabs.splice(aSelectTab, 1)[0]);
aTabData.unshift(aTabData.splice(aSelectTab, 1)[0]);
tabbrowser.selectedTab = aTabs[0];
}
// Prepare the tabs so that they can be properly restored. We'll pin/unpin
@ -2578,13 +2592,6 @@ SessionStoreService.prototype = {
}
}
if (!this._isWindowLoaded(aWindow)) {
// from now on, the data will come from the actual window
delete this._statesToRestore[aWindow.__SS_restoreID];
delete aWindow.__SS_restoreID;
delete this._windows[aWindow.__SSi]._restoring;
}
// helper hashes for ensuring unique frame IDs and unique document
// identifiers.
var idMap = { used: {} };

Просмотреть файл

@ -141,6 +141,7 @@ _BROWSER_TEST_FILES = \
browser_623779.js \
browser_624727.js \
browser_625257.js \
browser_628270.js \
$(NULL)
ifneq ($(OS_ARCH),Darwin)

Просмотреть файл

@ -0,0 +1,54 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let ss = Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
function test() {
let assertNumberOfTabs = function (num, msg) {
is(gBrowser.tabs.length, num, msg);
}
let assertNumberOfVisibleTabs = function (num, msg) {
is(gBrowser.visibleTabs.length, num, msg);
}
let assertNumberOfPinnedTabs = function (num, msg) {
is(gBrowser._numPinnedTabs, num, msg);
}
waitForExplicitFinish();
// check prerequisites
assertNumberOfTabs(1, "we start off with one tab");
// setup
let tab = gBrowser.addTab("about:robots");
whenTabIsLoaded(tab, function () {
// hide the newly created tab
assertNumberOfVisibleTabs(2, "there are two visible tabs");
gBrowser.showOnlyTheseTabs([gBrowser.tabs[0]]);
assertNumberOfVisibleTabs(1, "there is one visible tab");
ok(tab.hidden, "newly created tab is now hidden");
// close and restore hidden tab
gBrowser.removeTab(tab);
tab = ss.undoCloseTab(window, 0);
// check that everything was restored correctly, clean up and finish
whenTabIsLoaded(tab, function () {
is(tab.linkedBrowser.currentURI.spec, "about:robots", "restored tab has correct url");
gBrowser.removeTab(tab);
finish();
});
});
}
function whenTabIsLoaded(tab, callback) {
tab.linkedBrowser.addEventListener("load", function onLoad() {
tab.linkedBrowser.removeEventListener("load", onLoad, true);
callback();
}, true);
}

Просмотреть файл

@ -410,10 +410,13 @@ function TabWindow(win) {
this.previews = [];
for (let i = 0; i < this.events.length; i++)
this.tabbrowser.tabContainer.addEventListener(this.events[i], this, false);
for (let i = 0; i < this.tabEvents.length; i++)
this.tabbrowser.tabContainer.addEventListener(this.tabEvents[i], this, false);
this.tabbrowser.addTabsProgressListener(this);
for (let i = 0; i < this.winEvents.length; i++)
this.win.addEventListener(this.winEvents[i], this, false);
AeroPeek.windows.push(this);
let tabs = this.tabbrowser.tabs;
for (let i = 0; i < tabs.length; i++)
@ -425,7 +428,8 @@ function TabWindow(win) {
TabWindow.prototype = {
_enabled: false,
events: ["TabOpen", "TabClose", "TabSelect", "TabMove"],
tabEvents: ["TabOpen", "TabClose", "TabSelect", "TabMove"],
winEvents: ["tabviewshown", "tabviewhidden"],
destroy: function () {
this._destroying = true;
@ -433,9 +437,11 @@ TabWindow.prototype = {
let tabs = this.tabbrowser.tabs;
this.tabbrowser.removeTabsProgressListener(this);
for (let i = 0; i < this.tabEvents.length; i++)
this.tabbrowser.tabContainer.removeEventListener(this.tabEvents[i], this, false);
for (let i = 0; i < this.events.length; i++)
this.tabbrowser.tabContainer.removeEventListener(this.events[i], this, false);
for (let i = 0; i < this.winEvents.length; i++)
this.win.removeEventListener(this.winEvents[i], this, false);
for (let i = 0; i < tabs.length; i++)
this.removeTab(tabs[i]);
@ -459,7 +465,13 @@ TabWindow.prototype = {
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
let preview = AeroPeek.taskbar.createTaskbarTabPreview(docShell, controller);
let preview;
try {
preview = AeroPeek.taskbar.createTaskbarTabPreview(docShell, controller);
} catch (e) {
controller.destroy();
return;
}
preview.visible = AeroPeek.enabled;
preview.active = this.tabbrowser.selectedTab == tab;
// Grab the default favicon
@ -548,6 +560,12 @@ TabWindow.prototype = {
this.previews.splice(newPos, 0, preview);
this.updateTabOrdering();
break;
case "tabviewshown":
this.enabled = false;
break;
case "tabviewhidden":
this.enabled = true;
break;
}
},

Просмотреть файл

@ -1 +1 @@
4.0b11pre
4.0b12pre

Просмотреть файл

@ -14,8 +14,6 @@
<!ENTITY aboutProduct.accesskey "A">
<!ENTITY productHelp.label "&brandShortName; Help">
<!ENTITY productHelp.accesskey "H">
<!ENTITY helpForIEUsers.label "For Internet Explorer Users">
<!ENTITY helpForIEUsers.accesskey "I">
<!ENTITY helpMac.commandkey "?">
<!ENTITY helpSafeMode.label "Restart with Add-ons Disabled…">
<!ENTITY helpSafeMode.accesskey "R">

Просмотреть файл

@ -114,6 +114,9 @@ crashedpluginsMessage.reloadButton.accesskey=R
crashedpluginsMessage.submitButton.label=Submit a crash report
crashedpluginsMessage.submitButton.accesskey=S
crashedpluginsMessage.learnMore=Learn More…
carbonFailurePluginsMessage.title=This page requires a plugin that can only run in 32-bit mode
carbonFailurePluginsMessage.restartButton.label=Restart in 32-bit mode
carbonFailurePluginsMessage.restartButton.accesskey=R
# Sanitize
# LOCALIZATION NOTE (sanitizeDialog2.everything.title): When "Time range to

Просмотреть файл

@ -2,9 +2,14 @@
<ShortName>eBay</ShortName>
<Description>eBay - Online auctions</Description>
<InputEncoding>ISO-8859-1</InputEncoding>
<Image width="16" height="16">data:image/x-icon;base64,AAABAAEAEBAAAAEACABoBQAAFgAAACgAAAAQAAAAIAAAAAEACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAIAAAADAAAAA/wAAAABAAABAQAAAgEAAAMBAAAD/QAAAAIAAAECAAACAgAAAwIAAAP+AAAAAwAAAQMAAAIDAAADAwAAA/8AAAAD/AABA/wAAgP8AAMD/AAD//wAAAABAAEAAQACAAEAAwABAAP8AQAAAQEAAQEBAAIBAQADAQEAA/0BAAACAQABAgEAAgIBAAMCAQAD/gEAAAMBAAEDAQACAwEAAwMBAAP/AQAAA/0AAQP9AAID/QADA/0AA//9AAAAAgABAAIAAgACAAMAAgAD/AIAAAECAAEBAgACAQIAAwECAAP9AgAAAgIAAQICAAICAgADAgIAA/4CAAADAgABAwIAAgMCAAMDAgAD/wIAAAP+AAED/gACA/4AAwP+AAP//gAAAAMAAQADAAIAAwADAAMAA/wDAAABAwABAQMAAgEDAAMBAwAD/QMAAAIDAAECAwACAgMAAwIDAAP+AwAAAwMAAQMDAAIDAwADAwMAA/8DAAAD/wABA/8AAgP/AAMD/wAD//8AAAAD/AEAA/wCAAP8AwAD/AP8A/wAAQP8AQED/AIBA/wDAQP8A/0D/AACA/wBAgP8AgID/AMCA/wD/gP8AAMD/AEDA/wCAwP8AwMD/AP/A/wAA//8AQP//AID//wDA//8A////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB8fHx8fHx8fHx8fHx8AAB8cGRkUFAcHBx8fBUKfAAAfFBkfHxNHF4cb29vCnwAAHxkZFBQUBx8HG98bwp8fAB8ZGR8UGQcXhxvb28KFXx8fHZkZGRNHBwcfG8jCgoQfAB8fHx8HBx8b29vCnwPCnwAAAB8fBwcfHx8EBB8Dwp8AAAAAHx8fHwAfHx8AHx8fAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAA//8AAP//AACAAwAAAAMAAAADAAAAAQAAAAAAAAAAAACAAAAA4AAAAPCIAAD//wAA//8AAP//AAA=</Image>
<Image width="16" height="16">data:image/x-icon;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAABFUlEQVQ4jdWTvUoDQRSFvxUfQMFSyBvYpLGSSWFpncY6lsLWFiupBBtLBRsfQcQ2a782PoCkSrONlUGy5LPYn6wbu4DghcOcYs65595hIpVNamsj9V8ajOeFzgsFLmo+LxTXcWJVX8WyppIgKSVPkQQ/F0u3gSFwBfTqdoPoBYDnxRFcDgA4Z4cbPtazqblZptBgxJ2BtGydv+vbkyahSUGC0zxT7VeZ0DguBXFsRs9AKtzq/amOKA2sTAylzMDKoIM6wfXhcWmcBKd51ukeWq8Qx6V0MmFAuppxdx/OIgB6e/32+SoTUGfdHTxy0CRodtF6jZpW2R2qs/alQNrgYTytR8Cf1Rh08VuNGkECJCtd5L//TN/BEWxoE8dlIQAAAABJRU5ErkJggg==</Image>
<Url type="application/x-suggestions+json" method="GET" template="http://anywhere.ebay.com/services/suggest/">
<Param name="s" value="0"/>
<Param name="q" value="{searchTerms}"/>
</Url>
<Url type="text/html" method="GET" template="http://rover.ebay.com/rover/1/711-47294-18009-3/4">
<Param name="satitle" value="{searchTerms}"/>
<Param name="mpre" value="http://shop.ebay.com/?_nkw={searchTerms}"/>
</Url>
<SearchForm>http://search.ebay.com/</SearchForm>
</SearchPlugin>

Просмотреть файл

@ -908,7 +908,7 @@ toolbar[iconsize="small"] #feed-button {
padding: 0;
}
.urlbar-frontcap-and-textbox {
.urlbar-textbox-container {
-moz-appearance: none;
}
@ -954,47 +954,6 @@ toolbar[iconsize="small"] #feed-button {
color: GrayText;
}
/* over-link in location bar */
.urlbar-over-link-layer {
margin: -2px 0;
-moz-margin-start: 0;
}
.urlbar-origin-label {
padding-top: 0;
padding-bottom: 0;
-moz-padding-start: 4px;
-moz-padding-end: 0;
margin: 0;
}
.urlbar-over-link-box {
position: relative;
color: GrayText;
min-height: 22px;
padding-top: 0;
padding-bottom: 0;
-moz-padding-start: 18px;
-moz-padding-end: 5px;
}
.urlbar-over-link-box:-moz-locale-dir(ltr) {
background: url(chrome://browser/skin/urlbar-over-link-arrow.png) no-repeat left center;
right: 0;
}
.urlbar-over-link-box:-moz-locale-dir(rtl) {
background: url(chrome://browser/skin/urlbar-over-link-arrow-rtl.png) no-repeat right center;
left: 0;
}
.urlbar-over-link-host-label,
.urlbar-over-link-path-label {
padding: 0;
margin: 0;
}
/* Favicon */
#page-proxy-favicon,
#urlbar-throbber {
@ -1558,6 +1517,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
/* Tab drag and drop */
.tab-drop-indicator {
list-style-image: url(chrome://browser/skin/tabbrowser/tabDragIndicator.png);
margin-bottom: -11px;
}
/* In-tab close button */

Просмотреть файл

@ -1,8 +1,6 @@
browser.jar:
% skin browser classic/1.0 %skin/classic/browser/
% override chrome://global/skin/icons/warning-16.png moz-icon://stock/gtk-dialog-warning?size=menu
skin/classic/browser/urlbar-over-link-arrow.png
skin/classic/browser/urlbar-over-link-arrow-rtl.png
skin/classic/browser/sanitizeDialog.css (sanitizeDialog.css)
* skin/classic/browser/aboutPrivateBrowsing.css (aboutPrivateBrowsing.css)
* skin/classic/browser/aboutSessionRestore.css (aboutSessionRestore.css)

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 456 B

После

Ширина:  |  Высота:  |  Размер: 450 B

Просмотреть файл

@ -100,7 +100,8 @@ html[dir=rtl] .close {
left: 6px;
}
.close:hover {
.close:hover,
.appTabIcon:hover {
opacity: 1.0;
}
@ -124,7 +125,8 @@ html[dir=rtl] .expander {
}
.close:hover,
.expander:hover {
.expander:hover,
.appTabIcon:hover {
-moz-transition-property: opacity;
-moz-transition-duration: 0.5s;
-moz-transition-timing-function: ease-out;
@ -245,20 +247,52 @@ html[dir=rtl] .overlay {
box-shadow: -3px 3px 5.5px rgba(0,0,0,.5);
}
.appTabTray {
.appTabTrayContainer {
top: 34px;
right: 1px;
-moz-border-start: 1px solid #E1E1E1;
padding: 0 5px;
overflow-x: hidden;
text-align: start;
line-height: 0;
}
html[dir=rtl] .appTabTray {
html[dir=rtl] .appTabTrayContainer {
right: auto;
left: 1px;
}
.appTabTray {
display: inline-block;
-moz-column-width: 16px;
-moz-column-count: 0;
-moz-column-gap: 5px;
}
.appTabTrayContainerTruncated {
padding-bottom: 7px;
}
.appTabTrayContainerTruncated:after {
content: "…";
position: absolute;
bottom: 2px;
left: 0;
display: block;
width: 100%;
height: 15px;
line-height: 15px;
text-align: center;
font-size: 15px;
}
.appTabIcon {
width: 16px;
height: 16px;
cursor: pointer;
opacity: 0.8;
padding-bottom: 3px;
display: block;
}
.undo {

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 327 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 295 B

Просмотреть файл

@ -449,6 +449,11 @@ toolbar[mode="icons"] .toolbarbutton-1 > menupopup {
margin-top: 1px;
}
#navigator-toolbox > toolbar {
/* force iconsize="small" on these toolbars */
counter-reset: smallicons;
}
/* unified back/forward button */
#unified-back-forward-button {
@ -465,7 +470,7 @@ toolbar:not([mode="icons"]) #back-button:-moz-locale-dir(rtl) {
-moz-image-region: rect(0, 60px, 20px, 40px);
}
toolbar:not([iconsize="small"])[mode="icons"] #back-button {
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button {
-moz-margin-end: -5px;
position: relative;
z-index: 1;
@ -485,27 +490,17 @@ toolbar[mode="icons"] #forward-button {
-moz-margin-start: 0;
}
toolbar[mode="icons"]:not([iconsize="small"]) #forward-button {
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button {
/* 1px to the right */
padding-left: 4px;
padding-right: 2px;
}
toolbar[mode="icons"]:not([iconsize="small"]) #forward-button:-moz-lwtheme {
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button:-moz-lwtheme {
mask: url(chrome://browser/content/browser.xul#pinstripe-keyhole-forward-mask);
}
toolbar[iconsize="small"][mode="icons"] #back-button {
-moz-margin-end: 0;
}
toolbar[iconsize="small"][mode="icons"] #back-button {
width: 26px;
border-right-width: 0;
padding-right: 2px;
}
toolbar[iconsize="small"][mode="icons"] #forward-button {
#navigator-toolbox[iconsize="small"][mode="icons"] > #nav-bar #forward-button {
width: 27px;
padding-left: 2px;
}
@ -515,7 +510,11 @@ toolbar[mode="icons"] #forward-button {
border-bottom-left-radius: 0;
}
toolbar[iconsize="small"][mode="icons"] #back-button {
#navigator-toolbox[iconsize="small"][mode="icons"] > #nav-bar #back-button {
-moz-margin-end: 0;
width: 26px;
padding-right: 2px;
border-right-width: 0;
border-top-right-radius: 0;
border-bottom-right-radius: 0;
}
@ -897,42 +896,6 @@ toolbar[mode="icons"] #zoom-in-button {
margin-top: 2px;
}
/* over-link in location bar */
.urlbar-origin-label {
padding-top: 0;
padding-bottom: 0;
-moz-padding-start: 1px;
-moz-padding-end: 0;
margin: 0;
}
.urlbar-over-link-box {
position: relative;
color: GrayText;
min-height: 20px;
padding-top: 0;
padding-bottom: 0;
-moz-padding-start: 18px;
-moz-padding-end: 5px;
}
.urlbar-over-link-box:-moz-locale-dir(ltr) {
background: url(chrome://browser/skin/urlbar-over-link-arrow.png) no-repeat left center;
right: 0;
}
.urlbar-over-link-box:-moz-locale-dir(rtl) {
background: url(chrome://browser/skin/urlbar-over-link-arrow-rtl.png) no-repeat right center;
left: 0;
}
.urlbar-over-link-host-label,
.urlbar-over-link-path-label {
padding: 0;
margin: 0;
}
/* ----- AUTOCOMPLETE ----- */
#treecolAutoCompleteImage {
@ -1803,8 +1766,8 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
*/
.tab-drop-indicator {
margin-top: -8px !important;
list-style-image: url(chrome://browser/skin/tabbrowser/tabDragIndicator.png);
margin-bottom: -8px;
}
/**
@ -2358,6 +2321,7 @@ panel[dimmed="true"] {
#addon-bar {
min-height: 18px;
padding-right: 16px; /* replace with -moz-padding-end when/if bug 631729 gets fixed */
}
#addon-bar:not(:-moz-lwtheme) {
@ -2366,6 +2330,7 @@ panel[dimmed="true"] {
#status-bar {
-moz-appearance: none;
padding-right: 0;
}
#status-bar > statusbarpanel {

Просмотреть файл

@ -1,7 +1,5 @@
browser.jar:
% skin browser classic/1.0 %skin/classic/browser/
skin/classic/browser/urlbar-over-link-arrow.png
skin/classic/browser/urlbar-over-link-arrow-rtl.png
skin/classic/browser/sanitizeDialog.css (sanitizeDialog.css)
* skin/classic/browser/aboutPrivateBrowsing.css (aboutPrivateBrowsing.css)
* skin/classic/browser/aboutSessionRestore.css (aboutSessionRestore.css)

Просмотреть файл

@ -115,7 +115,8 @@ html[dir=rtl] .expander {
}
.close:hover,
.expander:hover {
.expander:hover,
.appTabIcon:hover {
-moz-transition-property: opacity;
-moz-transition-duration: 0.5s;
-moz-transition-timing-function: ease-out;
@ -239,20 +240,52 @@ html[dir=rtl] .overlay {
box-shadow: -3px 3px 5.5px rgba(0,0,0,.5);
}
.appTabTray {
.appTabTrayContainer {
top: 34px;
right: 1px;
-moz-border-start: 1px solid #E1E1E1;
padding: 0 5px;
overflow-x: hidden;
text-align: start;
line-height: 0;
}
html[dir=rtl] .appTabTray {
html[dir=rtl] .appTabTrayContainer {
right: auto;
left: 1px;
}
.appTabTray {
display: inline-block;
-moz-column-width: 16px;
-moz-column-count: 0;
-moz-column-gap: 5px;
}
.appTabTrayContainerTruncated {
padding-bottom: 7px;
}
.appTabTrayContainerTruncated:after {
content: "…";
position: absolute;
bottom: 2px;
left: 0;
display: block;
width: 100%;
height: 15px;
line-height: 15px;
text-align: center;
font-size: 15px;
}
.appTabIcon {
width: 16px;
height: 16px;
cursor: pointer;
opacity: 0.8;
padding-bottom: 3px;
display: block;
}
.undo {

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 327 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 295 B

Просмотреть файл

@ -35,7 +35,8 @@
}
@media all and (-moz-windows-default-theme) {
#navigator-toolbox > toolbar:not(:-moz-lwtheme) {
#navigator-toolbox > toolbar:not(:-moz-lwtheme),
#addon-bar:not(:-moz-lwtheme) {
background-color: @customToolbarColor@;
}
@ -190,6 +191,18 @@
background-clip: padding-box;
}
#main-window[sizemode=normal] #browser-bottombox:not(:-moz-lwtheme),
#main-window[sizemode=normal] #addon-bar:not(:-moz-lwtheme) {
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
}
#addon-bar:not(:-moz-lwtheme) {
-moz-appearance: none;
border-bottom-style: none;
background-image: -moz-linear-gradient(@toolbarHighlight@, rgba(255,255,255,0));
}
#main-menubar:not(:-moz-lwtheme):not(:-moz-window-inactive) {
background-color: rgba(255,255,255,.5);
border-radius: 4px;

Просмотреть файл

@ -108,8 +108,8 @@
}
%endif
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar)[iconsize="small"],
#navigator-toolbox > toolbar:not(#toolbar-menubar):not(#TabsToolbar)[defaulticonsize="small"]:not([iconsize]) {
#navigator-toolbox[iconsize="small"] > #nav-bar,
#navigator-toolbox > toolbar:not(#nav-bar):not(#toolbar-menubar):not(#TabsToolbar)[iconsize="small"] {
padding-top: 1px;
padding-bottom: 1px;
}
@ -572,6 +572,11 @@ menuitem.bookmark-item {
opacity: .4;
}
#nav-bar {
/* force iconsize="small" on this toolbar */
counter-reset: smallicons;
}
#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button,
#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker,
#nav-bar .toolbarbutton-1 {
@ -592,8 +597,8 @@ menuitem.bookmark-item {
}
#nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-dropmarker,
#nav-bar[iconsize="small"][mode="icons"] .toolbarbutton-1 > .toolbarbutton-menubutton-button,
#nav-bar[iconsize="small"][mode="icons"] .toolbarbutton-1 {
#navigator-toolbox[iconsize="small"][mode="icons"] > #nav-bar .toolbarbutton-1 > .toolbarbutton-menubutton-button,
#navigator-toolbox[iconsize="small"][mode="icons"] > #nav-bar .toolbarbutton-1 {
padding-left: 3px;
padding-right: 3px;
}
@ -610,7 +615,7 @@ menuitem.bookmark-item {
margin: 1px 3px;
}
#nav-bar[iconsize="small"][mode="icons"] .toolbarbutton-1 {
#navigator-toolbox[iconsize="small"][mode="icons"] > #nav-bar .toolbarbutton-1 {
margin-left: 2px;
margin-right: 2px;
}
@ -732,7 +737,7 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
-moz-image-region: rect(0, 36px, 18px, 18px);
}
toolbar:not([iconsize="small"])[mode="icons"] #back-button {
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button {
-moz-image-region: rect(18px, 20px, 38px, 0);
}
@ -743,12 +748,12 @@ toolbar:not([iconsize="small"])[mode="icons"] #back-button {
}
#nav-bar #back-button {
-moz-margin-end: 0;
-moz-margin-end: 0 !important;
}
#nav-bar #forward-button {
border-left: none;
-moz-margin-start: 0;
border-left-style: none;
-moz-margin-start: 0 !important;
}
#nav-bar #back-button:-moz-locale-dir(ltr) {
@ -762,7 +767,7 @@ toolbar:not([iconsize="small"])[mode="icons"] #back-button {
border-bottom-left-radius: 0;
}
#nav-bar:not([iconsize="small"])[mode="icons"] #back-button {
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button {
border-radius: 10000px;
padding: 0;
width: 30px;
@ -782,7 +787,7 @@ toolbar:not([iconsize="small"])[mode="icons"] #back-button {
1px 2px 1px rgba(0,0,0,.2);
}
#nav-bar:not([iconsize="small"])[mode="icons"] #back-button:not([disabled="true"]):not([open="true"]):not(:active):hover {
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not([disabled="true"]):not([open="true"]):not(:active):hover {
box-shadow: 0 0 0 1px rgba(255,255,255,.3) inset,
0 0 0 2px rgba(255,255,255,.1) inset,
0 0 0 1px hsla(190,50%,40%,.3),
@ -792,34 +797,34 @@ toolbar:not([iconsize="small"])[mode="icons"] #back-button {
0 0 5px 1px hsl(190,90%,80%);
}
#nav-bar:not([iconsize="small"])[mode="icons"] #back-button:not([disabled="true"]):hover:active,
#nav-bar:not([iconsize="small"])[mode="icons"] #back-button[open="true"] {
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button:not([disabled="true"]):hover:active,
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #back-button[open="true"] {
box-shadow: 0 0 6.5px rgba(0,0,0,.4) inset,
0 0 2px rgba(0,0,0,.4) inset,
0 0 0 1px rgba(0,0,0,.65),
0 2px 0 rgba(255,255,255,.4);
}
#nav-bar:not([iconsize="small"])[mode="icons"][currentset*="unified-back-forward-button"],
#nav-bar:not([iconsize="small"])[mode="icons"]:not([currentset]) {
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar[currentset*="unified-back-forward-button"],
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar:not([currentset]) {
padding-top: 3px;
padding-bottom: 5px;
}
#navigator-toolbox[tabsontop="true"] > #nav-bar:not([iconsize="small"])[mode="icons"][currentset*="unified-back-forward-button"],
#navigator-toolbox[tabsontop="true"] > #nav-bar:not([iconsize="small"])[mode="icons"]:not([currentset]) {
#navigator-toolbox[iconsize="large"][mode="icons"][tabsontop="true"] > #nav-bar[currentset*="unified-back-forward-button"],
#navigator-toolbox[iconsize="large"][mode="icons"][tabsontop="true"] > #nav-bar:not([currentset]) {
padding-top: 5px;
}
#nav-bar:not([iconsize="small"])[mode="icons"] #forward-button {
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button {
/*mask: url(keyhole-forward-mask.svg#mask); XXX: this regresses twinopen */
mask: url(chrome://browser/content/browser.xul#winstripe-keyhole-forward-mask);
-moz-margin-start: -6px;
-moz-margin-start: -6px !important;
padding-left: 7px;
padding-right: 3px;
}
#nav-bar:not([iconsize="small"])[mode="icons"] #forward-button:not([disabled="true"]):not(:active):hover {
#navigator-toolbox[iconsize="large"][mode="icons"] > #nav-bar #forward-button:not([disabled="true"]):not(:active):hover {
/*mask: url(keyhole-forward-mask.svg#mask-hover);*/
mask: url(chrome://browser/content/browser.xul#winstripe-keyhole-forward-mask-hover);
/* Don't animate the box shadow, as the blur and spread radii affect the mask. */
@ -1052,6 +1057,7 @@ toolbar:not([iconsize="small"])[mode="icons"] #back-button {
.searchbar-textbox {
-moz-appearance: none;
margin: 1px 3px;
padding: 2px;
background-clip: padding-box;
border: 1px solid ThreeDDarkShadow;
border-radius: 4px;
@ -1059,22 +1065,6 @@ toolbar:not([iconsize="small"])[mode="icons"] #back-button {
0 1px 0 rgba(255,255,255,.4);
}
.urlbar-textbox-container {
margin-top: 2px;
margin-bottom: 2px;
margin-right: 2px;
}
.urlbar-frontcap {
margin-top: 2px;
margin-bottom: 2px;
margin-left: 2px;
}
.searchbar-textbox {
padding: 2px;
}
@media all and (-moz-windows-default-theme) {
#urlbar,
.searchbar-textbox {
@ -1130,10 +1120,6 @@ html|*.urlbar-input:-moz-lwtheme:-moz-placeholder,
-moz-margin-start: 0;
}
.urlbar-frontcap-and-textbox {
-moz-box-align: stretch;
}
#urlbar-display-box {
margin-top: -2px;
margin-bottom: -2px;
@ -1147,42 +1133,6 @@ html|*.urlbar-input:-moz-lwtheme:-moz-placeholder,
color: GrayText;
}
/* over-link in location bar */
.urlbar-origin-label {
padding-top: 0;
padding-bottom: 0;
-moz-padding-start: 4px;
-moz-padding-end: 0;
margin: 0;
}
.urlbar-over-link-box {
position: relative;
color: GrayText;
min-height: 20px;
padding-top: 0;
padding-bottom: 0;
-moz-padding-start: 18px;
-moz-padding-end: 5px;
}
.urlbar-over-link-box:-moz-locale-dir(ltr) {
background: url(chrome://browser/skin/urlbar-over-link-arrow.png) no-repeat left center;
right: 0;
}
.urlbar-over-link-box:-moz-locale-dir(rtl) {
background: url(chrome://browser/skin/urlbar-over-link-arrow-rtl.png) no-repeat right center;
left: 0;
}
.urlbar-over-link-host-label,
.urlbar-over-link-path-label {
padding: 0;
margin: 0;
}
/* identity box */
#identity-box {
@ -1375,6 +1325,8 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
#urlbar > toolbarbutton {
-moz-appearance: none;
list-style-image: url("chrome://browser/skin/reload-stop-go.png");
margin: -2px;
-moz-margin-start: 0;
padding: 0 3px;
background-origin: border-box;
border: none;
@ -1663,6 +1615,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
/* Tab DnD indicator */
.tab-drop-indicator {
list-style-image: url(chrome://browser/skin/tabbrowser/tabDragIndicator.png);
margin-bottom: -11px;
}
/* Tab close button */
@ -2265,6 +2218,7 @@ panel[dimmed="true"] {
#addon-bar {
min-height: 20px;
border-top: 1px solid ThreeDShadow !important;
}
#addon-bar:not(:-moz-lwtheme) {

Просмотреть файл

@ -3,8 +3,6 @@ browser.jar:
% skin browser classic/1.0 %skin/classic/browser/ os!=WINNT
# NOTE: If you add a new file here, you'll need to add it to the aero
# section at the bottom of this file
skin/classic/browser/urlbar-over-link-arrow.png
skin/classic/browser/urlbar-over-link-arrow-rtl.png
skin/classic/browser/sanitizeDialog.css (sanitizeDialog.css)
* skin/classic/browser/aboutPrivateBrowsing.css (aboutPrivateBrowsing.css)
* skin/classic/browser/aboutSessionRestore.css (aboutSessionRestore.css)
@ -116,8 +114,6 @@ browser.jar:
#ifdef XP_WIN
browser.jar:
% skin browser classic/1.0 %skin/classic/aero/browser/ os=WINNT osversion>=6
skin/classic/aero/browser/urlbar-over-link-arrow.png
skin/classic/aero/browser/urlbar-over-link-arrow-rtl.png
skin/classic/aero/browser/sanitizeDialog.css (sanitizeDialog.css)
* skin/classic/aero/browser/aboutPrivateBrowsing.css (aboutPrivateBrowsing.css)
* skin/classic/aero/browser/aboutSessionRestore.css (aboutSessionRestore.css)

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 3.1 KiB

После

Ширина:  |  Высота:  |  Размер: 3.0 KiB

Просмотреть файл

@ -118,7 +118,8 @@ html[dir=rtl] .expander {
}
.close:hover,
.expander:hover {
.expander:hover,
.appTabIcon:hover {
-moz-transition-property: opacity;
-moz-transition-duration: 0.5s;
-moz-transition-timing-function: ease-out;
@ -262,20 +263,52 @@ html[dir=rtl] .overlay {
box-shadow: -3px 3px 5.5px rgba(0,0,0,.5);
}
.appTabTray {
.appTabTrayContainer {
top: 34px;
right: 1px;
-moz-border-start: 1px solid #E1E1E1;
padding: 0 5px;
overflow-x: hidden;
text-align: start;
line-height: 0;
}
html[dir=rtl] .appTabTray {
html[dir=rtl] .appTabTrayContainer {
right: auto;
left: 1px;
}
.appTabTray {
display: inline-block;
-moz-column-width: 16px;
-moz-column-count: 0;
-moz-column-gap: 5px;
}
.appTabTrayContainerTruncated {
padding-bottom: 7px;
}
.appTabTrayContainerTruncated:after {
content: "…";
position: absolute;
bottom: 2px;
left: 0;
display: block;
width: 100%;
height: 15px;
line-height: 15px;
text-align: center;
font-size: 15px;
}
.appTabIcon {
width: 16px;
height: 16px;
cursor: pointer;
opacity: 0.8;
padding-bottom: 3px;
display: block;
}
.undo {

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 327 B

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 295 B

Просмотреть файл

@ -92,6 +92,7 @@ AC_ARG_WITH(nspr-exec-prefix,
ifelse([$2], , :, [$2])
else
AC_MSG_RESULT(no)
ifelse([$3], , :, [$3])
fi

Просмотреть файл

@ -73,6 +73,7 @@ AC_ARG_WITH(nss-exec-prefix,
ifelse([$2], , :, [$2])
else
AC_MSG_RESULT(no)
ifelse([$3], , :, [$3])
fi

Просмотреть файл

@ -501,7 +501,7 @@ class DeviceManager:
timeslept = 0
while (timeslept <= 30):
process = self.processExist(appname)
if (self.process is not None):
if (process is not None):
break
time.sleep(3)
timeslept += 3
@ -743,14 +743,23 @@ class DeviceManager:
# copy directory structure from device (remoteDir) to host (localDir)
# external function
# checkDir exists so that we don't create local directories if the
# remote directory doesn't exist but also so that we don't call isDir
# twice when recursing.
# returns:
# success: list of files, string
# failure: None
def getDirectory(self, remoteDir, localDir):
def getDirectory(self, remoteDir, localDir, checkDir=True):
if (self.debug >= 2): print "getting files in '" + remoteDir + "'"
if checkDir:
try:
is_dir = self.isDir(remoteDir)
except FileError:
return None
if not is_dir:
return None
filelist = self.listFiles(remoteDir)
if (filelist == []):
return None
if (self.debug >= 3): print filelist
if not os.path.exists(localDir):
os.makedirs(localDir)
@ -766,7 +775,7 @@ class DeviceManager:
print 'isdir failed on file "%s"; continuing anyway...' % remotePath
continue
if is_dir:
if (self.getDirectory(remotePath, localPath) == None):
if (self.getDirectory(remotePath, localPath, False) == None):
print 'failed to get directory "%s"' % remotePath
return None
else:
@ -787,7 +796,10 @@ class DeviceManager:
try:
data = self.verifySendCMD(['isdir ' + remotePath])
except(DMError):
data = None
# normally there should be no error here; a nonexistent file/directory will
# return the string "<filename>: No such file or directory".
# However, I've seen AGENT-WARNING returned before.
return False
retVal = self.stripPrompt(data).strip()
if not retVal:
@ -971,17 +983,31 @@ class DeviceManager:
# returns:
# success: status from test agent
# failure: None
def reboot(self):
def reboot(self, wait = False):
cmd = 'rebt'
if (self.debug > 3): print "INFO: sending rebt command"
if (self.debug >= 3): print "INFO: sending rebt command"
try:
status = self.verifySendCMD([cmd])
status = self.sendCMD([cmd])
except DMError:
return None
if (self.debug > 3): print "INFO: rebt- got status back: " + str(status)
if (wait == True):
#this sleeps up to 5 minutes in 30 second intervals
count = 0
while (count < 10):
if (self.debug >= 4): print "DEBUG: sleeping 30 seconds while waiting for reboot"
time.sleep(30)
waitstatus = self.getDeviceRoot()
if (waitstatus is not None):
break
self.retries = 0
count += 1
if (count >= 10):
return None
if (self.debug >= 3): print "INFO: rebt- got status back: " + str(status)
return status
# validate localDir from host to remoteDir on the device

Просмотреть файл

@ -46,11 +46,13 @@ import os
import sys
import shutil
from datetime import datetime
SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0])))
sys.path.insert(0, SCRIPT_DIR)
from automation import Automation
from automationutils import getDebuggerInfo, addCommonOptions
PORT = 8888
SCRIPT_DIR = os.path.abspath(os.path.realpath(os.path.dirname(sys.argv[0])))
PROFILE_DIRECTORY = os.path.abspath(os.path.join(SCRIPT_DIR, "./pgoprofile"))
MOZ_JAR_LOG_DIR = os.path.abspath(os.path.join(os.path.join(os.getenv("OBJDIR"), "dist"), "jarlog"))
os.chdir(SCRIPT_DIR)

Просмотреть файл

@ -107,11 +107,12 @@ inject/%.c: inject.c | inject
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))
include $(topsrcdir)/config/rules.mk
inject/%.$(OBJ_SUFFIX): DEFINES += -DBITS=$(if $(HAVE_64BIT_OS),64,32)
inject/%.$(OBJ_SUFFIX): CFLAGS := -O2 -fno-stack-protector $(filter -m% -I%,$(CFLAGS))
inject/$(CPU)-noinit.$(OBJ_SUFFIX): DEFINES += -DNOINIT

Просмотреть файл

@ -551,7 +551,7 @@ MOZ_GTK2_LIBS = @MOZ_GTK2_LIBS@
MOZ_QT_CFLAGS = @MOZ_QT_CFLAGS@
MOZ_QT_LIBS = @MOZ_QT_LIBS@
MOZ_ENABLE_QTNETWORK = @MOZ_ENABLE_QTNETWORK@
MOZ_ENABLE_MEEGOTOUCH = @MOZ_ENABLE_MEEGOTOUCH@
MOZ_ENABLE_CONTENTACTION = @MOZ_ENABLE_CONTENTACTION@
MOZ_ENABLE_MEEGOTOUCHSHARE = @MOZ_ENABLE_MEEGOTOUCHSHARE@
MOZ_DBUS_CFLAGS = @MOZ_DBUS_CFLAGS@

Просмотреть файл

@ -10,4 +10,4 @@
# hardcoded milestones in the tree from these two files.
#--------------------------------------------------------
2.0b11pre
2.0b12pre

Просмотреть файл

@ -2521,7 +2521,13 @@ ia64*-hpux*)
if test $_MSC_VER -ge 1400; then
LDFLAGS="$LDFLAGS -SAFESEH"
fi
AC_CHECK_HEADERS(mmintrin.h)
if test -n "$GNU_CC"; then
CFLAGS="$CFLAGS -mstackrealign"
CXXFLAGS="$CXXFLAGS -mstackrealign"
fi
AC_CHECK_HEADERS(mmintrin.h)
AC_DEFINE(_X86_)
;;
alpha-*)
@ -4617,7 +4623,7 @@ MOZ_ARG_WITH_BOOL(system-nspr,
_USE_SYSTEM_NSPR=1 )
if test -n "$_USE_SYSTEM_NSPR"; then
AM_PATH_NSPR(4.8.7, [MOZ_NATIVE_NSPR=1], [MOZ_NATIVE_NSPR=])
AM_PATH_NSPR(4.8.7, [MOZ_NATIVE_NSPR=1], [AC_MSG_ERROR([your don't have NSPR installed or your version is too old])])
fi
if test -n "$MOZ_NATIVE_NSPR"; then
@ -4694,7 +4700,7 @@ MOZ_ARG_WITH_BOOL(system-nss,
_USE_SYSTEM_NSS=1 )
if test -n "$_USE_SYSTEM_NSS"; then
AM_PATH_NSS(3.12.9, [MOZ_NATIVE_NSS=1], [MOZ_NATIVE_NSS=])
AM_PATH_NSS(3.12.9, [MOZ_NATIVE_NSS=1], [AC_MSG_ERROR([you don't have NSS installed or your version is too old])])
fi
if test -n "$MOZ_NATIVE_NSS"; then
@ -5420,7 +5426,6 @@ AC_SUBST(MOZ_GTK2_CFLAGS)
AC_SUBST(MOZ_GTK2_LIBS)
AC_SUBST(MOZ_QT_CFLAGS)
AC_SUBST(MOZ_QT_LIBS)
AC_SUBST(MOZ_ENABLE_MEEGOTOUCH)
AC_SUBST(MOC)
@ -7092,19 +7097,27 @@ if test $MOZ_PLATFORM_MAEMO; then
fi
if test $MOZ_PLATFORM_MAEMO = 6; then
PKG_CHECK_MODULES(LIBCONTENTACTION, contentaction-0.1, _LIB_FOUND=1, _LIB_FOUND=)
MOZ_PLATFORM_MAEMO_LIBS="$MOZ_PLATFORM_MAEMO_LIBS $LIBCONTENTACTION_LIBS"
MOZ_PLATFORM_MAEMO_CFLAGS="$MOZ_PLATFORM_MAEMO_CFLAGS $LIBCONTENTACTION_CFLAGS"
if test -z "$_LIB_FOUND"; then
AC_MSG_ERROR([libcontentaction is required when build for Maemo])
dnl ========================================================
dnl = Enable meego libcontentaction
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(meegocontentaction,
[ --enable-meegocontentaction Enable meegocontentaction support],
MOZ_MEEGOCONTENTACTION=1,
MOZ_MEEGOCONTENTACTION=)
if test -n "$MOZ_MEEGOCONTENTACTION"; then
PKG_CHECK_MODULES(LIBCONTENTACTION, contentaction-0.1, _LIB_FOUND=1, _LIB_FOUND=)
if test "$_LIB_FOUND"; then
MOZ_PLATFORM_MAEMO_LIBS="$MOZ_PLATFORM_MAEMO_LIBS $LIBCONTENTACTION_LIBS"
MOZ_PLATFORM_MAEMO_CFLAGS="$MOZ_PLATFORM_MAEMO_CFLAGS $LIBCONTENTACTION_CFLAGS"
MOZ_ENABLE_CONTENTACTION=1
AC_DEFINE(MOZ_ENABLE_CONTENTACTION)
AC_SUBST(MOZ_ENABLE_CONTENTACTION)
fi
fi
MOZ_THUMB2=1
PKG_CHECK_MODULES(MOZ_MEEGOTOUCH, meegotouchcore)
MOZ_ENABLE_MEEGOTOUCH=1
AC_DEFINE(MOZ_ENABLE_MEEGOTOUCH)
MOZ_QT_CFLAGS="$MOZ_MEEGOTOUCH_CFLAGS $MOZ_QT_CFLAGS"
MOZ_QT_LIBS="$MOZ_MEEGOTOUCH_LIBS $MOZ_QT_LIBS"
MOZ_THUMB2=1
fi
PKG_CHECK_MODULES(LIBLOCATION,liblocation, _LIB_FOUND=1, _LIB_FOUND=)

Просмотреть файл

@ -0,0 +1,8 @@
<!DOCTYPE html>
<script>
var inputElem = document.createElementNS("http://www.w3.org/1999/xhtml", "input");
inputElem.QueryInterface(Components.interfaces.imgIDecoderObserver);
inputElem.onStartDecode(null);
</script>

Просмотреть файл

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html>
<head>
<script>
var w;
function b1()
{
w = window.open("404.gif", "w2", "f");
setTimeout(b2, 1200);
}
function b2()
{
w.close();
setTimeout(b3, 500);
}
function b3()
{
w.location = "data:text/html,2";
document.body.appendChild(document.createTextNode("Done"));
}
</script>
</head>
<body>
<div><button onclick="b1();">Start test</button></div>
</body>
</html>

Просмотреть файл

@ -84,3 +84,5 @@ load 606729-1.html
load 593302-1.html
load 593302-2.html
load 610571-1.html
load 604262-1.html
load 628599-1.html

Просмотреть файл

@ -91,4 +91,30 @@ public:
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentUtils2, NS_ICONTENTUTILS2_IID)
#ifndef MOZ_ENABLE_LIBXUL
// nsIContentUtils_MOZILLA_2_0_BRANCH is a non-libxul only interface to enable
// us keep those builds working.
#define NS_ICONTENTUTILS_MOZILLA_2_0_BRANCH_IID \
{ 0x0fe8099c, 0x622a, 0x4c79, \
{ 0xb0, 0x02, 0x55, 0xf0, 0x44, 0x34, 0x00, 0x30 } }
class nsIContentUtils_MOZILLA_2_0_BRANCH : public nsISupports
{
public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_ICONTENTURILS_MOZILLA_2_0_BRANCH_IID)
NS_DECL_ISUPPORTS
virtual nsresult DispatchTrustedEvent(nsIDocument* aDoc,
nsISupports* aTarget,
const nsAString& aEventName,
PRBool aCanBubble,
PRBool aCancelable,
PRBool *aDefaultAction = nsnull);
};
NS_DEFINE_STATIC_IID_ACCESSOR(nsIContentUtils_MOZILLA_2_0_BRANCH, NS_ICONTENTUTILS_MOZILLA_2_0_BRANCH_IID)
#endif
#endif /* nsIContentUtils_h__ */

Просмотреть файл

@ -64,9 +64,11 @@ interface nsIChannel;
/**
* The nsISyncDOMLoadService interface can be used to synchronously load
* a document.
*
* @deprecated use XMLHttpRequest instead
*/
[scriptable, uuid(8095998d-ae1c-4cfa-9b43-0973e5d77eb0)]
[deprecated, scriptable, uuid(8095998d-ae1c-4cfa-9b43-0973e5d77eb0)]
interface nsISyncLoadDOMService : nsISupports
{
/**

Просмотреть файл

@ -391,9 +391,9 @@ interface nsIXHRSendable : nsISupports {
};
/**
* DEPRECATED.
* @deprecated
*/
[scriptable, uuid(423fdd3d-41c9-4149-8fe5-b14a1d3912a0)]
[deprecated, scriptable, uuid(423fdd3d-41c9-4149-8fe5-b14a1d3912a0)]
interface nsIJSXMLHttpRequest : nsISupports {
/**
* Meant to be a script-only mechanism for setting an upload progress event

Просмотреть файл

@ -1054,8 +1054,7 @@ nsAttrValue::ParseEnumValue(const nsAString& aValue,
}
PRBool
nsAttrValue::ParseSpecialIntValue(const nsAString& aString,
PRBool aCanBePercent)
nsAttrValue::ParseSpecialIntValue(const nsAString& aString)
{
ResetIfSet();
@ -1063,7 +1062,7 @@ nsAttrValue::ParseSpecialIntValue(const nsAString& aString,
PRBool strict;
PRBool isPercent = PR_FALSE;
nsAutoString tmp(aString);
PRInt32 originalVal = StringToInteger(aString, &strict, &ec, aCanBePercent, &isPercent);
PRInt32 originalVal = StringToInteger(aString, &strict, &ec, PR_TRUE, &isPercent);
if (NS_FAILED(ec)) {
return PR_FALSE;
@ -1072,7 +1071,7 @@ nsAttrValue::ParseSpecialIntValue(const nsAString& aString,
PRInt32 val = NS_MAX(originalVal, 0);
// % (percent)
if (aCanBePercent && (isPercent || tmp.RFindChar('%') >= 0)) {
if (isPercent || tmp.RFindChar('%') >= 0) {
isPercent = PR_TRUE;
}

Просмотреть файл

@ -229,13 +229,11 @@ public:
* whether it be percent or raw integer.
*
* @param aString the string to parse
* @param aCanBePercent PR_TRUE if it can be a percent value (%)
* @return whether the value could be parsed
*
* @see http://www.whatwg.org/html/#rules-for-parsing-dimension-values
*/
PRBool ParseSpecialIntValue(const nsAString& aString,
PRBool aCanBePercent);
PRBool ParseSpecialIntValue(const nsAString& aString);
/**

Просмотреть файл

@ -524,9 +524,6 @@ nsContentSink::ProcessHeaderData(nsIAtom* aHeader, const nsAString& aValue,
return rv;
}
}
else if (aHeader == nsGkAtoms::link) {
rv = ProcessLinkHeader(aContent, aValue);
}
else if (aHeader == nsGkAtoms::msthemecompatible) {
// Disable theming for the presshell if the value is no.
// XXXbz don't we want to support this as an HTTP header too?

Просмотреть файл

@ -6504,3 +6504,21 @@ nsIContentUtils2::CheckSameOrigin(nsIChannel *aOldChannel, nsIChannel *aNewChann
{
return nsContentUtils::CheckSameOrigin(aOldChannel, aNewChannel);
}
#ifndef MOZ_ENABLE_LIBXUL
NS_IMPL_ISUPPORTS1(nsIContentUtils_MOZILLA_2_0_BRANCH, nsIContentUtils_MOZILLA_2_0_BRANCH)
nsresult
nsIContentUtils_MOZILLA_2_0_BRANCH::DispatchTrustedEvent(nsIDocument* aDoc,
nsISupports* aTarget,
const nsAString& aEventName,
PRBool aCanBubble,
PRBool aCancelable,
PRBool *aDefaultAction)
{
return nsContentUtils::DispatchTrustedEvent(aDoc, aTarget, aEventName,
aCanBubble, aCancelable, aDefaultAction);
}
#endif

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше