Merge MC -> JM
1
.hgtags
|
@ -67,3 +67,4 @@ a95d426422816513477e5863add1b00ac7041dcb AURORA_BASE_20110412
|
|||
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R14
|
||||
462c726144bc1fb45b61e774f64ac5d61b4e047c UPDATE_PACKAGING_R14
|
||||
5eb553dd2ceae5f88d80f27afc5ef3935c5d43b0 AURORA_BASE_20110705
|
||||
41b84b87c816403e1b74963d8094cff0406c989e AURORA_BASE_20110816
|
||||
|
|
|
@ -136,39 +136,10 @@ NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(AccEvent, Release)
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
// AccEvent protected methods
|
||||
|
||||
nsAccessible *
|
||||
nsAccessible*
|
||||
AccEvent::GetAccessibleForNode() const
|
||||
{
|
||||
if (!mNode)
|
||||
return nsnull;
|
||||
|
||||
nsAccessible *accessible = GetAccService()->GetAccessible(mNode);
|
||||
|
||||
#ifdef MOZ_XUL
|
||||
// hack for xul tree table. We need a better way for firing delayed event
|
||||
// against xul tree table. see bug 386821.
|
||||
// There will be problem if some day we want to fire delayed event against
|
||||
// the xul tree itself or an unselected treeitem.
|
||||
nsCOMPtr<nsIContent> content(do_QueryInterface(mNode));
|
||||
if (content && content->NodeInfo()->Equals(nsAccessibilityAtoms::tree,
|
||||
kNameSpaceID_XUL)) {
|
||||
|
||||
nsCOMPtr<nsIDOMXULMultiSelectControlElement> multiSelect =
|
||||
do_QueryInterface(mNode);
|
||||
|
||||
if (multiSelect) {
|
||||
PRInt32 treeIndex = -1;
|
||||
multiSelect->GetCurrentIndex(&treeIndex);
|
||||
if (treeIndex >= 0) {
|
||||
nsRefPtr<nsXULTreeAccessible> treeAcc = do_QueryObject(accessible);
|
||||
if (treeAcc)
|
||||
return treeAcc->GetTreeItemAccessible(treeIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return accessible;
|
||||
return mNode ? GetAccService()->GetAccessible(mNode) : nsnull;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
|
@ -11,15 +13,15 @@
|
|||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is Mozilla Communicator.
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Netscape Communications Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2002
|
||||
* Mozilla Foundation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2011
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Kai Engert <kaie@netscape.com>
|
||||
* Trevor Saunders <trev.saunders@gmail.com> (original author)
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -35,30 +37,21 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsICipherInfo.h"
|
||||
#include "nsString.h"
|
||||
#include "sslt.h"
|
||||
#ifndef A11Y_STATISTICS_H_
|
||||
#define A11Y_STATISTICS_H_
|
||||
|
||||
class nsCipherInfoService : public nsICipherInfoService
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICIPHERINFOSERVICE
|
||||
#include "mozilla/Telemetry.h"
|
||||
|
||||
nsCipherInfoService();
|
||||
virtual ~nsCipherInfoService();
|
||||
};
|
||||
namespace mozilla {
|
||||
namespace a11y {
|
||||
namespace statistics {
|
||||
|
||||
class nsCipherInfo : public nsICipherInfo
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICIPHERINFO
|
||||
inline void A11yInitialized()
|
||||
{ Telemetry::Accumulate(Telemetry::A11Y_INSTANTIATED, true); }
|
||||
|
||||
nsCipherInfo(PRUint16 aCipherId);
|
||||
virtual ~nsCipherInfo();
|
||||
} // namespace statistics
|
||||
} // namespace a11y
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
||||
|
||||
private:
|
||||
PRBool mHaveInfo;
|
||||
SSLCipherSuiteInfo mInfo;
|
||||
};
|
|
@ -56,6 +56,7 @@
|
|||
#include "nsIAccessibilityService.h"
|
||||
#include "nsIAccessibleProvider.h"
|
||||
#include "States.h"
|
||||
#include "Statistics.h"
|
||||
|
||||
#include "nsIDOMDocument.h"
|
||||
#include "nsIDOMHTMLAreaElement.h"
|
||||
|
@ -1772,6 +1773,8 @@ NS_GetAccessibilityService(nsIAccessibilityService** aResult)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
statistics::A11yInitialized();
|
||||
|
||||
nsAccessibilityService::gAccessibilityService = service;
|
||||
NS_ADDREF(*aResult = service);
|
||||
|
||||
|
|
|
@ -393,10 +393,10 @@ nsRootAccessible::FireAccessibleFocusEvent(nsAccessible* aFocusAccessible,
|
|||
|
||||
// Coalesce focus events from the same document, because DOM focus event might
|
||||
// be fired for the document node and then for the focused DOM element.
|
||||
focusDocument->FireDelayedAccessibleEvent(nsIAccessibleEvent::EVENT_FOCUS,
|
||||
focusNode,
|
||||
AccEvent::eCoalesceFromSameDocument,
|
||||
aIsFromUserInput);
|
||||
nsRefPtr<AccEvent> focusEvent =
|
||||
new AccEvent(nsIAccessibleEvent::EVENT_FOCUS, focusAccessible,
|
||||
aIsFromUserInput, AccEvent::eCoalesceFromSameDocument);
|
||||
focusDocument->FireDelayedAccessibleEvent(focusEvent);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "gfxFont.h"
|
||||
#include "gfxUserFontSet.h"
|
||||
#include "nsFontMetrics.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
// Constants and structures
|
||||
|
@ -479,10 +480,7 @@ nsFontSizeTextAttr::Format(const nscoord& aValue, nsAString& aFormattedValue)
|
|||
nscoord
|
||||
nsFontSizeTextAttr::GetFontSize(nsIFrame *aFrame)
|
||||
{
|
||||
nsStyleFont* styleFont =
|
||||
(nsStyleFont*)(aFrame->GetStyleDataExternal(eStyleStruct_Font));
|
||||
|
||||
return styleFont->mSize;
|
||||
return aFrame->GetStyleFont()->mSize;
|
||||
}
|
||||
|
||||
|
||||
|
@ -527,15 +525,8 @@ nsFontWeightTextAttr::GetFontWeight(nsIFrame *aFrame)
|
|||
{
|
||||
// nsFont::width isn't suitable here because it's necessary to expose real
|
||||
// value of font weight (used font might not have some font weight values).
|
||||
nsStyleFont* styleFont =
|
||||
(nsStyleFont*)(aFrame->GetStyleDataExternal(eStyleStruct_Font));
|
||||
|
||||
gfxUserFontSet *fs = aFrame->PresContext()->GetUserFontSet();
|
||||
|
||||
nsRefPtr<nsFontMetrics> fm;
|
||||
aFrame->PresContext()->DeviceContext()->
|
||||
GetMetricsFor(styleFont->mFont, aFrame->GetStyleVisibility()->mLanguage,
|
||||
fs, *getter_AddRefs(fm));
|
||||
nsLayoutUtils::GetFontMetricsForFrame(aFrame, getter_AddRefs(fm));
|
||||
|
||||
gfxFontGroup *fontGroup = fm->GetThebesFontGroup();
|
||||
gfxFont *font = fontGroup->GetFontAt(0);
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "nsIFrame.h"
|
||||
#include "nsFontMetrics.h"
|
||||
#include "nsPresContext.h"
|
||||
#include "nsLayoutUtils.h"
|
||||
|
||||
#include "gfxFont.h"
|
||||
|
||||
|
@ -256,11 +257,7 @@ __try {
|
|||
}
|
||||
|
||||
nsRefPtr<nsFontMetrics> fm;
|
||||
frame->PresContext()->DeviceContext()->
|
||||
GetMetricsFor(frame->GetStyleFont()->mFont,
|
||||
frame->GetStyleVisibility()->mLanguage,
|
||||
frame->PresContext()->GetUserFontSet(),
|
||||
*getter_AddRefs(fm));
|
||||
nsLayoutUtils::GetFontMetricsForFrame(frame, getter_AddRefs(fm));
|
||||
|
||||
const nsString& name = fm->GetThebesFontGroup()->GetFontAt(0)->GetName();
|
||||
if (name.IsEmpty())
|
||||
|
|
|
@ -66,6 +66,7 @@ _TEST_FILES =\
|
|||
test_focus.html \
|
||||
test_focus.xul \
|
||||
test_focus_name.html \
|
||||
test_focus_tree.xul \
|
||||
test_focusdoc.html \
|
||||
test_menu.xul \
|
||||
test_mutation.html \
|
||||
|
|
|
@ -0,0 +1,120 @@
|
|||
<?xml version="1.0"?>
|
||||
<?xml-stylesheet href="chrome://global/skin" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://mochikit/content/tests/SimpleTest/test.css"
|
||||
type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="XUL tree focus testing">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/MochiKit/packed.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js" />
|
||||
<script type="application/javascript"
|
||||
src="chrome://mochikit/content/tests/SimpleTest/EventUtils.js"/>
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../treeview.js" />
|
||||
|
||||
<script type="application/javascript"
|
||||
src="../common.js" />
|
||||
<script type="application/javascript"
|
||||
src="../events.js" />
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Invokers
|
||||
|
||||
function setTreeView(aTreeID, aView)
|
||||
{
|
||||
this.DOMNode = getNode(aTreeID);
|
||||
|
||||
this.eventSeq = [
|
||||
new invokerChecker(EVENT_REORDER, this.DOMNode)
|
||||
];
|
||||
|
||||
this.invoke = function setTreeView_invoke()
|
||||
{
|
||||
this.DOMNode.treeBoxObject.view = aView;
|
||||
}
|
||||
|
||||
this.getID = function setTreeView_getID()
|
||||
{ return "set tree view for " + prettyName(aTreeID); }
|
||||
};
|
||||
|
||||
function focusTree(aTreeID)
|
||||
{
|
||||
var checker = new invokerChecker(EVENT_FOCUS, getFirstTreeItem, aTreeID);
|
||||
this.__proto__ = new synthFocus(aTreeID, [ checker ]);
|
||||
}
|
||||
|
||||
function moveToNextItem(aTreeID)
|
||||
{
|
||||
var checker = new invokerChecker(EVENT_FOCUS, getSecondTreeItem, aTreeID);
|
||||
this.__proto__ = new synthDownKey(aTreeID, [ checker ]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Helpers
|
||||
|
||||
function getTreeItemAt(aTreeID, aIdx)
|
||||
{ return getAccessible(aTreeID).getChildAt(aIdx + 1); }
|
||||
|
||||
function getFirstTreeItem(aTreeID)
|
||||
{ return getTreeItemAt(aTreeID, 0); }
|
||||
|
||||
function getSecondTreeItem(aTreeID)
|
||||
{ return getTreeItemAt(aTreeID, 1); }
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////
|
||||
// Test
|
||||
|
||||
var gQueue = null;
|
||||
|
||||
//gA11yEventDumpID = "debug"; // debugging
|
||||
//gA11yEventDumpToConsole = true; // debugging
|
||||
|
||||
function doTest()
|
||||
{
|
||||
gQueue = new eventQueue();
|
||||
|
||||
gQueue.push(new setTreeView("tree", new nsTableTreeView(5)));
|
||||
gQueue.push(new focusTree("tree"));
|
||||
gQueue.push(new moveToNextItem("tree"));
|
||||
|
||||
gQueue.invoke();
|
||||
}
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
addA11yLoadEvent(doTest);
|
||||
]]>
|
||||
</script>
|
||||
|
||||
<hbox flex="1" style="overflow: auto;">
|
||||
<body xmlns="http://www.w3.org/1999/xhtml">
|
||||
<a target="_blank"
|
||||
href="https://bugzilla.mozilla.org/show_bug.cgi?id=386821"
|
||||
title="Need better solution for firing delayed event against xul tree">
|
||||
Mozilla Bug 386821
|
||||
</a><br/>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
</pre>
|
||||
</body>
|
||||
|
||||
<vbox id="debug"/>
|
||||
<tree id="tree" flex="1">
|
||||
<treecols>
|
||||
<treecol id="col1" flex="1" primary="true" label="column"/>
|
||||
<treecol id="col2" flex="1" label="column 2"/>
|
||||
</treecols>
|
||||
<treechildren id="treechildren"/>
|
||||
</tree>
|
||||
</hbox>
|
||||
|
||||
</window>
|
||||
|
|
@ -45,13 +45,13 @@ include $(topsrcdir)/config/config.mk
|
|||
PARALLEL_DIRS = \
|
||||
base \
|
||||
components \
|
||||
devtools \
|
||||
fuel \
|
||||
locales \
|
||||
themes \
|
||||
$(NULL)
|
||||
|
||||
DIRS = \
|
||||
devtools \
|
||||
app \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -783,12 +783,12 @@ pref("browser.sessionstore.max_windows_undo", 3);
|
|||
// number of crashes that can occur before the about:sessionrestore page is displayed
|
||||
// (this pref has no effect if more than 6 hours have passed since the last crash)
|
||||
pref("browser.sessionstore.max_resumed_crashes", 1);
|
||||
// The number of tabs that can restore concurrently:
|
||||
// < 0 = All tabs can restore at the same time
|
||||
// 0 = Only the selected tab in each window will be restored
|
||||
// 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);
|
||||
// restore_on_demand overrides MAX_CONCURRENT_TAB_RESTORES (sessionstore constant)
|
||||
// and restore_hidden_tabs. When true, tabs will not be restored until they are
|
||||
// focused (also applies to tabs that aren't visible). When false, the values
|
||||
// for MAX_CONCURRENT_TAB_RESTORES and restore_hidden_tabs are respected.
|
||||
// Selected tabs are always restored regardless of this pref.
|
||||
pref("browser.sessionstore.restore_on_demand", false);
|
||||
// Whether to automatically restore hidden tabs (i.e., tabs in other tab groups) or not
|
||||
pref("browser.sessionstore.restore_hidden_tabs", false);
|
||||
|
||||
|
@ -881,7 +881,7 @@ pref("browser.privatebrowsing.dont_prompt_on_enter", false);
|
|||
pref("browser.bookmarks.editDialog.firstEditField", "namePicker");
|
||||
|
||||
// base url for the wifi geolocation network provider
|
||||
pref("geo.wifi.uri", "https://www.google.com/loc/json");
|
||||
pref("geo.wifi.uri", "https://maps.googleapis.com/maps/api/browserlocation/json");
|
||||
pref("geo.wifi.protocol", 0);
|
||||
|
||||
// Whether to use a panel that looks like an OS X sheet for customization
|
||||
|
@ -1054,7 +1054,7 @@ pref("devtools.editor.expandtab", true);
|
|||
// provides programmer-specific editor features such as syntax highlighting,
|
||||
// indenting and bracket recognition. It may not be appropriate for all
|
||||
// locales (esp. RTL) or a11y situations.
|
||||
pref("devtools.editor.component", "textarea");
|
||||
pref("devtools.editor.component", "orion");
|
||||
|
||||
// Whether the character encoding menu is under the main Firefox button. This
|
||||
// preference is a string so that localizers can alter it.
|
||||
|
|
|
@ -1631,7 +1631,7 @@ BaseTemplates.AttrTag =
|
|||
" ",
|
||||
domplate.SPAN({"class": "nodeName editable"}, "$attr.nodeName"),
|
||||
"="",
|
||||
domplate.SPAN({"class": "nodeValue editable"}, "$attr.nodeValue"),
|
||||
domplate.SPAN({"class": "nodeValue editable", "data-attributeName": "$attr.nodeName"}, "$attr.nodeValue"),
|
||||
""");
|
||||
|
||||
BaseTemplates.TextTag =
|
||||
|
|
|
@ -7,5 +7,8 @@
|
|||
<link rel="stylesheet" href="chrome://browser/skin/inspector.css" type="text/css"/>
|
||||
</head>
|
||||
<body role="application">
|
||||
<div id="attribute-editor">
|
||||
<input id="attribute-editor-input" />
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
* Mihai Șucan <mihai.sucan@gmail.com>
|
||||
* Julian Viereck <jviereck@mozilla.com>
|
||||
* Paul Rouget <paul@mozilla.com>
|
||||
* Kyle Simpson <ksimpson@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -70,6 +71,11 @@ const INSPECTOR_NOTIFICATIONS = {
|
|||
|
||||
// Fires once the Inspector is closed.
|
||||
CLOSED: "inspector-closed",
|
||||
|
||||
// Event notifications for the attribute-value editor
|
||||
EDITOR_OPENED: "inspector-editor-opened",
|
||||
EDITOR_CLOSED: "inspector-editor-closed",
|
||||
EDITOR_SAVED: "inspector-editor-saved",
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
@ -591,6 +597,8 @@ var InspectorUI = {
|
|||
this.ioBox = new InsideOutBox(this, this.treePanelDiv);
|
||||
this.ioBox.createObjectBox(this.win.document.documentElement);
|
||||
this.treeLoaded = true;
|
||||
this.editingContext = null;
|
||||
this.editingEvents = {};
|
||||
|
||||
// initialize the highlighter
|
||||
this.initializeHighlighter();
|
||||
|
@ -614,6 +622,7 @@ var InspectorUI = {
|
|||
this.treeIFrame.setAttribute("flex", "1");
|
||||
this.treeIFrame.setAttribute("type", "content");
|
||||
this.treeIFrame.setAttribute("onclick", "InspectorUI.onTreeClick(event)");
|
||||
this.treeIFrame.setAttribute("ondblclick", "InspectorUI.onTreeDblClick(event);");
|
||||
this.treeIFrame = this.treePanel.insertBefore(this.treeIFrame, resizerBox);
|
||||
}
|
||||
|
||||
|
@ -817,6 +826,11 @@ var InspectorUI = {
|
|||
*/
|
||||
closeInspectorUI: function IUI_closeInspectorUI(aKeepStore)
|
||||
{
|
||||
// if currently editing an attribute value, closing the
|
||||
// highlighter/HTML panel dismisses the editor
|
||||
if (this.editingContext)
|
||||
this.closeEditor();
|
||||
|
||||
if (this.closing || !this.win || !this.browser) {
|
||||
return;
|
||||
}
|
||||
|
@ -893,6 +907,11 @@ var InspectorUI = {
|
|||
*/
|
||||
startInspecting: function IUI_startInspecting()
|
||||
{
|
||||
// if currently editing an attribute value, starting
|
||||
// "live inspection" mode closes the editor
|
||||
if (this.editingContext)
|
||||
this.closeEditor();
|
||||
|
||||
document.getElementById("inspector-inspect-toolbutton").checked = true;
|
||||
this.attachPageListeners();
|
||||
this.inspecting = true;
|
||||
|
@ -933,6 +952,11 @@ var InspectorUI = {
|
|||
*/
|
||||
select: function IUI_select(aNode, forceUpdate, aScroll)
|
||||
{
|
||||
// if currently editing an attribute value, using the
|
||||
// highlighter dismisses the editor
|
||||
if (this.editingContext)
|
||||
this.closeEditor();
|
||||
|
||||
if (!aNode)
|
||||
aNode = this.defaultSelection;
|
||||
|
||||
|
@ -1044,6 +1068,17 @@ var InspectorUI = {
|
|||
*/
|
||||
onTreeClick: function IUI_onTreeClick(aEvent)
|
||||
{
|
||||
// if currently editing an attribute value, clicking outside
|
||||
// the editor dismisses the editor
|
||||
if (this.editingContext) {
|
||||
this.closeEditor();
|
||||
|
||||
// clicking outside the editor ONLY closes the editor
|
||||
// so, cancel the rest of the processing of this event
|
||||
aEvent.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
let node;
|
||||
let target = aEvent.target;
|
||||
let hitTwisty = false;
|
||||
|
@ -1068,6 +1103,220 @@ var InspectorUI = {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle double-click events in the html tree panel.
|
||||
* (double-clicking an attribute value allows it to be edited)
|
||||
* @param aEvent
|
||||
* The mouse event.
|
||||
*/
|
||||
onTreeDblClick: function IUI_onTreeDblClick(aEvent)
|
||||
{
|
||||
// if already editing an attribute value, double-clicking elsewhere
|
||||
// in the tree is the same as a click, which dismisses the editor
|
||||
if (this.editingContext)
|
||||
this.closeEditor();
|
||||
|
||||
let target = aEvent.target;
|
||||
|
||||
if (this.hasClass(target, "nodeValue")) {
|
||||
let repObj = this.getRepObject(target);
|
||||
let attrName = target.getAttribute("data-attributeName");
|
||||
let attrVal = target.innerHTML;
|
||||
|
||||
this.editAttributeValue(target, repObj, attrName, attrVal);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Starts the editor for an attribute value.
|
||||
* @param aAttrObj
|
||||
* The DOM object representing the attribute value in the HTML Tree
|
||||
* @param aRepObj
|
||||
* The original DOM (target) object being inspected/edited
|
||||
* @param aAttrName
|
||||
* The name of the attribute being edited
|
||||
* @param aAttrVal
|
||||
* The current value of the attribute being edited
|
||||
*/
|
||||
editAttributeValue:
|
||||
function IUI_editAttributeValue(aAttrObj, aRepObj, aAttrName, aAttrVal)
|
||||
{
|
||||
let editor = this.treeBrowserDocument.getElementById("attribute-editor");
|
||||
let editorInput =
|
||||
this.treeBrowserDocument.getElementById("attribute-editor-input");
|
||||
let attrDims = aAttrObj.getBoundingClientRect();
|
||||
// figure out actual viewable viewport dimensions (sans scrollbars)
|
||||
let viewportWidth = this.treeBrowserDocument.documentElement.clientWidth;
|
||||
let viewportHeight = this.treeBrowserDocument.documentElement.clientHeight;
|
||||
|
||||
// saves the editing context for use when the editor is saved/closed
|
||||
this.editingContext = {
|
||||
attrObj: aAttrObj,
|
||||
repObj: aRepObj,
|
||||
attrName: aAttrName
|
||||
};
|
||||
|
||||
// highlight attribute-value node in tree while editing
|
||||
this.addClass(aAttrObj, "editingAttributeValue");
|
||||
|
||||
// show the editor
|
||||
this.addClass(editor, "editing");
|
||||
|
||||
// offset the editor below the attribute-value node being edited
|
||||
let editorVeritcalOffset = 2;
|
||||
|
||||
// keep the editor comfortably within the bounds of the viewport
|
||||
let editorViewportBoundary = 5;
|
||||
|
||||
// outer editor is sized based on the <input> box inside it
|
||||
editorInput.style.width = Math.min(attrDims.width, viewportWidth -
|
||||
editorViewportBoundary) + "px";
|
||||
editorInput.style.height = Math.min(attrDims.height, viewportHeight -
|
||||
editorViewportBoundary) + "px";
|
||||
let editorDims = editor.getBoundingClientRect();
|
||||
|
||||
// calculate position for the editor according to the attribute node
|
||||
let editorLeft = attrDims.left + this.treeIFrame.contentWindow.scrollX -
|
||||
// center the editor against the attribute value
|
||||
((editorDims.width - attrDims.width) / 2);
|
||||
let editorTop = attrDims.top + this.treeIFrame.contentWindow.scrollY +
|
||||
attrDims.height + editorVeritcalOffset;
|
||||
|
||||
// but, make sure the editor stays within the visible viewport
|
||||
editorLeft = Math.max(0, Math.min(
|
||||
(this.treeIFrame.contentWindow.scrollX +
|
||||
viewportWidth - editorDims.width),
|
||||
editorLeft)
|
||||
);
|
||||
editorTop = Math.max(0, Math.min(
|
||||
(this.treeIFrame.contentWindow.scrollY +
|
||||
viewportHeight - editorDims.height),
|
||||
editorTop)
|
||||
);
|
||||
|
||||
// position the editor
|
||||
editor.style.left = editorLeft + "px";
|
||||
editor.style.top = editorTop + "px";
|
||||
|
||||
// set and select the text
|
||||
editorInput.value = aAttrVal;
|
||||
editorInput.select();
|
||||
|
||||
// listen for editor specific events
|
||||
this.bindEditorEvent(editor, "click", function(aEvent) {
|
||||
aEvent.stopPropagation();
|
||||
});
|
||||
this.bindEditorEvent(editor, "dblclick", function(aEvent) {
|
||||
aEvent.stopPropagation();
|
||||
});
|
||||
this.bindEditorEvent(editor, "keypress",
|
||||
this.handleEditorKeypress.bind(this));
|
||||
|
||||
// event notification
|
||||
Services.obs.notifyObservers(null, INSPECTOR_NOTIFICATIONS.EDITOR_OPENED,
|
||||
null);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle binding an event handler for the editor.
|
||||
* (saves the callback for easier unbinding later)
|
||||
* @param aEditor
|
||||
* The DOM object for the editor
|
||||
* @param aEventName
|
||||
* The name of the event to listen for
|
||||
* @param aEventCallback
|
||||
* The callback to bind to the event (and also to save for later
|
||||
* unbinding)
|
||||
*/
|
||||
bindEditorEvent:
|
||||
function IUI_bindEditorEvent(aEditor, aEventName, aEventCallback)
|
||||
{
|
||||
this.editingEvents[aEventName] = aEventCallback;
|
||||
aEditor.addEventListener(aEventName, aEventCallback, false);
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle unbinding an event handler from the editor.
|
||||
* (unbinds the previously bound and saved callback)
|
||||
* @param aEditor
|
||||
* The DOM object for the editor
|
||||
* @param aEventName
|
||||
* The name of the event being listened for
|
||||
*/
|
||||
unbindEditorEvent: function IUI_unbindEditorEvent(aEditor, aEventName)
|
||||
{
|
||||
aEditor.removeEventListener(aEventName, this.editingEvents[aEventName],
|
||||
false);
|
||||
this.editingEvents[aEventName] = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle keypress events in the editor.
|
||||
* @param aEvent
|
||||
* The keyboard event.
|
||||
*/
|
||||
handleEditorKeypress: function IUI_handleEditorKeypress(aEvent)
|
||||
{
|
||||
if (aEvent.which == KeyEvent.DOM_VK_RETURN) {
|
||||
this.saveEditor();
|
||||
} else if (aEvent.keyCode == KeyEvent.DOM_VK_ESCAPE) {
|
||||
this.closeEditor();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Close the editor and cleanup.
|
||||
*/
|
||||
closeEditor: function IUI_closeEditor()
|
||||
{
|
||||
let editor = this.treeBrowserDocument.getElementById("attribute-editor");
|
||||
let editorInput =
|
||||
this.treeBrowserDocument.getElementById("attribute-editor-input");
|
||||
|
||||
// remove highlight from attribute-value node in tree
|
||||
this.removeClass(this.editingContext.attrObj, "editingAttributeValue");
|
||||
|
||||
// hide editor
|
||||
this.removeClass(editor, "editing");
|
||||
|
||||
// stop listening for editor specific events
|
||||
this.unbindEditorEvent(editor, "click");
|
||||
this.unbindEditorEvent(editor, "dblclick");
|
||||
this.unbindEditorEvent(editor, "keypress");
|
||||
|
||||
// clean up after the editor
|
||||
editorInput.value = "";
|
||||
editorInput.blur();
|
||||
this.editingContext = null;
|
||||
this.editingEvents = {};
|
||||
|
||||
// event notification
|
||||
Services.obs.notifyObservers(null, INSPECTOR_NOTIFICATIONS.EDITOR_CLOSED,
|
||||
null);
|
||||
},
|
||||
|
||||
/**
|
||||
* Commit the edits made in the editor, then close it.
|
||||
*/
|
||||
saveEditor: function IUI_saveEditor()
|
||||
{
|
||||
let editorInput =
|
||||
this.treeBrowserDocument.getElementById("attribute-editor-input");
|
||||
|
||||
// set the new attribute value on the original target DOM element
|
||||
this.editingContext.repObj.setAttribute(this.editingContext.attrName,
|
||||
editorInput.value);
|
||||
|
||||
// update the HTML tree attribute value
|
||||
this.editingContext.attrObj.innerHTML = editorInput.value;
|
||||
|
||||
// event notification
|
||||
Services.obs.notifyObservers(null, INSPECTOR_NOTIFICATIONS.EDITOR_SAVED,
|
||||
null);
|
||||
|
||||
this.closeEditor();
|
||||
},
|
||||
|
||||
/**
|
||||
* Attach event listeners to content window and child windows to enable
|
||||
* highlighting and click to stop inspection.
|
||||
|
|
|
@ -79,7 +79,8 @@ nsContextMenu.prototype = {
|
|||
|
||||
this.hasPageMenu = false;
|
||||
if (!aIsShift) {
|
||||
this.hasPageMenu = PageMenu.init(this.target, aXulMenu);
|
||||
this.hasPageMenu = PageMenu.maybeBuildAndAttachMenu(this.target,
|
||||
aXulMenu);
|
||||
}
|
||||
|
||||
this.isFrameImage = document.getElementById("isFrameImage");
|
||||
|
|
|
@ -515,7 +515,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
|||
// make some room for the expand button if we're stacked
|
||||
let isStacked = (options && options.forceStacked) || this.isStacked();
|
||||
if (isStacked)
|
||||
box.height -= 33; // 33px room for the expand button
|
||||
box.height -= this.$expander.height() + 9; // the button height plus padding
|
||||
|
||||
return box;
|
||||
},
|
||||
|
@ -1237,7 +1237,6 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
|||
showExpandControl: function GroupItem_showExpandControl() {
|
||||
let parentBB = this.getBounds();
|
||||
let childBB = this.getChild(0).getBounds();
|
||||
let padding = 7;
|
||||
this.$expander
|
||||
.show()
|
||||
.css({
|
||||
|
@ -1363,15 +1362,17 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
|
|||
|
||||
let shouldStack = this.shouldStack(childrenToArrange.length + (options.addTab ? 1 : 0));
|
||||
let shouldStackArrange = (shouldStack && !this.expanded);
|
||||
let box = this.getContentBounds({forceStacked: shouldStackArrange});
|
||||
|
||||
let box;
|
||||
|
||||
// if we should stack and we're not expanded
|
||||
if (shouldStackArrange) {
|
||||
this.showExpandControl();
|
||||
box = this.getContentBounds({forceStacked: true});
|
||||
this._stackArrange(childrenToArrange, box, options);
|
||||
return false;
|
||||
} else {
|
||||
this.hideExpandControl();
|
||||
box = this.getContentBounds({forceStacked: false});
|
||||
// a dropIndex is returned
|
||||
return this._gridArrange(childrenToArrange, box, options);
|
||||
}
|
||||
|
|
|
@ -177,6 +177,7 @@ _BROWSER_FILES = \
|
|||
browser_bug647886.js \
|
||||
browser_bug655584.js \
|
||||
browser_bug664672.js \
|
||||
browser_canonizeURL.js \
|
||||
browser_findbarClose.js \
|
||||
browser_keywordBookmarklets.js \
|
||||
browser_contextSearchTabPosition.js \
|
||||
|
|
|
@ -0,0 +1,54 @@
|
|||
function test() {
|
||||
waitForExplicitFinish();
|
||||
testNext();
|
||||
}
|
||||
|
||||
var pairs = [
|
||||
["example", "http://www.example.net/"],
|
||||
["ex-ample", "http://www.ex-ample.net/"],
|
||||
[" example ", "http://www.example.net/"],
|
||||
[" example/foo ", "http://www.example.net/foo"],
|
||||
[" example/foo bar ", "http://www.example.net/foo%20bar"],
|
||||
["example.net", "http://example.net/"],
|
||||
["http://example", "http://example/"],
|
||||
["example:8080", "http://example:8080/"],
|
||||
["ex-ample.foo", "http://ex-ample.foo/"],
|
||||
["example.foo/bar ", "http://example.foo/bar"],
|
||||
["1.1.1.1", "http://1.1.1.1/"],
|
||||
["ftp://example", "ftp://example/"],
|
||||
["ftp.example.bar", "ftp://ftp.example.bar/"],
|
||||
["ex ample", Services.search.originalDefaultEngine.getSubmission("ex ample").uri.spec],
|
||||
];
|
||||
|
||||
function testNext() {
|
||||
if (!pairs.length) {
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
|
||||
let [inputValue, expectedURL] = pairs.shift();
|
||||
|
||||
gBrowser.addProgressListener({
|
||||
onStateChange: function onStateChange(aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
if (aStateFlags & Ci.nsIWebProgressListener.STATE_START &&
|
||||
aStateFlags & Ci.nsIWebProgressListener.STATE_IS_NETWORK) {
|
||||
is(aRequest.originalURI.spec, expectedURL,
|
||||
"entering '" + inputValue + "' loads expected URL");
|
||||
|
||||
gBrowser.removeProgressListener(this);
|
||||
gBrowser.stop();
|
||||
|
||||
executeSoon(testNext);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
gURLBar.addEventListener("focus", function onFocus() {
|
||||
gURLBar.removeEventListener("focus", onFocus);
|
||||
EventUtils.synthesizeKey("VK_RETURN", { shiftKey: true });
|
||||
});
|
||||
|
||||
gBrowser.selectedBrowser.focus();
|
||||
gURLBar.inputField.value = inputValue;
|
||||
gURLBar.focus();
|
||||
}
|
|
@ -56,6 +56,7 @@ _BROWSER_FILES = \
|
|||
browser_inspector_treePanel_result.html \
|
||||
browser_inspector_registertools.js \
|
||||
browser_inspector_bug_665880.js \
|
||||
browser_inspector_editor.js \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_FILES)
|
||||
|
|
|
@ -0,0 +1,233 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*
|
||||
* Contributor(s):
|
||||
* Rob Campbell <rcampbell@mozilla.com>
|
||||
* Mihai Sucan <mihai.sucan@gmail.com>
|
||||
* Kyle Simpson <ksimpson@mozilla.com>
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
let doc;
|
||||
let div;
|
||||
let editorTestSteps;
|
||||
|
||||
function doNextStep() {
|
||||
editorTestSteps.next();
|
||||
}
|
||||
|
||||
function setupEditorTests()
|
||||
{
|
||||
div = doc.createElement("div");
|
||||
div.setAttribute("id", "foobar");
|
||||
div.setAttribute("class", "barbaz");
|
||||
doc.body.appendChild(div);
|
||||
|
||||
Services.obs.addObserver(runEditorTests, INSPECTOR_NOTIFICATIONS.OPENED, false);
|
||||
InspectorUI.toggleInspectorUI();
|
||||
}
|
||||
|
||||
function runEditorTests()
|
||||
{
|
||||
Services.obs.removeObserver(runEditorTests, INSPECTOR_NOTIFICATIONS.OPENED, false);
|
||||
InspectorUI.stopInspecting();
|
||||
|
||||
// setup generator for async test steps
|
||||
editorTestSteps = doEditorTestSteps();
|
||||
|
||||
// add step listeners
|
||||
Services.obs.addObserver(doNextStep, INSPECTOR_NOTIFICATIONS.EDITOR_OPENED, false);
|
||||
Services.obs.addObserver(doNextStep, INSPECTOR_NOTIFICATIONS.EDITOR_CLOSED, false);
|
||||
Services.obs.addObserver(doNextStep, INSPECTOR_NOTIFICATIONS.EDITOR_SAVED, false);
|
||||
|
||||
// start the tests
|
||||
doNextStep();
|
||||
}
|
||||
|
||||
function doEditorTestSteps()
|
||||
{
|
||||
let editor = InspectorUI.treeBrowserDocument.getElementById("attribute-editor");
|
||||
let editorInput = InspectorUI.treeBrowserDocument.getElementById("attribute-editor-input");
|
||||
|
||||
// Step 1: grab and test the attribute-value nodes in the HTML panel, then open editor
|
||||
let attrValNode_id = InspectorUI.treeBrowserDocument.querySelectorAll(".nodeValue.editable[data-attributeName='id']")[0];
|
||||
let attrValNode_class = InspectorUI.treeBrowserDocument.querySelectorAll(".nodeValue.editable[data-attributeName='class']")[0];
|
||||
|
||||
is(attrValNode_id.innerHTML, "foobar", "Step 1: we have the correct `id` attribute-value node in the HTML panel");
|
||||
is(attrValNode_class.innerHTML, "barbaz", "we have the correct `class` attribute-value node in the HTML panel");
|
||||
|
||||
// double-click the `id` attribute-value node to open the editor
|
||||
executeSoon(function() {
|
||||
// firing 2 clicks right in a row to simulate a double-click
|
||||
EventUtils.synthesizeMouse(attrValNode_id, 2, 2, {clickCount: 2}, attrValNode_id.ownerDocument.defaultView);
|
||||
});
|
||||
|
||||
yield; // End of Step 1
|
||||
|
||||
|
||||
// Step 2: validate editing session, enter new attribute value into editor, and save input
|
||||
ok(InspectorUI.editingContext, "Step 2: editor session started");
|
||||
|
||||
let editorVisible = editor.classList.contains("editing");
|
||||
ok(editorVisible, "editor popup visible");
|
||||
|
||||
// check if the editor popup is "near" the correct position
|
||||
let editorDims = editor.getBoundingClientRect();
|
||||
let attrValNodeDims = attrValNode_id.getBoundingClientRect();
|
||||
let editorPositionOK = (editorDims.left >= (attrValNodeDims.left - editorDims.width - 5)) &&
|
||||
(editorDims.right <= (attrValNodeDims.right + editorDims.width + 5)) &&
|
||||
(editorDims.top >= (attrValNodeDims.top - editorDims.height - 5)) &&
|
||||
(editorDims.bottom <= (attrValNodeDims.bottom + editorDims.height + 5));
|
||||
|
||||
ok(editorPositionOK, "editor position acceptable");
|
||||
|
||||
// check to make sure the attribute-value node being edited is properly highlighted
|
||||
let attrValNodeHighlighted = attrValNode_id.classList.contains("editingAttributeValue");
|
||||
ok(attrValNodeHighlighted, "`id` attribute-value node is editor-highlighted");
|
||||
|
||||
is(InspectorUI.editingContext.repObj, div, "editor session has correct reference to div");
|
||||
is(InspectorUI.editingContext.attrObj, attrValNode_id, "editor session has correct reference to `id` attribute-value node in HTML panel");
|
||||
is(InspectorUI.editingContext.attrName, "id", "editor session knows correct attribute-name");
|
||||
|
||||
editorInput.value = "Hello World";
|
||||
editorInput.focus();
|
||||
|
||||
// hit <enter> to save the inputted value
|
||||
executeSoon(function() {
|
||||
EventUtils.synthesizeKey("VK_RETURN", {}, attrValNode_id.ownerDocument.defaultView);
|
||||
});
|
||||
|
||||
// two `yield` statements, to trap both the "SAVED" and "CLOSED" events that will be triggered
|
||||
yield;
|
||||
yield; // End of Step 2
|
||||
|
||||
|
||||
// Step 3: validate that the previous editing session saved correctly, then open editor on `class` attribute value
|
||||
ok(!InspectorUI.editingContext, "Step 3: editor session ended");
|
||||
editorVisible = editor.classList.contains("editing");
|
||||
ok(!editorVisible, "editor popup hidden");
|
||||
attrValNodeHighlighted = attrValNode_id.classList.contains("editingAttributeValue");
|
||||
ok(!attrValNodeHighlighted, "`id` attribute-value node is no longer editor-highlighted");
|
||||
is(div.getAttribute("id"), "Hello World", "`id` attribute-value successfully updated");
|
||||
is(attrValNode_id.innerHTML, "Hello World", "attribute-value node in HTML panel successfully updated");
|
||||
|
||||
// double-click the `class` attribute-value node to open the editor
|
||||
executeSoon(function() {
|
||||
// firing 2 clicks right in a row to simulate a double-click
|
||||
EventUtils.synthesizeMouse(attrValNode_class, 2, 2, {clickCount: 2}, attrValNode_class.ownerDocument.defaultView);
|
||||
});
|
||||
|
||||
yield; // End of Step 3
|
||||
|
||||
|
||||
// Step 4: enter value into editor, then hit <escape> to discard it
|
||||
ok(InspectorUI.editingContext, "Step 4: editor session started");
|
||||
editorVisible = editor.classList.contains("editing");
|
||||
ok(editorVisible, "editor popup visible");
|
||||
|
||||
is(InspectorUI.editingContext.attrObj, attrValNode_class, "editor session has correct reference to `class` attribute-value node in HTML panel");
|
||||
is(InspectorUI.editingContext.attrName, "class", "editor session knows correct attribute-name");
|
||||
|
||||
editorInput.value = "Hello World";
|
||||
editorInput.focus();
|
||||
|
||||
// hit <escape> to discard the inputted value
|
||||
executeSoon(function() {
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, attrValNode_class.ownerDocument.defaultView);
|
||||
});
|
||||
|
||||
yield; // End of Step 4
|
||||
|
||||
|
||||
// Step 5: validate that the previous editing session discarded correctly, then open editor on `id` attribute value again
|
||||
ok(!InspectorUI.editingContext, "Step 5: editor session ended");
|
||||
editorVisible = editor.classList.contains("editing");
|
||||
ok(!editorVisible, "editor popup hidden");
|
||||
is(div.getAttribute("class"), "barbaz", "`class` attribute-value *not* updated");
|
||||
is(attrValNode_class.innerHTML, "barbaz", "attribute-value node in HTML panel *not* updated");
|
||||
|
||||
// double-click the `id` attribute-value node to open the editor
|
||||
executeSoon(function() {
|
||||
// firing 2 clicks right in a row to simulate a double-click
|
||||
EventUtils.synthesizeMouse(attrValNode_id, 2, 2, {clickCount: 2}, attrValNode_id.ownerDocument.defaultView);
|
||||
});
|
||||
|
||||
yield; // End of Step 5
|
||||
|
||||
|
||||
// Step 6: validate that editor opened again, then test double-click inside of editor (should do nothing)
|
||||
ok(InspectorUI.editingContext, "Step 6: editor session started");
|
||||
editorVisible = editor.classList.contains("editing");
|
||||
ok(editorVisible, "editor popup visible");
|
||||
|
||||
// double-click on the editor input box
|
||||
executeSoon(function() {
|
||||
// firing 2 clicks right in a row to simulate a double-click
|
||||
EventUtils.synthesizeMouse(editorInput, 2, 2, {clickCount: 2}, editorInput.ownerDocument.defaultView);
|
||||
|
||||
// since the previous double-click is supposed to do nothing,
|
||||
// wait a brief moment, then move on to the next step
|
||||
executeSoon(function() {
|
||||
doNextStep();
|
||||
});
|
||||
});
|
||||
|
||||
yield; // End of Step 6
|
||||
|
||||
|
||||
// Step 7: validate that editing session is still correct, then enter a value and try a click
|
||||
// outside of editor (should cancel the editing session)
|
||||
ok(InspectorUI.editingContext, "Step 7: editor session still going");
|
||||
editorVisible = editor.classList.contains("editing");
|
||||
ok(editorVisible, "editor popup still visible");
|
||||
|
||||
editorInput.value = "all your base are belong to us";
|
||||
|
||||
// single-click the `class` attribute-value node
|
||||
executeSoon(function() {
|
||||
EventUtils.synthesizeMouse(attrValNode_class, 2, 2, {}, attrValNode_class.ownerDocument.defaultView);
|
||||
});
|
||||
|
||||
yield; // End of Step 7
|
||||
|
||||
|
||||
// Step 8: validate that the editor was closed and that the editing was not saved
|
||||
ok(!InspectorUI.editingContext, "Step 8: editor session ended");
|
||||
editorVisible = editor.classList.contains("editing");
|
||||
ok(!editorVisible, "editor popup hidden");
|
||||
is(div.getAttribute("id"), "Hello World", "`id` attribute-value *not* updated");
|
||||
is(attrValNode_id.innerHTML, "Hello World", "attribute-value node in HTML panel *not* updated");
|
||||
|
||||
// End of Step 8
|
||||
|
||||
// end of all steps, so clean up
|
||||
Services.obs.removeObserver(doNextStep, INSPECTOR_NOTIFICATIONS.EDITOR_OPENED, false);
|
||||
Services.obs.removeObserver(doNextStep, INSPECTOR_NOTIFICATIONS.EDITOR_CLOSED, false);
|
||||
Services.obs.removeObserver(doNextStep, INSPECTOR_NOTIFICATIONS.EDITOR_SAVED, false);
|
||||
|
||||
executeSoon(finishUp);
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
doc = div = null;
|
||||
InspectorUI.closeInspectorUI();
|
||||
gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
function test()
|
||||
{
|
||||
waitForExplicitFinish();
|
||||
gBrowser.selectedTab = gBrowser.addTab();
|
||||
gBrowser.selectedBrowser.addEventListener("load", function() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
|
||||
doc = content.document;
|
||||
waitForFocus(setupEditorTests, content);
|
||||
}, true);
|
||||
|
||||
content.location = "data:text/html,basic tests for html panel attribute-value editor";
|
||||
}
|
||||
|
|
@ -35,14 +35,11 @@ function test() {
|
|||
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);
|
||||
});
|
||||
|
|
|
@ -49,9 +49,10 @@ function executeCopyCommand(command, expectedValue)
|
|||
is(input.value, expectedValue, "paste for command " + command);
|
||||
}
|
||||
|
||||
function invokeItemAction(ident)
|
||||
function invokeItemAction(generatedItemId)
|
||||
{
|
||||
var item = contextMenu.getElementsByAttribute("ident", ident)[0];
|
||||
var item = contextMenu.getElementsByAttribute("generateditemid",
|
||||
generatedItemId)[0];
|
||||
ok(item, "Got generated XUL menu item");
|
||||
item.doCommand();
|
||||
is(pagemenu.hasAttribute("hopeless"), false, "attribute got removed");
|
||||
|
@ -69,7 +70,7 @@ function getVisibleMenuItems(aMenu, aData) {
|
|||
if (key)
|
||||
key = key.toLowerCase();
|
||||
|
||||
var isGenerated = item.hasAttribute("generated");
|
||||
var isGenerated = item.hasAttribute("generateditemid");
|
||||
|
||||
if (item.nodeName == "menuitem") {
|
||||
var isSpellSuggestion = item.className == "spell-suggestion";
|
||||
|
|
|
@ -367,7 +367,7 @@
|
|||
|
||||
// Only add the suffix when the URL bar value isn't already "URL-like",
|
||||
// and only if we get a keyboard event, to match user expectations.
|
||||
if (!/^\s*(www|https?)\b|\/\s*$/i.test(url) &&
|
||||
if (/^\s*[^.:\/\s]+(?:\/.*|\s*)$/i.test(url) &&
|
||||
(aTriggeringEvent instanceof KeyEvent)) {
|
||||
#ifdef XP_MACOSX
|
||||
let accel = aTriggeringEvent.metaKey;
|
||||
|
@ -402,24 +402,15 @@
|
|||
|
||||
// Tack www. and suffix on. If user has appended directories, insert
|
||||
// suffix before them (bug 279035). Be careful not to get two slashes.
|
||||
// Also, don't add the suffix if it's in the original url (bug 233853).
|
||||
|
||||
let firstSlash = url.indexOf("/");
|
||||
let existingSuffix = url.indexOf(suffix.substring(0, suffix.length - 1));
|
||||
|
||||
// * Logic for slash and existing suffix (example)
|
||||
// No slash, no suffix: Add suffix (mozilla)
|
||||
// No slash, yes suffix: Add slash (mozilla.com)
|
||||
// Yes slash, no suffix: Insert suffix (mozilla/stuff)
|
||||
// Yes slash, suffix before slash: Do nothing (mozilla.com/stuff)
|
||||
// Yes slash, suffix after slash: Insert suffix (mozilla/?stuff=.com)
|
||||
|
||||
if (firstSlash >= 0) {
|
||||
if (existingSuffix == -1 || existingSuffix > firstSlash)
|
||||
url = url.substring(0, firstSlash) + suffix +
|
||||
url.substring(firstSlash + 1);
|
||||
} else
|
||||
url = url + (existingSuffix == -1 ? suffix : "/");
|
||||
url = url.substring(0, firstSlash) + suffix +
|
||||
url.substring(firstSlash + 1);
|
||||
} else {
|
||||
url = url + suffix;
|
||||
}
|
||||
|
||||
url = "http://www." + url;
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
#if !defined(XP_OS2)
|
||||
#include "nsOperaProfileMigrator.h"
|
||||
#endif
|
||||
#include "nsSeamonkeyProfileMigrator.h"
|
||||
#if defined(XP_WIN) && !defined(__MINGW32__)
|
||||
#include "nsIEProfileMigrator.h"
|
||||
#elif defined(XP_MACOSX)
|
||||
|
@ -85,7 +84,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGNOMEShellService, Init)
|
|||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsOperaProfileMigrator)
|
||||
#endif
|
||||
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)
|
||||
|
@ -114,7 +112,6 @@ NS_DEFINE_NAMED_CID(NS_SAFARIPROFILEMIGRATOR_CID);
|
|||
#if !defined(XP_OS2)
|
||||
NS_DEFINE_NAMED_CID(NS_OPERAPROFILEMIGRATOR_CID);
|
||||
#endif
|
||||
NS_DEFINE_NAMED_CID(NS_SEAMONKEYPROFILEMIGRATOR_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID);
|
||||
|
||||
static const mozilla::Module::CIDEntry kBrowserCIDs[] = {
|
||||
|
@ -136,7 +133,6 @@ static const mozilla::Module::CIDEntry kBrowserCIDs[] = {
|
|||
#if !defined(XP_OS2)
|
||||
{ &kNS_OPERAPROFILEMIGRATOR_CID, false, NULL, nsOperaProfileMigratorConstructor },
|
||||
#endif
|
||||
{ &kNS_SEAMONKEYPROFILEMIGRATOR_CID, false, NULL, nsSeamonkeyProfileMigratorConstructor },
|
||||
{ &kNS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID, false, NULL, nsPrivateBrowsingServiceWrapperConstructor },
|
||||
{ NULL }
|
||||
};
|
||||
|
@ -173,7 +169,6 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
|
|||
#if !defined(XP_OS2)
|
||||
{ NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "opera", &kNS_OPERAPROFILEMIGRATOR_CID },
|
||||
#endif
|
||||
{ NS_BROWSERPROFILEMIGRATOR_CONTRACTID_PREFIX "seamonkey", &kNS_SEAMONKEYPROFILEMIGRATOR_CID },
|
||||
{ NS_PRIVATE_BROWSING_SERVICE_CONTRACTID, &kNS_PRIVATE_BROWSING_SERVICE_WRAPPER_CID },
|
||||
{ NULL }
|
||||
};
|
||||
|
|
|
@ -340,9 +340,6 @@ var MigrationWizard = {
|
|||
case "safari":
|
||||
source = "sourceNameSafari";
|
||||
break;
|
||||
case "seamonkey":
|
||||
source = "sourceNameSeamonkey";
|
||||
break;
|
||||
}
|
||||
|
||||
// semi-wallpaper for crash when multiple profiles exist, since we haven't initialized mSourceProfile in places
|
||||
|
|
|
@ -70,19 +70,14 @@
|
|||
browser/components/migration/src/nsProfileMigrator.cpp -->
|
||||
#ifdef XP_MACOSX
|
||||
<radio id="safari" label="&importFromSafari.label;" accesskey="&importFromSafari.accesskey;"/>
|
||||
<radio id="seamonkey" label="&importFromSeamonkey.label;" accesskey="&importFromSeamonkey.accesskey;"/>
|
||||
<radio id="opera" label="&importFromOpera.label;" accesskey="&importFromOpera.accesskey;"/>
|
||||
#elifdef XP_UNIX
|
||||
<radio id="seamonkey" label="&importFromSeamonkey.label;" accesskey="&importFromSeamonkey.accesskey;"/>
|
||||
<radio id="opera" label="&importFromOpera.label;" accesskey="&importFromOpera.accesskey;"/>
|
||||
#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="opera" label="&importFromOpera.label;" accesskey="&importFromOpera.accesskey;"/>
|
||||
#else
|
||||
<radio id="seamonkey" label="&importFromSeamonkey.label;" accesskey="&importFromSeamonkey.accesskey;"/>
|
||||
#endif
|
||||
<radio id="fromfile" label="&importFromHTMLFile.label;" accesskey="&importFromHTMLFile.accesskey;" hidden="true"/>
|
||||
<radio id="nothing" label="&importFromNothing.label;" accesskey="&importFromNothing.accesskey;" hidden="true"/>
|
||||
|
|
|
@ -52,8 +52,6 @@ endif
|
|||
|
||||
CPPSRCS = nsProfileMigrator.cpp \
|
||||
nsBrowserProfileMigratorUtils.cpp \
|
||||
nsNetscapeProfileMigratorBase.cpp \
|
||||
nsSeamonkeyProfileMigrator.cpp \
|
||||
$(NULL)
|
||||
|
||||
ifneq ($(OS_ARCH),OS2)
|
||||
|
|
|
@ -2099,7 +2099,6 @@ nsIEProfileMigrator::CopySecurityPrefs(nsIPrefBranch* aPrefs)
|
|||
PRUint32 value;
|
||||
if (NS_SUCCEEDED(regKey->ReadIntValue(NS_LITERAL_STRING("SecureProtocols"),
|
||||
&value))) {
|
||||
aPrefs->SetBoolPref("security.enable_ssl2", (value >> 3) & PR_TRUE);
|
||||
aPrefs->SetBoolPref("security.enable_ssl3", (value >> 5) & PR_TRUE);
|
||||
aPrefs->SetBoolPref("security.enable_tls", (value >> 7) & PR_TRUE);
|
||||
}
|
||||
|
|
|
@ -1,469 +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 "nsICookieManager2.h"
|
||||
#include "nsIFile.h"
|
||||
#include "nsILineInputStream.h"
|
||||
#include "nsIOutputStream.h"
|
||||
#include "nsIPrefBranch.h"
|
||||
#include "nsIPrefLocalizedString.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "NSReg.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsIURL.h"
|
||||
#include "nsNetscapeProfileMigratorBase.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "prtime.h"
|
||||
#include "prprf.h"
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#define NEED_TO_FIX_4X_COOKIES 1
|
||||
#define SECONDS_BETWEEN_1900_AND_1970 2208988800UL
|
||||
#endif /* XP_MACOSX */
|
||||
|
||||
#define FILE_NAME_PREFS_5X NS_LITERAL_STRING("prefs.js")
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsNetscapeProfileMigratorBase
|
||||
nsNetscapeProfileMigratorBase::nsNetscapeProfileMigratorBase()
|
||||
{
|
||||
}
|
||||
|
||||
static nsresult
|
||||
regerr2nsresult(REGERR errCode)
|
||||
{
|
||||
switch (errCode) {
|
||||
case REGERR_PARAM:
|
||||
case REGERR_BADTYPE:
|
||||
case REGERR_BADNAME:
|
||||
return NS_ERROR_INVALID_ARG;
|
||||
|
||||
case REGERR_MEMORY:
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNetscapeProfileMigratorBase::GetProfileDataFromRegistry(nsILocalFile* aRegistryFile,
|
||||
nsISupportsArray* aProfileNames,
|
||||
nsISupportsArray* aProfileLocations)
|
||||
{
|
||||
nsresult rv;
|
||||
REGERR errCode;
|
||||
|
||||
// Ensure aRegistryFile exists before open it
|
||||
PRBool regFileExists = PR_FALSE;
|
||||
rv = aRegistryFile->Exists(®FileExists);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
if (!regFileExists)
|
||||
return NS_ERROR_FILE_NOT_FOUND;
|
||||
|
||||
// Open It
|
||||
nsCAutoString regPath;
|
||||
rv = aRegistryFile->GetNativePath(regPath);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
if ((errCode = NR_StartupRegistry()))
|
||||
return regerr2nsresult(errCode);
|
||||
|
||||
HREG reg;
|
||||
if ((errCode = NR_RegOpen(regPath.get(), ®))) {
|
||||
NR_ShutdownRegistry();
|
||||
|
||||
return regerr2nsresult(errCode);
|
||||
}
|
||||
|
||||
RKEY profilesTree;
|
||||
if ((errCode = NR_RegGetKey(reg, ROOTKEY_COMMON, "Profiles", &profilesTree))) {
|
||||
NR_RegClose(reg);
|
||||
NR_ShutdownRegistry();
|
||||
|
||||
return regerr2nsresult(errCode);
|
||||
}
|
||||
|
||||
char profileStr[MAXREGPATHLEN];
|
||||
REGENUM enumState = nsnull;
|
||||
|
||||
while (!NR_RegEnumSubkeys(reg, profilesTree, &enumState, profileStr,
|
||||
sizeof(profileStr), REGENUM_CHILDREN))
|
||||
{
|
||||
RKEY profileKey;
|
||||
if (NR_RegGetKey(reg, profilesTree, profileStr, &profileKey))
|
||||
continue;
|
||||
|
||||
// "migrated" is "yes" for all valid Seamonkey profiles. It is only "no"
|
||||
// for 4.x profiles.
|
||||
char migratedStr[3];
|
||||
errCode = NR_RegGetEntryString(reg, profileKey, (char *)"migrated",
|
||||
migratedStr, sizeof(migratedStr));
|
||||
if ((errCode != REGERR_OK && errCode != REGERR_BUFTOOSMALL) ||
|
||||
strcmp(migratedStr, "no") == 0)
|
||||
continue;
|
||||
|
||||
// Get the profile location and add it to the locations array
|
||||
REGINFO regInfo;
|
||||
regInfo.size = sizeof(REGINFO);
|
||||
|
||||
if (NR_RegGetEntryInfo(reg, profileKey, (char *)"directory", ®Info))
|
||||
continue;
|
||||
|
||||
nsCAutoString dirStr;
|
||||
dirStr.SetLength(regInfo.entryLength);
|
||||
|
||||
errCode = NR_RegGetEntryString(reg, profileKey, (char *)"directory",
|
||||
dirStr.BeginWriting(), regInfo.entryLength);
|
||||
// Remove trailing \0
|
||||
dirStr.SetLength(regInfo.entryLength-1);
|
||||
|
||||
nsCOMPtr<nsILocalFile> dir;
|
||||
#ifdef XP_MACOSX
|
||||
rv = NS_NewNativeLocalFile(EmptyCString(), PR_TRUE, getter_AddRefs(dir));
|
||||
if (NS_FAILED(rv)) break;
|
||||
dir->SetPersistentDescriptor(dirStr);
|
||||
#else
|
||||
rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(dirStr), PR_TRUE,
|
||||
getter_AddRefs(dir));
|
||||
if (NS_FAILED(rv)) break;
|
||||
#endif
|
||||
|
||||
PRBool exists;
|
||||
dir->Exists(&exists);
|
||||
|
||||
if (exists) {
|
||||
aProfileLocations->AppendElement(dir);
|
||||
|
||||
// Get the profile name and add it to the names array
|
||||
nsString profileName;
|
||||
CopyUTF8toUTF16(nsDependentCString(profileStr), profileName);
|
||||
|
||||
nsCOMPtr<nsISupportsString> profileNameString(
|
||||
do_CreateInstance("@mozilla.org/supports-string;1"));
|
||||
|
||||
profileNameString->SetData(profileName);
|
||||
aProfileNames->AppendElement(profileNameString);
|
||||
}
|
||||
}
|
||||
NR_RegClose(reg);
|
||||
NR_ShutdownRegistry();
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
#define GETPREF(xform, method, value) \
|
||||
nsresult rv = aBranch->method(xform->sourcePrefName, value); \
|
||||
if (NS_SUCCEEDED(rv)) \
|
||||
xform->prefHasValue = PR_TRUE; \
|
||||
return rv;
|
||||
|
||||
#define SETPREF(xform, method, value) \
|
||||
if (xform->prefHasValue) { \
|
||||
return aBranch->method(xform->targetPrefName ? xform->targetPrefName : xform->sourcePrefName, value); \
|
||||
} \
|
||||
return NS_OK;
|
||||
|
||||
nsresult
|
||||
nsNetscapeProfileMigratorBase::GetString(void* aTransform, nsIPrefBranch* aBranch)
|
||||
{
|
||||
PrefTransform* xform = (PrefTransform*)aTransform;
|
||||
GETPREF(xform, GetCharPref, &xform->stringValue);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNetscapeProfileMigratorBase::SetString(void* aTransform, nsIPrefBranch* aBranch)
|
||||
{
|
||||
PrefTransform* xform = (PrefTransform*)aTransform;
|
||||
SETPREF(xform, SetCharPref, xform->stringValue);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNetscapeProfileMigratorBase::GetWString(void* aTransform, nsIPrefBranch* aBranch)
|
||||
{
|
||||
PrefTransform* xform = (PrefTransform*)aTransform;
|
||||
nsCOMPtr<nsIPrefLocalizedString> prefValue;
|
||||
nsresult rv = aBranch->GetComplexValue(xform->sourcePrefName,
|
||||
NS_GET_IID(nsIPrefLocalizedString),
|
||||
getter_AddRefs(prefValue));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && prefValue) {
|
||||
nsString data;
|
||||
prefValue->ToString(getter_Copies(data));
|
||||
|
||||
xform->stringValue = ToNewCString(NS_ConvertUTF16toUTF8(data));
|
||||
xform->prefHasValue = PR_TRUE;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNetscapeProfileMigratorBase::SetWStringFromASCII(void* aTransform, nsIPrefBranch* aBranch)
|
||||
{
|
||||
PrefTransform* xform = (PrefTransform*)aTransform;
|
||||
if (xform->prefHasValue) {
|
||||
nsCOMPtr<nsIPrefLocalizedString> pls(do_CreateInstance("@mozilla.org/pref-localizedstring;1"));
|
||||
NS_ConvertUTF8toUTF16 data(xform->stringValue);
|
||||
pls->SetData(data.get());
|
||||
return aBranch->SetComplexValue(xform->targetPrefName ? xform->targetPrefName : xform->sourcePrefName, NS_GET_IID(nsIPrefLocalizedString), pls);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNetscapeProfileMigratorBase::SetWString(void* aTransform, nsIPrefBranch* aBranch)
|
||||
{
|
||||
PrefTransform* xform = (PrefTransform*)aTransform;
|
||||
if (xform->prefHasValue) {
|
||||
nsCOMPtr<nsIPrefLocalizedString> pls(do_CreateInstance("@mozilla.org/pref-localizedstring;1"));
|
||||
nsAutoString data = NS_ConvertUTF8toUTF16(xform->stringValue);
|
||||
pls->SetData(data.get());
|
||||
return aBranch->SetComplexValue(xform->targetPrefName ? xform->targetPrefName : xform->sourcePrefName, NS_GET_IID(nsIPrefLocalizedString), pls);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
nsresult
|
||||
nsNetscapeProfileMigratorBase::GetBool(void* aTransform, nsIPrefBranch* aBranch)
|
||||
{
|
||||
PrefTransform* xform = (PrefTransform*)aTransform;
|
||||
GETPREF(xform, GetBoolPref, &xform->boolValue);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNetscapeProfileMigratorBase::SetBool(void* aTransform, nsIPrefBranch* aBranch)
|
||||
{
|
||||
PrefTransform* xform = (PrefTransform*)aTransform;
|
||||
SETPREF(xform, SetBoolPref, xform->boolValue);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNetscapeProfileMigratorBase::GetInt(void* aTransform, nsIPrefBranch* aBranch)
|
||||
{
|
||||
PrefTransform* xform = (PrefTransform*)aTransform;
|
||||
GETPREF(xform, GetIntPref, &xform->intValue);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNetscapeProfileMigratorBase::SetInt(void* aTransform, nsIPrefBranch* aBranch)
|
||||
{
|
||||
PrefTransform* xform = (PrefTransform*)aTransform;
|
||||
SETPREF(xform, SetIntPref, xform->intValue);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNetscapeProfileMigratorBase::CopyFile(const nsAString& aSourceFileName, const nsAString& aTargetFileName)
|
||||
{
|
||||
nsCOMPtr<nsIFile> sourceFile;
|
||||
mSourceProfile->Clone(getter_AddRefs(sourceFile));
|
||||
|
||||
sourceFile->Append(aSourceFileName);
|
||||
PRBool exists = PR_FALSE;
|
||||
sourceFile->Exists(&exists);
|
||||
if (!exists)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIFile> targetFile;
|
||||
mTargetProfile->Clone(getter_AddRefs(targetFile));
|
||||
|
||||
targetFile->Append(aTargetFileName);
|
||||
targetFile->Exists(&exists);
|
||||
if (exists)
|
||||
targetFile->Remove(PR_FALSE);
|
||||
|
||||
return sourceFile->CopyTo(mTargetProfile, aTargetFileName);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNetscapeProfileMigratorBase::ImportNetscapeBookmarks(const nsAString& aBookmarksFileName,
|
||||
const PRUnichar* aImportSourceNameKey)
|
||||
{
|
||||
nsCOMPtr<nsIFile> bookmarksFile;
|
||||
mSourceProfile->Clone(getter_AddRefs(bookmarksFile));
|
||||
bookmarksFile->Append(aBookmarksFileName);
|
||||
|
||||
return ImportBookmarksHTML(bookmarksFile, PR_FALSE, PR_FALSE, aImportSourceNameKey);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNetscapeProfileMigratorBase::ImportNetscapeCookies(nsIFile* aCookiesFile)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIInputStream> cookiesStream;
|
||||
rv = NS_NewLocalFileInputStream(getter_AddRefs(cookiesStream), aCookiesFile);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsILineInputStream> lineInputStream(do_QueryInterface(cookiesStream));
|
||||
|
||||
// This code is copied from mozilla/netwerk/cookie/src/nsCookieManager.cpp
|
||||
static NS_NAMED_LITERAL_CSTRING(kTrue, "TRUE");
|
||||
|
||||
nsCAutoString buffer;
|
||||
PRBool isMore = PR_TRUE;
|
||||
PRInt32 hostIndex = 0, isDomainIndex, pathIndex, secureIndex, expiresIndex, nameIndex, cookieIndex;
|
||||
PRInt32 numInts;
|
||||
PRInt64 expires;
|
||||
PRBool isDomain;
|
||||
PRInt64 currentTime = PR_Now() / PR_USEC_PER_SEC;
|
||||
|
||||
nsCOMPtr<nsICookieManager2> cookieManager(do_GetService(NS_COOKIEMANAGER_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
/* file format is:
|
||||
*
|
||||
* host \t isDomain \t path \t secure \t expires \t name \t cookie
|
||||
*
|
||||
* if this format isn't respected we move onto the next line in the file.
|
||||
* isDomain is "TRUE" or "FALSE" (default to "FALSE")
|
||||
* isSecure is "TRUE" or "FALSE" (default to "TRUE")
|
||||
* expires is a PRInt64 integer
|
||||
* note 1: cookie can contain tabs.
|
||||
* note 2: cookies are written in order of lastAccessed time:
|
||||
* most-recently used come first; least-recently-used come last.
|
||||
*/
|
||||
|
||||
while (isMore && NS_SUCCEEDED(lineInputStream->ReadLine(buffer, &isMore))) {
|
||||
if (buffer.IsEmpty() || buffer.First() == '#')
|
||||
continue;
|
||||
|
||||
// this is a cheap, cheesy way of parsing a tab-delimited line into
|
||||
// string indexes, which can be lopped off into substrings. just for
|
||||
// purposes of obfuscation, it also checks that each token was found.
|
||||
// todo: use iterators?
|
||||
if ((isDomainIndex = buffer.FindChar('\t', hostIndex) + 1) == 0 ||
|
||||
(pathIndex = buffer.FindChar('\t', isDomainIndex) + 1) == 0 ||
|
||||
(secureIndex = buffer.FindChar('\t', pathIndex) + 1) == 0 ||
|
||||
(expiresIndex = buffer.FindChar('\t', secureIndex) + 1) == 0 ||
|
||||
(nameIndex = buffer.FindChar('\t', expiresIndex) + 1) == 0 ||
|
||||
(cookieIndex = buffer.FindChar('\t', nameIndex) + 1) == 0)
|
||||
continue;
|
||||
|
||||
// check the expirytime first - if it's expired, ignore
|
||||
// nullstomp the trailing tab, to avoid copying the string
|
||||
char *iter = buffer.BeginWriting();
|
||||
*(iter += nameIndex - 1) = char(0);
|
||||
numInts = PR_sscanf(buffer.get() + expiresIndex, "%lld", &expires);
|
||||
if (numInts != 1 || expires < currentTime)
|
||||
continue;
|
||||
|
||||
isDomain = Substring(buffer, isDomainIndex, pathIndex - isDomainIndex - 1).Equals(kTrue);
|
||||
const nsDependentCSubstring host =
|
||||
Substring(buffer, hostIndex, isDomainIndex - hostIndex - 1);
|
||||
// check for bad legacy cookies (domain not starting with a dot, or containing a port),
|
||||
// and discard
|
||||
if (isDomain && !host.IsEmpty() && host.First() != '.' ||
|
||||
host.FindChar(':') != -1)
|
||||
continue;
|
||||
|
||||
// create a new nsCookie and assign the data.
|
||||
rv = cookieManager->Add(host,
|
||||
Substring(buffer, pathIndex, secureIndex - pathIndex - 1),
|
||||
Substring(buffer, nameIndex, cookieIndex - nameIndex - 1),
|
||||
Substring(buffer, cookieIndex, buffer.Length() - cookieIndex),
|
||||
Substring(buffer, secureIndex, expiresIndex - secureIndex - 1).Equals(kTrue),
|
||||
PR_FALSE, // isHttpOnly
|
||||
PR_FALSE, // isSession
|
||||
expires);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNetscapeProfileMigratorBase::GetSignonFileName(PRBool aReplace, char** aFileName)
|
||||
{
|
||||
nsresult rv;
|
||||
if (aReplace) {
|
||||
// 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> sourcePrefsName;
|
||||
mSourceProfile->Clone(getter_AddRefs(sourcePrefsName));
|
||||
sourcePrefsName->Append(FILE_NAME_PREFS_5X);
|
||||
psvc->ReadUserPrefs(sourcePrefsName);
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> branch(do_QueryInterface(psvc));
|
||||
rv = branch->GetCharPref("signon.SignonFileName", aFileName);
|
||||
}
|
||||
else
|
||||
rv = LocateSignonsFile(aFileName);
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsNetscapeProfileMigratorBase::LocateSignonsFile(char** aResult)
|
||||
{
|
||||
nsCOMPtr<nsISimpleEnumerator> entries;
|
||||
nsresult rv = mSourceProfile->GetDirectoryEntries(getter_AddRefs(entries));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCAutoString fileName;
|
||||
do {
|
||||
PRBool hasMore = PR_FALSE;
|
||||
rv = entries->HasMoreElements(&hasMore);
|
||||
if (NS_FAILED(rv) || !hasMore) break;
|
||||
|
||||
nsCOMPtr<nsISupports> supp;
|
||||
rv = entries->GetNext(getter_AddRefs(supp));
|
||||
if (NS_FAILED(rv)) break;
|
||||
|
||||
nsCOMPtr<nsIFile> currFile(do_QueryInterface(supp));
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
rv = NS_NewFileURI(getter_AddRefs(uri), currFile);
|
||||
if (NS_FAILED(rv)) break;
|
||||
nsCOMPtr<nsIURL> url(do_QueryInterface(uri));
|
||||
|
||||
nsCAutoString extn;
|
||||
url->GetFileExtension(extn);
|
||||
|
||||
if (extn.Equals("s", CaseInsensitiveCompare)) {
|
||||
url->GetFileName(fileName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (1);
|
||||
|
||||
*aResult = ToNewCString(fileName);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
@ -1,101 +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 netscapeprofilemigratorbase___h___
|
||||
#define netscapeprofilemigratorbase___h___
|
||||
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsIStringBundle.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsStringAPI.h"
|
||||
|
||||
class nsIFile;
|
||||
class nsIPrefBranch;
|
||||
|
||||
class nsNetscapeProfileMigratorBase
|
||||
{
|
||||
public:
|
||||
nsNetscapeProfileMigratorBase();
|
||||
virtual ~nsNetscapeProfileMigratorBase() { }
|
||||
|
||||
public:
|
||||
typedef nsresult(*prefConverter)(void*, nsIPrefBranch*);
|
||||
|
||||
struct PrefTransform {
|
||||
const char* sourcePrefName;
|
||||
const char* targetPrefName;
|
||||
prefConverter prefGetterFunc;
|
||||
prefConverter prefSetterFunc;
|
||||
PRBool prefHasValue;
|
||||
union {
|
||||
PRInt32 intValue;
|
||||
PRBool boolValue;
|
||||
char* stringValue;
|
||||
};
|
||||
};
|
||||
|
||||
static nsresult GetString(void* aTransform, nsIPrefBranch* aBranch);
|
||||
static nsresult SetString(void* aTransform, nsIPrefBranch* aBranch);
|
||||
static nsresult GetWString(void* aTransform, nsIPrefBranch* aBranch);
|
||||
static nsresult SetWString(void* aTransform, nsIPrefBranch* aBranch);
|
||||
static nsresult SetWStringFromASCII(void* aTransform, nsIPrefBranch* aBranch);
|
||||
static nsresult GetBool(void* aTransform, nsIPrefBranch* aBranch);
|
||||
static nsresult SetBool(void* aTransform, nsIPrefBranch* aBranch);
|
||||
static nsresult GetInt(void* aTransform, nsIPrefBranch* aBranch);
|
||||
static nsresult SetInt(void* aTransform, nsIPrefBranch* aBranch);
|
||||
|
||||
protected:
|
||||
nsresult GetProfileDataFromRegistry(nsILocalFile* aRegistryFile,
|
||||
nsISupportsArray* aProfileNames,
|
||||
nsISupportsArray* aProfileLocations);
|
||||
|
||||
nsresult CopyFile(const nsAString& aSourceFileName, const nsAString& aTargetFileName);
|
||||
|
||||
nsresult ImportNetscapeBookmarks(const nsAString& aBookmarksFileName,
|
||||
const PRUnichar* aImportSourceNameKey);
|
||||
|
||||
nsresult ImportNetscapeCookies(nsIFile* aCookiesFile);
|
||||
|
||||
nsresult GetSignonFileName(PRBool aReplace, char** aFileName);
|
||||
nsresult LocateSignonsFile(char** aResult);
|
||||
|
||||
protected:
|
||||
nsCOMPtr<nsILocalFile> mSourceProfile;
|
||||
nsCOMPtr<nsIFile> mTargetProfile;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -320,7 +320,6 @@ nsOperaProfileMigrator::PrefTransform gTransforms[] = {
|
|||
{ "Link", nsnull, _OPM(COLOR), "browser.anchor_color", _OPM(SetString), PR_FALSE, { -1 } },
|
||||
{ nsnull, "Underline", _OPM(BOOL), "browser.underline_anchors", _OPM(SetBool), PR_FALSE, { -1 } },
|
||||
|
||||
{ "Security Prefs", "Enable SSL v2", _OPM(BOOL), "security.enable_ssl2", _OPM(SetBool), PR_FALSE, { -1 } },
|
||||
{ nsnull, "Enable SSL v3", _OPM(BOOL), "security.enable_ssl3", _OPM(SetBool), PR_FALSE, { -1 } },
|
||||
{ nsnull, "Enable TLS v1.0", _OPM(BOOL), "security.enable_tls", _OPM(SetBool), PR_FALSE, { -1 } },
|
||||
|
||||
|
|
|
@ -162,7 +162,6 @@ NS_IMPL_ISUPPORTS1(nsProfileMigrator, nsIProfileMigrator)
|
|||
|
||||
#define INTERNAL_NAME_IEXPLORE "iexplore"
|
||||
#define INTERNAL_NAME_MOZILLA_SUITE "apprunner"
|
||||
#define INTERNAL_NAME_SEAMONKEY "seamonkey"
|
||||
#define INTERNAL_NAME_OPERA "opera"
|
||||
#endif
|
||||
|
||||
|
@ -243,12 +242,7 @@ nsProfileMigrator::GetDefaultBrowserMigratorKey(nsACString& aKey,
|
|||
aKey = "ie";
|
||||
return NS_OK;
|
||||
}
|
||||
if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_MOZILLA_SUITE) ||
|
||||
internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_SEAMONKEY)) {
|
||||
aKey = "seamonkey";
|
||||
return NS_OK;
|
||||
}
|
||||
if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_OPERA)) {
|
||||
else if (internalName.LowerCaseEqualsLiteral(INTERNAL_NAME_OPERA)) {
|
||||
aKey = "opera";
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -267,7 +261,6 @@ nsProfileMigrator::GetDefaultBrowserMigratorKey(nsACString& aKey,
|
|||
#if defined(XP_MACOSX)
|
||||
CHECK_MIGRATOR("safari");
|
||||
#endif
|
||||
CHECK_MIGRATOR("seamonkey");
|
||||
CHECK_MIGRATOR("opera");
|
||||
|
||||
#undef CHECK_MIGRATOR
|
||||
|
|
|
@ -1,722 +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 "nsILoginInfo.h"
|
||||
#include "nsILoginManager.h"
|
||||
#include "nsILoginManagerStorage.h"
|
||||
#include "nsIPrefLocalizedString.h"
|
||||
#include "nsIPrefService.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsISupportsPrimitives.h"
|
||||
#include "nsNetCID.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsSeamonkeyProfileMigrator.h"
|
||||
#include "nsIProfileMigrator.h"
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsSeamonkeyProfileMigrator
|
||||
|
||||
#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_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_USERCONTENT NS_LITERAL_STRING("userContent.css")
|
||||
#define DIR_NAME_CHROME NS_LITERAL_STRING("chrome")
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsSeamonkeyProfileMigrator, nsIBrowserProfileMigrator)
|
||||
|
||||
nsSeamonkeyProfileMigrator::nsSeamonkeyProfileMigrator()
|
||||
{
|
||||
mObserverService = do_GetService("@mozilla.org/observer-service;1");
|
||||
}
|
||||
|
||||
nsSeamonkeyProfileMigrator::~nsSeamonkeyProfileMigrator()
|
||||
{
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsIBrowserProfileMigrator
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSeamonkeyProfileMigrator::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);
|
||||
|
||||
NOTIFY_OBSERVERS(MIGRATION_STARTED, nsnull);
|
||||
|
||||
COPY_DATA(CopyPreferences, aReplace, nsIBrowserProfileMigrator::SETTINGS);
|
||||
COPY_DATA(CopyCookies, aReplace, nsIBrowserProfileMigrator::COOKIES);
|
||||
COPY_DATA(CopyPasswords, aReplace, nsIBrowserProfileMigrator::PASSWORDS);
|
||||
COPY_DATA(CopyOtherData, aReplace, nsIBrowserProfileMigrator::OTHERDATA);
|
||||
|
||||
// Need to do startup before trying to copy bookmarks, since bookmarks
|
||||
// import requires a profile. Can't do it earlier because services might
|
||||
// end up creating the files we try to copy above.
|
||||
if (aStartup) {
|
||||
rv = aStartup->DoStartup();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
COPY_DATA(CopyBookmarks, aReplace, nsIBrowserProfileMigrator::BOOKMARKS);
|
||||
|
||||
if (aReplace &&
|
||||
(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
|
||||
nsSeamonkeyProfileMigrator::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_FALSE },
|
||||
{ ToNewUnicode(FILE_NAME_BOOKMARKS),
|
||||
nsIBrowserProfileMigrator::BOOKMARKS,
|
||||
PR_FALSE },
|
||||
{ ToNewUnicode(FILE_NAME_DOWNLOADS),
|
||||
nsIBrowserProfileMigrator::OTHERDATA,
|
||||
PR_TRUE },
|
||||
{ ToNewUnicode(FILE_NAME_MIMETYPES),
|
||||
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
|
||||
nsSeamonkeyProfileMigrator::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
|
||||
nsSeamonkeyProfileMigrator::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
|
||||
nsSeamonkeyProfileMigrator::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
|
||||
FillProfileDataFromSeamonkeyRegistry();
|
||||
}
|
||||
|
||||
NS_IF_ADDREF(*aResult = mProfileNames);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSeamonkeyProfileMigrator::GetSourceHomePageURL(nsACString& aResult)
|
||||
{
|
||||
// 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(FILE_NAME_PREFS);
|
||||
|
||||
psvc->ReadUserPrefs(sourcePrefsFile);
|
||||
|
||||
nsCOMPtr<nsIPrefBranch> branch(do_QueryInterface(psvc));
|
||||
|
||||
PRBool hasUserValue;
|
||||
nsCOMPtr<nsIPrefLocalizedString> prefValue;
|
||||
nsresult rv = branch->PrefHasUserValue("browser.startup.homepage", &hasUserValue);
|
||||
if (NS_SUCCEEDED(rv) && hasUserValue) {
|
||||
rv = branch->GetComplexValue("browser.startup.homepage",
|
||||
NS_GET_IID(nsIPrefLocalizedString),
|
||||
getter_AddRefs(prefValue));
|
||||
if (NS_SUCCEEDED(rv) && prefValue) {
|
||||
nsString data;
|
||||
prefValue->ToString(getter_Copies(data));
|
||||
|
||||
nsCAutoString val;
|
||||
val = ToNewCString(NS_ConvertUTF16toUTF8(data));
|
||||
|
||||
aResult.Assign(val);
|
||||
}
|
||||
}
|
||||
|
||||
psvc->ResetPrefs();
|
||||
psvc->ReadUserPrefs(nsnull);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// nsSeamonkeyProfileMigrator
|
||||
|
||||
nsresult
|
||||
nsSeamonkeyProfileMigrator::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
|
||||
nsSeamonkeyProfileMigrator::FillProfileDataFromSeamonkeyRegistry()
|
||||
{
|
||||
// Find the Seamonkey Registry
|
||||
nsCOMPtr<nsIProperties> fileLocator(do_GetService("@mozilla.org/file/directory_service;1"));
|
||||
nsCOMPtr<nsILocalFile> seamonkeyRegistry;
|
||||
#ifdef XP_WIN
|
||||
fileLocator->Get(NS_WIN_APPDATA_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(seamonkeyRegistry));
|
||||
|
||||
seamonkeyRegistry->Append(NS_LITERAL_STRING("Mozilla"));
|
||||
seamonkeyRegistry->Append(NS_LITERAL_STRING("registry.dat"));
|
||||
#elif defined(XP_MACOSX)
|
||||
fileLocator->Get(NS_MAC_USER_LIB_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(seamonkeyRegistry));
|
||||
|
||||
seamonkeyRegistry->Append(NS_LITERAL_STRING("Mozilla"));
|
||||
seamonkeyRegistry->Append(NS_LITERAL_STRING("Application Registry"));
|
||||
#elif defined(XP_UNIX)
|
||||
fileLocator->Get(NS_UNIX_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(seamonkeyRegistry));
|
||||
|
||||
seamonkeyRegistry->Append(NS_LITERAL_STRING(".mozilla"));
|
||||
seamonkeyRegistry->Append(NS_LITERAL_STRING("appreg"));
|
||||
#elif defined(XP_OS2)
|
||||
fileLocator->Get(NS_OS2_HOME_DIR, NS_GET_IID(nsILocalFile), getter_AddRefs(seamonkeyRegistry));
|
||||
|
||||
seamonkeyRegistry->Append(NS_LITERAL_STRING("Mozilla"));
|
||||
seamonkeyRegistry->Append(NS_LITERAL_STRING("registry.dat"));
|
||||
#endif
|
||||
|
||||
return GetProfileDataFromRegistry(seamonkeyRegistry, mProfileNames, mProfileLocations);
|
||||
}
|
||||
|
||||
#define F(a) nsSeamonkeyProfileMigrator::a
|
||||
|
||||
#define MAKEPREFTRANSFORM(pref, newpref, getmethod, setmethod) \
|
||||
{ pref, newpref, F(Get##getmethod), F(Set##setmethod), PR_FALSE, { -1 } }
|
||||
|
||||
#define MAKESAMETYPEPREFTRANSFORM(pref, method) \
|
||||
{ pref, 0, F(Get##method), F(Set##method), PR_FALSE, { -1 } }
|
||||
|
||||
|
||||
static
|
||||
nsSeamonkeyProfileMigrator::PrefTransform gTransforms[] = {
|
||||
MAKESAMETYPEPREFTRANSFORM("signon.SignonFileName", String),
|
||||
MAKESAMETYPEPREFTRANSFORM("browser.tabs.autoHide", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("browser.tabs.loadInBackground", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("browser.enable_automatic_image_resizing", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("network.cookie.warnAboutCookies", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("network.cookie.lifetime.enabled", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("network.cookie.lifetime.behavior", Int),
|
||||
MAKESAMETYPEPREFTRANSFORM("dom.disable_open_during_load", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("signon.rememberSignons", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("security.enable_ssl2", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("security.enable_ssl3", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("security.enable_tls", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("security.warn_entering_secure", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("security.warn_entering_weak", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("security.warn_leaving_secure", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("security.warn_submit_insecure", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("security.warn_viewing_mixed", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("security.default_personal_cert", String),
|
||||
MAKESAMETYPEPREFTRANSFORM("security.OSCP.enabled", Int),
|
||||
MAKESAMETYPEPREFTRANSFORM("security.OSCP.signingCA", String),
|
||||
MAKESAMETYPEPREFTRANSFORM("security.OSCP.URL", String),
|
||||
MAKESAMETYPEPREFTRANSFORM("javascript.enabled", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("dom.disable_window_move_resize", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("dom.disable_window_flip", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("dom.disable_window_open_feature.status", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("dom.disable_window_status_change", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("dom.disable_image_src_set", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("accessibility.typeaheadfind.autostart", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("accessibility.typeaheadfind.linksonly", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("network.proxy.type", Int),
|
||||
MAKESAMETYPEPREFTRANSFORM("network.proxy.http", String),
|
||||
MAKESAMETYPEPREFTRANSFORM("network.proxy.http_port", Int),
|
||||
MAKESAMETYPEPREFTRANSFORM("network.proxy.ftp", String),
|
||||
MAKESAMETYPEPREFTRANSFORM("network.proxy.ftp_port", Int),
|
||||
MAKESAMETYPEPREFTRANSFORM("network.proxy.ssl", String),
|
||||
MAKESAMETYPEPREFTRANSFORM("network.proxy.ssl_port", Int),
|
||||
MAKESAMETYPEPREFTRANSFORM("network.proxy.socks", String),
|
||||
MAKESAMETYPEPREFTRANSFORM("network.proxy.socks_port", Int),
|
||||
MAKESAMETYPEPREFTRANSFORM("network.proxy.no_proxies_on", String),
|
||||
MAKESAMETYPEPREFTRANSFORM("network.proxy.autoconfig_url", String),
|
||||
MAKESAMETYPEPREFTRANSFORM("browser.display.foreground_color", String),
|
||||
MAKESAMETYPEPREFTRANSFORM("browser.display.background_color", String),
|
||||
MAKESAMETYPEPREFTRANSFORM("browser.anchor_color", String),
|
||||
MAKESAMETYPEPREFTRANSFORM("browser.visited_color", String),
|
||||
MAKESAMETYPEPREFTRANSFORM("browser.underline_anchors", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("browser.display.use_system_colors", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("browser.display.use_document_colors", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("browser.display.use_document_fonts", Bool),
|
||||
MAKESAMETYPEPREFTRANSFORM("intl.charset.default", String),
|
||||
MAKESAMETYPEPREFTRANSFORM("intl.accept_languages", String),
|
||||
|
||||
MAKEPREFTRANSFORM("network.image.imageBehavior", 0, Int, Image),
|
||||
MAKEPREFTRANSFORM("network.cookie.cookieBehavior", 0, Int, Cookie),
|
||||
MAKEPREFTRANSFORM("browser.downloadmanager.behavior", 0, Int, DownloadManager),
|
||||
|
||||
MAKEPREFTRANSFORM("wallet.captureForms", "formfill.enabled", Bool, Bool)
|
||||
};
|
||||
|
||||
nsresult
|
||||
nsSeamonkeyProfileMigrator::SetImage(void* aTransform, nsIPrefBranch* aBranch)
|
||||
{
|
||||
PrefTransform* xform = (PrefTransform*)aTransform;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (xform->prefHasValue)
|
||||
rv = aBranch->SetIntPref("network.image.imageBehavior", xform->intValue == 1 ? 0 : xform->intValue);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSeamonkeyProfileMigrator::SetCookie(void* aTransform, nsIPrefBranch* aBranch)
|
||||
{
|
||||
PrefTransform* xform = (PrefTransform*)aTransform;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (xform->prefHasValue)
|
||||
rv = aBranch->SetIntPref("network.cookie.cookieBehavior", xform->intValue == 3 ? 0 : xform->intValue);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSeamonkeyProfileMigrator::SetDownloadManager(void* aTransform, nsIPrefBranch* aBranch)
|
||||
{
|
||||
PrefTransform* xform = (PrefTransform*)aTransform;
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
if (xform->prefHasValue) {
|
||||
// Seamonkey's download manager uses a single pref to control behavior:
|
||||
// 0 - show download manager window
|
||||
// 1 - show individual progress dialogs
|
||||
// 2 - show nothing
|
||||
//
|
||||
// Firefox has only a download manager window, but it can behave like a progress dialog, thus:
|
||||
// 0 || 1 -> show downloads window when a download starts
|
||||
// 2 -> don't show anything when a download starts
|
||||
// 1 -> close the downloads window as if it were a progress window when downloads complete.
|
||||
//
|
||||
rv |= aBranch->SetBoolPref("browser.download.manager.showWhenStarting", xform->intValue != 2);
|
||||
rv |= aBranch->SetBoolPref("browser.download.manager.closeWhenDone", xform->intValue == 1);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSeamonkeyProfileMigrator::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);
|
||||
|
||||
nsTArray<FontPref> fontPrefs;
|
||||
ReadFontsBranch(psvc, &fontPrefs);
|
||||
|
||||
// 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);
|
||||
|
||||
WriteFontsBranch(psvc, &fontPrefs);
|
||||
|
||||
nsCOMPtr<nsIFile> targetPrefsFile;
|
||||
mTargetProfile->Clone(getter_AddRefs(targetPrefsFile));
|
||||
targetPrefsFile->Append(aTargetPrefFileName);
|
||||
psvc->SavePrefFile(targetPrefsFile);
|
||||
|
||||
psvc->ResetPrefs();
|
||||
psvc->ReadUserPrefs(nsnull);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsSeamonkeyProfileMigrator::ReadFontsBranch(nsIPrefService* aPrefService,
|
||||
nsTArray<FontPref>* aPrefs)
|
||||
{
|
||||
// Enumerate the branch
|
||||
nsCOMPtr<nsIPrefBranch> branch;
|
||||
aPrefService->GetBranch("font.", getter_AddRefs(branch));
|
||||
|
||||
PRUint32 count;
|
||||
char** prefs = nsnull;
|
||||
nsresult rv = branch->GetChildList("", &count, &prefs);
|
||||
if (NS_FAILED(rv)) return;
|
||||
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
// Save each pref's value into an array
|
||||
char* currPref = prefs[i];
|
||||
PRInt32 type;
|
||||
branch->GetPrefType(currPref, &type);
|
||||
FontPref* pref = aPrefs->AppendElement();
|
||||
pref->prefName = currPref;
|
||||
pref->type = type;
|
||||
switch (type) {
|
||||
case nsIPrefBranch::PREF_STRING:
|
||||
rv = branch->GetCharPref(currPref, &pref->stringValue);
|
||||
break;
|
||||
case nsIPrefBranch::PREF_BOOL:
|
||||
rv = branch->GetBoolPref(currPref, &pref->boolValue);
|
||||
break;
|
||||
case nsIPrefBranch::PREF_INT:
|
||||
rv = branch->GetIntPref(currPref, &pref->intValue);
|
||||
break;
|
||||
case nsIPrefBranch::PREF_INVALID:
|
||||
{
|
||||
nsCOMPtr<nsIPrefLocalizedString> str;
|
||||
rv = branch->GetComplexValue(currPref,
|
||||
NS_GET_IID(nsIPrefLocalizedString),
|
||||
getter_AddRefs(str));
|
||||
if (NS_SUCCEEDED(rv) && str)
|
||||
str->ToString(&pref->wstringValue);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv))
|
||||
aPrefs->RemoveElementAt(aPrefs->Length()-1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSeamonkeyProfileMigrator::WriteFontsBranch(nsIPrefService* aPrefService,
|
||||
nsTArray<FontPref>* aPrefs)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
// Enumerate the branch
|
||||
nsCOMPtr<nsIPrefBranch> branch;
|
||||
aPrefService->GetBranch("font.", getter_AddRefs(branch));
|
||||
|
||||
PRUint32 count = aPrefs->Length();
|
||||
for (PRUint32 i = 0; i < count; ++i) {
|
||||
FontPref &pref = aPrefs->ElementAt(i);
|
||||
switch (pref.type) {
|
||||
case nsIPrefBranch::PREF_STRING:
|
||||
rv = branch->SetCharPref(pref.prefName, pref.stringValue);
|
||||
NS_Free(pref.stringValue);
|
||||
pref.stringValue = nsnull;
|
||||
break;
|
||||
case nsIPrefBranch::PREF_BOOL:
|
||||
rv = branch->SetBoolPref(pref.prefName, pref.boolValue);
|
||||
break;
|
||||
case nsIPrefBranch::PREF_INT:
|
||||
rv = branch->SetIntPref(pref.prefName, pref.intValue);
|
||||
break;
|
||||
case nsIPrefBranch::PREF_INVALID:
|
||||
nsCOMPtr<nsIPrefLocalizedString> pls(do_CreateInstance("@mozilla.org/pref-localizedstring;1"));
|
||||
pls->SetData(pref.wstringValue);
|
||||
rv = branch->SetComplexValue(pref.prefName,
|
||||
NS_GET_IID(nsIPrefLocalizedString),
|
||||
pls);
|
||||
NS_Free(pref.wstringValue);
|
||||
pref.wstringValue = nsnull;
|
||||
break;
|
||||
}
|
||||
NS_Free(pref.prefName);
|
||||
}
|
||||
aPrefs->Clear();
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSeamonkeyProfileMigrator::CopyPreferences(PRBool aReplace)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (!aReplace)
|
||||
return rv;
|
||||
|
||||
rv |= TransformPreferences(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 |= CopyUserContentSheet();
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSeamonkeyProfileMigrator::CopyUserContentSheet()
|
||||
{
|
||||
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)
|
||||
return NS_OK;
|
||||
|
||||
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);
|
||||
|
||||
return sourceUserContent->CopyTo(targetChromeDir, FILE_NAME_USERCONTENT);
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSeamonkeyProfileMigrator::CopyCookies(PRBool aReplace)
|
||||
{
|
||||
nsresult rv;
|
||||
if (aReplace)
|
||||
rv = CopyFile(FILE_NAME_COOKIES, FILE_NAME_COOKIES);
|
||||
else {
|
||||
nsCOMPtr<nsIFile> seamonkeyCookiesFile;
|
||||
mSourceProfile->Clone(getter_AddRefs(seamonkeyCookiesFile));
|
||||
seamonkeyCookiesFile->Append(FILE_NAME_COOKIES);
|
||||
|
||||
rv = ImportNetscapeCookies(seamonkeyCookiesFile);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSeamonkeyProfileMigrator::CopyPasswords(PRBool aReplace)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
nsCString signonsFileName;
|
||||
GetSignonFileName(aReplace, getter_Copies(signonsFileName));
|
||||
|
||||
if (signonsFileName.IsEmpty())
|
||||
return NS_ERROR_FILE_NOT_FOUND;
|
||||
|
||||
NS_ConvertASCIItoUTF16 fileName(signonsFileName);
|
||||
if (aReplace)
|
||||
rv = CopyFile(fileName, fileName);
|
||||
else {
|
||||
// Get the password manager, which is the destination for the passwords
|
||||
// being migrated. Also create a new instance of the legacy password
|
||||
// storage component, which we'll use to slurp in the signons from
|
||||
// Seamonkey's signons.txt.
|
||||
nsCOMPtr<nsILoginManager> pwmgr(
|
||||
do_GetService("@mozilla.org/login-manager;1"));
|
||||
nsCOMPtr<nsILoginManagerStorage> importer(
|
||||
do_CreateInstance("@mozilla.org/login-manager/storage/legacy;1"));
|
||||
|
||||
nsCOMPtr<nsIFile> signonsFile;
|
||||
mSourceProfile->Clone(getter_AddRefs(signonsFile));
|
||||
signonsFile->Append(fileName);
|
||||
|
||||
importer->InitWithFile(signonsFile, nsnull);
|
||||
|
||||
PRUint32 count;
|
||||
nsILoginInfo **logins;
|
||||
|
||||
rv = importer->GetAllLogins(&count, &logins);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
pwmgr->AddLogin(logins[i]);
|
||||
}
|
||||
NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, logins);
|
||||
|
||||
PRUnichar **hostnames;
|
||||
rv = importer->GetAllDisabledHosts(&count, &hostnames);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
for (PRUint32 i = 0; i < count; i++) {
|
||||
pwmgr->SetLoginSavingEnabled(nsDependentString(hostnames[i]),
|
||||
PR_FALSE);
|
||||
}
|
||||
NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(count, hostnames);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSeamonkeyProfileMigrator::CopyBookmarks(PRBool aReplace)
|
||||
{
|
||||
nsresult rv;
|
||||
if (aReplace) {
|
||||
// Initialize the default bookmarks
|
||||
rv = InitializeBookmarks(mTargetProfile);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Merge in the bookmarks from the source profile
|
||||
nsCOMPtr<nsIFile> sourceFile;
|
||||
mSourceProfile->Clone(getter_AddRefs(sourceFile));
|
||||
sourceFile->Append(FILE_NAME_BOOKMARKS);
|
||||
rv = ImportBookmarksHTML(sourceFile, PR_TRUE, PR_FALSE, EmptyString().get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
else {
|
||||
rv = ImportNetscapeBookmarks(FILE_NAME_BOOKMARKS,
|
||||
NS_LITERAL_STRING("sourceNameSeamonkey").get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsSeamonkeyProfileMigrator::CopyOtherData(PRBool aReplace)
|
||||
{
|
||||
return aReplace ? CopyFile(FILE_NAME_DOWNLOADS, FILE_NAME_DOWNLOADS) : NS_OK;
|
||||
}
|
||||
|
|
@ -1,105 +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 seamonkeyprofilemigrator___h___
|
||||
#define seamonkeyprofilemigrator___h___
|
||||
|
||||
#include "nsIBrowserProfileMigrator.h"
|
||||
#include "nsILocalFile.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsISupportsArray.h"
|
||||
#include "nsNetscapeProfileMigratorBase.h"
|
||||
#include "nsStringAPI.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsIFile;
|
||||
class nsIPrefBranch;
|
||||
class nsIPrefService;
|
||||
|
||||
struct FontPref {
|
||||
char* prefName;
|
||||
PRInt32 type;
|
||||
union {
|
||||
char* stringValue;
|
||||
PRInt32 intValue;
|
||||
PRBool boolValue;
|
||||
PRUnichar* wstringValue;
|
||||
};
|
||||
};
|
||||
|
||||
class nsSeamonkeyProfileMigrator : public nsNetscapeProfileMigratorBase,
|
||||
public nsIBrowserProfileMigrator
|
||||
{
|
||||
public:
|
||||
NS_DECL_NSIBROWSERPROFILEMIGRATOR
|
||||
NS_DECL_ISUPPORTS
|
||||
|
||||
nsSeamonkeyProfileMigrator();
|
||||
virtual ~nsSeamonkeyProfileMigrator();
|
||||
|
||||
public:
|
||||
static nsresult SetImage(void* aTransform, nsIPrefBranch* aBranch);
|
||||
static nsresult SetCookie(void* aTransform, nsIPrefBranch* aBranch);
|
||||
static nsresult SetDownloadManager(void* aTransform, nsIPrefBranch* aBranch);
|
||||
|
||||
protected:
|
||||
nsresult FillProfileDataFromSeamonkeyRegistry();
|
||||
nsresult GetSourceProfile(const PRUnichar* aProfile);
|
||||
|
||||
nsresult CopyPreferences(PRBool aReplace);
|
||||
nsresult TransformPreferences(const nsAString& aSourcePrefFileName,
|
||||
const nsAString& aTargetPrefFileName);
|
||||
void ReadFontsBranch(nsIPrefService* aPrefService,
|
||||
nsTArray<FontPref>* aPrefs);
|
||||
void WriteFontsBranch(nsIPrefService* aPrefService,
|
||||
nsTArray<FontPref>* aPrefs);
|
||||
|
||||
nsresult CopyUserContentSheet();
|
||||
|
||||
nsresult CopyCookies(PRBool aReplace);
|
||||
nsresult CopyPasswords(PRBool aReplace);
|
||||
nsresult LocateSignonsFile(char** aResult);
|
||||
nsresult CopyBookmarks(PRBool aReplace);
|
||||
nsresult CopyOtherData(PRBool aReplace);
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsISupportsArray> mProfileNames;
|
||||
nsCOMPtr<nsISupportsArray> mProfileLocations;
|
||||
nsCOMPtr<nsIObserverService> mObserverService;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -277,17 +277,30 @@ var PlacesOrganizer = {
|
|||
* the node to set up scope from
|
||||
*/
|
||||
_setSearchScopeForNode: function PO__setScopeForNode(aNode) {
|
||||
var itemId = aNode.itemId;
|
||||
let itemId = aNode.itemId;
|
||||
|
||||
// Set default buttons status.
|
||||
let bookmarksButton = document.getElementById("scopeBarAll");
|
||||
bookmarksButton.hidden = false;
|
||||
let downloadsButton = document.getElementById("scopeBarDownloads");
|
||||
downloadsButton.hidden = true;
|
||||
|
||||
if (PlacesUtils.nodeIsHistoryContainer(aNode) ||
|
||||
itemId == PlacesUIUtils.leftPaneQueries["History"]) {
|
||||
PlacesQueryBuilder.setScope("history");
|
||||
}
|
||||
// Default to All Bookmarks for all other nodes, per bug 469437.
|
||||
else
|
||||
else if (itemId == PlacesUIUtils.leftPaneQueries["Downloads"]) {
|
||||
downloadsButton.hidden = false;
|
||||
bookmarksButton.hidden = true;
|
||||
PlacesQueryBuilder.setScope("downloads");
|
||||
}
|
||||
else {
|
||||
// Default to All Bookmarks for all other nodes, per bug 469437.
|
||||
PlacesQueryBuilder.setScope("bookmarks");
|
||||
}
|
||||
|
||||
// Enable or disable the folder scope button.
|
||||
var folderButton = document.getElementById("scopeBarFolder");
|
||||
let folderButton = document.getElementById("scopeBarFolder");
|
||||
folderButton.hidden = !PlacesUtils.nodeIsFolder(aNode) ||
|
||||
itemId == PlacesUIUtils.allBookmarksFolderId;
|
||||
},
|
||||
|
@ -901,9 +914,21 @@ var PlacesSearchBox = {
|
|||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY;
|
||||
content.load([query], options);
|
||||
}
|
||||
else
|
||||
else {
|
||||
content.applyFilter(filterString);
|
||||
}
|
||||
break;
|
||||
case "downloads": {
|
||||
let query = PlacesUtils.history.getNewQuery();
|
||||
query.searchTerms = filterString;
|
||||
query.setTransitions([Ci.nsINavHistoryService.TRANSITION_DOWNLOAD], 1);
|
||||
let options = currentOptions.clone();
|
||||
// Make sure we're getting uri results.
|
||||
options.resultType = currentOptions.RESULT_TYPE_URI;
|
||||
options.queryType = Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY;
|
||||
content.load([query], options);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
throw "Invalid filterCollection on search";
|
||||
break;
|
||||
|
@ -933,17 +958,28 @@ var PlacesSearchBox = {
|
|||
|
||||
/**
|
||||
* Updates the display with the title of the current collection.
|
||||
* @param title
|
||||
* @param aTitle
|
||||
* The title of the current collection.
|
||||
*/
|
||||
updateCollectionTitle: function PSB_updateCollectionTitle(title) {
|
||||
if (title)
|
||||
this.searchFilter.placeholder =
|
||||
PlacesUIUtils.getFormattedString("searchCurrentDefault", [title]);
|
||||
else
|
||||
this.searchFilter.placeholder = this.filterCollection == "history" ?
|
||||
PlacesUIUtils.getString("searchHistory") :
|
||||
PlacesUIUtils.getString("searchBookmarks");
|
||||
updateCollectionTitle: function PSB_updateCollectionTitle(aTitle) {
|
||||
let title = "";
|
||||
if (aTitle) {
|
||||
title = PlacesUIUtils.getFormattedString("searchCurrentDefault",
|
||||
[aTitle]);
|
||||
}
|
||||
else {
|
||||
switch(this.filterCollection) {
|
||||
case "history":
|
||||
title = PlacesUIUtils.getString("searchHistory");
|
||||
break;
|
||||
case "downloads":
|
||||
title = PlacesUIUtils.getString("searchDownloads");
|
||||
break;
|
||||
default:
|
||||
title = PlacesUIUtils.getString("searchBookmarks");
|
||||
}
|
||||
}
|
||||
this.searchFilter.placeholder = title;
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1025,6 +1061,9 @@ var PlacesQueryBuilder = {
|
|||
case "scopeBarFolder":
|
||||
this.setScope("collection");
|
||||
break;
|
||||
case "scopeBarDownloads":
|
||||
this.setScope("downloads");
|
||||
break;
|
||||
case "scopeBarAll":
|
||||
this.setScope("bookmarks");
|
||||
break;
|
||||
|
@ -1040,7 +1079,8 @@ var PlacesQueryBuilder = {
|
|||
* PSB_search()). If there is an active search, it's performed again to
|
||||
* update the content tree.
|
||||
* @param aScope
|
||||
* the search scope, "bookmarks", "collection", or "history"
|
||||
* The search scope: "bookmarks", "collection", "downloads" or
|
||||
* "history".
|
||||
*/
|
||||
setScope: function PQB_setScope(aScope) {
|
||||
// Determine filterCollection, folders, and scopeButtonId based on aScope.
|
||||
|
@ -1072,6 +1112,10 @@ var PlacesQueryBuilder = {
|
|||
PlacesUtils.toolbarFolderId,
|
||||
PlacesUtils.unfiledBookmarksFolderId);
|
||||
break;
|
||||
case "downloads":
|
||||
filterCollection = "downloads";
|
||||
scopeButtonId = "scopeBarDownloads";
|
||||
break;
|
||||
default:
|
||||
throw "Invalid search scope";
|
||||
break;
|
||||
|
|
|
@ -412,18 +412,16 @@
|
|||
oncommand="PlacesQueryBuilder.onScopeSelected(this);"
|
||||
label="&search.scopeBookmarks.label;"
|
||||
accesskey="&search.scopeBookmarks.accesskey;"/>
|
||||
<!--
|
||||
<toolbarbutton id="scopeBarDownloads" class="small-margin"
|
||||
type="radio" group="scopeBar"
|
||||
oncommand="PlacesQueryBuilder.onScopeSelected(this);"
|
||||
label="&search.scopeDownloads.label;"
|
||||
accesskey="&search.scopeDownloads.accesskey;"/>
|
||||
-->
|
||||
<toolbarbutton id="scopeBarHistory" class="small-margin"
|
||||
type="radio" group="scopeBar"
|
||||
oncommand="PlacesQueryBuilder.onScopeSelected(this);"
|
||||
label="&search.scopeHistory.label;"
|
||||
accesskey="&search.scopeHistory.accesskey;"/>
|
||||
<toolbarbutton id="scopeBarDownloads" class="small-margin"
|
||||
type="radio" group="scopeBar"
|
||||
oncommand="PlacesQueryBuilder.onScopeSelected(this);"
|
||||
label="&search.scopeDownloads.label;"
|
||||
accesskey="&search.scopeDownloads.accesskey;"/>
|
||||
<toolbarbutton id="scopeBarFolder" class="small-margin"
|
||||
type="radio" group="scopeBar"
|
||||
oncommand="PlacesQueryBuilder.onScopeSelected(this);"
|
||||
|
|
|
@ -139,18 +139,3 @@ let tests = {
|
|||
is(unsortedNode.uri, MOZURISPEC, "node uri's are the same");
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Clears history invoking callback when done.
|
||||
*/
|
||||
function waitForClearHistory(aCallback) {
|
||||
const TOPIC_EXPIRATION_FINISHED = "places-expiration-finished";
|
||||
let observer = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
Services.obs.removeObserver(this, TOPIC_EXPIRATION_FINISHED);
|
||||
aCallback();
|
||||
}
|
||||
};
|
||||
Services.obs.addObserver(observer, TOPIC_EXPIRATION_FINISHED, false);
|
||||
PlacesUtils.bhistory.removeAllPages();
|
||||
}
|
||||
|
|
|
@ -37,25 +37,6 @@
|
|||
|
||||
// This test makes sure that the Forget This Site command is hidden for multiple
|
||||
// selections.
|
||||
|
||||
/**
|
||||
* Clears history invoking callback when done.
|
||||
*/
|
||||
function waitForClearHistory(aCallback) {
|
||||
const TOPIC_EXPIRATION_FINISHED = "places-expiration-finished";
|
||||
let observer = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
Services.obs.removeObserver(this, TOPIC_EXPIRATION_FINISHED);
|
||||
aCallback();
|
||||
}
|
||||
};
|
||||
Services.obs.addObserver(observer, TOPIC_EXPIRATION_FINISHED, false);
|
||||
|
||||
let hs = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
hs.QueryInterface(Ci.nsIBrowserHistory).removeAllPages();
|
||||
}
|
||||
|
||||
function test() {
|
||||
// initialization
|
||||
waitForExplicitFinish();
|
||||
|
|
|
@ -48,20 +48,6 @@ function uri(spec) {
|
|||
return ios.newURI(spec, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears history invoking callback when done.
|
||||
*/
|
||||
function waitForClearHistory(aCallback) {
|
||||
let observer = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
Services.obs.removeObserver(this, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
|
||||
aCallback(aSubject, aTopic, aData);
|
||||
}
|
||||
};
|
||||
Services.obs.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
|
||||
PlacesUtils.bhistory.removeAllPages();
|
||||
}
|
||||
|
||||
var sidebar = document.getElementById("sidebar");
|
||||
|
||||
function add_visit(aURI, aDate) {
|
||||
|
|
|
@ -83,14 +83,3 @@ function test() {
|
|||
|
||||
openLibrary(onLibraryReady);
|
||||
}
|
||||
|
||||
function waitForClearHistory(aCallback) {
|
||||
let observer = {
|
||||
observe: function(aSubject, aTopic, aData) {
|
||||
Services.obs.removeObserver(this, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
|
||||
aCallback(aSubject, aTopic, aData);
|
||||
}
|
||||
};
|
||||
Services.obs.addObserver(observer, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
|
||||
PlacesUtils.bhistory.removeAllPages();
|
||||
}
|
||||
|
|
|
@ -61,67 +61,74 @@
|
|||
*/
|
||||
|
||||
const TEST_URL = "http://dummy.mozilla.org/";
|
||||
const TEST_DOWNLOAD_URL = "http://dummy.mozilla.org/dummy.pdf";
|
||||
|
||||
// Add your tests here. Each is a function that's called by testHelper().
|
||||
var testCases = [
|
||||
let gLibrary;
|
||||
|
||||
// All Bookmarks
|
||||
function () {
|
||||
var defScope = getDefaultScope(PlacesUIUtils.allBookmarksFolderId);
|
||||
let testCases = [
|
||||
function allBookmarksScope() {
|
||||
let defScope = getDefaultScope(PlacesUIUtils.allBookmarksFolderId);
|
||||
search(PlacesUIUtils.allBookmarksFolderId, "dummy", defScope);
|
||||
is(selectScope("scopeBarFolder"), false,
|
||||
ok(!selectScope("scopeBarFolder"),
|
||||
"Folder scope should be disabled for All Bookmarks");
|
||||
resetSearch(defScope);
|
||||
ok(selectScope("scopeBarAll"),
|
||||
"Bookmarks scope should be enabled for All Bookmarks");
|
||||
resetSearch("scopeBarAll");
|
||||
},
|
||||
|
||||
// History
|
||||
function () {
|
||||
var defScope = getDefaultScope(PlacesUIUtils.leftPaneQueries["History"]);
|
||||
function historyScope() {
|
||||
let defScope = getDefaultScope(PlacesUIUtils.leftPaneQueries["History"]);
|
||||
search(PlacesUIUtils.leftPaneQueries["History"], "dummy", defScope);
|
||||
is(selectScope("scopeBarFolder"), false,
|
||||
ok(!selectScope("scopeBarFolder"),
|
||||
"Folder scope should be disabled for History");
|
||||
ok(selectScope("scopeBarAll"),
|
||||
"Bookmarks scope should be enabled for History");
|
||||
resetSearch("scopeBarAll");
|
||||
},
|
||||
|
||||
function downloadsScope() {
|
||||
let defScope = getDefaultScope(PlacesUIUtils.leftPaneQueries["Downloads"]);
|
||||
search(PlacesUIUtils.leftPaneQueries["Downloads"], "dummy", defScope);
|
||||
ok(!selectScope("scopeBarFolder"),
|
||||
"Folder scope should be disabled for Downloads");
|
||||
ok(!selectScope("scopeBarAll"),
|
||||
"Bookmarks scope should be disabled for Downloads");
|
||||
resetSearch(defScope);
|
||||
},
|
||||
|
||||
// Toolbar folder
|
||||
function () {
|
||||
var defScope = getDefaultScope(bmsvc.toolbarFolder);
|
||||
search(bmsvc.toolbarFolder, "dummy", defScope);
|
||||
is(selectScope("scopeBarFolder"), true,
|
||||
function toolbarFolderScope() {
|
||||
let defScope = getDefaultScope(PlacesUtils.toolbarFolderId);
|
||||
search(PlacesUtils.toolbarFolderId, "dummy", defScope);
|
||||
ok(selectScope("scopeBarAll"),
|
||||
"Bookmarks scope should be enabled for toolbar folder");
|
||||
ok(selectScope("scopeBarFolder"),
|
||||
"Folder scope should be enabled for toolbar folder");
|
||||
// Ensure that folder scope is still selected after resetting and searching
|
||||
// again.
|
||||
resetSearch("scopeBarFolder");
|
||||
search(bmsvc.toolbarFolder, "dummy", "scopeBarFolder");
|
||||
search(PlacesUtils.toolbarFolderId, "dummy", "scopeBarFolder");
|
||||
},
|
||||
|
||||
// A regular non-root subfolder
|
||||
function () {
|
||||
var folderId = bmsvc.createFolder(bmsvc.toolbarFolder,
|
||||
"dummy folder",
|
||||
bmsvc.DEFAULT_INDEX);
|
||||
var defScope = getDefaultScope(folderId);
|
||||
function subFolderScope() {
|
||||
let folderId = PlacesUtils.bookmarks.createFolder(PlacesUtils.toolbarFolderId,
|
||||
"dummy folder",
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX);
|
||||
let defScope = getDefaultScope(folderId);
|
||||
search(folderId, "dummy", defScope);
|
||||
is(selectScope("scopeBarFolder"), true,
|
||||
ok(selectScope("scopeBarAll"),
|
||||
"Bookmarks scope should be enabled for regularfolder");
|
||||
ok(selectScope("scopeBarFolder"),
|
||||
"Folder scope should be enabled for regular subfolder");
|
||||
// Ensure that folder scope is still selected after resetting and searching
|
||||
// again.
|
||||
resetSearch("scopeBarFolder");
|
||||
search(folderId, "dummy", "scopeBarFolder");
|
||||
bmsvc.removeItem(folderId);
|
||||
PlacesUtils.bookmarks.removeItem(folderId);
|
||||
},
|
||||
];
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var bmsvc = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
|
||||
getService(Ci.nsINavBookmarksService);
|
||||
var histsvc = Cc["@mozilla.org/browser/nav-history-service;1"].
|
||||
getService(Ci.nsINavHistoryService);
|
||||
var libraryWin;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* Returns the default search scope for a given folder.
|
||||
*
|
||||
|
@ -130,9 +137,14 @@ var libraryWin;
|
|||
* @return the default scope when the folder is newly selected
|
||||
*/
|
||||
function getDefaultScope(aFolderId) {
|
||||
return aFolderId === PlacesUIUtils.leftPaneQueries["History"] ?
|
||||
"scopeBarHistory" :
|
||||
"scopeBarAll";
|
||||
switch (aFolderId) {
|
||||
case PlacesUIUtils.leftPaneQueries["History"]:
|
||||
return "scopeBarHistory"
|
||||
case PlacesUIUtils.leftPaneQueries["Downloads"]:
|
||||
return "scopeBarDownloads";
|
||||
default:
|
||||
return "scopeBarAll";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -141,8 +153,8 @@ function getDefaultScope(aFolderId) {
|
|||
* @return the ID of the selected scope folder button
|
||||
*/
|
||||
function getSelectedScopeButtonId() {
|
||||
var doc = libraryWin.document;
|
||||
var scopeButtons = doc.getElementById("organizerScopeBar").childNodes;
|
||||
let doc = gLibrary.document;
|
||||
let scopeButtons = doc.getElementById("organizerScopeBar").childNodes;
|
||||
for (let i = 0; i < scopeButtons.length; i++) {
|
||||
if (scopeButtons[i].checked)
|
||||
return scopeButtons[i].id;
|
||||
|
@ -158,8 +170,8 @@ function getSelectedScopeButtonId() {
|
|||
* @return an nsINavHistoryQuery object
|
||||
*/
|
||||
function queryStringToQuery(aPlaceURI) {
|
||||
var queries = {};
|
||||
histsvc.queryStringToQueries(aPlaceURI, queries, {}, {});
|
||||
let queries = {};
|
||||
PlacesUtils.history.queryStringToQueries(aPlaceURI, queries, {}, {});
|
||||
return queries.value[0];
|
||||
}
|
||||
|
||||
|
@ -188,9 +200,9 @@ function resetSearch(aExpectedScopeButtonId) {
|
|||
* after searching the selected scope button should be this
|
||||
*/
|
||||
function search(aFolderId, aSearchStr, aExpectedScopeButtonId) {
|
||||
var doc = libraryWin.document;
|
||||
var folderTree = doc.getElementById("placesList");
|
||||
var contentTree = doc.getElementById("placeContent");
|
||||
let doc = gLibrary.document;
|
||||
let folderTree = doc.getElementById("placesList");
|
||||
let contentTree = doc.getElementById("placeContent");
|
||||
|
||||
// First, ensure that selecting the folder in the left pane updates the
|
||||
// content tree properly.
|
||||
|
@ -201,10 +213,11 @@ function search(aFolderId, aSearchStr, aExpectedScopeButtonId) {
|
|||
|
||||
// getFolders() on a History query returns an empty array, so no use
|
||||
// comparing against aFolderId in that case.
|
||||
if (aFolderId !== PlacesUIUtils.leftPaneQueries["History"]) {
|
||||
if (aFolderId !== PlacesUIUtils.leftPaneQueries["History"] &&
|
||||
aFolderId !== PlacesUIUtils.leftPaneQueries["Downloads"]) {
|
||||
// contentTree.place should be equal to contentTree.result.root.uri,
|
||||
// but it's not until bug 476952 is fixed.
|
||||
var query = queryStringToQuery(contentTree.result.root.uri);
|
||||
let query = queryStringToQuery(contentTree.result.root.uri);
|
||||
is(query.getFolders()[0], aFolderId,
|
||||
"Content tree's folder should be what was selected in the left pane");
|
||||
}
|
||||
|
@ -212,27 +225,41 @@ function search(aFolderId, aSearchStr, aExpectedScopeButtonId) {
|
|||
|
||||
// Second, ensure that searching updates the content tree and search UI
|
||||
// properly.
|
||||
var searchBox = doc.getElementById("searchFilter");
|
||||
let searchBox = doc.getElementById("searchFilter");
|
||||
searchBox.value = aSearchStr;
|
||||
libraryWin.PlacesSearchBox.search(searchBox.value);
|
||||
query = queryStringToQuery(contentTree.result.root.uri);
|
||||
gLibrary.PlacesSearchBox.search(searchBox.value);
|
||||
let query = queryStringToQuery(contentTree.result.root.uri);
|
||||
if (aSearchStr) {
|
||||
is(query.searchTerms, aSearchStr,
|
||||
"Content tree's searchTerms should be text in search box");
|
||||
is(doc.getElementById("searchModifiers").hidden, false,
|
||||
"Scope bar should not be hidden after searching");
|
||||
if (getSelectedScopeButtonId() == "scopeBarHistory" ||
|
||||
getSelectedScopeButtonId() == "scopeBarAll" ||
|
||||
aFolderId == PlacesUtils.bookmarks.unfiledBookmarksFolder) {
|
||||
|
||||
let scopeButtonId = getSelectedScopeButtonId();
|
||||
if (scopeButtonId == "scopeBarDownloads" ||
|
||||
scopeButtonId == "scopeBarHistory" ||
|
||||
scopeButtonId == "scopeBarAll" ||
|
||||
aFolderId == PlacesUtils.unfiledBookmarksFolderId) {
|
||||
// Check that the target node exists in the tree's search results.
|
||||
var node = null;
|
||||
for (var i = 0; i < contentTree.view.rowCount; i++) {
|
||||
let url, count;
|
||||
if (scopeButtonId == "scopeBarDownloads") {
|
||||
url = TEST_DOWNLOAD_URL;
|
||||
count = 1;
|
||||
}
|
||||
else {
|
||||
url = TEST_URL;
|
||||
count = scopeButtonId == "scopeBarHistory" ? 2 : 1;
|
||||
}
|
||||
is(contentTree.view.rowCount, count, "Found correct number of results");
|
||||
|
||||
let node = null;
|
||||
for (let i = 0; i < contentTree.view.rowCount; i++) {
|
||||
node = contentTree.view.nodeForTreeIndex(i);
|
||||
if (node.uri === TEST_URL)
|
||||
if (node.uri === url)
|
||||
break;
|
||||
}
|
||||
isnot(node, null, "At least the target node should be in the tree");
|
||||
is(node.uri, TEST_URL, "URI of node should match target URL");
|
||||
is(node.uri, url, "URI of node should match target URL");
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -253,10 +280,10 @@ function search(aFolderId, aSearchStr, aExpectedScopeButtonId) {
|
|||
* @return true if the button is enabled, false otherwise
|
||||
*/
|
||||
function selectScope(aScopeButtonId) {
|
||||
var doc = libraryWin.document;
|
||||
var button = doc.getElementById(aScopeButtonId);
|
||||
let doc = gLibrary.document;
|
||||
let button = doc.getElementById(aScopeButtonId);
|
||||
isnot(button, null,
|
||||
"Sanity check: scope button with ID " + aScopeButtonId + "should exist");
|
||||
"Sanity check: scope button with ID " + aScopeButtonId + " should exist");
|
||||
// Bug 469436 may hide an inappropriate scope button instead of disabling it.
|
||||
if (button.disabled || button.hidden)
|
||||
return false;
|
||||
|
@ -267,21 +294,17 @@ function selectScope(aScopeButtonId) {
|
|||
/**
|
||||
* test() contains window-launching boilerplate that calls this to really kick
|
||||
* things off. Add functions to the testCases array, and this will call them.
|
||||
*
|
||||
* @param aLibraryWin
|
||||
* the Places Library window
|
||||
*/
|
||||
function testHelper(aLibraryWin) {
|
||||
libraryWin = aLibraryWin;
|
||||
function onLibraryAvailable() {
|
||||
testCases.forEach(function (aTest) aTest());
|
||||
aLibraryWin.close();
|
||||
|
||||
gLibrary.close();
|
||||
gLibrary = null;
|
||||
|
||||
// Cleanup.
|
||||
PlacesUtils.tagging.untagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
|
||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.bookmarks.unfiledBookmarksFolder);
|
||||
PlacesUtils.history.QueryInterface(Ci.nsIBrowserHistory).removeAllPages();
|
||||
|
||||
finish();
|
||||
PlacesUtils.bookmarks.removeFolderChildren(PlacesUtils.unfiledBookmarksFolderId);
|
||||
waitForClearHistory(finish);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -291,15 +314,19 @@ function test() {
|
|||
|
||||
// Sanity:
|
||||
ok(PlacesUtils, "PlacesUtils in context");
|
||||
// Add a visit, a bookmark and a tag.
|
||||
|
||||
// Add visits, a bookmark and a tag.
|
||||
PlacesUtils.history.addVisit(PlacesUtils._uri(TEST_URL),
|
||||
Date.now() * 1000, null,
|
||||
PlacesUtils.history.TRANSITION_TYPED, false, 0);
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.bookmarks.unfiledBookmarksFolder,
|
||||
PlacesUtils.history.addVisit(PlacesUtils._uri(TEST_DOWNLOAD_URL),
|
||||
Date.now() * 1000, null,
|
||||
PlacesUtils.history.TRANSITION_DOWNLOAD, false, 0);
|
||||
PlacesUtils.bookmarks.insertBookmark(PlacesUtils.unfiledBookmarksFolderId,
|
||||
PlacesUtils._uri(TEST_URL),
|
||||
PlacesUtils.bookmarks.DEFAULT_INDEX,
|
||||
"dummy");
|
||||
PlacesUtils.tagging.tagURI(PlacesUtils._uri(TEST_URL), ["dummyTag"]);
|
||||
|
||||
openLibrary(testHelper);
|
||||
gLibrary = openLibrary(onLibraryAvailable);
|
||||
}
|
||||
|
|
|
@ -173,14 +173,6 @@ function test() {
|
|||
sidebar.contentDocument.documentElement.style.direction = aDirection;
|
||||
}
|
||||
|
||||
function waitForClearHistory(aCallback) {
|
||||
Services.obs.addObserver(function(aSubject, aTopic, aData) {
|
||||
Services.obs.removeObserver(arguments.callee, PlacesUtils.TOPIC_EXPIRATION_FINISHED);
|
||||
aCallback(aSubject, aTopic, aData);
|
||||
}, PlacesUtils.TOPIC_EXPIRATION_FINISHED, false);
|
||||
PlacesUtils.bhistory.removeAllPages();
|
||||
}
|
||||
|
||||
function runNextTest() {
|
||||
// Remove eventual tabs created by previous sub-tests.
|
||||
while (gBrowser.tabs.length > 1) {
|
||||
|
|
|
@ -53,6 +53,7 @@ var gMainPane = {
|
|||
window.addEventListener("focus", this._updateUseCurrentButton, false);
|
||||
|
||||
this.updateBrowserStartupLastSession();
|
||||
this.startupPagePrefChanged();
|
||||
|
||||
// Notify observers that the UI is now ready
|
||||
Components.classes["@mozilla.org/observer-service;1"]
|
||||
|
@ -81,6 +82,16 @@ var gMainPane = {
|
|||
* option is preserved.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Enables/Disables the restore on demand checkbox.
|
||||
*/
|
||||
startupPagePrefChanged: function ()
|
||||
{
|
||||
let startupPref = document.getElementById("browser.startup.page");
|
||||
let restoreOnDemandPref = document.getElementById("browser.sessionstore.restore_on_demand");
|
||||
restoreOnDemandPref.disabled = startupPref.value != 3;
|
||||
},
|
||||
|
||||
syncFromHomePref: function ()
|
||||
{
|
||||
let homePref = document.getElementById("browser.startup.homepage");
|
||||
|
|
|
@ -64,7 +64,11 @@
|
|||
<!-- Startup -->
|
||||
<preference id="browser.startup.page"
|
||||
name="browser.startup.page"
|
||||
type="int"/>
|
||||
type="int"
|
||||
onchange="gMainPane.startupPagePrefChanged();"/>
|
||||
<preference id="browser.sessionstore.restore_on_demand"
|
||||
name="browser.sessionstore.restore_on_demand"
|
||||
type="bool"/>
|
||||
<preference id="browser.startup.homepage"
|
||||
name="browser.startup.homepage"
|
||||
type="wstring"/>
|
||||
|
@ -120,6 +124,13 @@
|
|||
</menupopup>
|
||||
</menulist>
|
||||
</hbox>
|
||||
<hbox align="center">
|
||||
<checkbox id="restoreOnDemand"
|
||||
label="&restoreOnDemand.label;"
|
||||
accesskey="&restoreOnDemand.accesskey;"
|
||||
class="indent"
|
||||
preference="browser.sessionstore.restore_on_demand"/>
|
||||
</hbox>
|
||||
<separator class="thin"/>
|
||||
<hbox align="center">
|
||||
<label value="&homepage.label;" accesskey="&homepage.accesskey;" control="browserHomePage"/>
|
||||
|
|
|
@ -75,6 +75,10 @@ const PRIVACY_FULL = 2;
|
|||
const NOTIFY_WINDOWS_RESTORED = "sessionstore-windows-restored";
|
||||
const NOTIFY_BROWSER_STATE_RESTORED = "sessionstore-browser-state-restored";
|
||||
|
||||
// Maximum number of tabs to restore simultaneously. Previously controlled by
|
||||
// the browser.sessionstore.max_concurrent_tabs pref.
|
||||
const MAX_CONCURRENT_TAB_RESTORES = 3;
|
||||
|
||||
// global notifications observed
|
||||
const OBSERVING = [
|
||||
"domwindowopened", "domwindowclosed",
|
||||
|
@ -192,7 +196,7 @@ SessionStoreService.prototype = {
|
|||
|
||||
// During the initial restore and setBrowserState calls tracks the number of
|
||||
// windows yet to be restored
|
||||
_restoreCount: 0,
|
||||
_restoreCount: -1,
|
||||
|
||||
// whether a setBrowserState call is in progress
|
||||
_browserSetState: false,
|
||||
|
@ -229,9 +233,9 @@ SessionStoreService.prototype = {
|
|||
_tabsToRestore: { visible: [], hidden: [] },
|
||||
_tabsRestoringCount: 0,
|
||||
|
||||
// number of tabs to restore concurrently, pref controlled.
|
||||
_maxConcurrentTabRestores: null,
|
||||
|
||||
// overrides MAX_CONCURRENT_TAB_RESTORES and _restoreHiddenTabs when true
|
||||
_restoreOnDemand: false,
|
||||
|
||||
// whether to restore hidden tabs or not, pref controlled.
|
||||
_restoreHiddenTabs: null,
|
||||
|
||||
|
@ -281,7 +285,10 @@ SessionStoreService.prototype = {
|
|||
var pbs = Cc["@mozilla.org/privatebrowsing;1"].
|
||||
getService(Ci.nsIPrivateBrowsingService);
|
||||
this._inPrivateBrowsing = pbs.privateBrowsingEnabled;
|
||||
|
||||
|
||||
// Do pref migration before we store any values and start observing changes
|
||||
this._migratePrefs();
|
||||
|
||||
// observe prefs changes so we can modify stored data to match
|
||||
this._prefBranch.addObserver("sessionstore.max_tabs_undo", this, true);
|
||||
this._prefBranch.addObserver("sessionstore.max_windows_undo", this, true);
|
||||
|
@ -290,9 +297,9 @@ SessionStoreService.prototype = {
|
|||
this._sessionhistory_max_entries =
|
||||
this._prefBranch.getIntPref("sessionhistory.max_entries");
|
||||
|
||||
this._maxConcurrentTabRestores =
|
||||
this._prefBranch.getIntPref("sessionstore.max_concurrent_tabs");
|
||||
this._prefBranch.addObserver("sessionstore.max_concurrent_tabs", this, true);
|
||||
this._restoreOnDemand =
|
||||
this._prefBranch.getBoolPref("sessionstore.restore_on_demand");
|
||||
this._prefBranch.addObserver("sessionstore.restore_on_demand", this, true);
|
||||
|
||||
this._restoreHiddenTabs =
|
||||
this._prefBranch.getBoolPref("sessionstore.restore_hidden_tabs");
|
||||
|
@ -364,6 +371,9 @@ SessionStoreService.prototype = {
|
|||
delete this._initialState.windows[0].hidden;
|
||||
// Since nothing is hidden in the first window, it cannot be a popup
|
||||
delete this._initialState.windows[0].isPopup;
|
||||
// We don't want to minimize and then open a window at startup.
|
||||
if (this._initialState.windows[0].sizemode == "minimized")
|
||||
this._initialState.windows[0].sizemode = "normal";
|
||||
}
|
||||
}
|
||||
catch (ex) { debug("The session file is invalid: " + ex); }
|
||||
|
@ -440,6 +450,19 @@ SessionStoreService.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
_migratePrefs: function sss__migratePrefs() {
|
||||
// Added For Firefox 8
|
||||
// max_concurrent_tabs is going away. We're going to hard code a max value
|
||||
// (MAX_CONCURRENT_TAB_RESTORES) and start using a boolean pref restore_on_demand.
|
||||
if (this._prefBranch.prefHasUserValue("sessionstore.max_concurrent_tabs") &&
|
||||
!this._prefBranch.prefHasUserValue("sessionstore.restore_on_demand")) {
|
||||
let maxConcurrentTabs =
|
||||
this._prefBranch.getIntPref("sessionstore.max_concurrent_tabs");
|
||||
this._prefBranch.setBoolPref("sessionstore.restore_on_demand", maxConcurrentTabs == 0);
|
||||
this._prefBranch.clearUserPref("sessionstore.max_concurrent_tabs");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Handle notifications
|
||||
*/
|
||||
|
@ -629,9 +652,9 @@ SessionStoreService.prototype = {
|
|||
this._clearDisk();
|
||||
this.saveState(true);
|
||||
break;
|
||||
case "sessionstore.max_concurrent_tabs":
|
||||
this._maxConcurrentTabRestores =
|
||||
this._prefBranch.getIntPref("sessionstore.max_concurrent_tabs");
|
||||
case "sessionstore.restore_on_demand":
|
||||
this._restoreOnDemand =
|
||||
this._prefBranch.getBoolPref("sessionstore.restore_on_demand");
|
||||
break;
|
||||
case "sessionstore.restore_hidden_tabs":
|
||||
this._restoreHiddenTabs =
|
||||
|
@ -2903,7 +2926,7 @@ SessionStoreService.prototype = {
|
|||
_this.restoreHistory(aWindow, aTabs, aTabData, aIdMap, aDocIdentMap);
|
||||
}, 0);
|
||||
|
||||
// This could cause us to ignore the max_concurrent_tabs pref a bit, but
|
||||
// This could cause us to ignore MAX_CONCURRENT_TAB_RESTORES a bit, but
|
||||
// it ensures each window will have its selected tab loaded.
|
||||
if (aWindow.gBrowser.selectedBrowser == browser) {
|
||||
this.restoreTab(tab);
|
||||
|
@ -3039,8 +3062,8 @@ SessionStoreService.prototype = {
|
|||
return;
|
||||
|
||||
// If it's not possible to restore anything, then just bail out.
|
||||
if (this._maxConcurrentTabRestores >= 0 &&
|
||||
this._tabsRestoringCount >= this._maxConcurrentTabRestores)
|
||||
if (this._restoreOnDemand ||
|
||||
this._tabsRestoringCount >= MAX_CONCURRENT_TAB_RESTORES)
|
||||
return;
|
||||
|
||||
// Look in visible, then hidden
|
||||
|
@ -3969,16 +3992,23 @@ SessionStoreService.prototype = {
|
|||
},
|
||||
|
||||
_sendRestoreCompletedNotifications: function sss_sendRestoreCompletedNotifications() {
|
||||
if (this._restoreCount) {
|
||||
// not all windows restored, yet
|
||||
if (this._restoreCount > 1) {
|
||||
this._restoreCount--;
|
||||
if (this._restoreCount == 0) {
|
||||
// This was the last window restored at startup, notify observers.
|
||||
Services.obs.notifyObservers(null,
|
||||
this._browserSetState ? NOTIFY_BROWSER_STATE_RESTORED : NOTIFY_WINDOWS_RESTORED,
|
||||
"");
|
||||
this._browserSetState = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// observers were already notified
|
||||
if (this._restoreCount == -1)
|
||||
return;
|
||||
|
||||
// This was the last window restored at startup, notify observers.
|
||||
Services.obs.notifyObservers(null,
|
||||
this._browserSetState ? NOTIFY_BROWSER_STATE_RESTORED : NOTIFY_WINDOWS_RESTORED,
|
||||
"");
|
||||
|
||||
this._browserSetState = false;
|
||||
this._restoreCount = -1;
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -149,6 +149,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_628270.js \
|
||||
browser_635418.js \
|
||||
browser_636279.js \
|
||||
browser_645428.js \
|
||||
browser_659591.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -60,7 +60,7 @@ let tests = [test_cascade, test_select, test_multiWindowState,
|
|||
function runNextTest() {
|
||||
// Reset the pref
|
||||
try {
|
||||
Services.prefs.clearUserPref("browser.sessionstore.max_concurrent_tabs");
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
|
||||
} catch (e) {}
|
||||
|
||||
// set an empty state & run the next test, or finish
|
||||
|
@ -88,9 +88,6 @@ function runNextTest() {
|
|||
|
||||
|
||||
function test_cascade() {
|
||||
// Set the pref to 1 so we know exactly how many tabs should be restoring at any given time
|
||||
Services.prefs.setIntPref("browser.sessionstore.max_concurrent_tabs", 1);
|
||||
|
||||
// We have our own progress listener for this test, which we'll attach before our state is set
|
||||
let progressListener = {
|
||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
|
@ -118,11 +115,11 @@ function test_cascade() {
|
|||
// before sessionstore has marked the tab as finished restoring and before it
|
||||
// starts restoring the next tab
|
||||
let expectedCounts = [
|
||||
[5, 1, 0],
|
||||
[4, 1, 1],
|
||||
[3, 1, 2],
|
||||
[2, 1, 3],
|
||||
[1, 1, 4],
|
||||
[3, 3, 0],
|
||||
[2, 3, 1],
|
||||
[1, 3, 2],
|
||||
[0, 3, 3],
|
||||
[0, 2, 4],
|
||||
[0, 1, 5]
|
||||
];
|
||||
|
||||
|
@ -149,9 +146,9 @@ function test_cascade() {
|
|||
|
||||
|
||||
function test_select() {
|
||||
// Set the pref to 0 so we know exactly how many tabs should be restoring at
|
||||
// Set the pref to true so we know exactly how many tabs should be restoring at
|
||||
// any given time. This guarantees that a finishing load won't start another.
|
||||
Services.prefs.setIntPref("browser.sessionstore.max_concurrent_tabs", 0);
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
|
||||
|
||||
// We have our own progress listener for this test, which we'll attach before our state is set
|
||||
let progressListener = {
|
||||
|
@ -298,9 +295,6 @@ function test_multiWindowState() {
|
|||
|
||||
|
||||
function test_setWindowStateNoOverwrite() {
|
||||
// Set the pref to 1 so we know exactly how many tabs should be restoring at any given time
|
||||
Services.prefs.setIntPref("browser.sessionstore.max_concurrent_tabs", 1);
|
||||
|
||||
// We have our own progress listener for this test, which we'll attach before our state is set
|
||||
let progressListener = {
|
||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
|
@ -370,9 +364,6 @@ function test_setWindowStateNoOverwrite() {
|
|||
|
||||
|
||||
function test_setWindowStateOverwrite() {
|
||||
// Set the pref to 1 so we know exactly how many tabs should be restoring at any given time
|
||||
Services.prefs.setIntPref("browser.sessionstore.max_concurrent_tabs", 1);
|
||||
|
||||
// We have our own progress listener for this test, which we'll attach before our state is set
|
||||
let progressListener = {
|
||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
|
@ -442,9 +433,6 @@ function test_setWindowStateOverwrite() {
|
|||
|
||||
|
||||
function test_setBrowserStateInterrupted() {
|
||||
// Set the pref to 1 so we know exactly how many tabs should be restoring at any given time
|
||||
Services.prefs.setIntPref("browser.sessionstore.max_concurrent_tabs", 1);
|
||||
|
||||
// We have our own progress listener for this test, which we'll attach before our state is set
|
||||
let progressListener = {
|
||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
||||
|
@ -561,9 +549,9 @@ function test_setBrowserStateInterrupted() {
|
|||
|
||||
|
||||
function test_reload() {
|
||||
// Set the pref to 0 so we know exactly how many tabs should be restoring at
|
||||
// Set the pref to true so we know exactly how many tabs should be restoring at
|
||||
// any given time. This guarantees that a finishing load won't start another.
|
||||
Services.prefs.setIntPref("browser.sessionstore.max_concurrent_tabs", 0);
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
|
||||
|
||||
// We have our own progress listener for this test, which we'll attach before our state is set
|
||||
let progressListener = {
|
||||
|
|
|
@ -21,7 +21,6 @@ function test() {
|
|||
waitForExplicitFinish();
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref("browser.sessionstore.max_concurrent_tabs");
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_hidden_tabs");
|
||||
|
||||
TabsProgressListener.uninit();
|
||||
|
@ -31,8 +30,6 @@ function test() {
|
|||
|
||||
TabsProgressListener.init();
|
||||
|
||||
Services.prefs.setIntPref("browser.sessionstore.max_concurrent_tabs", 3);
|
||||
|
||||
// First stage: restoreHiddenTabs = true
|
||||
// Second stage: restoreHiddenTabs = false
|
||||
test_loadTabs(true, function () {
|
||||
|
|
|
@ -43,7 +43,7 @@ let stateBackup = ss.getBrowserState();
|
|||
function cleanup() {
|
||||
// Reset the pref
|
||||
try {
|
||||
Services.prefs.clearUserPref("browser.sessionstore.max_concurrent_tabs");
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
|
||||
} catch (e) {}
|
||||
ss.setBrowserState(stateBackup);
|
||||
executeSoon(finish);
|
||||
|
@ -53,9 +53,9 @@ function test() {
|
|||
/** Bug 599909 - to-be-reloaded tabs don't show up in switch-to-tab **/
|
||||
waitForExplicitFinish();
|
||||
|
||||
// Set the pref to 0 so we know exactly how many tabs should be restoring at
|
||||
// Set the pref to true so we know exactly how many tabs should be restoring at
|
||||
// any given time. This guarantees that a finishing load won't start another.
|
||||
Services.prefs.setIntPref("browser.sessionstore.max_concurrent_tabs", 0);
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
|
||||
|
||||
let state = { windows: [{ tabs: [
|
||||
{ entries: [{ url: "http://example.org/#1" }] },
|
||||
|
|
|
@ -43,7 +43,7 @@ let stateBackup = ss.getBrowserState();
|
|||
function cleanup() {
|
||||
// Reset the pref
|
||||
try {
|
||||
Services.prefs.clearUserPref("browser.sessionstore.max_concurrent_tabs");
|
||||
Services.prefs.clearUserPref("browser.sessionstore.restore_on_demand");
|
||||
} catch (e) {}
|
||||
ss.setBrowserState(stateBackup);
|
||||
executeSoon(finish);
|
||||
|
@ -53,9 +53,9 @@ function test() {
|
|||
/** Bug 607016 - If a tab is never restored, attributes (eg. hidden) aren't updated correctly **/
|
||||
waitForExplicitFinish();
|
||||
|
||||
// Set the pref to 0 so we know exactly how many tabs should be restoring at
|
||||
// Set the pref to true so we know exactly how many tabs should be restoring at
|
||||
// any given time. This guarantees that a finishing load won't start another.
|
||||
Services.prefs.setIntPref("browser.sessionstore.max_concurrent_tabs", 0);
|
||||
Services.prefs.setBoolPref("browser.sessionstore.restore_on_demand", true);
|
||||
|
||||
// We have our own progress listener for this test, which we'll attach before our state is set
|
||||
let progressListener = {
|
||||
|
|
|
@ -13,19 +13,18 @@ let statePinned = {windows:[{tabs:[
|
|||
let state = {windows:[{tabs:[
|
||||
{entries:[{url:"http://example.com#1"}]},
|
||||
{entries:[{url:"http://example.com#2"}]},
|
||||
{entries:[{url:"http://example.com#3"}]}
|
||||
{entries:[{url:"http://example.com#3"}]},
|
||||
{entries:[{url:"http://example.com#4"}]},
|
||||
]}]};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref("browser.sessionstore.max_concurrent_tabs");
|
||||
TabsProgressListener.uninit();
|
||||
ss.setBrowserState(stateBackup);
|
||||
});
|
||||
|
||||
Services.prefs.setIntPref("browser.sessionstore.max_concurrent_tabs", 2);
|
||||
|
||||
TabsProgressListener.init();
|
||||
|
||||
|
@ -37,9 +36,9 @@ function test() {
|
|||
TabsProgressListener.setCallback(function (needsRestore, isRestoring) {
|
||||
if (firstProgress) {
|
||||
firstProgress = false;
|
||||
is(isRestoring, 2, "restoring 2 tabs concurrently");
|
||||
is(isRestoring, 3, "restoring 3 tabs concurrently");
|
||||
} else {
|
||||
ok(isRestoring < 3, "restoring max. 2 tabs concurrently");
|
||||
ok(isRestoring <= 3, "restoring max. 2 tabs concurrently");
|
||||
}
|
||||
|
||||
if (0 == needsRestore) {
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const NOTIFICATION = "sessionstore-browser-state-restored";
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
function observe(subject, topic, data) {
|
||||
if (NOTIFICATION == topic) {
|
||||
finish();
|
||||
ok(true, "TOPIC received");
|
||||
}
|
||||
}
|
||||
|
||||
Services.obs.addObserver(observe, NOTIFICATION, false);
|
||||
registerCleanupFunction(function () {
|
||||
Services.obs.removeObserver(observe, NOTIFICATION, false);
|
||||
});
|
||||
|
||||
ss.setBrowserState(JSON.stringify({ windows: [] }));
|
||||
}
|
|
@ -1 +1 @@
|
|||
8.0a1
|
||||
9.0a1
|
||||
|
|
|
@ -20,13 +20,14 @@ function test()
|
|||
const windowFeatures = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
|
||||
|
||||
testWin = Services.ww.openWindow(null, windowUrl, "_blank", windowFeatures, null);
|
||||
|
||||
testWin.addEventListener("load", initEditor, false);
|
||||
testWin.addEventListener("load", function onWindowLoad() {
|
||||
testWin.removeEventListener("load", onWindowLoad, false);
|
||||
waitForFocus(initEditor, testWin);
|
||||
}, false);
|
||||
}
|
||||
|
||||
function initEditor()
|
||||
{
|
||||
testWin.removeEventListener("load", initEditor, false);
|
||||
testDoc = testWin.document;
|
||||
|
||||
let hbox = testDoc.querySelector("hbox");
|
||||
|
@ -319,7 +320,8 @@ function editorLoaded()
|
|||
testWin.close();
|
||||
|
||||
testWin = testDoc = editor = null;
|
||||
finish();
|
||||
|
||||
waitForFocus(finish, window);
|
||||
}
|
||||
|
||||
function testBackspaceKey()
|
||||
|
|
|
@ -2708,6 +2708,12 @@ HUD_SERVICE.prototype =
|
|||
|
||||
let _browser = gBrowser.
|
||||
getBrowserForDocument(aContentWindow.top.document);
|
||||
|
||||
// ignore newly created documents that don't belong to a tab's browser
|
||||
if (!_browser) {
|
||||
return;
|
||||
}
|
||||
|
||||
let nBox = gBrowser.getNotificationBox(_browser);
|
||||
let nBoxId = nBox.getAttribute("id");
|
||||
let hudId = "hud_" + nBoxId;
|
||||
|
|
|
@ -144,6 +144,7 @@ _BROWSER_TEST_FILES = \
|
|||
browser_webconsole_bug_651501_document_body_autocomplete.js \
|
||||
browser_webconsole_bug_653531_highlighter_console_helper.js \
|
||||
browser_webconsole_bug_659907_console_dir.js \
|
||||
browser_webconsole_bug_678816.js \
|
||||
head.js \
|
||||
$(NULL)
|
||||
|
||||
|
@ -212,6 +213,7 @@ _BROWSER_TEST_PAGES = \
|
|||
test-bug-644419-log-limits.html \
|
||||
test-bug-632275-getters.html \
|
||||
test-bug-646025-console-file-location.html \
|
||||
test-bug-678816-content.js \
|
||||
test-file-location.js \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,62 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const TEST_URI = "http://example.com/browser/browser/devtools/webconsole/test/browser/test-console.html";
|
||||
const FRAME_SCRIPT_URI ="chrome://mochitests/content/browser/browser/devtools/webconsole/test/browser/test-bug-678816-content.js";
|
||||
|
||||
let HUD;
|
||||
let outputItem;
|
||||
|
||||
function tabLoad1(aEvent) {
|
||||
browser.removeEventListener(aEvent.type, arguments.callee, true);
|
||||
|
||||
openConsole();
|
||||
HUD = HUDService.getHudByWindow(content);
|
||||
|
||||
browser.addEventListener("load", tabLoad2, true);
|
||||
|
||||
// Reload so we get some output in the console.
|
||||
browser.contentWindow.location.reload();
|
||||
}
|
||||
|
||||
function tabLoad2(aEvent) {
|
||||
browser.removeEventListener(aEvent.type, tabLoad2, true);
|
||||
|
||||
outputItem = HUD.outputNode.querySelector(".hud-networkinfo .hud-clickable");
|
||||
ok(outputItem, "found a network message");
|
||||
document.addEventListener("popupshown", networkPanelShown, false);
|
||||
|
||||
// Click the network message to open the network panel.
|
||||
EventUtils.synthesizeMouseAtCenter(outputItem, {});
|
||||
}
|
||||
|
||||
function networkPanelShown(aEvent) {
|
||||
document.removeEventListener(aEvent.type, networkPanelShown, false);
|
||||
|
||||
executeSoon(function() {
|
||||
aEvent.target.addEventListener("popuphidden", networkPanelHidden, false);
|
||||
aEvent.target.hidePopup();
|
||||
});
|
||||
}
|
||||
|
||||
function networkPanelHidden(aEvent) {
|
||||
this.removeEventListener(aEvent.type, networkPanelHidden, false);
|
||||
|
||||
is(HUD.contentWindow, browser.contentWindow,
|
||||
"console has not been re-attached to the wrong window");
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
||||
function test() {
|
||||
messageManager.loadFrameScript(FRAME_SCRIPT_URI, true);
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
// There's no way to unload a frameScript so send a kill signal to
|
||||
// unregister the frame script's webProgressListener
|
||||
messageManager.sendAsyncMessage("bug-678816-kill-webProgressListener");
|
||||
});
|
||||
|
||||
addTab(TEST_URI);
|
||||
browser.addEventListener("load", tabLoad1, true);
|
||||
}
|
|
@ -0,0 +1,28 @@
|
|||
(function () {
|
||||
let ifaceReq = docShell.QueryInterface(Ci.nsIInterfaceRequestor);
|
||||
let webProgress = ifaceReq.getInterface(Ci.nsIWebProgress);
|
||||
|
||||
let WebProgressListener = {
|
||||
onStateChange: function WebProgressListener_onStateChange(
|
||||
webProgress, request, flag, status) {
|
||||
|
||||
if (flag & Ci.nsIWebProgressListener.STATE_START &&
|
||||
flag & Ci.nsIWebProgressListener.STATE_IS_WINDOW) {
|
||||
// ensure the dom window is the top one
|
||||
return (webProgress.DOMWindow.parent == webProgress.DOMWindow);
|
||||
}
|
||||
},
|
||||
|
||||
// ----------
|
||||
// Implements progress listener interface.
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIWebProgressListener,
|
||||
Ci.nsISupportsWeakReference])
|
||||
};
|
||||
|
||||
// add web progress listener
|
||||
webProgress.addProgressListener(WebProgressListener, Ci.nsIWebProgress.NOTIFY_STATE_ALL);
|
||||
|
||||
addMessageListener("bug-678816-kill-webProgressListener", function () {
|
||||
webProgress.removeProgressListener(WebProgressListener);
|
||||
});
|
||||
})();
|
|
@ -99,7 +99,7 @@ endif
|
|||
ifdef MOZ_PKG_MANIFEST_P
|
||||
MOZ_PKG_MANIFEST = package-manifest
|
||||
|
||||
$(MOZ_PKG_MANIFEST): $(MOZ_PKG_MANIFEST_P)
|
||||
$(MOZ_PKG_MANIFEST): $(MOZ_PKG_MANIFEST_P) $(GLOBAL_DEPS)
|
||||
$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) $< > $@
|
||||
|
||||
GARBAGE += $(MOZ_PKG_MANIFEST)
|
||||
|
|
|
@ -42,6 +42,7 @@ view.sortBy.tags.accesskey=T
|
|||
|
||||
searchBookmarks=Search Bookmarks
|
||||
searchHistory=Search History
|
||||
searchDownloads=Search Downloads
|
||||
searchCurrentDefault=Search in '%S'
|
||||
findInPrefix=Find in '%S'…
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
<!ENTITY startupHomePage.label "Show my home page">
|
||||
<!ENTITY startupBlankPage.label "Show a blank page">
|
||||
<!ENTITY startupLastSession.label "Show my windows and tabs from last time">
|
||||
<!ENTITY restoreOnDemand.label "Don’t load tabs until selected">
|
||||
<!ENTITY restoreOnDemand.accesskey "l">
|
||||
|
||||
<!ENTITY homepage.label "Home Page:">
|
||||
<!ENTITY homepage.accesskey "P">
|
||||
<!ENTITY useCurrentPage.label "Use Current Page">
|
||||
|
|
|
@ -81,7 +81,7 @@ treechildren::-moz-tree-image(noicon) {
|
|||
}
|
||||
|
||||
treechildren::-moz-tree-image(noicon) {
|
||||
list-style-image: url("moz-icon://stock/gtk-file?size=menu");
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
treechildren::-moz-tree-image(container, noicon) {
|
||||
list-style-image: url("chrome://browser/skin/aboutSessionRestore-window-icon.png");
|
||||
|
|
|
@ -195,7 +195,7 @@ menuitem.bookmark-item {
|
|||
|
||||
/* Bookmark items */
|
||||
.bookmark-item:not([container]) {
|
||||
list-style-image: url("moz-icon://stock/gtk-file?size=menu");
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
|
||||
.bookmark-item[container] {
|
||||
|
@ -982,7 +982,7 @@ toolbar[iconsize="small"] #feed-button {
|
|||
}
|
||||
|
||||
#page-proxy-favicon:not([src]) {
|
||||
list-style-image: url("moz-icon://stock/gtk-file?size=menu");
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
|
||||
#page-proxy-favicon[pageproxystate="invalid"] {
|
||||
|
@ -1562,7 +1562,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
width: 16px;
|
||||
height: 16px;
|
||||
-moz-margin-end: 3px;
|
||||
list-style-image: url("moz-icon://stock/gtk-file?size=menu");
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
|
||||
.tab-throbber {
|
||||
|
@ -1700,7 +1700,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
|
||||
/* All tabs menupopup */
|
||||
.alltabs-item > .menu-iconic-left > .menu-iconic-icon {
|
||||
list-style-image: url("moz-icon://stock/gtk-file?size=menu");
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
|
||||
.alltabs-item[selected="true"] {
|
||||
|
|
|
@ -375,3 +375,26 @@ code {
|
|||
.nodeBox.highlighted > .nodeLabel {
|
||||
border-color: #3875d7 !important;
|
||||
}
|
||||
|
||||
.editingAttributeValue {
|
||||
background-color: #492;
|
||||
}
|
||||
|
||||
#attribute-editor {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
z-index: 5000;
|
||||
background-color: #fff;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
#attribute-editor.editing {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#attribute-editor-input {
|
||||
border: none;
|
||||
padding: 2px 5px;
|
||||
font-family: Menlo, Andale Mono, monospace;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
|
|
@ -23,7 +23,7 @@ treechildren::-moz-tree-image(title) {
|
|||
margin: 0px 2px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
list-style-image: url("moz-icon://stock/gtk-file?size=menu");
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
|
||||
treechildren::-moz-tree-image(title, livemarkItem) {
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
height: 16px;
|
||||
width: 16px;
|
||||
-moz-margin-end: 4px;
|
||||
list-style-image: url("moz-icon://stock/gtk-file?size=menu");
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
|
||||
#all-sites-item > .site-container > .site-favicon {
|
||||
|
|
|
@ -119,7 +119,7 @@ radio[pane=paneSync] {
|
|||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 0px 2px;
|
||||
list-style-image: url("moz-icon://stock/gtk-file?size=menu");
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
|
||||
#paneApplications {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
.searchbar-engine-image {
|
||||
height: 16px;
|
||||
width: 16px;
|
||||
list-style-image: url("moz-icon://stock/gtk-file?size=menu");
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
-moz-margin-start: 2px;
|
||||
}
|
||||
|
||||
|
|
|
@ -218,6 +218,17 @@ html[dir=rtl] .groupItem.activeGroupItem {
|
|||
|
||||
.groupItem .close {
|
||||
z-index: 10;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
background-position: bottom left;
|
||||
}
|
||||
|
||||
html[dir=rtl] .groupItem .close {
|
||||
right: auto;
|
||||
left: 0px;
|
||||
background-position: bottom right;
|
||||
}
|
||||
|
||||
.phantom {
|
||||
|
|
|
@ -1529,7 +1529,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
.tab-icon-image {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
list-style-image: url("chrome://global/skin/tree/item.png");
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
|
||||
.tab-throbber {
|
||||
|
@ -2027,7 +2027,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
|
|||
|
||||
/* All Tabs Menupopup */
|
||||
.alltabs-item > .menu-iconic-left > .menu-iconic-icon {
|
||||
list-style-image: url("chrome://global/skin/tree/item.png");
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
|
||||
.alltabs-item[busy] > .menu-iconic-left > .menu-iconic-icon {
|
||||
|
|
|
@ -363,3 +363,26 @@ code {
|
|||
.nodeBox.highlighted > .nodeLabel {
|
||||
border-color: #3875d7 !important;
|
||||
}
|
||||
|
||||
.editingAttributeValue {
|
||||
background-color: #492;
|
||||
}
|
||||
|
||||
#attribute-editor {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
z-index: 5000;
|
||||
background-color: #fff;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
#attribute-editor.editing {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#attribute-editor-input {
|
||||
border: none;
|
||||
padding: 2px 5px;
|
||||
font-family: Menlo, Andale Mono, monospace;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
|
|
@ -210,6 +210,17 @@ html[dir=rtl] .groupItem.activeGroupItem {
|
|||
|
||||
.groupItem .close {
|
||||
z-index: 10;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
background-position: bottom left;
|
||||
}
|
||||
|
||||
html[dir=rtl] .groupItem .close {
|
||||
right: auto;
|
||||
left: 0px;
|
||||
background-position: bottom right;
|
||||
}
|
||||
|
||||
.phantom {
|
||||
|
|
|
@ -588,11 +588,11 @@ menuitem.bookmark-item {
|
|||
/* ::::: bookmark items ::::: */
|
||||
|
||||
.bookmark-item {
|
||||
list-style-image: url("chrome://global/skin/icons/folder-item.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
|
||||
.bookmark-item[container] {
|
||||
list-style-image: url("chrome://global/skin/icons/folder-item.png");
|
||||
-moz-image-region: rect(0px, 32px, 16px, 16px);
|
||||
}
|
||||
|
||||
|
@ -968,6 +968,14 @@ toolbar[mode="full"] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
|
|||
list-style-image: url(chrome://browser/skin/tabview/tabview.png);
|
||||
}
|
||||
|
||||
%ifdef WINSTRIPE_AERO
|
||||
#TabsToolbar > #tabview-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
|
||||
#TabsToolbar > toolbarpaletteitem > #tabview-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
|
||||
%endif
|
||||
#tabview-button:-moz-lwtheme-brighttext {
|
||||
list-style-image: url(chrome://browser/skin/tabview/tabview-inverted.png);
|
||||
}
|
||||
|
||||
#tabview-button {
|
||||
-moz-image-region: rect(0, 90px, 18px, 72px);
|
||||
}
|
||||
|
@ -1376,12 +1384,11 @@ html|*.urlbar-input:-moz-lwtheme:-moz-placeholder,
|
|||
}
|
||||
|
||||
#page-proxy-favicon:not([src]) {
|
||||
list-style-image: url("chrome://global/skin/icons/folder-item.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px)
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
|
||||
#page-proxy-favicon[pageproxystate="invalid"] {
|
||||
-moz-image-region: rect(32px, 16px, 48px, 0px);
|
||||
opacity: 0.5;
|
||||
}
|
||||
|
||||
#urlbar-throbber {
|
||||
|
@ -1782,8 +1789,7 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
.tab-icon-image {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
list-style-image: url("chrome://global/skin/icons/folder-item.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
-moz-margin-start: 2px;
|
||||
-moz-margin-end: 3px;
|
||||
}
|
||||
|
@ -1887,23 +1893,26 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
.tabbrowser-arrowscrollbox > .scrollbutton-up,
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down {
|
||||
list-style-image: url("chrome://browser/skin/tabbrowser/tab-arrow-left.png");
|
||||
-moz-image-region: rect(0, 15px, 17px, 0);
|
||||
margin: 0;
|
||||
padding-right: 2px;
|
||||
border-right: 2px solid transparent;
|
||||
background-origin: border-box;
|
||||
}
|
||||
|
||||
%ifdef WINSTRIPE_AERO
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-up:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
|
||||
%endif
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-up:-moz-lwtheme-brighttext,
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down:-moz-lwtheme-brighttext {
|
||||
list-style-image: url(chrome://browser/skin/tabbrowser/tab-arrow-left-inverted.png);
|
||||
}
|
||||
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-up[disabled],
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down[disabled] {
|
||||
opacity: .4;
|
||||
}
|
||||
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled]):hover:active,
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled]):hover:active {
|
||||
-moz-image-region: rect(0, 30px, 17px, 15px);
|
||||
}
|
||||
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-up:-moz-locale-dir(rtl),
|
||||
.tabbrowser-arrowscrollbox > .scrollbutton-down:-moz-locale-dir(ltr) {
|
||||
-moz-transform: scaleX(-1);
|
||||
|
@ -1932,7 +1941,17 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
#TabsToolbar > #new-tab-button,
|
||||
#TabsToolbar > toolbarpaletteitem > #new-tab-button {
|
||||
list-style-image: url(chrome://browser/skin/tabbrowser/newtab.png);
|
||||
-moz-image-region: rect(0, 16px, 18px, 0);
|
||||
-moz-image-region: auto;
|
||||
}
|
||||
|
||||
%ifdef WINSTRIPE_AERO
|
||||
#TabsToolbar > #new-tab-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
|
||||
#TabsToolbar > toolbarpaletteitem > #new-tab-button:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
|
||||
%endif
|
||||
.tabs-newtab-button:-moz-lwtheme-brighttext,
|
||||
#TabsToolbar > #new-tab-button:-moz-lwtheme-brighttext,
|
||||
#TabsToolbar > toolbarpaletteitem > #new-tab-button:-moz-lwtheme-brighttext {
|
||||
list-style-image: url(chrome://browser/skin/tabbrowser/newtab-inverted.png);
|
||||
}
|
||||
|
||||
.tabs-newtab-button {
|
||||
|
@ -1943,25 +1962,24 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
width: 26px;
|
||||
}
|
||||
|
||||
.tabs-newtab-button:hover:active,
|
||||
#TabsToolbar > #new-tab-button:hover:active {
|
||||
-moz-image-region: rect(0, 32px, 18px, 16px);
|
||||
}
|
||||
|
||||
#alltabs-button {
|
||||
list-style-image: url("chrome://browser/skin/tabbrowser/alltabs.png");
|
||||
-moz-image-region: rect(0, 14px, 16px, 0);
|
||||
}
|
||||
|
||||
#alltabs-button:hover:active {
|
||||
-moz-image-region: rect(0, 28px, 16px, 14px);
|
||||
}
|
||||
|
||||
#alltabs-button[type="menu"] {
|
||||
list-style-image: url("chrome://browser/skin/mainwindow-dropdown-arrow.png");
|
||||
-moz-image-region: rect(0, 13px, 11px, 0);
|
||||
}
|
||||
|
||||
%ifdef WINSTRIPE_AERO
|
||||
#TabsToolbar > #alltabs-button[type="menu"]:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
|
||||
#TabsToolbar > toolbarpaletteitem > #alltabs-button[type="menu"]:-moz-system-metric(windows-compositor):not(:-moz-lwtheme),
|
||||
%endif
|
||||
#alltabs-button[type="menu"]:-moz-lwtheme-brighttext {
|
||||
list-style-image: url(chrome://browser/skin/mainwindow-dropdown-arrow-inverted.png);
|
||||
}
|
||||
|
||||
#alltabs-button[type="menu"] > .toolbarbutton-icon {
|
||||
margin: 3px 0;
|
||||
}
|
||||
|
@ -1970,15 +1988,9 @@ richlistitem[type~="action"][actiontype="switchtab"] > .ac-url-box > .ac-action-
|
|||
display: none;
|
||||
}
|
||||
|
||||
#alltabs-button[type="menu"]:hover:active,
|
||||
#alltabs-button[type="menu"][open="true"] {
|
||||
-moz-image-region: rect(0, 26px, 11px, 13px);
|
||||
}
|
||||
|
||||
/* All tabs menupopup */
|
||||
.alltabs-item > .menu-iconic-left > .menu-iconic-icon {
|
||||
list-style-image: url("chrome://global/skin/icons/folder-item.png");
|
||||
-moz-image-region: rect(0px, 16px, 16px, 0px);
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png");
|
||||
}
|
||||
|
||||
.alltabs-item[selected="true"] {
|
||||
|
|
|
@ -348,3 +348,25 @@ code {
|
|||
background-image: url("chrome://global/skin/tree/twisty-open.png") !important;
|
||||
}
|
||||
|
||||
.editingAttributeValue {
|
||||
background-color: #492;
|
||||
}
|
||||
|
||||
#attribute-editor {
|
||||
visibility: hidden;
|
||||
position: absolute;
|
||||
z-index: 5000;
|
||||
background-color: #fff;
|
||||
border: 1px solid #000;
|
||||
}
|
||||
|
||||
#attribute-editor.editing {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
#attribute-editor-input {
|
||||
border: none;
|
||||
padding: 2px 5px;
|
||||
font-family: Menlo, Andale Mono, monospace;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
|
|
@ -25,6 +25,7 @@ browser.jar:
|
|||
skin/classic/browser/KUI-background.png
|
||||
skin/classic/browser/KUI-close.png
|
||||
skin/classic/browser/mainwindow-dropdown-arrow.png
|
||||
skin/classic/browser/mainwindow-dropdown-arrow-inverted.png
|
||||
skin/classic/browser/pageInfo.css
|
||||
skin/classic/browser/pageInfo.png (pageInfo.png)
|
||||
skin/classic/browser/page-livemarks.png (feeds/feedIcon16.png)
|
||||
|
@ -89,10 +90,12 @@ browser.jar:
|
|||
skin/classic/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/browser/tabbrowser/alltabs.png (tabbrowser/alltabs.png)
|
||||
skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
|
||||
skin/classic/browser/tabbrowser/newtab-inverted.png (tabbrowser/newtab-inverted.png)
|
||||
skin/classic/browser/tabbrowser/connecting.png (tabbrowser/connecting.png)
|
||||
skin/classic/browser/tabbrowser/loading.png (tabbrowser/loading.png)
|
||||
skin/classic/browser/tabbrowser/tab.png (tabbrowser/tab.png)
|
||||
skin/classic/browser/tabbrowser/tab-arrow-left.png (tabbrowser/tab-arrow-left.png)
|
||||
skin/classic/browser/tabbrowser/tab-arrow-left-inverted.png (tabbrowser/tab-arrow-left-inverted.png)
|
||||
skin/classic/browser/tabbrowser/tab-overflow-border.png (tabbrowser/tab-overflow-border.png)
|
||||
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
|
||||
skin/classic/browser/tabview/close.png (tabview/close.png)
|
||||
|
@ -101,6 +104,7 @@ browser.jar:
|
|||
skin/classic/browser/tabview/search.png (tabview/search.png)
|
||||
skin/classic/browser/tabview/stack-expander.png (tabview/stack-expander.png)
|
||||
skin/classic/browser/tabview/tabview.png (tabview/tabview.png)
|
||||
skin/classic/browser/tabview/tabview-inverted.png (tabview/tabview-inverted.png)
|
||||
skin/classic/browser/tabview/tabview.css (tabview/tabview.css)
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
skin/classic/browser/sync-throbber.png
|
||||
|
@ -140,6 +144,7 @@ browser.jar:
|
|||
skin/classic/aero/browser/KUI-background.png
|
||||
skin/classic/aero/browser/KUI-close.png
|
||||
skin/classic/aero/browser/mainwindow-dropdown-arrow.png (mainwindow-dropdown-arrow-aero.png)
|
||||
skin/classic/aero/browser/mainwindow-dropdown-arrow-inverted.png
|
||||
skin/classic/aero/browser/pageInfo.css
|
||||
skin/classic/aero/browser/pageInfo.png (pageInfo-aero.png)
|
||||
skin/classic/aero/browser/page-livemarks.png (feeds/feedIcon16-aero.png)
|
||||
|
@ -205,10 +210,12 @@ browser.jar:
|
|||
skin/classic/aero/browser/preferences/aboutPermissions.css (preferences/aboutPermissions.css)
|
||||
skin/classic/aero/browser/tabbrowser/alltabs.png (tabbrowser/alltabs.png)
|
||||
skin/classic/aero/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
|
||||
skin/classic/aero/browser/tabbrowser/newtab-inverted.png (tabbrowser/newtab-inverted.png)
|
||||
skin/classic/aero/browser/tabbrowser/connecting.png (tabbrowser/connecting.png)
|
||||
skin/classic/aero/browser/tabbrowser/loading.png (tabbrowser/loading.png)
|
||||
skin/classic/aero/browser/tabbrowser/tab.png (tabbrowser/tab.png)
|
||||
skin/classic/aero/browser/tabbrowser/tab-arrow-left.png (tabbrowser/tab-arrow-left.png)
|
||||
skin/classic/aero/browser/tabbrowser/tab-arrow-left-inverted.png (tabbrowser/tab-arrow-left-inverted.png)
|
||||
skin/classic/aero/browser/tabbrowser/tab-overflow-border.png (tabbrowser/tab-overflow-border.png)
|
||||
skin/classic/aero/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
|
||||
skin/classic/aero/browser/tabview/close.png (tabview/close.png)
|
||||
|
@ -217,6 +224,7 @@ browser.jar:
|
|||
skin/classic/aero/browser/tabview/search.png (tabview/search.png)
|
||||
skin/classic/aero/browser/tabview/stack-expander.png (tabview/stack-expander.png)
|
||||
skin/classic/aero/browser/tabview/tabview.png (tabview/tabview.png)
|
||||
skin/classic/aero/browser/tabview/tabview-inverted.png (tabview/tabview-inverted.png)
|
||||
skin/classic/aero/browser/tabview/tabview.css (tabview/tabview.css)
|
||||
#ifdef MOZ_SERVICES_SYNC
|
||||
skin/classic/aero/browser/sync-throbber.png
|
||||
|
|
После Ширина: | Высота: | Размер: 230 B |
|
@ -118,11 +118,11 @@ radio[pane=paneSync] {
|
|||
width: 16px;
|
||||
height: 16px;
|
||||
margin: 0 2px;
|
||||
list-style-image: url("chrome://global/skin/icons/folder-item.png") !important;
|
||||
-moz-image-region: rect(0, 16px, 16px, 0);
|
||||
list-style-image: url("chrome://mozapps/skin/places/defaultFavicon.png") !important;
|
||||
}
|
||||
|
||||
#cookiesChildren::-moz-tree-image(domainCol, container) {
|
||||
list-style-image: url("chrome://global/skin/icons/folder-item.png") !important;
|
||||
-moz-image-region: rect(0, 32px, 16px, 16px);
|
||||
}
|
||||
|
||||
|
|
После Ширина: | Высота: | Размер: 247 B |
Двоичные данные
browser/themes/winstripe/browser/tabbrowser/newtab.png
До Ширина: | Высота: | Размер: 603 B После Ширина: | Высота: | Размер: 445 B |
После Ширина: | Высота: | Размер: 250 B |
Двоичные данные
browser/themes/winstripe/browser/tabbrowser/tab-arrow-left.png
До Ширина: | Высота: | Размер: 460 B После Ширина: | Высота: | Размер: 368 B |
После Ширина: | Высота: | Размер: 524 B |
|
@ -82,6 +82,7 @@ html[dir=rtl] .favicon {
|
|||
width: 16px;
|
||||
height: 16px;
|
||||
background-image: -moz-image-rect(url("chrome://browser/skin/tabview/close.png"), 0, 16, 16, 0);
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.close:hover {
|
||||
|
@ -236,6 +237,17 @@ html[dir=rtl] .groupItem.activeGroupItem {
|
|||
|
||||
.groupItem .close {
|
||||
z-index: 10;
|
||||
top: 0px;
|
||||
right: 0px;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
background-position: bottom left;
|
||||
}
|
||||
|
||||
html[dir=rtl] .groupItem .close {
|
||||
right: auto;
|
||||
left: 0px;
|
||||
background-position: bottom right;
|
||||
}
|
||||
|
||||
.dragRegion {
|
||||
|
|
|
@ -46,6 +46,27 @@
|
|||
#
|
||||
topsrcdir=$1
|
||||
|
||||
abspath() {
|
||||
if uname -s | grep -q MINGW; then
|
||||
# We have no way to figure out whether we're in gmake or pymake right
|
||||
# now. gmake gives us Unix-style paths while pymake gives us Windows-style
|
||||
# paths, so attempt to handle both.
|
||||
regexes='^\([A-Za-z]:\|\\\\\|\/\) ^\/'
|
||||
else
|
||||
regexes='^\/'
|
||||
fi
|
||||
|
||||
for regex in $regexes; do
|
||||
if echo $1 | grep -q $regex; then
|
||||
echo $1
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
||||
# If we're at this point, we have a relative path
|
||||
echo `pwd`/$1
|
||||
}
|
||||
|
||||
for _config in "$MOZCONFIG" \
|
||||
"$MOZ_MYCONFIG"
|
||||
do
|
||||
|
@ -66,7 +87,7 @@ for _config in "$MOZCONFIG" \
|
|||
"$HOME/.mozmyconfig.sh"
|
||||
do
|
||||
if test -f "$_config"; then
|
||||
echo "$_config";
|
||||
echo `abspath $_config`
|
||||
exit 0
|
||||
fi
|
||||
done
|
||||
|
|
|
@ -107,7 +107,6 @@ public class WatcherService extends Service
|
|||
|
||||
|
||||
private IWatcherService.Stub stub = new IWatcherService.Stub() {
|
||||
@Override
|
||||
public int UpdateApplication(String sAppName, String sFileName, String sOutFile, int bReboot) throws RemoteException
|
||||
{
|
||||
return UpdtApp(sAppName, sFileName, sOutFile, bReboot);
|
||||
|
@ -874,7 +873,6 @@ public class WatcherService extends Service
|
|||
runner.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
bInstalling = true;
|
||||
UpdtApp(msPkgName, msPkgFileName, msOutFile, mbReboot);
|
||||
|
|
|
@ -398,10 +398,11 @@ int do_relocation_section(Elf *elf, unsigned int rel_type, unsigned int rel_type
|
|||
assert(section->getType() == Rel_Type::sh_type);
|
||||
|
||||
Elf32_Shdr relhack32_section =
|
||||
{ 0, SHT_PROGBITS, SHF_ALLOC, 0, -1, 0, SHN_UNDEF, 0,
|
||||
{ 0, SHT_PROGBITS, SHF_ALLOC, 0, (Elf32_Off)-1, 0, SHN_UNDEF, 0,
|
||||
Elf_RelHack::size(elf->getClass()), Elf_RelHack::size(elf->getClass()) }; // TODO: sh_addralign should be an alignment, not size
|
||||
Elf32_Shdr relhackcode32_section =
|
||||
{ 0, SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0, -1, 0, SHN_UNDEF, 0, 1, 0 };
|
||||
{ 0, SHT_PROGBITS, SHF_ALLOC | SHF_EXECINSTR, 0, (Elf32_Off)-1, 0,
|
||||
SHN_UNDEF, 0, 1, 0 };
|
||||
Elf_Shdr relhack_section(relhack32_section);
|
||||
Elf_Shdr relhackcode_section(relhackcode32_section);
|
||||
ElfRelHack_Section *relhack = new ElfRelHack_Section(relhack_section);
|
||||
|
|
|
@ -276,7 +276,7 @@ public:
|
|||
throw std::runtime_error("Unsupported ELF class or data encoding");
|
||||
}
|
||||
|
||||
static inline int size(char ei_class)
|
||||
static inline unsigned int size(char ei_class)
|
||||
{
|
||||
if (ei_class == ELFCLASS32)
|
||||
return sizeof(typename T::Type32);
|
||||
|
|
|
@ -42,6 +42,8 @@ VPATH = @srcdir@
|
|||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
NO_PROFILE_GUIDED_OPTIMIZE = 1
|
||||
|
||||
ifdef ENABLE_TESTS
|
||||
|
||||
ifdef _MSC_VER
|
||||
|
|
|
@ -202,6 +202,20 @@ nsNullPrincipalURI::GetSpec(nsACString &_spec)
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
// result may contain unescaped UTF-8 characters
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetSpecIgnoringRef(nsACString &result)
|
||||
{
|
||||
return GetSpec(result);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::GetHasRef(PRBool *result)
|
||||
{
|
||||
*result = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNullPrincipalURI::SetSpec(const nsACString &aSpec)
|
||||
{
|
||||
|
|
|
@ -1737,7 +1737,8 @@ nsScriptSecurityManager::CheckFunctionAccess(JSContext *aCx, void *aFunObj,
|
|||
{
|
||||
#ifdef DEBUG
|
||||
{
|
||||
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, (JSObject *)aFunObj);
|
||||
JS_ASSERT(JS_ObjectIsFunction(aCx, (JSObject *)aFunObj));
|
||||
JSFunction *fun = (JSFunction *)JS_GetPrivate(aCx, (JSObject *)aFunObj);
|
||||
JSScript *script = JS_GetFunctionScript(aCx, fun);
|
||||
|
||||
NS_ASSERTION(!script, "Null principal for non-native function!");
|
||||
|
@ -2218,7 +2219,7 @@ nsScriptSecurityManager::GetFunctionObjectPrincipal(JSContext *cx,
|
|||
return result;
|
||||
}
|
||||
|
||||
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj);
|
||||
JSFunction *fun = (JSFunction *)JS_GetPrivate(cx, obj);
|
||||
JSScript *script = JS_GetFunctionScript(cx, fun);
|
||||
|
||||
if (!script)
|
||||
|
@ -2284,7 +2285,7 @@ nsScriptSecurityManager::GetFramePrincipal(JSContext *cx,
|
|||
#ifdef DEBUG
|
||||
if (NS_SUCCEEDED(*rv) && !result)
|
||||
{
|
||||
JSFunction *fun = GET_FUNCTION_PRIVATE(cx, obj);
|
||||
JSFunction *fun = (JSFunction *)JS_GetPrivate(cx, obj);
|
||||
JSScript *script = JS_GetFunctionScript(cx, fun);
|
||||
|
||||
NS_ASSERTION(!script, "Null principal for non-native function!");
|
||||
|
|
|
@ -278,6 +278,7 @@ EXTRA_CONFIG_DEPS := \
|
|||
$(NULL)
|
||||
|
||||
$(CONFIGURES): %: %.in $(EXTRA_CONFIG_DEPS)
|
||||
@$(PYTHON) $(TOPSRCDIR)/js/src/config/check-sync-dirs.py $(TOPSRCDIR)/js/src/build $(TOPSRCDIR)/build
|
||||
@echo Generating $@ using autoconf
|
||||
cd $(@D); $(AUTOCONF)
|
||||
|
||||
|
@ -346,6 +347,7 @@ endif
|
|||
# Build it
|
||||
|
||||
realbuild:: $(OBJDIR)/Makefile $(OBJDIR)/config.status
|
||||
@$(PYTHON) $(TOPSRCDIR)/js/src/config/check-sync-dirs.py $(TOPSRCDIR)/js/src/config $(TOPSRCDIR)/config
|
||||
$(MOZ_MAKE)
|
||||
|
||||
####################################
|
||||
|
|
|
@ -223,7 +223,6 @@ MOZ_XUL = @MOZ_XUL@
|
|||
MOZ_RDF = @MOZ_RDF@
|
||||
|
||||
NECKO_PROTOCOLS = @NECKO_PROTOCOLS@
|
||||
NECKO_DISK_CACHE = @NECKO_DISK_CACHE@
|
||||
NECKO_COOKIES = @NECKO_COOKIES@
|
||||
NECKO_WIFI = @NECKO_WIFI@
|
||||
MOZ_AUTH_EXTENSION = @MOZ_AUTH_EXTENSION@
|
||||
|
|
|
@ -88,6 +88,9 @@ space :=$(nullstr) # EOL
|
|||
|
||||
core_winabspath = $(firstword $(subst /, ,$(call core_abspath,$(1)))):$(subst $(space),,$(patsubst %,\\%,$(wordlist 2,$(words $(subst /, ,$(call core_abspath,$(1)))), $(strip $(subst /, ,$(call core_abspath,$(1)))))))
|
||||
|
||||
# LIBXUL_DIST is not defined under js/src, thus we make it mean DIST there.
|
||||
LIBXUL_DIST ?= $(DIST)
|
||||
|
||||
# FINAL_TARGET specifies the location into which we copy end-user-shipped
|
||||
# build products (typelibs, components, chrome).
|
||||
#
|
||||
|
@ -743,10 +746,10 @@ endif
|
|||
MERGE_FILES = $(foreach f,$(1),$(call MERGE_FILE,$(f)))
|
||||
|
||||
ifeq (OS2,$(OS_ARCH))
|
||||
RUN_TEST_PROGRAM = $(topsrcdir)/build/os2/test_os2.cmd "$(DIST)"
|
||||
RUN_TEST_PROGRAM = $(topsrcdir)/build/os2/test_os2.cmd "$(LIBXUL_DIST)"
|
||||
else
|
||||
ifneq (WINNT,$(OS_ARCH))
|
||||
RUN_TEST_PROGRAM = $(DIST)/bin/run-mozilla.sh
|
||||
RUN_TEST_PROGRAM = $(LIBXUL_DIST)/bin/run-mozilla.sh
|
||||
endif # ! WINNT
|
||||
endif # ! OS2
|
||||
|
||||
|
|
2809
config/gtscc.c
|
@ -10,4 +10,4 @@
|
|||
# hardcoded milestones in the tree from these two files.
|
||||
#--------------------------------------------------------
|
||||
|
||||
8.0a1
|
||||
9.0a1
|
||||
|
|
|
@ -433,7 +433,7 @@ endif
|
|||
|
||||
define SUBMAKE # $(call SUBMAKE,target,directory)
|
||||
+@$(UPDATE_TITLE)
|
||||
+@$(MAKE) $(if $(2),-C $(2)) $(1)
|
||||
+$(MAKE) $(if $(2),-C $(2)) $(1)
|
||||
|
||||
endef # The extra line is important here! don't delete it
|
||||
|
||||
|
@ -899,7 +899,7 @@ ifdef SHARED_LIBRARY
|
|||
endif
|
||||
endif # SHARED_LIBRARY || PROGRAM
|
||||
endif # WINNT_
|
||||
endif # MOZ_PROFILE_GENERATE || MOZ_PROFILE_USE
|
||||
endif # MOZ_PROFILE_USE
|
||||
ifdef MOZ_PROFILE_GENERATE
|
||||
# Clean up profiling data during PROFILE_GENERATE phase
|
||||
export::
|
||||
|
|
92
configure.in
|
@ -970,6 +970,7 @@ if test -n "$_WIN32_MSVC"; then
|
|||
AC_DEFINE(HAVE_IO_H)
|
||||
AC_DEFINE(HAVE_SETBUF)
|
||||
AC_DEFINE(HAVE_ISATTY)
|
||||
AC_DEFINE(HAVE_STDCALL)
|
||||
fi
|
||||
|
||||
fi # COMPILE_ENVIRONMENT
|
||||
|
@ -2107,6 +2108,8 @@ case "$target" in
|
|||
# logging code in nsObjCExceptions.h. Currently we only use that in debug
|
||||
# builds.
|
||||
MOZ_DEBUG_LDFLAGS="$MOZ_DEBUG_LDFLAGS -framework ExceptionHandling"
|
||||
# Debug builds should always have frame pointers
|
||||
MOZ_DEBUG_FLAGS="-g -fno-omit-frame-pointer"
|
||||
|
||||
if test "x$lto_is_enabled" = "xyes"; then
|
||||
echo "Skipping -dead_strip because lto is enabled."
|
||||
|
@ -2253,6 +2256,8 @@ ia64*-hpux*)
|
|||
else
|
||||
MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks -fno-reorder-functions -fno-omit-frame-pointer"
|
||||
fi
|
||||
# Debug builds should always have frame pointers
|
||||
MOZ_DEBUG_FLAGS="-g -fno-omit-frame-pointer"
|
||||
;;
|
||||
|
||||
*-*linux*)
|
||||
|
@ -2278,7 +2283,8 @@ ia64*-hpux*)
|
|||
fi
|
||||
MOZ_PGO_OPTIMIZE_FLAGS="-O3 $MOZ_FRAMEPTR_FLAGS"
|
||||
MOZ_OPTIMIZE_FLAGS="-Os -freorder-blocks $MOZ_OPTIMIZE_SIZE_TWEAK $MOZ_FRAMEPTR_FLAGS"
|
||||
MOZ_DEBUG_FLAGS="-g"
|
||||
# Debug builds should always have frame pointers
|
||||
MOZ_DEBUG_FLAGS="-g -fno-omit-frame-pointer"
|
||||
fi
|
||||
|
||||
TARGET_NSPR_MDCPUCFG='\"md/_linux.cfg\"'
|
||||
|
@ -2371,7 +2377,8 @@ ia64*-hpux*)
|
|||
CFLAGS="$CFLAGS -we4553"
|
||||
CXXFLAGS="$CXXFLAGS -we4553"
|
||||
LIBS="$LIBS kernel32.lib user32.lib gdi32.lib winmm.lib wsock32.lib advapi32.lib"
|
||||
MOZ_DEBUG_FLAGS='-Zi'
|
||||
# Debug builds should always have frame pointers
|
||||
MOZ_DEBUG_FLAGS='-Zi -Oy-'
|
||||
MOZ_DEBUG_LDFLAGS='-DEBUG -DEBUGTYPE:CV'
|
||||
WARNINGS_AS_ERRORS='-WX'
|
||||
# If we're building with --enable-profiling, we need -Oy-, which forces a frame pointer.
|
||||
|
@ -3588,53 +3595,6 @@ then
|
|||
LDFLAGS="${_PTHREAD_LDFLAGS} ${LDFLAGS}"
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl See if mmap sees writes
|
||||
dnl For cross compiling, just define it as no, which is a safe default
|
||||
dnl ========================================================
|
||||
AC_MSG_CHECKING(whether mmap() sees write()s)
|
||||
|
||||
changequote(,)
|
||||
mmap_test_prog='
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
char fname[] = "conftest.file";
|
||||
char zbuff[1024]; /* Fractional page is probably worst case */
|
||||
|
||||
int main() {
|
||||
char *map;
|
||||
int fd;
|
||||
int i;
|
||||
unlink(fname);
|
||||
fd = open(fname, O_RDWR | O_CREAT, 0660);
|
||||
if(fd<0) return 1;
|
||||
unlink(fname);
|
||||
write(fd, zbuff, sizeof(zbuff));
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
map = (char*)mmap(0, sizeof(zbuff), PROT_READ, MAP_SHARED, fd, 0);
|
||||
if(map==(char*)-1) return 2;
|
||||
for(i=0; fname[i]; i++) {
|
||||
int rc = write(fd, &fname[i], 1);
|
||||
if(map[i]!=fname[i]) return 4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
'
|
||||
changequote([,])
|
||||
|
||||
AC_TRY_RUN($mmap_test_prog , result="yes", result="no", result="yes")
|
||||
|
||||
AC_MSG_RESULT("$result")
|
||||
|
||||
if test "$result" = "no"; then
|
||||
AC_DEFINE(MMAP_MISSES_WRITES)
|
||||
fi
|
||||
|
||||
|
||||
dnl Checks for library functions.
|
||||
dnl ========================================================
|
||||
|
@ -4778,7 +4738,6 @@ MOZ_DISABLE_DOMCRYPTO=
|
|||
NSS_DISABLE_DBM=
|
||||
NECKO_WIFI=1
|
||||
NECKO_COOKIES=1
|
||||
NECKO_DISK_CACHE=1
|
||||
NECKO_PROTOCOLS_DEFAULT="about data file ftp http res viewsource websocket wyciwyg"
|
||||
USE_ARM_KUSER=
|
||||
BUILD_CTYPES=1
|
||||
|
@ -5194,7 +5153,7 @@ incorrect])
|
|||
fi
|
||||
|
||||
MOZ_ENABLE_QTMOBILITY=
|
||||
PKG_CHECK_MODULES(_QTMOBILITY, QtSensors,
|
||||
PKG_CHECK_MODULES(_QTMOBILITY, QtSensors QtFeedback QtLocation,
|
||||
MOZ_ENABLE_QTMOBILITY=1,
|
||||
MOZ_ENABLE_QTMOBILITY=)
|
||||
if test "$MOZ_ENABLE_QTMOBILITY"; then
|
||||
|
@ -5202,11 +5161,13 @@ incorrect])
|
|||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS $_QTMOBILITY_CFLAGS"
|
||||
MOZ_QT_LIBS="$MOZ_QT_LIBS $_QTMOBILITY_LIBS"
|
||||
else
|
||||
AC_CHECK_LIB(QtSensors, main, [
|
||||
AC_CHECK_LIB(QtSensors QtFeedback QtLocation, main, [
|
||||
MOZ_ENABLE_QTMOBILITY=1
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I/usr/include/qt4/QtMobility"
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I/usr/include/qt4/QtSensors"
|
||||
MOZ_QT_LIBS="$MOZ_QT_LIBS -lQtSensors"
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I/usr/include/qt4/QtFeedback"
|
||||
MOZ_QT_CFLAGS="$MOZ_QT_CFLAGS -I/usr/include/qt4/QtLocation"
|
||||
MOZ_QT_LIBS="$MOZ_QT_LIBS -lQtSensors -lQtFeedback -lQtLocation"
|
||||
])
|
||||
fi
|
||||
if test "$MOZ_ENABLE_QTMOBILITY"; then
|
||||
|
@ -8763,19 +8724,6 @@ for p in $NECKO_PROTOCOLS; do
|
|||
AC_DEFINE_UNQUOTED(NECKO_PROTOCOL_$p)
|
||||
done
|
||||
|
||||
dnl
|
||||
dnl option to disable necko's disk cache
|
||||
dnl
|
||||
MOZ_ARG_DISABLE_BOOL(necko-disk-cache,
|
||||
[ --disable-necko-disk-cache
|
||||
Disable necko disk cache],
|
||||
NECKO_DISK_CACHE=,
|
||||
NECKO_DISK_CACHE=1)
|
||||
AC_SUBST(NECKO_DISK_CACHE)
|
||||
if test "$NECKO_DISK_CACHE"; then
|
||||
AC_DEFINE(NECKO_DISK_CACHE)
|
||||
fi
|
||||
|
||||
dnl
|
||||
dnl option to disable necko's wifi scanner
|
||||
dnl
|
||||
|
@ -9322,7 +9270,7 @@ xpcom/xpcom-private.h
|
|||
# (apparently) only need this hack when egrep's "pattern" is particularly
|
||||
# long (as in the following code). See bug 655339.
|
||||
case "$host" in
|
||||
x86_64-apple-darwin*)
|
||||
*-apple-darwin*)
|
||||
FIXED_EGREP="arch -arch i386 egrep"
|
||||
;;
|
||||
*)
|
||||
|
@ -9366,6 +9314,16 @@ _EGREP_PATTERN="${_EGREP_PATTERN}dummy_never_defined)"
|
|||
* is defined before <stdint.h> is included. */
|
||||
#define __STDC_LIMIT_MACROS
|
||||
|
||||
/* Force-include hunspell_alloc_hooks.h for hunspell, so that we don't need to
|
||||
* modify it directly.
|
||||
*
|
||||
* HUNSPELL_STATIC is defined in extensions/spellcheck/hunspell/src/Makefile.in,
|
||||
* unless --enable-system-hunspell is defined.
|
||||
*/
|
||||
#if defined(HUNSPELL_STATIC)
|
||||
#include "hunspell_alloc_hooks.h"
|
||||
#endif
|
||||
|
||||
#endif /* _MOZILLA_CONFIG_H_ */
|
||||
|
||||
EOF
|
||||
|
|
|
@ -118,8 +118,15 @@ interface nsIInProcessContentFrameMessageManager : nsIContentFrameMessageManager
|
|||
[notxpcom] nsIContent getOwnerContent();
|
||||
};
|
||||
|
||||
[scriptable, uuid(ed6522fd-ffb6-4920-b50d-cf629309616b)]
|
||||
interface nsIChromeFrameMessageManager : nsIFrameMessageManager
|
||||
[scriptable, uuid(6331bbca-2c9f-4766-b3c7-ae75554bf1ec)]
|
||||
interface nsITreeItemFrameMessageManager : nsIFrameMessageManager
|
||||
{
|
||||
readonly attribute unsigned long childCount;
|
||||
nsITreeItemFrameMessageManager getChildAt(in unsigned long aIndex);
|
||||
};
|
||||
|
||||
[scriptable, uuid(23e6ef7b-8cc5-4e8b-9391-453440a3b858)]
|
||||
interface nsIChromeFrameMessageManager : nsITreeItemFrameMessageManager
|
||||
{
|
||||
/*
|
||||
* Load a script in the (remote) frame. aURL must be the absolute URL.
|
||||
|
|
|
@ -93,6 +93,23 @@ struct CharacterDataChangeInfo
|
|||
* The text that used to begin at mChangeEnd now begins at
|
||||
* mChangeStart + mReplaceLength.
|
||||
*/
|
||||
|
||||
struct Details {
|
||||
enum {
|
||||
eMerge, // two text nodes are merged as a result of normalize()
|
||||
eSplit // a text node is split as a result of splitText()
|
||||
} mType;
|
||||
/**
|
||||
* For eMerge it's the text node that will be removed, for eSplit it's the
|
||||
* new text node.
|
||||
*/
|
||||
nsIContent* mNextSibling;
|
||||
};
|
||||
|
||||
/**
|
||||
* Used for splitText() and normalize(), otherwise null.
|
||||
*/
|
||||
Details* mDetails;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|