Merge mozilla-central and tracemonkey. (a=blockers)
|
@ -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);
|
||||
|
|
Двоичные данные
browser/base/content/aboutHome-restore-icon-rtl.png
До Ширина: | Высота: | Размер: 4.5 KiB |
После Ширина: | Высота: | Размер: 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 O’Shannessy <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 |
Двоичные данные
browser/themes/gnomestripe/browser/urlbar-over-link-arrow.png
До Ширина: | Высота: | Размер: 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 {
|
||||
|
|
Двоичные данные
browser/themes/pinstripe/browser/urlbar-over-link-arrow-rtl.png
До Ширина: | Высота: | Размер: 327 B |
Двоичные данные
browser/themes/pinstripe/browser/urlbar-over-link-arrow.png
До Ширина: | Высота: | Размер: 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)
|
||||
|
|
Двоичные данные
browser/themes/winstripe/browser/tabbrowser/tabDragIndicator.png
До Ширина: | Высота: | Размер: 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 {
|
||||
|
|
Двоичные данные
browser/themes/winstripe/browser/urlbar-over-link-arrow-rtl.png
До Ширина: | Высота: | Размер: 327 B |
Двоичные данные
browser/themes/winstripe/browser/urlbar-over-link-arrow.png
До Ширина: | Высота: | Размер: 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
|
||||
|
|
45
configure.in
|
@ -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
|
||||
|
|