зеркало из https://github.com/mozilla/gecko-dev.git
Merge TM -> JM
This commit is contained in:
Коммит
43722431f8
|
@ -718,20 +718,18 @@ const gchar *
|
||||||
getDescriptionCB(AtkObject *aAtkObj)
|
getDescriptionCB(AtkObject *aAtkObj)
|
||||||
{
|
{
|
||||||
nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
|
nsAccessibleWrap *accWrap = GetAccessibleWrap(aAtkObj);
|
||||||
if (!accWrap) {
|
if (!accWrap || accWrap->IsDefunct())
|
||||||
return nsnull;
|
return nsnull;
|
||||||
}
|
|
||||||
|
|
||||||
/* nsIAccessible is responsible for the non-NULL description */
|
/* nsIAccessible is responsible for the non-NULL description */
|
||||||
nsAutoString uniDesc;
|
nsAutoString uniDesc;
|
||||||
nsresult rv = accWrap->GetDescription(uniDesc);
|
accWrap->Description(uniDesc);
|
||||||
NS_ENSURE_SUCCESS(rv, nsnull);
|
|
||||||
|
|
||||||
NS_ConvertUTF8toUTF16 objDesc(aAtkObj->description);
|
NS_ConvertUTF8toUTF16 objDesc(aAtkObj->description);
|
||||||
if (!uniDesc.Equals(objDesc)) {
|
if (!uniDesc.Equals(objDesc))
|
||||||
atk_object_set_description(aAtkObj,
|
atk_object_set_description(aAtkObj,
|
||||||
NS_ConvertUTF16toUTF8(uniDesc).get());
|
NS_ConvertUTF16toUTF8(uniDesc).get());
|
||||||
}
|
|
||||||
return aAtkObj->description;
|
return aAtkObj->description;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -197,10 +197,10 @@ nsAccessible::nsAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
|
||||||
(void*)shell.get());
|
(void*)shell.get());
|
||||||
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
|
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
|
||||||
if (content) {
|
if (content) {
|
||||||
|
printf(" Con: %s@%p",
|
||||||
|
NS_ConvertUTF16toUTF8(content->NodeInfo()->QualifiedName()).get(),
|
||||||
|
(void *)content.get());
|
||||||
nsAutoString buf;
|
nsAutoString buf;
|
||||||
if (content->NodeInfo())
|
|
||||||
content->NodeInfo()->GetQualifiedName(buf);
|
|
||||||
printf(" Con: %s@%p", NS_ConvertUTF16toUTF8(buf).get(), (void *)content.get());
|
|
||||||
if (NS_SUCCEEDED(GetName(buf))) {
|
if (NS_SUCCEEDED(GetName(buf))) {
|
||||||
printf(" Name:[%s]", NS_ConvertUTF16toUTF8(buf).get());
|
printf(" Name:[%s]", NS_ConvertUTF16toUTF8(buf).get());
|
||||||
}
|
}
|
||||||
|
@ -272,54 +272,60 @@ nsAccessible::GetName(nsAString& aName)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsAccessible::GetDescription(nsAString& aDescription)
|
NS_IMETHODIMP
|
||||||
|
nsAccessible::GetDescription(nsAString& aDescription)
|
||||||
{
|
{
|
||||||
if (IsDefunct())
|
if (IsDefunct())
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
|
|
||||||
|
nsAutoString desc;
|
||||||
|
Description(desc);
|
||||||
|
aDescription.Assign(desc);
|
||||||
|
|
||||||
|
return NS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
nsAccessible::Description(nsString& aDescription)
|
||||||
|
{
|
||||||
// There are 4 conditions that make an accessible have no accDescription:
|
// There are 4 conditions that make an accessible have no accDescription:
|
||||||
// 1. it's a text node; or
|
// 1. it's a text node; or
|
||||||
// 2. It has no DHTML describedby property
|
// 2. It has no DHTML describedby property
|
||||||
// 3. it doesn't have an accName; or
|
// 3. it doesn't have an accName; or
|
||||||
// 4. its title attribute already equals to its accName nsAutoString name;
|
// 4. its title attribute already equals to its accName nsAutoString name;
|
||||||
|
|
||||||
if (!mContent->IsNodeOfType(nsINode::eTEXT)) {
|
if (mContent->IsNodeOfType(nsINode::eTEXT))
|
||||||
nsAutoString description;
|
return;
|
||||||
nsresult rv = nsTextEquivUtils::
|
|
||||||
GetTextEquivFromIDRefs(this, nsAccessibilityAtoms::aria_describedby,
|
|
||||||
description);
|
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
|
||||||
|
|
||||||
if (description.IsEmpty()) {
|
nsTextEquivUtils::
|
||||||
PRBool isXUL = mContent->IsXUL();
|
GetTextEquivFromIDRefs(this, nsAccessibilityAtoms::aria_describedby,
|
||||||
if (isXUL) {
|
aDescription);
|
||||||
// Try XUL <description control="[id]">description text</description>
|
|
||||||
XULDescriptionIterator iter(GetDocAccessible(), mContent);
|
if (aDescription.IsEmpty()) {
|
||||||
nsAccessible* descr = nsnull;
|
PRBool isXUL = mContent->IsXUL();
|
||||||
while ((descr = iter.Next())) {
|
if (isXUL) {
|
||||||
nsTextEquivUtils::
|
// Try XUL <description control="[id]">description text</description>
|
||||||
AppendTextEquivFromContent(this, descr->GetContent(), &description);
|
XULDescriptionIterator iter(GetDocAccessible(), mContent);
|
||||||
}
|
nsAccessible* descr = nsnull;
|
||||||
|
while ((descr = iter.Next()))
|
||||||
|
nsTextEquivUtils::AppendTextEquivFromContent(this, descr->GetContent(),
|
||||||
|
&aDescription);
|
||||||
}
|
}
|
||||||
if (description.IsEmpty()) {
|
|
||||||
|
if (aDescription.IsEmpty()) {
|
||||||
nsIAtom *descAtom = isXUL ? nsAccessibilityAtoms::tooltiptext :
|
nsIAtom *descAtom = isXUL ? nsAccessibilityAtoms::tooltiptext :
|
||||||
nsAccessibilityAtoms::title;
|
nsAccessibilityAtoms::title;
|
||||||
if (mContent->GetAttr(kNameSpaceID_None, descAtom, description)) {
|
if (mContent->GetAttr(kNameSpaceID_None, descAtom, aDescription)) {
|
||||||
nsAutoString name;
|
nsAutoString name;
|
||||||
GetName(name);
|
GetName(name);
|
||||||
if (name.IsEmpty() || description == name) {
|
if (name.IsEmpty() || aDescription == name)
|
||||||
// Don't use tooltip for a description if this object
|
// Don't use tooltip for a description if this object
|
||||||
// has no name or the tooltip is the same as the name
|
// has no name or the tooltip is the same as the name
|
||||||
description.Truncate();
|
aDescription.Truncate();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
description.CompressWhitespace();
|
aDescription.CompressWhitespace();
|
||||||
aDescription = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// mask values for ui.key.chromeAccess and ui.key.contentAccess
|
// mask values for ui.key.chromeAccess and ui.key.contentAccess
|
||||||
|
|
|
@ -119,6 +119,11 @@ public:
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
// Public methods
|
// Public methods
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get the description of this accessible
|
||||||
|
*/
|
||||||
|
virtual void Description(nsString& aDescription);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the accessible name specified by ARIA.
|
* Returns the accessible name specified by ARIA.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -127,11 +127,10 @@ nsApplicationAccessible::GetValue(nsAString &aValue)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
void
|
||||||
nsApplicationAccessible::GetDescription(nsAString &aDescription)
|
nsApplicationAccessible::Description(nsString &aDescription)
|
||||||
{
|
{
|
||||||
aDescription.Truncate();
|
aDescription.Truncate();
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
|
@ -92,7 +92,6 @@ public:
|
||||||
NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
|
NS_IMETHOD GetPreviousSibling(nsIAccessible **aPreviousSibling);
|
||||||
NS_IMETHOD GetName(nsAString &aName);
|
NS_IMETHOD GetName(nsAString &aName);
|
||||||
NS_IMETHOD GetValue(nsAString &aValue);
|
NS_IMETHOD GetValue(nsAString &aValue);
|
||||||
NS_IMETHOD GetDescription(nsAString &aDescription);
|
|
||||||
NS_IMETHOD GetKeyboardShortcut(nsAString &aKeyboardShortcut);
|
NS_IMETHOD GetKeyboardShortcut(nsAString &aKeyboardShortcut);
|
||||||
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
|
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
|
||||||
NS_IMETHOD GroupPosition(PRInt32 *aGroupLevel, PRInt32 *aSimilarItemsInGroup,
|
NS_IMETHOD GroupPosition(PRInt32 *aGroupLevel, PRInt32 *aSimilarItemsInGroup,
|
||||||
|
@ -123,6 +122,7 @@ public:
|
||||||
|
|
||||||
// nsAccessible
|
// nsAccessible
|
||||||
virtual void ApplyARIAState(PRUint64* aState);
|
virtual void ApplyARIAState(PRUint64* aState);
|
||||||
|
virtual void Description(nsString& aDescription);
|
||||||
virtual PRUint32 NativeRole();
|
virtual PRUint32 NativeRole();
|
||||||
virtual PRUint64 State();
|
virtual PRUint64 State();
|
||||||
virtual PRUint64 NativeState();
|
virtual PRUint64 NativeState();
|
||||||
|
|
|
@ -273,21 +273,16 @@ nsDocAccessible::SetRoleMapEntry(nsRoleMapEntry* aRoleMapEntry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
void
|
||||||
nsDocAccessible::GetDescription(nsAString& aDescription)
|
nsDocAccessible::Description(nsString& aDescription)
|
||||||
{
|
{
|
||||||
if (mParent)
|
if (mParent)
|
||||||
mParent->GetDescription(aDescription);
|
mParent->Description(aDescription);
|
||||||
|
|
||||||
if (aDescription.IsEmpty()) {
|
if (aDescription.IsEmpty())
|
||||||
nsAutoString description;
|
|
||||||
nsTextEquivUtils::
|
nsTextEquivUtils::
|
||||||
GetTextEquivFromIDRefs(this, nsAccessibilityAtoms::aria_describedby,
|
GetTextEquivFromIDRefs(this, nsAccessibilityAtoms::aria_describedby,
|
||||||
description);
|
aDescription);
|
||||||
aDescription = description;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// nsAccessible public method
|
// nsAccessible public method
|
||||||
|
|
|
@ -93,7 +93,6 @@ public:
|
||||||
|
|
||||||
// nsIAccessible
|
// nsIAccessible
|
||||||
NS_IMETHOD GetName(nsAString& aName);
|
NS_IMETHOD GetName(nsAString& aName);
|
||||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
|
||||||
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
|
NS_IMETHOD GetAttributes(nsIPersistentProperties **aAttributes);
|
||||||
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
|
NS_IMETHOD GetFocusedChild(nsIAccessible **aFocusedChild);
|
||||||
NS_IMETHOD TakeFocus(void);
|
NS_IMETHOD TakeFocus(void);
|
||||||
|
@ -114,6 +113,7 @@ public:
|
||||||
virtual nsIDocument* GetDocumentNode() const { return mDocument; }
|
virtual nsIDocument* GetDocumentNode() const { return mDocument; }
|
||||||
|
|
||||||
// nsAccessible
|
// nsAccessible
|
||||||
|
virtual void Description(nsString& aDescription);
|
||||||
virtual PRUint32 NativeRole();
|
virtual PRUint32 NativeRole();
|
||||||
virtual PRUint64 NativeState();
|
virtual PRUint64 NativeState();
|
||||||
virtual void ApplyARIAState(PRUint64* aState);
|
virtual void ApplyARIAState(PRUint64* aState);
|
||||||
|
|
|
@ -264,7 +264,7 @@ nsresult nsRootAccessible::AddEventListeners()
|
||||||
* const* e_end = docEvents + NS_ARRAY_LENGTH(docEvents);
|
* const* e_end = docEvents + NS_ARRAY_LENGTH(docEvents);
|
||||||
e < e_end; ++e) {
|
e < e_end; ++e) {
|
||||||
nsresult rv = nstarget->AddEventListener(NS_ConvertASCIItoUTF16(*e),
|
nsresult rv = nstarget->AddEventListener(NS_ConvertASCIItoUTF16(*e),
|
||||||
this, PR_TRUE, PR_TRUE, 1);
|
this, PR_TRUE, PR_TRUE, 2);
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -168,8 +168,8 @@ nsHTMLAreaAccessible::GetNameInternal(nsAString & aName)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
void
|
||||||
nsHTMLAreaAccessible::GetDescription(nsAString& aDescription)
|
nsHTMLAreaAccessible::Description(nsString& aDescription)
|
||||||
{
|
{
|
||||||
aDescription.Truncate();
|
aDescription.Truncate();
|
||||||
|
|
||||||
|
@ -177,8 +177,6 @@ nsHTMLAreaAccessible::GetDescription(nsAString& aDescription)
|
||||||
nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(mContent));
|
nsCOMPtr<nsIDOMHTMLAreaElement> area(do_QueryInterface(mContent));
|
||||||
if (area)
|
if (area)
|
||||||
area->GetShape(aDescription);
|
area->GetShape(aDescription);
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
|
|
|
@ -87,11 +87,11 @@ public:
|
||||||
nsHTMLAreaAccessible(nsIContent *aContent, nsIWeakReference *aShell);
|
nsHTMLAreaAccessible(nsIContent *aContent, nsIWeakReference *aShell);
|
||||||
|
|
||||||
// nsIAccessible
|
// nsIAccessible
|
||||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
|
||||||
|
|
||||||
NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
|
NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
|
||||||
|
|
||||||
// nsAccessible
|
// nsAccessible
|
||||||
|
virtual void Description(nsString& aDescription);
|
||||||
virtual nsresult GetNameInternal(nsAString& aName);
|
virtual nsresult GetNameInternal(nsAString& aName);
|
||||||
virtual PRUint64 NativeState();
|
virtual PRUint64 NativeState();
|
||||||
virtual nsAccessible* GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
virtual nsAccessible* GetChildAtPoint(PRInt32 aX, PRInt32 aY,
|
||||||
|
|
|
@ -727,18 +727,19 @@ nsHTMLComboboxAccessible::NativeState()
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsHTMLComboboxAccessible::GetDescription(nsAString& aDescription)
|
void
|
||||||
|
nsHTMLComboboxAccessible::Description(nsString& aDescription)
|
||||||
{
|
{
|
||||||
aDescription.Truncate();
|
aDescription.Truncate();
|
||||||
// First check to see if combo box itself has a description, perhaps through
|
// First check to see if combo box itself has a description, perhaps through
|
||||||
// tooltip (title attribute) or via aria-describedby
|
// tooltip (title attribute) or via aria-describedby
|
||||||
nsAccessible::GetDescription(aDescription);
|
nsAccessible::Description(aDescription);
|
||||||
if (!aDescription.IsEmpty()) {
|
if (!aDescription.IsEmpty())
|
||||||
return NS_OK;
|
return;
|
||||||
}
|
|
||||||
// Use description of currently focused option
|
// Use description of currently focused option
|
||||||
nsAccessible *option = GetFocusedOptionAccessible();
|
nsAccessible *option = GetFocusedOptionAccessible();
|
||||||
return option ? option->GetDescription(aDescription) : NS_OK;
|
if (option)
|
||||||
|
option->Description(aDescription);
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAccessible *
|
nsAccessible *
|
||||||
|
|
|
@ -184,7 +184,6 @@ public:
|
||||||
|
|
||||||
// nsIAccessible
|
// nsIAccessible
|
||||||
NS_IMETHOD GetValue(nsAString& _retval);
|
NS_IMETHOD GetValue(nsAString& _retval);
|
||||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
|
||||||
NS_IMETHOD DoAction(PRUint8 index);
|
NS_IMETHOD DoAction(PRUint8 index);
|
||||||
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
|
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
|
||||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||||
|
@ -193,6 +192,7 @@ public:
|
||||||
virtual void Shutdown();
|
virtual void Shutdown();
|
||||||
|
|
||||||
// nsAccessible
|
// nsAccessible
|
||||||
|
virtual void Description(nsString& aDescription);
|
||||||
virtual PRUint32 NativeRole();
|
virtual PRUint32 NativeRole();
|
||||||
virtual PRUint64 NativeState();
|
virtual PRUint64 NativeState();
|
||||||
virtual void InvalidateChildren();
|
virtual void InvalidateChildren();
|
||||||
|
|
|
@ -1260,14 +1260,14 @@ nsHTMLTableAccessible::GetCellAt(PRInt32 aRowIndex,
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsHTMLTableAccessible::GetDescription(nsAString& aDescription)
|
void
|
||||||
|
nsHTMLTableAccessible::Description(nsString& aDescription)
|
||||||
{
|
{
|
||||||
// Helpful for debugging layout vs. data tables
|
// Helpful for debugging layout vs. data tables
|
||||||
aDescription.Truncate();
|
aDescription.Truncate();
|
||||||
nsAccessible::GetDescription(aDescription);
|
nsAccessible::Description(aDescription);
|
||||||
if (!aDescription.IsEmpty()) {
|
if (!aDescription.IsEmpty())
|
||||||
return NS_OK;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
nsCOMPtr<nsIAccessible> captionAccessible;
|
nsCOMPtr<nsIAccessible> captionAccessible;
|
||||||
GetCaption(getter_AddRefs(captionAccessible));
|
GetCaption(getter_AddRefs(captionAccessible));
|
||||||
|
@ -1276,10 +1276,9 @@ NS_IMETHODIMP nsHTMLTableAccessible::GetDescription(nsAString& aDescription)
|
||||||
nsCOMPtr<nsIDOMNode> captionNode;
|
nsCOMPtr<nsIDOMNode> captionNode;
|
||||||
captionAccessNode->GetDOMNode(getter_AddRefs(captionNode));
|
captionAccessNode->GetDOMNode(getter_AddRefs(captionNode));
|
||||||
nsCOMPtr<nsIContent> captionContent = do_QueryInterface(captionNode);
|
nsCOMPtr<nsIContent> captionContent = do_QueryInterface(captionNode);
|
||||||
if (captionContent) {
|
if (captionContent)
|
||||||
nsTextEquivUtils::
|
nsTextEquivUtils::AppendTextEquivFromContent(this, captionContent,
|
||||||
AppendTextEquivFromContent(this, captionContent, &aDescription);
|
&aDescription);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#ifdef SHOW_LAYOUT_HEURISTIC
|
#ifdef SHOW_LAYOUT_HEURISTIC
|
||||||
if (aDescription.IsEmpty()) {
|
if (aDescription.IsEmpty()) {
|
||||||
|
@ -1291,8 +1290,6 @@ NS_IMETHODIMP nsHTMLTableAccessible::GetDescription(nsAString& aDescription)
|
||||||
printf("\nTABLE: %s\n", NS_ConvertUTF16toUTF8(mLayoutHeuristic).get());
|
printf("\nTABLE: %s\n", NS_ConvertUTF16toUTF8(mLayoutHeuristic).get());
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
|
|
|
@ -131,11 +131,11 @@ public:
|
||||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_TABLEACCESSIBLE_IMPL_CID)
|
NS_DECLARE_STATIC_IID_ACCESSOR(NS_TABLEACCESSIBLE_IMPL_CID)
|
||||||
|
|
||||||
// nsIAccessible
|
// nsIAccessible
|
||||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
|
||||||
NS_IMETHOD GetRelationByType(PRUint32 aRelationType,
|
NS_IMETHOD GetRelationByType(PRUint32 aRelationType,
|
||||||
nsIAccessibleRelation **aRelation);
|
nsIAccessibleRelation **aRelation);
|
||||||
|
|
||||||
// nsAccessible
|
// nsAccessible
|
||||||
|
virtual void Description(nsString& aDescription);
|
||||||
virtual nsresult GetNameInternal(nsAString& aName);
|
virtual nsresult GetNameInternal(nsAString& aName);
|
||||||
virtual PRUint32 NativeRole();
|
virtual PRUint32 NativeRole();
|
||||||
virtual PRUint64 NativeState();
|
virtual PRUint64 NativeState();
|
||||||
|
|
|
@ -518,8 +518,11 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
||||||
{
|
{
|
||||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||||
|
|
||||||
|
if (mGeckoAccessible->IsDefunct())
|
||||||
|
return nil;
|
||||||
|
|
||||||
nsAutoString desc;
|
nsAutoString desc;
|
||||||
mGeckoAccessible->GetDescription (desc);
|
mGeckoAccessible->Description(desc);
|
||||||
return desc.IsEmpty() ? nil : [NSString stringWithCharacters:desc.BeginReading() length:desc.Length()];
|
return desc.IsEmpty() ? nil : [NSString stringWithCharacters:desc.BeginReading() length:desc.Length()];
|
||||||
|
|
||||||
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
NS_OBJC_END_TRY_ABORT_BLOCK_NIL;
|
||||||
|
|
|
@ -333,11 +333,11 @@ __try {
|
||||||
*pszDescription = NULL;
|
*pszDescription = NULL;
|
||||||
|
|
||||||
nsAccessible *xpAccessible = GetXPAccessibleFor(varChild);
|
nsAccessible *xpAccessible = GetXPAccessibleFor(varChild);
|
||||||
if (!xpAccessible)
|
if (!xpAccessible || xpAccessible->IsDefunct())
|
||||||
return E_FAIL;
|
return E_FAIL;
|
||||||
|
|
||||||
nsAutoString description;
|
nsAutoString description;
|
||||||
xpAccessible->GetDescription(description);
|
xpAccessible->Description(description);
|
||||||
|
|
||||||
*pszDescription = ::SysAllocStringLen(description.get(),
|
*pszDescription = ::SysAllocStringLen(description.get(),
|
||||||
description.Length());
|
description.Length());
|
||||||
|
|
|
@ -197,21 +197,15 @@ nsXFormsAccessible::GetNameInternal(nsAString& aName)
|
||||||
return GetBoundChildElementValue(NS_LITERAL_STRING("label"), aName);
|
return GetBoundChildElementValue(NS_LITERAL_STRING("label"), aName);
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
void
|
||||||
nsXFormsAccessible::GetDescription(nsAString& aDescription)
|
nsXFormsAccessible::Description(nsString& aDescription)
|
||||||
{
|
{
|
||||||
nsAutoString description;
|
nsTextEquivUtils::
|
||||||
nsresult rv = nsTextEquivUtils::
|
|
||||||
GetTextEquivFromIDRefs(this, nsAccessibilityAtoms::aria_describedby,
|
GetTextEquivFromIDRefs(this, nsAccessibilityAtoms::aria_describedby,
|
||||||
description);
|
aDescription);
|
||||||
|
|
||||||
if (NS_SUCCEEDED(rv) && !description.IsEmpty()) {
|
if (aDescription.IsEmpty())
|
||||||
aDescription = description;
|
GetBoundChildElementValue(NS_LITERAL_STRING("hint"), aDescription);
|
||||||
return NS_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
// search the xforms:hint element
|
|
||||||
return GetBoundChildElementValue(NS_LITERAL_STRING("hint"), aDescription);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
|
|
|
@ -77,10 +77,9 @@ public:
|
||||||
// Returns value of instance node that xforms element is bound to.
|
// Returns value of instance node that xforms element is bound to.
|
||||||
NS_IMETHOD GetValue(nsAString& aValue);
|
NS_IMETHOD GetValue(nsAString& aValue);
|
||||||
|
|
||||||
// Returns value of child xforms 'hint' element.
|
|
||||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
|
||||||
|
|
||||||
// nsAccessible
|
// nsAccessible
|
||||||
|
// Returns value of child xforms 'hint' element.
|
||||||
|
virtual void Description(nsString& aDescription);
|
||||||
|
|
||||||
// Returns value of child xforms 'label' element.
|
// Returns value of child xforms 'label' element.
|
||||||
virtual nsresult GetNameInternal(nsAString& aName);
|
virtual nsresult GetNameInternal(nsAString& aName);
|
||||||
|
|
|
@ -64,15 +64,12 @@ nsXFormsLabelAccessible::GetNameInternal(nsAString& aName)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
void
|
||||||
nsXFormsLabelAccessible::GetDescription(nsAString& aDescription)
|
nsXFormsLabelAccessible::Description(nsString& aDescription)
|
||||||
{
|
{
|
||||||
nsAutoString description;
|
nsTextEquivUtils::
|
||||||
nsresult rv = nsTextEquivUtils::
|
|
||||||
GetTextEquivFromIDRefs(this, nsAccessibilityAtoms::aria_describedby,
|
GetTextEquivFromIDRefs(this, nsAccessibilityAtoms::aria_describedby,
|
||||||
description);
|
aDescription);
|
||||||
aDescription = description;
|
|
||||||
return rv;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -50,10 +50,8 @@ class nsXFormsLabelAccessible : public nsXFormsAccessible
|
||||||
public:
|
public:
|
||||||
nsXFormsLabelAccessible(nsIContent *aContent, nsIWeakReference *aShell);
|
nsXFormsLabelAccessible(nsIContent *aContent, nsIWeakReference *aShell);
|
||||||
|
|
||||||
// nsIAccessible
|
|
||||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
|
||||||
|
|
||||||
// nsAccessible
|
// nsAccessible
|
||||||
|
virtual void Description(nsString& aDescription);
|
||||||
virtual nsresult GetNameInternal(nsAString& aName);
|
virtual nsresult GetNameInternal(nsAString& aName);
|
||||||
virtual PRUint32 NativeRole();
|
virtual PRUint32 NativeRole();
|
||||||
};
|
};
|
||||||
|
|
|
@ -177,11 +177,10 @@ nsXFormsComboboxPopupWidgetAccessible::GetNameInternal(nsAString& aName)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
void
|
||||||
nsXFormsComboboxPopupWidgetAccessible::GetDescription(nsAString& aDescription)
|
nsXFormsComboboxPopupWidgetAccessible::Description(nsString& aDescription)
|
||||||
{
|
{
|
||||||
aDescription.Truncate();
|
aDescription.Truncate();
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -91,9 +91,9 @@ public:
|
||||||
|
|
||||||
// nsIAccessible
|
// nsIAccessible
|
||||||
NS_IMETHOD GetValue(nsAString& aValue);
|
NS_IMETHOD GetValue(nsAString& aValue);
|
||||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
|
||||||
|
|
||||||
// nsAccessible
|
// nsAccessible
|
||||||
|
virtual void Description(nsString& aDescription);
|
||||||
virtual nsresult GetNameInternal(nsAString& aName);
|
virtual nsresult GetNameInternal(nsAString& aName);
|
||||||
virtual PRUint32 NativeRole();
|
virtual PRUint32 NativeRole();
|
||||||
virtual PRUint64 NativeState();
|
virtual PRUint64 NativeState();
|
||||||
|
|
|
@ -112,32 +112,25 @@ nsXULComboboxAccessible::GetValue(nsAString& aValue)
|
||||||
return NS_ERROR_FAILURE;
|
return NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
void
|
||||||
nsXULComboboxAccessible::GetDescription(nsAString& aDescription)
|
nsXULComboboxAccessible::Description(nsString& aDescription)
|
||||||
{
|
{
|
||||||
aDescription.Truncate();
|
aDescription.Truncate();
|
||||||
|
|
||||||
if (IsDefunct())
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
// Use description of currently focused option
|
// Use description of currently focused option
|
||||||
nsCOMPtr<nsIDOMXULMenuListElement> menuListElm(do_QueryInterface(mContent));
|
nsCOMPtr<nsIDOMXULMenuListElement> menuListElm(do_QueryInterface(mContent));
|
||||||
if (!menuListElm)
|
if (!menuListElm)
|
||||||
return NS_ERROR_FAILURE;
|
return;
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMXULSelectControlItemElement> focusedOptionItem;
|
nsCOMPtr<nsIDOMXULSelectControlItemElement> focusedOptionItem;
|
||||||
menuListElm->GetSelectedItem(getter_AddRefs(focusedOptionItem));
|
menuListElm->GetSelectedItem(getter_AddRefs(focusedOptionItem));
|
||||||
nsCOMPtr<nsIContent> focusedOptionContent =
|
nsCOMPtr<nsIContent> focusedOptionContent =
|
||||||
do_QueryInterface(focusedOptionItem);
|
do_QueryInterface(focusedOptionItem);
|
||||||
if (focusedOptionContent) {
|
if (focusedOptionContent) {
|
||||||
nsAccessible *focusedOption =
|
nsAccessible* focusedOptionAcc = GetAccService()->
|
||||||
GetAccService()->GetAccessibleInWeakShell(focusedOptionContent, mWeakShell);
|
GetAccessibleInWeakShell(focusedOptionContent, mWeakShell);
|
||||||
NS_ENSURE_TRUE(focusedOption, NS_ERROR_FAILURE);
|
if (focusedOptionAcc)
|
||||||
|
focusedOptionAcc->Description(aDescription);
|
||||||
return focusedOption->GetDescription(aDescription);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PRBool
|
PRBool
|
||||||
|
|
|
@ -55,12 +55,12 @@ public:
|
||||||
|
|
||||||
// nsIAccessible
|
// nsIAccessible
|
||||||
NS_IMETHOD GetValue(nsAString& aValue);
|
NS_IMETHOD GetValue(nsAString& aValue);
|
||||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
|
||||||
NS_IMETHOD DoAction(PRUint8 aIndex);
|
NS_IMETHOD DoAction(PRUint8 aIndex);
|
||||||
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
|
NS_IMETHOD GetNumActions(PRUint8 *aNumActions);
|
||||||
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
NS_IMETHOD GetActionName(PRUint8 aIndex, nsAString& aName);
|
||||||
|
|
||||||
// nsAccessible
|
// nsAccessible
|
||||||
|
virtual void Description(nsString& aDescription);
|
||||||
virtual PRUint32 NativeRole();
|
virtual PRUint32 NativeRole();
|
||||||
virtual PRUint64 NativeState();
|
virtual PRUint64 NativeState();
|
||||||
virtual PRBool GetAllowsAnonChildAccessibles();
|
virtual PRBool GetAllowsAnonChildAccessibles();
|
||||||
|
|
|
@ -861,6 +861,15 @@ nsXULListitemAccessible::GetListAccessible()
|
||||||
return GetAccService()->GetAccessibleInWeakShell(listContent, mWeakShell);
|
return GetAccService()->GetAccessibleInWeakShell(listContent, mWeakShell);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// nsXULListitemAccessible nsAccessible
|
||||||
|
|
||||||
|
void
|
||||||
|
nsXULListitemAccessible::Description(nsString& aDesc)
|
||||||
|
{
|
||||||
|
nsAccessibleWrap::Description(aDesc);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// nsXULListitemAccessible. nsIAccessible
|
// nsXULListitemAccessible. nsIAccessible
|
||||||
|
|
||||||
|
|
|
@ -123,9 +123,9 @@ public:
|
||||||
// nsIAccessible
|
// nsIAccessible
|
||||||
NS_IMETHOD GetActionName(PRUint8 index, nsAString& aName);
|
NS_IMETHOD GetActionName(PRUint8 index, nsAString& aName);
|
||||||
// Don't use XUL menuitems's description attribute
|
// Don't use XUL menuitems's description attribute
|
||||||
NS_IMETHOD GetDescription(nsAString& aDesc) { return nsAccessibleWrap::GetDescription(aDesc); }
|
|
||||||
|
|
||||||
// nsAccessible
|
// nsAccessible
|
||||||
|
virtual void Description(nsString& aDesc);
|
||||||
virtual nsresult GetNameInternal(nsAString& aName);
|
virtual nsresult GetNameInternal(nsAString& aName);
|
||||||
virtual PRUint32 NativeRole();
|
virtual PRUint32 NativeRole();
|
||||||
virtual PRUint64 NativeState();
|
virtual PRUint64 NativeState();
|
||||||
|
|
|
@ -378,16 +378,11 @@ nsXULMenuitemAccessible::GetNameInternal(nsAString& aName)
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
void
|
||||||
nsXULMenuitemAccessible::GetDescription(nsAString& aDescription)
|
nsXULMenuitemAccessible::Description(nsString& aDescription)
|
||||||
{
|
{
|
||||||
if (IsDefunct())
|
|
||||||
return NS_ERROR_FAILURE;
|
|
||||||
|
|
||||||
mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::description,
|
mContent->GetAttr(kNameSpaceID_None, nsAccessibilityAtoms::description,
|
||||||
aDescription);
|
aDescription);
|
||||||
|
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//return menu accesskey: N or Alt+F
|
//return menu accesskey: N or Alt+F
|
||||||
|
|
|
@ -82,7 +82,6 @@ public:
|
||||||
nsXULMenuitemAccessible(nsIContent *aContent, nsIWeakReference *aShell);
|
nsXULMenuitemAccessible(nsIContent *aContent, nsIWeakReference *aShell);
|
||||||
|
|
||||||
// nsIAccessible
|
// nsIAccessible
|
||||||
NS_IMETHOD GetDescription(nsAString& aDescription);
|
|
||||||
NS_IMETHOD GetKeyboardShortcut(nsAString& _retval);
|
NS_IMETHOD GetKeyboardShortcut(nsAString& _retval);
|
||||||
NS_IMETHOD GetDefaultKeyBinding(nsAString& aKeyBinding);
|
NS_IMETHOD GetDefaultKeyBinding(nsAString& aKeyBinding);
|
||||||
NS_IMETHOD DoAction(PRUint8 index);
|
NS_IMETHOD DoAction(PRUint8 index);
|
||||||
|
@ -90,6 +89,7 @@ public:
|
||||||
NS_IMETHOD GetNumActions(PRUint8 *_retval);
|
NS_IMETHOD GetNumActions(PRUint8 *_retval);
|
||||||
|
|
||||||
// nsAccessible
|
// nsAccessible
|
||||||
|
virtual void Description(nsString& aDescription);
|
||||||
virtual nsresult GetNameInternal(nsAString& aName);
|
virtual nsresult GetNameInternal(nsAString& aName);
|
||||||
virtual PRUint32 NativeRole();
|
virtual PRUint32 NativeRole();
|
||||||
virtual PRUint64 NativeState();
|
virtual PRUint64 NativeState();
|
||||||
|
|
|
@ -50,8 +50,8 @@ _TEST_FILES = \
|
||||||
test_doc.html \
|
test_doc.html \
|
||||||
test_hypertext.html \
|
test_hypertext.html \
|
||||||
test_passwords.html \
|
test_passwords.html \
|
||||||
test_singleline.html \
|
$(warning test_singleline.html disabled due to bug 652459) \
|
||||||
test_whitespaces.html \
|
$(warning test_whitespaces.html disabled due to bug 652459) \
|
||||||
test_words.html \
|
test_words.html \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
|
|
|
@ -178,7 +178,8 @@ endif
|
||||||
|
|
||||||
ifeq ($(OS_ARCH),WINNT)
|
ifeq ($(OS_ARCH),WINNT)
|
||||||
OS_LIBS += $(call EXPAND_LIBNAME,comctl32 comdlg32 uuid shell32 ole32 oleaut32 version winspool)
|
OS_LIBS += $(call EXPAND_LIBNAME,comctl32 comdlg32 uuid shell32 ole32 oleaut32 version winspool)
|
||||||
OS_LIBS += $(call EXPAND_LIBNAME,usp10 msimg32)
|
OS_LIBS += $(call EXPAND_LIBNAME,usp10 msimg32 delayimp)
|
||||||
|
LDFLAGS += -delayload:xul.dll -delayload:xpcom.dll -delayload:plc4.dll -delayload:nspr4.dll -delayload:mozalloc.dll
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(OS_ARCH),WINNT)
|
ifeq ($(OS_ARCH),WINNT)
|
||||||
|
|
|
@ -15,12 +15,6 @@
|
||||||
</targetApplication>
|
</targetApplication>
|
||||||
</versionRange>
|
</versionRange>
|
||||||
</emItem>
|
</emItem>
|
||||||
<emItem id="krupa.raj+545@gmail.com">
|
|
||||||
<versionRange severity="2"/>
|
|
||||||
</emItem>
|
|
||||||
<emItem id="krups@krup12s.com">
|
|
||||||
<versionRange severity="3"/>
|
|
||||||
</emItem>
|
|
||||||
<emItem id="langpack-vi-VN@firefox.mozilla.org">
|
<emItem id="langpack-vi-VN@firefox.mozilla.org">
|
||||||
<versionRange minVersion="2.0" maxVersion="2.0"/>
|
<versionRange minVersion="2.0" maxVersion="2.0"/>
|
||||||
</emItem>
|
</emItem>
|
||||||
|
@ -42,9 +36,6 @@
|
||||||
<emItem id="msntoolbar@msn.com">
|
<emItem id="msntoolbar@msn.com">
|
||||||
<versionRange minVersion=" " maxVersion="6.*"/>
|
<versionRange minVersion=" " maxVersion="6.*"/>
|
||||||
</emItem>
|
</emItem>
|
||||||
<emItem id="near799@wdios.com" os="Android">
|
|
||||||
<versionRange minVersion="0.8" maxVersion="1.0" severity="3"/>
|
|
||||||
</emItem>
|
|
||||||
<emItem id="personas@christopher.beard">
|
<emItem id="personas@christopher.beard">
|
||||||
<versionRange minVersion="1.6" maxVersion="1.6">
|
<versionRange minVersion="1.6" maxVersion="1.6">
|
||||||
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
|
||||||
|
@ -55,9 +46,6 @@
|
||||||
<emItem id="ShopperReports@ShopperReports.com">
|
<emItem id="ShopperReports@ShopperReports.com">
|
||||||
<versionRange minVersion="3.1.22.0" maxVersion="3.1.22.0"/>
|
<versionRange minVersion="3.1.22.0" maxVersion="3.1.22.0"/>
|
||||||
</emItem>
|
</emItem>
|
||||||
<emItem id="sidecar-test-addon20110103118@amazon.com" os="MACOSX, Windows, Linux">
|
|
||||||
<versionRange severity="3"/>
|
|
||||||
</emItem>
|
|
||||||
<emItem id="support@daemon-tools.cc">
|
<emItem id="support@daemon-tools.cc">
|
||||||
<versionRange minVersion=" " maxVersion="1.0.0.5"/>
|
<versionRange minVersion=" " maxVersion="1.0.0.5"/>
|
||||||
</emItem>
|
</emItem>
|
||||||
|
@ -196,38 +184,5 @@
|
||||||
<driverVersion>7.0.0.0</driverVersion>
|
<driverVersion>7.0.0.0</driverVersion>
|
||||||
<driverVersionComparator>GREATER_THAN_OR_EQUAL</driverVersionComparator>
|
<driverVersionComparator>GREATER_THAN_OR_EQUAL</driverVersionComparator>
|
||||||
</gfxBlacklistEntry>
|
</gfxBlacklistEntry>
|
||||||
<gfxBlacklistEntry>
|
|
||||||
<os>MAC OS X 10.5.8</os>
|
|
||||||
<vendor>0x10de</vendor>
|
|
||||||
<feature>DIRECT3D_9_LAYERS</feature>
|
|
||||||
<driverVersion>7.0.0.0</driverVersion>
|
|
||||||
<driverVersionComparator>GREATER_THAN_OR_EQUAL</driverVersionComparator>
|
|
||||||
</gfxBlacklistEntry>
|
|
||||||
<gfxBlacklistEntry>
|
|
||||||
<os>MAC OS X 10.5.8</os>
|
|
||||||
<vendor>0x10de</vendor>
|
|
||||||
<feature>DIRECT3D_9_LAYERS</feature>
|
|
||||||
<featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
|
|
||||||
<driverVersion>7.0.0.0</driverVersion>
|
|
||||||
<driverVersionComparator>GREATER_THAN_OR_EQUAL</driverVersionComparator>
|
|
||||||
</gfxBlacklistEntry>
|
|
||||||
<gfxBlacklistEntry>
|
|
||||||
<os>MAC OS X 10.6</os>
|
|
||||||
<vendor>0x10de</vendor>
|
|
||||||
<devices>
|
|
||||||
<device>0x0a6c</device>
|
|
||||||
</devices>
|
|
||||||
<feature>DIRECT3D_9_LAYERS</feature>
|
|
||||||
<featureStatus>BLOCKED_DRIVER_VERSION</featureStatus>
|
|
||||||
<driverVersion>8.17.12.5896</driverVersion>
|
|
||||||
<driverVersionComparator>LESS_THAN_OR_EQUAL</driverVersionComparator>
|
|
||||||
</gfxBlacklistEntry>
|
|
||||||
<gfxBlacklistEntry>
|
|
||||||
<os>MAC OS X 10.6</os>
|
|
||||||
<vendor>0x10de</vendor>
|
|
||||||
<feature>DIRECT3D_9_LAYERS</feature>
|
|
||||||
<driverVersion>7.0.0.0</driverVersion>
|
|
||||||
<driverVersionComparator>GREATER_THAN_OR_EQUAL</driverVersionComparator>
|
|
||||||
</gfxBlacklistEntry>
|
|
||||||
</gfxItems>
|
</gfxItems>
|
||||||
</blocklist>
|
</blocklist>
|
||||||
|
|
|
@ -56,6 +56,7 @@
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
// we want to use the DLL blocklist if possible
|
// we want to use the DLL blocklist if possible
|
||||||
#define XRE_WANT_DLL_BLOCKLIST
|
#define XRE_WANT_DLL_BLOCKLIST
|
||||||
|
#define XRE_PRELOAD_XUL
|
||||||
// we want a wmain entry point
|
// we want a wmain entry point
|
||||||
#include "nsWindowsWMain.cpp"
|
#include "nsWindowsWMain.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -75,12 +75,12 @@
|
||||||
|
|
||||||
<prefpane id="finished-studies-pane" class="tp-tab-panel">
|
<prefpane id="finished-studies-pane" class="tp-tab-panel">
|
||||||
<richlistbox id="finished-studies-listbox" class="tp-study-list"
|
<richlistbox id="finished-studies-listbox" class="tp-study-list"
|
||||||
disabled="true" />
|
disabled="true"/>
|
||||||
</prefpane>
|
</prefpane>
|
||||||
|
|
||||||
<prefpane id="study-results-pane" class="tp-tab-panel">
|
<prefpane id="study-results-pane" class="tp-tab-panel">
|
||||||
<richlistbox id="study-results-listbox" class="tp-study-list"
|
<richlistbox id="study-results-listbox" class="tp-study-list"
|
||||||
disabled="true" />
|
disabled="true"/>
|
||||||
</prefpane>
|
</prefpane>
|
||||||
|
|
||||||
<prefpane id="settings-pane" class="tp-tab-panel">
|
<prefpane id="settings-pane" class="tp-tab-panel">
|
||||||
|
|
|
@ -38,11 +38,16 @@
|
||||||
-moz-border-image: url(chrome://testpilot-os/skin/notification-tail-up.png) 26 56 22 18 / 26px 56px 22px 18px round stretch;
|
-moz-border-image: url(chrome://testpilot-os/skin/notification-tail-up.png) 26 56 22 18 / 26px 56px 22px 18px round stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* tail-down uses the old styling; it doesn't look as good as the new styling,
|
||||||
|
but the new styling doesn't work on 3.6.
|
||||||
|
TODO: If someone is using 3.7.* or 4.* but is NOT on the beta channel and
|
||||||
|
installed Test Pilot from AMO, they should get the new styling, similar
|
||||||
|
to .tail-up! */
|
||||||
.tail-down {
|
.tail-down {
|
||||||
-moz-border-image: url(chrome://testpilot-os/skin/notification-tail-down.png) 26 56 22 18 / 26px 56px 22px 18px round stretch;
|
-moz-border-image: url(chrome://testpilot/skin/notification-tail-down.png) 26 50 22 18 / 26px 50px 22px 18px repeat;
|
||||||
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.pilot-notification-popup-container {
|
.pilot-notification-popup-container {
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
margin-right: -42px;
|
margin-right: -42px;
|
||||||
|
@ -172,7 +177,7 @@ image.study-result {
|
||||||
color: white;
|
color: white;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
border-radius: 10000px;
|
-moz-border-radius: 100%;
|
||||||
margin-right: 25px;
|
margin-right: 25px;
|
||||||
margin-bottom: 13px;
|
margin-bottom: 13px;
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,6 +128,7 @@ var TestPilotMenuUtils;
|
||||||
let menuPopup = document.getElementById("pilot-menu-popup");
|
let menuPopup = document.getElementById("pilot-menu-popup");
|
||||||
let menuButton = document.getElementById(attachPointId);
|
let menuButton = document.getElementById(attachPointId);
|
||||||
|
|
||||||
|
// TODO failing here with "menuPopup is null" for Tracy
|
||||||
if (menuPopup.parentNode != menuButton)
|
if (menuPopup.parentNode != menuButton)
|
||||||
menuButton.appendChild(menuPopup);
|
menuButton.appendChild(menuPopup);
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,20 @@
|
||||||
|
|
||||||
function reloadAllExperiments() {
|
function reloadAllExperiments() {
|
||||||
Components.utils.import("resource://testpilot/modules/setup.js");
|
Components.utils.import("resource://testpilot/modules/setup.js");
|
||||||
TestPilotSetup.reloadRemoteExperiments();
|
TestPilotSetup.reloadRemoteExperiments(function(success) {
|
||||||
|
let errors = TestPilotSetup._remoteExperimentLoader.getLoadErrors();
|
||||||
|
let str;
|
||||||
|
if (errors.length > 0) {
|
||||||
|
str = "<ul>";
|
||||||
|
for each (let errStr in errors) {
|
||||||
|
str += "<li>" + errStr + "</li>";
|
||||||
|
}
|
||||||
|
str += "</ul>";
|
||||||
|
} else {
|
||||||
|
str = "All experiments reloaded, no errors.";
|
||||||
|
}
|
||||||
|
document.getElementById("debug").innerHTML = str;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function runUnitTests() {
|
function runUnitTests() {
|
||||||
|
@ -81,8 +94,7 @@
|
||||||
var path = codeStore.resolveModule(null, filename);
|
var path = codeStore.resolveModule(null, filename);
|
||||||
var textArea = document.getElementById("experiment-code-area");
|
var textArea = document.getElementById("experiment-code-area");
|
||||||
codeStore.setLocalOverride(path, textArea.value);
|
codeStore.setLocalOverride(path, textArea.value);
|
||||||
reloadAllExperiments(function(success) {
|
reloadAllExperiments();
|
||||||
document.getElementById("debug").innerHTML = "Success? " + success;});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function showMetaData() {
|
function showMetaData() {
|
||||||
|
|
|
@ -405,15 +405,9 @@ var stringBundle;
|
||||||
|
|
||||||
function onStatusPageLoad() {
|
function onStatusPageLoad() {
|
||||||
setStrings(PAGE_TYPE_STATUS);
|
setStrings(PAGE_TYPE_STATUS);
|
||||||
/* If an experiment ID (eid) is provided in the url params, show status
|
/* An experiment ID (eid) must be provided in the url params. Show status
|
||||||
* for that experiment. If not, show the main menu with status for all
|
* for that experiment.*/
|
||||||
* installed experiments. */
|
loadExperimentPage();
|
||||||
let eidString = getUrlParam("eid");
|
|
||||||
if (eidString == "") {
|
|
||||||
showStatusMenuPage();
|
|
||||||
} else {
|
|
||||||
loadExperimentPage();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function setStrings(pageType) {
|
function setStrings(pageType) {
|
||||||
|
|
|
@ -102,16 +102,16 @@ src: url('chrome://testpilot/skin/fonts/DroidSans-Bold.ttf') format('truetype');
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
color: rgba(0, 0, 0, 0.8);
|
color: rgba(0, 0, 0, 0.8);
|
||||||
border-radius: 0.5em;
|
-moz-border-radius: 0.5em;
|
||||||
-webkit-border-radius: 0.5em;
|
-webkit-border-radius: 0.5em;
|
||||||
box-shadow:
|
-moz-box-shadow:
|
||||||
inset rgba(0, 0, 0, 0.2) 0 1px 1px,
|
inset rgba(0, 0, 0, 0.2) 0 1px 1px,
|
||||||
inset rgba(255, 255, 255, 1) 0 3px 1px,
|
inset rgba(255, 255, 255, 1) 0 3px 1px,
|
||||||
inset rgba(255, 255, 255, 0.3) 0 16px 0px,
|
inset rgba(255, 255, 255, 0.3) 0 16px 0px,
|
||||||
inset rgba(0, 0, 0, 0.2) 0 -1px 1px,
|
inset rgba(0, 0, 0, 0.2) 0 -1px 1px,
|
||||||
inset rgba(0, 0, 0, 0.1) 0 -2px 1px,
|
inset rgba(0, 0, 0, 0.1) 0 -2px 1px,
|
||||||
rgba(255, 255, 255, 1) 0 1px,
|
rgba(255, 255, 255, 1) 0 1px,
|
||||||
rgba(133, 153, 166, 0.3) 0px 1px 8.5px;
|
rgba(133, 153, 166, 0.3) 0px 1px 12px;
|
||||||
background-color: #e7eaec;
|
background-color: #e7eaec;
|
||||||
//display: inline;
|
//display: inline;
|
||||||
}
|
}
|
||||||
|
@ -122,16 +122,16 @@ src: url('chrome://testpilot/skin/fonts/DroidSans-Bold.ttf') format('truetype');
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
width: 240px;
|
width: 240px;
|
||||||
color: rgba(0, 0, 0, 0.8);
|
color: rgba(0, 0, 0, 0.8);
|
||||||
border-radius: 0.5em;
|
-moz-border-radius: 0.5em;
|
||||||
-webkit-border-radius: 0.5em;
|
-webkit-border-radius: 0.5em;
|
||||||
box-shadow:
|
-moz-box-shadow:
|
||||||
inset rgba(0, 0, 0, 0.2) 0 1px 1px,
|
inset rgba(0, 0, 0, 0.2) 0 1px 1px,
|
||||||
inset rgba(255, 255, 255, 1) 0 3px 1px,
|
inset rgba(255, 255, 255, 1) 0 3px 1px,
|
||||||
inset rgba(255, 255, 255, 0.3) 0 16px 0px,
|
inset rgba(255, 255, 255, 0.3) 0 16px 0px,
|
||||||
inset rgba(0, 0, 0, 0.2) 0 -1px 1px,
|
inset rgba(0, 0, 0, 0.2) 0 -1px 1px,
|
||||||
inset rgba(0, 0, 0, 0.1) 0 -2px 1px,
|
inset rgba(0, 0, 0, 0.1) 0 -2px 1px,
|
||||||
rgba(255, 255, 255, 1) 0 1px,
|
rgba(255, 255, 255, 1) 0 1px,
|
||||||
rgba(133, 153, 166, 0.3) 0px 1px 8.5px;
|
rgba(133, 153, 166, 0.3) 0px 1px 12px;
|
||||||
background-color: #e7eaec;
|
background-color: #e7eaec;
|
||||||
//display: inline;
|
//display: inline;
|
||||||
}
|
}
|
||||||
|
@ -143,13 +143,13 @@ src: url('chrome://testpilot/skin/fonts/DroidSans-Bold.ttf') format('truetype');
|
||||||
padding: 8px 24px;
|
padding: 8px 24px;
|
||||||
margin: 24px auto;
|
margin: 24px auto;
|
||||||
color: rgba(0, 0, 0, 0.8);
|
color: rgba(0, 0, 0, 0.8);
|
||||||
border-radius: 0.5em;
|
-moz-border-radius: 0.5em;
|
||||||
-webkit-border-radius: 0.5em;
|
-webkit-border-radius: 0.5em;
|
||||||
background: rgba(220, 240, 247, 0.8) url('chrome://testpilot/skin/callout.png') no-repeat top center;
|
background: rgba(220, 240, 247, 0.8) url('chrome://testpilot/skin/callout.png') no-repeat top center;
|
||||||
box-shadow:
|
-moz-box-shadow:
|
||||||
inset rgba(185, 221, 234, 0.2) 0 -10px 8.5px,
|
inset rgba(185, 221, 234, 0.2) 0 -10px 12px,
|
||||||
inset rgba(185, 221, 234, 1) 0 0px 1px,
|
inset rgba(185, 221, 234, 1) 0 0px 1px,
|
||||||
inset rgba(255, 255, 255, 0.2) 0 10px 8.5px;
|
inset rgba(255, 255, 255, 0.2) 0 10px 12px;
|
||||||
//display: inline;
|
//display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,13 +161,13 @@ src: url('chrome://testpilot/skin/fonts/DroidSans-Bold.ttf') format('truetype');
|
||||||
padding: 8px 24px;
|
padding: 8px 24px;
|
||||||
margin: 8px auto;
|
margin: 8px auto;
|
||||||
color: rgba(0, 0, 0, 0.8);
|
color: rgba(0, 0, 0, 0.8);
|
||||||
border-radius: 0.5em;
|
-moz-border-radius: 0.5em;
|
||||||
-webkit-border-radius: 0.5em;
|
-webkit-border-radius: 0.5em;
|
||||||
background: rgba(220, 240, 247, 0.8) url('chrome://testpilot/skin/callout.png') no-repeat top center;
|
background: rgba(220, 240, 247, 0.8) url('chrome://testpilot/skin/callout.png') no-repeat top center;
|
||||||
box-shadow:
|
-moz-box-shadow:
|
||||||
inset rgba(185, 221, 234, 0.2) 0 -10px 8.5px,
|
inset rgba(185, 221, 234, 0.2) 0 -10px 12px,
|
||||||
inset rgba(185, 221, 234, 1) 0 0px 1px,
|
inset rgba(185, 221, 234, 1) 0 0px 1px,
|
||||||
inset rgba(255, 255, 255, 0.2) 0 10px 8.5px;
|
inset rgba(255, 255, 255, 0.2) 0 10px 12px;
|
||||||
//display: inline;
|
//display: inline;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ src: url('chrome://testpilot/skin/fonts/DroidSans-Bold.ttf') format('truetype');
|
||||||
padding: 4px 40px;
|
padding: 4px 40px;
|
||||||
width: 800px;
|
width: 800px;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
border-radius: 0.25em;
|
-moz-border-radius: 0.25em;
|
||||||
-webkit-border-radius: 0.25em;
|
-webkit-border-radius: 0.25em;
|
||||||
border-top: 1px solid #adb6ba;
|
border-top: 1px solid #adb6ba;
|
||||||
border-left: 1px solid #adb6ba;
|
border-left: 1px solid #adb6ba;
|
||||||
|
@ -223,8 +223,8 @@ src: url('chrome://testpilot/skin/fonts/DroidSans-Bold.ttf') format('truetype');
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
text-shadow: 1px 1px 1px rgba(173, 182, 186, 1);
|
text-shadow: 1px 1px 1px rgba(173, 182, 186, 1);
|
||||||
background-color: rgba(173, 182, 186, 0.3);
|
background-color: rgba(173, 182, 186, 0.3);
|
||||||
box-shadow:
|
-moz-box-shadow:
|
||||||
inset rgba(0, 0, 0, 0.2) 0 -10px 8.5px;
|
inset rgba(0, 0, 0, 0.2) 0 -10px 12px;
|
||||||
padding: 9px 8px 8px 8px;
|
padding: 9px 8px 8px 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,4 +255,4 @@ src: url('chrome://testpilot/skin/fonts/DroidSans-Bold.ttf') format('truetype');
|
||||||
|
|
||||||
p.embiggened {
|
p.embiggened {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
}
|
}
|
|
@ -28,9 +28,7 @@
|
||||||
<div class="home_callout">
|
<div class="home_callout">
|
||||||
<img class="homeIcon"
|
<img class="homeIcon"
|
||||||
src="chrome://testpilot/skin/images/home_comments.png">
|
src="chrome://testpilot/skin/images/home_comments.png">
|
||||||
<a id="comments-and-discussions-link"
|
<a id="comments-and-discussions-link" onclick="openLink('http://groups.google.com/group/mozilla-labs-testpilot');">
|
||||||
onclick="
|
|
||||||
openLink('http://groups.google.com/group/mozilla-labs-testpilot');">
|
|
||||||
</a>
|
</a>
|
||||||
</div><br>
|
</div><br>
|
||||||
<div class="home_callout">
|
<div class="home_callout">
|
||||||
|
|
|
@ -24,6 +24,11 @@
|
||||||
<span id="please-take-text"></span>
|
<span id="please-take-text"></span>
|
||||||
<a class="function-link" id="background-survey-text"
|
<a class="function-link" id="background-survey-text"
|
||||||
onclick="TestPilotWelcomePage.openPilotSurvey();"></a>!</p>
|
onclick="TestPilotWelcomePage.openPilotSurvey();"></a>!</p>
|
||||||
|
<p class="embiggened">
|
||||||
|
<a class="function-link" id="privacy-policy-link"
|
||||||
|
style="text-decoration: underline"
|
||||||
|
href="http://www.mozilla.com/en-US/privacy-policy.html"></a>
|
||||||
|
</p>
|
||||||
<p class="embiggened">
|
<p class="embiggened">
|
||||||
<a class="function-link" id="open-studies-window-link"
|
<a class="function-link" id="open-studies-window-link"
|
||||||
onclick="TestPilotWindowUtils.openAllStudiesWindow();"></a>
|
onclick="TestPilotWindowUtils.openAllStudiesWindow();"></a>
|
||||||
|
@ -45,8 +50,6 @@
|
||||||
</div>
|
</div>
|
||||||
<div id="footer">
|
<div id="footer">
|
||||||
<img class="mozLogo" src="chrome://testpilot/skin/mozilla-logo.png">
|
<img class="mozLogo" src="chrome://testpilot/skin/mozilla-logo.png">
|
||||||
<a href="http://www.mozilla.com/en-US/privacy-policy.html"
|
|
||||||
id="privacy-policy-link"></a>
|
|
||||||
<a href="http://www.mozilla.com/en-US/about/legal.html"
|
<a href="http://www.mozilla.com/en-US/about/legal.html"
|
||||||
id="legal-notices-link"></a>
|
id="legal-notices-link"></a>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||||
<Description about="urn:mozilla:install-manifest">
|
<Description about="urn:mozilla:install-manifest">
|
||||||
<em:id>testpilot@labs.mozilla.com</em:id>
|
<em:id>testpilot@labs.mozilla.com</em:id>
|
||||||
<em:version>1.0.9</em:version>
|
<em:version>1.1.1</em:version>
|
||||||
<em:type>2</em:type>
|
<em:type>2</em:type>
|
||||||
|
|
||||||
<!-- Target Application this extension can install into,
|
<!-- Target Application this extension can install into,
|
||||||
|
|
|
@ -75,9 +75,9 @@ DbUtils.createTable = function createTable(connection, tableName, schema){
|
||||||
logger.debug("File is " + file + "\n");
|
logger.debug("File is " + file + "\n");
|
||||||
try{
|
try{
|
||||||
if(!connection.tableExists(tableName)){
|
if(!connection.tableExists(tableName)){
|
||||||
|
// TODO why don't we use connection.createTable here??
|
||||||
connection.executeSimpleSQL(schema);
|
connection.executeSimpleSQL(schema);
|
||||||
}
|
} else{
|
||||||
else{
|
|
||||||
logger.debug("database table: " + tableName + " already exists\n");
|
logger.debug("database table: " + tableName + " already exists\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,8 @@ const TYPE_INT_32 = 0;
|
||||||
const TYPE_DOUBLE = 1;
|
const TYPE_DOUBLE = 1;
|
||||||
const TYPE_STRING = 2;
|
const TYPE_STRING = 2;
|
||||||
|
|
||||||
|
const EXCEPTION_TABLE_NAME = "exceptions";
|
||||||
|
|
||||||
function ExperimentDataStore(fileName, tableName, columns) {
|
function ExperimentDataStore(fileName, tableName, columns) {
|
||||||
this._init(fileName, tableName, columns);
|
this._init(fileName, tableName, columns);
|
||||||
}
|
}
|
||||||
|
@ -87,9 +89,17 @@ ExperimentDataStore.prototype = {
|
||||||
+ schemaClauses.join(", ") + ");";
|
+ schemaClauses.join(", ") + ");";
|
||||||
// CreateTable creates the table only if it does not already exist:
|
// CreateTable creates the table only if it does not already exist:
|
||||||
try {
|
try {
|
||||||
this._connection = DbUtils.createTable(this._connection,
|
DbUtils.createTable(this._connection, this._tableName, schema);
|
||||||
this._tableName,
|
} catch(e) {
|
||||||
schema);
|
logger.warn("Error in createTable: " + e + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a second table for storing exceptions for this study. It has a fixed
|
||||||
|
// name and schema:
|
||||||
|
let exceptionTableSchema = "CREATE TABLE " + EXCEPTION_TABLE_NAME +
|
||||||
|
" (time INTEGER, trace TEXT);";
|
||||||
|
try {
|
||||||
|
DbUtils.createTable(this._connection, "exceptions", exceptionTableSchema);
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
logger.warn("Error in createTable: " + e + "\n");
|
logger.warn("Error in createTable: " + e + "\n");
|
||||||
}
|
}
|
||||||
|
@ -150,8 +160,21 @@ ExperimentDataStore.prototype = {
|
||||||
insStmt.finalize();
|
insStmt.finalize();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
logException: function EDS_logException(exception) {
|
||||||
|
let insertSql = "INSERT INTO " + EXCEPTION_TABLE_NAME + " VALUES (?1, ?2);";
|
||||||
|
let insStmt = this._createStatement(insertSql);
|
||||||
|
// Even though the SQL says ?1 and ?2, the param indices count from 0.
|
||||||
|
insStmt.params[0] = Date.now();
|
||||||
|
let txt = exception.message ? exception.message : exception.toString();
|
||||||
|
insStmt.params[1] = txt;
|
||||||
|
insStmt.executeAsync();
|
||||||
|
insStmt.finalize(); // TODO Is this the right thing to do when calling asynchronously?
|
||||||
|
},
|
||||||
|
|
||||||
getJSONRows: function EDS_getJSONRows(callback) {
|
getJSONRows: function EDS_getJSONRows(callback) {
|
||||||
let selectSql = "SELECT * FROM " + this._tableName;
|
// TODO why do both this function and getAllDataAsJSON exist when they both do
|
||||||
|
// the same thing?
|
||||||
|
let selectSql = "SELECT * FROM " + this._tableName;
|
||||||
let selStmt = this._createStatement(selectSql);
|
let selStmt = this._createStatement(selectSql);
|
||||||
let records = [];
|
let records = [];
|
||||||
let self = this;
|
let self = this;
|
||||||
|
@ -255,33 +278,61 @@ ExperimentDataStore.prototype = {
|
||||||
selStmt.finalize();
|
selStmt.finalize();
|
||||||
},
|
},
|
||||||
|
|
||||||
wipeAllData: function EDS_wipeAllData(callback) {
|
getExceptionsAsJson: function(callback) {
|
||||||
let logger = Log4Moz.repository.getLogger("TestPilot.Database");
|
let selectSql = "SELECT * FROM " + EXCEPTION_TABLE_NAME;
|
||||||
logger.trace("ExperimentDataStore.wipeAllData called.\n");
|
let selStmt = this._createStatement(selectSql);
|
||||||
let wipeSql = "DELETE FROM " + this._tableName;
|
let records = [];
|
||||||
let wipeStmt = this._createStatement(wipeSql);
|
let self = this;
|
||||||
wipeStmt.executeAsync({
|
|
||||||
|
selStmt.executeAsync({
|
||||||
handleResult: function(aResultSet) {
|
handleResult: function(aResultSet) {
|
||||||
},
|
for (let row = aResultSet.getNextRow(); row;
|
||||||
handleError: function(aError) {
|
row = aResultSet.getNextRow()) {
|
||||||
if (callback) {
|
records.push({ time: row.getDouble(0),
|
||||||
callback(false);
|
exception: row.getString(1)});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
handleError: function(aError) {
|
||||||
|
callback(records);
|
||||||
|
},
|
||||||
|
handleCompletion: function(aReason) {
|
||||||
|
callback(records);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
wipeAllData: function EDS_wipeAllData(callback) {
|
||||||
|
// Wipe both the data table and the exception table; call callback when both
|
||||||
|
// are wiped.
|
||||||
|
let logger = Log4Moz.repository.getLogger("TestPilot.Database");
|
||||||
|
logger.trace("ExperimentDataStore.wipeAllData called.\n");
|
||||||
|
let wipeDataStmt = this._createStatement("DELETE FROM " + this._tableName);
|
||||||
|
let wipeExcpStmt = this._createStatement("DELETE FROM " + EXCEPTION_TABLE_NAME);
|
||||||
|
|
||||||
|
let numberWiped = 0;
|
||||||
|
let onComplete = function() {
|
||||||
|
numberWiped ++;
|
||||||
|
if (numberWiped == 2 && callback) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
wipeDataStmt.executeAsync({
|
||||||
|
handleResult: function(aResultSet) {},
|
||||||
|
handleError: function(aError) { onComplete(); },
|
||||||
handleCompletion: function(aReason) {
|
handleCompletion: function(aReason) {
|
||||||
if (aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED) {
|
if (aReason == Ci.mozIStorageStatementCallback.REASON_FINISHED) {
|
||||||
logger.trace("ExperimentDataStore.wipeAllData complete.\n");
|
logger.trace("ExperimentDataStore.wipeAllData complete.\n");
|
||||||
if (callback) {
|
|
||||||
callback(true);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (callback) {
|
|
||||||
callback(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
onComplete();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
wipeStmt.finalize();
|
wipeExcpStmt.executeAsync({
|
||||||
|
handleResult: function(aResultSet) {},
|
||||||
|
handleError: function(aError) { onComplete(); },
|
||||||
|
handleCompletion: function(aReason) { onComplete(); }
|
||||||
|
});
|
||||||
|
wipeDataStmt.finalize();
|
||||||
|
wipeExcpStmt.finalize();
|
||||||
},
|
},
|
||||||
|
|
||||||
nukeTable: function EDS_nukeTable() {
|
nukeTable: function EDS_nukeTable() {
|
||||||
|
|
|
@ -219,6 +219,7 @@ exports.RemoteExperimentLoader.prototype = {
|
||||||
this._studyResults = [];
|
this._studyResults = [];
|
||||||
this._legacyStudies = [];
|
this._legacyStudies = [];
|
||||||
this._experimentFileNames = [];
|
this._experimentFileNames = [];
|
||||||
|
this._loadErrors = [];
|
||||||
},
|
},
|
||||||
|
|
||||||
getLocalizedStudyInfo: function(studiesIndex) {
|
getLocalizedStudyInfo: function(studiesIndex) {
|
||||||
|
@ -504,12 +505,20 @@ exports.RemoteExperimentLoader.prototype = {
|
||||||
* the module name and value = the module object. */
|
* the module name and value = the module object. */
|
||||||
this._logger.trace("GetExperiments called.");
|
this._logger.trace("GetExperiments called.");
|
||||||
let remoteExperiments = {};
|
let remoteExperiments = {};
|
||||||
|
this._loadErrors = [];
|
||||||
for each (filename in this._experimentFileNames) {
|
for each (filename in this._experimentFileNames) {
|
||||||
this._logger.debug("GetExperiments is loading " + filename);
|
this._logger.debug("GetExperiments is loading " + filename);
|
||||||
try {
|
try {
|
||||||
remoteExperiments[filename] = this._loader.require(filename);
|
remoteExperiments[filename] = this._loader.require(filename);
|
||||||
this._logger.info("Loaded " + filename + " OK.");
|
this._logger.info("Loaded " + filename + " OK.");
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
|
/* Turn the load-time errors into strings and store them, so we can display
|
||||||
|
* them on a debug page or include them with a data upload! (Don't store
|
||||||
|
* exception objects directly as that causes garbage collector problems-
|
||||||
|
* aka bug 646122) */
|
||||||
|
let errStr = e.name + " on line " + e.lineNumber + " of file " +
|
||||||
|
e.fileName + ": " + e.message;
|
||||||
|
this._loadErrors.push(errStr);
|
||||||
this._logger.warn("Error loading " + filename);
|
this._logger.warn("Error loading " + filename);
|
||||||
this._logger.warn(e);
|
this._logger.warn(e);
|
||||||
}
|
}
|
||||||
|
@ -523,6 +532,10 @@ exports.RemoteExperimentLoader.prototype = {
|
||||||
|
|
||||||
getLegacyStudies: function() {
|
getLegacyStudies: function() {
|
||||||
return this._legacyStudies;
|
return this._legacyStudies;
|
||||||
|
},
|
||||||
|
|
||||||
|
getLoadErrors: function() {
|
||||||
|
return this._loadErrors;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -259,13 +259,13 @@ let TestPilotSetup = {
|
||||||
|
|
||||||
if (currVersion != self.version) {
|
if (currVersion != self.version) {
|
||||||
if(!self._isBetaChannel()) {
|
if(!self._isBetaChannel()) {
|
||||||
|
// Don't show first run page in ffx4 beta version.
|
||||||
self._prefs.setValue(VERSION_PREF, self.version);
|
self._prefs.setValue(VERSION_PREF, self.version);
|
||||||
let browser = self._getFrontBrowserWindow().getBrowser();
|
let browser = self._getFrontBrowserWindow().getBrowser();
|
||||||
let url = self._prefs.getValue(FIRST_RUN_PREF, "");
|
let url = self._prefs.getValue(FIRST_RUN_PREF, "");
|
||||||
let tab = browser.addTab(url);
|
let tab = browser.addTab(url);
|
||||||
browser.selectedTab = tab;
|
browser.selectedTab = tab;
|
||||||
}
|
}
|
||||||
// Don't show first run page in ffx4 beta version.
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Install tasks. (This requires knowing the version, so it is
|
// Install tasks. (This requires knowing the version, so it is
|
||||||
|
|
|
@ -487,29 +487,44 @@ TestPilotExperiment.prototype = {
|
||||||
onNewWindow: function TestPilotExperiment_onNewWindow(window) {
|
onNewWindow: function TestPilotExperiment_onNewWindow(window) {
|
||||||
this._logger.trace("Experiment.onNewWindow called.");
|
this._logger.trace("Experiment.onNewWindow called.");
|
||||||
if (this.experimentIsRunning()) {
|
if (this.experimentIsRunning()) {
|
||||||
this._handlers.onNewWindow(window);
|
try {
|
||||||
|
this._handlers.onNewWindow(window);
|
||||||
|
} catch(e) {
|
||||||
|
this._dataStore.logException("onNewWindow: " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onWindowClosed: function TestPilotExperiment_onWindowClosed(window) {
|
onWindowClosed: function TestPilotExperiment_onWindowClosed(window) {
|
||||||
this._logger.trace("Experiment.onWindowClosed called.");
|
this._logger.trace("Experiment.onWindowClosed called.");
|
||||||
if (this.experimentIsRunning()) {
|
if (this.experimentIsRunning()) {
|
||||||
this._handlers.onWindowClosed(window);
|
try {
|
||||||
|
this._handlers.onWindowClosed(window);
|
||||||
|
} catch(e) {
|
||||||
|
this._dataStore.logException("onWindowClosed: " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onAppStartup: function TestPilotExperiment_onAppStartup() {
|
onAppStartup: function TestPilotExperiment_onAppStartup() {
|
||||||
this._logger.trace("Experiment.onAppStartup called.");
|
this._logger.trace("Experiment.onAppStartup called.");
|
||||||
if (this.experimentIsRunning()) {
|
if (this.experimentIsRunning()) {
|
||||||
this._handlers.onAppStartup();
|
try {
|
||||||
|
this._handlers.onAppStartup();
|
||||||
|
} catch(e) {
|
||||||
|
this._dataStore.logException("onAppStartup: " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onAppShutdown: function TestPilotExperiment_onAppShutdown() {
|
onAppShutdown: function TestPilotExperiment_onAppShutdown() {
|
||||||
this._logger.trace("Experiment.onAppShutdown called.");
|
this._logger.trace("Experiment.onAppShutdown called.");
|
||||||
// TODO the caller for this is not yet implemented
|
|
||||||
if (this.experimentIsRunning()) {
|
if (this.experimentIsRunning()) {
|
||||||
this._handlers.onAppShutdown();
|
try {
|
||||||
|
this._handlers.onAppShutdown();
|
||||||
|
} catch(e) {
|
||||||
|
this._dataStore.logException("onAppShutdown: " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -518,7 +533,11 @@ TestPilotExperiment.prototype = {
|
||||||
// Make sure not to call this if it's already been called:
|
// Make sure not to call this if it's already been called:
|
||||||
if (this.experimentIsRunning() && !this._startedUpHandlers) {
|
if (this.experimentIsRunning() && !this._startedUpHandlers) {
|
||||||
this._logger.trace(" ... starting up handlers!");
|
this._logger.trace(" ... starting up handlers!");
|
||||||
this._handlers.onExperimentStartup(this._dataStore);
|
try {
|
||||||
|
this._handlers.onExperimentStartup(this._dataStore);
|
||||||
|
} catch(e) {
|
||||||
|
this._dataStore.logException("onExperimentStartup: " + e);
|
||||||
|
}
|
||||||
this._startedUpHandlers = true;
|
this._startedUpHandlers = true;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -526,7 +545,11 @@ TestPilotExperiment.prototype = {
|
||||||
onExperimentShutdown: function TestPilotExperiment_onShutdown() {
|
onExperimentShutdown: function TestPilotExperiment_onShutdown() {
|
||||||
this._logger.trace("Experiment.onExperimentShutdown called.");
|
this._logger.trace("Experiment.onExperimentShutdown called.");
|
||||||
if (this.experimentIsRunning() && this._startedUpHandlers) {
|
if (this.experimentIsRunning() && this._startedUpHandlers) {
|
||||||
this._handlers.onExperimentShutdown();
|
try {
|
||||||
|
this._handlers.onExperimentShutdown();
|
||||||
|
} catch(e) {
|
||||||
|
this._dataStore.logException("onExperimentShutdown: " + e);
|
||||||
|
}
|
||||||
this._startedUpHandlers = false;
|
this._startedUpHandlers = false;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -534,21 +557,33 @@ TestPilotExperiment.prototype = {
|
||||||
doExperimentCleanup: function TestPilotExperiment_doExperimentCleanup() {
|
doExperimentCleanup: function TestPilotExperiment_doExperimentCleanup() {
|
||||||
if (this._handlers.doExperimentCleanup) {
|
if (this._handlers.doExperimentCleanup) {
|
||||||
this._logger.trace("Doing experiment cleanup.");
|
this._logger.trace("Doing experiment cleanup.");
|
||||||
this._handlers.doExperimentCleanup();
|
try {
|
||||||
|
this._handlers.doExperimentCleanup();
|
||||||
|
} catch(e) {
|
||||||
|
this._dataStore.logException("doExperimentCleanup: " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onEnterPrivateBrowsing: function TestPilotExperiment_onEnterPrivate() {
|
onEnterPrivateBrowsing: function TestPilotExperiment_onEnterPrivate() {
|
||||||
this._logger.trace("Task is entering private browsing.");
|
this._logger.trace("Task is entering private browsing.");
|
||||||
if (this.experimentIsRunning()) {
|
if (this.experimentIsRunning()) {
|
||||||
this._handlers.onEnterPrivateBrowsing();
|
try {
|
||||||
|
this._handlers.onEnterPrivateBrowsing();
|
||||||
|
} catch(e) {
|
||||||
|
this._dataStore.logException("onEnterPrivateBrowsing: " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
onExitPrivateBrowsing: function TestPilotExperiment_onExitPrivate() {
|
onExitPrivateBrowsing: function TestPilotExperiment_onExitPrivate() {
|
||||||
this._logger.trace("Task is exiting private browsing.");
|
this._logger.trace("Task is exiting private browsing.");
|
||||||
if (this.experimentIsRunning()) {
|
if (this.experimentIsRunning()) {
|
||||||
this._handlers.onExitPrivateBrowsing();
|
try {
|
||||||
|
this._handlers.onExitPrivateBrowsing();
|
||||||
|
} catch(e) {
|
||||||
|
this._dataStore.logException("onExitPrivateBrowsing: " + e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -778,9 +813,12 @@ TestPilotExperiment.prototype = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self._dataStore.getJSONRows(function(rows) {
|
self._dataStore.getJSONRows(function(rows) {
|
||||||
json.events = rows;
|
json.events = rows;
|
||||||
callback( JSON.stringify(json) );
|
self._dataStore.getExceptionsAsJson(function(errs) {
|
||||||
});
|
json.exceptions = errs;
|
||||||
|
callback( JSON.stringify(json) );
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -57,10 +57,10 @@ pref("extensions.logging.enabled", false);
|
||||||
// Preferences for AMO integration
|
// Preferences for AMO integration
|
||||||
pref("extensions.getAddons.cache.enabled", true);
|
pref("extensions.getAddons.cache.enabled", true);
|
||||||
pref("extensions.getAddons.maxResults", 15);
|
pref("extensions.getAddons.maxResults", 15);
|
||||||
pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%&tMain=%TIME_MAIN%&tFirstPaint=%TIME_FIRST_PAINT%&tSessionRestored=%TIME_SESSION_RESTORED%");
|
pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/guid:%IDS%?src=firefox&appOS=%OS%&appVersion=%VERSION%&tMain=%TIME_MAIN%&tFirstPaint=%TIME_FIRST_PAINT%&tSessionRestored=%TIME_SESSION_RESTORED%");
|
||||||
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/%APP%/search?q=%TERMS%");
|
pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/firefox/search?q=%TERMS%");
|
||||||
pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%?src=firefox");
|
pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/firefox/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%?src=firefox");
|
||||||
pref("extensions.webservice.discoverURL", "https://services.addons.mozilla.org/%LOCALE%/%APP%/discovery/pane/%VERSION%/%OS%");
|
pref("extensions.webservice.discoverURL", "https://services.addons.mozilla.org/%LOCALE%/firefox/discovery/pane/%VERSION%/%OS%");
|
||||||
|
|
||||||
// Blocklist preferences
|
// Blocklist preferences
|
||||||
pref("extensions.blocklist.enabled", true);
|
pref("extensions.blocklist.enabled", true);
|
||||||
|
@ -74,7 +74,7 @@ pref("extensions.blocklist.detailsURL", "https://www.mozilla.com/%LOCALE%/blockl
|
||||||
pref("extensions.update.autoUpdateDefault", true);
|
pref("extensions.update.autoUpdateDefault", true);
|
||||||
|
|
||||||
// Dictionary download preference
|
// Dictionary download preference
|
||||||
pref("browser.dictionaries.download.url", "https://addons.mozilla.org/%LOCALE%/%APP%/dictionaries/");
|
pref("browser.dictionaries.download.url", "https://addons.mozilla.org/%LOCALE%/firefox/dictionaries/");
|
||||||
|
|
||||||
// The minimum delay in seconds for the timer to fire.
|
// The minimum delay in seconds for the timer to fire.
|
||||||
// default=2 minutes
|
// default=2 minutes
|
||||||
|
@ -199,7 +199,7 @@ pref("extensions.update.url", "https://versioncheck.addons.mozilla.org/update/Ve
|
||||||
pref("extensions.update.interval", 86400); // Check for updates to Extensions and
|
pref("extensions.update.interval", 86400); // Check for updates to Extensions and
|
||||||
// Themes every day
|
// Themes every day
|
||||||
// Non-symmetric (not shared by extensions) extension-specific [update] preferences
|
// Non-symmetric (not shared by extensions) extension-specific [update] preferences
|
||||||
pref("extensions.getMoreThemesURL", "https://addons.mozilla.org/%LOCALE%/%APP%/getpersonas");
|
pref("extensions.getMoreThemesURL", "https://addons.mozilla.org/%LOCALE%/firefox/getpersonas");
|
||||||
pref("extensions.dss.enabled", false); // Dynamic Skin Switching
|
pref("extensions.dss.enabled", false); // Dynamic Skin Switching
|
||||||
pref("extensions.dss.switchPending", false); // Non-dynamic switch pending after next
|
pref("extensions.dss.switchPending", false); // Non-dynamic switch pending after next
|
||||||
// restart.
|
// restart.
|
||||||
|
@ -299,6 +299,8 @@ pref("browser.urlbar.match.url", "@");
|
||||||
// 2 = only bookmarks, 3 = visited bookmarks, 1+16 = history matching in the url
|
// 2 = only bookmarks, 3 = visited bookmarks, 1+16 = history matching in the url
|
||||||
pref("browser.urlbar.default.behavior", 0);
|
pref("browser.urlbar.default.behavior", 0);
|
||||||
|
|
||||||
|
pref("browser.urlbar.formatting.enabled", true);
|
||||||
|
|
||||||
// Number of milliseconds to wait for the http headers (and thus
|
// Number of milliseconds to wait for the http headers (and thus
|
||||||
// the Content-Disposition filename) before giving up and falling back to
|
// the Content-Disposition filename) before giving up and falling back to
|
||||||
// picking a filename without that info in hand so that the user sees some
|
// picking a filename without that info in hand so that the user sees some
|
||||||
|
@ -321,7 +323,7 @@ pref("browser.download.manager.scanWhenDone", true);
|
||||||
pref("browser.download.manager.resumeOnWakeDelay", 10000);
|
pref("browser.download.manager.resumeOnWakeDelay", 10000);
|
||||||
|
|
||||||
// search engines URL
|
// search engines URL
|
||||||
pref("browser.search.searchEnginesURL", "https://addons.mozilla.org/%LOCALE%/%APP%/search-engines/");
|
pref("browser.search.searchEnginesURL", "https://addons.mozilla.org/%LOCALE%/firefox/search-engines/");
|
||||||
|
|
||||||
// pointer to the default engine name
|
// pointer to the default engine name
|
||||||
pref("browser.search.defaultenginename", "chrome://browser-region/locale/region.properties");
|
pref("browser.search.defaultenginename", "chrome://browser-region/locale/region.properties");
|
||||||
|
@ -710,8 +712,8 @@ pref("browser.safebrowsing.provider.0.reportMalwareURL", "http://{moz:locale}.ma
|
||||||
pref("browser.safebrowsing.provider.0.reportMalwareErrorURL", "http://{moz:locale}.malware-error.mozilla.com/?hl={moz:locale}");
|
pref("browser.safebrowsing.provider.0.reportMalwareErrorURL", "http://{moz:locale}.malware-error.mozilla.com/?hl={moz:locale}");
|
||||||
|
|
||||||
// FAQ URLs
|
// FAQ URLs
|
||||||
pref("browser.safebrowsing.warning.infoURL", "http://www.mozilla.com/%LOCALE%/%APP%/phishing-protection/");
|
pref("browser.safebrowsing.warning.infoURL", "http://www.mozilla.com/%LOCALE%/firefox/phishing-protection/");
|
||||||
pref("browser.geolocation.warning.infoURL", "http://www.mozilla.com/%LOCALE%/%APP%/geolocation/");
|
pref("browser.geolocation.warning.infoURL", "http://www.mozilla.com/%LOCALE%/firefox/geolocation/");
|
||||||
|
|
||||||
// Name of the about: page contributed by safebrowsing to handle display of error
|
// Name of the about: page contributed by safebrowsing to handle display of error
|
||||||
// pages on phishing/malware hits. (bug 399233)
|
// pages on phishing/malware hits. (bug 399233)
|
||||||
|
@ -857,7 +859,7 @@ pref("browser.zoom.updateBackgroundTabs", true);
|
||||||
pref("breakpad.reportURL", "http://crash-stats.mozilla.com/report/index/");
|
pref("breakpad.reportURL", "http://crash-stats.mozilla.com/report/index/");
|
||||||
|
|
||||||
// base URL for web-based support pages
|
// base URL for web-based support pages
|
||||||
pref("app.support.baseURL", "http://support.mozilla.com/1/%APP%/%VERSION%/%OS%/%LOCALE%/");
|
pref("app.support.baseURL", "http://support.mozilla.com/1/firefox/%VERSION%/%OS%/%LOCALE%/");
|
||||||
|
|
||||||
// Name of alternate about: page for certificate errors (when undefined, defaults to about:neterror)
|
// Name of alternate about: page for certificate errors (when undefined, defaults to about:neterror)
|
||||||
pref("security.alternate_certificate_error_page", "certerror");
|
pref("security.alternate_certificate_error_page", "certerror");
|
||||||
|
@ -990,6 +992,12 @@ pref("services.sync.prefs.sync.xpinstall.whitelist.required", true);
|
||||||
pref("devtools.errorconsole.enabled", false);
|
pref("devtools.errorconsole.enabled", false);
|
||||||
pref("devtools.inspector.enabled", false);
|
pref("devtools.inspector.enabled", false);
|
||||||
|
|
||||||
|
// Enable the Scratchpad tool.
|
||||||
|
pref("devtools.scratchpad.enabled", true);
|
||||||
|
|
||||||
|
// Enable tools for Chrome development.
|
||||||
|
pref("devtools.chrome.enabled", false);
|
||||||
|
|
||||||
// The last Web Console height. This is initially 0 which means that the Web
|
// The last Web Console height. This is initially 0 which means that the Web
|
||||||
// Console will use the default height next time it shows.
|
// Console will use the default height next time it shows.
|
||||||
// Change to -1 if you do not want the Web Console to remember its last height.
|
// Change to -1 if you do not want the Web Console to remember its last height.
|
||||||
|
|
|
@ -187,6 +187,11 @@
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
command="Tools:Inspect"
|
command="Tools:Inspect"
|
||||||
key="key_inspect"/>
|
key="key_inspect"/>
|
||||||
|
<menuitem id="appmenu_scratchpad"
|
||||||
|
hidden="true"
|
||||||
|
label="&scratchpad.label;"
|
||||||
|
key="key_scratchpad"
|
||||||
|
command="Tools:Scratchpad"/>
|
||||||
<menuitem id="appmenu_pageSource"
|
<menuitem id="appmenu_pageSource"
|
||||||
label="&viewPageSourceCmd.label;"
|
label="&viewPageSourceCmd.label;"
|
||||||
command="View:PageSource"
|
command="View:PageSource"
|
||||||
|
|
|
@ -315,11 +315,6 @@
|
||||||
</menu>
|
</menu>
|
||||||
#include browser-charsetmenu.inc
|
#include browser-charsetmenu.inc
|
||||||
<menuseparator/>
|
<menuseparator/>
|
||||||
<menuitem id="menu_pageSource"
|
|
||||||
accesskey="&pageSourceCmd.accesskey;"
|
|
||||||
label="&pageSourceCmd.label;"
|
|
||||||
key="key_viewSource"
|
|
||||||
command="View:PageSource"/>
|
|
||||||
<menuitem id="fullScreenItem"
|
<menuitem id="fullScreenItem"
|
||||||
accesskey="&fullScreenCmd.accesskey;"
|
accesskey="&fullScreenCmd.accesskey;"
|
||||||
label="&fullScreenCmd.label;"
|
label="&fullScreenCmd.label;"
|
||||||
|
@ -539,24 +534,41 @@
|
||||||
oncommand="gSyncUI.doSync(event);"/>
|
oncommand="gSyncUI.doSync(event);"/>
|
||||||
#endif
|
#endif
|
||||||
<menuseparator id="devToolsSeparator"/>
|
<menuseparator id="devToolsSeparator"/>
|
||||||
<menuitem id="menu_pageinspect"
|
<menu id="webDeveloperMenu"
|
||||||
type="checkbox"
|
label="&webDeveloperMenu.label;"
|
||||||
hidden="true"
|
accesskey="webDeveloperMenu.accesskey;">
|
||||||
label="&inspectMenu.label;"
|
<menupopup id="menuWebDeveloperPopup">
|
||||||
accesskey="&inspectMenu.accesskey;"
|
<menuitem id="webConsole"
|
||||||
key="key_inspect"
|
label="&webConsoleCmd.label;"
|
||||||
command="Tools:Inspect"/>
|
accesskey="&webConsoleCmd.accesskey;"
|
||||||
<menuitem id="javascriptConsole"
|
key="key_webConsole"
|
||||||
hidden="true"
|
oncommand="HUDConsoleUI.toggleHUD();"/>
|
||||||
label="&errorConsoleCmd.label;"
|
<menuitem id="menu_pageinspect"
|
||||||
accesskey="&errorConsoleCmd.accesskey;"
|
type="checkbox"
|
||||||
key="key_errorConsole"
|
hidden="true"
|
||||||
oncommand="toJavaScriptConsole();"/>
|
label="&inspectMenu.label;"
|
||||||
<menuitem id="webConsole"
|
accesskey="&inspectMenu.accesskey;"
|
||||||
label="&webConsoleCmd.label;"
|
key="key_inspect"
|
||||||
accesskey="&webConsoleCmd.accesskey;"
|
command="Tools:Inspect"/>
|
||||||
key="key_webConsole"
|
<menuitem id="menu_scratchpad"
|
||||||
oncommand="HUDConsoleUI.toggleHUD();"/>
|
hidden="true"
|
||||||
|
label="&scratchpad.label;"
|
||||||
|
accesskey="&scratchpad.accesskey;"
|
||||||
|
key="key_scratchpad"
|
||||||
|
command="Tools:Scratchpad"/>
|
||||||
|
<menuitem id="menu_pageSource"
|
||||||
|
accesskey="&pageSourceCmd.accesskey;"
|
||||||
|
label="&pageSourceCmd.label;"
|
||||||
|
key="key_viewSource"
|
||||||
|
command="View:PageSource"/>
|
||||||
|
<menuitem id="javascriptConsole"
|
||||||
|
hidden="true"
|
||||||
|
label="&errorConsoleCmd.label;"
|
||||||
|
accesskey="&errorConsoleCmd.accesskey;"
|
||||||
|
key="key_errorConsole"
|
||||||
|
oncommand="toJavaScriptConsole();"/>
|
||||||
|
</menupopup>
|
||||||
|
</menu>
|
||||||
<menuitem id="menu_pageInfo"
|
<menuitem id="menu_pageInfo"
|
||||||
accesskey="&pageInfoCmd.accesskey;"
|
accesskey="&pageInfoCmd.accesskey;"
|
||||||
label="&pageInfoCmd.label;"
|
label="&pageInfoCmd.label;"
|
||||||
|
|
|
@ -125,6 +125,7 @@
|
||||||
<command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
|
<command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
|
||||||
<command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/>
|
<command id="Tools:Downloads" oncommand="BrowserDownloadsUI();"/>
|
||||||
<command id="Tools:Inspect" oncommand="InspectorUI.toggleInspectorUI();" disabled="true"/>
|
<command id="Tools:Inspect" oncommand="InspectorUI.toggleInspectorUI();" disabled="true"/>
|
||||||
|
<command id="Tools:Scratchpad" oncommand="Scratchpad.openScratchpad();" disabled="true"/>
|
||||||
<command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
|
<command id="Tools:Addons" oncommand="BrowserOpenAddonsMgr();"/>
|
||||||
<command id="Tools:Sanitize"
|
<command id="Tools:Sanitize"
|
||||||
oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/>
|
oncommand="Cc['@mozilla.org/browser/browserglue;1'].getService(Ci.nsIBrowserGlue).sanitize(window);"/>
|
||||||
|
@ -241,6 +242,8 @@
|
||||||
<key id="key_errorConsole" key="&errorConsoleCmd.commandkey;" oncommand="toJavaScriptConsole();" modifiers="accel,shift" disabled="true"/>
|
<key id="key_errorConsole" key="&errorConsoleCmd.commandkey;" oncommand="toJavaScriptConsole();" modifiers="accel,shift" disabled="true"/>
|
||||||
<key id="key_webConsole" key="&webConsoleCmd.commandkey;" oncommand="HUDConsoleUI.toggleHUD();" modifiers="accel,shift"/>
|
<key id="key_webConsole" key="&webConsoleCmd.commandkey;" oncommand="HUDConsoleUI.toggleHUD();" modifiers="accel,shift"/>
|
||||||
<key id="key_inspect" key="&inspectMenu.commandkey;" command="Tools:Inspect" modifiers="accel,shift"/>
|
<key id="key_inspect" key="&inspectMenu.commandkey;" command="Tools:Inspect" modifiers="accel,shift"/>
|
||||||
|
<key id="key_scratchpad" keycode="&scratchpad.keycode;"
|
||||||
|
keytext="&scratchpad.keytext;" command="Tools:Scratchpad"/>
|
||||||
<key id="openFileKb" key="&openFileCmd.commandkey;" command="Browser:OpenFile" modifiers="accel"/>
|
<key id="openFileKb" key="&openFileCmd.commandkey;" command="Browser:OpenFile" modifiers="accel"/>
|
||||||
<key id="key_savePage" key="&savePageCmd.commandkey;" command="Browser:SavePage" modifiers="accel"/>
|
<key id="key_savePage" key="&savePageCmd.commandkey;" command="Browser:SavePage" modifiers="accel"/>
|
||||||
<key id="printKb" key="&printCmd.commandkey;" command="cmd_print" modifiers="accel"/>
|
<key id="printKb" key="&printCmd.commandkey;" command="cmd_print" modifiers="accel"/>
|
||||||
|
|
|
@ -54,6 +54,7 @@
|
||||||
# Rob Campbell <rcampbell@mozilla.com>
|
# Rob Campbell <rcampbell@mozilla.com>
|
||||||
# David Dahl <ddahl@mozilla.com>
|
# David Dahl <ddahl@mozilla.com>
|
||||||
# Patrick Walton <pcwalton@mozilla.com>
|
# Patrick Walton <pcwalton@mozilla.com>
|
||||||
|
# Mihai Sucan <mihai.sucan@gmail.com>
|
||||||
#
|
#
|
||||||
# Alternatively, the contents of this file may be used under the terms of
|
# 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
|
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||||
|
@ -1653,6 +1654,16 @@ function delayedStartup(isLoadingBlank, mustLoadSidebar) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Enable Scratchpad in the UI, if the preference allows this.
|
||||||
|
let scratchpadEnabled = gPrefService.getBoolPref(Scratchpad.prefEnabledName);
|
||||||
|
if (scratchpadEnabled) {
|
||||||
|
document.getElementById("menu_scratchpad").hidden = false;
|
||||||
|
document.getElementById("Tools:Scratchpad").removeAttribute("disabled");
|
||||||
|
#ifdef MENUBAR_CAN_AUTOHIDE
|
||||||
|
document.getElementById("appmenu_scratchpad").hidden = false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef MENUBAR_CAN_AUTOHIDE
|
#ifdef MENUBAR_CAN_AUTOHIDE
|
||||||
// If the user (or the locale) hasn't enabled the top-level "Character
|
// If the user (or the locale) hasn't enabled the top-level "Character
|
||||||
// Encoding" menu via the "browser.menu.showCharacterEncoding" preference,
|
// Encoding" menu via the "browser.menu.showCharacterEncoding" preference,
|
||||||
|
@ -2688,6 +2699,11 @@ function BrowserOnClick(event) {
|
||||||
gBrowser.loadURIWithFlags(content.location.href,
|
gBrowser.loadURIWithFlags(content.location.href,
|
||||||
nsIWebNavigation.LOAD_FLAGS_BYPASS_CLASSIFIER,
|
nsIWebNavigation.LOAD_FLAGS_BYPASS_CLASSIFIER,
|
||||||
null, null, null);
|
null, null, null);
|
||||||
|
|
||||||
|
Services.perms.add(makeURI(content.location.href), "safe-browsing",
|
||||||
|
Ci.nsIPermissionManager.ALLOW_ACTION,
|
||||||
|
Ci.nsIPermissionManager.EXPIRE_SESSION);
|
||||||
|
|
||||||
let buttons = [{
|
let buttons = [{
|
||||||
label: gNavigatorBundle.getString("safebrowsing.getMeOutOfHereButton.label"),
|
label: gNavigatorBundle.getString("safebrowsing.getMeOutOfHereButton.label"),
|
||||||
accessKey: gNavigatorBundle.getString("safebrowsing.getMeOutOfHereButton.accessKey"),
|
accessKey: gNavigatorBundle.getString("safebrowsing.getMeOutOfHereButton.accessKey"),
|
||||||
|
@ -7274,8 +7290,7 @@ var FeedHandler = {
|
||||||
* a page is loaded or the user switches tabs to a page that has feeds.
|
* a page is loaded or the user switches tabs to a page that has feeds.
|
||||||
*/
|
*/
|
||||||
updateFeeds: function() {
|
updateFeeds: function() {
|
||||||
if (this._updateFeedTimeout)
|
clearTimeout(this._updateFeedTimeout);
|
||||||
clearTimeout(this._updateFeedTimeout);
|
|
||||||
|
|
||||||
var feeds = gBrowser.selectedBrowser.feeds;
|
var feeds = gBrowser.selectedBrowser.feeds;
|
||||||
var haveFeeds = feeds && feeds.length > 0;
|
var haveFeeds = feeds && feeds.length > 0;
|
||||||
|
@ -7320,8 +7335,7 @@ var FeedHandler = {
|
||||||
if (browserForLink == gBrowser.selectedBrowser) {
|
if (browserForLink == gBrowser.selectedBrowser) {
|
||||||
// Batch updates to avoid updating the UI for multiple onLinkAdded events
|
// Batch updates to avoid updating the UI for multiple onLinkAdded events
|
||||||
// fired within 100ms of each other.
|
// fired within 100ms of each other.
|
||||||
if (this._updateFeedTimeout)
|
clearTimeout(this._updateFeedTimeout);
|
||||||
clearTimeout(this._updateFeedTimeout);
|
|
||||||
this._updateFeedTimeout = setTimeout(this.updateFeeds.bind(this), 100);
|
this._updateFeedTimeout = setTimeout(this.updateFeeds.bind(this), 100);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8628,6 +8642,19 @@ function toggleAddonBar() {
|
||||||
setToolbarVisibility(addonBar, addonBar.collapsed);
|
setToolbarVisibility(addonBar, addonBar.collapsed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var Scratchpad = {
|
||||||
|
prefEnabledName: "devtools.scratchpad.enabled",
|
||||||
|
|
||||||
|
openScratchpad: function SP_openScratchpad() {
|
||||||
|
const SCRATCHPAD_WINDOW_URL = "chrome://browser/content/scratchpad.xul";
|
||||||
|
const SCRATCHPAD_WINDOW_FEATURES = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
|
||||||
|
|
||||||
|
return Services.ww.openWindow(null, SCRATCHPAD_WINDOW_URL, "_blank",
|
||||||
|
SCRATCHPAD_WINDOW_FEATURES, null);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(window, "gShowPageResizers", function () {
|
XPCOMUtils.defineLazyGetter(window, "gShowPageResizers", function () {
|
||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
// Only show resizers on Windows 2000 and XP
|
// Only show resizers on Windows 2000 and XP
|
||||||
|
|
|
@ -240,7 +240,7 @@
|
||||||
noautohide="true"
|
noautohide="true"
|
||||||
titlebar="normal"
|
titlebar="normal"
|
||||||
close="true"
|
close="true"
|
||||||
onpopuphiding="InspectorUI.closeInspectorUI(true);"
|
onpopuphiding="InspectorUI.closeInspectorUI();"
|
||||||
label="&inspectPanelTitle.label;">
|
label="&inspectPanelTitle.label;">
|
||||||
<toolbar id="inspector-toolbar"
|
<toolbar id="inspector-toolbar"
|
||||||
nowindowdrag="true">
|
nowindowdrag="true">
|
||||||
|
|
|
@ -347,7 +347,7 @@ var InspectorUI = {
|
||||||
toggleInspectorUI: function IUI_toggleInspectorUI(aEvent)
|
toggleInspectorUI: function IUI_toggleInspectorUI(aEvent)
|
||||||
{
|
{
|
||||||
if (this.isTreePanelOpen) {
|
if (this.isTreePanelOpen) {
|
||||||
this.closeInspectorUI(true);
|
this.closeInspectorUI();
|
||||||
} else {
|
} else {
|
||||||
this.openInspectorUI();
|
this.openInspectorUI();
|
||||||
}
|
}
|
||||||
|
@ -738,10 +738,12 @@ var InspectorUI = {
|
||||||
* Remove event listeners for document scrolling, resize,
|
* Remove event listeners for document scrolling, resize,
|
||||||
* tabContainer.TabSelect and others.
|
* tabContainer.TabSelect and others.
|
||||||
*
|
*
|
||||||
* @param boolean aClearStore tells if you want the store associated to the
|
* @param boolean aKeepStore
|
||||||
* current tab/window to be cleared or not.
|
* Tells if you want the store associated to the current tab/window to
|
||||||
|
* be cleared or not. Set this to true to not clear the store, or false
|
||||||
|
* otherwise.
|
||||||
*/
|
*/
|
||||||
closeInspectorUI: function IUI_closeInspectorUI(aClearStore)
|
closeInspectorUI: function IUI_closeInspectorUI(aKeepStore)
|
||||||
{
|
{
|
||||||
if (this.closing || !this.win || !this.browser) {
|
if (this.closing || !this.win || !this.browser) {
|
||||||
return;
|
return;
|
||||||
|
@ -749,7 +751,7 @@ var InspectorUI = {
|
||||||
|
|
||||||
this.closing = true;
|
this.closing = true;
|
||||||
|
|
||||||
if (aClearStore) {
|
if (!aKeepStore) {
|
||||||
InspectorStore.deleteStore(this.winID);
|
InspectorStore.deleteStore(this.winID);
|
||||||
this.win.removeEventListener("pagehide", this, true);
|
this.win.removeEventListener("pagehide", this, true);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1028,7 +1030,7 @@ var InspectorUI = {
|
||||||
case "TabSelect":
|
case "TabSelect":
|
||||||
winID = this.getWindowID(gBrowser.selectedBrowser.contentWindow);
|
winID = this.getWindowID(gBrowser.selectedBrowser.contentWindow);
|
||||||
if (this.isTreePanelOpen && winID != this.winID) {
|
if (this.isTreePanelOpen && winID != this.winID) {
|
||||||
this.closeInspectorUI(false);
|
this.closeInspectorUI(true);
|
||||||
inspectorClosed = true;
|
inspectorClosed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -497,9 +497,9 @@ nsContextMenu.prototype = {
|
||||||
}
|
}
|
||||||
else if (this.target instanceof HTMLInputElement ) {
|
else if (this.target instanceof HTMLInputElement ) {
|
||||||
this.onTextInput = this.isTargetATextBox(this.target);
|
this.onTextInput = this.isTargetATextBox(this.target);
|
||||||
// allow spellchecking UI on all writable text boxes except passwords
|
// Allow spellchecking UI on all text and search inputs.
|
||||||
if (this.onTextInput && ! this.target.readOnly &&
|
if (this.onTextInput && ! this.target.readOnly &&
|
||||||
this.target.type != "password") {
|
(this.target.type == "text" || this.target.type == "search")) {
|
||||||
this.onEditableArea = true;
|
this.onEditableArea = true;
|
||||||
InlineSpellCheckerUI.init(this.target.QueryInterface(Ci.nsIDOMNSEditableElement).editor);
|
InlineSpellCheckerUI.init(this.target.QueryInterface(Ci.nsIDOMNSEditableElement).editor);
|
||||||
InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
|
InlineSpellCheckerUI.initFromEvent(aRangeParent, aRangeOffset);
|
||||||
|
|
|
@ -0,0 +1,627 @@
|
||||||
|
/* vim:set ts=2 sw=2 sts=2 et:
|
||||||
|
* ***** 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 Scratchpad.
|
||||||
|
*
|
||||||
|
* The Initial Developer of the Original Code is
|
||||||
|
* The Mozilla Foundation.
|
||||||
|
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||||
|
* the Initial Developer. All Rights Reserved.
|
||||||
|
*
|
||||||
|
* Contributor(s):
|
||||||
|
* Rob Campbell <robcee@mozilla.com> (original author)
|
||||||
|
* Erik Vold <erikvvold@gmail.com>
|
||||||
|
* David Dahl <ddahl@mozilla.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
|
||||||
|
* 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 *****/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Original version history can be found here:
|
||||||
|
* https://github.com/mozilla/workspace
|
||||||
|
*
|
||||||
|
* Copied and relicensed from the Public Domain.
|
||||||
|
* See bug 653934 for details.
|
||||||
|
* https://bugzilla.mozilla.org/show_bug.cgi?id=653934
|
||||||
|
*/
|
||||||
|
|
||||||
|
const Cc = Components.classes;
|
||||||
|
const Ci = Components.interfaces;
|
||||||
|
const Cu = Components.utils;
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||||
|
Cu.import("resource:///modules/PropertyPanel.jsm");
|
||||||
|
|
||||||
|
const SCRATCHPAD_CONTEXT_CONTENT = 1;
|
||||||
|
const SCRATCHPAD_CONTEXT_CHROME = 2;
|
||||||
|
const SCRATCHPAD_WINDOW_URL = "chrome://browser/content/scratchpad.xul";
|
||||||
|
const SCRATCHPAD_L10N = "chrome://browser/locale/scratchpad.properties";
|
||||||
|
const SCRATCHPAD_WINDOW_FEATURES = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
|
||||||
|
const DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The scratchpad object handles the Scratchpad window functionality.
|
||||||
|
*/
|
||||||
|
var Scratchpad = {
|
||||||
|
/**
|
||||||
|
* The script execution context. This tells Scratchpad in which context the
|
||||||
|
* script shall execute.
|
||||||
|
*
|
||||||
|
* Possible values:
|
||||||
|
* - SCRATCHPAD_CONTEXT_CONTENT to execute code in the context of the current
|
||||||
|
* tab content window object.
|
||||||
|
* - SCRATCHPAD_CONTEXT_CHROME to execute code in the context of the
|
||||||
|
* currently active chrome window object.
|
||||||
|
*/
|
||||||
|
executionContext: SCRATCHPAD_CONTEXT_CONTENT,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the xul:textbox DOM element. This element holds the source code
|
||||||
|
* the user writes and executes.
|
||||||
|
*/
|
||||||
|
get textbox() document.getElementById("scratchpad-textbox"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the xul:statusbarpanel DOM element. The status bar tells the
|
||||||
|
* current code execution context.
|
||||||
|
*/
|
||||||
|
get statusbarStatus() document.getElementById("scratchpad-status"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the selected text from the textbox.
|
||||||
|
*/
|
||||||
|
get selectedText()
|
||||||
|
{
|
||||||
|
return this.textbox.value.substring(this.textbox.selectionStart,
|
||||||
|
this.textbox.selectionEnd);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the most recent chrome window of type navigator:browser.
|
||||||
|
*/
|
||||||
|
get browserWindow() Services.wm.getMostRecentWindow("navigator:browser"),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reference to the last chrome window of type navigator:browser. We use this
|
||||||
|
* to check if the chrome window changed since the last code evaluation.
|
||||||
|
*/
|
||||||
|
_previousWindow: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the gBrowser object of the most recent browser window.
|
||||||
|
*/
|
||||||
|
get gBrowser()
|
||||||
|
{
|
||||||
|
let recentWin = this.browserWindow;
|
||||||
|
return recentWin ? recentWin.gBrowser : null;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached Cu.Sandbox object for the active tab content window object.
|
||||||
|
*/
|
||||||
|
_contentSandbox: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Cu.Sandbox object for the active tab content window object. Note
|
||||||
|
* that the returned object is cached for later reuse. The cached object is
|
||||||
|
* kept only for the current browser window and it is reset for each context
|
||||||
|
* switch or navigator:browser window switch.
|
||||||
|
*/
|
||||||
|
get contentSandbox()
|
||||||
|
{
|
||||||
|
if (!this.browserWindow) {
|
||||||
|
Cu.reportError(this.strings.
|
||||||
|
GetStringFromName("browserWindow.unavailable"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._contentSandbox ||
|
||||||
|
this.browserWindow != this._previousBrowserWindow) {
|
||||||
|
let contentWindow = this.gBrowser.selectedBrowser.contentWindow;
|
||||||
|
this._contentSandbox = new Cu.Sandbox(contentWindow,
|
||||||
|
{ sandboxPrototype: contentWindow, wantXrays: false });
|
||||||
|
|
||||||
|
this._previousBrowserWindow = this.browserWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._contentSandbox;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached Cu.Sandbox object for the most recently active navigator:browser
|
||||||
|
* chrome window object.
|
||||||
|
*/
|
||||||
|
_chromeSandbox: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the Cu.Sandbox object for the most recently active navigator:browser
|
||||||
|
* chrome window object. Note that the returned object is cached for later
|
||||||
|
* reuse. The cached object is kept only for the current browser window and it
|
||||||
|
* is reset for each context switch or navigator:browser window switch.
|
||||||
|
*/
|
||||||
|
get chromeSandbox()
|
||||||
|
{
|
||||||
|
if (!this.browserWindow) {
|
||||||
|
Cu.reportError(this.strings.
|
||||||
|
GetStringFromName("browserWindow.unavailable"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this._chromeSandbox ||
|
||||||
|
this.browserWindow != this._previousBrowserWindow) {
|
||||||
|
this._chromeSandbox = new Cu.Sandbox(this.browserWindow,
|
||||||
|
{ sandboxPrototype: this.browserWindow, wantXrays: false });
|
||||||
|
|
||||||
|
this._previousBrowserWindow = this.browserWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this._chromeSandbox;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drop the textbox selection.
|
||||||
|
*/
|
||||||
|
deselect: function SP_deselect()
|
||||||
|
{
|
||||||
|
this.textbox.selectionEnd = this.textbox.selectionStart;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Select a specific range in the Scratchpad xul:textbox.
|
||||||
|
*
|
||||||
|
* @param number aStart
|
||||||
|
* Selection range start.
|
||||||
|
* @param number aEnd
|
||||||
|
* Selection range end.
|
||||||
|
*/
|
||||||
|
selectRange: function SP_selectRange(aStart, aEnd)
|
||||||
|
{
|
||||||
|
this.textbox.selectionStart = aStart;
|
||||||
|
this.textbox.selectionEnd = aEnd;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate a string in the active tab content window.
|
||||||
|
*
|
||||||
|
* @param string aString
|
||||||
|
* The script you want evaluated.
|
||||||
|
* @return mixed
|
||||||
|
* The script evaluation result.
|
||||||
|
*/
|
||||||
|
evalInContentSandbox: function SP_evalInContentSandbox(aString)
|
||||||
|
{
|
||||||
|
let result;
|
||||||
|
try {
|
||||||
|
result = Cu.evalInSandbox(aString, this.contentSandbox, "1.8",
|
||||||
|
"Scratchpad", 1);
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
this.openWebConsole();
|
||||||
|
|
||||||
|
let contentWindow = this.gBrowser.selectedBrowser.contentWindow;
|
||||||
|
|
||||||
|
let scriptError = Cc["@mozilla.org/scripterror;1"].
|
||||||
|
createInstance(Ci.nsIScriptError2);
|
||||||
|
|
||||||
|
scriptError.initWithWindowID(ex.message + "\n" + ex.stack, ex.fileName,
|
||||||
|
"", ex.lineNumber, 0, scriptError.errorFlag,
|
||||||
|
"content javascript",
|
||||||
|
this.getWindowId(contentWindow));
|
||||||
|
|
||||||
|
Services.console.logMessage(scriptError);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate a string in the most recent navigator:browser chrome window.
|
||||||
|
*
|
||||||
|
* @param string aString
|
||||||
|
* The script you want evaluated.
|
||||||
|
* @return mixed
|
||||||
|
* The script evaluation result.
|
||||||
|
*/
|
||||||
|
evalInChromeSandbox: function SP_evalInChromeSandbox(aString)
|
||||||
|
{
|
||||||
|
let result;
|
||||||
|
try {
|
||||||
|
result = Cu.evalInSandbox(aString, this.chromeSandbox, "1.8",
|
||||||
|
"Scratchpad", 1);
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
Cu.reportError(ex);
|
||||||
|
Cu.reportError(ex.stack);
|
||||||
|
this.openErrorConsole();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Evaluate a string in the currently desired context, that is either the
|
||||||
|
* chrome window or the tab content window object.
|
||||||
|
*
|
||||||
|
* @param string aString
|
||||||
|
* The script you want to evaluate.
|
||||||
|
* @return mixed
|
||||||
|
* The script evaluation result.
|
||||||
|
*/
|
||||||
|
evalForContext: function SP_evaluateForContext(aString)
|
||||||
|
{
|
||||||
|
return this.executionContext == SCRATCHPAD_CONTEXT_CONTENT ?
|
||||||
|
this.evalInContentSandbox(aString) :
|
||||||
|
this.evalInChromeSandbox(aString);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the selected text (if any) or the entire textbox content in the
|
||||||
|
* current context.
|
||||||
|
*/
|
||||||
|
execute: function SP_execute()
|
||||||
|
{
|
||||||
|
let selection = this.selectedText || this.textbox.value;
|
||||||
|
let result = this.evalForContext(selection);
|
||||||
|
this.deselect();
|
||||||
|
return [selection, result];
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the selected text (if any) or the entire textbox content in the
|
||||||
|
* current context. The resulting object is opened up in the Property Panel
|
||||||
|
* for inspection.
|
||||||
|
*/
|
||||||
|
inspect: function SP_inspect()
|
||||||
|
{
|
||||||
|
let [selection, result] = this.execute();
|
||||||
|
|
||||||
|
if (result) {
|
||||||
|
this.openPropertyPanel(selection, result);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Execute the selected text (if any) or the entire textbox content in the
|
||||||
|
* current context. The evaluation result is "printed" in the textbox after
|
||||||
|
* the selected text, or at the end of the textbox value if there is no
|
||||||
|
* selected text.
|
||||||
|
*/
|
||||||
|
print: function SP_print()
|
||||||
|
{
|
||||||
|
let selectionStart = this.textbox.selectionStart;
|
||||||
|
let selectionEnd = this.textbox.selectionEnd;
|
||||||
|
if (selectionStart == selectionEnd) {
|
||||||
|
selectionEnd = this.textbox.value.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
let [selection, result] = this.execute();
|
||||||
|
if (!result) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let firstPiece = this.textbox.value.slice(0, selectionEnd);
|
||||||
|
let lastPiece = this.textbox.value.
|
||||||
|
slice(selectionEnd, this.textbox.value.length);
|
||||||
|
|
||||||
|
let newComment = "/*\n" + result.toString() + "\n*/";
|
||||||
|
|
||||||
|
this.textbox.value = firstPiece + newComment + lastPiece;
|
||||||
|
|
||||||
|
// Select the added comment.
|
||||||
|
this.selectRange(firstPiece.length, firstPiece.length + newComment.length);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the Property Panel to inspect the given object.
|
||||||
|
*
|
||||||
|
* @param string aEvalString
|
||||||
|
* The string that was evaluated. This is re-used when the user updates
|
||||||
|
* the properties list, by clicking the Update button.
|
||||||
|
* @param object aOutputObject
|
||||||
|
* The object to inspect, which is the aEvalString evaluation result.
|
||||||
|
* @return object
|
||||||
|
* The PropertyPanel object instance.
|
||||||
|
*/
|
||||||
|
openPropertyPanel: function SP_openPropertyPanel(aEvalString, aOutputObject)
|
||||||
|
{
|
||||||
|
let self = this;
|
||||||
|
let propPanel;
|
||||||
|
// The property panel has a button:
|
||||||
|
// `Update`: reexecutes the string executed on the command line. The
|
||||||
|
// result will be inspected by this panel.
|
||||||
|
let buttons = [];
|
||||||
|
|
||||||
|
// If there is a evalString passed to this function, then add a `Update`
|
||||||
|
// button to the panel so that the evalString can be reexecuted to update
|
||||||
|
// the content of the panel.
|
||||||
|
if (aEvalString !== null) {
|
||||||
|
buttons.push({
|
||||||
|
label: this.strings.
|
||||||
|
GetStringFromName("propertyPanel.updateButton.label"),
|
||||||
|
accesskey: this.strings.
|
||||||
|
GetStringFromName("propertyPanel.updateButton.accesskey"),
|
||||||
|
oncommand: function () {
|
||||||
|
try {
|
||||||
|
let result = self.evalForContext(aEvalString);
|
||||||
|
|
||||||
|
if (result !== undefined) {
|
||||||
|
propPanel.treeView.data = result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ex) { }
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let doc = this.browserWindow.document;
|
||||||
|
let parent = doc.getElementById("mainPopupSet");
|
||||||
|
let title = aOutputObject.toString();
|
||||||
|
propPanel = new PropertyPanel(parent, doc, title, aOutputObject, buttons);
|
||||||
|
|
||||||
|
let panel = propPanel.panel;
|
||||||
|
panel.setAttribute("class", "scratchpad_propertyPanel");
|
||||||
|
panel.openPopup(null, "after_pointer", 0, 0, false, false);
|
||||||
|
panel.sizeTo(200, 400);
|
||||||
|
|
||||||
|
return propPanel;
|
||||||
|
},
|
||||||
|
|
||||||
|
// Menu Operations
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a new Scratchpad window.
|
||||||
|
*/
|
||||||
|
openScratchpad: function SP_openScratchpad()
|
||||||
|
{
|
||||||
|
Services.ww.openWindow(null, SCRATCHPAD_WINDOW_URL, "_blank",
|
||||||
|
SCRATCHPAD_WINDOW_FEATURES, null);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Export the textbox content to a file.
|
||||||
|
*
|
||||||
|
* @param nsILocalFile aFile
|
||||||
|
* The file where you want to save the textbox content.
|
||||||
|
* @param boolean aNoConfirmation
|
||||||
|
* If the file already exists, ask for confirmation?
|
||||||
|
* @param boolean aSilentError
|
||||||
|
* True if you do not want to display an error when file save fails,
|
||||||
|
* false otherwise.
|
||||||
|
* @param function aCallback
|
||||||
|
* Optional function you want to call when file save completes. It will
|
||||||
|
* get the following arguments:
|
||||||
|
* 1) the nsresult status code for the export operation.
|
||||||
|
*/
|
||||||
|
exportToFile: function SP_exportToFile(aFile, aNoConfirmation, aSilentError,
|
||||||
|
aCallback)
|
||||||
|
{
|
||||||
|
if (!aNoConfirmation && aFile.exists() &&
|
||||||
|
!window.confirm(this.strings.
|
||||||
|
GetStringFromName("export.fileOverwriteConfirmation"))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let fs = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||||
|
createInstance(Ci.nsIFileOutputStream);
|
||||||
|
let modeFlags = 0x02 | 0x08 | 0x20;
|
||||||
|
fs.init(aFile, modeFlags, 0644, fs.DEFER_OPEN);
|
||||||
|
|
||||||
|
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||||
|
createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||||
|
converter.charset = "UTF-8";
|
||||||
|
let input = converter.convertToInputStream(this.textbox.value);
|
||||||
|
|
||||||
|
let self = this;
|
||||||
|
NetUtil.asyncCopy(input, fs, function(aStatus) {
|
||||||
|
if (!aSilentError && !Components.isSuccessCode(aStatus)) {
|
||||||
|
window.alert(self.strings.GetStringFromName("saveFile.failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aCallback) {
|
||||||
|
aCallback.call(self, aStatus);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read the content of a file and put it into the textbox.
|
||||||
|
*
|
||||||
|
* @param nsILocalFile aFile
|
||||||
|
* The file you want to save the textbox content into.
|
||||||
|
* @param boolean aSilentError
|
||||||
|
* True if you do not want to display an error when file load fails,
|
||||||
|
* false otherwise.
|
||||||
|
* @param function aCallback
|
||||||
|
* Optional function you want to call when file load completes. It will
|
||||||
|
* get the following arguments:
|
||||||
|
* 1) the nsresult status code for the import operation.
|
||||||
|
* 2) the data that was read from the file, if any.
|
||||||
|
*/
|
||||||
|
importFromFile: function SP_importFromFile(aFile, aSilentError, aCallback)
|
||||||
|
{
|
||||||
|
// Prevent file type detection.
|
||||||
|
let channel = NetUtil.newChannel(aFile);
|
||||||
|
channel.contentType = "application/javascript";
|
||||||
|
|
||||||
|
let self = this;
|
||||||
|
NetUtil.asyncFetch(channel, function(aInputStream, aStatus) {
|
||||||
|
let content = null;
|
||||||
|
|
||||||
|
if (Components.isSuccessCode(aStatus)) {
|
||||||
|
content = NetUtil.readInputStreamToString(aInputStream,
|
||||||
|
aInputStream.available());
|
||||||
|
self.textbox.value = content;
|
||||||
|
}
|
||||||
|
else if (!aSilentError) {
|
||||||
|
window.alert(self.strings.GetStringFromName("openFile.failed"));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (aCallback) {
|
||||||
|
aCallback.call(self, aStatus, content);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open a file to edit in the Scratchpad.
|
||||||
|
*/
|
||||||
|
openFile: function SP_openFile()
|
||||||
|
{
|
||||||
|
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||||
|
fp.init(window, this.strings.GetStringFromName("openFile.title"),
|
||||||
|
Ci.nsIFilePicker.modeOpen);
|
||||||
|
fp.defaultString = "";
|
||||||
|
if (fp.show() != Ci.nsIFilePicker.returnCancel) {
|
||||||
|
document.title = this.filename = fp.file.path;
|
||||||
|
this.importFromFile(fp.file);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the textbox content to the currently open file.
|
||||||
|
*/
|
||||||
|
saveFile: function SP_saveFile()
|
||||||
|
{
|
||||||
|
if (!this.filename) {
|
||||||
|
return this.saveFileAs();
|
||||||
|
}
|
||||||
|
|
||||||
|
let file = Cc["@mozilla.org/file/local;1"].createInstance(Ci.nsILocalFile);
|
||||||
|
file.initWithPath(this.filename);
|
||||||
|
this.exportToFile(file, true);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the textbox content to a new file.
|
||||||
|
*/
|
||||||
|
saveFileAs: function SP_saveFileAs()
|
||||||
|
{
|
||||||
|
let fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
|
||||||
|
fp.init(window, this.strings.GetStringFromName("saveFileAs"),
|
||||||
|
Ci.nsIFilePicker.modeSave);
|
||||||
|
fp.defaultString = "scratchpad.js";
|
||||||
|
if (fp.show() != Ci.nsIFilePicker.returnCancel) {
|
||||||
|
document.title = this.filename = fp.file.path;
|
||||||
|
this.exportToFile(fp.file);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the Error Console.
|
||||||
|
*/
|
||||||
|
openErrorConsole: function SP_openErrorConsole()
|
||||||
|
{
|
||||||
|
this.browserWindow.toJavaScriptConsole();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open the Web Console.
|
||||||
|
*/
|
||||||
|
openWebConsole: function SP_openWebConsole()
|
||||||
|
{
|
||||||
|
if (!this.browserWindow.HUDConsoleUI.getOpenHUD()) {
|
||||||
|
this.browserWindow.HUDConsoleUI.toggleHUD();
|
||||||
|
}
|
||||||
|
this.browserWindow.focus();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current execution context to be the active tab content window.
|
||||||
|
*/
|
||||||
|
setContentContext: function SP_setContentContext()
|
||||||
|
{
|
||||||
|
let content = document.getElementById("sp-menu-content");
|
||||||
|
document.getElementById("sp-menu-chrome").removeAttribute("checked");
|
||||||
|
content.setAttribute("checked", true);
|
||||||
|
this.statusbarStatus.label = content.getAttribute("label");
|
||||||
|
this.executionContext = SCRATCHPAD_CONTEXT_CONTENT;
|
||||||
|
this.resetContext();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the current execution context to be the most recent chrome window.
|
||||||
|
*/
|
||||||
|
setChromeContext: function SP_setChromeContext()
|
||||||
|
{
|
||||||
|
let chrome = document.getElementById("sp-menu-chrome");
|
||||||
|
document.getElementById("sp-menu-content").removeAttribute("checked");
|
||||||
|
chrome.setAttribute("checked", true);
|
||||||
|
this.statusbarStatus.label = chrome.getAttribute("label");
|
||||||
|
this.executionContext = SCRATCHPAD_CONTEXT_CHROME;
|
||||||
|
this.resetContext();
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the cached Cu.Sandbox object for the current context.
|
||||||
|
*/
|
||||||
|
resetContext: function SP_resetContext()
|
||||||
|
{
|
||||||
|
this._chromeSandbox = null;
|
||||||
|
this._contentSandbox = null;
|
||||||
|
this._previousWindow = null;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ID of the outer window of the given DOM window object.
|
||||||
|
*
|
||||||
|
* @param nsIDOMWindow aWindow
|
||||||
|
* @return integer
|
||||||
|
* the outer window ID
|
||||||
|
*/
|
||||||
|
getWindowId: function SP_getWindowId(aWindow)
|
||||||
|
{
|
||||||
|
return aWindow.QueryInterface(Ci.nsIInterfaceRequestor).
|
||||||
|
getInterface(Ci.nsIDOMWindowUtils).outerWindowID;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The Scratchpad window DOMContentLoaded event handler.
|
||||||
|
*/
|
||||||
|
onLoad: function SP_onLoad()
|
||||||
|
{
|
||||||
|
let chromeContextMenu = document.getElementById("sp-menu-chrome");
|
||||||
|
let errorConsoleMenu = document.getElementById("sp-menu-errorConsole");
|
||||||
|
let errorConsoleCommand = document.getElementById("sp-cmd-errorConsole");
|
||||||
|
let chromeContextCommand = document.getElementById("sp-cmd-chromeContext");
|
||||||
|
|
||||||
|
let chrome = Services.prefs.getBoolPref(DEVTOOLS_CHROME_ENABLED);
|
||||||
|
if (chrome) {
|
||||||
|
chromeContextMenu.removeAttribute("hidden");
|
||||||
|
errorConsoleMenu.removeAttribute("hidden");
|
||||||
|
errorConsoleCommand.removeAttribute("disabled");
|
||||||
|
chromeContextCommand.removeAttribute("disabled");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyGetter(Scratchpad, "strings", function () {
|
||||||
|
return Services.strings.createBundle(SCRATCHPAD_L10N);
|
||||||
|
});
|
||||||
|
|
||||||
|
addEventListener("DOMContentLoaded", Scratchpad.onLoad.bind(Scratchpad), false);
|
||||||
|
|
|
@ -0,0 +1,338 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
#ifdef 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 Scratchpad.
|
||||||
|
-
|
||||||
|
- The Initial Developer of the Original Code is
|
||||||
|
- The Mozilla Foundation.
|
||||||
|
- Portions created by the Initial Developer are Copyright (C) 2011
|
||||||
|
- the Initial Developer. All Rights Reserved.
|
||||||
|
-
|
||||||
|
- Contributor(s):
|
||||||
|
- Rob Campbell <robcee@mozilla.com> (original author)
|
||||||
|
- Mihai Sucan <mihai.sucan@gmail.com>
|
||||||
|
- Erik Vold <erikvvold@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
|
||||||
|
- 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 ***** -->
|
||||||
|
#endif
|
||||||
|
<!DOCTYPE window [
|
||||||
|
<!ENTITY % scratchpadDTD SYSTEM "chrome://browser/locale/scratchpad.dtd" >
|
||||||
|
%scratchpadDTD;
|
||||||
|
]>
|
||||||
|
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>
|
||||||
|
<?xul-overlay href="chrome://global/content/editMenuOverlay.xul"?>
|
||||||
|
|
||||||
|
<window id="main-window"
|
||||||
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
|
title="&window.title;"
|
||||||
|
windowtype="devtools:scratchpad"
|
||||||
|
screenX="4" screenY="4"
|
||||||
|
width="640" height="480"
|
||||||
|
persist="screenX screenY width height sizemode">
|
||||||
|
|
||||||
|
<script type="application/javascript" src="chrome://global/content/globalOverlay.js"/>
|
||||||
|
<script type="application/javascript" src="chrome://browser/content/scratchpad.js"/>
|
||||||
|
|
||||||
|
<commandset id="editMenuCommands"/>
|
||||||
|
|
||||||
|
<commandset id="sp-commandset">
|
||||||
|
<command id="sp-cmd-newWindow" oncommand="Scratchpad.openScratchpad();"/>
|
||||||
|
<command id="sp-cmd-openFile" oncommand="Scratchpad.openFile();"/>
|
||||||
|
<command id="sp-cmd-save" oncommand="Scratchpad.saveFile();"/>
|
||||||
|
<command id="sp-cmd-saveas" oncommand="Scratchpad.saveFileAs();"/>
|
||||||
|
|
||||||
|
<!-- TODO: bug 650340 - implement printFile()
|
||||||
|
<command id="sp-cmd-printFile" oncommand="Scratchpad.printFile();" disabled="true"/>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<command id="sp-cmd-close" oncommand="window.close();"/>
|
||||||
|
<command id="sp-cmd-execute" oncommand="Scratchpad.execute();"/>
|
||||||
|
<command id="sp-cmd-inspect" oncommand="Scratchpad.inspect();"/>
|
||||||
|
<command id="sp-cmd-print" oncommand="Scratchpad.print();"/>
|
||||||
|
<command id="sp-cmd-contentContext" oncommand="Scratchpad.setContentContext();"/>
|
||||||
|
<command id="sp-cmd-chromeContext" oncommand="Scratchpad.setChromeContext();" disabled="true"/>
|
||||||
|
<command id="sp-cmd-resetContext" oncommand="Scratchpad.resetContext();"/>
|
||||||
|
<command id="sp-cmd-errorConsole" oncommand="Scratchpad.openErrorConsole();" disabled="true"/>
|
||||||
|
<command id="sp-cmd-webConsole" oncommand="Scratchpad.openWebConsole();"/>
|
||||||
|
</commandset>
|
||||||
|
|
||||||
|
<keyset id="sp-keyset">
|
||||||
|
<key id="sp-key-window"
|
||||||
|
key="&newWindowCmd.commandkey;"
|
||||||
|
command="sp-cmd-newWindow"
|
||||||
|
modifiers="accel"/>
|
||||||
|
<key id="sp-key-open"
|
||||||
|
key="&openFileCmd.commandkey;"
|
||||||
|
command="sp-cmd-openFile"
|
||||||
|
modifiers="accel"/>
|
||||||
|
<key id="sp-key-save"
|
||||||
|
key="&saveFileCmd.commandkey;"
|
||||||
|
command="sp-cmd-save"
|
||||||
|
modifiers="accel"/>
|
||||||
|
<key id="sp-key-close"
|
||||||
|
key="&closeCmd.key;"
|
||||||
|
command="sp-cmd-close"
|
||||||
|
modifiers="accel"/>
|
||||||
|
|
||||||
|
<!-- TODO: bug 650340 - implement printFile
|
||||||
|
<key id="sp-key-printFile"
|
||||||
|
key="&printCmd.commandkey;"
|
||||||
|
command="sp-cmd-printFile"
|
||||||
|
modifiers="accel"/>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<key id="key_cut"
|
||||||
|
key="&cutCmd.key;"
|
||||||
|
modifiers="accel"/>
|
||||||
|
|
||||||
|
<key id="key_copy"
|
||||||
|
key="©Cmd.key;"
|
||||||
|
modifiers="accel"/>
|
||||||
|
<key id="key_paste"
|
||||||
|
key="&pasteCmd.key;"
|
||||||
|
modifiers="accel"/>
|
||||||
|
<key id="key_selectAll" key="&selectAllCmd.key;" modifiers="accel"/>
|
||||||
|
<key id="key_undo" key="&undoCmd.key;" modifiers="accel"/>
|
||||||
|
<key id="key_redo" key="&undoCmd.key;" modifiers="accel,shift"/>
|
||||||
|
<key id="sp-key-execute"
|
||||||
|
key="&execute.key;"
|
||||||
|
command="sp-cmd-execute"
|
||||||
|
modifiers="accel"/>
|
||||||
|
<key id="sp-key-inspect"
|
||||||
|
key="&inspect.key;"
|
||||||
|
command="sp-cmd-inspect"
|
||||||
|
modifiers="accel"/>
|
||||||
|
<key id="sp-key-print"
|
||||||
|
key="&print.key;"
|
||||||
|
command="sp-cmd-print"
|
||||||
|
modifiers="accel"/>
|
||||||
|
<key id="sp-key-errorConsole"
|
||||||
|
key="&errorConsoleCmd.commandkey;"
|
||||||
|
command="sp-cmd-errorConsole"
|
||||||
|
modifiers="accel,shift"/>
|
||||||
|
<key id="sp-key-webConsole"
|
||||||
|
key="&webConsoleCmd.commandkey;"
|
||||||
|
command="sp-cmd-webConsole"
|
||||||
|
modifiers="accel,shift"/>
|
||||||
|
</keyset>
|
||||||
|
|
||||||
|
|
||||||
|
<menubar id="sp-menubar">
|
||||||
|
<menu id="sp-file-menu" label="&fileMenu.label;"
|
||||||
|
accesskey="&fileMenu.accesskey;">
|
||||||
|
<menupopup id="sp-menu-filepopup">
|
||||||
|
<menuitem id="sp-menu-newscratchpad"
|
||||||
|
label="&newWindowCmd.label;"
|
||||||
|
accesskey="&newWindowCmd.accesskey;"
|
||||||
|
key="sp-key-window"
|
||||||
|
command="sp-cmd-newWindow"/>
|
||||||
|
<menuseparator/>
|
||||||
|
<menuitem id="sp-menu-open"
|
||||||
|
label="&openFileCmd.label;"
|
||||||
|
command="sp-cmd-openFile"
|
||||||
|
key="sp-key-open"
|
||||||
|
accesskey="&openFileCmd.accesskey;"/>
|
||||||
|
<menuitem id="sp-menu-save"
|
||||||
|
label="&saveFileCmd.label;"
|
||||||
|
accesskey="&saveFileCmd.accesskey;"
|
||||||
|
key="sp-key-save"
|
||||||
|
command="sp-cmd-save"/>
|
||||||
|
<menuitem id="sp-menu-saveas"
|
||||||
|
label="&saveFileAsCmd.label;"
|
||||||
|
accesskey="&saveFileAsCmd.accesskey;"
|
||||||
|
command="sp-cmd-saveas"/>
|
||||||
|
<menuseparator/>
|
||||||
|
|
||||||
|
<!-- TODO: bug 650340 - implement printFile
|
||||||
|
<menuitem id="sp-menu-print"
|
||||||
|
label="&printCmd.label;"
|
||||||
|
accesskey="&printCmd.accesskey;"
|
||||||
|
command="sp-cmd-printFile"/>
|
||||||
|
<menuseparator/>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<menuitem id="sp-menu-close"
|
||||||
|
label="&closeCmd.label;"
|
||||||
|
key="sp-key-close"
|
||||||
|
accesskey="&closeCmd.accesskey;"
|
||||||
|
command="sp-cmd-close"/>
|
||||||
|
</menupopup>
|
||||||
|
</menu>
|
||||||
|
|
||||||
|
<menu id="sp-edit-menu" label="&editMenu.label;"
|
||||||
|
accesskey="&editMenu.accesskey;">
|
||||||
|
<menupopup id="sp-menu_editpopup">
|
||||||
|
<menuitem id="sp-menu_undo"
|
||||||
|
label="&undoCmd.label;"
|
||||||
|
key="key_undo"
|
||||||
|
accesskey="&undoCmd.accesskey;"
|
||||||
|
disabled="true"
|
||||||
|
oncommand="cmd_undo"/>
|
||||||
|
<menuitem id="sp-menu-redo"
|
||||||
|
label="&redoCmd.label;"
|
||||||
|
key="key_redo"
|
||||||
|
disabled="true"
|
||||||
|
accesskey="&redoCmd.accesskey;"
|
||||||
|
command="cmd_redo"/>
|
||||||
|
<menuseparator/>
|
||||||
|
<menuitem id="sp-menu-cut"
|
||||||
|
label="&cutCmd.label;"
|
||||||
|
key="key_cut"
|
||||||
|
accesskey="&cutCmd.accesskey;"
|
||||||
|
command="cmd_cut"/>
|
||||||
|
<menuitem id="sp-menu-copy"
|
||||||
|
label="©Cmd.label;"
|
||||||
|
key="key_copy"
|
||||||
|
accesskey="©Cmd.accesskey;"
|
||||||
|
command="cmd_copy"/>
|
||||||
|
<menuitem id="sp-menu-paste"
|
||||||
|
label="&pasteCmd.label;"
|
||||||
|
key="key_paste"
|
||||||
|
accesskey="&pasteCmd.accesskey;"
|
||||||
|
command="cmd_paste"/>
|
||||||
|
<menuseparator/>
|
||||||
|
<menuitem id="sp-menu-selectAll"
|
||||||
|
label="&selectAllCmd.label;"
|
||||||
|
key="key_selectAll"
|
||||||
|
accesskey="&selectAllCmd.accesskey;"
|
||||||
|
command="cmd_selectAll"/>
|
||||||
|
<menuseparator/>
|
||||||
|
|
||||||
|
<!-- TODO: bug 650345 - implement search and replace
|
||||||
|
<menuitem id="sp-menu-find"
|
||||||
|
label="&findOnCmd.label;"
|
||||||
|
accesskey="&findOnCmd.accesskey;"
|
||||||
|
key="key_find"
|
||||||
|
disabled="true"
|
||||||
|
command="cmd_find"/>
|
||||||
|
<menuitem id="sp-menu-findAgain"
|
||||||
|
label="&findAgainCmd.label;"
|
||||||
|
accesskey="&findAgainCmd.accesskey;"
|
||||||
|
key="key_findAgain"
|
||||||
|
disabled="true"
|
||||||
|
command="cmd_findAgain"/>
|
||||||
|
<menuseparator id="sp-execute-separator"/>
|
||||||
|
-->
|
||||||
|
|
||||||
|
<menuitem id="sp-text-execute"
|
||||||
|
label="&execute.label;"
|
||||||
|
accesskey="&execute.accesskey;"
|
||||||
|
key="sp-key-execute"
|
||||||
|
command="sp-cmd-execute"/>
|
||||||
|
<menuitem id="sp-text-inspect"
|
||||||
|
label="&inspect.label;"
|
||||||
|
accesskey="&inspect.accesskey;"
|
||||||
|
key="sp-key-inspect"
|
||||||
|
command="sp-cmd-inspect"/>
|
||||||
|
<menuitem id="sp-text-print"
|
||||||
|
label="&print.label;"
|
||||||
|
accesskey="&print.accesskey;"
|
||||||
|
key="sp-key-print"
|
||||||
|
command="sp-cmd-print"/>
|
||||||
|
</menupopup>
|
||||||
|
</menu>
|
||||||
|
|
||||||
|
<menu id="sp-context-menu"
|
||||||
|
label="&contextMenu.label;"
|
||||||
|
accesskey="&contextMenu.accesskey;">
|
||||||
|
<menupopup id="sp-menu-context">
|
||||||
|
<menuitem id="sp-menu-content"
|
||||||
|
label="&contentContext.label;"
|
||||||
|
accesskey="&contentContext.accesskey;"
|
||||||
|
command="sp-cmd-contentContext"
|
||||||
|
checked="true"
|
||||||
|
type="radio"/>
|
||||||
|
<menuitem id="sp-menu-chrome" hidden="true"
|
||||||
|
command="sp-cmd-chromeContext"
|
||||||
|
label="&chromeContext.label;"
|
||||||
|
accesskey="&chromeContext.accesskey;"
|
||||||
|
type="radio"/>
|
||||||
|
<menuseparator/>
|
||||||
|
<menuitem id="sp-menu-resetContext"
|
||||||
|
command="sp-cmd-resetContext"
|
||||||
|
label="&resetContext.label;"
|
||||||
|
accesskey="&resetContext.accesskey;"/>
|
||||||
|
</menupopup>
|
||||||
|
</menu>
|
||||||
|
|
||||||
|
<menu id="sp-tools-menu"
|
||||||
|
label="&toolsMenu.label;"
|
||||||
|
accesskey="&toolsMenu.accesskey;">
|
||||||
|
<menupopup id="sp-menu-tools">
|
||||||
|
<menuitem id="sp-menu-errorConsole" hidden="true"
|
||||||
|
label="&errorConsoleCmd.label;"
|
||||||
|
accesskey="&errorConsoleCmd.accesskey;"
|
||||||
|
key="sp-key-errorConsole"
|
||||||
|
command="sp-cmd-errorConsole"/>
|
||||||
|
<menuitem id="sp-menu-webConsole"
|
||||||
|
label="&webConsoleCmd.label;"
|
||||||
|
accesskey="&webConsoleCmd.accesskey;"
|
||||||
|
key="sp-key-webConsole"
|
||||||
|
command="sp-cmd-webConsole"/>
|
||||||
|
</menupopup>
|
||||||
|
</menu>
|
||||||
|
</menubar>
|
||||||
|
|
||||||
|
<popupset id="scratchpad-popups">
|
||||||
|
<menupopup id="scratchpad-text-popup">
|
||||||
|
<menuitem id="menu_cut"/>
|
||||||
|
<menuitem id="menu_copy"/>
|
||||||
|
<menuitem id="menu_paste"/>
|
||||||
|
<menuitem id="menu_delete"/>
|
||||||
|
<menuseparator/>
|
||||||
|
<menuitem id="menu_selectAll"/>
|
||||||
|
<menuseparator/>
|
||||||
|
<menuitem id="sp-text-execute"
|
||||||
|
label="&execute.label;"
|
||||||
|
accesskey="&execute.accesskey;"
|
||||||
|
key="sp-key-execute"
|
||||||
|
command="sp-cmd-execute"/>
|
||||||
|
<menuitem id="sp-text-inspect"
|
||||||
|
label="&inspect.label;"
|
||||||
|
accesskey="&inspect.accesskey;"
|
||||||
|
key="sp-key-inspect"
|
||||||
|
command="sp-cmd-inspect"/>
|
||||||
|
<menuitem id="sp-text-print"
|
||||||
|
label="&print.label;"
|
||||||
|
accesskey="&print.accesskey;"
|
||||||
|
key="sp-key-print"
|
||||||
|
command="sp-cmd-print"/>
|
||||||
|
</menupopup>
|
||||||
|
</popupset>
|
||||||
|
|
||||||
|
<textbox id="scratchpad-textbox"
|
||||||
|
multiline="true"
|
||||||
|
flex="1"
|
||||||
|
context="scratchpad-text-popup"
|
||||||
|
placeholder="&textbox.placeholder;" />
|
||||||
|
<statusbar id="scratchpad-statusbar" align="end">
|
||||||
|
<statusbarpanel id="scratchpad-status"
|
||||||
|
label="&contentContext.label;"
|
||||||
|
class="statusbarpanel-iconic-text"/>
|
||||||
|
<spacer flex="1"/>
|
||||||
|
</statusbar>
|
||||||
|
</window>
|
|
@ -77,11 +77,11 @@
|
||||||
value="&addDevice.showMeHow.label;"
|
value="&addDevice.showMeHow.label;"
|
||||||
href="https://services.mozilla.com/sync/help/add-device"/>
|
href="https://services.mozilla.com/sync/help/add-device"/>
|
||||||
</description>
|
</description>
|
||||||
<spacer flex="1"/>
|
<separator class="groove-thin"/>
|
||||||
<description>
|
<description>
|
||||||
&addDevice.dialog.enterCode.label;
|
&addDevice.dialog.enterCode.label;
|
||||||
</description>
|
</description>
|
||||||
<spacer flex="1"/>
|
<separator class="groove-thin"/>
|
||||||
<vbox align="center">
|
<vbox align="center">
|
||||||
<textbox id="pin1"
|
<textbox id="pin1"
|
||||||
class="pin"
|
class="pin"
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
onfocus="this.select();"
|
onfocus="this.select();"
|
||||||
/>
|
/>
|
||||||
</vbox>
|
</vbox>
|
||||||
<spacer flex="1"/>
|
<separator class="groove-thin"/>
|
||||||
<vbox id="add-device-throbber" align="center" hidden="true">
|
<vbox id="add-device-throbber" align="center" hidden="true">
|
||||||
<image/>
|
<image/>
|
||||||
</vbox>
|
</vbox>
|
||||||
|
|
|
@ -111,7 +111,7 @@ let Change = {
|
||||||
pp = Weave.Utils.hyphenatePassphrase(pp);
|
pp = Weave.Utils.hyphenatePassphrase(pp);
|
||||||
this._passphraseBox.value = pp;
|
this._passphraseBox.value = pp;
|
||||||
this._passphraseBox.focus();
|
this._passphraseBox.focus();
|
||||||
document.title = this._str("change.synckey.title");
|
document.title = this._str("change.synckey2.title");
|
||||||
introText.textContent = this._str("change.synckey.introText2");
|
introText.textContent = this._str("change.synckey.introText2");
|
||||||
warningText.textContent = this._str("change.synckey2.warningText");
|
warningText.textContent = this._str("change.synckey2.warningText");
|
||||||
this._dialog.getButton("finish").label
|
this._dialog.getButton("finish").label
|
||||||
|
|
|
@ -100,7 +100,7 @@
|
||||||
<spacer flex="1"/>
|
<spacer flex="1"/>
|
||||||
<label id="generatePassphraseButton"
|
<label id="generatePassphraseButton"
|
||||||
hidden="true"
|
hidden="true"
|
||||||
value="&syncKeyGenerate.label;"
|
value="&syncGenerateNewKey.label;"
|
||||||
class="text-link inline-link"
|
class="text-link inline-link"
|
||||||
onclick="event.stopPropagation();
|
onclick="event.stopPropagation();
|
||||||
Change.doGeneratePassphrase();"/>
|
Change.doGeneratePassphrase();"/>
|
||||||
|
|
|
@ -56,6 +56,11 @@ const OPTIONS_PAGE = 6;
|
||||||
const OPTIONS_CONFIRM_PAGE = 7;
|
const OPTIONS_CONFIRM_PAGE = 7;
|
||||||
const SETUP_SUCCESS_PAGE = 8;
|
const SETUP_SUCCESS_PAGE = 8;
|
||||||
|
|
||||||
|
// Broader than we'd like, but after this changed from api-secure.recaptcha.net
|
||||||
|
// we had no choice. At least we only do this for the duration of setup.
|
||||||
|
// See discussion in Bugs 508112 and 653307.
|
||||||
|
const RECAPTCHA_DOMAIN = "https://www.google.com";
|
||||||
|
|
||||||
Cu.import("resource://services-sync/main.js");
|
Cu.import("resource://services-sync/main.js");
|
||||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
Cu.import("resource://gre/modules/Services.jsm");
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
@ -69,7 +74,6 @@ var gSyncSetup = {
|
||||||
captchaBrowser: null,
|
captchaBrowser: null,
|
||||||
wizard: null,
|
wizard: null,
|
||||||
_disabledSites: [],
|
_disabledSites: [],
|
||||||
_remoteSites: [Weave.Service.serverURL, "https://api-secure.recaptcha.net"],
|
|
||||||
|
|
||||||
status: {
|
status: {
|
||||||
password: false,
|
password: false,
|
||||||
|
@ -77,6 +81,8 @@ var gSyncSetup = {
|
||||||
server: false
|
server: false
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get _remoteSites() [Weave.Service.serverURL, RECAPTCHA_DOMAIN],
|
||||||
|
|
||||||
get _usingMainServers() {
|
get _usingMainServers() {
|
||||||
if (this._settingUpNew)
|
if (this._settingUpNew)
|
||||||
return document.getElementById("server").selectedIndex == 0;
|
return document.getElementById("server").selectedIndex == 0;
|
||||||
|
|
|
@ -35,7 +35,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
tabpanels {
|
tabpanels {
|
||||||
background-color: white;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.tab-drop-indicator {
|
.tab-drop-indicator {
|
||||||
|
|
|
@ -2456,6 +2456,11 @@
|
||||||
this.mTabListeners[0] = tabListener;
|
this.mTabListeners[0] = tabListener;
|
||||||
this.mTabFilters[0] = filter;
|
this.mTabFilters[0] = filter;
|
||||||
this.init();
|
this.init();
|
||||||
|
|
||||||
|
this.style.backgroundColor =
|
||||||
|
Services.prefs.getBoolPref("browser.display.use_system_colors") ?
|
||||||
|
"-moz-default-background-color" :
|
||||||
|
Services.prefs.getCharPref("browser.display.background_color");
|
||||||
]]>
|
]]>
|
||||||
</constructor>
|
</constructor>
|
||||||
|
|
||||||
|
|
|
@ -92,10 +92,10 @@ function Drag(item, event, isFauxDrag) {
|
||||||
var tab = UI.getActiveTab();
|
var tab = UI.getActiveTab();
|
||||||
if (!tab || tab.parent != this.item) {
|
if (!tab || tab.parent != this.item) {
|
||||||
if (this.item._children.length)
|
if (this.item._children.length)
|
||||||
UI.setActiveTab(this.item._children[0]);
|
UI.setActive(this.item._children[0]);
|
||||||
}
|
}
|
||||||
} else if (this.item.isATabItem) {
|
} else if (this.item.isATabItem) {
|
||||||
UI.setActiveTab(this.item);
|
UI.setActive(this.item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -708,12 +708,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
let closeCenter = this.getBounds().center();
|
let closeCenter = this.getBounds().center();
|
||||||
// Find closest tab to make active
|
// Find closest tab to make active
|
||||||
let closestTabItem = UI.getClosestTab(closeCenter);
|
let closestTabItem = UI.getClosestTab(closeCenter);
|
||||||
UI.setActiveTab(closestTabItem);
|
UI.setActive(closestTabItem);
|
||||||
|
|
||||||
if (closestTabItem && closestTabItem.parent)
|
|
||||||
GroupItems.setActiveGroupItem(closestTabItem.parent);
|
|
||||||
else
|
|
||||||
GroupItems.setActiveGroupItem(null);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
@ -744,9 +739,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
this.droppable(true);
|
this.droppable(true);
|
||||||
this.setTrenches(this.bounds);
|
this.setTrenches(this.bounds);
|
||||||
|
|
||||||
GroupItems.setActiveGroupItem(this);
|
UI.setActive(this);
|
||||||
if (this._activeTab)
|
|
||||||
UI.setActiveTab(this._activeTab);
|
|
||||||
|
|
||||||
iQ(this.container).show().animate({
|
iQ(this.container).show().animate({
|
||||||
"-moz-transform": "scale(1)",
|
"-moz-transform": "scale(1)",
|
||||||
|
@ -1012,10 +1005,8 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
if (dontArrange)
|
if (dontArrange)
|
||||||
self._freezeItemSize(count);
|
self._freezeItemSize(count);
|
||||||
|
|
||||||
if (self._children.length > 0 && self._activeTab) {
|
if (self._children.length > 0 && self._activeTab)
|
||||||
GroupItems.setActiveGroupItem(self);
|
UI.setActive(self);
|
||||||
UI.setActiveTab(self._activeTab);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
item.setParent(this);
|
item.setParent(this);
|
||||||
|
@ -1027,11 +1018,11 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
if (iQ(item.container).hasClass("focus"))
|
if (iQ(item.container).hasClass("focus"))
|
||||||
this.setActiveTab(item);
|
this.setActiveTab(item);
|
||||||
|
|
||||||
// if it matches the selected tab or no active tab and the browser
|
// if it matches the selected tab or no active tab and the browser
|
||||||
// tab is hidden, the active group item would be set.
|
// tab is hidden, the active group item would be set.
|
||||||
if (item.tab == gBrowser.selectedTab ||
|
if (item.tab == gBrowser.selectedTab ||
|
||||||
(!GroupItems.getActiveGroupItem() && !item.tab.hidden))
|
(!GroupItems.getActiveGroupItem() && !item.tab.hidden))
|
||||||
GroupItems.setActiveGroupItem(this);
|
UI.setActive(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!options.dontArrange)
|
if (!options.dontArrange)
|
||||||
|
@ -1140,19 +1131,6 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
self.remove(child, newOptions);
|
self.remove(child, newOptions);
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
|
||||||
// Handles error event for loading app tab's fav icon.
|
|
||||||
_onAppTabError : function(event) {
|
|
||||||
iQ(".appTabIcon", this.$appTabTray).each(function(icon) {
|
|
||||||
let $icon = iQ(icon);
|
|
||||||
if ($icon.data("xulTab") == event.target) {
|
|
||||||
$icon.attr("src", Utils.defaultFaviconURL);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// Adds the given xul:tab as an app tab in this group's apptab tray
|
// Adds the given xul:tab as an app tab in this group's apptab tray
|
||||||
|
@ -1167,10 +1145,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
addAppTab: function GroupItem_addAppTab(xulTab, options) {
|
addAppTab: function GroupItem_addAppTab(xulTab, options) {
|
||||||
let self = this;
|
let self = this;
|
||||||
|
|
||||||
xulTab.addEventListener("error", this._onAppTabError, false);
|
let iconUrl = GroupItems.getAppTabFavIconUrl(xulTab);
|
||||||
|
|
||||||
// add the icon
|
|
||||||
let iconUrl = xulTab.image || Utils.defaultFaviconURL;
|
|
||||||
let $appTab = iQ("<img>")
|
let $appTab = iQ("<img>")
|
||||||
.addClass("appTabIcon")
|
.addClass("appTabIcon")
|
||||||
.attr("src", iconUrl)
|
.attr("src", iconUrl)
|
||||||
|
@ -1180,7 +1155,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
if (!Utils.isLeftClick(event))
|
if (!Utils.isLeftClick(event))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
GroupItems.setActiveGroupItem(self);
|
UI.setActive(self, { dontSetActiveTabInGroup: true });
|
||||||
UI.goToTab(iQ(this).data("xulTab"));
|
UI.goToTab(iQ(this).data("xulTab"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1204,8 +1179,6 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
|
|
||||||
// adjust the tray
|
// adjust the tray
|
||||||
this.adjustAppTabTray(true);
|
this.adjustAppTabTray(true);
|
||||||
|
|
||||||
xulTab.removeEventListener("error", this._onAppTabError, false);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
@ -1227,7 +1200,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
if (targetIndex < (length - 1))
|
if (targetIndex < (length - 1))
|
||||||
self.$appTabTray[0].insertBefore(
|
self.$appTabTray[0].insertBefore(
|
||||||
icon,
|
icon,
|
||||||
iQ(".appTabIcon:nth-child(" + (targetIndex + 1) + ")", self.$appTabTray)[0]);
|
iQ(".appTabIcon:nth-child(" + (targetIndex + 1) + ")", self.$appTabTray)[0]);
|
||||||
else
|
else
|
||||||
$icon.appendTo(self.$appTabTray);
|
$icon.appendTo(self.$appTabTray);
|
||||||
return false;
|
return false;
|
||||||
|
@ -1539,8 +1512,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
expand: function GroupItem_expand() {
|
expand: function GroupItem_expand() {
|
||||||
var self = this;
|
var self = this;
|
||||||
// ___ we're stacked, and command is held down so expand
|
// ___ we're stacked, and command is held down so expand
|
||||||
GroupItems.setActiveGroupItem(self);
|
UI.setActive(this.getTopChild());
|
||||||
UI.setActiveTab(this.getTopChild());
|
|
||||||
|
|
||||||
var startBounds = this.getChild(0).getBounds();
|
var startBounds = this.getChild(0).getBounds();
|
||||||
var $tray = iQ("<div>").css({
|
var $tray = iQ("<div>").css({
|
||||||
|
@ -1756,7 +1728,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
if (dropIndex !== false)
|
if (dropIndex !== false)
|
||||||
options = {index: dropIndex};
|
options = {index: dropIndex};
|
||||||
this.add(drag.info.$el, options);
|
this.add(drag.info.$el, options);
|
||||||
GroupItems.setActiveGroupItem(this);
|
UI.setActive(this);
|
||||||
dropIndex = false;
|
dropIndex = false;
|
||||||
};
|
};
|
||||||
this.dropOptions.out = function GroupItem_dropOptions_out(event) {
|
this.dropOptions.out = function GroupItem_dropOptions_out(event) {
|
||||||
|
@ -1811,7 +1783,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
// Function: newTab
|
// Function: newTab
|
||||||
// Creates a new tab within this groupItem.
|
// Creates a new tab within this groupItem.
|
||||||
newTab: function GroupItem_newTab(url) {
|
newTab: function GroupItem_newTab(url) {
|
||||||
GroupItems.setActiveGroupItem(this);
|
UI.setActive(this, { dontSetActiveTabInGroup: true });
|
||||||
let newTab = gBrowser.loadOneTab(url || "about:blank", {inBackground: true});
|
let newTab = gBrowser.loadOneTab(url || "about:blank", {inBackground: true});
|
||||||
|
|
||||||
// TabItems will have handled the new tab and added the tabItem property.
|
// TabItems will have handled the new tab and added the tabItem property.
|
||||||
|
@ -2037,7 +2009,7 @@ let GroupItems = {
|
||||||
if (xulTab.ownerDocument.defaultView != gWindow || !xulTab.pinned)
|
if (xulTab.ownerDocument.defaultView != gWindow || !xulTab.pinned)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
let iconUrl = xulTab.image || Utils.defaultFaviconURL;
|
let iconUrl = this.getAppTabFavIconUrl(xulTab);
|
||||||
this.groupItems.forEach(function(groupItem) {
|
this.groupItems.forEach(function(groupItem) {
|
||||||
iQ(".appTabIcon", groupItem.$appTabTray).each(function(icon) {
|
iQ(".appTabIcon", groupItem.$appTabTray).each(function(icon) {
|
||||||
let $icon = iQ(icon);
|
let $icon = iQ(icon);
|
||||||
|
@ -2049,7 +2021,21 @@ let GroupItems = {
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Function: getAppTabFavIconUrl
|
||||||
|
// Gets the fav icon url for app tab.
|
||||||
|
getAppTabFavIconUrl: function GroupItems__getAppTabFavIconUrl(xulTab) {
|
||||||
|
let iconUrl;
|
||||||
|
|
||||||
|
if (UI.shouldLoadFavIcon(xulTab.linkedBrowser))
|
||||||
|
iconUrl = UI.getFavIconUrlForTab(xulTab);
|
||||||
|
else
|
||||||
|
iconUrl = Utils.defaultFaviconURL;
|
||||||
|
|
||||||
|
return iconUrl;
|
||||||
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// Function: addAppTab
|
// Function: addAppTab
|
||||||
|
@ -2185,7 +2171,7 @@ let GroupItems = {
|
||||||
if (activeGroupId) {
|
if (activeGroupId) {
|
||||||
let activeGroupItem = this.groupItem(activeGroupId);
|
let activeGroupItem = this.groupItem(activeGroupId);
|
||||||
if (activeGroupItem)
|
if (activeGroupItem)
|
||||||
this.setActiveGroupItem(activeGroupItem);
|
UI.setActive(activeGroupItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
this._inited = true;
|
this._inited = true;
|
||||||
|
@ -2322,7 +2308,7 @@ let GroupItems = {
|
||||||
if (targetGroupItem) {
|
if (targetGroupItem) {
|
||||||
// add the new tabItem to the first group item
|
// add the new tabItem to the first group item
|
||||||
targetGroupItem.add(tabItem);
|
targetGroupItem.add(tabItem);
|
||||||
this.setActiveGroupItem(targetGroupItem);
|
UI.setActive(targetGroupItem);
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
// find the first visible group item
|
// find the first visible group item
|
||||||
|
@ -2331,7 +2317,7 @@ let GroupItems = {
|
||||||
});
|
});
|
||||||
if (visibleGroupItems.length > 0) {
|
if (visibleGroupItems.length > 0) {
|
||||||
visibleGroupItems[0].add(tabItem);
|
visibleGroupItems[0].add(tabItem);
|
||||||
this.setActiveGroupItem(visibleGroupItems[0]);
|
UI.setActive(visibleGroupItems[0]);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2360,7 +2346,7 @@ let GroupItems = {
|
||||||
newGroupItemBounds.inset(-40,-40);
|
newGroupItemBounds.inset(-40,-40);
|
||||||
let newGroupItem = new GroupItem(tabItems, { bounds: newGroupItemBounds });
|
let newGroupItem = new GroupItem(tabItems, { bounds: newGroupItemBounds });
|
||||||
newGroupItem.snap();
|
newGroupItem.snap();
|
||||||
this.setActiveGroupItem(newGroupItem);
|
UI.setActive(newGroupItem);
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
@ -2420,11 +2406,7 @@ let GroupItems = {
|
||||||
updateActiveGroupItemAndTabBar: function GroupItems_updateActiveGroupItemAndTabBar(tabItem) {
|
updateActiveGroupItemAndTabBar: function GroupItems_updateActiveGroupItemAndTabBar(tabItem) {
|
||||||
Utils.assertThrow(tabItem && tabItem.isATabItem, "tabItem must be a TabItem");
|
Utils.assertThrow(tabItem && tabItem.isATabItem, "tabItem must be a TabItem");
|
||||||
|
|
||||||
let groupItem = tabItem.parent;
|
UI.setActive(tabItem);
|
||||||
this.setActiveGroupItem(groupItem);
|
|
||||||
if (groupItem)
|
|
||||||
groupItem.setActiveTab(tabItem);
|
|
||||||
|
|
||||||
this._updateTabBar();
|
this._updateTabBar();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -152,7 +152,7 @@ Item.prototype = {
|
||||||
cancelClass: 'close stackExpander',
|
cancelClass: 'close stackExpander',
|
||||||
start: function(e, ui) {
|
start: function(e, ui) {
|
||||||
if (this.isAGroupItem) {
|
if (this.isAGroupItem) {
|
||||||
GroupItems.setActiveGroupItem(this);
|
UI.setActive(this);
|
||||||
this._unfreezeItemSize();
|
this._unfreezeItemSize();
|
||||||
}
|
}
|
||||||
// if we start dragging a tab within a group, start with dropSpace on.
|
// if we start dragging a tab within a group, start with dropSpace on.
|
||||||
|
@ -202,7 +202,7 @@ Item.prototype = {
|
||||||
minHeight: 90,
|
minHeight: 90,
|
||||||
start: function(e,ui) {
|
start: function(e,ui) {
|
||||||
if (this.isAGroupItem)
|
if (this.isAGroupItem)
|
||||||
GroupItems.setActiveGroupItem(this);
|
UI.setActive(this);
|
||||||
resize.info = new Drag(this, e);
|
resize.info = new Drag(this, e);
|
||||||
},
|
},
|
||||||
resize: function(e,ui) {
|
resize: function(e,ui) {
|
||||||
|
|
|
@ -218,43 +218,39 @@ TabMatcher.prototype = {
|
||||||
|
|
||||||
// ---------
|
// ---------
|
||||||
// Function: _getTabsForOtherWindows
|
// Function: _getTabsForOtherWindows
|
||||||
// Returns an array of <TabItem>s and <xul:tabs>s representing that
|
// Returns an array of <TabItem>s and <xul:tabs>s representing tabs
|
||||||
// tabs from all windows but the currently focused window. <TabItem>s
|
// from all windows but the current window. <TabItem>s will be returned
|
||||||
// will be returned for windows in which Panorama has been activated at
|
// for windows in which Panorama has been activated at least once, while
|
||||||
// least once, while <xul:tab>s will be return for windows in which
|
// <xul:tab>s will be returned for windows in which Panorama has never
|
||||||
// Panorama has never been activated.
|
// been activated.
|
||||||
_getTabsForOtherWindows: function TabMatcher__getTabsForOtherWindows(){
|
_getTabsForOtherWindows: function TabMatcher__getTabsForOtherWindows() {
|
||||||
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
|
var enumerator = Services.wm.getEnumerator("navigator:browser");
|
||||||
.getService(Components.interfaces.nsIWindowMediator);
|
var allTabs = [];
|
||||||
var enumerator = wm.getEnumerator("navigator:browser");
|
|
||||||
var currentWindow = wm.getMostRecentWindow("navigator:browser");
|
|
||||||
|
|
||||||
var allTabs = [];
|
|
||||||
while (enumerator.hasMoreElements()) {
|
while (enumerator.hasMoreElements()) {
|
||||||
var win = enumerator.getNext();
|
var win = enumerator.getNext();
|
||||||
// This function gets tabs from other windows: not the one you currently
|
// This function gets tabs from other windows, not from the current window
|
||||||
// have focused.
|
if (win != gWindow) {
|
||||||
if (win != currentWindow) {
|
|
||||||
// If TabView is around iterate over all tabs, else get the currently
|
// If TabView is around iterate over all tabs, else get the currently
|
||||||
// shown tabs...
|
// shown tabs...
|
||||||
|
|
||||||
let tvWindow = win.TabView.getContentWindow();
|
let tvWindow = win.TabView.getContentWindow();
|
||||||
if (tvWindow)
|
if (tvWindow)
|
||||||
allTabs = allTabs.concat( tvWindow.TabItems.getItems() );
|
allTabs = allTabs.concat(tvWindow.TabItems.getItems());
|
||||||
else
|
else
|
||||||
// win.gBrowser.tabs isn't a proper array, so we can't use concat
|
// win.gBrowser.tabs isn't a proper array, so we can't use concat
|
||||||
for (var i=0; i<win.gBrowser.tabs.length; i++) allTabs.push( win.gBrowser.tabs[i] );
|
for (let i = 0; i < win.gBrowser.tabs.length; i++)
|
||||||
}
|
allTabs.push(win.gBrowser.tabs[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return allTabs;
|
return allTabs;
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// Function: matchedTabsFromOtherWindows
|
// Function: matchedTabsFromOtherWindows
|
||||||
// Returns an array of <TabItem>s and <xul:tab>s that match the search term
|
// Returns an array of <TabItem>s and <xul:tab>s that match the search term
|
||||||
// from all windows but the currently focused window. <TabItem>s will be
|
// from all windows but the current window. <TabItem>s will be returned for
|
||||||
// returned for windows in which Panorama has been activated at least once,
|
// windows in which Panorama has been activated at least once, while
|
||||||
// while <xul:tab>s will be return for windows in which Panorama has never
|
// <xul:tab>s will be returned for windows in which Panorama has never
|
||||||
// been activated.
|
// been activated.
|
||||||
// (new TabMatcher("app")).matchedTabsFromOtherWindows();
|
// (new TabMatcher("app")).matchedTabsFromOtherWindows();
|
||||||
matchedTabsFromOtherWindows: function TabMatcher_matchedTabsFromOtherWindows(){
|
matchedTabsFromOtherWindows: function TabMatcher_matchedTabsFromOtherWindows(){
|
||||||
|
|
|
@ -361,7 +361,7 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
// tab is hidden, the active group item would be set.
|
// tab is hidden, the active group item would be set.
|
||||||
if (self.tab == gBrowser.selectedTab ||
|
if (self.tab == gBrowser.selectedTab ||
|
||||||
(!GroupItems.getActiveGroupItem() && !self.tab.hidden))
|
(!GroupItems.getActiveGroupItem() && !self.tab.hidden))
|
||||||
GroupItems.setActiveGroupItem(self.parent);
|
UI.setActive(self.parent);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// When duplicating a non-blank orphaned tab, create a group including both of them.
|
// When duplicating a non-blank orphaned tab, create a group including both of them.
|
||||||
|
@ -643,9 +643,7 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
let $tabEl = this.$container;
|
let $tabEl = this.$container;
|
||||||
let $canvas = this.$canvas;
|
let $canvas = this.$canvas;
|
||||||
|
|
||||||
UI.setActiveTab(this);
|
UI.setActive(this);
|
||||||
GroupItems.setActiveGroupItem(this.parent);
|
|
||||||
|
|
||||||
TabItems._update(this.tab, {force: true});
|
TabItems._update(this.tab, {force: true});
|
||||||
|
|
||||||
// Zoom in!
|
// Zoom in!
|
||||||
|
@ -714,7 +712,7 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
||||||
complete();
|
complete();
|
||||||
};
|
};
|
||||||
|
|
||||||
UI.setActiveTab(this);
|
UI.setActive(this);
|
||||||
TabItems._update(this.tab, {force: true});
|
TabItems._update(this.tab, {force: true});
|
||||||
|
|
||||||
$tab.addClass("front");
|
$tab.addClass("front");
|
||||||
|
@ -985,12 +983,10 @@ let TabItems = {
|
||||||
// Even if the page hasn't loaded, display the favicon and title
|
// Even if the page hasn't loaded, display the favicon and title
|
||||||
|
|
||||||
// ___ icon
|
// ___ icon
|
||||||
if (this.shouldLoadFavIcon(tab.linkedBrowser)) {
|
if (UI.shouldLoadFavIcon(tab.linkedBrowser)) {
|
||||||
let iconUrl = tab.image;
|
let iconUrl = UI.getFavIconUrlForTab(tab);
|
||||||
if (!iconUrl)
|
|
||||||
iconUrl = Utils.defaultFaviconURL;
|
|
||||||
|
|
||||||
if (iconUrl != tabItem.$favImage[0].src)
|
if (tabItem.$favImage[0].src != iconUrl)
|
||||||
tabItem.$favImage[0].src = iconUrl;
|
tabItem.$favImage[0].src = iconUrl;
|
||||||
|
|
||||||
iQ(tabItem.$fav[0]).show();
|
iQ(tabItem.$fav[0]).show();
|
||||||
|
@ -1052,14 +1048,6 @@ let TabItems = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
|
||||||
// Function: shouldLoadFavIcon
|
|
||||||
// Takes a xul:browser and checks whether we should display a favicon for it.
|
|
||||||
shouldLoadFavIcon: function TabItems_shouldLoadFavIcon(browser) {
|
|
||||||
return !(browser.contentDocument instanceof window.ImageDocument) &&
|
|
||||||
gBrowser.shouldLoadFavIcon(browser.contentDocument.documentURIObject);
|
|
||||||
},
|
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// Function: link
|
// Function: link
|
||||||
// Takes in a xul:tab, creates a TabItem for it and adds it to the scene.
|
// Takes in a xul:tab, creates a TabItem for it and adds it to the scene.
|
||||||
|
@ -1084,7 +1072,7 @@ let TabItems = {
|
||||||
// note that it's ok to unlink an app tab; see .handleTabUnpin
|
// note that it's ok to unlink an app tab; see .handleTabUnpin
|
||||||
|
|
||||||
if (tab._tabViewTabItem == UI.getActiveOrphanTab())
|
if (tab._tabViewTabItem == UI.getActiveOrphanTab())
|
||||||
UI.setActiveTab(null);
|
UI.setActive(null, { onlyRemoveActiveTab: true });
|
||||||
|
|
||||||
this.unregister(tab._tabViewTabItem);
|
this.unregister(tab._tabViewTabItem);
|
||||||
tab._tabViewTabItem._sendToSubscribers("close");
|
tab._tabViewTabItem._sendToSubscribers("close");
|
||||||
|
|
|
@ -23,6 +23,11 @@ XPCOMUtils.defineLazyGetter(this, "gPrivateBrowsing", function() {
|
||||||
getService(Ci.nsIPrivateBrowsingService);
|
getService(Ci.nsIPrivateBrowsingService);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
XPCOMUtils.defineLazyGetter(this, "gFavIconService", function() {
|
||||||
|
return Cc["@mozilla.org/browser/favicon-service;1"].
|
||||||
|
getService(Ci.nsIFaviconService);
|
||||||
|
});
|
||||||
|
|
||||||
XPCOMUtils.defineLazyGetter(this, "gNetUtil", function() {
|
XPCOMUtils.defineLazyGetter(this, "gNetUtil", function() {
|
||||||
var obj = {};
|
var obj = {};
|
||||||
Cu.import("resource://gre/modules/NetUtil.jsm", obj);
|
Cu.import("resource://gre/modules/NetUtil.jsm", obj);
|
||||||
|
|
|
@ -193,7 +193,7 @@ let UI = {
|
||||||
(self._lastClickPositions.x + self.DBLCLICK_OFFSET) >= e.clientX &&
|
(self._lastClickPositions.x + self.DBLCLICK_OFFSET) >= e.clientX &&
|
||||||
(self._lastClickPositions.y - self.DBLCLICK_OFFSET) <= e.clientY &&
|
(self._lastClickPositions.y - self.DBLCLICK_OFFSET) <= e.clientY &&
|
||||||
(self._lastClickPositions.y + self.DBLCLICK_OFFSET) >= e.clientY) {
|
(self._lastClickPositions.y + self.DBLCLICK_OFFSET) >= e.clientY) {
|
||||||
GroupItems.setActiveGroupItem(null);
|
self.setActive(null);
|
||||||
TabItems.creatingNewOrphanTab = true;
|
TabItems.creatingNewOrphanTab = true;
|
||||||
|
|
||||||
let newTab =
|
let newTab =
|
||||||
|
@ -205,7 +205,7 @@ let UI = {
|
||||||
TabItems.tabWidth, TabItems.tabHeight);
|
TabItems.tabWidth, TabItems.tabHeight);
|
||||||
newTab._tabViewTabItem.setBounds(box, true);
|
newTab._tabViewTabItem.setBounds(box, true);
|
||||||
newTab._tabViewTabItem.pushAway(true);
|
newTab._tabViewTabItem.pushAway(true);
|
||||||
UI.setActiveTab(newTab._tabViewTabItem);
|
self.setActive(newTab._tabViewTabItem);
|
||||||
|
|
||||||
TabItems.creatingNewOrphanTab = false;
|
TabItems.creatingNewOrphanTab = false;
|
||||||
newTab._tabViewTabItem.zoomIn(true);
|
newTab._tabViewTabItem.zoomIn(true);
|
||||||
|
@ -349,7 +349,7 @@ let UI = {
|
||||||
item.parent.remove(item);
|
item.parent.remove(item);
|
||||||
groupItem.add(item, {immediately: true});
|
groupItem.add(item, {immediately: true});
|
||||||
});
|
});
|
||||||
GroupItems.setActiveGroupItem(groupItem);
|
this.setActive(groupItem);
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
|
@ -381,7 +381,7 @@ let UI = {
|
||||||
},
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// Function: setActiveTab
|
// Function: _setActiveTab
|
||||||
// Sets the currently active tab. The idea of a focused tab is useful
|
// Sets the currently active tab. The idea of a focused tab is useful
|
||||||
// for keyboard navigation and returning to the last zoomed-in tab.
|
// for keyboard navigation and returning to the last zoomed-in tab.
|
||||||
// Hitting return/esc brings you to the focused tab, and using the
|
// Hitting return/esc brings you to the focused tab, and using the
|
||||||
|
@ -389,7 +389,7 @@ let UI = {
|
||||||
//
|
//
|
||||||
// Parameters:
|
// Parameters:
|
||||||
// - Takes a <TabItem>
|
// - Takes a <TabItem>
|
||||||
setActiveTab: function UI_setActiveTab(tabItem) {
|
_setActiveTab: function UI__setActiveTab(tabItem) {
|
||||||
if (tabItem == this._activeTab)
|
if (tabItem == this._activeTab)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -403,7 +403,7 @@ let UI = {
|
||||||
let self = this;
|
let self = this;
|
||||||
this._activeTab.addSubscriber(this, "close", function(closedTabItem) {
|
this._activeTab.addSubscriber(this, "close", function(closedTabItem) {
|
||||||
if (self._activeTab == closedTabItem)
|
if (self._activeTab == closedTabItem)
|
||||||
self.setActiveTab(null);
|
self._setActiveTab(null);
|
||||||
});
|
});
|
||||||
|
|
||||||
this._activeTab.makeActive();
|
this._activeTab.makeActive();
|
||||||
|
@ -417,6 +417,44 @@ let UI = {
|
||||||
return (this._activeTab && !this._activeTab.parent) ? this._activeTab : null;
|
return (this._activeTab && !this._activeTab.parent) ? this._activeTab : null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Function: setActive
|
||||||
|
// Sets the active tab item or group item
|
||||||
|
// Parameters:
|
||||||
|
//
|
||||||
|
// options
|
||||||
|
// dontSetActiveTabInGroup bool for not setting active tab in group
|
||||||
|
// onlyRemoveActiveGroup bool for removing active group
|
||||||
|
// onlyRemoveActiveTab bool for removing active tab
|
||||||
|
setActive: function UI_setActive(item, options) {
|
||||||
|
if (item) {
|
||||||
|
if (item.isATabItem) {
|
||||||
|
if (item.parent)
|
||||||
|
GroupItems.setActiveGroupItem(item.parent);
|
||||||
|
else
|
||||||
|
GroupItems.setActiveGroupItem(null);
|
||||||
|
this._setActiveTab(item);
|
||||||
|
} else {
|
||||||
|
GroupItems.setActiveGroupItem(item);
|
||||||
|
if (!options || !options.dontSetActiveTabInGroup) {
|
||||||
|
let activeTab = item.getActiveTab()
|
||||||
|
if (activeTab)
|
||||||
|
this._setActiveTab(activeTab);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (options) {
|
||||||
|
if (options.onlyRemoveActiveGroup)
|
||||||
|
GroupItems.setActiveGroupItem(null);
|
||||||
|
else if (options.onlyRemoveActiveTab)
|
||||||
|
this._setActiveTab(null);
|
||||||
|
} else {
|
||||||
|
GroupItems.setActiveGroupItem(null);
|
||||||
|
this._setActiveTab(null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// ----------
|
// ----------
|
||||||
// Function: isTabViewVisible
|
// Function: isTabViewVisible
|
||||||
// Returns true if the TabView UI is currently shown.
|
// Returns true if the TabView UI is currently shown.
|
||||||
|
@ -495,7 +533,7 @@ let UI = {
|
||||||
if (!currentTab._tabViewTabItem) // if the tab's been destroyed
|
if (!currentTab._tabViewTabItem) // if the tab's been destroyed
|
||||||
item = null;
|
item = null;
|
||||||
|
|
||||||
self.setActiveTab(item);
|
self.setActive(item);
|
||||||
|
|
||||||
self._resize(true);
|
self._resize(true);
|
||||||
dispatchEvent(event);
|
dispatchEvent(event);
|
||||||
|
@ -506,7 +544,7 @@ let UI = {
|
||||||
TabItems.resumePainting();
|
TabItems.resumePainting();
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
self.setActiveTab(null);
|
self.setActive(null, { onlyRemoveActiveTab: true });
|
||||||
dispatchEvent(event);
|
dispatchEvent(event);
|
||||||
|
|
||||||
// Flush pending updates
|
// Flush pending updates
|
||||||
|
@ -871,10 +909,10 @@ let UI = {
|
||||||
// already in the tab bar.
|
// already in the tab bar.
|
||||||
if (!GroupItems.getActiveGroupItem() && !UI.getActiveOrphanTab()) {
|
if (!GroupItems.getActiveGroupItem() && !UI.getActiveOrphanTab()) {
|
||||||
for (let a = 0; a < gBrowser.tabs.length; a++) {
|
for (let a = 0; a < gBrowser.tabs.length; a++) {
|
||||||
let theTab = gBrowser.tabs[a];
|
let theTab = gBrowser.tabs[a];
|
||||||
if (!theTab.pinned) {
|
if (!theTab.pinned) {
|
||||||
let tabItem = theTab._tabViewTabItem;
|
let tabItem = theTab._tabViewTabItem;
|
||||||
GroupItems.setActiveGroupItem(tabItem.parent);
|
this.setActive(tabItem.parent);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1083,7 +1121,7 @@ let UI = {
|
||||||
if (nextTab) {
|
if (nextTab) {
|
||||||
if (nextTab.isStacked && !nextTab.parent.expanded)
|
if (nextTab.isStacked && !nextTab.parent.expanded)
|
||||||
nextTab = nextTab.parent.getChild(0);
|
nextTab = nextTab.parent.getChild(0);
|
||||||
self.setActiveTab(nextTab);
|
self.setActive(nextTab);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch(event.keyCode) {
|
switch(event.keyCode) {
|
||||||
|
@ -1121,7 +1159,7 @@ let UI = {
|
||||||
else
|
else
|
||||||
newIndex = (currentIndex + 1);
|
newIndex = (currentIndex + 1);
|
||||||
}
|
}
|
||||||
self.setActiveTab(tabItems[newIndex]);
|
self.setActive(tabItems[newIndex]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -1156,7 +1194,7 @@ let UI = {
|
||||||
const minMinSize = 15;
|
const minMinSize = 15;
|
||||||
|
|
||||||
let lastActiveGroupItem = GroupItems.getActiveGroupItem();
|
let lastActiveGroupItem = GroupItems.getActiveGroupItem();
|
||||||
GroupItems.setActiveGroupItem(null);
|
this.setActive(null, { onlyRemoveActiveGroup: true });
|
||||||
|
|
||||||
var startPos = { x: e.clientX, y: e.clientY };
|
var startPos = { x: e.clientX, y: e.clientY };
|
||||||
var phantom = iQ("<div>")
|
var phantom = iQ("<div>")
|
||||||
|
@ -1225,6 +1263,7 @@ let UI = {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let self = this;
|
||||||
function collapse() {
|
function collapse() {
|
||||||
let center = phantom.bounds().center();
|
let center = phantom.bounds().center();
|
||||||
phantom.animate({
|
phantom.animate({
|
||||||
|
@ -1238,7 +1277,7 @@ let UI = {
|
||||||
phantom.remove();
|
phantom.remove();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
GroupItems.setActiveGroupItem(lastActiveGroupItem);
|
self.setActive(lastActiveGroupItem);
|
||||||
}
|
}
|
||||||
|
|
||||||
function finalize(e) {
|
function finalize(e) {
|
||||||
|
@ -1260,7 +1299,7 @@ let UI = {
|
||||||
}
|
}
|
||||||
|
|
||||||
var groupItem = new GroupItem(insideTabs,{bounds:bounds});
|
var groupItem = new GroupItem(insideTabs,{bounds:bounds});
|
||||||
GroupItems.setActiveGroupItem(groupItem);
|
self.setActive(groupItem);
|
||||||
phantom.remove();
|
phantom.remove();
|
||||||
dragOutInfo = null;
|
dragOutInfo = null;
|
||||||
gTabView.firstUseExperienced = true;
|
gTabView.firstUseExperienced = true;
|
||||||
|
@ -1370,7 +1409,6 @@ let UI = {
|
||||||
// These computations may be done using cached values. The cache can be
|
// These computations may be done using cached values. The cache can be
|
||||||
// cleared with UI.clearShouldResizeItems().
|
// cleared with UI.clearShouldResizeItems().
|
||||||
shouldResizeItems: function UI_shouldResizeItems() {
|
shouldResizeItems: function UI_shouldResizeItems() {
|
||||||
|
|
||||||
let newPageBounds = Items.getPageBounds();
|
let newPageBounds = Items.getPageBounds();
|
||||||
|
|
||||||
// If we don't have cached cached values...
|
// If we don't have cached cached values...
|
||||||
|
@ -1523,6 +1561,30 @@ let UI = {
|
||||||
this._save();
|
this._save();
|
||||||
GroupItems.saveAll();
|
GroupItems.saveAll();
|
||||||
TabItems.saveAll();
|
TabItems.saveAll();
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Function: shouldLoadFavIcon
|
||||||
|
// Takes a xul:browser and checks whether we should display a favicon for it.
|
||||||
|
shouldLoadFavIcon: function UI_shouldLoadFavIcon(browser) {
|
||||||
|
return !(browser.contentDocument instanceof window.ImageDocument) &&
|
||||||
|
(browser.currentURI.schemeIs("about") ||
|
||||||
|
gBrowser.shouldLoadFavIcon(browser.contentDocument.documentURIObject));
|
||||||
|
},
|
||||||
|
|
||||||
|
// ----------
|
||||||
|
// Function: getFavIconUrlForTab
|
||||||
|
// Gets fav icon url for the given xul:tab.
|
||||||
|
getFavIconUrlForTab: function UI_getFavIconUrlForTab(tab) {
|
||||||
|
let url;
|
||||||
|
|
||||||
|
// use the tab image if it doesn't start with http e.g. data:image/png, chrome://
|
||||||
|
if (tab.image && !(/^https?:/.test(tab.image)))
|
||||||
|
url = tab.image;
|
||||||
|
else
|
||||||
|
url = gFavIconService.getFaviconImageForPage(tab.linkedBrowser.currentURI).spec;
|
||||||
|
|
||||||
|
return url;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -192,6 +192,13 @@ _BROWSER_FILES = \
|
||||||
browser_inspector_treePanel_output.js \
|
browser_inspector_treePanel_output.js \
|
||||||
browser_inspector_treePanel_input.html \
|
browser_inspector_treePanel_input.html \
|
||||||
browser_inspector_treePanel_result.html \
|
browser_inspector_treePanel_result.html \
|
||||||
|
browser_scratchpad_initialization.js \
|
||||||
|
browser_scratchpad_contexts.js \
|
||||||
|
browser_scratchpad_execute_print.js \
|
||||||
|
browser_scratchpad_inspect.js \
|
||||||
|
browser_scratchpad_files.js \
|
||||||
|
browser_scratchpad_ui.js \
|
||||||
|
browser_scratchpad_bug_646070_chrome_context_pref.js \
|
||||||
browser_overflowScroll.js \
|
browser_overflowScroll.js \
|
||||||
browser_pageInfo.js \
|
browser_pageInfo.js \
|
||||||
browser_page_style_menu.js \
|
browser_page_style_menu.js \
|
||||||
|
@ -215,12 +222,14 @@ _BROWSER_FILES = \
|
||||||
browser_tabfocus.js \
|
browser_tabfocus.js \
|
||||||
browser_tabs_isActive.js \
|
browser_tabs_isActive.js \
|
||||||
browser_tabs_owner.js \
|
browser_tabs_owner.js \
|
||||||
|
browser_urlHighlight.js \
|
||||||
browser_visibleFindSelection.js \
|
browser_visibleFindSelection.js \
|
||||||
browser_visibleTabs.js \
|
browser_visibleTabs.js \
|
||||||
browser_visibleTabs_contextMenu.js \
|
browser_visibleTabs_contextMenu.js \
|
||||||
browser_visibleTabs_bookmarkAllPages.js \
|
browser_visibleTabs_bookmarkAllPages.js \
|
||||||
browser_visibleTabs_bookmarkAllTabs.js \
|
browser_visibleTabs_bookmarkAllTabs.js \
|
||||||
browser_visibleTabs_tabPreview.js \
|
browser_visibleTabs_tabPreview.js \
|
||||||
|
browser_webdev_menu.js \
|
||||||
bug592338.html \
|
bug592338.html \
|
||||||
disablechrome.html \
|
disablechrome.html \
|
||||||
discovery.html \
|
discovery.html \
|
||||||
|
|
|
@ -56,7 +56,7 @@ function runInspectorTests()
|
||||||
ok(InspectorUI.isTreePanelOpen, "Inspector Tree Panel is open");
|
ok(InspectorUI.isTreePanelOpen, "Inspector Tree Panel is open");
|
||||||
ok(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
|
ok(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
|
||||||
ok(InspectorUI.isDOMPanelOpen, "Inspector DOM Panel is open");
|
ok(InspectorUI.isDOMPanelOpen, "Inspector DOM Panel is open");
|
||||||
InspectorUI.closeInspectorUI(true);
|
InspectorUI.closeInspectorUI();
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishInspectorTests()
|
function finishInspectorTests()
|
||||||
|
|
|
@ -157,6 +157,7 @@ function inspectorTabUnload1(evt)
|
||||||
ok(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
|
ok(InspectorUI.isStylePanelOpen, "Inspector Style Panel is open");
|
||||||
is(InspectorStore.length, 1, "InspectorStore.length = 1");
|
is(InspectorStore.length, 1, "InspectorStore.length = 1");
|
||||||
|
|
||||||
|
InspectorUI.closeInspectorUI();
|
||||||
gBrowser.removeCurrentTab();
|
gBrowser.removeCurrentTab();
|
||||||
finish();
|
finish();
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Reference to the Scratchpad chrome window object.
|
||||||
|
let gScratchpadWindow;
|
||||||
|
|
||||||
|
let gOldPref;
|
||||||
|
let DEVTOOLS_CHROME_ENABLED = "devtools.chrome.enabled";
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gOldPref = Services.prefs.getBoolPref(DEVTOOLS_CHROME_ENABLED);
|
||||||
|
Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, true);
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||||
|
|
||||||
|
ok(Scratchpad, "Scratchpad variable exists");
|
||||||
|
|
||||||
|
gScratchpadWindow = Scratchpad.openScratchpad();
|
||||||
|
gScratchpadWindow.addEventListener("load", runTests, false);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,Scratchpad test for bug 646070 - chrome context preference";
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests()
|
||||||
|
{
|
||||||
|
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
|
||||||
|
|
||||||
|
let sp = gScratchpadWindow.Scratchpad;
|
||||||
|
ok(sp, "Scratchpad object exists in new window");
|
||||||
|
|
||||||
|
let chromeContextMenu = gScratchpadWindow.document.
|
||||||
|
getElementById("sp-menu-chrome");
|
||||||
|
ok(chromeContextMenu, "Chrome context menuitem element exists");
|
||||||
|
ok(!chromeContextMenu.hasAttribute("hidden"),
|
||||||
|
"Chrome context menuitem is visible");
|
||||||
|
|
||||||
|
let errorConsoleCommand = gScratchpadWindow.document.
|
||||||
|
getElementById("sp-cmd-errorConsole");
|
||||||
|
ok(errorConsoleCommand, "Error console command element exists");
|
||||||
|
ok(!errorConsoleCommand.hasAttribute("disabled"),
|
||||||
|
"Error console command is enabled");
|
||||||
|
|
||||||
|
let errorConsoleMenu = gScratchpadWindow.document.
|
||||||
|
getElementById("sp-menu-errorConsole");
|
||||||
|
ok(errorConsoleMenu, "Error console menu element exists");
|
||||||
|
ok(!errorConsoleMenu.hasAttribute("hidden"),
|
||||||
|
"Error console menuitem is visible");
|
||||||
|
|
||||||
|
let chromeContextCommand = gScratchpadWindow.document.
|
||||||
|
getElementById("sp-cmd-chromeContext");
|
||||||
|
ok(chromeContextCommand, "Chrome context command element exists");
|
||||||
|
ok(!chromeContextCommand.hasAttribute("disabled"),
|
||||||
|
"Chrome context command is disabled");
|
||||||
|
|
||||||
|
Services.prefs.setBoolPref(DEVTOOLS_CHROME_ENABLED, gOldPref);
|
||||||
|
|
||||||
|
gScratchpadWindow.close();
|
||||||
|
gScratchpadWindow = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Reference to the Scratchpad chrome window object.
|
||||||
|
let gScratchpadWindow;
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||||
|
|
||||||
|
gScratchpadWindow = Scratchpad.openScratchpad();
|
||||||
|
gScratchpadWindow.addEventListener("load", runTests, false);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,test context switch in Scratchpad";
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests()
|
||||||
|
{
|
||||||
|
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
|
||||||
|
|
||||||
|
let sp = gScratchpadWindow.Scratchpad;
|
||||||
|
|
||||||
|
let contentMenu = gScratchpadWindow.document.getElementById("sp-menu-content");
|
||||||
|
let chromeMenu = gScratchpadWindow.document.getElementById("sp-menu-chrome");
|
||||||
|
let statusbar = sp.statusbarStatus;
|
||||||
|
|
||||||
|
ok(contentMenu, "found #sp-menu-content");
|
||||||
|
ok(chromeMenu, "found #sp-menu-chrome");
|
||||||
|
ok(statusbar, "found Scratchpad.statusbarStatus");
|
||||||
|
|
||||||
|
sp.setContentContext();
|
||||||
|
|
||||||
|
is(sp.executionContext, gScratchpadWindow.SCRATCHPAD_CONTEXT_CONTENT,
|
||||||
|
"executionContext is content");
|
||||||
|
|
||||||
|
is(contentMenu.getAttribute("checked"), "true",
|
||||||
|
"content menuitem is checked");
|
||||||
|
|
||||||
|
ok(!chromeMenu.hasAttribute("checked"),
|
||||||
|
"chrome menuitem is not checked");
|
||||||
|
|
||||||
|
is(statusbar.getAttribute("label"), contentMenu.getAttribute("label"),
|
||||||
|
"statusbar label is correct");
|
||||||
|
|
||||||
|
ok(sp.textbox, "textbox exists");
|
||||||
|
sp.textbox.value = "window.foobarBug636725 = 'aloha';";
|
||||||
|
|
||||||
|
ok(!content.wrappedJSObject.foobarBug636725,
|
||||||
|
"no content.foobarBug636725");
|
||||||
|
|
||||||
|
sp.execute();
|
||||||
|
|
||||||
|
is(content.wrappedJSObject.foobarBug636725, "aloha",
|
||||||
|
"content.foobarBug636725 has been set");
|
||||||
|
|
||||||
|
sp.setChromeContext();
|
||||||
|
|
||||||
|
is(sp.executionContext, gScratchpadWindow.SCRATCHPAD_CONTEXT_CHROME,
|
||||||
|
"executionContext is chrome");
|
||||||
|
|
||||||
|
is(chromeMenu.getAttribute("checked"), "true",
|
||||||
|
"chrome menuitem is checked");
|
||||||
|
|
||||||
|
ok(!contentMenu.hasAttribute("checked"),
|
||||||
|
"content menuitem is not checked");
|
||||||
|
|
||||||
|
is(statusbar.getAttribute("label"), chromeMenu.getAttribute("label"),
|
||||||
|
"statusbar label is correct");
|
||||||
|
|
||||||
|
sp.textbox.value = "window.foobarBug636725 = 'aloha2';";
|
||||||
|
|
||||||
|
ok(!window.foobarBug636725, "no window.foobarBug636725");
|
||||||
|
|
||||||
|
sp.execute();
|
||||||
|
|
||||||
|
is(window.foobarBug636725, "aloha2", "window.foobarBug636725 has been set");
|
||||||
|
|
||||||
|
sp.textbox.value = "window.gBrowser";
|
||||||
|
|
||||||
|
is(typeof sp.execute()[1].addTab, "function",
|
||||||
|
"chrome context has access to chrome objects");
|
||||||
|
|
||||||
|
// Check that the sandbox is cached.
|
||||||
|
|
||||||
|
sp.textbox.value = "typeof foobarBug636725cache;";
|
||||||
|
is(sp.execute()[1], "undefined", "global variable does not exist");
|
||||||
|
|
||||||
|
sp.textbox.value = "var foobarBug636725cache = 'foo';";
|
||||||
|
sp.execute();
|
||||||
|
|
||||||
|
sp.textbox.value = "typeof foobarBug636725cache;";
|
||||||
|
is(sp.execute()[1], "string",
|
||||||
|
"global variable exists across two different executions");
|
||||||
|
|
||||||
|
sp.resetContext();
|
||||||
|
|
||||||
|
is(sp.execute()[1], "undefined",
|
||||||
|
"global variable no longer exists after calling resetContext()");
|
||||||
|
|
||||||
|
sp.textbox.value = "var foobarBug636725cache2 = 'foo';";
|
||||||
|
sp.execute();
|
||||||
|
|
||||||
|
sp.textbox.value = "typeof foobarBug636725cache2;";
|
||||||
|
is(sp.execute()[1], "string",
|
||||||
|
"global variable exists across two different executions");
|
||||||
|
|
||||||
|
sp.setContentContext();
|
||||||
|
|
||||||
|
is(sp.executionContext, gScratchpadWindow.SCRATCHPAD_CONTEXT_CONTENT,
|
||||||
|
"executionContext is content");
|
||||||
|
|
||||||
|
is(sp.execute()[1], "undefined",
|
||||||
|
"global variable no longer exists after changing the context");
|
||||||
|
|
||||||
|
gScratchpadWindow.close();
|
||||||
|
gScratchpadWindow = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Reference to the Scratchpad chrome window object.
|
||||||
|
let gScratchpadWindow;
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||||
|
|
||||||
|
gScratchpadWindow = Scratchpad.openScratchpad();
|
||||||
|
gScratchpadWindow.addEventListener("load", runTests, false);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,<p>test execute() and print() in Scratchpad";
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests()
|
||||||
|
{
|
||||||
|
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
|
||||||
|
|
||||||
|
let sp = gScratchpadWindow.Scratchpad;
|
||||||
|
|
||||||
|
content.wrappedJSObject.foobarBug636725 = 1;
|
||||||
|
|
||||||
|
ok(sp.textbox, "textbox exists");
|
||||||
|
sp.textbox.value = "++window.foobarBug636725";
|
||||||
|
|
||||||
|
let exec = sp.execute();
|
||||||
|
is(exec[0], sp.textbox.value, "execute()[0] is correct");
|
||||||
|
is(exec[1], content.wrappedJSObject.foobarBug636725,
|
||||||
|
"execute()[1] is correct");
|
||||||
|
|
||||||
|
is(sp.textbox.value, "++window.foobarBug636725",
|
||||||
|
"execute() does not change the textbox value");
|
||||||
|
|
||||||
|
is(content.wrappedJSObject.foobarBug636725, 2,
|
||||||
|
"execute() updated window.foobarBug636725");
|
||||||
|
|
||||||
|
sp.print();
|
||||||
|
|
||||||
|
is(content.wrappedJSObject.foobarBug636725, 3,
|
||||||
|
"print() updated window.foobarBug636725");
|
||||||
|
|
||||||
|
is(sp.textbox.value, "++window.foobarBug636725/*\n3\n*/",
|
||||||
|
"print() shows evaluation result in the textbox");
|
||||||
|
|
||||||
|
is(sp.selectedText, "/*\n3\n*/", "selectedText is correct");
|
||||||
|
is(sp.textbox.selectionStart, 24, "selectionStart is correct");
|
||||||
|
is(sp.textbox.selectionEnd, 31, "selectionEnd is correct");
|
||||||
|
|
||||||
|
// Test selection execute() and print().
|
||||||
|
|
||||||
|
sp.textbox.value = "window.foobarBug636725 = 'a';\n" +
|
||||||
|
"window.foobarBug636725 = 'b';";
|
||||||
|
|
||||||
|
sp.selectRange(1, 2);
|
||||||
|
|
||||||
|
is(sp.textbox.selectionStart, 1, "selectionStart is 1");
|
||||||
|
is(sp.textbox.selectionEnd, 2, "selectionEnd is 2");
|
||||||
|
|
||||||
|
sp.selectRange(0, 29);
|
||||||
|
|
||||||
|
is(sp.textbox.selectionStart, 0, "selectionStart is 0");
|
||||||
|
is(sp.textbox.selectionEnd, 29, "selectionEnd is 29");
|
||||||
|
|
||||||
|
exec = sp.execute();
|
||||||
|
|
||||||
|
is(exec[0], "window.foobarBug636725 = 'a';",
|
||||||
|
"execute()[0] is correct");
|
||||||
|
is(exec[1], "a",
|
||||||
|
"execute()[1] is correct");
|
||||||
|
|
||||||
|
is(sp.textbox.value, "window.foobarBug636725 = 'a';\n" +
|
||||||
|
"window.foobarBug636725 = 'b';",
|
||||||
|
"execute() does not change the textbox value");
|
||||||
|
|
||||||
|
is(content.wrappedJSObject.foobarBug636725, "a",
|
||||||
|
"execute() worked for the selected range");
|
||||||
|
|
||||||
|
sp.textbox.value = "window.foobarBug636725 = 'c';\n" +
|
||||||
|
"window.foobarBug636725 = 'b';";
|
||||||
|
|
||||||
|
sp.selectRange(0, 22);
|
||||||
|
|
||||||
|
sp.print();
|
||||||
|
|
||||||
|
is(content.wrappedJSObject.foobarBug636725, "a",
|
||||||
|
"print() worked for the selected range");
|
||||||
|
|
||||||
|
is(sp.textbox.value, "window.foobarBug636725" +
|
||||||
|
"/*\na\n*/" +
|
||||||
|
" = 'c';\n" +
|
||||||
|
"window.foobarBug636725 = 'b';",
|
||||||
|
"print() shows evaluation result in the textbox");
|
||||||
|
|
||||||
|
is(sp.selectedText, "/*\na\n*/", "selectedText is correct");
|
||||||
|
is(sp.textbox.selectionStart, 22, "selectionStart is correct");
|
||||||
|
is(sp.textbox.selectionEnd, 29, "selectionEnd is correct");
|
||||||
|
|
||||||
|
sp.deselect();
|
||||||
|
|
||||||
|
ok(!sp.selectedText, "selectedText is empty");
|
||||||
|
is(sp.textbox.selectionStart, sp.textbox.selectionEnd, "deselect() works");
|
||||||
|
|
||||||
|
gScratchpadWindow.close();
|
||||||
|
gScratchpadWindow = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
|
@ -0,0 +1,149 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
const Cc = Components.classes;
|
||||||
|
const Ci = Components.interfaces;
|
||||||
|
const Cu = Components.utils;
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||||
|
Cu.import("resource://gre/modules/FileUtils.jsm");
|
||||||
|
|
||||||
|
// Reference to the Scratchpad chrome window object.
|
||||||
|
let gScratchpadWindow;
|
||||||
|
|
||||||
|
// Reference to the Scratchpad object.
|
||||||
|
let gScratchpad;
|
||||||
|
|
||||||
|
// Reference to the temporary nsIFile we will work with.
|
||||||
|
let gFile;
|
||||||
|
|
||||||
|
// The temporary file content.
|
||||||
|
let gFileContent = "hello.world('bug636725');";
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||||
|
|
||||||
|
gScratchpadWindow = Scratchpad.openScratchpad();
|
||||||
|
gScratchpadWindow.addEventListener("load", runTests, false);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,<p>test file open and save in Scratchpad";
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests()
|
||||||
|
{
|
||||||
|
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
|
||||||
|
|
||||||
|
gScratchpad = gScratchpadWindow.Scratchpad;
|
||||||
|
|
||||||
|
// Create a temporary file.
|
||||||
|
gFile = FileUtils.getFile("TmpD", ["fileForBug636725.tmp"]);
|
||||||
|
gFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0666);
|
||||||
|
|
||||||
|
// Write the temporary file.
|
||||||
|
let fout = Cc["@mozilla.org/network/file-output-stream;1"].
|
||||||
|
createInstance(Ci.nsIFileOutputStream);
|
||||||
|
fout.init(gFile.QueryInterface(Ci.nsILocalFile), 0x02 | 0x08 | 0x20,
|
||||||
|
0644, fout.DEFER_OPEN);
|
||||||
|
|
||||||
|
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"].
|
||||||
|
createInstance(Ci.nsIScriptableUnicodeConverter);
|
||||||
|
converter.charset = "UTF-8";
|
||||||
|
let fileContentStream = converter.convertToInputStream(gFileContent);
|
||||||
|
|
||||||
|
NetUtil.asyncCopy(fileContentStream, fout, tempFileSaved);
|
||||||
|
}
|
||||||
|
|
||||||
|
function tempFileSaved(aStatus)
|
||||||
|
{
|
||||||
|
ok(Components.isSuccessCode(aStatus),
|
||||||
|
"the temporary file was saved successfully");
|
||||||
|
|
||||||
|
// Import the file into Scratchpad.
|
||||||
|
gScratchpad.importFromFile(gFile.QueryInterface(Ci.nsILocalFile), true,
|
||||||
|
fileImported);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fileImported(aStatus, aFileContent)
|
||||||
|
{
|
||||||
|
ok(Components.isSuccessCode(aStatus),
|
||||||
|
"the temporary file was imported successfully with Scratchpad");
|
||||||
|
|
||||||
|
is(aFileContent, gFileContent,
|
||||||
|
"received data is correct");
|
||||||
|
|
||||||
|
is(gScratchpad.textbox.value, gFileContent,
|
||||||
|
"the textbox.value is correct");
|
||||||
|
|
||||||
|
// Save the file after changes.
|
||||||
|
gFileContent += "// omg, saved!";
|
||||||
|
gScratchpad.textbox.value = gFileContent;
|
||||||
|
|
||||||
|
gScratchpad.exportToFile(gFile.QueryInterface(Ci.nsILocalFile), true, true,
|
||||||
|
fileExported);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fileExported(aStatus)
|
||||||
|
{
|
||||||
|
ok(Components.isSuccessCode(aStatus),
|
||||||
|
"the temporary file was exported successfully with Scratchpad");
|
||||||
|
|
||||||
|
let oldContent = gFileContent;
|
||||||
|
|
||||||
|
// Attempt another file save, with confirmation which returns false.
|
||||||
|
gFileContent += "// omg, saved twice!";
|
||||||
|
gScratchpad.textbox.value = gFileContent;
|
||||||
|
|
||||||
|
let oldConfirm = gScratchpadWindow.confirm;
|
||||||
|
let askedConfirmation = false;
|
||||||
|
gScratchpadWindow.confirm = function() {
|
||||||
|
askedConfirmation = true;
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
gScratchpad.exportToFile(gFile.QueryInterface(Ci.nsILocalFile), false, true,
|
||||||
|
fileExported2);
|
||||||
|
|
||||||
|
gScratchpadWindow.confirm = oldConfirm;
|
||||||
|
|
||||||
|
ok(askedConfirmation, "exportToFile() asked for overwrite confirmation");
|
||||||
|
|
||||||
|
gFileContent = oldContent;
|
||||||
|
|
||||||
|
let channel = NetUtil.newChannel(gFile);
|
||||||
|
channel.contentType = "application/javascript";
|
||||||
|
|
||||||
|
// Read back the temporary file.
|
||||||
|
NetUtil.asyncFetch(channel, fileRead);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fileExported2()
|
||||||
|
{
|
||||||
|
ok(false, "exportToFile() did not cancel file overwrite");
|
||||||
|
}
|
||||||
|
|
||||||
|
function fileRead(aInputStream, aStatus)
|
||||||
|
{
|
||||||
|
ok(Components.isSuccessCode(aStatus),
|
||||||
|
"the temporary file was read back successfully");
|
||||||
|
|
||||||
|
let updatedContent =
|
||||||
|
NetUtil.readInputStreamToString(aInputStream, aInputStream.available());;
|
||||||
|
|
||||||
|
is(updatedContent, gFileContent, "file properly updated");
|
||||||
|
|
||||||
|
// Done!
|
||||||
|
gFile.remove(false);
|
||||||
|
gFile = null;
|
||||||
|
gScratchpad = null;
|
||||||
|
gScratchpadWindow.close();
|
||||||
|
gScratchpadWindow = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
|
@ -0,0 +1,63 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Reference to the Scratchpad chrome window object.
|
||||||
|
let gScratchpadWindow;
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||||
|
|
||||||
|
ok(Scratchpad, "Scratchpad variable exists");
|
||||||
|
|
||||||
|
gScratchpadWindow = Scratchpad.openScratchpad();
|
||||||
|
gScratchpadWindow.addEventListener("load", runTests, false);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,initialization test for Scratchpad";
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests()
|
||||||
|
{
|
||||||
|
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
|
||||||
|
|
||||||
|
let sp = gScratchpadWindow.Scratchpad;
|
||||||
|
ok(sp, "Scratchpad object exists in new window");
|
||||||
|
is(typeof sp.execute, "function", "Scratchpad.execute() exists");
|
||||||
|
is(typeof sp.inspect, "function", "Scratchpad.inspect() exists");
|
||||||
|
is(typeof sp.print, "function", "Scratchpad.print() exists");
|
||||||
|
|
||||||
|
let chromeContextMenu = gScratchpadWindow.document.
|
||||||
|
getElementById("sp-menu-chrome");
|
||||||
|
ok(chromeContextMenu, "Chrome context menuitem element exists");
|
||||||
|
is(chromeContextMenu.getAttribute("hidden"), "true",
|
||||||
|
"Chrome context menuitem is hidden");
|
||||||
|
|
||||||
|
let errorConsoleCommand = gScratchpadWindow.document.
|
||||||
|
getElementById("sp-cmd-errorConsole");
|
||||||
|
ok(errorConsoleCommand, "Error console command element exists");
|
||||||
|
is(errorConsoleCommand.getAttribute("disabled"), "true",
|
||||||
|
"Error console command is disabled");
|
||||||
|
|
||||||
|
let errorConsoleMenu = gScratchpadWindow.document.
|
||||||
|
getElementById("sp-menu-errorConsole");
|
||||||
|
ok(errorConsoleMenu, "Error console menu element exists");
|
||||||
|
is(errorConsoleMenu.getAttribute("hidden"), "true",
|
||||||
|
"Error console menu item is hidden");
|
||||||
|
|
||||||
|
let chromeContextCommand = gScratchpadWindow.document.
|
||||||
|
getElementById("sp-cmd-chromeContext");
|
||||||
|
ok(chromeContextCommand, "Chrome context command element exists");
|
||||||
|
is(chromeContextCommand.getAttribute("disabled"), "true",
|
||||||
|
"Chrome context command is disabled");
|
||||||
|
|
||||||
|
gScratchpadWindow.close();
|
||||||
|
gScratchpadWindow = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Reference to the Scratchpad chrome window object.
|
||||||
|
let gScratchpadWindow;
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||||
|
|
||||||
|
gScratchpadWindow = Scratchpad.openScratchpad();
|
||||||
|
gScratchpadWindow.addEventListener("load", runTests, false);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,<title>foobarBug636725</title>" +
|
||||||
|
"<p>test inspect() in Scratchpad";
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests()
|
||||||
|
{
|
||||||
|
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
|
||||||
|
|
||||||
|
let sp = gScratchpadWindow.Scratchpad;
|
||||||
|
|
||||||
|
ok(sp.textbox, "textbox exists");
|
||||||
|
sp.textbox.value = "document";
|
||||||
|
|
||||||
|
sp.inspect();
|
||||||
|
|
||||||
|
let propPanel = document.querySelector(".scratchpad_propertyPanel");
|
||||||
|
ok(propPanel, "property panel is open");
|
||||||
|
|
||||||
|
propPanel.addEventListener("popupshown", function() {
|
||||||
|
propPanel.removeEventListener("popupshown", arguments.callee, false);
|
||||||
|
|
||||||
|
let tree = propPanel.querySelector("tree");
|
||||||
|
ok(tree, "property panel tree found");
|
||||||
|
|
||||||
|
let column = tree.columns[0];
|
||||||
|
let found = false;
|
||||||
|
|
||||||
|
for (let i = 0; i < tree.view.rowCount; i++) {
|
||||||
|
let cell = tree.view.getCellText(i, column);
|
||||||
|
if (cell == 'title: "foobarBug636725"') {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ok(found, "found the document.title property");
|
||||||
|
|
||||||
|
executeSoon(function() {
|
||||||
|
propPanel.hidePopup();
|
||||||
|
|
||||||
|
gScratchpadWindow.close();
|
||||||
|
gScratchpadWindow = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
});
|
||||||
|
}, false);
|
||||||
|
}
|
|
@ -0,0 +1,81 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
// Reference to the Scratchpad chrome window object.
|
||||||
|
let gScratchpadWindow;
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||||
|
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||||
|
|
||||||
|
gScratchpadWindow = Scratchpad.openScratchpad();
|
||||||
|
gScratchpadWindow.addEventListener("load", runTests, false);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,<title>foobarBug636725</title>" +
|
||||||
|
"<p>test inspect() in Scratchpad";
|
||||||
|
}
|
||||||
|
|
||||||
|
function runTests()
|
||||||
|
{
|
||||||
|
gScratchpadWindow.removeEventListener("load", arguments.callee, false);
|
||||||
|
|
||||||
|
let sp = gScratchpadWindow.Scratchpad;
|
||||||
|
let doc = gScratchpadWindow.document;
|
||||||
|
|
||||||
|
let methodsAndItems = {
|
||||||
|
"sp-menu-newscratchpad": "openScratchpad",
|
||||||
|
"sp-menu-open": "openFile",
|
||||||
|
"sp-menu-save": "saveFile",
|
||||||
|
"sp-menu-saveas": "saveFileAs",
|
||||||
|
"sp-text-execute": "execute",
|
||||||
|
"sp-text-inspect": "inspect",
|
||||||
|
"sp-menu-content": "setContentContext",
|
||||||
|
"sp-menu-chrome": "setChromeContext",
|
||||||
|
"sp-menu-resetContext": "resetContext",
|
||||||
|
"sp-menu-errorConsole": "openErrorConsole",
|
||||||
|
"sp-menu-webConsole": "openWebConsole",
|
||||||
|
};
|
||||||
|
|
||||||
|
let lastMethodCalled = null;
|
||||||
|
sp.__noSuchMethod__ = function(aMethodName) {
|
||||||
|
lastMethodCalled = aMethodName;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (let id in methodsAndItems) {
|
||||||
|
lastMethodCalled = null;
|
||||||
|
|
||||||
|
let methodName = methodsAndItems[id];
|
||||||
|
let oldMethod = sp[methodName];
|
||||||
|
ok(oldMethod, "found method " + methodName + " in Scratchpad object");
|
||||||
|
|
||||||
|
delete sp[methodName];
|
||||||
|
|
||||||
|
let menu = doc.getElementById(id);
|
||||||
|
ok(menu, "found menuitem #" + id);
|
||||||
|
|
||||||
|
try {
|
||||||
|
menu.doCommand();
|
||||||
|
}
|
||||||
|
catch (ex) {
|
||||||
|
ok(false, "exception thrown while executing the command of menuitem #" + id);
|
||||||
|
}
|
||||||
|
|
||||||
|
ok(lastMethodCalled == methodName,
|
||||||
|
"method " + methodName + " invoked by the associated menuitem");
|
||||||
|
|
||||||
|
sp[methodName] = oldMethod;
|
||||||
|
}
|
||||||
|
|
||||||
|
delete sp.__noSuchMethod__;
|
||||||
|
|
||||||
|
gScratchpadWindow.close();
|
||||||
|
gScratchpadWindow = null;
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
|
@ -0,0 +1,58 @@
|
||||||
|
function testVal(aExpected) {
|
||||||
|
gURLBar.value = aExpected.replace(/[<>]/g, "");
|
||||||
|
|
||||||
|
let selectionController = gURLBar.editor.selectionController;
|
||||||
|
let selection = selectionController.getSelection(selectionController.SELECTION_URLSECONDARY);
|
||||||
|
let value = gURLBar.editor.rootElement.textContent;
|
||||||
|
let result = "";
|
||||||
|
for (let i = 0; i < selection.rangeCount; i++) {
|
||||||
|
let range = selection.getRangeAt(i).toString();
|
||||||
|
let pos = value.indexOf(range);
|
||||||
|
result += value.substring(0, pos) + "<" + range + ">";
|
||||||
|
value = value.substring(pos + range.length);
|
||||||
|
}
|
||||||
|
result += value;
|
||||||
|
is(result, aExpected);
|
||||||
|
}
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
const prefname = "browser.urlbar.formatting.enabled";
|
||||||
|
|
||||||
|
registerCleanupFunction(function () {
|
||||||
|
Services.prefs.clearUserPref(prefname);
|
||||||
|
URLBarSetURI();
|
||||||
|
});
|
||||||
|
|
||||||
|
Services.prefs.setBoolPref(prefname, true);
|
||||||
|
|
||||||
|
testVal("<http://>mozilla.org");
|
||||||
|
testVal("<http://>mozilla.org</>");
|
||||||
|
testVal("<http://>mözilla.org</>");
|
||||||
|
testVal("<http://>mozilla.imaginatory</>");
|
||||||
|
testVal("<http://www.>mozilla.org</>");
|
||||||
|
testVal("<http://sub.>mozilla.org</>");
|
||||||
|
testVal("<http://sub1.sub2.sub3.>mozilla.org</>");
|
||||||
|
testVal("<http://ftp.>mozilla.org</>");
|
||||||
|
testVal("<ftp://ftp.>mozilla.org</>");
|
||||||
|
|
||||||
|
testVal("<https://sub.>mozilla.org</>");
|
||||||
|
testVal("<https://sub1.sub2.sub3.>mozilla.org</>");
|
||||||
|
testVal("<https://user:pass@sub1.sub2.sub3.>mozilla.org</>");
|
||||||
|
testVal("<https://user:pass@>mozilla.org</>");
|
||||||
|
|
||||||
|
testVal("<http://>mozilla.org</file.ext>");
|
||||||
|
testVal("<http://>mozilla.org</sub/file.ext>");
|
||||||
|
testVal("<http://>mozilla.org</sub/file.ext?foo>");
|
||||||
|
testVal("<http://>mozilla.org</sub/file.ext?foo&bar>");
|
||||||
|
testVal("<http://>mozilla.org</sub/file.ext?foo&bar#top>");
|
||||||
|
|
||||||
|
testVal("<http://sub.>mozilla.org<:666/file.ext>");
|
||||||
|
|
||||||
|
testVal("mailto:admin@mozilla.org");
|
||||||
|
testVal("gopher://mozilla.org/");
|
||||||
|
testVal("about:config");
|
||||||
|
|
||||||
|
Services.prefs.setBoolPref(prefname, false);
|
||||||
|
|
||||||
|
testVal("http://mozilla.org/");
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
/* vim: set ts=2 et sw=2 tw=80: */
|
||||||
|
/* Any copyright is dedicated to the Public Domain.
|
||||||
|
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||||
|
|
||||||
|
function menuTest()
|
||||||
|
{
|
||||||
|
gBrowser.selectedBrowser.removeEventListener("load", menuTest, true);
|
||||||
|
|
||||||
|
let menuContents = [
|
||||||
|
"menu_pageinspect",
|
||||||
|
"webConsole",
|
||||||
|
"menu_scratchpad",
|
||||||
|
"menu_pageSource",
|
||||||
|
"javascriptConsole"
|
||||||
|
];
|
||||||
|
|
||||||
|
let menu = document.getElementById("webDeveloperMenu");
|
||||||
|
ok(menu, "we have the menu");
|
||||||
|
|
||||||
|
let popup = menu.firstChild;
|
||||||
|
is(popup.id, "menuWebDeveloperPopup", "menu first child is menuWebDeveloperPopup");
|
||||||
|
|
||||||
|
is(popup.childNodes.length, menuContents.length, "popup childNodes.length matches");
|
||||||
|
|
||||||
|
for(let a = 0; a < popup.children.length; a++) {
|
||||||
|
isnot(menuContents.indexOf(popup.children[a].id), -1, "menuitem " + popup.children[a].id + " in popup");
|
||||||
|
};
|
||||||
|
|
||||||
|
gBrowser.removeCurrentTab();
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
|
||||||
|
function test()
|
||||||
|
{
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
gBrowser.selectedTab = gBrowser.addTab();
|
||||||
|
gBrowser.selectedBrowser.addEventListener("load", menuTest, true);
|
||||||
|
|
||||||
|
content.location = "data:text/html,<title>Web Developer Menu Test</title>" +
|
||||||
|
"<p>testing the Web Developer Menu";
|
||||||
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ function onTabViewWindowLoaded() {
|
||||||
let groupItemOne = new contentWindow.GroupItem([],
|
let groupItemOne = new contentWindow.GroupItem([],
|
||||||
{ bounds: box, title: "test1" });
|
{ bounds: box, title: "test1" });
|
||||||
is(contentWindow.GroupItems.groupItems.length, 2, "we now have two groups");
|
is(contentWindow.GroupItems.groupItems.length, 2, "we now have two groups");
|
||||||
contentWindow.GroupItems.setActiveGroupItem(groupItemOne);
|
contentWindow.UI.setActive(groupItemOne);
|
||||||
|
|
||||||
// create a tab
|
// create a tab
|
||||||
let xulTab = gBrowser.loadOneTab("about:blank");
|
let xulTab = gBrowser.loadOneTab("about:blank");
|
||||||
|
|
|
@ -80,7 +80,7 @@ function onTabViewWindowLoaded() {
|
||||||
|
|
||||||
let currentTabs = contentWindow.TabItems.getItems();
|
let currentTabs = contentWindow.TabItems.getItems();
|
||||||
ok(currentTabs[0], "A tab item exists to make active");
|
ok(currentTabs[0], "A tab item exists to make active");
|
||||||
contentWindow.UI.setActiveTab(currentTabs[0]);
|
contentWindow.UI.setActive(currentTabs[0]);
|
||||||
|
|
||||||
window.addEventListener("tabviewhidden", finishTest, false);
|
window.addEventListener("tabviewhidden", finishTest, false);
|
||||||
TabView.toggle();
|
TabView.toggle();
|
||||||
|
|
|
@ -19,7 +19,7 @@ function onTabViewWindowLoaded(win) {
|
||||||
let box = new contentWindow.Rect(100, 100, 400, 430);
|
let box = new contentWindow.Rect(100, 100, 400, 430);
|
||||||
let group = new contentWindow.GroupItem([], { bounds: box });
|
let group = new contentWindow.GroupItem([], { bounds: box });
|
||||||
ok(group.isEmpty(), "This group is empty");
|
ok(group.isEmpty(), "This group is empty");
|
||||||
contentWindow.GroupItems.setActiveGroupItem(group);
|
contentWindow.UI.setActive(group);
|
||||||
|
|
||||||
// Create a bunch of tabs in the group
|
// Create a bunch of tabs in the group
|
||||||
let tabs = [];
|
let tabs = [];
|
||||||
|
@ -167,12 +167,12 @@ function simulateSlowDragDrop(srcElement, offsetX, offsetY, contentWindow, time)
|
||||||
}
|
}
|
||||||
|
|
||||||
function checkDropIndexAndDropSpace(item, group, offsetX, offsetY, contentWindow, callback, time) {
|
function checkDropIndexAndDropSpace(item, group, offsetX, offsetY, contentWindow, callback, time) {
|
||||||
contentWindow.UI.setActiveTab(item);
|
contentWindow.UI.setActive(item);
|
||||||
let dropSpaceActiveValues = [];
|
let dropSpaceActiveValues = [];
|
||||||
let recordDropSpaceValue = function() {
|
let recordDropSpaceValue = function() {
|
||||||
dropSpaceActiveValues.push(group._dropSpaceActive);
|
dropSpaceActiveValues.push(group._dropSpaceActive);
|
||||||
};
|
};
|
||||||
// contentWindow.iQ(item.container).css({border: 'red 1px solid'});
|
|
||||||
let onDrop = function() {
|
let onDrop = function() {
|
||||||
item.container.removeEventListener('dragover', recordDropSpaceValue, false);
|
item.container.removeEventListener('dragover', recordDropSpaceValue, false);
|
||||||
item.container.removeEventListener('drop', onDrop, false);
|
item.container.removeEventListener('drop', onDrop, false);
|
||||||
|
|
|
@ -31,7 +31,7 @@ function onTabViewWindowLoaded() {
|
||||||
let box = new contentWindow.Rect(10, 10, 300, 300);
|
let box = new contentWindow.Rect(10, 10, 300, 300);
|
||||||
let group = new contentWindow.GroupItem([], { bounds: box });
|
let group = new contentWindow.GroupItem([], { bounds: box });
|
||||||
ok(group.isEmpty(), "This group is empty");
|
ok(group.isEmpty(), "This group is empty");
|
||||||
contentWindow.GroupItems.setActiveGroupItem(group);
|
contentWindow.UI.setActive(group);
|
||||||
|
|
||||||
// Create a second tab in this new group
|
// Create a second tab in this new group
|
||||||
let secondTab = gBrowser.loadOneTab("about:blank#2", {inBackground: true});
|
let secondTab = gBrowser.loadOneTab("about:blank#2", {inBackground: true});
|
||||||
|
|
|
@ -20,7 +20,7 @@ function onTabViewWindowLoaded() {
|
||||||
let box1 = new contentWindow.Rect(310, 10, 300, 300);
|
let box1 = new contentWindow.Rect(310, 10, 300, 300);
|
||||||
let group1 = new contentWindow.GroupItem([], { bounds: box1 });
|
let group1 = new contentWindow.GroupItem([], { bounds: box1 });
|
||||||
ok(group1.isEmpty(), "This group is empty");
|
ok(group1.isEmpty(), "This group is empty");
|
||||||
contentWindow.GroupItems.setActiveGroupItem(group1);
|
contentWindow.UI.setActive(group1);
|
||||||
let tab1 = gBrowser.loadOneTab("about:blank#1", {inBackground: true});
|
let tab1 = gBrowser.loadOneTab("about:blank#1", {inBackground: true});
|
||||||
let tab1Item = tab1._tabViewTabItem;
|
let tab1Item = tab1._tabViewTabItem;
|
||||||
ok(group1.getChildren().some(function(child) child == tab1Item), "The tab was made in our new group");
|
ok(group1.getChildren().some(function(child) child == tab1Item), "The tab was made in our new group");
|
||||||
|
|
|
@ -27,7 +27,7 @@ function onTabViewWindowLoaded() {
|
||||||
let box = new contentWindow.Rect(20, 20, 180, 180);
|
let box = new contentWindow.Rect(20, 20, 180, 180);
|
||||||
let groupItem = new contentWindow.GroupItem([], { bounds: box });
|
let groupItem = new contentWindow.GroupItem([], { bounds: box });
|
||||||
is(contentWindow.GroupItems.groupItems.length, 2, "we now have two groups");
|
is(contentWindow.GroupItems.groupItems.length, 2, "we now have two groups");
|
||||||
contentWindow.GroupItems.setActiveGroupItem(groupItem);
|
contentWindow.UI.setActive(groupItem);
|
||||||
|
|
||||||
// create a second tab
|
// create a second tab
|
||||||
let normalXulTab = gBrowser.loadOneTab("about:blank");
|
let normalXulTab = gBrowser.loadOneTab("about:blank");
|
||||||
|
|
|
@ -35,7 +35,7 @@ function onTabViewShown(win) {
|
||||||
let groupItem = new contentWindow.GroupItem([],
|
let groupItem = new contentWindow.GroupItem([],
|
||||||
{ bounds: box, title: "test1" });
|
{ bounds: box, title: "test1" });
|
||||||
is(contentWindow.GroupItems.groupItems.length, 2, "we now have two groups");
|
is(contentWindow.GroupItems.groupItems.length, 2, "we now have two groups");
|
||||||
contentWindow.GroupItems.setActiveGroupItem(groupItem);
|
contentWindow.UI.setActive(groupItem);
|
||||||
|
|
||||||
// create a tab
|
// create a tab
|
||||||
let xulTabs = [];
|
let xulTabs = [];
|
||||||
|
|
|
@ -25,7 +25,7 @@ function part1(win) {
|
||||||
newGroup.add(newTab._tabViewTabItem, {immediately: true});
|
newGroup.add(newTab._tabViewTabItem, {immediately: true});
|
||||||
|
|
||||||
// ensure active group item and tab
|
// ensure active group item and tab
|
||||||
contentWindow.GroupItems.setActiveGroupItem(originalGroup);
|
contentWindow.UI.setActive(originalGroup);
|
||||||
is(contentWindow.GroupItems.getActiveGroupItem(), originalGroup,
|
is(contentWindow.GroupItems.getActiveGroupItem(), originalGroup,
|
||||||
"The original group is active");
|
"The original group is active");
|
||||||
is(contentWindow.UI.getActiveTab(), originalTab._tabViewTabItem,
|
is(contentWindow.UI.getActiveTab(), originalTab._tabViewTabItem,
|
||||||
|
|
|
@ -20,7 +20,7 @@ function onTabViewWindowLoaded() {
|
||||||
// Create a group and make it active
|
// Create a group and make it active
|
||||||
let box = new contentWindow.Rect(10, 10, 300, 300);
|
let box = new contentWindow.Rect(10, 10, 300, 300);
|
||||||
let groupItemTwo = new contentWindow.GroupItem([], { bounds: box });
|
let groupItemTwo = new contentWindow.GroupItem([], { bounds: box });
|
||||||
contentWindow.GroupItems.setActiveGroupItem(groupItemTwo);
|
contentWindow.UI.setActive(groupItemTwo);
|
||||||
|
|
||||||
let testTab =
|
let testTab =
|
||||||
gBrowser.addTab(
|
gBrowser.addTab(
|
||||||
|
|
|
@ -38,7 +38,7 @@ function onTabViewWindowLoaded() {
|
||||||
// code.
|
// code.
|
||||||
executeSoon(function() {
|
executeSoon(function() {
|
||||||
is($icon.attr("src"), contentWindow.Utils.defaultFaviconURL,
|
is($icon.attr("src"), contentWindow.Utils.defaultFaviconURL,
|
||||||
"The icon is showing th default fav icon");
|
"The icon is showing the default fav icon");
|
||||||
|
|
||||||
// clean up
|
// clean up
|
||||||
gBrowser.removeTab(newTab);
|
gBrowser.removeTab(newTab);
|
||||||
|
|
|
@ -8,7 +8,7 @@ function test() {
|
||||||
let bounds = new cw.Rect(20, 20, 150, 150);
|
let bounds = new cw.Rect(20, 20, 150, 150);
|
||||||
let groupItem = new cw.GroupItem([], {bounds: bounds, immediately: true});
|
let groupItem = new cw.GroupItem([], {bounds: bounds, immediately: true});
|
||||||
|
|
||||||
cw.GroupItems.setActiveGroupItem(groupItem);
|
cw.UI.setActive(groupItem);
|
||||||
gBrowser.loadOneTab('about:blank', {inBackground: true});
|
gBrowser.loadOneTab('about:blank', {inBackground: true});
|
||||||
|
|
||||||
return groupItem;
|
return groupItem;
|
||||||
|
|
|
@ -8,7 +8,7 @@ function test() {
|
||||||
let bounds = new cw.Rect(20, 20, 200, 200);
|
let bounds = new cw.Rect(20, 20, 200, 200);
|
||||||
let groupItem = new cw.GroupItem([], {bounds: bounds, immediately: true});
|
let groupItem = new cw.GroupItem([], {bounds: bounds, immediately: true});
|
||||||
|
|
||||||
cw.GroupItems.setActiveGroupItem(groupItem);
|
cw.UI.setActive(groupItem);
|
||||||
gBrowser.loadOneTab('about:blank', {inBackground: true});
|
gBrowser.loadOneTab('about:blank', {inBackground: true});
|
||||||
|
|
||||||
return groupItem;
|
return groupItem;
|
||||||
|
|
|
@ -38,7 +38,7 @@ function test() {
|
||||||
ok(!originalBounds.equals(groupItem.getChild(0).getBounds()), testName + ': tabs changed their size');
|
ok(!originalBounds.equals(groupItem.getChild(0).getBounds()), testName + ': tabs changed their size');
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
cw.GroupItems.setActiveGroupItem(groupItem);
|
cw.UI.setActive(groupItem);
|
||||||
win.gBrowser.loadOneTab('about:blank', {inBackground: true});
|
win.gBrowser.loadOneTab('about:blank', {inBackground: true});
|
||||||
afterAllTabsLoaded(callback, win);
|
afterAllTabsLoaded(callback, win);
|
||||||
}, 500);
|
}, 500);
|
||||||
|
|
|
@ -21,7 +21,7 @@ function onTabViewWindowLoaded(win) {
|
||||||
let box = new contentWindow.Rect(100, 100, 370, 370);
|
let box = new contentWindow.Rect(100, 100, 370, 370);
|
||||||
let group = new contentWindow.GroupItem([], { bounds: box });
|
let group = new contentWindow.GroupItem([], { bounds: box });
|
||||||
ok(group.isEmpty(), "This group is empty");
|
ok(group.isEmpty(), "This group is empty");
|
||||||
contentWindow.GroupItems.setActiveGroupItem(group);
|
contentWindow.UI.setActive(group);
|
||||||
is(contentWindow.GroupItems.getActiveGroupItem(), group, "new group is active");
|
is(contentWindow.GroupItems.getActiveGroupItem(), group, "new group is active");
|
||||||
|
|
||||||
// Create a bunch of tabs in the group
|
// Create a bunch of tabs in the group
|
||||||
|
@ -41,7 +41,7 @@ function onTabViewWindowLoaded(win) {
|
||||||
|
|
||||||
ok(group.isEmpty(), "The group is empty again");
|
ok(group.isEmpty(), "The group is empty again");
|
||||||
|
|
||||||
contentWindow.GroupItems.setActiveGroupItem(currentGroup);
|
contentWindow.UI.setActive(currentGroup);
|
||||||
isnot(contentWindow.GroupItems.getActiveGroupItem(), null, "There is an active group");
|
isnot(contentWindow.GroupItems.getActiveGroupItem(), null, "There is an active group");
|
||||||
is(win.gBrowser.tabs.length, 1, "There is only one tab left");
|
is(win.gBrowser.tabs.length, 1, "There is only one tab left");
|
||||||
is(win.gBrowser.visibleTabs.length, 1, "There is also only one visible tab");
|
is(win.gBrowser.visibleTabs.length, 1, "There is also only one visible tab");
|
||||||
|
@ -71,7 +71,7 @@ function onTabViewWindowLoaded(win) {
|
||||||
afterAllTabItemsUpdated(function() {
|
afterAllTabItemsUpdated(function() {
|
||||||
check(datatext, "datatext", false);
|
check(datatext, "datatext", false);
|
||||||
check(datahtml, "datahtml", false);
|
check(datahtml, "datahtml", false);
|
||||||
check(mozilla, "about:mozilla", false);
|
check(mozilla, "about:mozilla", true);
|
||||||
check(html, "html", true);
|
check(html, "html", true);
|
||||||
check(png, "png", false);
|
check(png, "png", false);
|
||||||
check(svg, "svg", true);
|
check(svg, "svg", true);
|
||||||
|
|
|
@ -18,7 +18,7 @@ function test() {
|
||||||
is(cw.GroupItems.groupItems.length, 1, "There's only one group");
|
is(cw.GroupItems.groupItems.length, 1, "There's only one group");
|
||||||
|
|
||||||
groupItem = createEmptyGroupItem(cw, 200, 200, 20);
|
groupItem = createEmptyGroupItem(cw, 200, 200, 20);
|
||||||
cw.GroupItems.setActiveGroupItem(groupItem);
|
cw.UI.setActive(groupItem);
|
||||||
|
|
||||||
executeSoon(function () hideTabView(onHide, win));
|
executeSoon(function () hideTabView(onHide, win));
|
||||||
};
|
};
|
||||||
|
|
|
@ -12,7 +12,7 @@ function test() {
|
||||||
let createGroupItem = function (numTabs) {
|
let createGroupItem = function (numTabs) {
|
||||||
let bounds = new cw.Rect(20, 20, 200, 200);
|
let bounds = new cw.Rect(20, 20, 200, 200);
|
||||||
let groupItem = new cw.GroupItem([], {bounds: bounds, immediately: true});
|
let groupItem = new cw.GroupItem([], {bounds: bounds, immediately: true});
|
||||||
cw.GroupItems.setActiveGroupItem(groupItem);
|
cw.UI.setActive(groupItem);
|
||||||
|
|
||||||
for (let i=0; i<numTabs || 0; i++)
|
for (let i=0; i<numTabs || 0; i++)
|
||||||
gBrowser.loadOneTab('about:blank', {inBackground: true});
|
gBrowser.loadOneTab('about:blank', {inBackground: true});
|
||||||
|
|
|
@ -28,7 +28,7 @@ function onTabViewShown(win) {
|
||||||
bounds: {left: 20, top: 20, width: 100, height: 100}
|
bounds: {left: 20, top: 20, width: 100, height: 100}
|
||||||
});
|
});
|
||||||
|
|
||||||
contentWindow.GroupItems.setActiveGroupItem(groupItem);
|
contentWindow.UI.setActive(groupItem);
|
||||||
|
|
||||||
// we need seven tabs at least to reproduce this
|
// we need seven tabs at least to reproduce this
|
||||||
for (var i=0; i<7; i++)
|
for (var i=0; i<7; i++)
|
||||||
|
|
|
@ -30,7 +30,7 @@ function part1(win) {
|
||||||
ok(!originalGroup.getChildren().some(function(child) child == newTabItem),"The new tab was orphaned");
|
ok(!originalGroup.getChildren().some(function(child) child == newTabItem),"The new tab was orphaned");
|
||||||
newTabItem.pushAway();
|
newTabItem.pushAway();
|
||||||
// activate this tab item
|
// activate this tab item
|
||||||
contentWindow.UI.setActiveTab(newTabItem);
|
contentWindow.UI.setActive(newTabItem);
|
||||||
|
|
||||||
// PART 2: close this orphan tab (newTab)
|
// PART 2: close this orphan tab (newTab)
|
||||||
let part2 = function part2() {
|
let part2 = function part2() {
|
||||||
|
|
|
@ -123,7 +123,7 @@ function test() {
|
||||||
let cw = getContentWindow();
|
let cw = getContentWindow();
|
||||||
let box = new cw.Rect(20, 20, 250, 200);
|
let box = new cw.Rect(20, 20, 250, 200);
|
||||||
let groupItem = new cw.GroupItem([], {bounds: box, immediately: true});
|
let groupItem = new cw.GroupItem([], {bounds: box, immediately: true});
|
||||||
cw.GroupItems.setActiveGroupItem(groupItem);
|
cw.UI.setActive(groupItem);
|
||||||
|
|
||||||
gBrowser.selectedTab = gBrowser.loadOneTab('http://mochi.test:8888/#3', {inBackground: true});
|
gBrowser.selectedTab = gBrowser.loadOneTab('http://mochi.test:8888/#3', {inBackground: true});
|
||||||
gBrowser.loadOneTab('http://mochi.test:8888/#4', {inBackground: true});
|
gBrowser.loadOneTab('http://mochi.test:8888/#4', {inBackground: true});
|
||||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче