Merge MC -> JM

This commit is contained in:
Brian Hackett 2011-08-21 16:00:26 -07:00
commit 9ba7e372e9
1103 changed files with 26327 additions and 23337 deletions

View File

@ -67,3 +67,4 @@ a95d426422816513477e5863add1b00ac7041dcb AURORA_BASE_20110412
138f593553b66c9f815e8f57870c19d6347f7702 UPDATE_PACKAGING_R14
462c726144bc1fb45b61e774f64ac5d61b4e047c UPDATE_PACKAGING_R14
5eb553dd2ceae5f88d80f27afc5ef3935c5d43b0 AURORA_BASE_20110705
41b84b87c816403e1b74963d8094cff0406c989e AURORA_BASE_20110816

View File

@ -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

View File

@ -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;
};

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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())

View File

@ -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 \

View File

@ -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>

View File

@ -45,13 +45,13 @@ include $(topsrcdir)/config/config.mk
PARALLEL_DIRS = \
base \
components \
devtools \
fuel \
locales \
themes \
$(NULL)
DIRS = \
devtools \
app \
$(NULL)

View File

@ -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.

View File

@ -1631,7 +1631,7 @@ BaseTemplates.AttrTag =
"&nbsp;",
domplate.SPAN({"class": "nodeName editable"}, "$attr.nodeName"),
"=&quot;",
domplate.SPAN({"class": "nodeValue editable"}, "$attr.nodeValue"),
domplate.SPAN({"class": "nodeValue editable", "data-attributeName": "$attr.nodeName"}, "$attr.nodeValue"),
"&quot;");
BaseTemplates.TextTag =

View File

@ -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>

View File

@ -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.

View File

@ -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");

View File

@ -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);
}

View File

@ -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 \

View File

@ -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();
}

View File

@ -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)

View File

@ -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";
}

File diff suppressed because one or more lines are too long

View File

@ -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);
});

View File

@ -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";

View File

@ -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;
}

View File

@ -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 }
};

View File

@ -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

View File

@ -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"/>

View File

@ -52,8 +52,6 @@ endif
CPPSRCS = nsProfileMigrator.cpp \
nsBrowserProfileMigratorUtils.cpp \
nsNetscapeProfileMigratorBase.cpp \
nsSeamonkeyProfileMigrator.cpp \
$(NULL)
ifneq ($(OS_ARCH),OS2)

View File

@ -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);
}

View File

@ -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(&regFileExists);
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(), &reg))) {
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", &regInfo))
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;
}

View File

@ -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

View File

@ -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 } },

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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);"

View File

@ -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();
}

View File

@ -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();

View File

@ -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) {

View File

@ -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();
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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");

View File

@ -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"/>

View File

@ -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;
},
/**

View File

@ -149,6 +149,7 @@ _BROWSER_TEST_FILES = \
browser_628270.js \
browser_635418.js \
browser_636279.js \
browser_645428.js \
browser_659591.js \
$(NULL)

View File

@ -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 = {

View File

@ -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 () {

View File

@ -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" }] },

View File

@ -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 = {

View File

@ -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) {

View File

@ -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: [] }));
}

View File

@ -1 +1 @@
8.0a1
9.0a1

View File

@ -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()

View File

@ -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;

View File

@ -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)

View File

@ -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);
}

View File

@ -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);
});
})();

View File

@ -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)

View File

@ -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'…

View File

@ -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 "Dont load tabs until selected">
<!ENTITY restoreOnDemand.accesskey "l">
<!ENTITY homepage.label "Home Page:">
<!ENTITY homepage.accesskey "P">
<!ENTITY useCurrentPage.label "Use Current Page">

View File

@ -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");

View File

@ -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"] {

View File

@ -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;
}

View File

@ -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) {

View File

@ -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 {

View File

@ -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 {

View File

@ -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;
}

View File

@ -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 {

View File

@ -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 {

View File

@ -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;
}

View File

@ -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 {

View File

@ -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"] {

View File

@ -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;
}

View File

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 230 B

View File

@ -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);
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 247 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 603 B

After

Width:  |  Height:  |  Size: 445 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 250 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 460 B

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 524 B

View File

@ -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 {

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -42,6 +42,8 @@ VPATH = @srcdir@
include $(DEPTH)/config/autoconf.mk
NO_PROFILE_GUIDED_OPTIMIZE = 1
ifdef ENABLE_TESTS
ifdef _MSC_VER

View File

@ -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)
{

View File

@ -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!");

View File

@ -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)
####################################

View File

@ -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@

View File

@ -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

File diff suppressed because it is too large Load Diff

View File

@ -10,4 +10,4 @@
# hardcoded milestones in the tree from these two files.
#--------------------------------------------------------
8.0a1
9.0a1

View File

@ -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::

View File

@ -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

View File

@ -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.

View File

@ -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;
};
/**

Some files were not shown because too many files have changed in this diff Show More