mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 13:51:41 +00:00
Merge m-c to devtools
This commit is contained in:
commit
eb5d5ebaa0
1
.hgtags
1
.hgtags
@ -62,3 +62,4 @@ b70744835d94e54eec97b8fd186c96da5708a506 PRE_MOBILE_MERGE_20110406
|
||||
a71bd564ebf5bf4f93d13e84114f759c263130b0 MOBILE_MERGE_DONE
|
||||
a71bd564ebf5bf4f93d13e84114f759c263130b0 MOBILE_MERGE_DONE_20110406
|
||||
a95d426422816513477e5863add1b00ac7041dcb AURORA_BASE_20110412
|
||||
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R14
|
||||
|
@ -162,7 +162,7 @@ ifdef MOZ_SYMBOLS_EXTRA_BUILDID
|
||||
EXTRA_BUILDID := -$(MOZ_SYMBOLS_EXTRA_BUILDID)
|
||||
endif
|
||||
|
||||
export SYMBOL_INDEX_NAME = \
|
||||
SYMBOL_INDEX_NAME = \
|
||||
$(MOZ_APP_NAME)-$(MOZ_APP_VERSION)-$(OS_TARGET)-$(BUILDID)$(EXTRA_BUILDID)-symbols.txt
|
||||
|
||||
buildsymbols:
|
||||
@ -194,7 +194,7 @@ endif # MOZ_CRASHREPORTER
|
||||
|
||||
uploadsymbols:
|
||||
ifdef MOZ_CRASHREPORTER
|
||||
$(SHELL) $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.sh "$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip"
|
||||
$(SHELL) $(topsrcdir)/toolkit/crashreporter/tools/upload_symbols.sh $(SYMBOL_INDEX_NAME) "$(DIST)/$(PKG_PATH)$(SYMBOL_FULL_ARCHIVE_BASENAME).zip"
|
||||
endif
|
||||
|
||||
# defined in package-name.mk
|
||||
|
@ -341,9 +341,7 @@ void nsAccessibleWrap::SetMaiHyperlink(MaiHyperlink* aMaiHyperlink)
|
||||
if (!maiHyperlink && !aMaiHyperlink) {
|
||||
return; // Never set and we're shutting down
|
||||
}
|
||||
if (maiHyperlink) {
|
||||
delete maiHyperlink;
|
||||
}
|
||||
delete maiHyperlink;
|
||||
g_object_set_qdata(G_OBJECT(mAtkObject), quark_mai_hyperlink,
|
||||
aMaiHyperlink);
|
||||
}
|
||||
|
@ -199,23 +199,32 @@ private:
|
||||
printf("uri: %s", spec);
|
||||
|
||||
#define NS_LOG_ACCDOC_TYPE(aDocument) \
|
||||
PRBool isContent = nsCoreUtils::IsContentDocument(aDocument); \
|
||||
printf("%s document", (isContent ? "content" : "chrome"));
|
||||
if (aDocument->IsActive()) { \
|
||||
PRBool isContent = nsCoreUtils::IsContentDocument(aDocument); \
|
||||
printf("%s document", (isContent ? "content" : "chrome")); \
|
||||
} else { \
|
||||
printf("document type: [failed]"); \
|
||||
}
|
||||
|
||||
#define NS_LOG_ACCDOC_SHELLSTATE(aDocument) \
|
||||
nsCOMPtr<nsISupports> container = aDocument->GetContainer(); \
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container); \
|
||||
PRUint32 busyFlags = nsIDocShell::BUSY_FLAGS_NONE; \
|
||||
docShell->GetBusyFlags(&busyFlags); \
|
||||
nsCAutoString docShellBusy; \
|
||||
if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE) \
|
||||
docShellBusy.AppendLiteral("'none'"); \
|
||||
if (busyFlags & nsIDocShell::BUSY_FLAGS_BUSY) \
|
||||
docShellBusy.AppendLiteral("'busy'"); \
|
||||
if (busyFlags & nsIDocShell::BUSY_FLAGS_BEFORE_PAGE_LOAD) \
|
||||
docShellBusy.AppendLiteral(", 'before page load'"); \
|
||||
if (busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING) \
|
||||
docShellBusy.AppendLiteral(", 'page loading'"); \
|
||||
nsCOMPtr<nsISupports> container = aDocument->GetContainer(); \
|
||||
if (container) { \
|
||||
nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(container); \
|
||||
PRUint32 busyFlags = nsIDocShell::BUSY_FLAGS_NONE; \
|
||||
docShell->GetBusyFlags(&busyFlags); \
|
||||
if (busyFlags == nsIDocShell::BUSY_FLAGS_NONE) \
|
||||
docShellBusy.AppendLiteral("'none'"); \
|
||||
if (busyFlags & nsIDocShell::BUSY_FLAGS_BUSY) \
|
||||
docShellBusy.AppendLiteral("'busy'"); \
|
||||
if (busyFlags & nsIDocShell::BUSY_FLAGS_BEFORE_PAGE_LOAD) \
|
||||
docShellBusy.AppendLiteral(", 'before page load'"); \
|
||||
if (busyFlags & nsIDocShell::BUSY_FLAGS_PAGE_LOADING) \
|
||||
docShellBusy.AppendLiteral(", 'page loading'"); \
|
||||
} \
|
||||
else { \
|
||||
docShellBusy.AppendLiteral("[failed]"); \
|
||||
} \
|
||||
printf("docshell busy: %s", docShellBusy.get());
|
||||
|
||||
#define NS_LOG_ACCDOC_DOCSTATES(aDocument) \
|
||||
@ -336,20 +345,22 @@ private:
|
||||
printf(" "); \
|
||||
NS_LOG_ACCDOC_ADDRESS(aDocument, aDocAcc) \
|
||||
printf("\n "); \
|
||||
NS_LOG_ACCDOC_URI(aDocument) \
|
||||
printf("\n "); \
|
||||
NS_LOG_ACCDOC_SHELLSTATE(aDocument) \
|
||||
printf("; "); \
|
||||
NS_LOG_ACCDOC_TYPE(aDocument) \
|
||||
printf("\n "); \
|
||||
NS_LOG_ACCDOC_DOCSTATES(aDocument) \
|
||||
printf("\n "); \
|
||||
NS_LOG_ACCDOC_DOCPRESSHELL(aDocument) \
|
||||
printf("\n "); \
|
||||
NS_LOG_ACCDOC_DOCLOADGROUP(aDocument) \
|
||||
printf(", "); \
|
||||
NS_LOG_ACCDOC_DOCPARENT(aDocument) \
|
||||
printf("\n"); \
|
||||
if (aDocument) { \
|
||||
NS_LOG_ACCDOC_URI(aDocument) \
|
||||
printf("\n "); \
|
||||
NS_LOG_ACCDOC_SHELLSTATE(aDocument) \
|
||||
printf("; "); \
|
||||
NS_LOG_ACCDOC_TYPE(aDocument) \
|
||||
printf("\n "); \
|
||||
NS_LOG_ACCDOC_DOCSTATES(aDocument) \
|
||||
printf("\n "); \
|
||||
NS_LOG_ACCDOC_DOCPRESSHELL(aDocument) \
|
||||
printf("\n "); \
|
||||
NS_LOG_ACCDOC_DOCLOADGROUP(aDocument) \
|
||||
printf(", "); \
|
||||
NS_LOG_ACCDOC_DOCPARENT(aDocument) \
|
||||
printf("\n"); \
|
||||
} \
|
||||
}
|
||||
#define NS_LOG_ACCDOC_DOCINFO_END \
|
||||
printf(" }\n");
|
||||
|
@ -67,7 +67,7 @@ struct WalkState
|
||||
nsAccTreeWalker::
|
||||
nsAccTreeWalker(nsIWeakReference* aShell, nsIContent* aContent,
|
||||
PRBool aWalkAnonContent, bool aWalkCache) :
|
||||
mWeakShell(aShell), mState(nsnull), mWalkCache(aWalkCache)
|
||||
mWeakShell(aShell), mWalkCache(aWalkCache), mState(nsnull)
|
||||
{
|
||||
NS_ASSERTION(aContent, "No node for the accessible tree walker!");
|
||||
|
||||
|
@ -160,7 +160,8 @@ nsAccUtils::GetPositionAndSizeForXULSelectControlItem(nsIContent *aContent,
|
||||
control->GetItemAtIndex(index, getter_AddRefs(currItem));
|
||||
nsCOMPtr<nsINode> currNode(do_QueryInterface(currItem));
|
||||
|
||||
nsAccessible* itemAcc = GetAccService()->GetAccessible(currNode);
|
||||
nsAccessible* itemAcc = currNode ?
|
||||
GetAccService()->GetAccessible(currNode) : nsnull;
|
||||
|
||||
if (!itemAcc || itemAcc->State() & states::INVISIBLE) {
|
||||
(*aSetSize)--;
|
||||
@ -201,7 +202,8 @@ nsAccUtils::GetPositionAndSizeForXULContainerItem(nsIContent *aContent,
|
||||
container->GetItemAtIndex(index, getter_AddRefs(item));
|
||||
nsCOMPtr<nsINode> itemNode(do_QueryInterface(item));
|
||||
|
||||
nsAccessible* itemAcc = GetAccService()->GetAccessible(itemNode);
|
||||
nsAccessible* itemAcc = itemNode ?
|
||||
GetAccService()->GetAccessible(itemNode) : nsnull;
|
||||
|
||||
if (itemAcc) {
|
||||
PRUint32 itemRole = Role(itemAcc);
|
||||
@ -221,7 +223,8 @@ nsAccUtils::GetPositionAndSizeForXULContainerItem(nsIContent *aContent,
|
||||
container->GetItemAtIndex(index, getter_AddRefs(item));
|
||||
nsCOMPtr<nsINode> itemNode(do_QueryInterface(item));
|
||||
|
||||
nsAccessible* itemAcc = GetAccService()->GetAccessible(itemNode);
|
||||
nsAccessible* itemAcc =
|
||||
itemNode ? GetAccService()->GetAccessible(itemNode) : nsnull;
|
||||
|
||||
if (itemAcc) {
|
||||
PRUint32 itemRole = Role(itemAcc);
|
||||
|
@ -171,7 +171,7 @@ public:
|
||||
nsINode* node = GetNode();
|
||||
return node && node->IsElement();
|
||||
}
|
||||
PRBool IsDocument() const
|
||||
bool IsDocumentNode() const
|
||||
{
|
||||
return GetNode() && GetNode()->IsNodeOfType(nsINode::eDOCUMENT);
|
||||
}
|
||||
|
@ -68,7 +68,7 @@
|
||||
#include "nsImageFrame.h"
|
||||
#include "nsILink.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIPluginInstance.h"
|
||||
#include "nsNPAPIPluginInstance.h"
|
||||
#include "nsISupportsUtils.h"
|
||||
#include "nsObjectFrame.h"
|
||||
#include "nsOuterDocAccessible.h"
|
||||
@ -346,8 +346,8 @@ nsAccessibilityService::CreateHTMLObjectFrameAccessible(nsObjectFrame* aFrame,
|
||||
|
||||
#if defined(XP_WIN) || defined(MOZ_ACCESSIBILITY_ATK)
|
||||
// 2) for plugins
|
||||
nsCOMPtr<nsIPluginInstance> pluginInstance;
|
||||
if (NS_SUCCEEDED(aFrame->GetPluginInstance(*getter_AddRefs(pluginInstance))) &&
|
||||
nsRefPtr<nsNPAPIPluginInstance> pluginInstance;
|
||||
if (NS_SUCCEEDED(aFrame->GetPluginInstance(getter_AddRefs(pluginInstance))) &&
|
||||
pluginInstance) {
|
||||
#ifdef XP_WIN
|
||||
// Note: pluginPort will be null if windowless.
|
||||
@ -842,6 +842,8 @@ nsAccessibilityService::GetAccessibleInShell(nsINode* aNode,
|
||||
nsAccessible*
|
||||
nsAccessibilityService::GetAccessible(nsINode* aNode)
|
||||
{
|
||||
NS_PRECONDITION(aNode, "Getting an accessible for null node! Crash.");
|
||||
|
||||
nsDocAccessible* document = GetDocAccessible(aNode->GetOwnerDoc());
|
||||
return document ? document->GetAccessible(aNode) : nsnull;
|
||||
}
|
||||
|
@ -376,6 +376,9 @@ public:
|
||||
|
||||
inline bool IsApplication() const { return mFlags & eApplicationAccessible; }
|
||||
|
||||
inline bool IsDoc() const { return mFlags & eDocAccessible; }
|
||||
nsDocAccessible* AsDoc();
|
||||
|
||||
inline bool IsHyperText() const { return mFlags & eHyperTextAccessible; }
|
||||
nsHyperTextAccessible* AsHyperText();
|
||||
|
||||
@ -529,10 +532,11 @@ protected:
|
||||
*/
|
||||
enum AccessibleTypes {
|
||||
eApplicationAccessible = 1 << 2,
|
||||
eHyperTextAccessible = 1 << 3,
|
||||
eHTMLListItemAccessible = 1 << 4,
|
||||
eRootAccessible = 1 << 5,
|
||||
eTextLeafAccessible = 1 << 6
|
||||
eDocAccessible = 1 << 3,
|
||||
eHyperTextAccessible = 1 << 4,
|
||||
eHTMLListItemAccessible = 1 << 5,
|
||||
eRootAccessible = 1 << 6,
|
||||
eTextLeafAccessible = 1 << 7
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -93,7 +93,7 @@ nsLeafAccessible::CacheChildren()
|
||||
nsLinkableAccessible::
|
||||
nsLinkableAccessible(nsIContent *aContent, nsIWeakReference *aShell) :
|
||||
nsAccessibleWrap(aContent, aShell),
|
||||
mActionContent(nsnull),
|
||||
mActionAcc(nsnull),
|
||||
mIsLink(PR_FALSE),
|
||||
mIsOnclick(PR_FALSE)
|
||||
{
|
||||
@ -107,11 +107,7 @@ NS_IMPL_ISUPPORTS_INHERITED0(nsLinkableAccessible, nsAccessibleWrap)
|
||||
NS_IMETHODIMP
|
||||
nsLinkableAccessible::TakeFocus()
|
||||
{
|
||||
nsAccessible *actionAcc = GetActionAccessible();
|
||||
if (actionAcc)
|
||||
return actionAcc->TakeFocus();
|
||||
|
||||
return nsAccessibleWrap::TakeFocus();
|
||||
return mActionAcc ? mActionAcc->TakeFocus() : nsAccessibleWrap::TakeFocus();
|
||||
}
|
||||
|
||||
PRUint64
|
||||
@ -120,8 +116,7 @@ nsLinkableAccessible::NativeState()
|
||||
PRUint64 states = nsAccessibleWrap::NativeState();
|
||||
if (mIsLink) {
|
||||
states |= states::LINKED;
|
||||
nsAccessible* actionAcc = GetActionAccessible();
|
||||
if (actionAcc->State() & states::TRAVERSED)
|
||||
if (mActionAcc->State() & states::TRAVERSED)
|
||||
states |= states::TRAVERSED;
|
||||
}
|
||||
|
||||
@ -137,13 +132,7 @@ nsLinkableAccessible::GetValue(nsAString& aValue)
|
||||
if (!aValue.IsEmpty())
|
||||
return NS_OK;
|
||||
|
||||
if (mIsLink) {
|
||||
nsAccessible *actionAcc = GetActionAccessible();
|
||||
if (actionAcc)
|
||||
return actionAcc->GetValue(aValue);
|
||||
}
|
||||
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
return mIsLink ? mActionAcc->GetValue(aValue) : NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
|
||||
@ -152,7 +141,7 @@ nsLinkableAccessible::GetNumActions(PRUint8 *aNumActions)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aNumActions);
|
||||
|
||||
*aNumActions = mActionContent ? 1 : 0;
|
||||
*aNumActions = mActionAcc ? 1 : 0;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -182,11 +171,8 @@ nsLinkableAccessible::DoAction(PRUint8 aIndex)
|
||||
if (aIndex != eAction_Jump)
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
nsAccessible *actionAcc = GetActionAccessible();
|
||||
if (actionAcc)
|
||||
return actionAcc->DoAction(aIndex);
|
||||
|
||||
return nsAccessibleWrap::DoAction(aIndex);
|
||||
return mActionAcc ? mActionAcc->DoAction(aIndex) :
|
||||
nsAccessibleWrap::DoAction(aIndex);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
@ -194,11 +180,8 @@ nsLinkableAccessible::GetKeyboardShortcut(nsAString& aKeyboardShortcut)
|
||||
{
|
||||
aKeyboardShortcut.Truncate();
|
||||
|
||||
nsAccessible *actionAcc = GetActionAccessible();
|
||||
if (actionAcc)
|
||||
return actionAcc->GetKeyboardShortcut(aKeyboardShortcut);
|
||||
|
||||
return nsAccessible::GetKeyboardShortcut(aKeyboardShortcut);
|
||||
return mActionAcc ? mActionAcc->GetKeyboardShortcut(aKeyboardShortcut) :
|
||||
nsAccessible::GetKeyboardShortcut(aKeyboardShortcut);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
@ -207,7 +190,9 @@ nsLinkableAccessible::GetKeyboardShortcut(nsAString& aKeyboardShortcut)
|
||||
void
|
||||
nsLinkableAccessible::Shutdown()
|
||||
{
|
||||
mActionContent = nsnull;
|
||||
mIsLink = PR_FALSE;
|
||||
mIsOnclick = PR_FALSE;
|
||||
mActionAcc = nsnull;
|
||||
nsAccessibleWrap::Shutdown();
|
||||
}
|
||||
|
||||
@ -218,14 +203,11 @@ already_AddRefed<nsIURI>
|
||||
nsLinkableAccessible::GetAnchorURI(PRUint32 aAnchorIndex)
|
||||
{
|
||||
if (mIsLink) {
|
||||
nsAccessible* link = GetActionAccessible();
|
||||
if (link) {
|
||||
NS_ASSERTION(link->IsHyperLink(),
|
||||
"nsIAccessibleHyperLink isn't implemented.");
|
||||
NS_ASSERTION(mActionAcc->IsHyperLink(),
|
||||
"nsIAccessibleHyperLink isn't implemented.");
|
||||
|
||||
if (link->IsHyperLink())
|
||||
return link->GetAnchorURI(aAnchorIndex);
|
||||
}
|
||||
if (mActionAcc->IsHyperLink())
|
||||
return mActionAcc->GetAnchorURI(aAnchorIndex);
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
@ -241,55 +223,36 @@ nsLinkableAccessible::BindToParent(nsAccessible* aParent,
|
||||
nsAccessibleWrap::BindToParent(aParent, aIndexInParent);
|
||||
|
||||
// Cache action content.
|
||||
mActionContent = nsnull;
|
||||
mActionAcc = nsnull;
|
||||
mIsLink = PR_FALSE;
|
||||
mIsOnclick = PR_FALSE;
|
||||
|
||||
nsIContent* walkUpContent = mContent;
|
||||
PRBool isOnclick = nsCoreUtils::HasClickListener(walkUpContent);
|
||||
|
||||
if (isOnclick) {
|
||||
mActionContent = walkUpContent;
|
||||
if (nsCoreUtils::HasClickListener(mContent)) {
|
||||
mActionAcc = this;
|
||||
mIsOnclick = PR_TRUE;
|
||||
return;
|
||||
}
|
||||
|
||||
while ((walkUpContent = walkUpContent->GetParent())) {
|
||||
nsAccessible* walkUpAcc =
|
||||
GetAccService()->GetAccessibleInWeakShell(walkUpContent, mWeakShell);
|
||||
|
||||
// XXX: The logic looks broken since the click listener may be registered
|
||||
// on non accessible node in parent chain but this node is skipped when tree
|
||||
// is traversed.
|
||||
nsAccessible* walkUpAcc = this;
|
||||
while ((walkUpAcc = walkUpAcc->GetParent()) && !walkUpAcc->IsDoc()) {
|
||||
if (walkUpAcc && walkUpAcc->Role() == nsIAccessibleRole::ROLE_LINK &&
|
||||
walkUpAcc->State() & states::LINKED) {
|
||||
mIsLink = PR_TRUE;
|
||||
mActionContent = walkUpContent;
|
||||
mActionAcc = walkUpAcc;
|
||||
return;
|
||||
}
|
||||
|
||||
isOnclick = nsCoreUtils::HasClickListener(walkUpContent);
|
||||
if (isOnclick) {
|
||||
mActionContent = walkUpContent;
|
||||
if (nsCoreUtils::HasClickListener(walkUpAcc->GetContent())) {
|
||||
mActionAcc = walkUpAcc;
|
||||
mIsOnclick = PR_TRUE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsLinkableAccessible: protected
|
||||
|
||||
nsAccessible *
|
||||
nsLinkableAccessible::GetActionAccessible() const
|
||||
{
|
||||
// Return accessible for the action content if it's different from node of
|
||||
// this accessible. If the action accessible is not null then it is used to
|
||||
// redirect methods calls otherwise we use method implementation from the
|
||||
// base class.
|
||||
if (!mActionContent || mContent == mActionContent)
|
||||
return nsnull;
|
||||
|
||||
return GetAccService()->GetAccessibleInWeakShell(mActionContent, mWeakShell);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// nsEnumRoleAccessible
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -108,14 +108,10 @@ protected:
|
||||
// nsAccessible
|
||||
virtual void BindToParent(nsAccessible* aParent, PRUint32 aIndexInParent);
|
||||
|
||||
// nsLinkableAccessible
|
||||
|
||||
/**
|
||||
* Return an accessible for cached action node.
|
||||
* Parent accessible that provides an action for this linkable accessible.
|
||||
*/
|
||||
nsAccessible *GetActionAccessible() const;
|
||||
|
||||
nsCOMPtr<nsIContent> mActionContent;
|
||||
nsAccessible* mActionAcc;
|
||||
PRPackedBool mIsLink;
|
||||
PRPackedBool mIsOnclick;
|
||||
};
|
||||
|
@ -493,12 +493,10 @@ nsCoreUtils::IsErrorPage(nsIDocument *aDocument)
|
||||
nsCAutoString path;
|
||||
uri->GetPath(path);
|
||||
|
||||
nsCAutoString::const_iterator start, end;
|
||||
path.BeginReading(start);
|
||||
path.EndReading(end);
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(neterror, "neterror");
|
||||
return FindInReadable(neterror, start, end);
|
||||
NS_NAMED_LITERAL_CSTRING(certerror, "certerror");
|
||||
|
||||
return StringBeginsWith(path, neterror) || StringBeginsWith(path, certerror);
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
@ -109,6 +109,8 @@ nsDocAccessible::
|
||||
mDocument(aDocument), mScrollPositionChangedTicks(0), mIsLoaded(PR_FALSE),
|
||||
mCacheRoot(nsnull), mIsPostCacheProcessing(PR_FALSE)
|
||||
{
|
||||
mFlags |= eDocAccessible;
|
||||
|
||||
mDependentIDsHash.Init();
|
||||
// XXX aaronl should we use an algorithm for the initial cache size?
|
||||
mAccessibleCache.Init(kDefaultCacheSize);
|
||||
@ -1114,7 +1116,8 @@ nsDocAccessible::ARIAAttributeChanged(nsIContent* aContent, nsIAtom* aAttribute)
|
||||
// at least until native API comes up with a more meaningful event.
|
||||
if (aAttribute == nsAccessibilityAtoms::aria_grabbed ||
|
||||
aAttribute == nsAccessibilityAtoms::aria_dropeffect ||
|
||||
aAttribute == nsAccessibilityAtoms::aria_hidden) {
|
||||
aAttribute == nsAccessibilityAtoms::aria_hidden ||
|
||||
aAttribute == nsAccessibilityAtoms::aria_sort) {
|
||||
FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_OBJECT_ATTRIBUTE_CHANGED,
|
||||
aContent);
|
||||
}
|
||||
|
@ -552,4 +552,11 @@ protected:
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsDocAccessible,
|
||||
NS_DOCACCESSIBLE_IMPL_CID)
|
||||
|
||||
inline nsDocAccessible*
|
||||
nsAccessible::AsDoc()
|
||||
{
|
||||
return mFlags & eDocAccessible ?
|
||||
static_cast<nsDocAccessible*>(this) : nsnull;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -213,8 +213,8 @@ nsOuterDocAccessible::RemoveChild(nsAccessible *aAccessible)
|
||||
return PR_FALSE;
|
||||
}
|
||||
|
||||
NS_LOG_ACCDOCDESTROY("remove document from outerdoc",
|
||||
child->GetDocumentNode())
|
||||
NS_LOG_ACCDOCDESTROY_FOR("remove document from outerdoc",
|
||||
child->GetDocumentNode(), child)
|
||||
NS_LOG_ACCDOCDESTROY_ACCADDRESS("outerdoc", this)
|
||||
|
||||
PRBool wasRemoved = nsAccessible::RemoveChild(child);
|
||||
|
@ -297,7 +297,7 @@ nsTextEquivUtils::AppendFromValue(nsAccessible *aAccessible,
|
||||
}
|
||||
|
||||
//XXX: is it necessary to care the accessible is not a document?
|
||||
if (aAccessible->IsDocument())
|
||||
if (aAccessible->IsDocumentNode())
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
nsIContent *content = aAccessible->GetContent();
|
||||
|
@ -916,7 +916,7 @@ nsresult nsHyperTextAccessible::GetTextHelper(EGetTextType aType, nsAccessibleTe
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISelectionPrivate> privateSelection(do_QueryInterface(domSel));
|
||||
nsCOMPtr<nsFrameSelection> frameSelection;
|
||||
nsRefPtr<nsFrameSelection> frameSelection;
|
||||
rv = privateSelection->GetFrameSelection(getter_AddRefs(frameSelection));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
@ -1014,7 +1014,7 @@ nsresult nsHyperTextAccessible::GetTextHelper(EGetTextType aType, nsAccessibleTe
|
||||
}
|
||||
|
||||
if (aType == eGetBefore) {
|
||||
endOffset = aOffset;
|
||||
finalEndOffset = aOffset;
|
||||
}
|
||||
else {
|
||||
// Start moving forward from the start so that we don't get
|
||||
@ -1680,7 +1680,7 @@ PRInt32 nsHyperTextAccessible::GetCaretLineNumber()
|
||||
getter_AddRefs(domSel));
|
||||
nsCOMPtr<nsISelectionPrivate> privateSelection(do_QueryInterface(domSel));
|
||||
NS_ENSURE_TRUE(privateSelection, -1);
|
||||
nsCOMPtr<nsFrameSelection> frameSelection;
|
||||
nsRefPtr<nsFrameSelection> frameSelection;
|
||||
privateSelection->GetFrameSelection(getter_AddRefs(frameSelection));
|
||||
NS_ENSURE_TRUE(frameSelection, -1);
|
||||
|
||||
|
@ -238,7 +238,7 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
||||
if ([attribute isEqualToString:NSAccessibilityRoleDescriptionAttribute])
|
||||
return NSAccessibilityRoleDescription([self role], nil);
|
||||
#endif
|
||||
if ([attribute isEqualToString:kInstanceDescriptionAttribute])
|
||||
if ([attribute isEqualToString: (NSString*) kInstanceDescriptionAttribute])
|
||||
return [self customDescription];
|
||||
if ([attribute isEqualToString:NSAccessibilityFocusedAttribute])
|
||||
return [NSNumber numberWithBool:[self isFocused]];
|
||||
@ -246,7 +246,7 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
||||
return [self size];
|
||||
if ([attribute isEqualToString:NSAccessibilityWindowAttribute])
|
||||
return [self window];
|
||||
if ([attribute isEqualToString:kTopLevelUIElementAttribute])
|
||||
if ([attribute isEqualToString: (NSString*) kTopLevelUIElementAttribute])
|
||||
return [self window];
|
||||
if ([attribute isEqualToString:NSAccessibilityTitleAttribute] ||
|
||||
[attribute isEqualToString:NSAccessibilityTitleUIElementAttribute])
|
||||
@ -471,7 +471,7 @@ GetNativeFromGeckoAccessible(nsIAccessible *anAccessible)
|
||||
NS_ASSERTION(nsAccUtils::IsTextInterfaceSupportCorrect(mGeckoAccessible),
|
||||
"Does not support nsIAccessibleText when it should");
|
||||
#endif
|
||||
return AXRoles[mRole];
|
||||
return (NSString*) AXRoles[mRole];
|
||||
}
|
||||
|
||||
- (NSString*)subrole
|
||||
|
@ -43,6 +43,8 @@
|
||||
#ifndef _nsAccessibleWrap_H_
|
||||
#define _nsAccessibleWrap_H_
|
||||
|
||||
#include <objc/objc.h>
|
||||
|
||||
#include "nsAccessible.h"
|
||||
#include "nsAccUtils.h"
|
||||
#include "States.h"
|
||||
@ -54,7 +56,6 @@
|
||||
#include "nsAutoPtr.h"
|
||||
|
||||
struct AccessibleWrapper;
|
||||
struct objc_class;
|
||||
|
||||
class nsAccessibleWrap : public nsAccessible
|
||||
{
|
||||
@ -71,7 +72,7 @@ class nsAccessibleWrap : public nsAccessible
|
||||
// the objective-c |Class| type that this accessible's native object
|
||||
// should be instantied with. used on runtime to determine the
|
||||
// right type for this accessible's associated native object.
|
||||
virtual objc_class* GetNativeType ();
|
||||
virtual Class GetNativeType ();
|
||||
|
||||
virtual void Shutdown ();
|
||||
virtual void InvalidateChildren();
|
||||
|
@ -88,7 +88,7 @@ nsAccessibleWrap::GetNativeInterface (void **aOutInterface)
|
||||
|
||||
// overridden in subclasses to create the right kind of object. by default we create a generic
|
||||
// 'mozAccessible' node.
|
||||
objc_class*
|
||||
Class
|
||||
nsAccessibleWrap::GetNativeType ()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
nsIWeakReference *aShell);
|
||||
virtual ~nsRootAccessibleWrap();
|
||||
|
||||
objc_class* GetNativeType ();
|
||||
Class GetNativeType ();
|
||||
|
||||
// let's our native accessible get in touch with the
|
||||
// native cocoa view that is our accessible parent.
|
||||
|
@ -59,7 +59,7 @@ nsRootAccessibleWrap::~nsRootAccessibleWrap()
|
||||
{
|
||||
}
|
||||
|
||||
objc_class*
|
||||
Class
|
||||
nsRootAccessibleWrap::GetNativeType ()
|
||||
{
|
||||
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL;
|
||||
|
@ -275,7 +275,7 @@ STDMETHODIMP nsAccessNodeWrap::get_attributes(
|
||||
__try{
|
||||
*aNumAttribs = 0;
|
||||
|
||||
if (IsDefunct() || IsDocument())
|
||||
if (IsDefunct() || IsDocumentNode())
|
||||
return E_FAIL;
|
||||
|
||||
PRUint32 numAttribs = mContent->GetAttrCount();
|
||||
@ -348,7 +348,7 @@ STDMETHODIMP nsAccessNodeWrap::get_computedStyle(
|
||||
__try{
|
||||
*aNumStyleProperties = 0;
|
||||
|
||||
if (IsDefunct() || IsDocument())
|
||||
if (IsDefunct() || IsDocumentNode())
|
||||
return E_FAIL;
|
||||
|
||||
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl =
|
||||
@ -383,7 +383,7 @@ STDMETHODIMP nsAccessNodeWrap::get_computedStyleForProperties(
|
||||
/* [length_is][size_is][out] */ BSTR __RPC_FAR *aStyleValues)
|
||||
{
|
||||
__try {
|
||||
if (IsDefunct() || IsDocument())
|
||||
if (IsDefunct() || IsDocumentNode())
|
||||
return E_FAIL;
|
||||
|
||||
nsCOMPtr<nsIDOMCSSStyleDeclaration> cssDecl =
|
||||
|
@ -1762,6 +1762,38 @@ nsAccessibleWrap::GetXPAccessibleFor(const VARIANT& aVarChild)
|
||||
if (nsAccUtils::MustPrune(this))
|
||||
return nsnull;
|
||||
|
||||
// If lVal negative then it is treated as child ID and we should look for
|
||||
// accessible through whole accessible subtree including subdocuments.
|
||||
// Otherwise we treat lVal as index in parent.
|
||||
|
||||
if (aVarChild.lVal < 0) {
|
||||
// Convert child ID to unique ID.
|
||||
void* uniqueID = reinterpret_cast<void*>(-aVarChild.lVal);
|
||||
|
||||
// Document.
|
||||
if (IsDoc())
|
||||
return AsDoc()->GetAccessibleByUniqueIDInSubtree(uniqueID);
|
||||
|
||||
// ARIA document.
|
||||
if (ARIARole() == nsIAccessibleRole::ROLE_DOCUMENT) {
|
||||
nsDocAccessible* document = GetDocAccessible();
|
||||
nsAccessible* child =
|
||||
document->GetAccessibleByUniqueIDInSubtree(uniqueID);
|
||||
|
||||
// Check whether the accessible for the given ID is a child of ARIA
|
||||
// document.
|
||||
nsAccessible* parent = child ? child->GetParent() : nsnull;
|
||||
while (parent && parent != document) {
|
||||
if (parent == this)
|
||||
return child;
|
||||
|
||||
parent = parent->GetParent();
|
||||
}
|
||||
}
|
||||
|
||||
return nsnull;
|
||||
}
|
||||
|
||||
// Gecko child indices are 0-based in contrast to indices used in MSAA.
|
||||
return GetChildAt(aVarChild.lVal - 1);
|
||||
}
|
||||
|
@ -327,7 +327,7 @@ public: // construction, destruction
|
||||
/**
|
||||
* Find an accessible by the given child ID in cached documents.
|
||||
*/
|
||||
virtual nsAccessible *GetXPAccessibleFor(const VARIANT& aVarChild);
|
||||
nsAccessible* GetXPAccessibleFor(const VARIANT& aVarChild);
|
||||
|
||||
NS_IMETHOD GetNativeInterface(void **aOutAccessible);
|
||||
|
||||
|
@ -99,22 +99,6 @@ STDMETHODIMP nsDocAccessibleWrap::QueryInterface(REFIID iid, void** ppv)
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
nsAccessible*
|
||||
nsDocAccessibleWrap::GetXPAccessibleFor(const VARIANT& aVarChild)
|
||||
{
|
||||
// If lVal negative then it is treated as child ID and we should look for
|
||||
// accessible through whole accessible subtree including subdocuments.
|
||||
// Otherwise we treat lVal as index in parent.
|
||||
|
||||
if (aVarChild.vt == VT_I4 && aVarChild.lVal < 0) {
|
||||
// Convert child ID to unique ID.
|
||||
void* uniqueID = reinterpret_cast<void*>(-aVarChild.lVal);
|
||||
return GetAccessibleByUniqueIDInSubtree(uniqueID);
|
||||
}
|
||||
|
||||
return nsAccessibleWrap::GetXPAccessibleFor(aVarChild);
|
||||
}
|
||||
|
||||
STDMETHODIMP nsDocAccessibleWrap::get_URL(/* [out] */ BSTR __RPC_FAR *aURL)
|
||||
{
|
||||
__try {
|
||||
|
@ -92,9 +92,6 @@ public:
|
||||
// nsAccessNode
|
||||
virtual void Shutdown();
|
||||
|
||||
// nsAccessibleWrap
|
||||
virtual nsAccessible *GetXPAccessibleFor(const VARIANT& varChild);
|
||||
|
||||
// nsDocAccessible
|
||||
virtual void* GetNativeWindow() const;
|
||||
|
||||
|
@ -51,8 +51,8 @@ _TEST_FILES =\
|
||||
focus.html \
|
||||
scroll.html \
|
||||
test_aria_alert.html \
|
||||
test_aria_hidden.html \
|
||||
test_aria_menu.html \
|
||||
test_aria_objattr.html \
|
||||
test_aria_statechange.html \
|
||||
test_attrs.html \
|
||||
test_caretmove.html \
|
||||
|
@ -192,11 +192,11 @@
|
||||
/**
|
||||
* Load wrong URI what results in error page loading.
|
||||
*/
|
||||
function loadErrorPageInvoker()
|
||||
function loadErrorPageInvoker(aURL, aURLDescr)
|
||||
{
|
||||
this.invoke = function loadErrorPageInvoker_invoke()
|
||||
{
|
||||
gTabBrowser.loadURI("www.wronguri.wronguri");
|
||||
gTabBrowser.loadURI(aURL);
|
||||
}
|
||||
|
||||
this.eventSeq = [
|
||||
@ -209,7 +209,7 @@
|
||||
|
||||
this.getID = function loadErrorPageInvoker_getID()
|
||||
{
|
||||
return "load error page";
|
||||
return "load error page: '" + aURLDescr + "'";
|
||||
}
|
||||
}
|
||||
|
||||
@ -230,7 +230,11 @@
|
||||
gQueue.push(new clickReloadBtnInvoker());
|
||||
gQueue.push(new loadURIInvoker("about:mozilla"));
|
||||
gQueue.push(new reloadInvoker());
|
||||
gQueue.push(new loadErrorPageInvoker());
|
||||
gQueue.push(new loadErrorPageInvoker("www.wronguri.wronguri",
|
||||
"Server not found"));
|
||||
gQueue.push(new loadErrorPageInvoker("https://nocert.example.com:443",
|
||||
"Untrusted Connection"));
|
||||
|
||||
gQueue.onFinish = function() { window.close(); }
|
||||
gQueue.invoke();
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<title>Accessible ARIA hidden attribute</title>
|
||||
<title>Accessible ARIA object attribute changes</title>
|
||||
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
|
||||
@ -43,14 +43,38 @@
|
||||
}
|
||||
}
|
||||
|
||||
function updateSort(aID, aSort)
|
||||
{
|
||||
this.node = getNode(aID);
|
||||
this.accessible = getAccessible(this.node);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_OBJECT_ATTRIBUTE_CHANGED, this.accessible),
|
||||
];
|
||||
|
||||
this.invoke = function updateSort_invoke()
|
||||
{
|
||||
this.node.setAttribute("aria-sort", aSort);
|
||||
}
|
||||
|
||||
this.getID = function updateSort_getID()
|
||||
{
|
||||
return "aria-sort for " + aID + " " + aSort;
|
||||
}
|
||||
}
|
||||
|
||||
// Debug stuff.
|
||||
// gA11yEventDumpID = "eventdump";
|
||||
// gA11yEventDumpToConsole = true;
|
||||
|
||||
function doTests()
|
||||
{
|
||||
//gA11yEventDumpID = "eventdump"; // debug stuff
|
||||
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new hideNode("hideable", "true"));
|
||||
|
||||
gQueue.push(new updateSort("sortable", "ascending"));
|
||||
|
||||
gQueue.invoke(); // Will call SimpleTest.finish();
|
||||
}
|
||||
|
||||
@ -67,6 +91,12 @@
|
||||
Mozilla Bug 581096
|
||||
</a>
|
||||
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=640707"
|
||||
title="Add event support for aria-sort">
|
||||
Mozilla Bug 640707
|
||||
</a>
|
||||
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none"></div>
|
||||
<pre id="test">
|
||||
@ -75,5 +105,6 @@
|
||||
|
||||
<div id="hideable"><div>Hi</div><div>there</div></div>
|
||||
|
||||
<div id="sortable" role="columnheader" aria-sort"none">aria-sort</div>
|
||||
</body>
|
||||
</html>
|
@ -50,8 +50,8 @@ _TEST_FILES = \
|
||||
test_doc.html \
|
||||
test_hypertext.html \
|
||||
test_passwords.html \
|
||||
$(warning test_singleline.html disabled due to bug 652459) \
|
||||
$(warning test_whitespaces.html disabled due to bug 652459) \
|
||||
test_singleline.html \
|
||||
test_whitespaces.html \
|
||||
test_words.html \
|
||||
$(NULL)
|
||||
|
||||
|
@ -216,10 +216,10 @@
|
||||
|
||||
// BOUNDARY_WORD_START
|
||||
testTextBeforeOffset(0, BOUNDARY_WORD_START, "", 0, 0,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
"editable", kTodo, kOk, kTodo,
|
||||
"textarea", kTodo, kOk, kTodo);
|
||||
"input", kOk, kOk, kOk,
|
||||
"div", kOk, kOk, kOk,
|
||||
"editable", kOk, kOk, kOk,
|
||||
"textarea", kOk, kOk, kOk);
|
||||
testTextBeforeOffset(1, BOUNDARY_WORD_START, "", 0, 0,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
@ -231,10 +231,10 @@
|
||||
"editable", kTodo, kOk, kTodo,
|
||||
"textarea", kTodo, kOk, kTodo);
|
||||
testTextBeforeOffset(6, BOUNDARY_WORD_START, "hello ", 0, 6,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
"editable", kTodo, kOk, kTodo,
|
||||
"textarea", kTodo, kOk, kTodo);
|
||||
"input", kOk, kOk, kOk,
|
||||
"div", kOk, kOk, kOk,
|
||||
"editable", kOk, kOk, kOk,
|
||||
"textarea", kOk, kOk, kOk);
|
||||
testTextBeforeOffset(7, BOUNDARY_WORD_START, "hello ", 0, 6,
|
||||
"input", kTodo, kTodo, kTodo,
|
||||
"div", kTodo, kTodo, kTodo,
|
||||
@ -246,10 +246,10 @@
|
||||
"editable", kTodo, kTodo, kTodo,
|
||||
"textarea", kTodo, kTodo, kTodo);
|
||||
testTextBeforeOffset(9, BOUNDARY_WORD_START, "my ", 6, 9,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
"editable", kTodo, kOk, kTodo,
|
||||
"textarea", kTodo, kOk, kTodo);
|
||||
"input", kOk, kOk, kOk,
|
||||
"div", kOk, kOk, kOk,
|
||||
"editable", kOk, kOk, kOk,
|
||||
"textarea", kOk, kOk, kOk);
|
||||
testTextBeforeOffset(10, BOUNDARY_WORD_START, "my ", 6, 9,
|
||||
"input", kTodo, kTodo, kTodo,
|
||||
"div", kTodo, kTodo, kTodo,
|
||||
@ -268,10 +268,10 @@
|
||||
|
||||
// BOUNDARY_WORD_END
|
||||
testTextBeforeOffset(0, BOUNDARY_WORD_END, "", 0, 0,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
"editable", kTodo, kOk, kTodo,
|
||||
"textarea", kTodo, kOk, kTodo);
|
||||
"input", kOk, kOk, kOk,
|
||||
"div", kOk, kOk, kOk,
|
||||
"editable", kOk, kOk, kOk,
|
||||
"textarea", kOk, kOk, kOk);
|
||||
testTextBeforeOffset(1, BOUNDARY_WORD_END, "", 0, 0,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
@ -283,10 +283,10 @@
|
||||
"editable", kTodo, kOk, kTodo,
|
||||
"textarea", kTodo, kOk, kTodo);
|
||||
testTextBeforeOffset(6, BOUNDARY_WORD_END, "hello ", 0, 6,
|
||||
"input", kTodo, kTodo, kTodo,
|
||||
"div", kTodo, kTodo, kTodo,
|
||||
"editable", kTodo, kTodo, kTodo,
|
||||
"textarea", kTodo, kTodo, kTodo);
|
||||
"input", kTodo, kTodo, kOk,
|
||||
"div", kTodo, kTodo, kOk,
|
||||
"editable", kTodo, kTodo, kOk,
|
||||
"textarea", kTodo, kTodo, kOk);
|
||||
testTextBeforeOffset(7, BOUNDARY_WORD_END, "hello ", 0, 6,
|
||||
"input", kTodo, kTodo, kTodo,
|
||||
"div", kTodo, kTodo, kTodo,
|
||||
@ -320,10 +320,10 @@
|
||||
|
||||
// BOUNDARY_LINE_START
|
||||
testTextBeforeOffset(0, BOUNDARY_LINE_START, "", 0, 0,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
"editable", kTodo, kOk, kTodo,
|
||||
"textarea", kTodo, kOk, kTodo);
|
||||
"input", kOk, kOk, kOk,
|
||||
"div", kOk, kOk, kOk,
|
||||
"editable", kOk, kOk, kOk,
|
||||
"textarea", kOk, kOk, kOk);
|
||||
testTextBeforeOffset(1, BOUNDARY_LINE_START, "", 0, 0,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
@ -342,10 +342,10 @@
|
||||
|
||||
// BOUNDARY_LINE_END
|
||||
testTextBeforeOffset(0, BOUNDARY_LINE_END, "", 0, 0,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
"editable", kTodo, kOk, kTodo,
|
||||
"textarea", kTodo, kOk, kTodo);
|
||||
"input", kOk, kOk, kOk,
|
||||
"div", kOk, kOk, kOk,
|
||||
"editable", kOk, kOk, kOk,
|
||||
"textarea", kOk, kOk, kOk);
|
||||
testTextBeforeOffset(1, BOUNDARY_LINE_END, "", 0, 0,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
|
@ -196,10 +196,10 @@
|
||||
|
||||
// BOUNDARY_WORD_START
|
||||
testTextBeforeOffset(0, BOUNDARY_WORD_START, "", 0, 0,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
"editable", kTodo, kOk, kTodo,
|
||||
"textarea", kTodo, kOk, kTodo);
|
||||
"input", kOk, kOk, kOk,
|
||||
"div", kOk, kOk, kOk,
|
||||
"editable", kOk, kOk, kOk,
|
||||
"textarea", kOk, kOk, kOk);
|
||||
testTextBeforeOffset(1, BOUNDARY_WORD_START, "", 0, 0,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
@ -211,10 +211,10 @@
|
||||
"editable", kTodo, kOk, kTodo,
|
||||
"textarea", kTodo, kOk, kTodo);
|
||||
testTextBeforeOffset(6, BOUNDARY_WORD_START, "Brave ", 0, 6,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
"editable", kTodo, kOk, kTodo,
|
||||
"textarea", kTodo, kOk, kTodo);
|
||||
"input", kOk, kOk, kOk,
|
||||
"div", kOk, kOk, kOk,
|
||||
"editable", kOk, kOk, kOk,
|
||||
"textarea", kOk, kOk, kOk);
|
||||
testTextBeforeOffset(9, BOUNDARY_WORD_START, "Brave ", 0, 6,
|
||||
"input", kTodo, kTodo, kTodo,
|
||||
"div", kTodo, kTodo, kTodo,
|
||||
@ -226,10 +226,10 @@
|
||||
"editable", kTodo, kTodo, kTodo,
|
||||
"textarea", kTodo, kTodo, kTodo);
|
||||
testTextBeforeOffset(11, BOUNDARY_WORD_START, "Sir ", 6, 11,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
"editable", kTodo, kOk, kTodo,
|
||||
"textarea", kTodo, kOk, kTodo);
|
||||
"input", kOk, kOk, kOk,
|
||||
"div", kOk, kOk, kOk,
|
||||
"editable", kOk, kOk, kOk,
|
||||
"textarea", kOk, kOk, kOk);
|
||||
testTextBeforeOffset(15, BOUNDARY_WORD_START, "Sir ", 6, 11,
|
||||
"input", kTodo, kTodo, kTodo,
|
||||
"div", kTodo, kTodo, kTodo,
|
||||
@ -251,10 +251,10 @@
|
||||
"editable", kTodo, kTodo, kTodo,
|
||||
"textarea", kTodo, kTodo, kTodo);
|
||||
testTextBeforeOffset(19, BOUNDARY_WORD_START, "Robin ", 11, 19,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
"editable", kTodo, kOk, kTodo,
|
||||
"textarea", kTodo, kOk, kTodo);
|
||||
"input", kOk, kOk, kOk,
|
||||
"div", kOk, kOk, kOk,
|
||||
"editable", kOk, kOk, kOk,
|
||||
"textarea", kOk, kOk, kOk);
|
||||
testTextBeforeOffset(20, BOUNDARY_WORD_START, "Robin ", 11, 19,
|
||||
"input", kTodo, kTodo, kTodo,
|
||||
"div", kTodo, kTodo, kTodo,
|
||||
@ -268,10 +268,10 @@
|
||||
|
||||
// BOUNDARY_WORD_END
|
||||
testTextBeforeOffset(0, BOUNDARY_WORD_END, "", 0, 0,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
"editable", kTodo, kOk, kTodo,
|
||||
"textarea", kTodo, kOk, kTodo);
|
||||
"input", kOk, kOk, kOk,
|
||||
"div", kOk, kOk, kOk,
|
||||
"editable", kOk, kOk, kOk,
|
||||
"textarea", kOk, kOk, kOk);
|
||||
testTextBeforeOffset(1, BOUNDARY_WORD_END, "", 0, 0,
|
||||
"input", kTodo, kOk, kTodo,
|
||||
"div", kTodo, kOk, kTodo,
|
||||
|
@ -185,8 +185,7 @@ endif
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,comctl32 comdlg32 uuid shell32 ole32 oleaut32 version winspool)
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,usp10 msimg32 delayimp)
|
||||
LDFLAGS += -delayload:xul.dll -delayload:xpcom.dll -delayload:plc4.dll -delayload:nspr4.dll -delayload:mozalloc.dll
|
||||
OS_LIBS += $(call EXPAND_LIBNAME,usp10 msimg32)
|
||||
endif
|
||||
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
|
@ -56,7 +56,6 @@
|
||||
#ifdef XP_WIN
|
||||
// we want to use the DLL blocklist if possible
|
||||
#define XRE_WANT_DLL_BLOCKLIST
|
||||
#define XRE_PRELOAD_XUL
|
||||
// we want a wmain entry point
|
||||
#include "nsWindowsWMain.cpp"
|
||||
#endif
|
||||
|
@ -254,18 +254,15 @@ let TestPilotSetup = {
|
||||
Ci.nsITimer.TYPE_REPEATING_SLACK);
|
||||
|
||||
this.getVersion(function() {
|
||||
// Show first run page (in front window) if newly installed or upgraded.
|
||||
let currVersion = self._prefs.getValue(VERSION_PREF, "firstrun");
|
||||
|
||||
if (currVersion != self.version) {
|
||||
if(!self._isBetaChannel()) {
|
||||
// Don't show first run page in ffx4 beta version.
|
||||
/* Show first run page (in front window) only the first time after install;
|
||||
* Don't show first run page in Feedback UI version. */
|
||||
if ((self._prefs.getValue(VERSION_PREF, "") == "") &&
|
||||
(!self._interfaceBuilder.channelUsesFeedback())) {
|
||||
self._prefs.setValue(VERSION_PREF, self.version);
|
||||
let browser = self._getFrontBrowserWindow().getBrowser();
|
||||
let url = self._prefs.getValue(FIRST_RUN_PREF, "");
|
||||
let tab = browser.addTab(url);
|
||||
browser.selectedTab = tab;
|
||||
}
|
||||
}
|
||||
|
||||
// Install tasks. (This requires knowing the version, so it is
|
||||
|
@ -785,6 +785,8 @@ pref("browser.sessionstore.max_resumed_crashes", 1);
|
||||
// Other tabs won't be restored until they are selected
|
||||
// N = The number of tabs to restore at the same time
|
||||
pref("browser.sessionstore.max_concurrent_tabs", 3);
|
||||
// Whether to automatically restore hidden tabs (i.e., tabs in other tab groups) or not
|
||||
pref("browser.sessionstore.restore_hidden_tabs", false);
|
||||
|
||||
// allow META refresh by default
|
||||
pref("accessibility.blockautorefresh", false);
|
||||
|
@ -359,7 +359,6 @@ appUpdater.prototype =
|
||||
// notified with the normal app update user interface so this is safe.
|
||||
gAppUpdater.isChecking = false;
|
||||
gAppUpdater.selectPanel("noUpdatesFound");
|
||||
return;
|
||||
},
|
||||
|
||||
/**
|
||||
@ -613,6 +612,8 @@ var gChannelSelector = {
|
||||
// Change app update channel.
|
||||
Services.prefs.setCharPref("app.update.desiredChannel", this.channelValue);
|
||||
|
||||
// Stop any downloads in progress
|
||||
gAppUpdater.aus.pauseDownload();
|
||||
// App updater will look at app.update.desiredChannel for new channel value
|
||||
// and will clear it when the update is complete.
|
||||
gAppUpdater.isChecking = true;
|
||||
|
@ -40,10 +40,13 @@ let TabView = {
|
||||
_deck: null,
|
||||
_iframe: null,
|
||||
_window: null,
|
||||
_firstUseExperienced: false,
|
||||
_browserKeyHandlerInitialized: false,
|
||||
_isFrameLoading: false,
|
||||
_initFrameCallbacks: [],
|
||||
PREF_BRANCH: "browser.panorama.",
|
||||
PREF_FIRST_RUN: "browser.panorama.experienced_first_run",
|
||||
PREF_STARTUP_PAGE: "browser.startup.page",
|
||||
PREF_RESTORE_ENABLED_ONCE: "browser.panorama.session_restore_enabled_once",
|
||||
VISIBILITY_IDENTIFIER: "tabview-visibility",
|
||||
|
||||
// ----------
|
||||
@ -57,24 +60,35 @@ let TabView = {
|
||||
|
||||
// ----------
|
||||
get firstUseExperienced() {
|
||||
return this._firstUseExperienced;
|
||||
let pref = this.PREF_FIRST_RUN;
|
||||
if (Services.prefs.prefHasUserValue(pref))
|
||||
return Services.prefs.getBoolPref(pref);
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
// ----------
|
||||
set firstUseExperienced(val) {
|
||||
if (val != this._firstUseExperienced)
|
||||
Services.prefs.setBoolPref("browser.panorama.experienced_first_run", val);
|
||||
Services.prefs.setBoolPref(this.PREF_FIRST_RUN, val);
|
||||
},
|
||||
|
||||
// ----------
|
||||
get sessionRestoreEnabledOnce() {
|
||||
let pref = this.PREF_RESTORE_ENABLED_ONCE;
|
||||
if (Services.prefs.prefHasUserValue(pref))
|
||||
return Services.prefs.getBoolPref(pref);
|
||||
|
||||
return false;
|
||||
},
|
||||
|
||||
// ----------
|
||||
set sessionRestoreEnabledOnce(val) {
|
||||
Services.prefs.setBoolPref(this.PREF_RESTORE_ENABLED_ONCE, val);
|
||||
},
|
||||
|
||||
// ----------
|
||||
init: function TabView_init() {
|
||||
if (!Services.prefs.prefHasUserValue("browser.panorama.experienced_first_run") ||
|
||||
!Services.prefs.getBoolPref("browser.panorama.experienced_first_run")) {
|
||||
Services.prefs.addObserver(
|
||||
"browser.panorama.experienced_first_run", this, false);
|
||||
} else {
|
||||
this._firstUseExperienced = true;
|
||||
|
||||
if (this.firstUseExperienced) {
|
||||
if ((gBrowser.tabs.length - gBrowser.visibleTabs.length) > 0)
|
||||
this._setBrowserKeyHandlers();
|
||||
|
||||
@ -100,26 +114,24 @@ let TabView = {
|
||||
"TabShow", this._tabShowEventListener, true);
|
||||
}
|
||||
}
|
||||
|
||||
Services.prefs.addObserver(this.PREF_BRANCH, this, false);
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Observes topic changes.
|
||||
observe: function TabView_observe(subject, topic, data) {
|
||||
if (topic == "nsPref:changed") {
|
||||
Services.prefs.removeObserver(
|
||||
"browser.panorama.experienced_first_run", this);
|
||||
this._firstUseExperienced = true;
|
||||
if (data == this.PREF_FIRST_RUN && this.firstUseExperienced) {
|
||||
this._addToolbarButton();
|
||||
this.enableSessionRestore();
|
||||
}
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Uninitializes TabView.
|
||||
uninit: function TabView_uninit() {
|
||||
if (!this._firstUseExperienced) {
|
||||
Services.prefs.removeObserver(
|
||||
"browser.panorama.experienced_first_run", this);
|
||||
}
|
||||
Services.prefs.removeObserver(this.PREF_BRANCH, this);
|
||||
|
||||
if (this._tabShowEventListener) {
|
||||
gBrowser.tabContainer.removeEventListener(
|
||||
"TabShow", this._tabShowEventListener, true);
|
||||
@ -366,5 +378,23 @@ let TabView = {
|
||||
toolbar.currentSet = currentSet;
|
||||
toolbar.setAttribute("currentset", currentSet);
|
||||
document.persist(toolbar.id, "currentset");
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Function: enableSessionRestore
|
||||
// Enables automatic session restore when the browser is started. Does
|
||||
// nothing if we already did that once in the past.
|
||||
enableSessionRestore: function UI_enableSessionRestore() {
|
||||
if (!this._window || !this.firstUseExperienced)
|
||||
return;
|
||||
|
||||
// do nothing if we already enabled session restore once
|
||||
if (this.sessionRestoreEnabledOnce)
|
||||
return;
|
||||
|
||||
this.sessionRestoreEnabledOnce = true;
|
||||
|
||||
// enable session restore
|
||||
Services.prefs.setIntPref(this.PREF_STARTUP_PAGE, 3);
|
||||
}
|
||||
};
|
||||
|
@ -306,22 +306,28 @@ function SetClickAndHoldHandlers() {
|
||||
aElm.addEventListener("click", clickHandler, true);
|
||||
}
|
||||
|
||||
// Bug 414797: Clone the dropmarker's menu into both the back and
|
||||
// the forward buttons.
|
||||
// Bug 414797: Clone unified-back-forward-button's context menu into both the
|
||||
// back and the forward buttons.
|
||||
var unifiedButton = document.getElementById("unified-back-forward-button");
|
||||
if (unifiedButton && !unifiedButton._clickHandlersAttached) {
|
||||
var popup = document.getElementById("backForwardMenu").cloneNode(true);
|
||||
unifiedButton._clickHandlersAttached = true;
|
||||
|
||||
let popup = document.getElementById("backForwardMenu").cloneNode(true);
|
||||
popup.removeAttribute("id");
|
||||
var backButton = document.getElementById("back-button");
|
||||
// Prevent the context attribute on unified-back-forward-button from being
|
||||
// inherited.
|
||||
popup.setAttribute("context", "");
|
||||
|
||||
let backButton = document.getElementById("back-button");
|
||||
backButton.setAttribute("type", "menu");
|
||||
backButton.appendChild(popup);
|
||||
_addClickAndHoldListenersOnElement(backButton);
|
||||
var forwardButton = document.getElementById("forward-button");
|
||||
|
||||
let forwardButton = document.getElementById("forward-button");
|
||||
popup = popup.cloneNode(true);
|
||||
forwardButton.setAttribute("type", "menu");
|
||||
forwardButton.appendChild(popup);
|
||||
_addClickAndHoldListenersOnElement(forwardButton);
|
||||
unifiedButton._clickHandlersAttached = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -4118,7 +4124,7 @@ var XULBrowserWindow = {
|
||||
startTime: 0,
|
||||
statusText: "",
|
||||
isBusy: false,
|
||||
inContentWhitelist: ["about:addons"],
|
||||
inContentWhitelist: ["about:addons", "about:permissions"],
|
||||
|
||||
QueryInterface: function (aIID) {
|
||||
if (aIID.equals(Ci.nsIWebProgressListener) ||
|
||||
|
@ -92,9 +92,9 @@ var gSyncSetup = {
|
||||
init: function () {
|
||||
let obs = [
|
||||
["weave:service:changepph:finish", "onResetPassphrase"],
|
||||
["weave:service:verify-login:start", "onLoginStart"],
|
||||
["weave:service:verify-login:error", "onLoginEnd"],
|
||||
["weave:service:verify-login:finish", "onLoginEnd"]];
|
||||
["weave:service:login:start", "onLoginStart"],
|
||||
["weave:service:login:error", "onLoginEnd"],
|
||||
["weave:service:login:finish", "onLoginEnd"]];
|
||||
|
||||
// Add the observers now and remove them on unload
|
||||
let self = this;
|
||||
@ -216,6 +216,8 @@ var gSyncSetup = {
|
||||
feedback = server;
|
||||
break;
|
||||
case Weave.LOGIN_FAILED_LOGIN_REJECTED:
|
||||
case Weave.LOGIN_FAILED_NO_USERNAME:
|
||||
case Weave.LOGIN_FAILED_NO_PASSWORD:
|
||||
feedback = password;
|
||||
break;
|
||||
case Weave.LOGIN_FAILED_INVALID_PASSPHRASE:
|
||||
|
@ -194,12 +194,13 @@ let gSyncUtils = {
|
||||
*/
|
||||
passphraseSave: function(elid) {
|
||||
let dialogTitle = this.bundle.GetStringFromName("save.synckey.title");
|
||||
let defaultSaveName = this.bundle.GetStringFromName("save.default.label");
|
||||
this._preparePPiframe(elid, function(iframe) {
|
||||
let filepicker = Cc["@mozilla.org/filepicker;1"]
|
||||
.createInstance(Ci.nsIFilePicker);
|
||||
filepicker.init(window, dialogTitle, Ci.nsIFilePicker.modeSave);
|
||||
filepicker.appendFilters(Ci.nsIFilePicker.filterHTML);
|
||||
filepicker.defaultString = "Firefox Sync Key.html";
|
||||
filepicker.defaultString = defaultSaveName;
|
||||
let rv = filepicker.show();
|
||||
if (rv == Ci.nsIFilePicker.returnOK
|
||||
|| rv == Ci.nsIFilePicker.returnReplace) {
|
||||
|
@ -1540,8 +1540,10 @@
|
||||
}
|
||||
|
||||
this._removingTabs.push(aTab);
|
||||
|
||||
this.tabContainer.updateVisibility();
|
||||
if (newTab)
|
||||
this.addTab("about:blank", {skipAnimation: true});
|
||||
else
|
||||
this.tabContainer.updateVisibility();
|
||||
|
||||
// We're committed to closing the tab now.
|
||||
// Dispatch a notification.
|
||||
@ -1597,8 +1599,6 @@
|
||||
|
||||
// update the UI early for responsiveness
|
||||
aTab.collapsed = true;
|
||||
if (aNewTab)
|
||||
this.addTab("about:blank", {skipAnimation: true});
|
||||
this.tabContainer._fillTrailingGap();
|
||||
this._blurTab(aTab);
|
||||
|
||||
|
@ -2163,7 +2163,16 @@ let GroupItems = {
|
||||
}
|
||||
|
||||
toClose.forEach(function(groupItem) {
|
||||
groupItem.destroy({immediately: true});
|
||||
// All remaining children in to-be-closed groups are re-used by
|
||||
// session restore. Reconnect them so that they're put into their
|
||||
// right groups.
|
||||
groupItem.getChildren().forEach(function (tabItem) {
|
||||
if (tabItem.parent && tabItem.parent.hidden)
|
||||
iQ(tabItem.container).show();
|
||||
tabItem._reconnected = false;
|
||||
tabItem._reconnect();
|
||||
});
|
||||
groupItem.close({immediately: true});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -57,7 +57,10 @@ let AllTabs = {
|
||||
get tabs() {
|
||||
// Get tabs from each browser window and flatten them into one array
|
||||
return Array.concat.apply(null, browserWindows.map(function(browserWindow) {
|
||||
return Array.slice(browserWindow.gBrowser.tabs);
|
||||
let removingTabs = browserWindow.gBrowser._removingTabs;
|
||||
return Array.filter(browserWindow.gBrowser.tabs, function (tab) {
|
||||
return removingTabs.indexOf(tab) == -1;
|
||||
});
|
||||
}));
|
||||
},
|
||||
|
||||
|
@ -552,6 +552,9 @@ let UI = {
|
||||
|
||||
TabItems.resumePainting();
|
||||
}
|
||||
|
||||
if (gTabView.firstUseExperienced)
|
||||
gTabView.enableSessionRestore();
|
||||
},
|
||||
|
||||
// ----------
|
||||
@ -739,7 +742,7 @@ let UI = {
|
||||
} else {
|
||||
// If we're currently in the process of entering private browsing,
|
||||
// we don't want to go to the Tab View UI.
|
||||
if (self._privateBrowsing.transitionMode)
|
||||
if (self._storageBusyCount)
|
||||
return;
|
||||
|
||||
// if not closing the last tab
|
||||
|
@ -201,6 +201,7 @@ _BROWSER_FILES = \
|
||||
browser_scratchpad_ui.js \
|
||||
browser_scratchpad_bug_646070_chrome_context_pref.js \
|
||||
browser_overflowScroll.js \
|
||||
browser_locationBarExternalLoad.js \
|
||||
browser_pageInfo.js \
|
||||
browser_page_style_menu.js \
|
||||
browser_pinnedTabs.js \
|
||||
|
@ -96,11 +96,10 @@ function test_disabled_install() {
|
||||
|
||||
wait_for_notification_close(function() {
|
||||
try {
|
||||
Services.prefs.getBoolPref("xpinstall.disabled");
|
||||
ok(false, "xpinstall.disabled should not be set");
|
||||
ok(Services.prefs.getBoolPref("xpinstall.enabled"), "Installation should be enabled");
|
||||
}
|
||||
catch (e) {
|
||||
ok(true, "xpinstall.disabled should not be set");
|
||||
ok(false, "xpinstall.enabled should be set");
|
||||
}
|
||||
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
|
45
browser/base/content/test/browser_locationBarExternalLoad.js
Normal file
45
browser/base/content/test/browser_locationBarExternalLoad.js
Normal file
@ -0,0 +1,45 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
nextTest();
|
||||
}
|
||||
|
||||
let urls = [
|
||||
"javascript:'foopy';",
|
||||
"data:text/html,<script>document.write(document.domain);</script>"
|
||||
];
|
||||
|
||||
function nextTest() {
|
||||
let url = urls.shift();
|
||||
if (url)
|
||||
testURL(url, nextTest);
|
||||
else
|
||||
finish();
|
||||
}
|
||||
|
||||
function testURL(newURL, func) {
|
||||
let tab = gBrowser.selectedTab = gBrowser.addTab();
|
||||
registerCleanupFunction(function () {
|
||||
gBrowser.removeTab(tab);
|
||||
});
|
||||
addPageShowListener(function () {
|
||||
let pagePrincipal = gBrowser.contentPrincipal;
|
||||
gURLBar.value = newURL;
|
||||
gURLBar.handleCommand();
|
||||
|
||||
addPageShowListener(function () {
|
||||
ok(!gBrowser.contentPrincipal.equals(pagePrincipal), "load of " + newURL + " produced a page with a different principal");
|
||||
func();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function addPageShowListener(func) {
|
||||
gBrowser.selectedBrowser.addEventListener("pageshow", function loadListener() {
|
||||
gBrowser.selectedBrowser.removeEventListener("pageshow", loadListener, false);
|
||||
func();
|
||||
});
|
||||
}
|
@ -64,6 +64,7 @@ _BROWSER_FILES = \
|
||||
browser_tabview_bug595518.js \
|
||||
browser_tabview_bug595521.js \
|
||||
browser_tabview_bug595560.js \
|
||||
browser_tabview_bug595601.js \
|
||||
browser_tabview_bug595804.js \
|
||||
browser_tabview_bug595930.js \
|
||||
browser_tabview_bug595943.js \
|
||||
@ -131,13 +132,16 @@ _BROWSER_FILES = \
|
||||
browser_tabview_bug640765.js \
|
||||
browser_tabview_bug641802.js \
|
||||
browser_tabview_bug642793.js \
|
||||
browser_tabview_bug643392.js \
|
||||
browser_tabview_bug644097.js \
|
||||
browser_tabview_bug645653.js \
|
||||
browser_tabview_bug648882.js \
|
||||
browser_tabview_bug649006.js \
|
||||
browser_tabview_bug649307.js \
|
||||
browser_tabview_bug650573.js \
|
||||
browser_tabview_bug651311.js \
|
||||
browser_tabview_bug654941.js \
|
||||
browser_tabview_bug656778.js \
|
||||
browser_tabview_dragdrop.js \
|
||||
browser_tabview_exit_button.js \
|
||||
browser_tabview_expander.js \
|
||||
|
@ -1,93 +1,121 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
const DUMMY_PAGE_URL = "http://mochi.test:8888/browser/browser/base/content/test/tabview/dummy_page.html";
|
||||
const DUMMY_PAGE_URL_2 = "http://mochi.test:8888/";
|
||||
const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||
|
||||
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||
const DUMMY_PAGE_URL = "http://mochi.test:8888/browser/browser/base/content/test/tabview/dummy_page.html";
|
||||
const DUMMY_PAGE_URL_2 = "http://mochi.test:8888/";
|
||||
|
||||
let state = {
|
||||
windows: [{
|
||||
tabs: [{
|
||||
entries: [{ url: DUMMY_PAGE_URL }],
|
||||
hidden: true,
|
||||
attributes: {},
|
||||
extData: {
|
||||
"tabview-tab":
|
||||
'{"bounds":{"left":21,"top":29,"width":204,"height":153},' +
|
||||
'"userSize":null,"url":"' + DUMMY_PAGE_URL + '","groupID":1,' +
|
||||
'"imageData":null,"title":null}'
|
||||
}
|
||||
},{
|
||||
entries: [{ url: DUMMY_PAGE_URL_2 }],
|
||||
hidden: false,
|
||||
attributes: {},
|
||||
extData: {
|
||||
"tabview-tab":
|
||||
'{"bounds":{"left":315,"top":29,"width":111,"height":84},' +
|
||||
'"userSize":null,"url":"' + DUMMY_PAGE_URL_2 + '","groupID":2,' +
|
||||
'"imageData":null,"title":null}'
|
||||
},
|
||||
}],
|
||||
selected:2,
|
||||
_closedTabs: [],
|
||||
extData: {
|
||||
"tabview-groups": '{"nextID":3,"activeGroupId":2}',
|
||||
"tabview-group":
|
||||
'{"1":{"bounds":{"left":15,"top":5,"width":280,"height":232},' +
|
||||
'"userSize":null,"title":"","id":1},' +
|
||||
'"2":{"bounds":{"left":309,"top":5,"width":267,"height":226},' +
|
||||
'"userSize":null,"title":"","id":2}}',
|
||||
"tabview-ui": '{"pageBounds":{"left":0,"top":0,"width":788,"height":548}}'
|
||||
}, sizemode:"normal"
|
||||
}]
|
||||
};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
// open a new window and setup the window state.
|
||||
let newWin = openDialog(getBrowserURL(), "_blank", "chrome,all,dialog=no");
|
||||
newWin.addEventListener("load", function(event) {
|
||||
this.removeEventListener("load", arguments.callee, false);
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_hidden_tabs");
|
||||
});
|
||||
|
||||
let newState = {
|
||||
windows: [{
|
||||
tabs: [{
|
||||
entries: [{ url: DUMMY_PAGE_URL }],
|
||||
hidden: true,
|
||||
attributes: {},
|
||||
extData: {
|
||||
"tabview-tab":
|
||||
'{"bounds":{"left":21,"top":29,"width":204,"height":153},' +
|
||||
'"userSize":null,"url":"' + DUMMY_PAGE_URL + '","groupID":1,' +
|
||||
'"imageData":null,"title":null}'
|
||||
}
|
||||
},{
|
||||
entries: [{ url: DUMMY_PAGE_URL_2 }],
|
||||
hidden: false,
|
||||
attributes: {},
|
||||
extData: {
|
||||
"tabview-tab":
|
||||
'{"bounds":{"left":315,"top":29,"width":111,"height":84},' +
|
||||
'"userSize":null,"url":"' + DUMMY_PAGE_URL_2 + '","groupID":2,' +
|
||||
'"imageData":null,"title":null}'
|
||||
},
|
||||
}],
|
||||
selected:2,
|
||||
_closedTabs: [],
|
||||
extData: {
|
||||
"tabview-groups": '{"nextID":3,"activeGroupId":2}',
|
||||
"tabview-group":
|
||||
'{"1":{"bounds":{"left":15,"top":5,"width":280,"height":232},' +
|
||||
'"userSize":null,"title":"","id":1},' +
|
||||
'"2":{"bounds":{"left":309,"top":5,"width":267,"height":226},' +
|
||||
'"userSize":null,"title":"","id":2}}',
|
||||
"tabview-ui": '{"pageBounds":{"left":0,"top":0,"width":788,"height":548}}'
|
||||
}, sizemode:"normal"
|
||||
}]
|
||||
};
|
||||
ss.setWindowState(newWin, JSON.stringify(newState), true);
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_hidden_tabs", false);
|
||||
|
||||
let firstTab = newWin.gBrowser.tabs[0];
|
||||
let secondTab = newWin.gBrowser.tabs[1];
|
||||
testTabSwitchAfterRestore(function () {
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_hidden_tabs", true);
|
||||
|
||||
// wait until the first tab is fully loaded
|
||||
let browser = newWin.gBrowser.getBrowserForTab(firstTab);
|
||||
let onLoad = function() {
|
||||
browser.removeEventListener("load", onLoad, true);
|
||||
testTabSwitchAfterRestore(function () {
|
||||
waitForFocus(finish);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
is(browser.currentURI.spec, DUMMY_PAGE_URL,
|
||||
"The url of first tab url is dummy_page.html");
|
||||
function testTabSwitchAfterRestore(callback) {
|
||||
newWindowWithState(state, function (win) {
|
||||
registerCleanupFunction(function () win.close());
|
||||
|
||||
// check the hidden state of both tabs.
|
||||
ok(firstTab.hidden, "The first tab is hidden");
|
||||
ok(!secondTab.hidden, "The second tab is not hidden");
|
||||
is(secondTab, newWin.gBrowser.selectedTab, "The second tab is selected");
|
||||
let [firstTab, secondTab] = win.gBrowser.tabs;
|
||||
is(firstTab.linkedBrowser.currentURI.spec, DUMMY_PAGE_URL,
|
||||
"The url of first tab url is dummy_page.html");
|
||||
|
||||
// when the second tab is hidden, the iframe should be initialized and
|
||||
// the first tab should be visible.
|
||||
let onTabHide = function() {
|
||||
newWin.gBrowser.tabContainer.removeEventListener("TabHide", onTabHide, true);
|
||||
// check the hidden state of both tabs.
|
||||
ok(firstTab.hidden, "The first tab is hidden");
|
||||
ok(!secondTab.hidden, "The second tab is not hidden");
|
||||
is(secondTab, win.gBrowser.selectedTab, "The second tab is selected");
|
||||
|
||||
ok(newWin.TabView.getContentWindow(), "");
|
||||
// when the second tab is hidden, Panorama should be initialized and
|
||||
// the first tab should be visible.
|
||||
let container = win.gBrowser.tabContainer;
|
||||
container.addEventListener("TabHide", function onTabHide() {
|
||||
container.removeEventListener("TabHide", onTabHide, false);
|
||||
|
||||
ok(!firstTab.hidden, "The first tab is not hidden");
|
||||
is(firstTab, newWin.gBrowser.selectedTab, "The first tab is selected");
|
||||
ok(secondTab.hidden, "The second tab is hidden");
|
||||
ok(win.TabView.getContentWindow(), "Panorama is loaded");
|
||||
ok(!firstTab.hidden, "The first tab is not hidden");
|
||||
is(firstTab, win.gBrowser.selectedTab, "The first tab is selected");
|
||||
ok(secondTab.hidden, "The second tab is hidden");
|
||||
|
||||
// clean up and finish
|
||||
newWin.close();
|
||||
callback();
|
||||
}, false);
|
||||
|
||||
finish();
|
||||
};
|
||||
newWin.gBrowser.tabContainer.addEventListener("TabHide", onTabHide, true);
|
||||
// switch to another tab
|
||||
win.switchToTabHavingURI(DUMMY_PAGE_URL);
|
||||
});
|
||||
}
|
||||
|
||||
// switch to another tab
|
||||
newWin.switchToTabHavingURI(DUMMY_PAGE_URL);
|
||||
}
|
||||
browser.addEventListener("load", onLoad, true);
|
||||
function newWindowWithState(state, callback) {
|
||||
let opts = "chrome,all,dialog=no,height=800,width=800";
|
||||
let win = window.openDialog(getBrowserURL(), "_blank", opts);
|
||||
|
||||
whenWindowLoaded(win, function () {
|
||||
ss.setWindowState(win, JSON.stringify(state), true);
|
||||
});
|
||||
|
||||
whenWindowStateReady(win, function () {
|
||||
afterAllTabsLoaded(function () callback(win), win);
|
||||
});
|
||||
}
|
||||
|
||||
function whenWindowLoaded(win, callback) {
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad, false);
|
||||
executeSoon(callback);
|
||||
}, false);
|
||||
}
|
||||
|
||||
function whenWindowStateReady(win, callback) {
|
||||
win.addEventListener("SSWindowStateReady", function onReady() {
|
||||
win.removeEventListener("SSWindowStateReady", onReady, false);
|
||||
executeSoon(callback);
|
||||
}, false);
|
||||
}
|
||||
|
@ -1,134 +1,97 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let newTabOne;
|
||||
let originalTab;
|
||||
let win;
|
||||
let cw;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
originalTab = gBrowser.visibleTabs[0];
|
||||
newTabOne = gBrowser.addTab("http://mochi.test:8888/");
|
||||
|
||||
let browser = gBrowser.getBrowserForTab(newTabOne);
|
||||
let onLoad = function() {
|
||||
browser.removeEventListener("load", onLoad, true);
|
||||
|
||||
// show the tab view
|
||||
window.addEventListener("tabviewshown", onTabViewWindowLoaded, false);
|
||||
TabView.toggle();
|
||||
}
|
||||
browser.addEventListener("load", onLoad, true);
|
||||
}
|
||||
|
||||
function onTabViewWindowLoaded() {
|
||||
window.removeEventListener("tabviewshown", onTabViewWindowLoaded, false);
|
||||
ok(TabView.isVisible(), "Tab View is visible");
|
||||
|
||||
afterAllTabItemsUpdated(function() {
|
||||
let contentWindow = document.getElementById("tab-view").contentWindow;
|
||||
testOne(contentWindow);
|
||||
});
|
||||
}
|
||||
|
||||
function testOne(contentWindow) {
|
||||
onSearchEnabledAndDisabled(contentWindow, function() {
|
||||
testTwo(contentWindow);
|
||||
});
|
||||
// press cmd/ctrl F
|
||||
EventUtils.synthesizeKey("f", { accelKey: true });
|
||||
}
|
||||
|
||||
function testTwo(contentWindow) {
|
||||
onSearchEnabledAndDisabled(contentWindow, function() {
|
||||
testThree(contentWindow);
|
||||
});
|
||||
// press /
|
||||
EventUtils.synthesizeKey("VK_SLASH", { type: "keydown" }, contentWindow);
|
||||
}
|
||||
|
||||
function testThree(contentWindow) {
|
||||
let groupItem = createEmptyGroupItem(contentWindow, 200);
|
||||
|
||||
let onTabViewHidden = function() {
|
||||
window.removeEventListener("tabviewhidden", onTabViewHidden, false);
|
||||
TabView.toggle();
|
||||
let onLoad = function (tvwin) {
|
||||
win = tvwin;
|
||||
registerCleanupFunction(function () win.close());
|
||||
win.gBrowser.loadOneTab("http://mochi.test:8888/", {inBackground: true});
|
||||
};
|
||||
let onTabViewShown = function() {
|
||||
window.removeEventListener("tabviewshown", onTabViewShown, false);
|
||||
|
||||
is(contentWindow.UI.getActiveTab(), groupItem.getChild(0),
|
||||
let onShow = function () {
|
||||
cw = win.TabView.getContentWindow();
|
||||
ok(win.TabView.isVisible(), "Tab View is visible");
|
||||
afterAllTabItemsUpdated(testOne, win);
|
||||
};
|
||||
|
||||
newWindowWithTabView(onShow, onLoad);
|
||||
}
|
||||
|
||||
function testOne() {
|
||||
whenSearchEnabledAndDisabled(testTwo);
|
||||
// press cmd/ctrl F
|
||||
EventUtils.synthesizeKey("f", {accelKey: true}, cw);
|
||||
}
|
||||
|
||||
function testTwo() {
|
||||
whenSearchEnabledAndDisabled(testThree);
|
||||
// press /
|
||||
EventUtils.synthesizeKey("VK_SLASH", {}, cw);
|
||||
}
|
||||
|
||||
function testThree() {
|
||||
let onTabViewShown = function () {
|
||||
is(cw.UI.getActiveTab(), groupItem.getChild(0),
|
||||
"The active tab is newly created tab item");
|
||||
|
||||
let onSearchEnabled = function() {
|
||||
contentWindow.removeEventListener(
|
||||
"tabviewsearchenabled", onSearchEnabled, false);
|
||||
let onSearchEnabled = function () {
|
||||
let doc = cw.document;
|
||||
let searchBox = cw.iQ("#searchbox");
|
||||
let hasFocus = doc.hasFocus() && doc.activeElement == searchBox[0];
|
||||
ok(hasFocus, "The search box has focus");
|
||||
|
||||
let searchBox = contentWindow.iQ("#searchbox");
|
||||
let tab = win.gBrowser.tabs[1];
|
||||
searchBox.val(tab._tabViewTabItem.$tabTitle[0].innerHTML);
|
||||
|
||||
ok(contentWindow.document.hasFocus() &&
|
||||
contentWindow.document.activeElement == searchBox[0],
|
||||
"The search box has focus");
|
||||
searchBox.val(newTabOne._tabViewTabItem.$tabTitle[0].innerHTML);
|
||||
cw.performSearch();
|
||||
|
||||
contentWindow.performSearch();
|
||||
|
||||
let checkSelectedTab = function() {
|
||||
window.removeEventListener("tabviewhidden", checkSelectedTab, false);
|
||||
is(newTabOne, gBrowser.selectedTab, "The search result tab is shown");
|
||||
cleanUpAndFinish(groupItem.getChild(0), contentWindow);
|
||||
};
|
||||
window.addEventListener("tabviewhidden", checkSelectedTab, false);
|
||||
whenTabViewIsHidden(function () {
|
||||
is(tab, win.gBrowser.selectedTab, "The search result tab is shown");
|
||||
waitForFocus(finish);
|
||||
}, win);
|
||||
|
||||
// use the tabview menu (the same as pressing cmd/ctrl + e)
|
||||
document.getElementById("menu_tabview").doCommand();
|
||||
};
|
||||
contentWindow.addEventListener("tabviewsearchenabled", onSearchEnabled, false);
|
||||
EventUtils.synthesizeKey("VK_SLASH", { type: "keydown" }, contentWindow);
|
||||
win.document.getElementById("menu_tabview").doCommand();
|
||||
};
|
||||
|
||||
whenSearchEnabled(onSearchEnabled);
|
||||
EventUtils.synthesizeKey("VK_SLASH", {}, cw);
|
||||
};
|
||||
window.addEventListener("tabviewhidden", onTabViewHidden, false);
|
||||
window.addEventListener("tabviewshown", onTabViewShown, false);
|
||||
|
||||
whenTabViewIsHidden(function () {
|
||||
showTabView(onTabViewShown, win);
|
||||
}, win);
|
||||
|
||||
// click on the + button
|
||||
let groupItem = createEmptyGroupItem(cw, 300, 300, 200);
|
||||
let newTabButton = groupItem.container.getElementsByClassName("newTabButton");
|
||||
ok(newTabButton[0], "New tab button exists");
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "click" }, newTabButton[0], contentWindow);
|
||||
EventUtils.sendMouseEvent({type: "click"}, newTabButton[0], cw);
|
||||
}
|
||||
|
||||
function onSearchEnabledAndDisabled(contentWindow, callback) {
|
||||
let onSearchEnabled = function() {
|
||||
contentWindow.removeEventListener(
|
||||
"tabviewsearchenabled", onSearchEnabled, false);
|
||||
contentWindow.addEventListener("tabviewsearchdisabled", onSearchDisabled, false);
|
||||
contentWindow.hideSearch();
|
||||
}
|
||||
let onSearchDisabled = function() {
|
||||
contentWindow.removeEventListener(
|
||||
"tabviewsearchdisabled", onSearchDisabled, false);
|
||||
function whenSearchEnabledAndDisabled(callback) {
|
||||
whenSearchEnabled(function () {
|
||||
whenSearchDisabled(callback);
|
||||
cw.hideSearch();
|
||||
});
|
||||
}
|
||||
|
||||
function whenSearchEnabled(callback) {
|
||||
cw.addEventListener("tabviewsearchenabled", function onSearchEnabled() {
|
||||
cw.removeEventListener("tabviewsearchenabled", onSearchEnabled, false);
|
||||
callback();
|
||||
}
|
||||
contentWindow.addEventListener("tabviewsearchenabled", onSearchEnabled, false);
|
||||
}, false);
|
||||
}
|
||||
|
||||
function cleanUpAndFinish(tabItem, contentWindow) {
|
||||
gBrowser.selectedTab = originalTab;
|
||||
gBrowser.removeTab(newTabOne);
|
||||
gBrowser.removeTab(tabItem.tab);
|
||||
|
||||
finish();
|
||||
function whenSearchDisabled(callback) {
|
||||
cw.addEventListener("tabviewsearchdisabled", function onSearchDisabled() {
|
||||
cw.removeEventListener("tabviewsearchdisabled", onSearchDisabled, false);
|
||||
callback();
|
||||
}, false);
|
||||
}
|
||||
|
||||
function createEmptyGroupItem(contentWindow, padding) {
|
||||
let pageBounds = contentWindow.Items.getPageBounds();
|
||||
pageBounds.inset(padding, padding);
|
||||
|
||||
let box = new contentWindow.Rect(pageBounds);
|
||||
box.width = 300;
|
||||
box.height = 300;
|
||||
|
||||
let emptyGroupItem = new contentWindow.GroupItem([], { bounds: box });
|
||||
|
||||
return emptyGroupItem;
|
||||
}
|
||||
|
||||
|
184
browser/base/content/test/tabview/browser_tabview_bug595601.js
Normal file
184
browser/base/content/test/tabview/browser_tabview_bug595601.js
Normal file
@ -0,0 +1,184 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||
|
||||
const TAB_STATE_NEEDS_RESTORE = 1;
|
||||
const TAB_STATE_RESTORING = 2;
|
||||
|
||||
let stateBackup = ss.getBrowserState();
|
||||
|
||||
let state = {windows:[{tabs:[
|
||||
// first group
|
||||
{entries:[{url:"http://example.com#1"}],extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#1\",\"groupID\":2}"}},
|
||||
{entries:[{url:"http://example.com#2"}],extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#2\",\"groupID\":2}"}},
|
||||
{entries:[{url:"http://example.com#3"}],extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#3\",\"groupID\":2}"}},
|
||||
{entries:[{url:"http://example.com#4"}],extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#4\",\"groupID\":2}"}},
|
||||
|
||||
// second group
|
||||
{entries:[{url:"http://example.com#5"}],hidden:true,extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#5\",\"groupID\":1}"}},
|
||||
{entries:[{url:"http://example.com#6"}],hidden:true,extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#6\",\"groupID\":1}"}},
|
||||
{entries:[{url:"http://example.com#7"}],hidden:true,extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#7\",\"groupID\":1}"}},
|
||||
{entries:[{url:"http://example.com#8"}],hidden:true,extData:{"tabview-tab":"{\"bounds\":{\"left\":20,\"top\":20,\"width\":20,\"height\":20},\"url\":\"http://example.com#8\",\"groupID\":1}"}}
|
||||
],selected:5,extData:{
|
||||
"tabview-groups":"{\"nextID\":8,\"activeGroupId\":1}","tabview-group":"{\"1\":{\"bounds\":{\"left\":15,\"top\":10,\"width\":415,\"height\":367},\"userSize\":{\"x\":415,\"y\":367},\"title\":\"\",\"id\":1},\"2\":{\"bounds\":{\"left\":286,\"top\":488,\"width\":418,\"height\":313},\"title\":\"\",\"id\":2}}",
|
||||
"tabview-ui":"{\"pageBounds\":{\"left\":0,\"top\":0,\"width\":940,\"height\":1075}}"
|
||||
}}]};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_hidden_tabs", false);
|
||||
|
||||
TabsProgressListener.init();
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
TabsProgressListener.uninit();
|
||||
|
||||
Services.prefs.clearUserPref("browser.sessionstore.max_concurrent_tabs");
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_hidden_tabs");
|
||||
|
||||
ss.setBrowserState(stateBackup);
|
||||
});
|
||||
|
||||
Services.prefs.setIntPref("browser.sessionstore.max_concurrent_tabs", 3);
|
||||
|
||||
TabView._initFrame(function () {
|
||||
executeSoon(testRestoreWithHiddenTabs);
|
||||
});
|
||||
}
|
||||
|
||||
function testRestoreWithHiddenTabs() {
|
||||
let checked = false;
|
||||
let ssReady = false;
|
||||
let tabsRestored = false;
|
||||
|
||||
let check = function () {
|
||||
if (checked || !ssReady || !tabsRestored)
|
||||
return;
|
||||
|
||||
checked = true;
|
||||
|
||||
is(gBrowser.tabs.length, 8, "there are now eight tabs");
|
||||
is(gBrowser.visibleTabs.length, 4, "four visible tabs");
|
||||
|
||||
let cw = TabView.getContentWindow();
|
||||
is(cw.GroupItems.groupItems.length, 2, "there are now two groupItems");
|
||||
|
||||
testSwitchToInactiveGroup();
|
||||
}
|
||||
|
||||
whenSessionStoreReady(function () {
|
||||
ssReady = true;
|
||||
check();
|
||||
});
|
||||
|
||||
TabsProgressListener.setCallback(function (needsRestore, isRestoring) {
|
||||
if (4 < needsRestore)
|
||||
return;
|
||||
|
||||
TabsProgressListener.unsetCallback();
|
||||
is(needsRestore, 4, "4/8 tabs restored");
|
||||
|
||||
tabsRestored = true;
|
||||
check();
|
||||
});
|
||||
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
}
|
||||
|
||||
function testSwitchToInactiveGroup() {
|
||||
let firstProgress = true;
|
||||
|
||||
TabsProgressListener.setCallback(function (needsRestore, isRestoring) {
|
||||
if (firstProgress) {
|
||||
firstProgress = false;
|
||||
is(isRestoring, 3, "restoring 3 tabs concurrently");
|
||||
} else {
|
||||
ok(isRestoring < 4, "restoring max. 3 tabs concurrently");
|
||||
}
|
||||
|
||||
if (needsRestore)
|
||||
return;
|
||||
|
||||
TabsProgressListener.unsetCallback();
|
||||
|
||||
is(gBrowser.visibleTabs.length, 4, "four visible tabs");
|
||||
waitForFocus(finish);
|
||||
});
|
||||
|
||||
gBrowser.selectedTab = gBrowser.tabs[4];
|
||||
}
|
||||
|
||||
function whenSessionStoreReady(callback) {
|
||||
window.addEventListener("SSWindowStateReady", function onReady() {
|
||||
window.removeEventListener("SSWindowStateReady", onReady, false);
|
||||
executeSoon(callback);
|
||||
}, false);
|
||||
}
|
||||
|
||||
function countTabs() {
|
||||
let needsRestore = 0, isRestoring = 0;
|
||||
let windowsEnum = Services.wm.getEnumerator("navigator:browser");
|
||||
|
||||
while (windowsEnum.hasMoreElements()) {
|
||||
let window = windowsEnum.getNext();
|
||||
if (window.closed)
|
||||
continue;
|
||||
|
||||
for (let i = 0; i < window.gBrowser.tabs.length; i++) {
|
||||
let browser = window.gBrowser.tabs[i].linkedBrowser;
|
||||
if (browser.__SS_restoreState == TAB_STATE_RESTORING)
|
||||
isRestoring++;
|
||||
else if (browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE)
|
||||
needsRestore++;
|
||||
}
|
||||
}
|
||||
|
||||
return [needsRestore, isRestoring];
|
||||
}
|
||||
|
||||
let TabsProgressListener = {
|
||||
init: function () {
|
||||
gBrowser.addTabsProgressListener(this);
|
||||
},
|
||||
|
||||
uninit: function () {
|
||||
this.unsetCallback();
|
||||
gBrowser.removeTabsProgressListener(this);
|
||||
},
|
||||
|
||||
setCallback: function (callback) {
|
||||
this.callback = callback;
|
||||
},
|
||||
|
||||
unsetCallback: function () {
|
||||
delete this.callback;
|
||||
},
|
||||
|
||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
let isNetwork = aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK;
|
||||
let isWindow = aStateFlags & Ci.nsIWebProgressListener.STATE_IS_WINDOW;
|
||||
|
||||
if (!(this.callback && isNetwork && isWindow))
|
||||
return;
|
||||
|
||||
let self = this;
|
||||
let finalize = function () {
|
||||
if (wasRestoring)
|
||||
delete aBrowser.__wasRestoring;
|
||||
|
||||
self.callback.apply(null, countTabs());
|
||||
};
|
||||
|
||||
let isRestoring = aBrowser.__SS_restoreState == TAB_STATE_RESTORING;
|
||||
let wasRestoring = !aBrowser.__SS_restoreState && aBrowser.__wasRestoring;
|
||||
let hasStopped = aStateFlags & Ci.nsIWebProgressListener.STATE_STOP;
|
||||
|
||||
if (isRestoring && !hasStopped)
|
||||
aBrowser.__wasRestoring = true;
|
||||
|
||||
if (hasStopped && (isRestoring || wasRestoring))
|
||||
finalize();
|
||||
}
|
||||
}
|
@ -38,6 +38,7 @@ function test() {
|
||||
if (!callback)
|
||||
callback = finish;
|
||||
|
||||
assertOneSingleGroupItem();
|
||||
callback();
|
||||
});
|
||||
}
|
||||
@ -111,7 +112,7 @@ function test() {
|
||||
// some callback waiting to be fired after gBrowser.loadOneTab(). After
|
||||
// that the browser is in a state where loadURI() will create a new entry
|
||||
// in the session history (that is vital for back/forward functionality).
|
||||
afterAllTabsLoaded(function () SimpleTest.executeSoon(continueTest));
|
||||
afterAllTabsLoaded(function () executeSoon(continueTest));
|
||||
}
|
||||
|
||||
// ----------
|
||||
@ -190,7 +191,7 @@ function enterAndLeavePrivateBrowsing(callback) {
|
||||
pb.privateBrowsingEnabled = false;
|
||||
else {
|
||||
Services.obs.removeObserver(pbObserver, "private-browsing-transition-complete");
|
||||
afterAllTabsLoaded(callback);
|
||||
afterAllTabsLoaded(function () executeSoon(callback));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -62,7 +62,10 @@ function test() {
|
||||
let testStateAfterEnteringPB = function () {
|
||||
let prefix = 'enter';
|
||||
ok(!pb.privateBrowsingEnabled, prefix + ': private browsing is disabled');
|
||||
registerCleanupFunction(function () pb.privateBrowsingEnabled = false);
|
||||
registerCleanupFunction(function () {
|
||||
if (pb.privateBrowsingEnabled)
|
||||
pb.privateBrowsingEnabled = false
|
||||
});
|
||||
|
||||
togglePrivateBrowsing(function () {
|
||||
assertTabViewIsHidden(prefix);
|
||||
@ -110,6 +113,8 @@ function test() {
|
||||
|
||||
showTabView(function () {
|
||||
cw = TabView.getContentWindow();
|
||||
assertNumberOfGroups('start', 1);
|
||||
|
||||
createGroupItem();
|
||||
|
||||
afterAllTabsLoaded(function () {
|
||||
|
@ -16,10 +16,8 @@ function test() {
|
||||
|
||||
showTabView(function() {
|
||||
registerCleanupFunction(function () {
|
||||
if (gBrowser.tabs[1])
|
||||
while (gBrowser.tabs.length > 1)
|
||||
gBrowser.removeTab(gBrowser.tabs[1]);
|
||||
if (gBrowser.tabs[2])
|
||||
gBrowser.removeTab(gBrowser.tabs[2]);
|
||||
TabView.hide();
|
||||
});
|
||||
|
||||
|
@ -109,6 +109,6 @@ function restore(groupId) {
|
||||
}]
|
||||
};
|
||||
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||
ss.setWindowState(win, JSON.stringify(newState), false);
|
||||
ss.setWindowState(win, JSON.stringify(newState), true);
|
||||
}
|
||||
|
||||
|
@ -0,0 +1,56 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||
|
||||
let state = {
|
||||
windows: [{
|
||||
tabs: [{
|
||||
entries: [{ url: "about:home" }],
|
||||
hidden: true,
|
||||
extData: {"tabview-tab": '{"url":"about:home","groupID":1,"bounds":{"left":20,"top":20,"width":20,"height":20}}'}
|
||||
},{
|
||||
entries: [{ url: "about:home" }],
|
||||
hidden: false,
|
||||
extData: {"tabview-tab": '{"url":"about:home","groupID":2,"bounds":{"left":20,"top":20,"width":20,"height":20}}'},
|
||||
}],
|
||||
selected: 2,
|
||||
extData: {
|
||||
"tabview-groups": '{"nextID":3,"activeGroupId":2}',
|
||||
"tabview-group":
|
||||
'{"1":{"bounds":{"left":15,"top":5,"width":280,"height":232},"id":1},' +
|
||||
'"2":{"bounds":{"left":309,"top":5,"width":267,"height":226},"id":2}}'
|
||||
}
|
||||
}]
|
||||
};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
newWindowWithState(state, function (win) {
|
||||
registerCleanupFunction(function () win.close());
|
||||
|
||||
is(win.gBrowser.tabs.length, 2, "two tabs");
|
||||
|
||||
let opts = {animate: true, byMouse: true};
|
||||
win.gBrowser.removeTab(win.gBrowser.visibleTabs[0], opts);
|
||||
|
||||
let checkTabCount = function () {
|
||||
if (win.gBrowser.tabs.length > 1) {
|
||||
executeSoon(checkTabCount);
|
||||
return;
|
||||
}
|
||||
|
||||
is(win.gBrowser.tabs.length, 1, "one tab");
|
||||
|
||||
showTabView(function () {
|
||||
let cw = win.TabView.getContentWindow();
|
||||
is(cw.TabItems.items.length, 1, "one tabItem");
|
||||
|
||||
waitForFocus(finish);
|
||||
}, win);
|
||||
};
|
||||
|
||||
checkTabCount();
|
||||
});
|
||||
}
|
100
browser/base/content/test/tabview/browser_tabview_bug650573.js
Normal file
100
browser/base/content/test/tabview/browser_tabview_bug650573.js
Normal file
@ -0,0 +1,100 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
let ss = Cc["@mozilla.org/browser/sessionstore;1"].getService(Ci.nsISessionStore);
|
||||
let stateBackup = ss.getBrowserState();
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
ss.setBrowserState(stateBackup);
|
||||
});
|
||||
|
||||
TabView._initFrame(function() {
|
||||
executeSoon(testRestoreNormal);
|
||||
});
|
||||
}
|
||||
|
||||
function testRestoreNormal() {
|
||||
testRestore("normal", function () {
|
||||
waitForBrowserState(JSON.parse(stateBackup), testRestorePinned);
|
||||
});
|
||||
}
|
||||
|
||||
function testRestorePinned() {
|
||||
gBrowser.loadOneTab("about:blank", {inBackground: true});
|
||||
gBrowser.pinTab(gBrowser.tabs[0]);
|
||||
|
||||
testRestore("pinned", function () {
|
||||
waitForBrowserState(JSON.parse(stateBackup), testRestoreHidden);
|
||||
});
|
||||
}
|
||||
|
||||
function testRestoreHidden() {
|
||||
let groupItem = createGroupItemWithBlankTabs(window, 20, 20, 20, 1);
|
||||
let tabItem = groupItem.getChild(0);
|
||||
|
||||
hideGroupItem(groupItem, function () {
|
||||
testRestore("hidden", function () {
|
||||
isnot(tabItem.container.style.display, "none", "tabItem is visible");
|
||||
waitForFocus(finish);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testRestore(prefix, callback) {
|
||||
waitForBrowserState(createBrowserState(), function () {
|
||||
is(gBrowser.tabs.length, 2, prefix + ": two tabs restored");
|
||||
|
||||
let cw = TabView.getContentWindow();
|
||||
is(cw.GroupItems.groupItems.length, 2, prefix + ": we have two groupItems");
|
||||
|
||||
let [groupItem1, groupItem2] = cw.GroupItems.groupItems;
|
||||
is(groupItem1.id, "1st-group-id", prefix + ": groupItem1's ID is valid");
|
||||
is(groupItem1.getChildren().length, 1, prefix + ": groupItem1 has one child");
|
||||
|
||||
is(groupItem2.id, "2nd-group-id", prefix + ": groupItem2's ID is valid");
|
||||
is(groupItem2.getChildren().length, 1, prefix + ": groupItem2 has one child");
|
||||
|
||||
callback();
|
||||
});
|
||||
}
|
||||
|
||||
function waitForBrowserState(state, callback) {
|
||||
window.addEventListener("SSWindowStateReady", function onReady() {
|
||||
window.removeEventListener("SSWindowStateReady", onReady, false);
|
||||
executeSoon(callback);
|
||||
}, false);
|
||||
|
||||
ss.setBrowserState(JSON.stringify(state));
|
||||
}
|
||||
|
||||
function createBrowserState() {
|
||||
let bounds = {left: 20, top: 20, width: 20, height: 20};
|
||||
|
||||
let tabViewGroups = {nextID: 99, activeGroupId: 1};
|
||||
let tabViewGroup = {
|
||||
"1st-group-id": {bounds: bounds, title: "new group 1", id: "1st-group-id"},
|
||||
"2nd-group-id": {bounds: bounds, title: "new group 2", id: "2nd-group-id"}
|
||||
};
|
||||
|
||||
let tab1Data = {bounds: bounds, url: "about:robots", groupID: "2nd-group-id"};
|
||||
let tab1 = {
|
||||
entries: [{url: "about:robots"}],
|
||||
extData: {"tabview-tab": JSON.stringify(tab1Data)}
|
||||
};
|
||||
|
||||
let tab2Data = {bounds: bounds, url: "about:mozilla", groupID: "1st-group-id"};
|
||||
let tab2 = {
|
||||
entries: [{url: "about:mozilla"}],
|
||||
extData: {"tabview-tab": JSON.stringify(tab2Data)}
|
||||
};
|
||||
|
||||
return {windows: [{
|
||||
tabs: [tab1, tab2],
|
||||
selected: 1,
|
||||
extData: {"tabview-groups": JSON.stringify(tabViewGroups),
|
||||
"tabview-group": JSON.stringify(tabViewGroup)}
|
||||
}]};
|
||||
}
|
141
browser/base/content/test/tabview/browser_tabview_bug656778.js
Normal file
141
browser/base/content/test/tabview/browser_tabview_bug656778.js
Normal file
@ -0,0 +1,141 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref(TabView.PREF_FIRST_RUN);
|
||||
Services.prefs.clearUserPref(TabView.PREF_STARTUP_PAGE);
|
||||
Services.prefs.clearUserPref(TabView.PREF_RESTORE_ENABLED_ONCE);
|
||||
});
|
||||
|
||||
let assertBoolPref = function (pref, value) {
|
||||
is(Services.prefs.getBoolPref(pref), value, pref + " is " + value);
|
||||
};
|
||||
|
||||
let assertIntPref = function (pref, value) {
|
||||
is(Services.prefs.getIntPref(pref), value, pref + " is " + value);
|
||||
};
|
||||
|
||||
let setPreferences = function (startupPage, firstRun, enabledOnce) {
|
||||
Services.prefs.setIntPref(TabView.PREF_STARTUP_PAGE, startupPage);
|
||||
Services.prefs.setBoolPref(TabView.PREF_FIRST_RUN, firstRun);
|
||||
Services.prefs.setBoolPref(TabView.PREF_RESTORE_ENABLED_ONCE, enabledOnce);
|
||||
};
|
||||
|
||||
let assertPreferences = function (startupPage, firstRun, enabledOnce) {
|
||||
assertIntPref(TabView.PREF_STARTUP_PAGE, startupPage);
|
||||
assertBoolPref(TabView.PREF_FIRST_RUN, firstRun);
|
||||
assertBoolPref(TabView.PREF_RESTORE_ENABLED_ONCE, enabledOnce);
|
||||
};
|
||||
|
||||
let next = function () {
|
||||
if (tests.length == 0) {
|
||||
waitForFocus(finish);
|
||||
return;
|
||||
}
|
||||
|
||||
let test = tests.shift();
|
||||
info("running " + test.name + "...");
|
||||
test();
|
||||
};
|
||||
|
||||
// State:
|
||||
// Panorama was already used before (firstUseExperienced = true) but session
|
||||
// restore is deactivated. We did not automatically enable SR, yet.
|
||||
//
|
||||
// Expected result:
|
||||
// When entering Panorma session restore will be enabled and a notification
|
||||
// banner is shown.
|
||||
let test1 = function test1() {
|
||||
setPreferences(1, true, false);
|
||||
|
||||
newWindowWithTabView(function (win) {
|
||||
assertPreferences(3, true, true);
|
||||
|
||||
win.close();
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
// State:
|
||||
// Panorama has not been used before (firstUseExperienced = false) and session
|
||||
// restore is deactivated. We did not automatically enable SR, yet. That state
|
||||
// is equal to starting the browser the first time.
|
||||
//
|
||||
// Expected result:
|
||||
// When entering Panorma nothing happens. When we detect that Panorama is
|
||||
// really used (firstUseExperienced = true) we notify that session restore
|
||||
// is now enabled.
|
||||
let test2 = function test2() {
|
||||
setPreferences(1, false, false);
|
||||
|
||||
newWindowWithTabView(function (win) {
|
||||
assertPreferences(1, false, false);
|
||||
|
||||
win.TabView.firstUseExperienced = true;
|
||||
|
||||
assertPreferences(3, true, true);
|
||||
|
||||
win.close();
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
// State:
|
||||
// Panorama was already used before (firstUseExperienced = true) and session
|
||||
// restore is activated. We did not automatically enable SR, yet.
|
||||
//
|
||||
// Expected result:
|
||||
// When entering Panorama nothing happens because session store is already
|
||||
// enabled so there's no reason to notify.
|
||||
let test3 = function test3() {
|
||||
setPreferences(3, true, false);
|
||||
|
||||
newWindowWithTabView(function (win) {
|
||||
assertPreferences(3, true, true);
|
||||
|
||||
win.close();
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
// State:
|
||||
// Panorama was already used before (firstUseExperienced = true) and session
|
||||
// restore has been automatically activated.
|
||||
//
|
||||
// Expected result:
|
||||
// When entering Panorama nothing happens.
|
||||
let test4 = function test4() {
|
||||
setPreferences(3, true, true);
|
||||
|
||||
newWindowWithTabView(function (win) {
|
||||
assertPreferences(3, true, true);
|
||||
|
||||
win.close();
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
// State:
|
||||
// Panorama was already used before (firstUseExperienced = true) and session
|
||||
// restore has been automatically activated. Session store was afterwards
|
||||
// disabled by the user so we won't touch that again.
|
||||
//
|
||||
// Expected result:
|
||||
// When entering Panorama nothing happens and we didn't enable session restore.
|
||||
let test5 = function test5() {
|
||||
setPreferences(1, true, true);
|
||||
|
||||
newWindowWithTabView(function (win) {
|
||||
assertPreferences(1, true, true);
|
||||
|
||||
win.close();
|
||||
next();
|
||||
});
|
||||
};
|
||||
|
||||
let tests = [test1, test2, test3, test4, test5];
|
||||
next();
|
||||
}
|
@ -93,9 +93,13 @@ function newWindowWithTabView(shownCallback, loadCallback, width, height) {
|
||||
|
||||
// ----------
|
||||
function afterAllTabsLoaded(callback, win) {
|
||||
const TAB_STATE_NEEDS_RESTORE = 1;
|
||||
|
||||
win = win || window;
|
||||
|
||||
let stillToLoad = 0;
|
||||
let restoreHiddenTabs = Services.prefs.getBoolPref(
|
||||
"browser.sessionstore.restore_hidden_tabs");
|
||||
|
||||
function onLoad() {
|
||||
this.removeEventListener("load", onLoad, true);
|
||||
@ -105,8 +109,14 @@ function afterAllTabsLoaded(callback, win) {
|
||||
}
|
||||
|
||||
for (let a = 0; a < win.gBrowser.tabs.length; a++) {
|
||||
let browser = win.gBrowser.tabs[a].linkedBrowser;
|
||||
if (browser.contentDocument.readyState != "complete" ||
|
||||
let tab = win.gBrowser.tabs[a];
|
||||
let browser = tab.linkedBrowser;
|
||||
|
||||
let isRestorable = !(tab.hidden && !restoreHiddenTabs &&
|
||||
browser.__SS_restoreState &&
|
||||
browser.__SS_restoreState == TAB_STATE_NEEDS_RESTORE);
|
||||
|
||||
if (isRestorable && browser.contentDocument.readyState != "complete" ||
|
||||
browser.webProgress.isLoadingDocument) {
|
||||
stillToLoad++;
|
||||
browser.addEventListener("load", onLoad, true);
|
||||
@ -114,7 +124,7 @@ function afterAllTabsLoaded(callback, win) {
|
||||
}
|
||||
|
||||
if (!stillToLoad)
|
||||
callback();
|
||||
executeSoon(callback);
|
||||
}
|
||||
|
||||
// ----------
|
||||
@ -261,3 +271,33 @@ function unhideGroupItem(groupItem, callback) {
|
||||
});
|
||||
groupItem._unhide();
|
||||
}
|
||||
|
||||
// ----------
|
||||
function whenWindowLoaded(win, callback) {
|
||||
win.addEventListener("load", function onLoad() {
|
||||
win.removeEventListener("load", onLoad, false);
|
||||
executeSoon(callback);
|
||||
}, false);
|
||||
}
|
||||
|
||||
// ----------
|
||||
function whenWindowStateReady(win, callback) {
|
||||
win.addEventListener("SSWindowStateReady", function onReady() {
|
||||
win.removeEventListener("SSWindowStateReady", onReady, false);
|
||||
executeSoon(callback);
|
||||
}, false);
|
||||
}
|
||||
|
||||
// ----------
|
||||
function newWindowWithState(state, callback) {
|
||||
let opts = "chrome,all,dialog=no,height=800,width=800";
|
||||
let win = window.openDialog(getBrowserURL(), "_blank", opts);
|
||||
|
||||
whenWindowLoaded(win, function () {
|
||||
ss.setWindowState(win, JSON.stringify(state), true);
|
||||
});
|
||||
|
||||
whenWindowStateReady(win, function () {
|
||||
afterAllTabsLoaded(function () callback(win), win);
|
||||
});
|
||||
}
|
||||
|
@ -316,9 +316,13 @@
|
||||
allowThirdPartyFixup: true});
|
||||
aTriggeringEvent.preventDefault();
|
||||
aTriggeringEvent.stopPropagation();
|
||||
} else {
|
||||
// Pass LOAD_FLAGS_DISALLOW_INHERIT_OWNER to prevent any loads from
|
||||
// inheriting the currently loaded document's principal.
|
||||
let flags = Ci.nsIWebNavigation.LOAD_FLAGS_ALLOW_THIRD_PARTY_FIXUP |
|
||||
Ci.nsIWebNavigation.LOAD_FLAGS_DISALLOW_INHERIT_OWNER;
|
||||
gBrowser.loadURIWithFlags(url, flags, null, null, postData);
|
||||
}
|
||||
else
|
||||
loadURI(url, null, postData, true /* allow third party fixup */);
|
||||
|
||||
gBrowser.selectedBrowser.focus();
|
||||
]]></body>
|
||||
|
@ -103,6 +103,8 @@ static RedirEntry kRedirMap[] = {
|
||||
{ "home", "chrome://browser/content/aboutHome.xhtml",
|
||||
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
|
||||
nsIAboutModule::ALLOW_SCRIPT },
|
||||
{ "permissions", "chrome://browser/content/preferences/aboutPermissions.xul",
|
||||
nsIAboutModule::ALLOW_SCRIPT },
|
||||
};
|
||||
static const int kRedirTotal = NS_ARRAY_LENGTH(kRedirMap);
|
||||
|
||||
|
@ -46,33 +46,14 @@
|
||||
#ifdef XP_MACOSX
|
||||
#define NS_SAFARIPROFILEMIGRATOR_CID \
|
||||
{ 0x29e3b139, 0xad19, 0x44f3, { 0xb2, 0xc2, 0xe9, 0xf1, 0x3b, 0xa2, 0xbb, 0xc6 } }
|
||||
|
||||
#define NS_MACIEPROFILEMIGRATOR_CID \
|
||||
{ 0xf1a4e549, 0x5c4b, 0x41ff, { 0xb5, 0xe3, 0xeb, 0x87, 0xae, 0x31, 0x41, 0x9b } }
|
||||
|
||||
#define NS_OMNIWEBPROFILEMIGRATOR_CID \
|
||||
{ 0xb80ae6d8, 0x766c, 0x43da, { 0x9c, 0x7a, 0xd, 0x82, 0x44, 0x52, 0x61, 0x6a } }
|
||||
|
||||
#define NS_CAMINOPROFILEMIGRATOR_CID \
|
||||
{ 0x01d88ea9, 0x0feb, 0x495e, { 0x8c, 0x9b, 0x41, 0x65, 0x99, 0x55, 0x52, 0x65 } }
|
||||
|
||||
#define NS_ICABPROFILEMIGRATOR_CID \
|
||||
{ 0xf394a036, 0xc5e1, 0x46d8, { 0x99, 0x39, 0x6b, 0x35, 0xe1, 0x13, 0x0a, 0x27 } }
|
||||
|
||||
#endif
|
||||
|
||||
#define NS_OPERAPROFILEMIGRATOR_CID \
|
||||
{ 0xf34ff792, 0x722e, 0x4490, { 0xb1, 0x95, 0x47, 0xd2, 0x42, 0xed, 0xca, 0x1c } }
|
||||
|
||||
#define NS_DOGBERTPROFILEMIGRATOR_CID \
|
||||
{ 0x24f92fae, 0xf793, 0x473b, { 0x80, 0x61, 0x71, 0x34, 0x8, 0xbd, 0x11, 0xd5 } }
|
||||
|
||||
#define NS_SEAMONKEYPROFILEMIGRATOR_CID \
|
||||
{ 0x9a28ffa7, 0xe6ef, 0x4b52, { 0xa1, 0x27, 0x6a, 0xd9, 0x51, 0xde, 0x8e, 0x9b } }
|
||||
|
||||
#define NS_PHOENIXPROFILEMIGRATOR_CID \
|
||||
{ 0x78481e4a, 0x50e4, 0x4489, { 0xb6, 0x8a, 0xef, 0x82, 0x67, 0xe, 0xd6, 0x3f } }
|
||||
|
||||
#define NS_SHELLSERVICE_CID \
|
||||
{ 0x63c7b9f4, 0xcc8, 0x43f8, { 0xb6, 0x66, 0xa, 0x66, 0x16, 0x55, 0xcb, 0x73 } }
|
||||
|
||||
|
@ -50,20 +50,14 @@
|
||||
#endif
|
||||
|
||||
#include "nsProfileMigrator.h"
|
||||
#include "nsDogbertProfileMigrator.h"
|
||||
#if !defined(XP_OS2)
|
||||
#include "nsOperaProfileMigrator.h"
|
||||
#endif
|
||||
#include "nsPhoenixProfileMigrator.h"
|
||||
#include "nsSeamonkeyProfileMigrator.h"
|
||||
#if defined(XP_WIN) && !defined(__MINGW32__)
|
||||
#include "nsIEProfileMigrator.h"
|
||||
#elif defined(XP_MACOSX)
|
||||
#include "nsSafariProfileMigrator.h"
|
||||
#include "nsOmniWebProfileMigrator.h"
|
||||
#include "nsMacIEProfileMigrator.h"
|
||||
#include "nsCaminoProfileMigrator.h"
|
||||
#include "nsICabProfileMigrator.h"
|
||||
#endif
|
||||
|
||||
#include "rdf.h"
|
||||
@ -87,21 +81,15 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacShellService)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init)
|
||||
#endif
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsDogbertProfileMigrator)
|
||||
#if !defined(XP_OS2)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsOperaProfileMigrator)
|
||||
#endif
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsPhoenixProfileMigrator)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsProfileMigrator)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSeamonkeyProfileMigrator)
|
||||
#if defined(XP_WIN) && !defined(__MINGW32__)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsIEProfileMigrator)
|
||||
#elif defined(XP_MACOSX)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsSafariProfileMigrator)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsOmniWebProfileMigrator)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMacIEProfileMigrator)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCaminoProfileMigrator)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsICabProfileMigrator)
|
||||
#endif
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsFeedSniffer)
|
||||
@ -122,16 +110,10 @@ NS_DEFINE_NAMED_CID(NS_WINIEPROFILEMIGRATOR_CID);
|
||||
#elif defined(XP_MACOSX)
|
||||
NS_DEFINE_NAMED_CID(NS_SHELLSERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_SAFARIPROFILEMIGRATOR_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_MACIEPROFILEMIGRATOR_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_OMNIWEBPROFILEMIGRATOR_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_CAMINOPROFILEMIGRATOR_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_ICABPROFILEMIGRATOR_CID);
|
||||
#endif
|
||||
#if !defined(XP_OS2)
|
||||
NS_DEFINE_NAMED_CID(NS_OPERAPROFILEMIGRATOR_CID);
|
||||
#endif
|
||||
NS_DEFINE_NAMED_CID(NS_DOGBERTPROFILEMIGRATOR_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_PHOENIXPROFILEMIGRATOR_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_SEAMONKEYPROFILEMIGRATOR_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID);
|
||||
|
||||
@ -150,16 +132,10 @@ static const mozilla::Module::CIDEntry kBrowserCIDs[] = {
|
||||
#elif defined(XP_MACOSX)
|
||||
{ &kNS_SHELLSERVICE_CID, false, NULL, nsMacShellServiceConstructor },
|
||||
{ &kNS_SAFARIPROFILEMIGRATOR_CID, false, NULL, nsSafariProfileMigratorConstructor },
|
||||
{ &kNS_MACIEPROFILEMIGRATOR_CID, false, NULL, nsMacIEProfileMigratorConstructor },
|
||||
{ &kNS_OMNIWEBPROFILEMIGRATOR_CID, false, NULL, nsOmniWebProfileMigratorConstructor },
|
||||
{ &kNS_CAMINOPROFILEMIGRATOR_CID, false, NULL, nsCaminoProfileMigratorConstructor },
|
||||
{ &kNS_ICABPROFILEMIGRATOR_CID, false, NULL, nsICabProfileMigratorConstructor },
|
||||
#endif
|
||||
#if !defined(XP_OS2)
|
||||
{ &kNS_OPERAPROFILEMIGRATOR_CID, false, NULL, nsOperaProfileMigratorConstructor },
|
||||
#endif
|
||||
{ &kNS_DOGBERTPROFILEMIGRATOR_CID, false, NULL, nsDogbertProfileMigratorConstructor },
|
||||
{ &kNS_PHOENIXPROFILEMIGRATOR_CID, false, NULL, nsPhoenixProfileMigratorConstructor },
|
||||
{ &kNS_SEAMONKEYPROFILEMIGRATOR_CID, false, NULL, nsSeamonkeyProfileMigratorConstructor },
|
||||
{ &kNS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID, false, NULL, nsPrivateBrowsingServiceWrapperConstructor },
|
||||
{ NULL }
|
||||
@ -186,22 +162,17 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "sync-tabs", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
#endif
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "home", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "permissions", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
|
||||
{ NS_PROFILEMIGRATOR_CONTRACTID, &kNS_FIREFOX_PROFILEMIGRATOR_CID },
|
||||
#if defined(XP_WIN) && !defined(__MINGW32__)
|
||||
{ NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "ie", &kNS_WINIEPROFILEMIGRATOR_CID },
|
||||
#elif defined(XP_MACOSX)
|
||||
{ NS_SHELLSERVICE_CONTRACTID, &kNS_SHELLSERVICE_CID },
|
||||
{ NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "safari", &kNS_SAFARIPROFILEMIGRATOR_CID },
|
||||
{ NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "macie", &kNS_MACIEPROFILEMIGRATOR_CID },
|
||||
{ NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "omniweb", &kNS_OMNIWEBPROFILEMIGRATOR_CID },
|
||||
{ NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "camino", &kNS_CAMINOPROFILEMIGRATOR_CID },
|
||||
{ NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "icab", &kNS_ICABPROFILEMIGRATOR_CID },
|
||||
#endif
|
||||
#if !defined(XP_OS2)
|
||||
{ NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "opera", &kNS_OPERAPROFILEMIGRATOR_CID },
|
||||
#endif
|
||||
{ NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "dogbert", &kNS_DOGBERTPROFILEMIGRATOR_CID },
|
||||
{ NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "phoenix", &kNS_PHOENIXPROFILEMIGRATOR_CID },
|
||||
{ NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "seamonkey", &kNS_SEAMONKEYPROFILEMIGRATOR_CID },
|
||||
{ NS_PRIVATE_BROWSING_SERVICE_CONTRACTID, &kNS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID },
|
||||
{ NULL }
|
||||
|
6
browser/components/dirprovider/tests/unit/xpcshell.ini
Normal file
6
browser/components/dirprovider/tests/unit/xpcshell.ini
Normal file
@ -0,0 +1,6 @@
|
||||
[DEFAULT]
|
||||
head = head_dirprovider.js
|
||||
tail =
|
||||
|
||||
[test_bookmark_pref.js]
|
||||
[test_keys.js]
|
5
browser/components/feeds/test/unit/xpcshell.ini
Normal file
5
browser/components/feeds/test/unit/xpcshell.ini
Normal file
@ -0,0 +1,5 @@
|
||||
[DEFAULT]
|
||||
head = head_feeds.js
|
||||
tail =
|
||||
|
||||
[test_355473.js]
|
@ -128,8 +128,7 @@ var MigrationWizard = {
|
||||
return;
|
||||
}
|
||||
|
||||
if (migrator.sourceExists &&
|
||||
!(suffix == "phoenix" && !this._autoMigrate)) {
|
||||
if (migrator.sourceExists) {
|
||||
// Save this as the first selectable item, if we don't already have
|
||||
// one, or if it is the migrator that was passed to us.
|
||||
if (!selectedMigrator || this._source == suffix)
|
||||
@ -333,15 +332,11 @@ var MigrationWizard = {
|
||||
var source = null;
|
||||
switch (this._source) {
|
||||
case "ie":
|
||||
case "macie":
|
||||
source = "sourceNameIE";
|
||||
break;
|
||||
case "opera":
|
||||
source = "sourceNameOpera";
|
||||
break;
|
||||
case "dogbert":
|
||||
source = "sourceNameDogbert";
|
||||
break;
|
||||
case "safari":
|
||||
source = "sourceNameSafari";
|
||||
break;
|
||||
|
@ -68,43 +68,21 @@
|
||||
<!-- If you are adding a migrator, please add the appropriate
|
||||
hooks to GetDefaultBrowserMigratorKey in
|
||||
browser/components/migration/src/nsProfileMigrator.cpp -->
|
||||
<radio id="phoenix" label="&importFromPhoenix.label;" accesskey="&importFromPhoenix.accesskey;"/>
|
||||
#ifdef XP_UNIX
|
||||
#ifdef XP_MACOSX
|
||||
<radio id="safari" label="&importFromSafari.label;" accesskey="&importFromSafari.accesskey;"/>
|
||||
<radio id="macie" label="&importFromIE.label;" accesskey="&importFromIE.accesskey;"/>
|
||||
<!-- XXXben - uncomment these as we write migrators for them
|
||||
<radio id="camino" label="&importFromCamino.label;" accesskey="&importFromCamino.accesskey;"/>
|
||||
<radio id="omniweb" label="&importFromOmniWeb.label;" accesskey="&importFromOmniWeb.accesskey;"/>
|
||||
<radio id="icab" label="&importFromICab.label;" accesskey="&importFromICab.accesskey;"/>
|
||||
-->
|
||||
<radio id="seamonkey" label="&importFromSeamonkey.label;" accesskey="&importFromSeamonkey.accesskey;"/>
|
||||
<radio id="dogbert" label="&importFromNetscape4.label;" accesskey="&importFromNetscape4.accesskey;"/>
|
||||
<radio id="opera" label="&importFromOpera.label;" accesskey="&importFromOpera.accesskey;"/>
|
||||
#else
|
||||
#elifdef XP_UNIX
|
||||
<radio id="seamonkey" label="&importFromSeamonkey.label;" accesskey="&importFromSeamonkey.accesskey;"/>
|
||||
<radio id="dogbert" label="&importFromNetscape4.label;" accesskey="&importFromNetscape4.accesskey;"/>
|
||||
<radio id="opera" label="&importFromOpera.label;" accesskey="&importFromOpera.accesskey;"/>
|
||||
<!-- XXXben - uncomment these as we write migrators for them
|
||||
<radio id="konqueror" label="&importFromKonqueror.label;" accesskey="&importFromKonqueror.accesskey;"/>
|
||||
<radio id="epiphany" label="&importFromEpiphany.label;" accesskey="&importFromEpiphany.accesskey;"/>
|
||||
<radio id="galeon" label="&importFromGaleon.label;" accesskey="&importFromGaleon.accesskey;"/>
|
||||
-->
|
||||
#endif
|
||||
#endif
|
||||
#ifdef XP_WIN
|
||||
#elifdef XP_WIN
|
||||
#ifndef NO_IE_MIGRATOR
|
||||
<radio id="ie" label="&importFromIE.label;" accesskey="&importFromIE.accesskey;"/>
|
||||
#endif
|
||||
<radio id="seamonkey" label="&importFromSeamonkey.label;" accesskey="&importFromSeamonkey.accesskey;"/>
|
||||
<radio id="dogbert" label="&importFromNetscape4.label;" accesskey="&importFromNetscape4.accesskey;"/>
|
||||
<radio id="opera" label="&importFromOpera.label;" accesskey="&importFromOpera.accesskey;"/>
|
||||
#endif
|
||||
#ifndef XP_UNIX
|
||||
#ifndef XP_WIN
|
||||
#else
|
||||
<radio id="seamonkey" label="&importFromSeamonkey.label;" accesskey="&importFromSeamonkey.accesskey;"/>
|
||||
<radio id="dogbert" label="&importFromNetscape4.label;" accesskey="&importFromNetscape4.accesskey;"/>
|
||||
#endif
|
||||
#endif
|
||||
<radio id="fromfile" label="&importFromHTMLFile.label;" accesskey="&importFromHTMLFile.accesskey;" hidden="true"/>
|
||||
<radio id="nothing" label="&importFromNothing.label;" accesskey="&importFromNothing.accesskey;" hidden="true"/>
|
||||
|
@ -54,8 +54,6 @@ CPPSRCS = nsProfileMigrator.cpp \
|
||||
nsBrowserProfileMigratorUtils.cpp \
|
||||
nsNetscapeProfileMigratorBase.cpp \
|
||||
nsSeamonkeyProfileMigrator.cpp \
|
||||
nsPhoenixProfileMigrator.cpp \
|
||||
nsDogbertProfileMigrator.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifneq ($(OS_ARCH),OS2)
|
||||
@ -69,10 +67,6 @@ endif
|
||||
|
||||
ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||
CPPSRCS += nsSafariProfileMigrator.cpp \
|
||||
nsMacIEProfileMigrator.cpp \
|
||||
nsOmniWebProfileMigrator.cpp \
|
||||
nsCaminoProfileMigrator.cpp \
|
||||
nsICabProfileMigrator.cpp \
|
||||
$(NULL)
|
||||
endif
|
||||
|
||||
|
@ -1,115 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** 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 The Browser Profile Migrator.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ben Goodger.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@bengoodger.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 ***** */
|
||||
|
||||
#include "nsBrowserProfileMigratorUtils.h"
|
||||
#include "nsCaminoProfileMigrator.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIProfileMigrator.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsCaminoProfileMigrator
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsCaminoProfileMigrator, nsIBrowserProfileMigrator)
|
||||
|
||||
nsCaminoProfileMigrator::nsCaminoProfileMigrator()
|
||||
{
|
||||
mObserverService = do_GetService("@mozilla.org/observer-service;1");
|
||||
}
|
||||
|
||||
nsCaminoProfileMigrator::~nsCaminoProfileMigrator()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsIBrowserProfileMigrator
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCaminoProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup, const PRUnichar* aProfile)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);
|
||||
|
||||
NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCaminoProfileMigrator::GetMigrateData(const PRUnichar* aProfile,
|
||||
PRBool aReplace,
|
||||
PRUint16* aResult)
|
||||
{
|
||||
*aResult = 0; // XXXben implement me
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCaminoProfileMigrator::GetSourceExists(PRBool* aResult)
|
||||
{
|
||||
*aResult = PR_FALSE; // XXXben implement me
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCaminoProfileMigrator::GetSourceHasMultipleProfiles(PRBool* aResult)
|
||||
{
|
||||
*aResult = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCaminoProfileMigrator::GetSourceProfiles(nsISupportsArray** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCaminoProfileMigrator::GetSourceHomePageURL(nsACString& aResult)
|
||||
{
|
||||
aResult.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsCaminoProfileMigrator
|
||||
|
@ -1,672 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** 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 The Browser Profile Migrator.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ben Goodger.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@bengoodger.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 ***** */
|
||||
|
||||
#include "nsAppDirectoryServiceDefs.h"
|
||||
#include "nsBrowserProfileMigratorUtils.h"
|
||||
#include "nsDogbertProfileMigrator.h"
|
||||
#include "nsICookieManager2.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsIInputStream.h"
|
||||
#include "nsILineInputStream.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefLocalizedString.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "prprf.h"
|
||||
#include "prenv.h"
|
||||
#include "NSReg.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include <stdlib.h>
|
||||
#include <limits.h>
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
#ifdef PATH_MAX
|
||||
#define MAXPATHLEN PATH_MAX
|
||||
#elif defined(_MAX_PATH)
|
||||
#define MAXPATHLEN _MAX_PATH
|
||||
#elif defined(CCHMAXPATH)
|
||||
#define MAXPATHLEN CCHMAXPATH
|
||||
#else
|
||||
#define MAXPATHLEN 1024
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define PREF_FILE_HEADER_STRING "# Mozilla User Preferences "
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
#define OLDREG_NAME "Netscape Registry"
|
||||
#define OLDREG_DIR NS_MAC_PREFS_DIR
|
||||
#define PREF_FILE_NAME_IN_4x NS_LITERAL_STRING("Netscape Preferences")
|
||||
#define COOKIES_FILE_NAME_IN_4x NS_LITERAL_STRING("MagicCookie")
|
||||
#define BOOKMARKS_FILE_NAME_IN_4x NS_LITERAL_STRING("Bookmarks.html")
|
||||
#define SECURITY_PATH "Security"
|
||||
#define PSM_CERT7_DB NS_LITERAL_STRING("Certificates7")
|
||||
#define PSM_KEY3_DB NS_LITERAL_STRING("Key Database3")
|
||||
#define PSM_SECMODULE_DB NS_LITERAL_STRING("Security Modules")
|
||||
|
||||
#elif defined(XP_WIN) || defined(XP_OS2)
|
||||
#define OLDREG_NAME "nsreg.dat"
|
||||
#ifdef XP_WIN
|
||||
#define OLDREG_DIR NS_WIN_WINDOWS_DIR
|
||||
#else
|
||||
#define OLDREG_DIR NS_OS2_DIR
|
||||
#endif
|
||||
#define PREF_FILE_NAME_IN_4x NS_LITERAL_STRING("prefs.js")
|
||||
#define COOKIES_FILE_NAME_IN_4x NS_LITERAL_STRING("cookies.txt")
|
||||
#define BOOKMARKS_FILE_NAME_IN_4x NS_LITERAL_STRING("bookmark.htm")
|
||||
#define PSM_CERT7_DB NS_LITERAL_STRING("cert7.db")
|
||||
#define PSM_KEY3_DB NS_LITERAL_STRING("key3.db")
|
||||
#define PSM_SECMODULE_DB NS_LITERAL_STRING("secmod.db")
|
||||
|
||||
#elif defined(XP_UNIX)
|
||||
#define PREF_FILE_NAME_IN_4x NS_LITERAL_STRING("preferences.js")
|
||||
#define COOKIES_FILE_NAME_IN_4x NS_LITERAL_STRING("cookies")
|
||||
#define BOOKMARKS_FILE_NAME_IN_4x NS_LITERAL_STRING("bookmarks.html")
|
||||
#define PSM_CERT7_DB NS_LITERAL_STRING("cert7.db")
|
||||
#define PSM_KEY3_DB NS_LITERAL_STRING("key3.db")
|
||||
#define PSM_SECMODULE_DB NS_LITERAL_STRING("secmodule.db")
|
||||
#define HOME_ENVIRONMENT_VARIABLE "HOME"
|
||||
#define PROFILE_HOME_ENVIRONMENT_VARIABLE "PROFILE_HOME"
|
||||
#define DEFAULT_UNIX_PROFILE_NAME "default"
|
||||
#else
|
||||
#error No netscape4.x profile-migrator on this platform.
|
||||
#endif /* XP_UNIX */
|
||||
|
||||
#define COOKIES_FILE_NAME_IN_5x NS_LITERAL_STRING("cookies.txt")
|
||||
#define BOOKMARKS_FILE_NAME_IN_5x NS_LITERAL_STRING("bookmarks.html")
|
||||
#define PREF_FILE_NAME_IN_5x NS_LITERAL_STRING("prefs.js")
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsDogbertProfileMigrator
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsDogbertProfileMigrator, nsIBrowserProfileMigrator)
|
||||
|
||||
nsDogbertProfileMigrator::nsDogbertProfileMigrator()
|
||||
{
|
||||
mObserverService = do_GetService("@mozilla.org/observer-service;1");
|
||||
}
|
||||
|
||||
nsDogbertProfileMigrator::~nsDogbertProfileMigrator()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsIBrowserProfileMigrator
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDogbertProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup,
|
||||
const PRUnichar* aProfile)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
PRBool aReplace = aStartup ? PR_TRUE : PR_FALSE;
|
||||
|
||||
if (!mTargetProfile) {
|
||||
GetProfilePath(aStartup, mTargetProfile);
|
||||
if (!mTargetProfile) return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!mSourceProfile) {
|
||||
GetSourceProfile(aProfile);
|
||||
if (!mSourceProfile)
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);
|
||||
|
||||
COPY_DATA(CopyPreferences, aReplace, nsIBrowserProfileMigrator::SETTINGS);
|
||||
COPY_DATA(CopyCookies, aReplace, nsIBrowserProfileMigrator::COOKIES);
|
||||
COPY_DATA(CopyBookmarks, aReplace, nsIBrowserProfileMigrator::BOOKMARKS);
|
||||
|
||||
NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
// on win/mac/os2, NS4x uses a registry to determine profile locations
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(XP_OS2)
|
||||
void
|
||||
nsDogbertProfileMigrator::GetSourceProfile(const PRUnichar* aProfile)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCOMPtr<nsIFile> regFile;
|
||||
rv = NS_GetSpecialDirectory(OLDREG_DIR, getter_AddRefs(regFile));
|
||||
if (NS_FAILED(rv)) return;
|
||||
|
||||
regFile->AppendNative(NS_LITERAL_CSTRING(OLDREG_NAME));
|
||||
|
||||
nsCAutoString path;
|
||||
rv = regFile->GetNativePath(path);
|
||||
if (NS_FAILED(rv)) return;
|
||||
|
||||
if (NR_StartupRegistry())
|
||||
return;
|
||||
|
||||
HREG reg = nsnull;
|
||||
RKEY profile = nsnull;
|
||||
|
||||
if (NR_RegOpen(path.get(), ®))
|
||||
goto cleanup;
|
||||
|
||||
{
|
||||
// on macos, registry entries are UTF8 encoded
|
||||
NS_ConvertUTF16toUTF8 profileName(aProfile);
|
||||
|
||||
if (NR_RegGetKey(reg, ROOTKEY_USERS, profileName.get(), &profile))
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
char profilePath[MAXPATHLEN];
|
||||
if (NR_RegGetEntryString(reg, profile, "ProfileLocation", profilePath, MAXPATHLEN))
|
||||
goto cleanup;
|
||||
|
||||
mSourceProfile = do_CreateInstance("@mozilla.org/file/local;1");
|
||||
if (!mSourceProfile) goto cleanup;
|
||||
|
||||
{
|
||||
// the string is UTF8 encoded, which forces us to do some strange string-do
|
||||
rv = mSourceProfile->InitWithPath(NS_ConvertUTF8toUTF16(profilePath));
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
mSourceProfile = nsnull;
|
||||
|
||||
cleanup:
|
||||
if (reg)
|
||||
NR_RegClose(reg);
|
||||
NR_ShutdownRegistry();
|
||||
}
|
||||
#else
|
||||
|
||||
#endif
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDogbertProfileMigrator::GetMigrateData(const PRUnichar* aProfile,
|
||||
PRBool aReplace,
|
||||
PRUint16* aResult)
|
||||
{
|
||||
*aResult = 0;
|
||||
if (!mSourceProfile) {
|
||||
GetSourceProfile(aProfile);
|
||||
if (!mSourceProfile)
|
||||
return NS_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
MigrationData data[] = { { ToNewUnicode(PREF_FILE_NAME_IN_4x),
|
||||
nsIBrowserProfileMigrator::SETTINGS,
|
||||
PR_TRUE },
|
||||
{ ToNewUnicode(COOKIES_FILE_NAME_IN_4x),
|
||||
nsIBrowserProfileMigrator::COOKIES,
|
||||
PR_FALSE },
|
||||
{ ToNewUnicode(BOOKMARKS_FILE_NAME_IN_4x),
|
||||
nsIBrowserProfileMigrator::BOOKMARKS,
|
||||
PR_FALSE } };
|
||||
|
||||
// Frees file name strings allocated above.
|
||||
GetMigrateDataFromArray(data, sizeof(data)/sizeof(MigrationData),
|
||||
aReplace, mSourceProfile, aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDogbertProfileMigrator::GetSourceExists(PRBool* aResult)
|
||||
{
|
||||
nsCOMPtr<nsISupportsArray> profiles;
|
||||
GetSourceProfiles(getter_AddRefs(profiles));
|
||||
|
||||
if (profiles) {
|
||||
PRUint32 count;
|
||||
profiles->Count(&count);
|
||||
*aResult = count > 0;
|
||||
}
|
||||
else
|
||||
*aResult = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDogbertProfileMigrator::GetSourceHasMultipleProfiles(PRBool* aResult)
|
||||
{
|
||||
nsCOMPtr<nsISupportsArray> profiles;
|
||||
GetSourceProfiles(getter_AddRefs(profiles));
|
||||
|
||||
if (profiles) {
|
||||
PRUint32 count;
|
||||
profiles->Count(&count);
|
||||
*aResult = count > 1;
|
||||
}
|
||||
else
|
||||
*aResult = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_MACOSX)
|
||||
NS_IMETHODIMP
|
||||
nsDogbertProfileMigrator::GetSourceProfiles(nsISupportsArray** aResult)
|
||||
{
|
||||
if (!mProfiles) {
|
||||
nsresult rv;
|
||||
|
||||
mProfiles = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIFile> regFile;
|
||||
rv = NS_GetSpecialDirectory(OLDREG_DIR, getter_AddRefs(regFile));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
regFile->AppendNative(NS_LITERAL_CSTRING(OLDREG_NAME));
|
||||
|
||||
nsCAutoString path;
|
||||
rv = regFile->GetNativePath(path);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if (NR_StartupRegistry())
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
HREG reg = nsnull;
|
||||
REGENUM enumstate = 0;
|
||||
|
||||
if (NR_RegOpen(path.get(), ®)) {
|
||||
NR_ShutdownRegistry();
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
char profileName[MAXREGNAMELEN];
|
||||
while (!NR_RegEnumSubkeys(reg, ROOTKEY_USERS, &enumstate,
|
||||
profileName, MAXREGNAMELEN, REGENUM_CHILDREN)) {
|
||||
nsCOMPtr<nsISupportsString> nameString
|
||||
(do_CreateInstance("@mozilla.org/supports-string;1"));
|
||||
if (nameString) {
|
||||
nameString->SetData(NS_ConvertUTF8toUTF16(profileName));
|
||||
mProfiles->AppendElement(nameString);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aResult = mProfiles);
|
||||
return NS_OK;
|
||||
}
|
||||
#else // XP_UNIX
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDogbertProfileMigrator::GetSourceProfiles(nsISupportsArray** aResult)
|
||||
{
|
||||
nsresult rv;
|
||||
const char* profileDir = PR_GetEnv(PROFILE_HOME_ENVIRONMENT_VARIABLE);
|
||||
|
||||
if (!profileDir) {
|
||||
profileDir = PR_GetEnv(HOME_ENVIRONMENT_VARIABLE);
|
||||
}
|
||||
if (!profileDir) return NS_ERROR_FAILURE;
|
||||
|
||||
nsCAutoString profilePath(profileDir);
|
||||
profilePath += "/.netscape";
|
||||
|
||||
nsCOMPtr<nsILocalFile> profileFile;
|
||||
rv = NS_NewNativeLocalFile(profilePath, PR_TRUE, getter_AddRefs(profileFile));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIFile> prefFile;
|
||||
rv = profileFile->Clone(getter_AddRefs(prefFile));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
prefFile->AppendNative(NS_LITERAL_CSTRING("preferences.js"));
|
||||
|
||||
PRBool exists;
|
||||
rv = prefFile->Exists(&exists);
|
||||
if (NS_FAILED(rv) || !exists) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mSourceProfile = profileFile;
|
||||
|
||||
mProfiles = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsISupportsString> nameString
|
||||
(do_CreateInstance("@mozilla.org/supports-string;1"));
|
||||
if (!nameString) return NS_ERROR_FAILURE;
|
||||
|
||||
nameString->SetData(NS_LITERAL_STRING("Netscape 4.x"));
|
||||
mProfiles->AppendElement(nameString);
|
||||
NS_ADDREF(*aResult = mProfiles);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsDogbertProfileMigrator::GetSourceProfile(const PRUnichar* aProfile)
|
||||
{
|
||||
// if GetSourceProfiles didn't do its magic, we're screwed
|
||||
}
|
||||
#endif // GetSourceProfiles
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDogbertProfileMigrator::GetSourceHomePageURL(nsACString& aResult)
|
||||
{
|
||||
aResult.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsDogbertProfileMigrator
|
||||
#define F(a) nsDogbertProfileMigrator::a
|
||||
|
||||
static
|
||||
nsDogbertProfileMigrator::PrefTransform gTransforms[] = {
|
||||
// Simple Copy Prefs
|
||||
{ "browser.anchor_color", 0, F(GetString), F(SetString), PR_FALSE, { -1 } },
|
||||
{ "browser.visited_color", 0, F(GetString), F(SetString), PR_FALSE, { -1 } },
|
||||
{ "browser.startup.homepage", 0, F(GetString), F(SetString), PR_FALSE, { -1 } },
|
||||
{ "network.cookie.cookieBehavior", 0, F(GetInt), F(SetInt), PR_FALSE, { -1 } },
|
||||
{ "network.cookie.warnAboutCookies",0, F(GetBool), F(SetBool), PR_FALSE, { -1 } },
|
||||
{ "javascript.enabled", 0, F(GetBool), F(SetBool), PR_FALSE, { -1 } },
|
||||
{ "network.proxy.type", 0, F(GetInt), F(SetInt), PR_FALSE, { -1 } },
|
||||
{ "network.proxy.no_proxies_on", 0, F(GetString), F(SetString), PR_FALSE, { -1 } },
|
||||
{ "network.proxy.autoconfig_url", 0, F(GetString), F(SetString), PR_FALSE, { -1 } },
|
||||
{ "network.proxy.ftp", 0, F(GetString), F(SetString), PR_FALSE, { -1 } },
|
||||
{ "network.proxy.ftp_port", 0, F(GetInt), F(SetInt), PR_FALSE, { -1 } },
|
||||
{ "network.proxy.http", 0, F(GetString), F(SetString), PR_FALSE, { -1 } },
|
||||
{ "network.proxy.http_port", 0, F(GetInt), F(SetInt), PR_FALSE, { -1 } },
|
||||
{ "network.proxy.ssl", 0, F(GetString), F(SetString), PR_FALSE, { -1 } },
|
||||
{ "network.proxy.ssl_port", 0, F(GetInt), F(SetInt), PR_FALSE, { -1 } },
|
||||
|
||||
// Prefs with Different Names
|
||||
{ "network.hosts.socks_server", "network.proxy.socks", F(GetString), F(SetString), PR_FALSE, { -1 } },
|
||||
{ "network.hosts.socks_serverport", "network.proxy.socks_port", F(GetInt), F(SetInt), PR_FALSE, { -1 } },
|
||||
{ "browser.background_color", "browser.display.background_color", F(GetString), F(SetString), PR_FALSE, { -1 } },
|
||||
{ "browser.foreground_color", "browser.display.foreground_color", F(GetString), F(SetString), PR_FALSE, { -1 } },
|
||||
{ "browser.wfe.use_windows_colors", "browser.display.use_system_colors", F(GetBool), F(SetBool), PR_FALSE, { -1 } },
|
||||
{ "browser.use_document_colors", "browser.display.use_document_colors",F(GetBool), F(SetBool), PR_FALSE, { -1 } },
|
||||
{ "browser.use_document.fonts", "browser.display.use_document_fonts", F(GetInt), F(SetInt), PR_FALSE, { -1 } },
|
||||
{ "browser.startup.page", "browser.startup.homepage", F(GetHomepage), F(SetWStringFromASCII), PR_FALSE, { -1 } },
|
||||
{ "general.always_load_images", "permissions.default.image", F(GetImagePref),F(SetInt), PR_FALSE, { -1 } },
|
||||
};
|
||||
|
||||
nsresult
|
||||
nsDogbertProfileMigrator::TransformPreferences(const nsAString& aSourcePrefFileName,
|
||||
const nsAString& aTargetPrefFileName)
|
||||
{
|
||||
PrefTransform* transform;
|
||||
PrefTransform* end = gTransforms + sizeof(gTransforms)/sizeof(PrefTransform);
|
||||
|
||||
// Load the source pref file
|
||||
nsCOMPtr<nsIPrefService> psvc(do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
psvc->ResetPrefs();
|
||||
|
||||
nsCOMPtr<nsIFile> sourcePrefsFile;
|
||||
mSourceProfile->Clone(getter_AddRefs(sourcePrefsFile));
|
||||
sourcePrefsFile->Append(aSourcePrefFileName);
|
||||
psvc->ReadUserPrefs(sourcePrefsFile);
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> branch(do_QueryInterface(psvc));
|
||||
for (transform = gTransforms; transform < end; ++transform)
|
||||
transform->prefGetterFunc(transform, branch);
|
||||
|
||||
// Now that we have all the pref data in memory, load the target pref file,
|
||||
// and write it back out
|
||||
psvc->ResetPrefs();
|
||||
for (transform = gTransforms; transform < end; ++transform)
|
||||
transform->prefSetterFunc(transform, branch);
|
||||
|
||||
nsCOMPtr<nsIFile> targetPrefsFile;
|
||||
mTargetProfile->Clone(getter_AddRefs(targetPrefsFile));
|
||||
targetPrefsFile->Append(aTargetPrefFileName);
|
||||
psvc->SavePrefFile(targetPrefsFile);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDogbertProfileMigrator::CopyPreferences(PRBool aReplace)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (!aReplace)
|
||||
return rv;
|
||||
|
||||
// 1) Copy Preferences
|
||||
TransformPreferences(PREF_FILE_NAME_IN_4x, PREF_FILE_NAME_IN_5x);
|
||||
|
||||
// 2) Copy Certficates
|
||||
rv |= CopyFile(PSM_CERT7_DB, PSM_CERT7_DB);
|
||||
rv |= CopyFile(PSM_KEY3_DB, PSM_KEY3_DB);
|
||||
rv |= CopyFile(PSM_SECMODULE_DB, PSM_SECMODULE_DB);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDogbertProfileMigrator::GetHomepage(void* aTransform, nsIPrefBranch* aBranch)
|
||||
{
|
||||
PrefTransform* xform = (PrefTransform*)aTransform;
|
||||
PRInt32 val;
|
||||
nsresult rv = aBranch->GetIntPref(xform->sourcePrefName, &val);
|
||||
if (NS_SUCCEEDED(rv) && val == 0) {
|
||||
xform->stringValue = ToNewCString(NS_LITERAL_CSTRING("about:blank"));
|
||||
if (!xform->stringValue)
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
xform->prefHasValue = PR_TRUE;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDogbertProfileMigrator::GetImagePref(void* aTransform, nsIPrefBranch* aBranch)
|
||||
{
|
||||
PrefTransform* xform = (PrefTransform*)aTransform;
|
||||
PRBool loadImages;
|
||||
nsresult rv = aBranch->GetBoolPref(xform->sourcePrefName, &loadImages);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
xform->intValue = loadImages ? 1 : 2;
|
||||
xform->prefHasValue = PR_TRUE;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDogbertProfileMigrator::CopyCookies(PRBool aReplace)
|
||||
{
|
||||
nsresult rv;
|
||||
if (aReplace) {
|
||||
#ifdef NEED_TO_FIX_4X_COOKIES
|
||||
rv = CopyFile(COOKIES_FILE_NAME_IN_4x, COOKIES_FILE_NAME_IN_5x);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
rv = FixDogbertCookies();
|
||||
#else
|
||||
rv = CopyFile(COOKIES_FILE_NAME_IN_4x, COOKIES_FILE_NAME_IN_5x);
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
nsCOMPtr<nsICookieManager2> cookieManager(do_GetService(NS_COOKIEMANAGER_CONTRACTID));
|
||||
if (!cookieManager)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsCOMPtr<nsIFile> dogbertCookiesFile;
|
||||
mSourceProfile->Clone(getter_AddRefs(dogbertCookiesFile));
|
||||
dogbertCookiesFile->Append(COOKIES_FILE_NAME_IN_4x);
|
||||
|
||||
rv = ImportNetscapeCookies(dogbertCookiesFile);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
#if NEED_TO_FIX_4X_COOKIES
|
||||
nsresult
|
||||
nsDogbertProfileMigrator::FixDogbertCookies()
|
||||
{
|
||||
nsCOMPtr<nsIFile> dogbertCookiesFile;
|
||||
mSourceProfile->Clone(getter_AddRefs(dogbertCookiesFile));
|
||||
dogbertCookiesFile->Append(COOKIES_FILE_NAME_IN_4x);
|
||||
|
||||
nsCOMPtr<nsIInputStream> fileInputStream;
|
||||
NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), dogbertCookiesFile);
|
||||
if (!fileInputStream) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsCOMPtr<nsIFile> firebirdCookiesFile;
|
||||
mTargetProfile->Clone(getter_AddRefs(firebirdCookiesFile));
|
||||
firebirdCookiesFile->Append(COOKIES_FILE_NAME_IN_5x);
|
||||
|
||||
nsCOMPtr<nsIOutputStream> fileOutputStream;
|
||||
NS_NewLocalFileOutputStream(getter_AddRefs(fileOutputStream), firebirdCookiesFile);
|
||||
if (!fileOutputStream) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
nsCOMPtr<nsILineInputStream> lineInputStream(do_QueryInterface(fileInputStream));
|
||||
nsCAutoString buffer, outBuffer;
|
||||
PRBool moreData = PR_FALSE;
|
||||
PRUint32 written = 0;
|
||||
do {
|
||||
nsresult rv = lineInputStream->ReadLine(buffer, &moreData);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (!moreData)
|
||||
break;
|
||||
|
||||
// skip line if it is a comment or null line
|
||||
if (buffer.IsEmpty() || buffer.CharAt(0) == '#' ||
|
||||
buffer.CharAt(0) == '\r' || buffer.CharAt(0) == '\n') {
|
||||
fileOutputStream->Write(buffer.get(), buffer.Length(), &written);
|
||||
continue;
|
||||
}
|
||||
|
||||
// locate expire field, skip line if it does not contain all its fields
|
||||
int hostIndex, isDomainIndex, pathIndex, xxxIndex, expiresIndex, nameIndex, cookieIndex;
|
||||
hostIndex = 0;
|
||||
if ((isDomainIndex = buffer.FindChar('\t', hostIndex)+1) == 0 ||
|
||||
(pathIndex = buffer.FindChar('\t', isDomainIndex)+1) == 0 ||
|
||||
(xxxIndex = buffer.FindChar('\t', pathIndex)+1) == 0 ||
|
||||
(expiresIndex = buffer.FindChar('\t', xxxIndex)+1) == 0 ||
|
||||
(nameIndex = buffer.FindChar('\t', expiresIndex)+1) == 0 ||
|
||||
(cookieIndex = buffer.FindChar('\t', nameIndex)+1) == 0 )
|
||||
continue;
|
||||
|
||||
// separate the expires field from the rest of the cookie line
|
||||
const nsDependentCSubstring prefix =
|
||||
Substring(buffer, hostIndex, expiresIndex-hostIndex-1);
|
||||
const nsDependentCSubstring expiresString =
|
||||
Substring(buffer, expiresIndex, nameIndex-expiresIndex-1);
|
||||
const nsDependentCSubstring suffix =
|
||||
Substring(buffer, nameIndex, buffer.Length()-nameIndex);
|
||||
|
||||
// correct the expires field
|
||||
char* expiresCString = ToNewCString(expiresString);
|
||||
unsigned long expires = strtoul(expiresCString, nsnull, 10);
|
||||
NS_Free(expiresCString);
|
||||
|
||||
// if the cookie is supposed to expire at the end of the session
|
||||
// expires == 0. don't adjust those cookies.
|
||||
if (expires)
|
||||
expires -= SECONDS_BETWEEN_1900_AND_1970;
|
||||
char dateString[36];
|
||||
PR_snprintf(dateString, sizeof(dateString), "%lu", expires);
|
||||
|
||||
// generate the output buffer and write it to file
|
||||
outBuffer = prefix;
|
||||
outBuffer.Append('\t');
|
||||
outBuffer.Append(dateString);
|
||||
outBuffer.Append('\t');
|
||||
outBuffer.Append(suffix);
|
||||
|
||||
fileOutputStream->Write(outBuffer.get(), outBuffer.Length(), &written);
|
||||
}
|
||||
while (1);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#endif // NEED_TO_FIX_4X_COOKIES
|
||||
|
||||
|
||||
nsresult
|
||||
nsDogbertProfileMigrator::CopyBookmarks(PRBool aReplace)
|
||||
{
|
||||
// If we're blowing away existing content, just copy the file, don't do fancy importing.
|
||||
if (aReplace) {
|
||||
nsresult rv = InitializeBookmarks(mTargetProfile);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return MigrateDogbertBookmarks();
|
||||
}
|
||||
|
||||
return ImportNetscapeBookmarks(BOOKMARKS_FILE_NAME_IN_4x,
|
||||
NS_LITERAL_STRING("sourceNameDogbert").get());
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDogbertProfileMigrator::MigrateDogbertBookmarks()
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// Find out what the personal toolbar folder was called, this is stored in a pref
|
||||
// in 4.x
|
||||
nsCOMPtr<nsIPrefService> psvc(do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
psvc->ResetPrefs();
|
||||
|
||||
nsCOMPtr<nsIFile> dogbertPrefsFile;
|
||||
mSourceProfile->Clone(getter_AddRefs(dogbertPrefsFile));
|
||||
dogbertPrefsFile->Append(PREF_FILE_NAME_IN_4x);
|
||||
psvc->ReadUserPrefs(dogbertPrefsFile);
|
||||
|
||||
nsCString toolbarName;
|
||||
nsCOMPtr<nsIPrefBranch> branch(do_QueryInterface(psvc));
|
||||
rv = branch->GetCharPref("custtoolbar.personal_toolbar_folder", getter_Copies(toolbarName));
|
||||
// If the pref wasn't set in the user's 4.x preferences, there's no way we can "Fix" the
|
||||
// file when importing it to set the personal toolbar folder correctly, so don't bother
|
||||
// with the more involved file correction procedure and just copy the file over.
|
||||
if (NS_FAILED(rv))
|
||||
return CopyFile(BOOKMARKS_FILE_NAME_IN_4x, BOOKMARKS_FILE_NAME_IN_5x);
|
||||
|
||||
// Now read the 4.x bookmarks file, correcting the Personal Toolbar Folder line
|
||||
// and writing to the new location.
|
||||
nsCOMPtr<nsIFile> sourceBookmarksFile;
|
||||
mSourceProfile->Clone(getter_AddRefs(sourceBookmarksFile));
|
||||
sourceBookmarksFile->Append(BOOKMARKS_FILE_NAME_IN_4x);
|
||||
|
||||
nsCOMPtr<nsIFile> targetBookmarksFile;
|
||||
mTargetProfile->Clone(getter_AddRefs(targetBookmarksFile));
|
||||
targetBookmarksFile->Append(BOOKMARKS_FILE_NAME_IN_5x);
|
||||
|
||||
return AnnotatePersonalToolbarFolder(sourceBookmarksFile,
|
||||
targetBookmarksFile, toolbarName.get());
|
||||
}
|
@ -1,89 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** 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 The Browser Profile Migrator.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ben Goodger.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@bengoodger.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 ***** */
|
||||
|
||||
#ifndef dogbertprofilemigrator___h___
|
||||
#define dogbertprofilemigrator___h___
|
||||
|
||||
#include "nsIBrowserProfileMigrator.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsNetscapeProfileMigratorBase.h"
|
||||
#include "nsStringAPI.h"
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#define NEED_TO_FIX_4X_COOKIES 1
|
||||
#define SECONDS_BETWEEN_1900_AND_1970 2208988800UL
|
||||
#endif /* XP_MACOSX */
|
||||
|
||||
class nsIFile;
|
||||
|
||||
class nsDogbertProfileMigrator : public nsNetscapeProfileMigratorBase,
|
||||
public nsIBrowserProfileMigrator
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSIBROWSERPROFILEMIGRATOR
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsDogbertProfileMigrator();
|
||||
virtual ~nsDogbertProfileMigrator();
|
||||
|
||||
public:
|
||||
static nsresult GetHomepage(void* aTransform, nsIPrefBranch* aBranch);
|
||||
static nsresult GetImagePref(void* aTransform, nsIPrefBranch* aBranch);
|
||||
|
||||
protected:
|
||||
nsresult CopyPreferences(PRBool aReplace);
|
||||
nsresult TransformPreferences(const nsAString& aSourcePrefFileName,
|
||||
const nsAString& aTargetPrefFileName);
|
||||
|
||||
nsresult CopyCookies(PRBool aReplace);
|
||||
#ifdef NEED_TO_FIX_4X_COOKIES
|
||||
nsresult FixDogbertCookies();
|
||||
#endif
|
||||
|
||||
nsresult CopyBookmarks(PRBool aReplace);
|
||||
nsresult MigrateDogbertBookmarks();
|
||||
|
||||
void GetSourceProfile(const PRUnichar* aProfile);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsISupportsArray> mProfiles;
|
||||
nsCOMPtr<nsIObserverService> mObserverService;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,116 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** 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 The Browser Profile Migrator.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ben Goodger.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@bengoodger.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 ***** */
|
||||
|
||||
#include "nsBrowserProfileMigratorUtils.h"
|
||||
#include "nsICabProfileMigrator.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIProfileMigrator.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsICabProfileMigrator
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsICabProfileMigrator, nsIBrowserProfileMigrator)
|
||||
|
||||
nsICabProfileMigrator::nsICabProfileMigrator()
|
||||
{
|
||||
mObserverService = do_GetService("@mozilla.org/observer-service;1");
|
||||
}
|
||||
|
||||
nsICabProfileMigrator::~nsICabProfileMigrator()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsIBrowserProfileMigrator
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsICabProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup, const PRUnichar* aProfile)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);
|
||||
|
||||
NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsICabProfileMigrator::GetMigrateData(const PRUnichar* aProfile,
|
||||
PRBool aReplace,
|
||||
PRUint16* aResult)
|
||||
{
|
||||
*aResult = 0; // XXXben implement me
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsICabProfileMigrator::GetSourceExists(PRBool* aResult)
|
||||
{
|
||||
*aResult = PR_FALSE; // XXXben implement me
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsICabProfileMigrator::GetSourceHasMultipleProfiles(PRBool* aResult)
|
||||
{
|
||||
*aResult = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsICabProfileMigrator::GetSourceProfiles(nsISupportsArray** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsICabProfileMigrator::GetSourceHomePageURL(nsACString& aResult)
|
||||
{
|
||||
aResult.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsICabProfileMigrator
|
||||
|
@ -1,259 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** 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 The Browser Profile Migrator.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ben Goodger.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@bengoodger.com>
|
||||
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsBrowserProfileMigratorUtils.h"
|
||||
#include "nsMacIEProfileMigrator.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIProfileMigrator.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "nsIProperties.h"
|
||||
#include <Carbon/Carbon.h>
|
||||
|
||||
#define MACIE_BOOKMARKS_FILE_NAME NS_LITERAL_STRING("Favorites.html")
|
||||
#define MACIE_PREFERENCES_FOLDER_NAME NS_LITERAL_STRING("Explorer")
|
||||
#define MACIE_DEFAULT_HOMEPAGE_PREF "\p4D534945¥WWWHomePage"
|
||||
#define TEMP_BOOKMARKS_FILE_NAME NS_LITERAL_STRING("bookmarks_tmp.html")
|
||||
|
||||
#define MIGRATION_BUNDLE "chrome://browser/locale/migration/migration.properties"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsMacIEProfileMigrator
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsMacIEProfileMigrator, nsIBrowserProfileMigrator)
|
||||
|
||||
nsMacIEProfileMigrator::nsMacIEProfileMigrator()
|
||||
{
|
||||
mObserverService = do_GetService("@mozilla.org/observer-service;1");
|
||||
}
|
||||
|
||||
nsMacIEProfileMigrator::~nsMacIEProfileMigrator()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsIBrowserProfileMigrator
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMacIEProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup, const PRUnichar* aProfile)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRBool replace = aStartup ? PR_TRUE : PR_FALSE;
|
||||
|
||||
if (!mTargetProfile) {
|
||||
GetProfilePath(aStartup, mTargetProfile);
|
||||
if (!mTargetProfile) return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
if (!mSourceProfile) {
|
||||
nsCOMPtr<nsIProperties> fileLocator =
|
||||
do_GetService("@mozilla.org/file/directory_service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
fileLocator->Get(NS_OSX_USER_PREFERENCES_DIR,
|
||||
NS_GET_IID(nsILocalFile),
|
||||
getter_AddRefs(mSourceProfile));
|
||||
mSourceProfile->Append(MACIE_PREFERENCES_FOLDER_NAME);
|
||||
}
|
||||
|
||||
NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);
|
||||
|
||||
COPY_DATA(CopyBookmarks, replace, nsIBrowserProfileMigrator::BOOKMARKS);
|
||||
|
||||
NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMacIEProfileMigrator::GetMigrateData(const PRUnichar* aProfile,
|
||||
PRBool aReplace,
|
||||
PRUint16* aResult)
|
||||
{
|
||||
*aResult = 0;
|
||||
|
||||
if (!mSourceProfile) {
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIProperties> fileLocator =
|
||||
do_GetService("@mozilla.org/file/directory_service;1", &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
fileLocator->Get(NS_OSX_USER_PREFERENCES_DIR,
|
||||
NS_GET_IID(nsILocalFile),
|
||||
getter_AddRefs(mSourceProfile));
|
||||
mSourceProfile->Append(MACIE_PREFERENCES_FOLDER_NAME);
|
||||
}
|
||||
|
||||
MigrationData data[] = { { ToNewUnicode(MACIE_BOOKMARKS_FILE_NAME),
|
||||
nsIBrowserProfileMigrator::BOOKMARKS,
|
||||
PR_FALSE } };
|
||||
|
||||
// Frees file name strings allocated above.
|
||||
GetMigrateDataFromArray(data, sizeof(data)/sizeof(MigrationData),
|
||||
aReplace, mSourceProfile, aResult);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMacIEProfileMigrator::GetSourceExists(PRBool* aResult)
|
||||
{
|
||||
// Since the IE bookmarks file can sometimes be created by programs
|
||||
// other than Internet Explorer, thus misleading, we must first
|
||||
// check whether IE is even installed on this Mac. We accomplish this by
|
||||
// checking one of IEs stored preferences in the apple.internetconfig file.
|
||||
PRBool prefExists = PR_FALSE;
|
||||
OSErr err;
|
||||
ICInstance icInstance;
|
||||
|
||||
err = ::ICStart(&icInstance, 'FRFX');
|
||||
if (err == noErr) {
|
||||
ICAttr attrs;
|
||||
Str255 IEhomePageValue;
|
||||
long size = kICFileSpecHeaderSize;
|
||||
err = ::ICGetPref(icInstance, MACIE_DEFAULT_HOMEPAGE_PREF, &attrs,
|
||||
IEhomePageValue, &size);
|
||||
if (err == noErr)
|
||||
prefExists = PR_TRUE;
|
||||
|
||||
::ICStop(icInstance);
|
||||
}
|
||||
|
||||
if (!prefExists) {
|
||||
*aResult = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRUint16 data;
|
||||
GetMigrateData(nsnull, PR_FALSE, &data);
|
||||
|
||||
*aResult = data != 0;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMacIEProfileMigrator::GetSourceHasMultipleProfiles(PRBool* aResult)
|
||||
{
|
||||
*aResult = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMacIEProfileMigrator::GetSourceProfiles(nsISupportsArray** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMacIEProfileMigrator::GetSourceHomePageURL(nsACString& aResult)
|
||||
{
|
||||
aResult.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsMacIEProfileMigrator
|
||||
|
||||
nsresult
|
||||
nsMacIEProfileMigrator::CopyBookmarks(PRBool aReplace)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIFile> sourceFile;
|
||||
mSourceProfile->Clone(getter_AddRefs(sourceFile));
|
||||
|
||||
sourceFile->Append(MACIE_BOOKMARKS_FILE_NAME);
|
||||
PRBool exists = PR_FALSE;
|
||||
sourceFile->Exists(&exists);
|
||||
if (!exists)
|
||||
return NS_OK;
|
||||
|
||||
// it's an import
|
||||
if (!aReplace)
|
||||
return ImportBookmarksHTML(sourceFile,
|
||||
PR_FALSE,
|
||||
PR_FALSE,
|
||||
NS_LITERAL_STRING("sourceNameIE").get());
|
||||
|
||||
// Initialize the default bookmarks
|
||||
rv = InitializeBookmarks(mTargetProfile);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// If we're blowing away existing content, annotate the Personal Toolbar and
|
||||
// then import the file.
|
||||
nsCOMPtr<nsIFile> tempFile;
|
||||
mTargetProfile->Clone(getter_AddRefs(tempFile));
|
||||
tempFile->Append(TEMP_BOOKMARKS_FILE_NAME);
|
||||
|
||||
// Look for the localized name of the IE Favorites Bar
|
||||
nsCOMPtr<nsIStringBundleService> bundleService =
|
||||
do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
nsCOMPtr<nsIStringBundle> bundle;
|
||||
rv = bundleService->CreateBundle(MIGRATION_BUNDLE, getter_AddRefs(bundle));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsString toolbarFolderNameMacIE;
|
||||
rv = bundle->GetStringFromName(NS_LITERAL_STRING("toolbarFolderNameMacIE").get(),
|
||||
getter_Copies(toolbarFolderNameMacIE));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Now read the 4.x bookmarks file, correcting the Personal Toolbar Folder
|
||||
// line and writing to the temporary file.
|
||||
rv = AnnotatePersonalToolbarFolder(sourceFile,
|
||||
tempFile,
|
||||
NS_ConvertUTF16toUTF8(toolbarFolderNameMacIE).get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// import the temp file
|
||||
rv = ImportBookmarksHTML(tempFile,
|
||||
PR_TRUE,
|
||||
PR_FALSE,
|
||||
EmptyString().get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// remove the temp file
|
||||
return tempFile->Remove(PR_FALSE);
|
||||
}
|
@ -1,116 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** 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 The Browser Profile Migrator.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ben Goodger.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@bengoodger.com>
|
||||
* Benjamin Smedberg <benjamin@smedbergs.us>
|
||||
*
|
||||
* 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 ***** */
|
||||
|
||||
#include "nsBrowserProfileMigratorUtils.h"
|
||||
#include "nsOmniWebProfileMigrator.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIProfileMigrator.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsOmniWebProfileMigrator
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsOmniWebProfileMigrator, nsIBrowserProfileMigrator)
|
||||
|
||||
nsOmniWebProfileMigrator::nsOmniWebProfileMigrator()
|
||||
{
|
||||
mObserverService = do_GetService("@mozilla.org/observer-service;1");
|
||||
}
|
||||
|
||||
nsOmniWebProfileMigrator::~nsOmniWebProfileMigrator()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsIBrowserProfileMigrator
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOmniWebProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup, const PRUnichar* aProfile)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);
|
||||
|
||||
NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOmniWebProfileMigrator::GetMigrateData(const PRUnichar* aProfile,
|
||||
PRBool aReplace,
|
||||
PRUint16* aResult)
|
||||
{
|
||||
*aResult = 0; // XXXben implement me
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOmniWebProfileMigrator::GetSourceExists(PRBool* aResult)
|
||||
{
|
||||
*aResult = PR_FALSE; // XXXben implement me
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOmniWebProfileMigrator::GetSourceHasMultipleProfiles(PRBool* aResult)
|
||||
{
|
||||
*aResult = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOmniWebProfileMigrator::GetSourceProfiles(nsISupportsArray** aResult)
|
||||
{
|
||||
*aResult = nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsOmniWebProfileMigrator::GetSourceHomePageURL(nsACString& aResult)
|
||||
{
|
||||
aResult.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsOmniWebProfileMigrator
|
||||
|
@ -46,6 +46,7 @@
|
||||
#include "nsStringAPI.h"
|
||||
#include "nsTArray.h"
|
||||
#include "nsINavHistoryService.h"
|
||||
#include "nsIStringBundle.h"
|
||||
|
||||
class nsICookieManager2;
|
||||
class nsILineInputStream;
|
||||
|
@ -1,438 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** 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 The Browser Profile Migrator.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ben Goodger.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@bengoodger.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 ***** */
|
||||
|
||||
#include "nsBrowserProfileMigratorUtils.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsPhoenixProfileMigrator.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsPhoenixProfileMigrator
|
||||
|
||||
#define FILE_NAME_BOOKMARKS NS_LITERAL_STRING("bookmarks.html")
|
||||
#define FILE_NAME_COOKIES NS_LITERAL_STRING("cookies.txt")
|
||||
#define FILE_NAME_SITEPERM_OLD NS_LITERAL_STRING("cookperm.txt")
|
||||
#define FILE_NAME_SITEPERM_NEW NS_LITERAL_STRING("hostperm.1")
|
||||
#define FILE_NAME_CERT8DB NS_LITERAL_STRING("cert8.db")
|
||||
#define FILE_NAME_KEY3DB NS_LITERAL_STRING("key3.db")
|
||||
#define FILE_NAME_SECMODDB NS_LITERAL_STRING("secmod.db")
|
||||
#define FILE_NAME_HISTORY NS_LITERAL_STRING("history.dat")
|
||||
#define FILE_NAME_FORMHISTORY NS_LITERAL_STRING("formhistory.dat")
|
||||
#define FILE_NAME_LOCALSTORE NS_LITERAL_STRING("localstore.rdf")
|
||||
#define FILE_NAME_MIMETYPES NS_LITERAL_STRING("mimeTypes.rdf")
|
||||
#define FILE_NAME_DOWNLOADS NS_LITERAL_STRING("downloads.rdf")
|
||||
#define FILE_NAME_PREFS NS_LITERAL_STRING("prefs.js")
|
||||
#define FILE_NAME_USER_PREFS NS_LITERAL_STRING("user.js")
|
||||
#define FILE_NAME_USERCHROME NS_LITERAL_STRING("userChrome.css")
|
||||
#define FILE_NAME_USERCONTENT NS_LITERAL_STRING("userContent.css")
|
||||
#define DIR_NAME_CHROME NS_LITERAL_STRING("chrome")
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsPhoenixProfileMigrator, nsIBrowserProfileMigrator)
|
||||
|
||||
nsPhoenixProfileMigrator::nsPhoenixProfileMigrator()
|
||||
{
|
||||
mObserverService = do_GetService("@mozilla.org/observer-service;1");
|
||||
}
|
||||
|
||||
nsPhoenixProfileMigrator::~nsPhoenixProfileMigrator()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsIBrowserProfileMigrator
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPhoenixProfileMigrator::Migrate(PRUint16 aItems, nsIProfileStartup* aStartup, const PRUnichar* aProfile)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
// At this time the only reason for this migrator is to get data across from the
|
||||
// Phoenix profile directory on initial run, so we don't need to support after-the-fact
|
||||
// importing.
|
||||
NS_ASSERTION(aStartup, "Can't migrate from Phoenix/Firebird/Firefox profiles once Firefox is running!");
|
||||
if (!aStartup)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
if (!mTargetProfile) {
|
||||
GetProfilePath(aStartup, mTargetProfile);
|
||||
if (!mTargetProfile) return NS_ERROR_FAILURE;
|
||||
}
|
||||
if (!mSourceProfile)
|
||||
GetSourceProfile(aProfile);
|
||||
|
||||
NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);
|
||||
|
||||
COPY_DATA(CopyPreferences, PR_TRUE, nsIBrowserProfileMigrator::SETTINGS);
|
||||
COPY_DATA(CopyCookies, PR_TRUE, nsIBrowserProfileMigrator::COOKIES);
|
||||
COPY_DATA(CopyHistory, PR_TRUE, nsIBrowserProfileMigrator::HISTORY);
|
||||
COPY_DATA(CopyPasswords, PR_TRUE, nsIBrowserProfileMigrator::PASSWORDS);
|
||||
COPY_DATA(CopyOtherData, PR_TRUE, nsIBrowserProfileMigrator::OTHERDATA);
|
||||
COPY_DATA(CopyBookmarks, PR_TRUE, nsIBrowserProfileMigrator::BOOKMARKS);
|
||||
|
||||
if (aItems & nsIBrowserProfileMigrator::SETTINGS ||
|
||||
aItems & nsIBrowserProfileMigrator::COOKIES ||
|
||||
aItems & nsIBrowserProfileMigrator::PASSWORDS ||
|
||||
!aItems) {
|
||||
// Permissions (Images, Cookies, Popups)
|
||||
rv |= CopyFile(FILE_NAME_SITEPERM_NEW, FILE_NAME_SITEPERM_NEW);
|
||||
rv |= CopyFile(FILE_NAME_SITEPERM_OLD, FILE_NAME_SITEPERM_OLD);
|
||||
}
|
||||
|
||||
NOTIFY_OBSERVERS(MIGRATION_ENDED, nsnull);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPhoenixProfileMigrator::GetMigrateData(const PRUnichar* aProfile,
|
||||
PRBool aReplace,
|
||||
PRUint16* aResult)
|
||||
{
|
||||
*aResult = 0;
|
||||
if (!mSourceProfile) {
|
||||
GetSourceProfile(aProfile);
|
||||
if (!mSourceProfile)
|
||||
return NS_ERROR_FILE_NOT_FOUND;
|
||||
}
|
||||
|
||||
MigrationData data[] = { { ToNewUnicode(FILE_NAME_PREFS),
|
||||
nsIBrowserProfileMigrator::SETTINGS,
|
||||
PR_TRUE },
|
||||
{ ToNewUnicode(FILE_NAME_USER_PREFS),
|
||||
nsIBrowserProfileMigrator::SETTINGS,
|
||||
PR_TRUE },
|
||||
{ ToNewUnicode(FILE_NAME_COOKIES),
|
||||
nsIBrowserProfileMigrator::COOKIES,
|
||||
PR_TRUE },
|
||||
{ ToNewUnicode(FILE_NAME_HISTORY),
|
||||
nsIBrowserProfileMigrator::HISTORY,
|
||||
PR_TRUE },
|
||||
{ ToNewUnicode(FILE_NAME_BOOKMARKS),
|
||||
nsIBrowserProfileMigrator::BOOKMARKS,
|
||||
PR_TRUE },
|
||||
{ ToNewUnicode(FILE_NAME_DOWNLOADS),
|
||||
nsIBrowserProfileMigrator::OTHERDATA,
|
||||
PR_TRUE },
|
||||
{ ToNewUnicode(FILE_NAME_MIMETYPES),
|
||||
nsIBrowserProfileMigrator::OTHERDATA,
|
||||
PR_TRUE },
|
||||
{ ToNewUnicode(FILE_NAME_USERCHROME),
|
||||
nsIBrowserProfileMigrator::OTHERDATA,
|
||||
PR_TRUE },
|
||||
{ ToNewUnicode(FILE_NAME_USERCONTENT),
|
||||
nsIBrowserProfileMigrator::OTHERDATA,
|
||||
PR_TRUE },
|
||||
{ ToNewUnicode(FILE_NAME_FORMHISTORY),
|
||||
nsIBrowserProfileMigrator::OTHERDATA,
|
||||
PR_TRUE } };
|
||||
|
||||
// Frees file name strings allocated above.
|
||||
GetMigrateDataFromArray(data, sizeof(data)/sizeof(MigrationData),
|
||||
aReplace, mSourceProfile, aResult);
|
||||
|
||||
// Now locate passwords
|
||||
nsCString signonsFileName;
|
||||
GetSignonFileName(aReplace, getter_Copies(signonsFileName));
|
||||
|
||||
if (!signonsFileName.IsEmpty()) {
|
||||
NS_ConvertASCIItoUTF16 fileName(signonsFileName);
|
||||
nsCOMPtr<nsIFile> sourcePasswordsFile;
|
||||
mSourceProfile->Clone(getter_AddRefs(sourcePasswordsFile));
|
||||
sourcePasswordsFile->Append(fileName);
|
||||
|
||||
PRBool exists;
|
||||
sourcePasswordsFile->Exists(&exists);
|
||||
if (exists)
|
||||
*aResult |= nsIBrowserProfileMigrator::PASSWORDS;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPhoenixProfileMigrator::GetSourceExists(PRBool* aResult)
|
||||
{
|
||||
nsCOMPtr<nsISupportsArray> profiles;
|
||||
GetSourceProfiles(getter_AddRefs(profiles));
|
||||
|
||||
if (profiles) {
|
||||
PRUint32 count;
|
||||
profiles->Count(&count);
|
||||
*aResult = count > 0;
|
||||
}
|
||||
else
|
||||
*aResult = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPhoenixProfileMigrator::GetSourceHasMultipleProfiles(PRBool* aResult)
|
||||
{
|
||||
nsCOMPtr<nsISupportsArray> profiles;
|
||||
GetSourceProfiles(getter_AddRefs(profiles));
|
||||
|
||||
if (profiles) {
|
||||
PRUint32 count;
|
||||
profiles->Count(&count);
|
||||
*aResult = count > 1;
|
||||
}
|
||||
else
|
||||
*aResult = PR_FALSE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsPhoenixProfileMigrator::GetSourceProfiles(nsISupportsArray** aResult)
|
||||
{
|
||||
if (!mProfileNames && !mProfileLocations) {
|
||||
mProfileNames = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID);
|
||||
mProfileLocations = do_CreateInstance(NS_SUPPORTSARRAY_CONTRACTID);
|
||||
NS_ENSURE_TRUE(mProfileNames && mProfileLocations, NS_ERROR_UNEXPECTED);
|
||||
|
||||
// Fills mProfileNames and mProfileLocations
|
||||
FillProfileDataFromPhoenixRegistry();
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aResult = mProfileNames);
|
||||
return NS_OK;
|
||||
}
|
||||
NS_IMETHODIMP
|
||||
nsPhoenixProfileMigrator::GetSourceHomePageURL(nsACString& aResult)
|
||||
{
|
||||
aResult.Truncate();
|
||||
return NS_OK;
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsPhoenixProfileMigrator
|
||||
|
||||
nsresult
|
||||
nsPhoenixProfileMigrator::GetSourceProfile(const PRUnichar* aProfile)
|
||||
{
|
||||
PRUint32 count;
|
||||
mProfileNames->Count(&count);
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
nsCOMPtr<nsISupportsString> str;
|
||||
mProfileNames->QueryElementAt(i, NS_GET_IID(nsISupportsString),
|
||||
getter_AddRefs(str));
|
||||
nsString profileName;
|
||||
str->GetData(profileName);
|
||||
if (profileName.Equals(aProfile)) {
|
||||
mProfileLocations->QueryElementAt(i, NS_GET_IID(nsILocalFile),
|
||||
getter_AddRefs(mSourceProfile));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPhoenixProfileMigrator::FillProfileDataFromPhoenixRegistry()
|
||||
{
|
||||
// Find the Phoenix Registry
|
||||
nsCOMPtr<nsIProperties> fileLocator(do_GetService("@mozilla.org/file/directory_service;1"));
|
||||
nsCOMPtr<nsILocalFile> phoenixRegistry;
|
||||
#ifdef XP_WIN
|
||||
fileLocator->Get(NS_WIN_APPDATA_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(phoenixRegistry));
|
||||
|
||||
phoenixRegistry->Append(NS_LITERAL_STRING("Phoenix"));
|
||||
phoenixRegistry->Append(NS_LITERAL_STRING("registry.dat"));
|
||||
#elif defined(XP_MACOSX)
|
||||
fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(phoenixRegistry));
|
||||
|
||||
phoenixRegistry->Append(NS_LITERAL_STRING("Phoenix"));
|
||||
phoenixRegistry->Append(NS_LITERAL_STRING("Application Registry"));
|
||||
#elif defined(XP_UNIX)
|
||||
fileLocator->Get(NS_UNIX_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(phoenixRegistry));
|
||||
|
||||
phoenixRegistry->Append(NS_LITERAL_STRING(".phoenix"));
|
||||
phoenixRegistry->Append(NS_LITERAL_STRING("appreg"));
|
||||
#elif defined(XP_OS2)
|
||||
fileLocator->Get(NS_OS2_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(phoenixRegistry));
|
||||
|
||||
phoenixRegistry->Append(NS_LITERAL_STRING("Phoenix"));
|
||||
phoenixRegistry->Append(NS_LITERAL_STRING("registry.dat"));
|
||||
#endif
|
||||
|
||||
|
||||
return GetProfileDataFromRegistry(phoenixRegistry, mProfileNames, mProfileLocations);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPhoenixProfileMigrator::CopyPreferences(PRBool aReplace)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!aReplace)
|
||||
return rv;
|
||||
|
||||
// Prefs files
|
||||
rv |= CopyFile(FILE_NAME_PREFS, FILE_NAME_PREFS);
|
||||
rv |= CopyFile(FILE_NAME_USER_PREFS, FILE_NAME_USER_PREFS);
|
||||
|
||||
// Security Stuff
|
||||
rv |= CopyFile(FILE_NAME_CERT8DB, FILE_NAME_CERT8DB);
|
||||
rv |= CopyFile(FILE_NAME_KEY3DB, FILE_NAME_KEY3DB);
|
||||
rv |= CopyFile(FILE_NAME_SECMODDB, FILE_NAME_SECMODDB);
|
||||
|
||||
// User MIME Type overrides
|
||||
rv |= CopyFile(FILE_NAME_MIMETYPES, FILE_NAME_MIMETYPES);
|
||||
|
||||
rv |= CopyUserStyleSheets();
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPhoenixProfileMigrator::CopyUserStyleSheets()
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
nsCOMPtr<nsIFile> sourceUserContent;
|
||||
mSourceProfile->Clone(getter_AddRefs(sourceUserContent));
|
||||
sourceUserContent->Append(DIR_NAME_CHROME);
|
||||
sourceUserContent->Append(FILE_NAME_USERCONTENT);
|
||||
|
||||
PRBool exists = PR_FALSE;
|
||||
sourceUserContent->Exists(&exists);
|
||||
if (exists) {
|
||||
nsCOMPtr<nsIFile> targetUserContent;
|
||||
mTargetProfile->Clone(getter_AddRefs(targetUserContent));
|
||||
targetUserContent->Append(DIR_NAME_CHROME);
|
||||
nsCOMPtr<nsIFile> targetChromeDir;
|
||||
targetUserContent->Clone(getter_AddRefs(targetChromeDir));
|
||||
targetUserContent->Append(FILE_NAME_USERCONTENT);
|
||||
|
||||
targetUserContent->Exists(&exists);
|
||||
if (exists)
|
||||
targetUserContent->Remove(PR_FALSE);
|
||||
|
||||
rv |= sourceUserContent->CopyTo(targetChromeDir, FILE_NAME_USERCONTENT);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIFile> sourceUserChrome;
|
||||
mSourceProfile->Clone(getter_AddRefs(sourceUserChrome));
|
||||
sourceUserChrome->Append(DIR_NAME_CHROME);
|
||||
sourceUserChrome->Append(FILE_NAME_USERCHROME);
|
||||
|
||||
sourceUserChrome->Exists(&exists);
|
||||
if (exists) {
|
||||
nsCOMPtr<nsIFile> targetUserChrome;
|
||||
mTargetProfile->Clone(getter_AddRefs(targetUserChrome));
|
||||
targetUserChrome->Append(DIR_NAME_CHROME);
|
||||
nsCOMPtr<nsIFile> targetChromeDir;
|
||||
targetUserChrome->Clone(getter_AddRefs(targetChromeDir));
|
||||
targetUserChrome->Append(FILE_NAME_USERCHROME);
|
||||
|
||||
targetUserChrome->Exists(&exists);
|
||||
if (exists)
|
||||
targetUserChrome->Remove(PR_FALSE);
|
||||
|
||||
rv |= sourceUserChrome->CopyTo(targetChromeDir, FILE_NAME_USERCHROME);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPhoenixProfileMigrator::CopyCookies(PRBool aReplace)
|
||||
{
|
||||
return aReplace ? CopyFile(FILE_NAME_COOKIES, FILE_NAME_COOKIES) : NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPhoenixProfileMigrator::CopyHistory(PRBool aReplace)
|
||||
{
|
||||
return aReplace ? CopyFile(FILE_NAME_HISTORY, FILE_NAME_HISTORY) : NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPhoenixProfileMigrator::CopyPasswords(PRBool aReplace)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCString signonsFileName;
|
||||
if (!aReplace)
|
||||
return NS_OK;
|
||||
|
||||
// Find out what the signons file was called, this is stored in a pref
|
||||
// in Seamonkey.
|
||||
nsCOMPtr<nsIPrefService> psvc(do_GetService(NS_PREFSERVICE_CONTRACTID));
|
||||
psvc->ResetPrefs();
|
||||
|
||||
nsCOMPtr<nsIFile> seamonkeyPrefsFile;
|
||||
mSourceProfile->Clone(getter_AddRefs(seamonkeyPrefsFile));
|
||||
seamonkeyPrefsFile->Append(FILE_NAME_PREFS);
|
||||
psvc->ReadUserPrefs(seamonkeyPrefsFile);
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> branch(do_QueryInterface(psvc));
|
||||
rv = branch->GetCharPref("signon.SignonFileName", getter_Copies(signonsFileName));
|
||||
|
||||
if (signonsFileName.IsEmpty())
|
||||
return NS_ERROR_FILE_NOT_FOUND;
|
||||
|
||||
NS_ConvertASCIItoUTF16 fileName(signonsFileName);
|
||||
return aReplace ? CopyFile(fileName, fileName) : NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPhoenixProfileMigrator::CopyBookmarks(PRBool aReplace)
|
||||
{
|
||||
// This overwrites the defaults. This might be ok in this instance.
|
||||
return aReplace ? CopyFile(FILE_NAME_BOOKMARKS, FILE_NAME_BOOKMARKS) : NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsPhoenixProfileMigrator::CopyOtherData(PRBool aReplace)
|
||||
{
|
||||
if (!aReplace)
|
||||
return NS_OK;
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
rv |= CopyFile(FILE_NAME_DOWNLOADS, FILE_NAME_DOWNLOADS);
|
||||
rv |= CopyFile(FILE_NAME_LOCALSTORE, FILE_NAME_LOCALSTORE);
|
||||
rv |= CopyFile(FILE_NAME_FORMHISTORY, FILE_NAME_FORMHISTORY);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
@ -1,87 +0,0 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* ***** 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 The Browser Profile Migrator.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ben Goodger.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2004
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Ben Goodger <ben@bengoodger.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 ***** */
|
||||
|
||||
#ifndef phoenixprofilemigrator___h___
|
||||
#define phoenixprofilemigrator___h___
|
||||
|
||||
#include "nsIBrowserProfileMigrator.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsNetscapeProfileMigratorBase.h"
|
||||
#include "nsStringAPI.h"
|
||||
|
||||
class nsIFile;
|
||||
class nsIPrefBranch;
|
||||
class nsIPrefService;
|
||||
|
||||
class nsPhoenixProfileMigrator : public nsNetscapeProfileMigratorBase,
|
||||
public nsIBrowserProfileMigrator
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSIBROWSERPROFILEMIGRATOR
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsPhoenixProfileMigrator();
|
||||
virtual ~nsPhoenixProfileMigrator();
|
||||
|
||||
public:
|
||||
static nsresult SetImage(void* aTransform, nsIPrefBranch* aBranch);
|
||||
static nsresult SetCookie(void* aTransform, nsIPrefBranch* aBranch);
|
||||
static nsresult SetDownloadManager(void* aTransform, nsIPrefBranch* aBranch);
|
||||
|
||||
protected:
|
||||
nsresult FillProfileDataFromPhoenixRegistry();
|
||||
nsresult GetSourceProfile(const PRUnichar* aProfile);
|
||||
|
||||
nsresult CopyPreferences(PRBool aReplace);
|
||||
nsresult CopyUserStyleSheets();
|
||||
|
||||
nsresult CopyCookies(PRBool aReplace);
|
||||
nsresult CopyHistory(PRBool aReplace);
|
||||
nsresult CopyPasswords(PRBool aReplace);
|
||||
nsresult CopyBookmarks(PRBool aReplace);
|
||||
nsresult CopyOtherData(PRBool aReplace);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsISupportsArray> mProfileNames;
|
||||
nsCOMPtr<nsISupportsArray> mProfileLocations;
|
||||
nsCOMPtr<nsIObserverService> mObserverService;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -160,13 +160,9 @@ NS_IMPL_ISUPPORTS1(nsProfileMigrator, nsIProfileMigrator)
|
||||
|
||||
#ifdef XP_WIN
|
||||
|
||||
#define INTERNAL_NAME_FIREBIRD "firebird"
|
||||
#define INTERNAL_NAME_FIREFOX "firefox"
|
||||
#define INTERNAL_NAME_PHOENIX "phoenix"
|
||||
#define INTERNAL_NAME_IEXPLORE "iexplore"
|
||||
#define INTERNAL_NAME_MOZILLA_SUITE "apprunner"
|
||||
#define INTERNAL_NAME_SEAMONKEY "seamonkey"
|
||||
#define INTERNAL_NAME_DOGBERT "netscape"
|
||||
#define INTERNAL_NAME_OPERA "opera"
|
||||
#endif
|
||||
|
||||
@ -252,22 +248,11 @@ nsProfileMigrator::GetDefaultBrowserMigratorKey(nsACString& aKey,
|
||||
aKey = "seamonkey";
|
||||
return NS_OK;
|
||||
}
|
||||
if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_DOGBERT)) {
|
||||
aKey = "dogbert";
|
||||
return NS_OK;
|
||||
}
|
||||
if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_OPERA)) {
|
||||
aKey = "opera";
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Migrate data from any existing Application Data\Phoenix\* installations.
|
||||
if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_FIREBIRD) ||
|
||||
internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_FIREFOX) ||
|
||||
internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_PHOENIX)) {
|
||||
aKey = "phoenix";
|
||||
return NS_OK;
|
||||
}
|
||||
#else
|
||||
PRBool exists = PR_FALSE;
|
||||
#define CHECK_MIGRATOR(browser) do {\
|
||||
@ -281,9 +266,7 @@ nsProfileMigrator::GetDefaultBrowserMigratorKey(nsACString& aKey,
|
||||
|
||||
#if defined(XP_MACOSX)
|
||||
CHECK_MIGRATOR("safari");
|
||||
CHECK_MIGRATOR("macie");
|
||||
#endif
|
||||
CHECK_MIGRATOR("phoenix");
|
||||
CHECK_MIGRATOR("seamonkey");
|
||||
CHECK_MIGRATOR("opera");
|
||||
|
||||
|
@ -60,7 +60,7 @@ protected:
|
||||
nsCOMPtr<nsIBrowserProfileMigrator>& bpm);
|
||||
|
||||
/**
|
||||
* Import profiles from ~/.firefox/ or ~/.phoenix/
|
||||
* Import profiles from ~/.firefox/
|
||||
* @return PR_TRUE if any profiles imported.
|
||||
*/
|
||||
PRBool ImportRegistryProfiles(const nsACString& aAppName);
|
||||
|
@ -1269,29 +1269,5 @@ nsSafariProfileMigrator::GetSourceHomePageURL(nsACString& aResult)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
#ifdef __LP64__
|
||||
return NS_ERROR_FAILURE;
|
||||
#else
|
||||
// Couldn't find the home page in com.apple.safai, time to check
|
||||
// com.apple.internetconfig for this key!
|
||||
ICInstance internetConfig;
|
||||
OSStatus error = ::ICStart(&internetConfig, 'FRFX');
|
||||
if (error != noErr)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
ICAttr dummy;
|
||||
Str255 homePagePValue;
|
||||
long prefSize = sizeof(homePagePValue);
|
||||
error = ::ICGetPref(internetConfig, kICWWWHomePage, &dummy,
|
||||
homePagePValue, &prefSize);
|
||||
if (error != noErr)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
char homePageValue[256] = "";
|
||||
CopyPascalStringToC((ConstStr255Param)homePagePValue, homePageValue);
|
||||
aResult.Assign(homePageValue);
|
||||
::ICStop(internetConfig);
|
||||
|
||||
return NS_OK;
|
||||
#endif
|
||||
}
|
||||
|
@ -749,7 +749,8 @@ PlacesViewBase.prototype = {
|
||||
aPopup._endOptOpenAllInTabs = document.createElement("menuitem");
|
||||
aPopup._endOptOpenAllInTabs.className = "openintabs-menuitem";
|
||||
aPopup._endOptOpenAllInTabs.setAttribute("oncommand",
|
||||
"PlacesUIUtils.openContainerNodeInTabs(this.parentNode._placesNode, event);");
|
||||
"PlacesUIUtils.openContainerNodeInTabs(this.parentNode._placesNode, event, " +
|
||||
"PlacesUIUtils.getViewForNode(this));");
|
||||
aPopup._endOptOpenAllInTabs.setAttribute("onclick",
|
||||
"checkForMiddleClick(this, event); event.stopPropagation();");
|
||||
aPopup._endOptOpenAllInTabs.setAttribute("label",
|
||||
|
@ -187,12 +187,12 @@
|
||||
|
||||
<toolbox id="placesToolbox">
|
||||
<toolbar class="chromeclass-toolbar" id="placesToolbar" align="center">
|
||||
<toolbarbutton id="back-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
<toolbarbutton id="back-button"
|
||||
command="OrganizerCommand:Back"
|
||||
tooltiptext="&backButton.tooltip;"
|
||||
disabled="true"/>
|
||||
|
||||
<toolbarbutton id="forward-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
|
||||
<toolbarbutton id="forward-button"
|
||||
command="OrganizerCommand:Forward"
|
||||
tooltiptext="&forwardButton.tooltip;"
|
||||
disabled="true"/>
|
||||
|
@ -774,8 +774,9 @@ var PlacesUIUtils = {
|
||||
|
||||
// Prefer the caller window if it's a browser window, otherwise use
|
||||
// the top browser window.
|
||||
var browserWindow =
|
||||
aWindow.document.documentElement.getAttribute("windowtype") == "navigator:browser" ?
|
||||
var browserWindow = null;
|
||||
browserWindow =
|
||||
aWindow && aWindow.document.documentElement.getAttribute("windowtype") == "navigator:browser" ?
|
||||
aWindow : this._getTopBrowserWin();
|
||||
|
||||
// whereToOpenLink doesn't return "window" when there's no browser window
|
||||
@ -783,8 +784,16 @@ var PlacesUIUtils = {
|
||||
var where = browserWindow ?
|
||||
browserWindow.whereToOpenLink(aEvent, false, true) : "window";
|
||||
if (where == "window") {
|
||||
aWindow.openDialog(aWindow.getBrowserURL(), "_blank",
|
||||
"chrome,all,dialog=no", urls.join("|"));
|
||||
// There is no browser window open, thus open a new one.
|
||||
var uriList = Cc["@mozilla.org/supports-string;1"].
|
||||
createInstance(Ci.nsISupportsString);
|
||||
uriList.data = urls.join("|");
|
||||
var args = Cc["@mozilla.org/supports-array;1"].
|
||||
createInstance(Ci.nsISupportsArray);
|
||||
args.AppendElement(uriList);
|
||||
browserWindow = Services.ww.openWindow(aWindow,
|
||||
"chrome://browser/content/browser.xul",
|
||||
null, "chrome,dialog=no,all", args);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -247,10 +247,9 @@ var bookmarksObserver = {
|
||||
var index = null;
|
||||
[node, index] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places);
|
||||
// Left pane should not be updated for normal bookmarks or separators.
|
||||
var type = PlacesUtils.bookmarks.getItemType(aItemId);
|
||||
switch (type) {
|
||||
switch (aItemType) {
|
||||
case PlacesUtils.bookmarks.TYPE_BOOKMARK:
|
||||
var uriString = PlacesUtils.bookmarks.getBookmarkURI(aItemId).spec;
|
||||
var uriString = aURI.spec;
|
||||
var isQuery = uriString.substr(0, 6) == "place:";
|
||||
if (isQuery) {
|
||||
isnot(node, null, "Found new Places node in left pane");
|
||||
@ -276,13 +275,12 @@ var bookmarksObserver = {
|
||||
|
||||
onItemMoved: function(aItemId,
|
||||
aOldFolderId, aOldIndex,
|
||||
aNewFolderId, aNewIndex) {
|
||||
aNewFolderId, aNewIndex, aItemType) {
|
||||
var node = null;
|
||||
var index = null;
|
||||
[node, index] = getNodeForTreeItem(aItemId, gLibrary.PlacesOrganizer._places);
|
||||
// Left pane should not be updated for normal bookmarks or separators.
|
||||
var type = PlacesUtils.bookmarks.getItemType(aItemId);
|
||||
switch (type) {
|
||||
switch (aItemType) {
|
||||
case PlacesUtils.bookmarks.TYPE_BOOKMARK:
|
||||
var uriString = PlacesUtils.bookmarks.getBookmarkURI(aItemId).spec;
|
||||
var isQuery = uriString.substr(0, 6) == "place:";
|
||||
|
@ -319,11 +319,13 @@ var bookmarksObserver = {
|
||||
onItemVisited: function() {},
|
||||
|
||||
onItemChanged: function PSB_onItemChanged(aItemId, aProperty,
|
||||
aIsAnnotationProperty, aNewValue) {
|
||||
aIsAnnotationProperty, aNewValue,
|
||||
aLastModified, aItemType,
|
||||
aParentId) {
|
||||
if (aProperty !== "title")
|
||||
return;
|
||||
|
||||
var views = getViewsForFolder(PlacesUtils.bookmarks.getFolderIdForItem(aItemId));
|
||||
var views = getViewsForFolder(aParentId);
|
||||
ok(views.length > 0, "Found affected views (" + views.length + "): " + views);
|
||||
|
||||
// Check that item has been moved in the correct position.
|
||||
|
23
browser/components/places/tests/unit/xpcshell.ini
Normal file
23
browser/components/places/tests/unit/xpcshell.ini
Normal file
@ -0,0 +1,23 @@
|
||||
[DEFAULT]
|
||||
head = head_bookmarks.js
|
||||
tail =
|
||||
|
||||
[test_384370.js]
|
||||
[test_398914.js]
|
||||
[test_421483.js]
|
||||
[test_457441-import-export-corrupt-bookmarks-html.js]
|
||||
[test_bookmarksRestoreNotification.js]
|
||||
[test_bookmarks_html.js]
|
||||
[test_browserGlue_corrupt.js]
|
||||
[test_browserGlue_corrupt_nobackup.js]
|
||||
[test_browserGlue_corrupt_nobackup_default.js]
|
||||
[test_browserGlue_distribution.js]
|
||||
[test_browserGlue_migrate.js]
|
||||
[test_browserGlue_prefs.js]
|
||||
[test_browserGlue_restore.js]
|
||||
[test_browserGlue_shutdown.js]
|
||||
[test_browserGlue_smartBookmarks.js]
|
||||
[test_clearHistory_shutdown.js]
|
||||
[test_leftpane_corruption_handling.js]
|
||||
[test_placesTxn.js]
|
||||
[test_txnGUIDs.js]
|
3
browser/components/preferences/aboutPermissions.css
Normal file
3
browser/components/preferences/aboutPermissions.css
Normal file
@ -0,0 +1,3 @@
|
||||
.site {
|
||||
-moz-binding: url("chrome://browser/content/preferences/aboutPermissions.xml#site");
|
||||
}
|
810
browser/components/preferences/aboutPermissions.js
Normal file
810
browser/components/preferences/aboutPermissions.js
Normal file
@ -0,0 +1,810 @@
|
||||
/* ***** 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 about:permissions code.
|
||||
*
|
||||
* 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):
|
||||
* Margaret Leibovic <margaret.leibovic@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 ***** */
|
||||
|
||||
let Ci = Components.interfaces;
|
||||
let Cc = Components.classes;
|
||||
let Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/PluralForm.jsm");
|
||||
Cu.import("resource://gre/modules/DownloadUtils.jsm");
|
||||
Cu.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
let gFaviconService = Cc["@mozilla.org/browser/favicon-service;1"].
|
||||
getService(Ci.nsIFaviconService);
|
||||
|
||||
let gPlacesDatabase = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsPIPlacesDatabase).
|
||||
DBConnection.
|
||||
clone(true);
|
||||
|
||||
let gSitesStmt = gPlacesDatabase.createAsyncStatement(
|
||||
"SELECT get_unreversed_host(rev_host) AS host " +
|
||||
"FROM moz_places " +
|
||||
"WHERE rev_host > '.' " +
|
||||
"AND visit_count > 0 " +
|
||||
"GROUP BY rev_host " +
|
||||
"ORDER BY MAX(frecency) DESC " +
|
||||
"LIMIT :limit");
|
||||
|
||||
let gVisitStmt = gPlacesDatabase.createAsyncStatement(
|
||||
"SELECT SUM(visit_count) AS count " +
|
||||
"FROM moz_places " +
|
||||
"WHERE rev_host = :rev_host");
|
||||
|
||||
/**
|
||||
* Permission types that should be tested with testExactPermission, as opposed
|
||||
* to testPermission. This is based on what consumers use to test these permissions.
|
||||
*/
|
||||
let TEST_EXACT_PERM_TYPES = ["geo"];
|
||||
|
||||
/**
|
||||
* Site object represents a single site, uniquely identified by a host.
|
||||
*/
|
||||
function Site(host) {
|
||||
this.host = host;
|
||||
this.listitem = null;
|
||||
|
||||
this.httpURI = NetUtil.newURI("http://" + this.host);
|
||||
this.httpsURI = NetUtil.newURI("https://" + this.host);
|
||||
|
||||
this._favicon = "";
|
||||
}
|
||||
|
||||
Site.prototype = {
|
||||
/**
|
||||
* Gets the favicon to use for the site. This will return the default favicon
|
||||
* if there is no favicon stored for the site.
|
||||
*
|
||||
* @return A favicon image URL.
|
||||
*/
|
||||
get favicon() {
|
||||
if (!this._favicon) {
|
||||
// TODO: Bug 657961: Make this async when bug 655270 is fixed.
|
||||
try {
|
||||
// First try to see if a favicon is stored for the http URI.
|
||||
this._favicon = gFaviconService.getFaviconForPage(this.httpURI).spec;
|
||||
} catch (e) {
|
||||
// getFaviconImageForPage returns the default favicon if no stored favicon is found.
|
||||
this._favicon = gFaviconService.getFaviconImageForPage(this.httpsURI).spec;
|
||||
}
|
||||
}
|
||||
return this._favicon;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the number of history visits for the site.
|
||||
*
|
||||
* @param aCallback
|
||||
* A function that takes the visit count (a number) as a parameter.
|
||||
*/
|
||||
getVisitCount: function Site_getVisitCount(aCallback) {
|
||||
let rev_host = this.host.split("").reverse().join("") + ".";
|
||||
gVisitStmt.params.rev_host = rev_host;
|
||||
gVisitStmt.executeAsync({
|
||||
handleResult: function(aResults) {
|
||||
let row = aResults.getNextRow();
|
||||
let count = row.getResultByName("count") || 0;
|
||||
try {
|
||||
aCallback(count);
|
||||
} catch (e) {
|
||||
Cu.reportError("AboutPermissions: " + e);
|
||||
}
|
||||
},
|
||||
handleError: function(aError) {
|
||||
Cu.reportError("AboutPermissions: " + aError);
|
||||
},
|
||||
handleCompletion: function(aReason) {
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets the permission value stored for a specified permission type.
|
||||
*
|
||||
* @param aType
|
||||
* The permission type string stored in permission manager.
|
||||
* e.g. "cookie", "geo", "indexedDB", "popup", "image"
|
||||
* @param aResultObj
|
||||
* An object that stores the permission value set for aType.
|
||||
*
|
||||
* @return A boolean indicating whether or not a permission is set.
|
||||
*/
|
||||
getPermission: function Site_getPermission(aType, aResultObj) {
|
||||
let permissionValue;
|
||||
if (TEST_EXACT_PERM_TYPES.indexOf(aType) == -1) {
|
||||
permissionValue = Services.perms.testPermission(this.httpURI, aType);
|
||||
} else {
|
||||
permissionValue = Services.perms.testExactPermission(this.httpURI, aType);
|
||||
}
|
||||
aResultObj.value = permissionValue;
|
||||
|
||||
return permissionValue != Ci.nsIPermissionManager.UNKNOWN_ACTION;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets a permission for the site given a permission type and value.
|
||||
*
|
||||
* @param aType
|
||||
* The permission type string stored in permission manager.
|
||||
* e.g. "cookie", "geo", "indexedDB", "popup", "image"
|
||||
* @param aPerm
|
||||
* The permission value to set for the permission type. This should
|
||||
* be one of the constants defined in nsIPermissionManager.
|
||||
*/
|
||||
setPermission: function Site_setPermission(aType, aPerm) {
|
||||
// Using httpURI is kind of bogus, but the permission manager stores the
|
||||
// permission for the host, so the right thing happens in the end.
|
||||
Services.perms.add(this.httpURI, aType, aPerm);
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears a user-set permission value for the site given a permission type.
|
||||
*
|
||||
* @param aType
|
||||
* The permission type string stored in permission manager.
|
||||
* e.g. "cookie", "geo", "indexedDB", "popup", "image"
|
||||
*/
|
||||
clearPermission: function Site_clearPermission(aType) {
|
||||
Services.perms.remove(this.host, aType);
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets cookies stored for the site. This does not return cookies stored
|
||||
* for the base domain, only the exact hostname stored for the site.
|
||||
*
|
||||
* @return An array of the cookies set for the site.
|
||||
*/
|
||||
get cookies() {
|
||||
let cookies = [];
|
||||
let enumerator = Services.cookies.getCookiesFromHost(this.host);
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let cookie = enumerator.getNext().QueryInterface(Ci.nsICookie2);
|
||||
// getCookiesFromHost returns cookies for base domain, but we only want
|
||||
// the cookies for the exact domain.
|
||||
if (cookie.rawHost == this.host) {
|
||||
cookies.push(cookie);
|
||||
}
|
||||
}
|
||||
return cookies;
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes a set of specific cookies from the browser.
|
||||
*/
|
||||
clearCookies: function Site_clearCookies() {
|
||||
this.cookies.forEach(function(aCookie) {
|
||||
Services.cookies.remove(aCookie.host, aCookie.name, aCookie.path, false);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Gets logins stored for the site.
|
||||
*
|
||||
* @return An array of the logins stored for the site.
|
||||
*/
|
||||
get logins() {
|
||||
// There could be more logins for different schemes/ports, but this covers
|
||||
// the vast majority of cases.
|
||||
let httpLogins = Services.logins.findLogins({}, this.httpURI.prePath, "", null);
|
||||
let httpsLogins = Services.logins.findLogins({}, this.httpsURI.prePath, "", null);
|
||||
return httpLogins.concat(httpsLogins);
|
||||
},
|
||||
|
||||
get loginSavingEnabled() {
|
||||
// Only say that login saving is blocked if it is blocked for both http and https.
|
||||
return Services.logins.getLoginSavingEnabled(this.httpURI.prePath) &&
|
||||
Services.logins.getLoginSavingEnabled(this.httpsURI.prePath);
|
||||
},
|
||||
|
||||
set loginSavingEnabled(isEnabled) {
|
||||
Services.logins.setLoginSavingEnabled(this.httpURI.prePath, isEnabled);
|
||||
Services.logins.setLoginSavingEnabled(this.httpsURI.prePath, isEnabled);
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes all data from the browser corresponding to the site.
|
||||
*/
|
||||
forgetSite: function Site_forgetSite() {
|
||||
let pb = Cc["@mozilla.org/privatebrowsing;1"].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
pb.removeDataFromDomain(this.host);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* PermissionDefaults object keeps track of default permissions for sites based
|
||||
* on global preferences.
|
||||
*
|
||||
* Inspired by pageinfo/permissions.js
|
||||
*/
|
||||
let PermissionDefaults = {
|
||||
UNKNOWN: Ci.nsIPermissionManager.UNKNOWN_ACTION, // 0
|
||||
ALLOW: Ci.nsIPermissionManager.ALLOW_ACTION, // 1
|
||||
DENY: Ci.nsIPermissionManager.DENY_ACTION, // 2
|
||||
SESSION: Ci.nsICookiePermission.ACCESS_SESSION, // 8
|
||||
|
||||
get password() {
|
||||
if (Services.prefs.getBoolPref("signon.rememberSignons")) {
|
||||
return this.ALLOW;
|
||||
}
|
||||
return this.DENY;
|
||||
},
|
||||
set password(aValue) {
|
||||
let value = (aValue == this.ALLOW);
|
||||
Services.prefs.setBoolPref("signon.rememberSignons", value);
|
||||
},
|
||||
|
||||
// For use with network.cookie.* prefs.
|
||||
COOKIE_ACCEPT: 0,
|
||||
COOKIE_DENY: 2,
|
||||
COOKIE_NORMAL: 0,
|
||||
COOKIE_SESSION: 2,
|
||||
|
||||
get cookie() {
|
||||
if (Services.prefs.getIntPref("network.cookie.cookieBehavior") == this.COOKIE_DENY) {
|
||||
return this.DENY;
|
||||
}
|
||||
|
||||
if (Services.prefs.getIntPref("network.cookie.lifetimePolicy") == this.COOKIE_DENY) {
|
||||
return this.SESSION;
|
||||
}
|
||||
return this.ALLOW;
|
||||
},
|
||||
set cookie(aValue) {
|
||||
let value = (aValue == this.DENY) ? this.COOKIE_DENY : this.COOKIE_ACCEPT;
|
||||
Services.prefs.setIntPref("network.cookie.cookieBehavior", value);
|
||||
|
||||
let lifetimeValue = aValue == this.SESSION ? this.COOKIE_SESSION :
|
||||
this.COOKIE_NORMAL;
|
||||
Services.prefs.setIntPref("network.cookie.lifetimePolicy", lifetimeValue);
|
||||
},
|
||||
|
||||
get geo() {
|
||||
if (!Services.prefs.getBoolPref("geo.enabled")) {
|
||||
return this.DENY;
|
||||
}
|
||||
// We always ask for permission to share location with a specific site, so
|
||||
// there is no global ALLOW.
|
||||
return this.UNKNOWN;
|
||||
},
|
||||
set geo(aValue) {
|
||||
let value = (aValue == this.ALLOW);
|
||||
Services.prefs.setBoolPref("geo.enabled", value);
|
||||
},
|
||||
|
||||
get indexedDB() {
|
||||
if (!Services.prefs.getBoolPref("dom.indexedDB.enabled")) {
|
||||
return this.DENY;
|
||||
}
|
||||
// We always ask for permission to enable indexedDB storage for a specific
|
||||
// site, so there is no global ALLOW.
|
||||
return this.UNKNOWN;
|
||||
},
|
||||
set indexedDB(aValue) {
|
||||
let value = (aValue == this.ALLOW);
|
||||
Services.prefs.setBoolPref("dom.indexedDB.enabled", value);
|
||||
},
|
||||
|
||||
get popup() {
|
||||
if (Services.prefs.getBoolPref("dom.disable_open_during_load")) {
|
||||
return this.DENY;
|
||||
}
|
||||
return this.ALLOW;
|
||||
},
|
||||
set popup(aValue) {
|
||||
let value = (aValue == this.DENY);
|
||||
Services.prefs.setBoolPref("dom.disable_open_during_load", value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* AboutPermissions manages the about:permissions page.
|
||||
*/
|
||||
let AboutPermissions = {
|
||||
/**
|
||||
* Number of sites to return from the places database.
|
||||
*/
|
||||
PLACES_SITES_LIMIT: 50,
|
||||
|
||||
/**
|
||||
* Stores a mapping of host strings to Site objects.
|
||||
*/
|
||||
_sites: {},
|
||||
|
||||
sitesList: null,
|
||||
_selectedSite: null,
|
||||
|
||||
/**
|
||||
* This reflects the permissions that we expose in the UI. These correspond
|
||||
* to permission type strings in the permission manager, PermissionDefaults,
|
||||
* and element ids in aboutPermissions.xul.
|
||||
*
|
||||
* Potential future additions: "sts/use", "sts/subd"
|
||||
*/
|
||||
_supportedPermissions: ["password", "cookie", "geo", "indexedDB", "popup"],
|
||||
|
||||
/**
|
||||
* Permissions that don't have a global "Allow" option.
|
||||
*/
|
||||
_noGlobalAllow: ["geo", "indexedDB"],
|
||||
|
||||
_stringBundle: Services.strings.
|
||||
createBundle("chrome://browser/locale/preferences/aboutPermissions.properties"),
|
||||
|
||||
/**
|
||||
* Called on page load.
|
||||
*/
|
||||
init: function() {
|
||||
this.sitesList = document.getElementById("sites-list");
|
||||
|
||||
this.getSitesFromPlaces();
|
||||
this.enumerateServices();
|
||||
|
||||
// Attach observers in case data changes while the page is open.
|
||||
Services.prefs.addObserver("signon.rememberSignons", this, false);
|
||||
Services.prefs.addObserver("network.cookie.", this, false);
|
||||
Services.prefs.addObserver("geo.enabled", this, false);
|
||||
Services.prefs.addObserver("dom.indexedDB.enabled", this, false);
|
||||
Services.prefs.addObserver("dom.disable_open_during_load", this, false);
|
||||
|
||||
Services.obs.addObserver(this, "perm-changed", false);
|
||||
Services.obs.addObserver(this, "passwordmgr-storage-changed", false);
|
||||
Services.obs.addObserver(this, "cookie-changed", false);
|
||||
Services.obs.addObserver(this, "browser:purge-domain-data", false);
|
||||
|
||||
this._observersInitialized = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Called on page unload.
|
||||
*/
|
||||
cleanUp: function() {
|
||||
if (this._observersInitialized) {
|
||||
Services.prefs.removeObserver("signon.rememberSignons", this, false);
|
||||
Services.prefs.removeObserver("network.cookie.", this, false);
|
||||
Services.prefs.removeObserver("geo.enabled", this, false);
|
||||
Services.prefs.removeObserver("dom.indexedDB.enabled", this, false);
|
||||
Services.prefs.removeObserver("dom.disable_open_during_load", this, false);
|
||||
|
||||
Services.obs.removeObserver(this, "perm-changed", false);
|
||||
Services.obs.removeObserver(this, "passwordmgr-storage-changed", false);
|
||||
Services.obs.removeObserver(this, "cookie-changed", false);
|
||||
Services.obs.removeObserver(this, "browser:purge-domain-data", false);
|
||||
}
|
||||
|
||||
gSitesStmt.finalize();
|
||||
gVisitStmt.finalize();
|
||||
},
|
||||
|
||||
observe: function (aSubject, aTopic, aData) {
|
||||
switch(aTopic) {
|
||||
case "perm-changed":
|
||||
// Permissions changes only affect individual sites.
|
||||
if (!this._selectedSite) {
|
||||
break;
|
||||
}
|
||||
// aSubject is null when nsIPermisionManager::removeAll() is called.
|
||||
if (!aSubject) {
|
||||
this._supportedPermissions.forEach(function(aType){
|
||||
this.updatePermission(aType);
|
||||
}, this);
|
||||
break;
|
||||
}
|
||||
let permission = aSubject.QueryInterface(Ci.nsIPermission);
|
||||
// We can't compare selectedSite.host and permission.host here because
|
||||
// we need to handle the case where a parent domain was changed in a
|
||||
// way that affects the subdomain.
|
||||
if (this._supportedPermissions.indexOf(permission.type) != -1) {
|
||||
this.updatePermission(permission.type);
|
||||
}
|
||||
break;
|
||||
case "nsPref:changed":
|
||||
this._supportedPermissions.forEach(function(aType){
|
||||
this.updatePermission(aType);
|
||||
}, this);
|
||||
break;
|
||||
case "passwordmgr-storage-changed":
|
||||
this.updatePermission("password");
|
||||
if (this._selectedSite) {
|
||||
this.updatePasswordsCount();
|
||||
}
|
||||
break;
|
||||
case "cookie-changed":
|
||||
if (this._selectedSite) {
|
||||
this.updateCookiesCount();
|
||||
}
|
||||
break;
|
||||
case "browser:purge-domain-data":
|
||||
this.deleteFromSitesList(aData);
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates Site objects for the top-frecency sites in the places database and stores
|
||||
* them in _sites. The number of sites created is controlled by PLACES_SITES_LIMIT.
|
||||
*/
|
||||
getSitesFromPlaces: function() {
|
||||
gSitesStmt.params.limit = this.PLACES_SITES_LIMIT;
|
||||
gSitesStmt.executeAsync({
|
||||
handleResult: function(aResults) {
|
||||
let row;
|
||||
while (row = aResults.getNextRow()) {
|
||||
let host = row.getResultByName("host");
|
||||
AboutPermissions.addHost(host);
|
||||
}
|
||||
},
|
||||
handleError: function(aError) {
|
||||
Cu.reportError("AboutPermissions: " + aError);
|
||||
},
|
||||
handleCompletion: function(aReason) {
|
||||
// Notify oberservers for testing purposes.
|
||||
Services.obs.notifyObservers(null, "browser-permissions-initialized", null);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Finds sites that have non-default permissions and creates Site objects for
|
||||
* them if they are not already stored in _sites.
|
||||
*/
|
||||
enumerateServices: function() {
|
||||
let logins = Services.logins.getAllLogins();
|
||||
logins.forEach(function(aLogin) {
|
||||
try {
|
||||
// aLogin.hostname is a string in origin URL format (e.g. "http://foo.com")
|
||||
let uri = NetUtil.newURI(aLogin.hostname);
|
||||
this.addHost(uri.host);
|
||||
} catch (e) {
|
||||
// newURI will throw for add-ons logins stored in chrome:// URIs
|
||||
}
|
||||
}, this);
|
||||
|
||||
let disabledHosts = Services.logins.getAllDisabledHosts();
|
||||
disabledHosts.forEach(function(aHostname) {
|
||||
try {
|
||||
// aHostname is a string in origin URL format (e.g. "http://foo.com")
|
||||
let uri = NetUtil.newURI(aHostname);
|
||||
this.addHost(uri.host);
|
||||
} catch (e) {
|
||||
// newURI will throw for add-ons logins stored in chrome:// URIs
|
||||
}
|
||||
}, this);
|
||||
|
||||
let (enumerator = Services.perms.enumerator) {
|
||||
while (enumerator.hasMoreElements()) {
|
||||
let permission = enumerator.getNext().QueryInterface(Ci.nsIPermission);
|
||||
// Only include sites with exceptions set for supported permission types.
|
||||
if (this._supportedPermissions.indexOf(permission.type) != -1) {
|
||||
this.addHost(permission.host);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Creates a new Site and adds it to _sites if it's not already there.
|
||||
*
|
||||
* @param aHost
|
||||
* A host string.
|
||||
*/
|
||||
addHost: function(aHost) {
|
||||
if (aHost in this._sites) {
|
||||
return;
|
||||
}
|
||||
let site = new Site(aHost);
|
||||
this._sites[aHost] = site;
|
||||
this.addToSitesList(site);
|
||||
},
|
||||
|
||||
/**
|
||||
* Populates sites-list richlistbox with data from Site object.
|
||||
*
|
||||
* @param aSite
|
||||
* A Site object.
|
||||
*/
|
||||
addToSitesList: function(aSite) {
|
||||
let item = document.createElement("richlistitem");
|
||||
item.setAttribute("class", "site");
|
||||
item.setAttribute("value", aSite.host);
|
||||
item.setAttribute("favicon", aSite.favicon);
|
||||
aSite.listitem = item;
|
||||
|
||||
this.sitesList.appendChild(item);
|
||||
},
|
||||
|
||||
/**
|
||||
* Hides sites in richlistbox based on search text in sites-filter textbox.
|
||||
*/
|
||||
filterSitesList: function() {
|
||||
let siteItems = this.sitesList.children;
|
||||
let filterValue = document.getElementById("sites-filter").value.toLowerCase();
|
||||
|
||||
if (filterValue == "") {
|
||||
for (let i = 0; i < siteItems.length; i++) {
|
||||
siteItems[i].collapsed = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 0; i < siteItems.length; i++) {
|
||||
let siteValue = siteItems[i].value.toLowerCase();
|
||||
siteItems[i].collapsed = siteValue.indexOf(filterValue) == -1;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Removes all evidence of the selected site. The "forget this site" observer
|
||||
* will call deleteFromSitesList to update the UI.
|
||||
*/
|
||||
forgetSite: function() {
|
||||
this._selectedSite.forgetSite();
|
||||
},
|
||||
|
||||
/**
|
||||
* Deletes sites for a host and all of its sub-domains. Removes these sites
|
||||
* from _sites and removes their corresponding elements from the DOM.
|
||||
*
|
||||
* @param aHost
|
||||
* The host string corresponding to the site to delete.
|
||||
*/
|
||||
deleteFromSitesList: function(aHost) {
|
||||
for each (let site in this._sites) {
|
||||
if (site.host.hasRootDomain(aHost)) {
|
||||
if (site == this._selectedSite) {
|
||||
// Replace site-specific interface with "All Sites" interface.
|
||||
this.sitesList.selectedItem = document.getElementById("all-sites-item");
|
||||
}
|
||||
|
||||
this.sitesList.removeChild(site.listitem);
|
||||
delete this._sites[site.host];
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows interface for managing site-specific permissions.
|
||||
*/
|
||||
onSitesListSelect: function(event) {
|
||||
if (event.target.selectedItem.id == "all-sites-item") {
|
||||
// Clear the header label value from the previously selected site.
|
||||
document.getElementById("site-label").value = "";
|
||||
this.manageDefaultPermissions();
|
||||
return;
|
||||
}
|
||||
|
||||
let host = event.target.value;
|
||||
let site = this._selectedSite = this._sites[host];
|
||||
document.getElementById("site-label").value = host;
|
||||
document.getElementById("header-deck").selectedPanel =
|
||||
document.getElementById("site-header");
|
||||
|
||||
this.updateVisitCount();
|
||||
this.updatePermissionsBox();
|
||||
},
|
||||
|
||||
/**
|
||||
* Shows interface for managing default permissions. This corresponds to
|
||||
* the "All Sites" list item.
|
||||
*/
|
||||
manageDefaultPermissions: function() {
|
||||
this._selectedSite = null;
|
||||
|
||||
document.getElementById("header-deck").selectedPanel =
|
||||
document.getElementById("defaults-header");
|
||||
|
||||
this.updatePermissionsBox();
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates permissions interface based on selected site.
|
||||
*/
|
||||
updatePermissionsBox: function() {
|
||||
this._supportedPermissions.forEach(function(aType){
|
||||
this.updatePermission(aType);
|
||||
}, this);
|
||||
|
||||
this.updatePasswordsCount();
|
||||
this.updateCookiesCount();
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets menulist for a given permission to the correct state, based on the
|
||||
* stored permission.
|
||||
*
|
||||
* @param aType
|
||||
* The permission type string stored in permission manager.
|
||||
* e.g. "cookie", "geo", "indexedDB", "popup", "image"
|
||||
*/
|
||||
updatePermission: function(aType) {
|
||||
let allowItem = document.getElementById(aType + "-" + PermissionDefaults.ALLOW);
|
||||
if (!this._selectedSite &&
|
||||
this._noGlobalAllow.indexOf(aType) != -1) {
|
||||
allowItem.hidden = true;
|
||||
return;
|
||||
}
|
||||
|
||||
allowItem.hidden = false;
|
||||
|
||||
let permissionMenulist = document.getElementById(aType + "-menulist");
|
||||
let permissionValue;
|
||||
if (!this._selectedSite) {
|
||||
|
||||
// If there is no selected site, we are updating the default permissions interface.
|
||||
permissionValue = PermissionDefaults[aType];
|
||||
} else if (aType == "password") {
|
||||
// Services.logins.getLoginSavingEnabled already looks at the default
|
||||
// permission, so we don't need to.
|
||||
permissionValue = this._selectedSite.loginSavingEnabled ?
|
||||
PermissionDefaults.ALLOW : PermissionDefaults.DENY;
|
||||
} else {
|
||||
let result = {};
|
||||
permissionValue = this._selectedSite.getPermission(aType, result) ?
|
||||
result.value : PermissionDefaults[aType];
|
||||
}
|
||||
|
||||
permissionMenulist.selectedItem = document.getElementById(aType + "-" + permissionValue);
|
||||
},
|
||||
|
||||
onPermissionCommand: function(event) {
|
||||
let permissionType = event.currentTarget.getAttribute("type");
|
||||
let permissionValue = event.target.value;
|
||||
|
||||
if (!this._selectedSite) {
|
||||
// If there is no selected site, we are setting the default permission.
|
||||
PermissionDefaults[permissionType] = permissionValue;
|
||||
} else if (permissionType == "password") {
|
||||
let isEnabled = permissionValue == PermissionDefaults.ALLOW;
|
||||
this._selectedSite.loginSavingEnabled = isEnabled;
|
||||
} else {
|
||||
this._selectedSite.setPermission(permissionType, permissionValue);
|
||||
}
|
||||
},
|
||||
|
||||
updateVisitCount: function() {
|
||||
this._selectedSite.getVisitCount(function(aCount) {
|
||||
let visitForm = AboutPermissions._stringBundle.GetStringFromName("visitCount");
|
||||
let visitLabel = PluralForm.get(aCount, visitForm)
|
||||
.replace("#1", aCount);
|
||||
document.getElementById("site-visit-count").value = visitLabel;
|
||||
});
|
||||
},
|
||||
|
||||
updatePasswordsCount: function() {
|
||||
if (!this._selectedSite) {
|
||||
document.getElementById("passwords-count").hidden = true;
|
||||
document.getElementById("passwords-manage-all-button").hidden = false;
|
||||
return;
|
||||
}
|
||||
|
||||
let passwordsCount = this._selectedSite.logins.length;
|
||||
let passwordsForm = this._stringBundle.GetStringFromName("passwordsCount");
|
||||
let passwordsLabel = PluralForm.get(passwordsCount, passwordsForm)
|
||||
.replace("#1", passwordsCount);
|
||||
|
||||
document.getElementById("passwords-label").value = passwordsLabel;
|
||||
document.getElementById("passwords-manage-button").disabled = (passwordsCount < 1);
|
||||
document.getElementById("passwords-manage-all-button").hidden = true;
|
||||
document.getElementById("passwords-count").hidden = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Opens password manager dialog.
|
||||
*/
|
||||
managePasswords: function() {
|
||||
let selectedHost = "";
|
||||
if (this._selectedSite) {
|
||||
selectedHost = this._selectedSite.host;
|
||||
}
|
||||
|
||||
let win = Services.wm.getMostRecentWindow("Toolkit:PasswordManager");
|
||||
if (win) {
|
||||
win.setFilter(selectedHost);
|
||||
win.focus();
|
||||
} else {
|
||||
window.openDialog("chrome://passwordmgr/content/passwordManager.xul",
|
||||
"Toolkit:PasswordManager", "", {filterString : selectedHost});
|
||||
}
|
||||
},
|
||||
|
||||
updateCookiesCount: function() {
|
||||
if (!this._selectedSite) {
|
||||
document.getElementById("cookies-count").hidden = true;
|
||||
document.getElementById("cookies-clear-all-button").hidden = false;
|
||||
document.getElementById("cookies-manage-all-button").hidden = false;
|
||||
return;
|
||||
}
|
||||
|
||||
let cookiesCount = this._selectedSite.cookies.length;
|
||||
let cookiesForm = this._stringBundle.GetStringFromName("cookiesCount");
|
||||
let cookiesLabel = PluralForm.get(cookiesCount, cookiesForm)
|
||||
.replace("#1", cookiesCount);
|
||||
|
||||
document.getElementById("cookies-label").value = cookiesLabel;
|
||||
document.getElementById("cookies-clear-button").disabled = (cookiesCount < 1);
|
||||
document.getElementById("cookies-manage-button").disabled = (cookiesCount < 1);
|
||||
document.getElementById("cookies-clear-all-button").hidden = true;
|
||||
document.getElementById("cookies-manage-all-button").hidden = true;
|
||||
document.getElementById("cookies-count").hidden = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clears cookies for the selected site.
|
||||
*/
|
||||
clearCookies: function() {
|
||||
if (!this._selectedSite) {
|
||||
return;
|
||||
}
|
||||
let site = this._selectedSite;
|
||||
site.clearCookies(site.cookies);
|
||||
this.updateCookiesCount();
|
||||
},
|
||||
|
||||
/**
|
||||
* Opens cookie manager dialog.
|
||||
*/
|
||||
manageCookies: function() {
|
||||
let selectedHost = "";
|
||||
if (this._selectedSite) {
|
||||
selectedHost = this._selectedSite.host;
|
||||
}
|
||||
|
||||
let win = Services.wm.getMostRecentWindow("Browser:Cookies");
|
||||
if (win) {
|
||||
win.gCookiesWindow.setFilter(selectedHost);
|
||||
win.focus();
|
||||
} else {
|
||||
window.openDialog("chrome://browser/content/preferences/cookies.xul",
|
||||
"Browser:Cookies", "", {filterString : selectedHost});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// See nsPrivateBrowsingService.js
|
||||
String.prototype.hasRootDomain = function hasRootDomain(aDomain) {
|
||||
let index = this.indexOf(aDomain);
|
||||
if (index == -1)
|
||||
return false;
|
||||
|
||||
if (this == aDomain)
|
||||
return true;
|
||||
|
||||
let prevChar = this[index - 1];
|
||||
return (index == (this.length - aDomain.length)) &&
|
||||
(prevChar == "." || prevChar == "/");
|
||||
}
|
51
browser/components/preferences/aboutPermissions.xml
Normal file
51
browser/components/preferences/aboutPermissions.xml
Normal file
@ -0,0 +1,51 @@
|
||||
<?xml version="1.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 about:permssions code.
|
||||
-
|
||||
- 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):
|
||||
- Margaret Leibovic <margaret.leibovic@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 LGPL or the GPL. 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 ***** -->
|
||||
|
||||
<!DOCTYPE bindings>
|
||||
<bindings xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl">
|
||||
<binding id="site" extends="chrome://global/content/bindings/richlistbox.xml#richlistitem">
|
||||
<content>
|
||||
<xul:hbox class="site-container" align="center">
|
||||
<xul:image xbl:inherits="src=favicon" class="site-favicon"/>
|
||||
<xul:label xbl:inherits="value,selected" class="site-domain" crop="end"/>
|
||||
</xul:hbox>
|
||||
</content>
|
||||
</binding>
|
||||
</bindings>
|
228
browser/components/preferences/aboutPermissions.xul
Normal file
228
browser/components/preferences/aboutPermissions.xul
Normal file
@ -0,0 +1,228 @@
|
||||
<?xml version="1.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 about:permssions code.
|
||||
-
|
||||
- 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):
|
||||
- Margaret Leibovic <margaret.leibovic@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 LGPL or the GPL. 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 ***** -->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://browser/content/preferences/aboutPermissions.css"?>
|
||||
<?xml-stylesheet href="chrome://browser/skin/preferences/aboutPermissions.css"?>
|
||||
|
||||
<!DOCTYPE page [
|
||||
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
|
||||
%brandDTD;
|
||||
<!ENTITY % aboutPermissionsDTD SYSTEM "chrome://browser/locale/preferences/aboutPermissions.dtd" >
|
||||
%aboutPermissionsDTD;
|
||||
]>
|
||||
|
||||
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:xhtml="http://www.w3.org/1999/xhtml"
|
||||
id="permissions-page" title="&permissionsManager.title;"
|
||||
onload="AboutPermissions.init();"
|
||||
onunload="AboutPermissions.cleanUp();"
|
||||
role="application">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://browser/content/preferences/aboutPermissions.js"/>
|
||||
|
||||
<hbox flex="1" id="permissions-content">
|
||||
|
||||
<vbox id="sites-box">
|
||||
<textbox id="sites-filter"
|
||||
emptytext="&sites.search;"
|
||||
oncommand="AboutPermissions.filterSitesList();"
|
||||
type="search"/>
|
||||
<richlistbox id="sites-list"
|
||||
flex="1"
|
||||
class="list"
|
||||
onselect="AboutPermissions.onSitesListSelect(event);">
|
||||
<richlistitem id="all-sites-item"
|
||||
class="site"
|
||||
value="&sites.allSites;"/>
|
||||
</richlistbox>
|
||||
</vbox>
|
||||
|
||||
<vbox id="permissions-box" flex="1">
|
||||
|
||||
<deck id="header-deck">
|
||||
<hbox id="site-header" class="pref-item" align="center">
|
||||
<description id="site-description">
|
||||
&header.site.start;<label id="site-label"/>&header.site.end;
|
||||
</description>
|
||||
<label id="site-visit-count"/>
|
||||
<spacer flex="1"/>
|
||||
<button id="forget-site-button"
|
||||
label="&permissions.forgetSite;"
|
||||
oncommand="AboutPermissions.forgetSite();"/>
|
||||
</hbox>
|
||||
|
||||
<hbox id="defaults-header" class="pref-item" align="center">
|
||||
<description id="defaults-description">
|
||||
&header.defaults;
|
||||
</description>
|
||||
</hbox>
|
||||
</deck>
|
||||
|
||||
<!-- Passwords -->
|
||||
<hbox id="password-pref-item"
|
||||
class="pref-item" align="top">
|
||||
<image class="pref-icon" type="password"/>
|
||||
<vbox>
|
||||
<label class="pref-title" value="&password.label;"/>
|
||||
<hbox align="center">
|
||||
<menulist id="password-menulist"
|
||||
class="pref-menulist"
|
||||
type="password"
|
||||
oncommand="AboutPermissions.onPermissionCommand(event);">
|
||||
<menupopup>
|
||||
<menuitem id="password-1" value="1" label="&permission.allow;"/>
|
||||
<menuitem id="password-2" value="2" label="&permission.block;"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<button id="passwords-manage-all-button"
|
||||
label="&password.manage;"
|
||||
oncommand="AboutPermissions.managePasswords();"/>
|
||||
</hbox>
|
||||
<hbox id="passwords-count" align="center">
|
||||
<label id="passwords-label"/>
|
||||
<button id="passwords-manage-button"
|
||||
label="&password.manage;"
|
||||
oncommand="AboutPermissions.managePasswords();"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
<!-- Geolocation -->
|
||||
<hbox id="geo-pref-item"
|
||||
class="pref-item" align="top">
|
||||
<image class="pref-icon" type="geo"/>
|
||||
<vbox>
|
||||
<label class="pref-title" value="&geo.label;"/>
|
||||
<hbox>
|
||||
<menulist id="geo-menulist"
|
||||
class="pref-menulist"
|
||||
type="geo"
|
||||
oncommand="AboutPermissions.onPermissionCommand(event);">
|
||||
<menupopup>
|
||||
<menuitem id="geo-0" value="0" label="&permission.alwaysAsk;"/>
|
||||
<menuitem id="geo-1" value="1" label="&permission.allow;"/>
|
||||
<menuitem id="geo-2" value="2" label="&permission.block;"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
<!-- Cookies -->
|
||||
<hbox id="cookie-pref-item"
|
||||
class="pref-item" align="top">
|
||||
<image class="pref-icon" type="cookie"/>
|
||||
<vbox>
|
||||
<label class="pref-title" value="&cookie.label;"/>
|
||||
<hbox algin="center">
|
||||
<menulist id="cookie-menulist"
|
||||
class="pref-menulist"
|
||||
type="cookie"
|
||||
oncommand="AboutPermissions.onPermissionCommand(event);">
|
||||
<menupopup>
|
||||
<menuitem id="cookie-1" value="1" label="&permission.allow;"/>
|
||||
<menuitem id="cookie-8" value="8" label="&permission.allowForSession;"/>
|
||||
<menuitem id="cookie-2" value="2" label="&permission.block;"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<button id="cookies-clear-all-button"
|
||||
label="&cookie.clearAll;"
|
||||
oncommand="Services.cookies.removeAll();"/>
|
||||
<button id="cookies-manage-all-button"
|
||||
label="&cookie.manage;"
|
||||
oncommand="AboutPermissions.manageCookies();"/>
|
||||
</hbox>
|
||||
<hbox id="cookies-count" align="center">
|
||||
<label id="cookies-label"/>
|
||||
<button id="cookies-clear-button"
|
||||
label="&cookie.clear;"
|
||||
oncommand="AboutPermissions.clearCookies();"/>
|
||||
<button id="cookies-manage-button"
|
||||
label="&cookie.manage;"
|
||||
oncommand="AboutPermissions.manageCookies();"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
<!-- Pop-up Blocking -->
|
||||
<hbox id="popup-pref-item"
|
||||
class="pref-item" align="top">
|
||||
<image class="pref-icon" type="popup"/>
|
||||
<vbox>
|
||||
<label class="pref-title" value="&popup.label;"/>
|
||||
<hbox>
|
||||
<menulist id="popup-menulist"
|
||||
class="pref-menulist"
|
||||
type="popup"
|
||||
oncommand="AboutPermissions.onPermissionCommand(event);">
|
||||
<menupopup>
|
||||
<menuitem id="popup-1" value="1" label="&permission.allow;"/>
|
||||
<menuitem id="popup-2" value="2" label="&permission.block;"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
<!-- IndexedDB Storage -->
|
||||
<hbox id="indexedDB-pref-item"
|
||||
class="pref-item" align="top">
|
||||
<image class="pref-icon" type="indexedDB"/>
|
||||
<vbox>
|
||||
<label class="pref-title" value="&indexedDB.label;"/>
|
||||
<hbox>
|
||||
<menulist id="indexedDB-menulist"
|
||||
class="pref-menulist"
|
||||
type="indexedDB"
|
||||
oncommand="AboutPermissions.onPermissionCommand(event);">
|
||||
<menupopup>
|
||||
<menuitem id="indexedDB-0" value="0" label="&permission.alwaysAsk;"/>
|
||||
<menuitem id="indexedDB-1" value="1" label="&permission.allow;"/>
|
||||
<menuitem id="indexedDB-2" value="2" label="&permission.block;"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
</page>
|
@ -1,4 +1,8 @@
|
||||
browser.jar:
|
||||
* content/browser/preferences/aboutPermissions.xul
|
||||
* content/browser/preferences/aboutPermissions.js
|
||||
* content/browser/preferences/aboutPermissions.css
|
||||
* content/browser/preferences/aboutPermissions.xml
|
||||
* content/browser/preferences/advanced.xul
|
||||
* content/browser/preferences/advanced.js
|
||||
* content/browser/preferences/advanced-scripts.xul
|
||||
|
@ -55,6 +55,7 @@ _BROWSER_FILES = \
|
||||
browser_privacypane_6.js \
|
||||
browser_privacypane_7.js \
|
||||
browser_privacypane_8.js \
|
||||
browser_permissions.js \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_FILES)
|
||||
|
@ -1,5 +1,6 @@
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
resetPreferences();
|
||||
|
||||
function observer(win, topic, data) {
|
||||
if (topic != "main-pane-loaded")
|
||||
@ -57,11 +58,13 @@ function runTest(win) {
|
||||
is(menu.selectedItem, option, "The correct value should be restored");
|
||||
|
||||
// cleanup
|
||||
[pbAutoStartPref, startupPref].forEach(function (pref) {
|
||||
if (pref.hasUserValue)
|
||||
pref.reset();
|
||||
});
|
||||
resetPreferences();
|
||||
|
||||
win.close();
|
||||
finish();
|
||||
}
|
||||
|
||||
function resetPreferences() {
|
||||
Services.prefs.clearUserPref("browser.startup.page");
|
||||
Services.prefs.clearUserPref("browser.privatebrowsing.autostart");
|
||||
}
|
||||
|
304
browser/components/preferences/tests/browser_permissions.js
Normal file
304
browser/components/preferences/tests/browser_permissions.js
Normal file
@ -0,0 +1,304 @@
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
Components.utils.import("resource://gre/modules/PlacesUtils.jsm");
|
||||
Components.utils.import("resource://gre/modules/NetUtil.jsm");
|
||||
|
||||
const ABOUT_PERMISSIONS_SPEC = "about:permissions";
|
||||
|
||||
const TEST_URI_1 = NetUtil.newURI("http://mozilla.com/");
|
||||
const TEST_URI_2 = NetUtil.newURI("http://mozilla.org/");
|
||||
|
||||
// values from DefaultPermissions object
|
||||
const PERM_UNKNOWN = 0;
|
||||
const PERM_ALLOW = 1;
|
||||
const PERM_DENY = 2;
|
||||
const PERM_SESION = 8;
|
||||
|
||||
// used to set permissions on test sites
|
||||
const TEST_PERMS = {
|
||||
"password": PERM_ALLOW,
|
||||
"cookie": PERM_ALLOW,
|
||||
"geo": PERM_UNKNOWN,
|
||||
"indexedDB": PERM_UNKNOWN,
|
||||
"popup": PERM_DENY
|
||||
};
|
||||
|
||||
// number of managed permissions in the interface
|
||||
const TEST_PERMS_COUNT = 5;
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
registerCleanupFunction(cleanUp);
|
||||
|
||||
// add test history visit
|
||||
PlacesUtils.history.addVisit(TEST_URI_1, Date.now() * 1000, null,
|
||||
Ci.nsINavHistoryService.TRANSITION_LINK, false, 0);
|
||||
|
||||
// set permissions ourselves to avoid problems with different defaults
|
||||
// from test harness configuration
|
||||
for (let type in TEST_PERMS) {
|
||||
if (type == "password") {
|
||||
Services.logins.setLoginSavingEnabled(TEST_URI_2.prePath, true);
|
||||
} else {
|
||||
// set permissions on a site without history visits to test enumerateServices
|
||||
Services.perms.add(TEST_URI_2, type, TEST_PERMS[type]);
|
||||
}
|
||||
}
|
||||
|
||||
function observer() {
|
||||
Services.obs.removeObserver(observer, "browser-permissions-initialized", false);
|
||||
runNextTest();
|
||||
}
|
||||
Services.obs.addObserver(observer, "browser-permissions-initialized", false);
|
||||
|
||||
// open about:permissions
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:permissions");
|
||||
}
|
||||
|
||||
function cleanUp() {
|
||||
for (let type in TEST_PERMS) {
|
||||
if (type != "password") {
|
||||
Services.perms.remove(TEST_URI_1.host, type);
|
||||
Services.perms.remove(TEST_URI_2.host, type);
|
||||
}
|
||||
}
|
||||
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
}
|
||||
|
||||
function runNextTest() {
|
||||
if (gTestIndex == tests.length) {
|
||||
waitForClearHistory(finish);
|
||||
return;
|
||||
}
|
||||
|
||||
let nextTest = tests[gTestIndex++];
|
||||
info("[" + nextTest.name + "] running test");
|
||||
nextTest();
|
||||
}
|
||||
|
||||
var gSitesList;
|
||||
var gHeaderDeck;
|
||||
var gSiteLabel;
|
||||
|
||||
var gTestIndex = 0;
|
||||
var tests = [
|
||||
function test_page_load() {
|
||||
is(gBrowser.currentURI.spec, ABOUT_PERMISSIONS_SPEC, "about:permissions loaded");
|
||||
|
||||
gSitesList = gBrowser.contentDocument.getElementById("sites-list");
|
||||
ok(gSitesList, "got sites list");
|
||||
|
||||
gHeaderDeck = gBrowser.contentDocument.getElementById("header-deck");
|
||||
ok(gHeaderDeck, "got header deck");
|
||||
|
||||
gSiteLabel = gBrowser.contentDocument.getElementById("site-label");
|
||||
ok(gSiteLabel, "got site label");
|
||||
|
||||
runNextTest();
|
||||
},
|
||||
|
||||
function test_sites_list() {
|
||||
is(gSitesList.firstChild.id, "all-sites-item",
|
||||
"all sites is the first item in the sites list");
|
||||
|
||||
ok(getSiteItem(TEST_URI_1.host), "site item from places db exists");
|
||||
ok(getSiteItem(TEST_URI_2.host), "site item from enumerating services exists");
|
||||
|
||||
runNextTest();
|
||||
},
|
||||
|
||||
function test_filter_sites_list() {
|
||||
// set filter to test host
|
||||
let sitesFilter = gBrowser.contentDocument.getElementById("sites-filter");
|
||||
sitesFilter.value = TEST_URI_1.host;
|
||||
sitesFilter.doCommand();
|
||||
|
||||
// make sure correct sites are collapsed/showing
|
||||
let testSite1 = getSiteItem(TEST_URI_1.host);
|
||||
ok(!testSite1.collapsed, "test site 1 is not collapsed");
|
||||
let testSite2 = getSiteItem(TEST_URI_2.host);
|
||||
ok(testSite2.collapsed, "test site 2 is collapsed");
|
||||
|
||||
// clear filter
|
||||
sitesFilter.value = "";
|
||||
sitesFilter.doCommand();
|
||||
|
||||
runNextTest();
|
||||
},
|
||||
|
||||
function test_all_sites() {
|
||||
// "All Sites" item should be selected when the page is first loaded
|
||||
is(gSitesList.selectedItem, gBrowser.contentDocument.getElementById("all-sites-item"),
|
||||
"all sites item is selected");
|
||||
|
||||
let defaultsHeader = gBrowser.contentDocument.getElementById("defaults-header");
|
||||
is(defaultsHeader, gHeaderDeck.selectedPanel,
|
||||
"correct header shown for all sites");
|
||||
|
||||
ok(gBrowser.contentDocument.getElementById("passwords-count").hidden,
|
||||
"passwords count is hidden");
|
||||
ok(gBrowser.contentDocument.getElementById("cookies-count").hidden,
|
||||
"cookies count is hidden");
|
||||
|
||||
runNextTest();
|
||||
},
|
||||
|
||||
function test_all_sites_permission() {
|
||||
// there should be no user-set pref for cookie behavior
|
||||
is(Services.prefs.getIntPref("network.cookie.cookieBehavior"), PERM_UNKNOWN,
|
||||
"network.cookie.cookieBehavior is expected default");
|
||||
|
||||
// the default behavior is to allow cookies
|
||||
let cookieMenulist = getPermissionMenulist("cookie");
|
||||
is(cookieMenulist.value, PERM_ALLOW,
|
||||
"menulist correctly shows that cookies are allowed");
|
||||
|
||||
// set the pref to block cookies
|
||||
Services.prefs.setIntPref("network.cookie.cookieBehavior", PERM_DENY);
|
||||
// check to make sure this change is reflected in the UI
|
||||
is(cookieMenulist.value, PERM_DENY, "menulist correctly shows that cookies are blocked");
|
||||
|
||||
// clear the pref
|
||||
Services.prefs.clearUserPref("network.cookie.cookieBehavior");
|
||||
|
||||
runNextTest();
|
||||
},
|
||||
|
||||
function test_manage_all_passwords() {
|
||||
// make sure "Manage All Passwords..." button opens the correct dialog
|
||||
addWindowListener("chrome://passwordmgr/content/passwordManager.xul", runNextTest);
|
||||
gBrowser.contentDocument.getElementById("passwords-manage-all-button").doCommand();
|
||||
|
||||
},
|
||||
|
||||
function test_manage_all_cookies() {
|
||||
// make sure "Manage All Cookies..." button opens the correct dialog
|
||||
addWindowListener("chrome://browser/content/preferences/cookies.xul", runNextTest);
|
||||
gBrowser.contentDocument.getElementById("cookies-manage-all-button").doCommand();
|
||||
},
|
||||
|
||||
function test_select_site() {
|
||||
// select the site that has the permissions we set at the beginning of the test
|
||||
let testSiteItem = getSiteItem(TEST_URI_2.host);
|
||||
gSitesList.selectedItem = testSiteItem;
|
||||
|
||||
let siteHeader = gBrowser.contentDocument.getElementById("site-header");
|
||||
is(siteHeader, gHeaderDeck.selectedPanel,
|
||||
"correct header shown for a specific site");
|
||||
is(gSiteLabel.value, TEST_URI_2.host, "header updated for selected site");
|
||||
|
||||
ok(!gBrowser.contentDocument.getElementById("passwords-count").hidden,
|
||||
"passwords count is not hidden");
|
||||
ok(!gBrowser.contentDocument.getElementById("cookies-count").hidden,
|
||||
"cookies count is not hidden");
|
||||
|
||||
runNextTest();
|
||||
},
|
||||
|
||||
function test_permissions() {
|
||||
let menulists = gBrowser.contentDocument.getElementsByClassName("pref-menulist");
|
||||
is(menulists.length, TEST_PERMS_COUNT, "got expected number of managed permissions");
|
||||
|
||||
for (let i = 0; i < menulists.length; i++) {
|
||||
let permissionMenulist = menulists.item(i);
|
||||
let permissionType = permissionMenulist.getAttribute("type");
|
||||
|
||||
// permissions should reflect what we set at the beginning of the test
|
||||
is(permissionMenulist.value, TEST_PERMS[permissionType],
|
||||
"got expected value for " + permissionType + " permission");
|
||||
}
|
||||
|
||||
runNextTest();
|
||||
},
|
||||
|
||||
function test_permission_change() {
|
||||
let geoMenulist = getPermissionMenulist("geo");
|
||||
is(geoMenulist.value, PERM_UNKNOWN, "menulist correctly shows that geolocation permission is unspecified");
|
||||
|
||||
// change a permission programatically
|
||||
Services.perms.add(TEST_URI_2, "geo", PERM_DENY);
|
||||
// check to make sure this change is reflected in the UI
|
||||
is(geoMenulist.value, PERM_DENY, "menulist shows that geolocation is blocked");
|
||||
|
||||
// change a permisssion in the UI
|
||||
let geoAllowItem = gBrowser.contentDocument.getElementById("geo-" + PERM_ALLOW);
|
||||
geoMenulist.selectedItem = geoAllowItem;
|
||||
geoMenulist.doCommand();
|
||||
// check to make sure this change is reflected in the permission manager
|
||||
is(Services.perms.testPermission(TEST_URI_2, "geo"), PERM_ALLOW,
|
||||
"permission manager shows that geolocation is allowed");
|
||||
|
||||
runNextTest();
|
||||
},
|
||||
|
||||
function test_forget_site() {
|
||||
// click "Forget About This Site" button
|
||||
gBrowser.contentDocument.getElementById("forget-site-button").doCommand();
|
||||
|
||||
is(gSiteLabel.value, "", "site label cleared");
|
||||
|
||||
let allSitesItem = gBrowser.contentDocument.getElementById("all-sites-item");
|
||||
is(gSitesList.selectedItem, allSitesItem,
|
||||
"all sites item selected after forgetting selected site");
|
||||
|
||||
// check to make sure site is gone from sites list
|
||||
let testSiteItem = getSiteItem(TEST_URI_2.host);
|
||||
ok(!testSiteItem, "site removed from sites list");
|
||||
|
||||
// check to make sure we forgot all permissions corresponding to site
|
||||
for (let type in TEST_PERMS) {
|
||||
if (type == "password") {
|
||||
ok(Services.logins.getLoginSavingEnabled(TEST_URI_2.prePath),
|
||||
"password saving should be enabled by default");
|
||||
} else {
|
||||
is(Services.perms.testPermission(TEST_URI_2, type), PERM_UNKNOWN,
|
||||
type + " permission should not be set for test site 2");
|
||||
}
|
||||
}
|
||||
|
||||
runNextTest();
|
||||
}
|
||||
];
|
||||
|
||||
function getPermissionMenulist(aType) {
|
||||
return gBrowser.contentDocument.getElementById(aType + "-menulist");
|
||||
}
|
||||
|
||||
function getSiteItem(aHost) {
|
||||
return gBrowser.contentDocument.
|
||||
querySelector(".site[value='" + aHost + "']");
|
||||
}
|
||||
|
||||
function addWindowListener(aURL, aCallback) {
|
||||
Services.wm.addListener({
|
||||
onOpenWindow: function(aXULWindow) {
|
||||
info("window opened, waiting for focus");
|
||||
Services.wm.removeListener(this);
|
||||
|
||||
var domwindow = aXULWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowInternal);
|
||||
waitForFocus(function() {
|
||||
is(domwindow.document.location.href, aURL, "should have seen the right window open");
|
||||
domwindow.close();
|
||||
aCallback();
|
||||
}, domwindow);
|
||||
},
|
||||
onCloseWindow: function(aXULWindow) { },
|
||||
onWindowTitleChange: function(aXULWindow, aNewTitle) { }
|
||||
});
|
||||
}
|
||||
|
||||
// copied from toolkit/components/places/tests/head_common.js
|
||||
function waitForClearHistory(aCallback) {
|
||||
let observer = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
Services.obs.removeObserver(this, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
|
||||
aCallback();
|
||||
}
|
||||
};
|
||||
Services.obs.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
|
||||
PlacesUtils.bhistory.removeAllPages();
|
||||
}
|
23
browser/components/privatebrowsing/test/unit/xpcshell.ini
Normal file
23
browser/components/privatebrowsing/test/unit/xpcshell.ini
Normal file
@ -0,0 +1,23 @@
|
||||
[DEFAULT]
|
||||
head = head_privatebrowsing.js
|
||||
tail = tail_privatebrowsing.js
|
||||
|
||||
[test_0-privatebrowsing.js]
|
||||
[test_0-privatebrowsingwrapper.js]
|
||||
[test_aboutprivatebrowsing.js]
|
||||
[test_geoClearCookie.js]
|
||||
[test_httpauth.js]
|
||||
[test_openLocationLastURL.js]
|
||||
[test_placesTitleNoUpdate.js]
|
||||
[test_privatebrowsing_autostart.js]
|
||||
[test_privatebrowsing_commandline.js]
|
||||
[test_privatebrowsing_exit.js]
|
||||
[test_privatebrowsingwrapper_autostart.js]
|
||||
[test_privatebrowsingwrapper_commandline.js]
|
||||
[test_privatebrowsingwrapper_exit.js]
|
||||
[test_privatebrowsingwrapper_placesTitleNoUpdate.js]
|
||||
[test_privatebrowsingwrapper_removeDataFromDomain.js]
|
||||
[test_privatebrowsingwrapper_removeDataFromDomain_activeDownloads.js]
|
||||
[test_removeDataFromDomain.js]
|
||||
[test_removeDataFromDomain_activeDownloads.js]
|
||||
[test_transition_nooffline.js]
|
@ -225,6 +225,9 @@ SessionStoreService.prototype = {
|
||||
// number of tabs to restore concurrently, pref controlled.
|
||||
_maxConcurrentTabRestores: null,
|
||||
|
||||
// whether to restore hidden tabs or not, pref controlled.
|
||||
_restoreHiddenTabs: null,
|
||||
|
||||
// The state from the previous session (after restoring pinned tabs)
|
||||
_lastSessionState: null,
|
||||
|
||||
@ -281,6 +284,10 @@ SessionStoreService.prototype = {
|
||||
this._prefBranch.getIntPref("sessionstore.max_concurrent_tabs");
|
||||
this._prefBranch.addObserver("sessionstore.max_concurrent_tabs", this, true);
|
||||
|
||||
this._restoreHiddenTabs =
|
||||
this._prefBranch.getBoolPref("sessionstore.restore_hidden_tabs");
|
||||
this._prefBranch.addObserver("sessionstore.restore_hidden_tabs", this, true);
|
||||
|
||||
// Make sure gRestoreTabsProgressListener has a reference to sessionstore
|
||||
// so that it can make calls back in
|
||||
gRestoreTabsProgressListener.ss = this;
|
||||
@ -598,6 +605,10 @@ SessionStoreService.prototype = {
|
||||
this._maxConcurrentTabRestores =
|
||||
this._prefBranch.getIntPref("sessionstore.max_concurrent_tabs");
|
||||
break;
|
||||
case "sessionstore.restore_hidden_tabs":
|
||||
this._restoreHiddenTabs =
|
||||
this._prefBranch.getBoolPref("sessionstore.restore_hidden_tabs");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case "timer-callback": // timer call back for delayed saving
|
||||
@ -1078,6 +1089,10 @@ SessionStoreService.prototype = {
|
||||
this._tabsToRestore.hidden.splice(this._tabsToRestore.hidden.indexOf(aTab));
|
||||
// Just put it at the end of the list of visible tabs;
|
||||
this._tabsToRestore.visible.push(aTab);
|
||||
|
||||
// let's kick off tab restoration again to ensure this tab gets restored
|
||||
// with "restore_hidden_tabs" == false (now that it has become visible)
|
||||
this.restoreNextTab();
|
||||
}
|
||||
|
||||
// Default delay of 2 seconds gives enough time to catch multiple TabShow
|
||||
@ -1329,8 +1344,6 @@ SessionStoreService.prototype = {
|
||||
if (aWindow.__SSi && this._windows[aWindow.__SSi].extData &&
|
||||
this._windows[aWindow.__SSi].extData[aKey])
|
||||
delete this._windows[aWindow.__SSi].extData[aKey];
|
||||
else
|
||||
throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
|
||||
},
|
||||
|
||||
getTabValue: function sss_getTabValue(aTab, aKey) {
|
||||
@ -1377,8 +1390,6 @@ SessionStoreService.prototype = {
|
||||
|
||||
if (deleteFrom && deleteFrom[aKey])
|
||||
delete deleteFrom[aKey];
|
||||
else
|
||||
throw (Components.returnCode = Cr.NS_ERROR_INVALID_ARG);
|
||||
},
|
||||
|
||||
persistTabAttribute: function sss_persistTabAttribute(aName) {
|
||||
@ -2944,7 +2955,7 @@ SessionStoreService.prototype = {
|
||||
if (this._tabsToRestore.visible.length) {
|
||||
nextTabArray = this._tabsToRestore.visible;
|
||||
}
|
||||
else if (this._tabsToRestore.hidden.length) {
|
||||
else if (this._restoreHiddenTabs && this._tabsToRestore.hidden.length) {
|
||||
nextTabArray = this._tabsToRestore.hidden;
|
||||
}
|
||||
|
||||
@ -3974,7 +3985,8 @@ SessionStoreService.prototype = {
|
||||
this._removeTabsProgressListener(window);
|
||||
|
||||
if (previousState == TAB_STATE_RESTORING) {
|
||||
this._tabsRestoringCount--;
|
||||
if (this._tabsRestoringCount)
|
||||
this._tabsRestoringCount--;
|
||||
}
|
||||
else if (previousState == TAB_STATE_NEEDS_RESTORE) {
|
||||
// Make sure the session history listener is removed. This is normally
|
||||
|
@ -127,6 +127,7 @@ _BROWSER_TEST_FILES = \
|
||||
browser_589246.js \
|
||||
browser_590268.js \
|
||||
browser_590563.js \
|
||||
browser_595601-restore_hidden.js \
|
||||
browser_597315.js \
|
||||
browser_597315_index.html \
|
||||
browser_597315_a.html \
|
||||
@ -145,6 +146,7 @@ _BROWSER_TEST_FILES = \
|
||||
browser_625257.js \
|
||||
browser_628270.js \
|
||||
browser_635418.js \
|
||||
browser_636279.js \
|
||||
$(NULL)
|
||||
|
||||
ifneq ($(OS_ARCH),Darwin)
|
||||
|
@ -72,14 +72,6 @@ function test() {
|
||||
"Invalid index for undoCloseTab throws");
|
||||
ok(test(function() ss.getWindowValue({}, "")),
|
||||
"Invalid window for getWindowValue throws");
|
||||
ok(test(function() ss.getWindowValue({}, "")),
|
||||
"Invalid window for getWindowValue throws");
|
||||
ok(test(function() ss.getWindowValue({}, "", "")),
|
||||
ok(test(function() ss.setWindowValue({}, "", "")),
|
||||
"Invalid window for setWindowValue throws");
|
||||
ok(test(function() ss.deleteWindowValue({}, "")),
|
||||
"Invalid window for deleteWindowValue throws");
|
||||
ok(test(function() ss.deleteWindowValue(window, Date.now().toString())),
|
||||
"Nonexistent value for deleteWindowValue throws");
|
||||
ok(test(function() ss.deleteTabValue(gBrowser.selectedTab, Date.now().toString())),
|
||||
"Nonexistent value for deleteTabValue throws");
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user