Merge from cvs-trunk-mirror to mozilla-central.

--HG--
rename : js/src/js.c => js/src/js.cpp
rename : js/src/jsfun.c => js/src/jsfun.cpp
rename : js/src/jsinterp.c => js/src/jsinterp.cpp
rename : js/src/jsobj.c => js/src/jsobj.cpp
This commit is contained in:
jorendorff@mozilla.com 2007-10-31 10:40:29 -05:00
Родитель 0a4915ceb4 ad25b4ed1d
Коммит df571c0233
581 изменённых файлов: 18015 добавлений и 5853 удалений

Просмотреть файл

@ -1639,15 +1639,14 @@ nsresult nsAccessible::AppendFlatStringFromContentNode(nsIContent *aContent, nsA
nsresult nsAccessible::AppendFlatStringFromSubtree(nsIContent *aContent, nsAString *aFlatString) nsresult nsAccessible::AppendFlatStringFromSubtree(nsIContent *aContent, nsAString *aFlatString)
{ {
static nsIContent *startContent = nsnull; static PRBool isAlreadyHere; // Prevent recursion which can cause infinite loops
// never run into the same content node, to prevent infinite recursion if (isAlreadyHere) {
if (startContent == aContent) {
return NS_OK; return NS_OK;
} }
if (!startContent) { isAlreadyHere = PR_TRUE;
startContent = aContent;
}
nsresult rv = AppendFlatStringFromSubtreeRecurse(aContent, aFlatString); nsresult rv = AppendFlatStringFromSubtreeRecurse(aContent, aFlatString);
isAlreadyHere = PR_FALSE;
if (NS_SUCCEEDED(rv) && !aFlatString->IsEmpty()) { if (NS_SUCCEEDED(rv) && !aFlatString->IsEmpty()) {
nsAString::const_iterator start, end; nsAString::const_iterator start, end;
aFlatString->BeginReading(start); aFlatString->BeginReading(start);
@ -1661,10 +1660,6 @@ nsresult nsAccessible::AppendFlatStringFromSubtree(nsIContent *aContent, nsAStri
aFlatString->Truncate(aFlatString->Length() - spacesToTruncate); aFlatString->Truncate(aFlatString->Length() - spacesToTruncate);
} }
if (startContent == aContent) {
// we are leaving the original invoking
startContent = nsnull;
}
return rv; return rv;
} }

Просмотреть файл

@ -64,7 +64,7 @@ public:
NS_IMETHOD GetChildCount(PRInt32 *_retval); NS_IMETHOD GetChildCount(PRInt32 *_retval);
NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren); NS_IMETHOD GetAllowsAnonChildAccessibles(PRBool *aAllowsAnonChildren);
NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY, nsIAccessible **aAccessible) NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY, nsIAccessible **aAccessible)
{ *aAccessible = this; return NS_OK; } // Don't walk into these { NS_ENSURE_ARG_POINTER(aAccessible); NS_ADDREF(*aAccessible = this); return NS_OK; } // Don't walk into these
}; };
/** /**

Просмотреть файл

@ -731,7 +731,7 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
else else
#endif #endif
if (eventType.EqualsLiteral("focus")) { if (eventType.EqualsLiteral("focus")) {
if (aTargetNode == mDOMNode) { if (aTargetNode == mDOMNode && mDOMNode != gLastFocusedNode) {
// Got focus event for the window, we will make sure that an accessible // Got focus event for the window, we will make sure that an accessible
// focus event for initial focus is fired. We do this on a short timer // focus event for initial focus is fired. We do this on a short timer
// because the initial focus may not have been set yet. // because the initial focus may not have been set yet.
@ -847,8 +847,15 @@ nsresult nsRootAccessible::HandleEventWithTarget(nsIDOMEvent* aEvent,
NS_ENSURE_TRUE(containerAccessible, NS_ERROR_FAILURE); NS_ENSURE_TRUE(containerAccessible, NS_ERROR_FAILURE);
// It is not top level menuitem // It is not top level menuitem
// Only fire focus event if it is not inside collapsed popup // Only fire focus event if it is not inside collapsed popup
if (State(containerAccessible) & nsIAccessibleStates::STATE_COLLAPSED) // and not a listitem of a combo box
return NS_OK; if (State(containerAccessible) & nsIAccessibleStates::STATE_COLLAPSED) {
nsCOMPtr<nsIAccessible> containerParent;
containerAccessible->GetParent(getter_AddRefs(containerParent));
NS_ENSURE_TRUE(containerParent, NS_ERROR_FAILURE);
if (Role(containerParent) != nsIAccessibleRole::ROLE_COMBOBOX) {
return NS_OK;
}
}
} }
} }
nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE); // Always asynch, always from user input nsAccEvent::PrepareForEvent(aTargetNode, PR_TRUE); // Always asynch, always from user input

Просмотреть файл

@ -57,7 +57,7 @@ public:
NS_IMETHOD GetDescription(nsAString& _retval); NS_IMETHOD GetDescription(nsAString& _retval);
NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height); NS_IMETHOD GetBounds(PRInt32 *x, PRInt32 *y, PRInt32 *width, PRInt32 *height);
NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY, nsIAccessible **aAccessible) NS_IMETHOD GetChildAtPoint(PRInt32 aX, PRInt32 aY, nsIAccessible **aAccessible)
{ *aAccessible = this; return NS_OK; } // Don't walk into these { NS_ENSURE_ARG_POINTER(aAccessible); NS_ADDREF(*aAccessible = this); return NS_OK; } // Don't walk into these
}; };
#endif #endif

Просмотреть файл

@ -849,7 +849,10 @@ nsHTMLTableAccessible::GetTableLayout(nsITableLayout **aLayoutObject)
nsCOMPtr<nsIContent> content(do_QueryInterface(tableNode)); nsCOMPtr<nsIContent> content(do_QueryInterface(tableNode));
NS_ENSURE_TRUE(content, NS_ERROR_FAILURE); NS_ENSURE_TRUE(content, NS_ERROR_FAILURE);
nsIPresShell *presShell = content->GetDocument()->GetPrimaryShell(); nsIDocument *doc = content->GetDocument();
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
nsIPresShell *presShell = doc->GetPrimaryShell();
nsCOMPtr<nsISupports> layoutObject; nsCOMPtr<nsISupports> layoutObject;
rv = presShell->GetLayoutObjectFor(content, getter_AddRefs(layoutObject)); rv = presShell->GetLayoutObjectFor(content, getter_AddRefs(layoutObject));

Просмотреть файл

@ -200,8 +200,6 @@ pref("browser.urlbar.doubleClickSelectsAll", false);
#endif #endif
pref("browser.urlbar.autoFill", false); pref("browser.urlbar.autoFill", false);
pref("browser.urlbar.matchOnlyTyped", false); pref("browser.urlbar.matchOnlyTyped", false);
pref("browser.urlbar.hideProtocols", "");
pref("browser.urlbar.animateBlend", true);
pref("browser.download.useDownloadDir", true); pref("browser.download.useDownloadDir", true);
pref("browser.download.folderList", 0); pref("browser.download.folderList", 0);
@ -380,7 +378,7 @@ pref("mousewheel.withmetakey.action",0);
pref("mousewheel.withmetakey.sysnumlines",true); pref("mousewheel.withmetakey.sysnumlines",true);
pref("mousewheel.withmetakey.numlines",1); pref("mousewheel.withmetakey.numlines",1);
#endif #endif
pref("mousewheel.withcontrolkey.action",3); pref("mousewheel.withcontrolkey.action",5);
pref("mousewheel.withcontrolkey.sysnumlines",false); pref("mousewheel.withcontrolkey.sysnumlines",false);
pref("mousewheel.withcontrolkey.numlines",1); pref("mousewheel.withcontrolkey.numlines",1);
@ -443,11 +441,7 @@ pref("browser.preferences.instantApply", false);
#else #else
pref("browser.preferences.instantApply", true); pref("browser.preferences.instantApply", true);
#endif #endif
#ifdef XP_MACOSX
pref("browser.preferences.animateFadeIn", true);
#else
pref("browser.preferences.animateFadeIn", false); pref("browser.preferences.animateFadeIn", false);
#endif
pref("browser.download.show_plugins_in_list", true); pref("browser.download.show_plugins_in_list", true);
pref("browser.download.hide_plugins_without_extensions", true); pref("browser.download.hide_plugins_without_extensions", true);
@ -545,6 +539,10 @@ pref("browser.safebrowsing.provider.0.reportPhishURL", "http://{moz:locale}.phis
// FAQ URL // FAQ URL
pref("browser.safebrowsing.warning.infoURL", "http://%LOCALE%.www.mozilla.com/%LOCALE%/firefox/phishing-protection/"); pref("browser.safebrowsing.warning.infoURL", "http://%LOCALE%.www.mozilla.com/%LOCALE%/firefox/phishing-protection/");
// Name of the about: page contributed by safebrowsing to handle display of error
// pages on phishing/malware hits. (bug 399233)
pref("urlclassifier.alternate_error_page", "blocked");
#endif #endif
// defaults to true // defaults to true
@ -574,8 +572,5 @@ pref("accessibility.blockautorefresh", false);
// import bookmarks.html into Places bookmarks // import bookmarks.html into Places bookmarks
pref("browser.places.importBookmarksHTML", true); pref("browser.places.importBookmarksHTML", true);
// Show infobar on chromeless windows
pref("browser.warn_chromeless_window.infobar", false);
// if false, will add the "Places" folder to the personal toolbar // if false, will add the "Places" folder to the personal toolbar
pref("browser.places.createdDefaultQueries", false); pref("browser.places.createdDefaultQueries", false);

Просмотреть файл

@ -1,5 +1,8 @@
#aboutDialog { #aboutDialog {
padding: 0px 0px 10px 0px; padding-top: 0;
-moz-padding-end: 0;
padding-bottom: 10px;
-moz-padding-start: 0;
width: 299px; width: 299px;
} }
@ -20,53 +23,71 @@
} }
#userAgent { #userAgent {
margin: 11px 20px 0px 13px; margin-top: 11px;
-moz-margin-end: 20px;
margin-bottom: 0;
-moz-margin-start: 13px;
background-color: #FFFFFF; background-color: #FFFFFF;
color: #000000; color: #000000;
padding: 1px 0px 0px 3px; padding-top: 1px;
-moz-padding-end: 0;
padding-bottom: 0;
-moz-padding-start: 3px;
-moz-appearance: none; -moz-appearance: none;
overflow: hidden; overflow: hidden;
border: 0px; border: 0;
} }
#groove { #groove {
margin-top: 0px; margin-top: 0;
} }
#creditsIframe { #creditsIframe {
cursor: default; cursor: default;
-moz-user-select: none; -moz-user-select: none;
border: 0px; border: 0;
} }
#version { #version {
font-weight: bold; font-weight: bold;
color: #909090; color: #909090;
margin: 1em 0px 10px 17px; margin-top: 1em;
-moz-margin-end: 0;
margin-bottom: 10px;
-moz-margin-start: 17px;
} }
#distribution { #distribution {
font-weight: bold; font-weight: bold;
color: #909090; color: #909090;
display: none; display: none;
margin: 0em 0px 0px 17px; margin-top: 0;
-moz-margin-end: 0;
margin-bottom: 0;
-moz-margin-start: 17px;
} }
#distributionId { #distributionId {
font-weight: bold; font-weight: bold;
color: #909090; color: #909090;
display: none; display: none;
margin: 0em 0px 10px 17px; margin-top: 0;
-moz-margin-end: 0;
margin-bottom: 10px;
-moz-margin-start: 17px;
} }
#copyright { #copyright {
margin: 0px 0px 3px 16px; margin-top: 0;
-moz-margin-end: 0;
margin-bottom: 3px;
-moz-margin-start: 16px;
} }
button[dlgtype="extra2"] { button[dlgtype="extra2"] {
margin-left: 13px; -moz-margin-start: 13px;
} }
button[dlgtype="accept"] { button[dlgtype="accept"] {
margin-right: 13px; -moz-margin-end: 13px;
} }

Просмотреть файл

@ -171,15 +171,15 @@
#endif #endif
<menuitem label="&reloadCmd.label;" accesskey="&reloadCmd.accesskey;" command="Browser:Reload" key="key_reload"/> <menuitem label="&reloadCmd.label;" accesskey="&reloadCmd.accesskey;" command="Browser:Reload" key="key_reload"/>
<menuseparator/> <menuseparator/>
<menu id="viewTextZoomMenu" label="&textSize.label;" accesskey="&textSize.accesskey;" observes="isImage"> <menu id="viewFullZoomMenu" label="&fullZoom.label;" accesskey="&fullZoom.accesskey;" observes="isImage">
<menupopup> <menupopup>
<menuitem key="key_textZoomEnlarge" label="&textZoomEnlargeCmd.label;" accesskey="&textZoomEnlargeCmd.accesskey;" <menuitem key="key_fullZoomEnlarge" label="&fullZoomEnlargeCmd.label;" accesskey="&fullZoomEnlargeCmd.accesskey;"
command="cmd_textZoomEnlarge"/> command="cmd_fullZoomEnlarge"/>
<menuitem key="key_textZoomReduce" label="&textZoomReduceCmd.label;" accesskey="&textZoomReduceCmd.accesskey;" <menuitem key="key_fullZoomReduce" label="&fullZoomReduceCmd.label;" accesskey="&fullZoomReduceCmd.accesskey;"
command="cmd_textZoomReduce"/> command="cmd_fullZoomReduce"/>
<menuseparator/> <menuseparator/>
<menuitem key="key_textZoomReset" label="&textZoomResetCmd.label;" accesskey="&textZoomResetCmd.accesskey;" <menuitem key="key_fullZoomReset" label="&fullZoomResetCmd.label;" accesskey="&fullZoomResetCmd.accesskey;"
command="cmd_textZoomReset"/> command="cmd_fullZoomReset"/>
</menupopup> </menupopup>
</menu> </menu>
<menu id="pageStyleMenu" label="&pageStyleMenu.label;" accesskey="&pageStyleMenu.accesskey;" observes="isImage"> <menu id="pageStyleMenu" label="&pageStyleMenu.label;" accesskey="&pageStyleMenu.accesskey;" observes="isImage">

Просмотреть файл

@ -50,7 +50,11 @@ var PlacesCommandHook = {
// Edit-bookmark panel // Edit-bookmark panel
get panel() { get panel() {
return document.getElementById("editBookmarkPanel"); delete this.panel;
var element = document.getElementById("editBookmarkPanel");
element.addEventListener("popuphiding", this, false);
element.addEventListener("keypress", this, true);
return this.panel = element;
}, },
// list of command elements (by id) to disable when the panel is opened // list of command elements (by id) to disable when the panel is opened
@ -129,13 +133,15 @@ var PlacesCommandHook = {
this._overlayLoading = true; this._overlayLoading = true;
document.loadOverlay("chrome://browser/content/places/editBookmarkOverlay.xul", document.loadOverlay("chrome://browser/content/places/editBookmarkOverlay.xul",
loadObserver); loadObserver);
this.panel.addEventListener("popuphiding", this, false);
}, },
_doShowEditBookmarkPanel: _doShowEditBookmarkPanel:
function PCH__doShowEditBookmarkPanel(aItemId, aAnchorElement, aPosition) { function PCH__doShowEditBookmarkPanel(aItemId, aAnchorElement, aPosition) {
this.panel.addEventListener("keypress", this, true);
this._blockCommands(); // un-done in the popuphiding handler this._blockCommands(); // un-done in the popuphiding handler
// Consume dismiss clicks, see bug 400924
this.panel.popupBoxObject
.setConsumeRollupEvent(Ci.nsIPopupBoxObject.ROLLUP_CONSUME);
this.panel.openPopup(aAnchorElement, aPosition, -1, -1); this.panel.openPopup(aAnchorElement, aPosition, -1, -1);
gEditItemOverlay.initPanel(aItemId, gEditItemOverlay.initPanel(aItemId,
@ -405,7 +411,7 @@ var BookmarksEventHandler = {
node.localName == "menupopup")) { node.localName == "menupopup")) {
if (node.localName == "menupopup") if (node.localName == "menupopup")
node.hidePopup(); node.hidePopup();
node = node.parentNode; node = node.parentNode;
} }
} }
@ -415,9 +421,9 @@ var BookmarksEventHandler = {
// separately. // separately.
var bookmarksBar = document.getElementById("bookmarksBarContent"); var bookmarksBar = document.getElementById("bookmarksBarContent");
if (bookmarksBar._chevron.getAttribute("open") == "true") if (bookmarksBar._chevron.getAttribute("open") == "true")
bookmarksBar._chevron.firstChild.hidePopupAndChildPopups(); bookmarksBar._chevron.firstChild.hidePopup();
}, },
/** /**
* Handler for command event for an item in the bookmarks toolbar. * Handler for command event for an item in the bookmarks toolbar.
* Menus and submenus from the folder buttons bubble up to this handler. * Menus and submenus from the folder buttons bubble up to this handler.
@ -426,17 +432,12 @@ var BookmarksEventHandler = {
* DOMEvent for the command * DOMEvent for the command
*/ */
onCommand: function BM_onCommand(aEvent) { onCommand: function BM_onCommand(aEvent) {
// If this is the special "Open All in Tabs" menuitem,
// load all the menuitems in tabs.
var target = aEvent.originalTarget; var target = aEvent.originalTarget;
if (target.hasAttribute("siteURI")) if (target.node) {
openUILink(target.getAttribute("siteURI"), aEvent);
// If this is a normal bookmark, just load the bookmark's URI.
else if (!target.hasAttribute("openInTabs"))
PlacesUtils.getViewForNode(target) PlacesUtils.getViewForNode(target)
.controller .controller
.openSelectedNodeWithEvent(aEvent); .openSelectedNodeWithEvent(aEvent);
}
}, },
/** /**
@ -456,7 +457,6 @@ var BookmarksEventHandler = {
// Add the "Open (Feed Name)" menuitem if it's a livemark with a siteURI. // Add the "Open (Feed Name)" menuitem if it's a livemark with a siteURI.
var numNodes = 0; var numNodes = 0;
var hasMultipleEntries = false; var hasMultipleEntries = false;
var hasFeedHomePage = false;
var currentChild = target.firstChild; var currentChild = target.firstChild;
while (currentChild) { while (currentChild) {
if (currentChild.localName == "menuitem" && currentChild.node) if (currentChild.localName == "menuitem" && currentChild.node)
@ -473,32 +473,35 @@ var BookmarksEventHandler = {
if (numNodes > 1) if (numNodes > 1)
hasMultipleEntries = true; hasMultipleEntries = true;
var button = target.parentNode; var itemId = target._resultNode.itemId;
if (button.getAttribute("livemark") == "true" && var siteURIString = "";
button.hasAttribute("siteURI")) if (itemId != -1 && PlacesUtils.livemarks.isLivemark(itemId)) {
hasFeedHomePage = true; var siteURI = PlacesUtils.livemarks.getSiteURI(itemId);
if (siteURI)
siteURIString = siteURI.spec;
}
if (hasMultipleEntries || hasFeedHomePage) { if (hasMultipleEntries || siteURIString) {
var separator = document.createElement("menuseparator"); var separator = document.createElement("menuseparator");
target.appendChild(separator); target.appendChild(separator);
if (hasFeedHomePage) { if (siteURIString) {
var openHomePage = document.createElement("menuitem"); var openHomePage = document.createElement("menuitem");
openHomePage.setAttribute( openHomePage.setAttribute("siteURI", siteURIString);
"siteURI", button.getAttribute("siteURI")); openHomePage.setAttribute("oncommand",
"openUILink(this.getAttribute('siteURI'), event);");
openHomePage.setAttribute( openHomePage.setAttribute(
"label", "label",
PlacesUtils.getFormattedString("menuOpenLivemarkOrigin.label", PlacesUtils.getFormattedString("menuOpenLivemarkOrigin.label",
[button.getAttribute("label")])); [target.parentNode.getAttribute("label")]));
target.appendChild(openHomePage); target.appendChild(openHomePage);
} }
if (hasMultipleEntries) { if (hasMultipleEntries) {
var openInTabs = document.createElement("menuitem"); var openInTabs = document.createElement("menuitem");
openInTabs.setAttribute("openInTabs", "true"); openInTabs.setAttribute("openInTabs", "true");
openInTabs.setAttribute("onclick", "checkForMiddleClick(this, event)");
openInTabs.setAttribute("oncommand", openInTabs.setAttribute("oncommand",
"PlacesUtils.openContainerNodeInTabs(this.parentNode.getResultNode(), event);"); "PlacesUtils.openContainerNodeInTabs(this.parentNode._resultNode, event);");
openInTabs.setAttribute("label", openInTabs.setAttribute("label",
gNavigatorBundle.getString("menuOpenAllInTabs.label")); gNavigatorBundle.getString("menuOpenAllInTabs.label"));
target.appendChild(openInTabs); target.appendChild(openInTabs);
@ -703,19 +706,19 @@ var PlacesMenuDNDController = {
// Close the bookmarks menu // Close the bookmarks menu
var bookmarksMenu = document.getElementById("bookmarksMenu"); var bookmarksMenu = document.getElementById("bookmarksMenu");
bookmarksMenu.firstChild.hidePopupAndChildPopups(); bookmarksMenu.firstChild.hidePopup();
var bookmarksBar = document.getElementById("bookmarksBarContent"); var bookmarksBar = document.getElementById("bookmarksBarContent");
if (bookmarksBar) { if (bookmarksBar) {
// Close the overflow chevron menu and all its children // Close the overflow chevron menu and all its children
bookmarksBar._chevron.firstChild.hidePopupAndChildPopups(); bookmarksBar._chevron.firstChild.hidePopup();
// Close all popups on the bookmarks toolbar // Close all popups on the bookmarks toolbar
var toolbarItems = bookmarksBar.childNodes; var toolbarItems = bookmarksBar.childNodes;
for (var i = 0; i < toolbarItems.length; ++i) { for (var i = 0; i < toolbarItems.length; ++i) {
var item = toolbarItems[i] var item = toolbarItems[i]
if (this._isContainer(item)) if (this._isContainer(item))
item.firstChild.hidePopupAndChildPopups(); item.firstChild.hidePopup();
} }
} }
}, },

Просмотреть файл

@ -101,9 +101,9 @@
<command id="Browser:Stop" oncommand="BrowserStop();" disabled="true"/> <command id="Browser:Stop" oncommand="BrowserStop();" disabled="true"/>
<command id="Browser:Reload" oncommand="if (event.shiftKey) BrowserReloadSkipCache(); else BrowserReload()" disabled="true"/> <command id="Browser:Reload" oncommand="if (event.shiftKey) BrowserReloadSkipCache(); else BrowserReload()" disabled="true"/>
<command id="Browser:ReloadSkipCache" oncommand="BrowserReloadSkipCache()" disabled="true"/> <command id="Browser:ReloadSkipCache" oncommand="BrowserReloadSkipCache()" disabled="true"/>
<command id="cmd_textZoomReduce" oncommand="TextZoom.reduce()"/> <command id="cmd_fullZoomReduce" oncommand="FullZoom.reduce()"/>
<command id="cmd_textZoomEnlarge" oncommand="TextZoom.enlarge()"/> <command id="cmd_fullZoomEnlarge" oncommand="FullZoom.enlarge()"/>
<command id="cmd_textZoomReset" oncommand="TextZoom.reset()"/> <command id="cmd_fullZoomReset" oncommand="FullZoom.reset()"/>
<command id="Browser:OpenLocation" oncommand="openLocation();"/> <command id="Browser:OpenLocation" oncommand="openLocation();"/>
<command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/> <command id="Tools:Search" oncommand="BrowserSearch.webSearch();"/>
@ -286,10 +286,10 @@
#endif #endif
command="viewHistorySidebar"/> command="viewHistorySidebar"/>
<key id="key_textZoomReduce" key="&textZoomReduceCmd.commandkey;" command="cmd_textZoomReduce" modifiers="accel"/> <key id="key_fullZoomReduce" key="&fullZoomReduceCmd.commandkey;" command="cmd_fullZoomReduce" modifiers="accel"/>
<key id="key_textZoomEnlarge" key="&textZoomEnlargeCmd.commandkey;" command="cmd_textZoomEnlarge" modifiers="accel"/> <key id="key_fullZoomEnlarge" key="&fullZoomEnlargeCmd.commandkey;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
<key key="&textZoomEnlargeCmd.commandkey2;" command="cmd_textZoomEnlarge" modifiers="accel"/> <key key="&fullZoomEnlargeCmd.commandkey2;" command="cmd_fullZoomEnlarge" modifiers="accel"/>
<key id="key_textZoomReset" key="&textZoomResetCmd.commandkey;" command="cmd_textZoomReset" modifiers="accel"/> <key id="key_fullZoomReset" key="&fullZoomResetCmd.commandkey;" command="cmd_fullZoomReset" modifiers="accel"/>
<key id="key_switchTextDirection" key="&bidiSwitchTextDirectionItem.commandkey;" command="cmd_switchTextDirection" modifiers="accel,shift" /> <key id="key_switchTextDirection" key="&bidiSwitchTextDirectionItem.commandkey;" command="cmd_switchTextDirection" modifiers="accel,shift" />

Просмотреть файл

@ -21,6 +21,7 @@
* *
* Contributor(s): * Contributor(s):
* Myk Melez <myk@mozilla.org> * Myk Melez <myk@mozilla.org>
* Dão Gottwald <dao@mozilla.com>
* *
* Alternatively, the contents of this file may be used under the terms of * Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or * either the GNU General Public License Version 2 or later (the "GPL"), or
@ -41,58 +42,35 @@
// From nsMouseScrollEvent::kIsHorizontal // From nsMouseScrollEvent::kIsHorizontal
const MOUSE_SCROLL_IS_HORIZONTAL = 1 << 2; const MOUSE_SCROLL_IS_HORIZONTAL = 1 << 2;
// Not sure where this comes from. It's one of the possible values // One of the possible values for the mousewheel.* preferences.
// for the mousewheel.* preferences. // From nsEventStateManager.cpp.
const MOUSE_SCROLL_TEXTSIZE = 3; const MOUSE_SCROLL_FULLZOOM = 5;
/** /**
* Controls the "text zoom" setting and its site-specific preferences. * Controls the "full zoom" setting and its site-specific preferences.
*/ */
var TextZoom = { var FullZoom = {
//**************************************************************************// //**************************************************************************//
// Name & Values // Name & Values
// The name of the setting. Identifies the setting in the prefs database. // The name of the setting. Identifies the setting in the prefs database.
name: "browser.content.text-zoom", name: "browser.content.full-zoom",
// The global value (if any) for the setting. Retrieved from the prefs // The global value (if any) for the setting. Retrieved from the prefs
// database when this handler gets initialized, then updated as it changes. // database when this handler gets initialized, then updated as it changes.
// If there is no global value, then this should be undefined. // If there is no global value, then this should be undefined.
globalValue: undefined, globalValue: undefined,
// From viewZoomOverlay.js
minValue: 1,
maxValue: 2000,
defaultValue: 100,
//**************************************************************************// //**************************************************************************//
// Convenience Getters // Convenience Getters
__zoomManager: null,
get _zoomManager() {
if (!this.__zoomManager)
this.__zoomManager = ZoomManager.prototype.getInstance();
return this.__zoomManager;
},
// Content Pref Service // Content Pref Service
__cps: null,
get _cps() { get _cps() {
if (!this.__cps) delete this._cps;
this.__cps = Cc["@mozilla.org/content-pref/service;1"]. return this._cps = Cc["@mozilla.org/content-pref/service;1"].
getService(Ci.nsIContentPrefService); getService(Ci.nsIContentPrefService);
return this.__cps;
},
// Pref Branch
__prefBranch: null,
get _prefBranch() {
if (!this.__prefBranch)
this.__prefBranch = Cc["@mozilla.org/preferences-service;1"].
getService(Ci.nsIPrefBranch);
return this.__prefBranch;
}, },
@ -104,8 +82,8 @@ var TextZoom = {
Components.interfaces.nsIContentPrefObserver, Components.interfaces.nsIContentPrefObserver,
Components.interfaces.nsISupports], Components.interfaces.nsISupports],
QueryInterface: function TextZoom_QueryInterface(aIID) { QueryInterface: function (aIID) {
if (!this.interfaces.some( function(v) { return aIID.equals(v) } )) if (!this.interfaces.some(function (v) aIID.equals(v)))
throw Cr.NS_ERROR_NO_INTERFACE; throw Cr.NS_ERROR_NO_INTERFACE;
return this; return this;
}, },
@ -114,7 +92,7 @@ var TextZoom = {
//**************************************************************************// //**************************************************************************//
// Initialization & Destruction // Initialization & Destruction
init: function TextZoom_init() { init: function () {
// Listen for scrollwheel events so we can save scrollwheel-based changes. // Listen for scrollwheel events so we can save scrollwheel-based changes.
window.addEventListener("DOMMouseScroll", this, false); window.addEventListener("DOMMouseScroll", this, false);
@ -129,7 +107,7 @@ var TextZoom = {
this._applyPrefToSetting(); this._applyPrefToSetting();
}, },
destroy: function TextZoom_destroy() { destroy: function () {
ContentPrefSink.removeObserver(this.name, this); ContentPrefSink.removeObserver(this.name, this);
this._cps.removeObserver(this.name, this); this._cps.removeObserver(this.name, this);
window.removeEventListener("DOMMouseScroll", this, false); window.removeEventListener("DOMMouseScroll", this, false);
@ -149,12 +127,15 @@ var TextZoom = {
// nsIDOMEventListener // nsIDOMEventListener
handleEvent: function TextZoom_handleEvent(event) { handleEvent: function (event) {
// The only events we handle are DOMMouseScroll events. switch (event.type) {
this._handleMouseScrolled(event); case "DOMMouseScroll":
this._handleMouseScrolled(event);
break;
}
}, },
_handleMouseScrolled: function TextZoom__handleMouseScrolled(event) { _handleMouseScrolled: function (event) {
// Construct the "mousewheel action" pref key corresponding to this event. // Construct the "mousewheel action" pref key corresponding to this event.
// Based on nsEventStateManager::GetBasePrefKeyForMouseWheel. // Based on nsEventStateManager::GetBasePrefKeyForMouseWheel.
var pref = "mousewheel"; var pref = "mousewheel";
@ -174,8 +155,12 @@ var TextZoom = {
pref += ".action"; pref += ".action";
// Don't do anything if this isn't a "change text size" scroll event. // Don't do anything if this isn't a "zoom" scroll event.
if (this._getAppPref(pref, null) != MOUSE_SCROLL_TEXTSIZE) var isZoomEvent = false;
try {
isZoomEvent = (gPrefService.getIntPref(pref) == MOUSE_SCROLL_FULLZOOM);
} catch (e) {}
if (!isZoomEvent)
return; return;
// XXX Lazily cache all the possible action prefs so we don't have to get // XXX Lazily cache all the possible action prefs so we don't have to get
@ -185,12 +170,12 @@ var TextZoom = {
// We have to call _applySettingToPref in a timeout because we handle // We have to call _applySettingToPref in a timeout because we handle
// the event before the event state manager has a chance to apply the zoom // the event before the event state manager has a chance to apply the zoom
// during nsEventStateManager::PostHandleEvent. // during nsEventStateManager::PostHandleEvent.
window.setTimeout(function() { TextZoom._applySettingToPref() }, 0); window.setTimeout(function (self) { self._applySettingToPref() }, 0, this);
}, },
// nsIContentPrefObserver // nsIContentPrefObserver
onContentPrefSet: function TextZoom_onContentPrefSet(aGroup, aName, aValue) { onContentPrefSet: function (aGroup, aName, aValue) {
if (aGroup == this._cps.grouper.group(gBrowser.currentURI)) if (aGroup == this._cps.grouper.group(gBrowser.currentURI))
this._applyPrefToSetting(aValue); this._applyPrefToSetting(aValue);
else if (aGroup == null) { else if (aGroup == null) {
@ -204,7 +189,7 @@ var TextZoom = {
} }
}, },
onContentPrefRemoved: function TextZoom_onContentPrefRemoved(aGroup, aName) { onContentPrefRemoved: function (aGroup, aName) {
if (aGroup == this._cps.grouper.group(gBrowser.currentURI)) if (aGroup == this._cps.grouper.group(gBrowser.currentURI))
this._applyPrefToSetting(); this._applyPrefToSetting();
else if (aGroup == null) { else if (aGroup == null) {
@ -220,7 +205,7 @@ var TextZoom = {
// ContentPrefSink observer // ContentPrefSink observer
onLocationChanged: function TextZoom_onLocationChanged(aURI, aName, aValue) { onLocationChanged: function (aURI, aName, aValue) {
this._applyPrefToSetting(aValue); this._applyPrefToSetting(aValue);
}, },
@ -228,35 +213,35 @@ var TextZoom = {
//**************************************************************************// //**************************************************************************//
// Setting & Pref Manipulation // Setting & Pref Manipulation
reduce: function TextZoom_reduce() { reduce: function () {
this._zoomManager.reduce(); ZoomManager.reduce();
this._applySettingToPref(); this._applySettingToPref();
}, },
enlarge: function TextZoom_enlarge() { enlarge: function () {
this._zoomManager.enlarge(); ZoomManager.enlarge();
this._applySettingToPref(); this._applySettingToPref();
}, },
reset: function TextZoom_reset() { reset: function () {
if (typeof this.globalValue != "undefined") if (typeof this.globalValue != "undefined")
this._zoomManager.textZoom = this.globalValue; ZoomManager.fullZoom = this.globalValue;
else else
this._zoomManager.reset(); ZoomManager.reset();
this._removePref(); this._removePref();
}, },
/** /**
* Set the text zoom for the current tab. * Set the zoom level for the current tab.
* *
* Per DocumentViewerImpl::SetTextZoom in nsDocumentViewer.cpp, it looks * Per DocumentViewerImpl::SetFullZoom in nsDocumentViewer.cpp, it looks
* like we can set the zoom to its current value without significant impact * like we can set the zoom to its current value without significant impact
* on performance, as the setting is only applied if it differs from the * on performance, as the setting is only applied if it differs from the
* current setting. * current setting.
* *
* And perhaps we should always set the zoom even if it were to incur * And perhaps we should always set the zoom even if it were to incur
* a performance penalty, since SetTextZoom claims that child documents * a performance penalty, since SetFullZoom claims that child documents
* may have a different zoom under unusual circumstances, and it implies * may have a different zoom under unusual circumstances, and it implies
* that those child zooms should get updated when the parent zoom gets set. * that those child zooms should get updated when the parent zoom gets set.
* *
@ -264,26 +249,26 @@ var TextZoom = {
* We don't check first to see if the new value is the same as the current * We don't check first to see if the new value is the same as the current
* one. * one.
**/ **/
_applyPrefToSetting: function TextZoom__applyPrefToSetting(aValue) { _applyPrefToSetting: function (aValue) {
// Bug 375918 means this will sometimes throw, so we catch it // Bug 375918 means this will sometimes throw, so we catch it
// and don't do anything in those cases. // and don't do anything in those cases.
try { try {
if (typeof aValue != "undefined") if (typeof aValue != "undefined")
this._zoomManager.textZoom = this._ensureValid(aValue); ZoomManager.fullZoom = this._ensureValid(aValue);
else if (typeof this.globalValue != "undefined") else if (typeof this.globalValue != "undefined")
this._zoomManager.textZoom = this.globalValue; ZoomManager.fullZoom = this.globalValue;
else else
this._zoomManager.reset(); ZoomManager.reset();
} }
catch(ex) {} catch(ex) {}
}, },
_applySettingToPref: function TextZoom__applySettingToPref() { _applySettingToPref: function () {
var textZoom = this._zoomManager.textZoom; var fullZoom = ZoomManager.fullZoom;
this._cps.setPref(gBrowser.currentURI, this.name, textZoom); this._cps.setPref(gBrowser.currentURI, this.name, fullZoom);
}, },
_removePref: function TextZoom__removePref() { _removePref: function () {
this._cps.removePref(gBrowser.currentURI, this.name); this._cps.removePref(gBrowser.currentURI, this.name);
}, },
@ -291,41 +276,16 @@ var TextZoom = {
//**************************************************************************// //**************************************************************************//
// Utilities // Utilities
_ensureValid: function TextZoom__ensureValid(aValue) { _ensureValid: function (aValue) {
if (isNaN(aValue)) if (isNaN(aValue))
return this.defaultValue; return 1;
if (aValue < this.minValue) if (aValue < ZoomManager.MIN)
return this.minValue; return ZoomManager.MIN;
if (aValue > this.maxValue) if (aValue > ZoomManager.MAX)
return this.maxValue; return ZoomManager.MAX;
return aValue; return aValue;
},
/**
* Get a value from a pref or a default value if the pref doesn't exist.
*
* @param aPrefName
* @param aDefaultValue
* @returns the pref's value or the default (if it is missing)
*/
_getAppPref: function TextZoom__getAppPref(aPrefName, aDefaultValue) {
try {
switch (this._prefBranch.getPrefType(aPrefName)) {
case this._prefBranch.PREF_STRING:
return this._prefBranch.getCharPref(aPrefName);
case this._prefBranch.PREF_BOOL:
return this._prefBranch.getBoolPref(aPrefName);
case this._prefBranch.PREF_INT:
return this._prefBranch.getIntPref(aPrefName);
}
}
catch (ex) { /* return the default value */ }
return aDefaultValue;
} }
}; };

Просмотреть файл

@ -362,7 +362,7 @@ function initPlacesDefaultQueries() {
var recentlyCreatedBookmarksItem = bmsvc.insertBookmark(placesFolder, var recentlyCreatedBookmarksItem = bmsvc.insertBookmark(placesFolder,
IO.newURI("place:folder=" + bookmarksRoot + "&folder=" + unfiledRoot + IO.newURI("place:folder=" + bookmarksRoot + "&folder=" + unfiledRoot +
"&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS + "&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS +
"&sort=" + "&sort=" +
Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING + Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING +
"&excludeItemIfParentHasAnnotation=livemark%2FfeedURI" + "&excludeItemIfParentHasAnnotation=livemark%2FfeedURI" +
"&maxResults=" + maxResults + "&maxResults=" + maxResults +
@ -372,15 +372,17 @@ function initPlacesDefaultQueries() {
var recentlyVisitedBookmarksItem = bmsvc.insertBookmark(placesFolder, var recentlyVisitedBookmarksItem = bmsvc.insertBookmark(placesFolder,
IO.newURI("place:folder=" + bookmarksRoot + "&folder=" + unfiledRoot + IO.newURI("place:folder=" + bookmarksRoot + "&folder=" + unfiledRoot +
"&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS + "&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS +
"&sort=" + Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING + "&sort=" + Ci.nsINavHistoryQueryOptions.SORT_BY_DATE_DESCENDING +
"&excludeItemIfParentHasAnnotation=livemark%2FfeedURI" +
"&minVisits=1&maxResults=" + maxResults), "&minVisits=1&maxResults=" + maxResults),
defaultIndex, recentlyVisitedBookmarksTitle); defaultIndex, recentlyVisitedBookmarksTitle);
var mostVisitedBookmarksItem = bmsvc.insertBookmark(placesFolder, var mostVisitedBookmarksItem = bmsvc.insertBookmark(placesFolder,
IO.newURI("place:folder=" + bookmarksRoot + "&folder=" + unfiledRoot + IO.newURI("place:folder=" + bookmarksRoot + "&folder=" + unfiledRoot +
"&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS + "&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS +
"&sort=" + "&sort=" +
Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING + Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING +
"&excludeItemIfParentHasAnnotation=livemark%2FfeedURI" +
"&minVisits=1&maxResults=" + maxResults), "&minVisits=1&maxResults=" + maxResults),
defaultIndex, mostVisitedBookmarksTitle); defaultIndex, mostVisitedBookmarksTitle);
@ -388,28 +390,28 @@ function initPlacesDefaultQueries() {
IO.newURI("place:folder=" + tagRoot + IO.newURI("place:folder=" + tagRoot +
"&group=" + Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER + "&group=" + Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER +
"&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS + "&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS +
"&applyOptionsToContainers=1" + "&applyOptionsToContainers=1" +
"&sort=" + "&sort=" +
Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING + Ci.nsINavHistoryQueryOptions.SORT_BY_DATEADDED_DESCENDING +
"&resolveNullBookmarkTitles=1" + "&resolveNullBookmarkTitles=1" +
"&maxResults=" + maxResults), "&maxResults=" + maxResults),
defaultIndex, recentlyUsedTagsTitle); defaultIndex, recentlyUsedTagsTitle);
var mostUsedTagsItem = bmsvc.insertBookmark(placesFolder, var mostUsedTagsItem = bmsvc.insertBookmark(placesFolder,
IO.newURI("place:folder=" + tagRoot + IO.newURI("place:folder=" + tagRoot +
"&group=" + Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER + "&group=" + Ci.nsINavHistoryQueryOptions.GROUP_BY_FOLDER +
"&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS + "&queryType=" + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_BOOKMARKS +
"&applyOptionsToContainers=1" + "&applyOptionsToContainers=1" +
"&sort=" + Ci.nsINavHistoryQueryOptions.SORT_BY_COUNT_DESCENDING + "&sort=" + Ci.nsINavHistoryQueryOptions.SORT_BY_COUNT_DESCENDING +
"&resolveNullBookmarkTitles=1" + "&resolveNullBookmarkTitles=1" +
"&maxResults=" + maxResults), "&maxResults=" + maxResults),
defaultIndex, mostUsedTagsTitle); defaultIndex, mostUsedTagsTitle);
var mostVisitedSitesItem = bmsvc.insertBookmark(placesFolder, var mostVisitedSitesItem = bmsvc.insertBookmark(placesFolder,
IO.newURI("place:queryType=" + IO.newURI("place:queryType=" +
Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY + Ci.nsINavHistoryQueryOptions.QUERY_TYPE_HISTORY +
"&sort=" + "&sort=" +
Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING + Ci.nsINavHistoryQueryOptions.SORT_BY_VISITCOUNT_DESCENDING +
"&maxResults=" + maxResults), "&maxResults=" + maxResults),
defaultIndex, mostVisitedSitesTitle); defaultIndex, mostVisitedSitesTitle);
} }
@ -1164,7 +1166,7 @@ function delayedStartup()
// apply text zoom settings to tabs restored by the session restore service. // apply text zoom settings to tabs restored by the session restore service.
try { try {
ContentPrefSink.init(); ContentPrefSink.init();
TextZoom.init(); FullZoom.init();
} }
catch(ex) { catch(ex) {
Components.utils.reportError("Failed to init content pref service:\n" + ex); Components.utils.reportError("Failed to init content pref service:\n" + ex);
@ -1202,16 +1204,12 @@ function delayedStartup()
// bookmark-all-tabs command // bookmark-all-tabs command
gBookmarkAllTabsHandler = new BookmarkAllTabsHandler(); gBookmarkAllTabsHandler = new BookmarkAllTabsHandler();
// Prevent chrome-spoofing popups from forging our chrome, by adding a
// notification box entry in cases of chromeless popups.
checkForChromelessWindow();
} }
function BrowserShutdown() function BrowserShutdown()
{ {
try { try {
TextZoom.destroy(); FullZoom.destroy();
ContentPrefSink.destroy(); ContentPrefSink.destroy();
} }
catch(ex) { catch(ex) {
@ -1288,7 +1286,7 @@ function nonBrowserWindowStartup()
var disabledItems = ['cmd_newNavigatorTab', 'Browser:SavePage', 'Browser:SendLink', var disabledItems = ['cmd_newNavigatorTab', 'Browser:SavePage', 'Browser:SendLink',
'cmd_pageSetup', 'cmd_print', 'cmd_find', 'cmd_findAgain', 'viewToolbarsMenu', 'cmd_pageSetup', 'cmd_print', 'cmd_find', 'cmd_findAgain', 'viewToolbarsMenu',
'cmd_toggleTaskbar', 'viewSidebarMenuMenu', 'Browser:Reload', 'Browser:ReloadSkipCache', 'cmd_toggleTaskbar', 'viewSidebarMenuMenu', 'Browser:Reload', 'Browser:ReloadSkipCache',
'viewTextZoomMenu', 'pageStyleMenu', 'charsetMenu', 'View:PageSource', 'View:FullScreen', 'viewFullZoomMenu', 'pageStyleMenu', 'charsetMenu', 'View:PageSource', 'View:FullScreen',
'viewHistorySidebar', 'Browser:AddBookmarkAs', 'View:PageInfo', 'Tasks:InspectPage']; 'viewHistorySidebar', 'Browser:AddBookmarkAs', 'View:PageInfo', 'Tasks:InspectPage'];
var element; var element;
@ -2233,6 +2231,16 @@ function PageProxyClickHandler(aEvent)
return true; return true;
} }
function URLBarOnInput(evt)
{
gBrowser.userTypedValue = gURLBar.value;
// If the user is interacting with the url bar, get rid of the identity popup
var ih = getIdentityHandler();
if(ih._identityPopup)
ih._identityPopup.hidePopup();
}
function URLBarOnDragOver(evt) function URLBarOnDragOver(evt)
{ {
nsDragAndDrop.dragOver(evt, urlbarObserver); nsDragAndDrop.dragOver(evt, urlbarObserver);
@ -3848,6 +3856,7 @@ nsBrowserStatusHandler.prototype =
this.securityButton.removeAttribute("label"); this.securityButton.removeAttribute("label");
this.securityButton.setAttribute("tooltiptext", this._tooltipText); this.securityButton.setAttribute("tooltiptext", this._tooltipText);
getIdentityHandler().checkIdentity(this._state, this._host);
}, },
// simulate all change notifications after switching tabs // simulate all change notifications after switching tabs
@ -3942,6 +3951,10 @@ nsBrowserAccess.prototype =
return null; return null;
} }
if (!gPrefService)
gPrefService = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch2);
var loadflags = isExternal ? var loadflags = isExternal ?
Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL : Ci.nsIWebNavigation.LOAD_FLAGS_FROM_EXTERNAL :
Ci.nsIWebNavigation.LOAD_FLAGS_NONE; Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
@ -3977,6 +3990,8 @@ nsBrowserAccess.prototype =
newWindow.QueryInterface(Ci.nsIInterfaceRequestor) newWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation) .getInterface(Ci.nsIWebNavigation)
.loadURI(url, loadflags, referrer, null, null); .loadURI(url, loadflags, referrer, null, null);
if (!loadInBackground && isExternal)
newWindow.focus();
} catch(e) { } catch(e) {
} }
break; break;
@ -5576,87 +5591,6 @@ BookmarkAllTabsHandler.prototype = {
} }
}; };
/**
* Check the chromehidden attribute to see if the toolbar is hidden. If so,
* and if they haven't disabled the security.warn_chromeless_window.infobar
* pref, show an infobar notification informing them of what's going on. This
* helps fight chrome spoofing on popups. See bug 337344
*/
function checkForChromelessWindow() {
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
// true by default
if (!prefs.getBoolPref("browser.warn_chromeless_window.infobar"))
return;
if (document.documentElement.getAttribute("chromehidden").indexOf("toolbar") != -1 ||
document.documentElement.getAttribute("chromehidden").indexOf("location") != -1) {
var bundle_browser = document.getElementById("bundle_browser");
// It's possible that something in the window.content.opener.location.path
// chain might be null. Rather than chaining a ton of 99% pass null checks,
// though, let's try/catch in order to fail gracefully
try {
var messageString = bundle_browser.getFormattedString("chromelessWindow.warningMessage",
[window.content.opener.location.host]);
} catch (ex) {
// An exception here is not worth breaking our security warning, but is worth
// logging, since it shouldn't happen.
Components.utils.reportError(ex);
messageString = bundle_browser.getString("chromelessWindow.warningNoLocation");
}
var notificationBox = gBrowser.getNotificationBox();
var notificationName = "chromeless-info";
if (notificationBox.getNotificationWithValue(notificationName)) {
Components.utils.reportError("Already have a chromeless-info notification!")
return;
}
var buttons = [{
label: bundle_browser.getString("chromelessWindow.showToolbarsButton"),
accessKey: bundle_browser.getString("chromelessWindow.accessKey"),
popup: null,
callback: function() { return showToolbars(); }
}];
notificationBox.appendNotification(messageString,
notificationName,
"chrome://browser/skin/Info.png",
notificationBox.PRIORITY_INFO_HIGH,
buttons);
}
}
/**
* Callback for "Show Toolbars" button in chromeless window notification box.
* Resets visibility of the go button stack and url bar, and wipes the
* chromehidden document attribute.
*/
function showToolbars() {
// Unhide the chrome elements
document.documentElement.removeAttribute("chromehidden");
// Undo the URLBar tweaks performed when the url bar was chromehidden
if (gURLBar) {
gURLBar.removeAttribute("readonly");
gURLBar.setAttribute("enablehistory", "true");
}
var goButtonStack = document.getElementById("go-button-stack");
if (goButtonStack)
goButtonStack.removeAttribute("hidden");
return false; // Dismiss the notification message
}
/** /**
* Utility class to handle manipulations of the identity indicators in the UI * Utility class to handle manipulations of the identity indicators in the UI
*/ */
@ -5696,7 +5630,7 @@ IdentityHandler.prototype = {
// Cache the most recently seen SSLStatus and URI to prevent unnecessary updates // Cache the most recently seen SSLStatus and URI to prevent unnecessary updates
_lastStatus : null, _lastStatus : null,
_lastURI : null, _lastHost : null,
/** /**
* Handler for mouseclicks on the "Tell me more about this website" link text * Handler for mouseclicks on the "Tell me more about this website" link text
@ -5744,27 +5678,17 @@ IdentityHandler.prototype = {
/** /**
* Determine the identity of the page being displayed by examining its SSL cert * Determine the identity of the page being displayed by examining its SSL cert
* (if available) and, if necessary, update the UI to reflect this. Intended to * (if available) and, if necessary, update the UI to reflect this. Intended to
* be called by an nsIWebProgressListener. * be called by onSecurityChange
* *
* @param nsIWebProgress webProgress
* @param nsIRequest request
* @param PRUint32 state * @param PRUint32 state
* @param AUTF8String host
*/ */
checkIdentity : function(state) { checkIdentity : function(state, host) {
var currentURI = gBrowser.currentURI;
if (currentURI.schemeIs("http") && this._lastURI.schemeIs("http"))
return;
var currentStatus = gBrowser.securityUI var currentStatus = gBrowser.securityUI
.QueryInterface(Components.interfaces.nsISSLStatusProvider) .QueryInterface(Components.interfaces.nsISSLStatusProvider)
.SSLStatus; .SSLStatus;
if (currentStatus == this._lastStatus && currentURI == this._lastURI) {
// No need to update, this is a no-op check
return;
}
this._lastStatus = currentStatus; this._lastStatus = currentStatus;
this._lastURI = currentURI; this._lastHost = host;
if (state & Components.interfaces.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL) if (state & Components.interfaces.nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL)
this.setMode(this.IDENTITY_MODE_IDENTIFIED); this.setMode(this.IDENTITY_MODE_IDENTIFIED);
@ -5802,7 +5726,7 @@ IdentityHandler.prototype = {
// it's not the only place you have to check, there can be more than one domain, // it's not the only place you have to check, there can be more than one domain,
// et cetera, ad nauseum. We know the cert is valid for location.host, so // et cetera, ad nauseum. We know the cert is valid for location.host, so
// let's just use that, it's what the status bar does too. // let's just use that, it's what the status bar does too.
var icon_label = this._lastURI.host; var icon_label = this._lastHost;
var tooltip = this._stringBundle.getFormattedString("identity.identified.verifier", var tooltip = this._stringBundle.getFormattedString("identity.identified.verifier",
[iData.caOrg]); [iData.caOrg]);
} }
@ -5850,7 +5774,7 @@ IdentityHandler.prototype = {
if (newMode == this.IDENTITY_MODE_DOMAIN_VERIFIED) { if (newMode == this.IDENTITY_MODE_DOMAIN_VERIFIED) {
var iData = this.getIdentityData(); var iData = this.getIdentityData();
var body = this._lastURI.host; var body = this._lastHost;
verifier = this._stringBundle.getFormattedString("identity.identified.verifier", verifier = this._stringBundle.getFormattedString("identity.identified.verifier",
[iData.caOrg]); [iData.caOrg]);
supplemental = this._stringBundle.getString("identity.domainverified.supplemental"); supplemental = this._stringBundle.getString("identity.domainverified.supplemental");
@ -5897,6 +5821,10 @@ IdentityHandler.prototype = {
// the popup is actually needed // the popup is actually needed
this._identityPopup.hidden = false; this._identityPopup.hidden = false;
// Tell the popup to consume dismiss clicks, to avoid bug 395314
this._identityPopup.popupBoxObject
.setConsumeRollupEvent(Ci.nsIPopupBoxObject.ROLLUP_CONSUME);
// Update the popup strings // Update the popup strings
this.setPopupMessages(this._identityBox.className); this.setPopupMessages(this._identityBox.className);

Просмотреть файл

@ -28,6 +28,7 @@
# Joe Hewitt <hewitt@netscape.com> # Joe Hewitt <hewitt@netscape.com>
# Pierre Chanial <chanial@noos.fr> # Pierre Chanial <chanial@noos.fr>
# Dean Tessman <dean_tessman@hotmail.com> # Dean Tessman <dean_tessman@hotmail.com>
# Johnathan Nightingale <johnath@mozilla.com>
# #
# Alternatively, the contents of this file may be used under the terms of # Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or # either the GNU General Public License Version 2 or later (the "GPL"), or
@ -57,7 +58,7 @@
# All DTD information is stored in a separate file so that it can be shared by # All DTD information is stored in a separate file so that it can be shared by
# hiddenWindow.xul. # hiddenWindow.xul.
#include browser-doctype.inc #include browser-doctype.inc
<window id="main-window" <window id="main-window"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
@ -138,6 +139,34 @@
<popup id="placesContext"/> <popup id="placesContext"/>
<!-- Popup for site identity information -->
<panel id="identity-popup" position="after_start" hidden="true" noautofocus="true">
<hbox id="identity-popup-container" align="top">
<image id="identity-popup-icon"/>
<vbox id="identity-popup-content-box">
<!-- Title Bar -->
<label id="identity-popup-title"/>
<!-- Content area -->
<description id="identity-popup-content"/>
<description id="identity-popup-content-supplemental"/>
<description id="identity-popup-content-verifier"/>
<hbox id="identity-popup-encryption" flex="1">
<vbox>
<image id="identity-popup-encryption-icon"/>
<spacer flex="1"/>
</vbox>
<description id="identity-popup-encryption-label" flex="1"/>
</hbox>
<spacer flex="1"/>
<!-- Footer link to page info -->
<label id="identity-popup-more-info-link"
class="text-link plain"
value="&identity.moreInfoLinkText;"
onclick="getIdentityHandler().handleMoreInfoClick(event);"/>
</vbox>
</hbox>
</panel>
<tooltip id="urlTooltip"> <tooltip id="urlTooltip">
<label crop="center" flex="1"/> <label crop="center" flex="1"/>
</tooltip> </tooltip>
@ -146,7 +175,7 @@
<!-- bookmarks toolbar tooltip --> <!-- bookmarks toolbar tooltip -->
<tooltip id="btTooltip" noautohide="true" <tooltip id="btTooltip" noautohide="true"
onpopupshowing="return BookmarksEventHandler.fillInBTTooltip(document.tooltipNode)"> onpopupshowing="return BookmarksEventHandler.fillInBTTooltip(document.tooltipNode)">
<vbox id="btTooltipTextBox" flex="1"> <vbox id="btTooltipTextBox" flex="1">
<label id="btTitleText" /> <label id="btTitleText" />
<label id="btUrlText" /> <label id="btUrlText" />
</vbox> </vbox>
@ -183,7 +212,7 @@
oncommand="gotoHistoryIndex(event); event.stopPropagation();" oncommand="gotoHistoryIndex(event); event.stopPropagation();"
onclick="checkForMiddleClick(this, event);"/> onclick="checkForMiddleClick(this, event);"/>
</toolbarbutton> </toolbarbutton>
<toolbarbutton id="forward-button" type="menu-button" class="toolbarbutton-1 chromeclass-toolbar-additional" <toolbarbutton id="forward-button" type="menu-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
chromedir="&locale.dir;" chromedir="&locale.dir;"
label="&forwardCmd.label;" label="&forwardCmd.label;"
@ -197,12 +226,12 @@
oncommand="gotoHistoryIndex(event); event.stopPropagation()" oncommand="gotoHistoryIndex(event); event.stopPropagation()"
onclick="checkForMiddleClick(this, event);"/> onclick="checkForMiddleClick(this, event);"/>
</toolbarbutton> </toolbarbutton>
<toolbarbutton id="reload-button" class="toolbarbutton-1 chromeclass-toolbar-additional" <toolbarbutton id="reload-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
label="&reloadCmd.label;" label="&reloadCmd.label;"
command="Browser:Reload" command="Browser:Reload"
tooltiptext="&reloadButton.tooltip;"/> tooltiptext="&reloadButton.tooltip;"/>
<toolbarbutton id="stop-button" class="toolbarbutton-1 chromeclass-toolbar-additional" <toolbarbutton id="stop-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
label="&stopCmd.label;" label="&stopCmd.label;"
command="Browser:Stop" command="Browser:Stop"
@ -221,30 +250,36 @@
<textbox id="urlbar" flex="1" <textbox id="urlbar" flex="1"
chromedir="&locale.dir;" chromedir="&locale.dir;"
type="autocomplete" type="autocomplete"
autocompletesearch="history" autocompletesearch="history"
autocompletepopup="PopupAutoComplete" autocompletepopup="PopupAutoComplete"
completeselectedindex="true" completeselectedindex="true"
tabscrolling="true" tabscrolling="true"
showcommentcolumn="true" showcommentcolumn="true"
showimagecolumn="true" showimagecolumn="true"
enablehistory="true" enablehistory="true"
maxrows="10" maxrows="10"
newlines="stripsurroundingwhitespace" newlines="stripsurroundingwhitespace"
oninput="gBrowser.userTypedValue = this.value" oninput="URLBarOnInput(event);"
ontextentered="return handleURLBarCommand(param);" ontextentered="return handleURLBarCommand(param);"
ontextreverted="return handleURLBarRevert();"> ontextreverted="return handleURLBarRevert();">
<deck id="page-proxy-deck" onclick="PageProxyClickHandler(event);"> <!-- Use onclick instead of normal popup= syntax since the popup
<image id="page-proxy-button" code fires onmousedown, and hence eats our favicon drag events -->
ondraggesture="PageProxyDragGesture(event);" <box id="identity-box" align="center"
tooltiptext="&proxyIcon.tooltip;"/> onclick="getIdentityHandler().handleIdentityClick(event);">
<image id="page-proxy-favicon" validate="never" <deck id="page-proxy-deck" onclick="PageProxyClickHandler(event);">
ondraggesture="PageProxyDragGesture(event);" <image id="page-proxy-button"
onload="this.parentNode.selectedIndex = 1; ondraggesture="PageProxyDragGesture(event);"
event.stopPropagation();" tooltiptext="&proxyIcon.tooltip;"/>
onerror="this.removeAttribute('src'); <image id="page-proxy-favicon" validate="never"
this.parentNode.selectedIndex = 0;" ondraggesture="PageProxyDragGesture(event);"
tooltiptext="&proxyIcon.tooltip;"/> onload="this.parentNode.selectedIndex = 1;
</deck> event.stopPropagation();"
onerror="this.removeAttribute('src');
this.parentNode.selectedIndex = 0;"
tooltiptext="&proxyIcon.tooltip;"/>
</deck>
<label id="identity-icon-label"/>
</box>
<hbox id="urlbar-icons"> <hbox id="urlbar-icons">
<button type="menu" <button type="menu"
style="-moz-user-focus: none" style="-moz-user-focus: none"
@ -257,7 +292,6 @@
oncommand="return FeedHandler.subscribeToFeed(null, event);" oncommand="return FeedHandler.subscribeToFeed(null, event);"
onclick="checkForMiddleClick(this, event);"/> onclick="checkForMiddleClick(this, event);"/>
</button> </button>
<image id="lock-icon" onclick="if (event.button == 0) displaySecurityInfo(); event.stopPropagation();"/>
#ifdef MOZ_SAFE_BROWSING #ifdef MOZ_SAFE_BROWSING
<image id="safebrowsing-urlbar-icon" tooltiptext="&safeb.urlbaricon.tooltip;" <image id="safebrowsing-urlbar-icon" tooltiptext="&safeb.urlbaricon.tooltip;"
level="safe" level="safe"
@ -282,7 +316,7 @@
</hbox> </hbox>
</toolbaritem> </toolbaritem>
<toolbaritem id="search-container" title="&searchItem.title;" <toolbaritem id="search-container" title="&searchItem.title;"
align="center" class="chromeclass-toolbar-additional" align="center" class="chromeclass-toolbar-additional"
flex="100" persist="width"> flex="100" persist="width">
<searchbar id="searchbar" flex="1" chromedir="&locale.dir;" <searchbar id="searchbar" flex="1" chromedir="&locale.dir;"
@ -299,7 +333,7 @@
<toolbaritem flex="1" id="personal-bookmarks" title="&bookmarksItem.title;"> <toolbaritem flex="1" id="personal-bookmarks" title="&bookmarksItem.title;">
<hbox id="bookmarksBarContent" flex="1" type="places" <hbox id="bookmarksBarContent" flex="1" type="places"
context="placesContext" asyncinit="true" context="placesContext" asyncinit="true"
onclick="BookmarksEventHandler.onClick(event);" onclick="BookmarksEventHandler.onClick(event);"
oncommand="BookmarksEventHandler.onCommand(event);" oncommand="BookmarksEventHandler.onCommand(event);"
onpopupshowing="BookmarksEventHandler.onPopupShowing(event);" onpopupshowing="BookmarksEventHandler.onPopupShowing(event);"
@ -333,7 +367,7 @@
tooltiptext="&newTabButton.tooltip;" tooltiptext="&newTabButton.tooltip;"
ondragover="nsDragAndDrop.dragOver(event, newTabButtonObserver);" ondragover="nsDragAndDrop.dragOver(event, newTabButtonObserver);"
ondragdrop="nsDragAndDrop.drop(event, newTabButtonObserver);" ondragdrop="nsDragAndDrop.drop(event, newTabButtonObserver);"
ondragexit="nsDragAndDrop.dragExit(event, newTabButtonObserver);"/> ondragexit="nsDragAndDrop.dragExit(event, newTabButtonObserver);"/>
<toolbarbutton id="new-window-button" class="toolbarbutton-1 chromeclass-toolbar-additional" <toolbarbutton id="new-window-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
label="&newNavigatorCmd.label;" label="&newNavigatorCmd.label;"
@ -362,7 +396,7 @@
<toolbar id="nav-bar" class="toolbar-primary chromeclass-toolbar" <toolbar id="nav-bar" class="toolbar-primary chromeclass-toolbar"
toolbarname="&navbarCmd.label;" accesskey="&navbarCmd.accesskey;" toolbarname="&navbarCmd.label;" accesskey="&navbarCmd.accesskey;"
fullscreentoolbar="true" mode="icons" fullscreentoolbar="true" mode="icons"
customizable="true" customizable="true"
#ifdef XP_MACOSX #ifdef XP_MACOSX
defaultset="back-button,forward-button,reload-button,stop-button,home-button,urlbar-container,splitter,search-container,throbber-box" defaultset="back-button,forward-button,reload-button,stop-button,home-button,urlbar-container,splitter,search-container,throbber-box"
@ -387,28 +421,28 @@
</hbox> </hbox>
#endif #endif
</toolbar> </toolbar>
<toolbarset id="customToolbars" context="toolbar-context-menu"/> <toolbarset id="customToolbars" context="toolbar-context-menu"/>
<toolbar id="PersonalToolbar" mode="icons" iconsize="small" <toolbar id="PersonalToolbar" mode="icons" iconsize="small"
class="chromeclass-directories" class="chromeclass-directories"
context="toolbar-context-menu" context="toolbar-context-menu"
defaultset="bookmarksBarShowPlaces,personal-bookmarks" defaultset="bookmarksBarShowPlaces,personal-bookmarks"
toolbarname="&personalbarCmd.label;" accesskey="&personalbarCmd.accesskey;" toolbarname="&personalbarCmd.label;" accesskey="&personalbarCmd.accesskey;"
customizable="true"/> customizable="true"/>
</toolbox> </toolbox>
<hbox flex="1" id="browser"> <hbox flex="1" id="browser">
<vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome"> <vbox id="sidebar-box" hidden="true" class="chromeclass-extrachrome">
<sidebarheader align="center"> <sidebarheader align="center">
<label id="sidebar-title" persist="value" flex="1" crop="end" control="sidebar"/> <label id="sidebar-title" persist="value" flex="1" crop="end" control="sidebar"/>
<image id="sidebar-throbber"/> <image id="sidebar-throbber"/>
<toolbarbutton class="tabs-closebutton" tooltiptext="&sidebarCloseButton.tooltip;" oncommand="toggleSidebar();"/> <toolbarbutton class="tabs-closebutton" tooltiptext="&sidebarCloseButton.tooltip;" oncommand="toggleSidebar();"/>
</sidebarheader> </sidebarheader>
<browser id="sidebar" flex="1" autoscroll="false" <browser id="sidebar" flex="1" autoscroll="false"
style="min-width: 14em; width: 18em; max-width: 36em;"/> style="min-width: 14em; width: 18em; max-width: 36em;"/>
</vbox> </vbox>
<splitter id="sidebar-splitter" class="chromeclass-extrachrome" hidden="true"/> <splitter id="sidebar-splitter" class="chromeclass-extrachrome" hidden="true"/>
<vbox id="appcontent" flex="1"> <vbox id="appcontent" flex="1">
<tabbrowser id="content" disablehistory="true" <tabbrowser id="content" disablehistory="true"
@ -430,7 +464,7 @@
#endif #endif
<findbar browserid="content" id="FindToolbar"/> <findbar browserid="content" id="FindToolbar"/>
<statusbar class="chromeclass-status" id="status-bar" <statusbar class="chromeclass-status" id="status-bar"
ondragdrop="nsDragAndDrop.drop(event, contentAreaDNDObserver);"> ondragdrop="nsDragAndDrop.drop(event, contentAreaDNDObserver);">
<statusbarpanel id="statusbar-display" label="" flex="1"/> <statusbarpanel id="statusbar-display" label="" flex="1"/>
@ -439,8 +473,8 @@
</statusbarpanel> </statusbarpanel>
<statusbarpanel id="security-button" class="statusbarpanel-iconic-text" <statusbarpanel id="security-button" class="statusbarpanel-iconic-text"
ondblclick="if (event.button == 0) displaySecurityInfo();"/> ondblclick="if (event.button == 0) displaySecurityInfo();"/>
<statusbarpanel id="page-report-button" type="menu" <statusbarpanel id="page-report-button" type="menu"
class="statusbarpanel-menu-iconic" class="statusbarpanel-menu-iconic"
tooltiptext="&pageReportIcon.tooltip;"> tooltiptext="&pageReportIcon.tooltip;">
<menupopup onpopupshowing="gPopupBlockerObserver.fillPopupList(event);"> <menupopup onpopupshowing="gPopupBlockerObserver.fillPopupList(event);">
<menuitem observes="blockedPopupAllowSite"/> <menuitem observes="blockedPopupAllowSite"/>
@ -451,4 +485,4 @@
</statusbarpanel> </statusbarpanel>
</statusbar> </statusbar>
</window> </window>

Просмотреть файл

@ -59,7 +59,7 @@
windowtype="Browser:page-info" windowtype="Browser:page-info"
onload="onLoadPageInfo()" onload="onLoadPageInfo()"
onunload="onUnloadPageInfo()" onunload="onUnloadPageInfo()"
xmlns:xhtml="http://www.w3.org/1999/xhtml"> xmlns:xhtml="http://www.w3.org/1999/xhtml"
align="stretch" align="stretch"
screenX="10" screenY="10" screenX="10" screenY="10"
width="&pageInfoWindow.width;" height="&pageInfoWindow.height;" width="&pageInfoWindow.width;" height="&pageInfoWindow.height;"

Просмотреть файл

@ -1699,22 +1699,26 @@
<body> <body>
<![CDATA[ <![CDATA[
var tabStrip = this.mTabContainer.mTabstrip; var tabStrip = this.mTabContainer.mTabstrip;
var ltr = (window.getComputedStyle(this.parentNode, null).direction
== "ltr");
// autoscroll the tab strip if we drag over the scroll // autoscroll the tab strip if we drag over the scroll
// buttons, even if we aren't dragging a tab, but then // buttons, even if we aren't dragging a tab, but then
// return to avoid drawing the drop indicator // return to avoid drawing the drop indicator
var pixelsToScroll = 0; var pixelsToScroll = 0;
if (this.mTabContainer.getAttribute("overflow") == "true") {
var targetAnonid = aEvent.originalTarget.getAttribute("anonid"); var targetAnonid = aEvent.originalTarget.getAttribute("anonid");
if (targetAnonid == "scrollbutton-up") { switch (targetAnonid) {
pixelsToScroll = tabStrip.scrollIncrement * -1; case "scrollbutton-up":
tabStrip.scrollByPixels(pixelsToScroll); pixelsToScroll = tabStrip.scrollIncrement * -1;
} break;
else if (targetAnonid == "scrollbutton-down" || case "scrollbutton-down":
(targetAnonid == "alltabs-button" && case "alltabs-button":
this.mTabContainer.getAttribute("overflow") == "true")) { pixelsToScroll = tabStrip.scrollIncrement;
pixelsToScroll = tabStrip.scrollIncrement; break;
tabStrip.scrollByPixels(pixelsToScroll); }
if (pixelsToScroll)
tabStrip.scrollByPixels((ltr ? 1 : -1) * pixelsToScroll);
} }
var isTabDrag = (aDragSession.sourceNode && var isTabDrag = (aDragSession.sourceNode &&
@ -1742,9 +1746,10 @@
var maxMargin = Math.min(minMargin + tabStripBoxObject.width, var maxMargin = Math.min(minMargin + tabStripBoxObject.width,
ib.boxObject.x + ib.boxObject.width - ib.boxObject.x + ib.boxObject.width -
ind.boxObject.width); ind.boxObject.width);
if (!ltr)
[minMargin, maxMargin] = [this.boxObject.width - maxMargin,
this.boxObject.width - minMargin];
var newMargin, tabBoxObject; var newMargin, tabBoxObject;
var ltr = (window.getComputedStyle(this.parentNode, null).direction
== "ltr");
if (pixelsToScroll) { if (pixelsToScroll) {
// if we are scrolling, put the drop indicator at the edge // if we are scrolling, put the drop indicator at the edge
// so that it doesn't jump while scrolling // so that it doesn't jump while scrolling
@ -1775,10 +1780,7 @@
newMargin = maxMargin; newMargin = maxMargin;
} }
if (ltr) ind.style.MozMarginStart = newMargin + 'px';
ind.style.marginLeft = newMargin + 'px';
else
ind.style.marginRight = newMargin + 'px';
ib.collapsed = !aDragSession.canDrop; ib.collapsed = !aDragSession.canDrop;
]]> ]]>

Просмотреть файл

@ -38,54 +38,9 @@
# #
# ***** END LICENSE BLOCK ***** # ***** END LICENSE BLOCK *****
<bindings id="urlbarBindings" xmlns="http://www.mozilla.org/xbl" <bindings id="urlbarBindings" xmlns="http://www.mozilla.org/xbl">
xmlns:html="http://www.w3.org/1999/xhtml"
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:xbl="http://www.mozilla.org/xbl">
<binding id="urlbar" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete"> <binding id="urlbar" extends="chrome://global/content/bindings/autocomplete.xml#autocomplete">
<content sizetopopup="pref">
<xul:hbox class="autocomplete-textbox-container" flex="1">
<children includes="image|deck|stack">
<xul:image class="autocomplete-icon" allowevents="true"/>
</children>
<xul:stack flex="1" class="textbox-stack">
<xul:hbox anonid="textbox-input-box" class="textbox-input-box"
flex="1" xbl:inherits="tooltiptext=inputtooltiptext">
<children/>
<html:input anonid="input" class="autocomplete-textbox textbox-input"
flex="1" allowevents="true"
xbl:inherits="tooltiptext=inputtooltiptext,onfocus,onblur,value,type,maxlength,disabled,size,readonly,userAction"/>
</xul:hbox>
<xul:hbox anonid="presentation-box" class="formatted-url" flex="1"
onmousedown="focus();" hidden="true">
<xul:scrollbox anonid="presentation" class="formatted-url-contents" flex="1"
onoverflow="_contentIsCropped = true;"
onunderflow="_contentIsCropped = false;">
<xul:hbox anonid="prePath" class="formatted-url-prePath">
<xul:label anonid="protocol" class="formatted-url-protocol"/>
<xul:label anonid="subdomain" class="formatted-url-subdomain"/>
<xul:label anonid="domain" class="formatted-url-domain"/>
<xul:label anonid="port" class="formatted-url-port"/>
</xul:hbox>
<xul:label anonid="path" class="formatted-url-path"/>
</xul:scrollbox>
<xul:label anonid="overflow-ellipsis" class="formatted-url-ellipsis"
value="&#8230;" hidden="true"/>
</xul:hbox>
</xul:stack>
<children includes="hbox"/>
</xul:hbox>
<xul:dropmarker anonid="historydropmarker" class="autocomplete-history-dropmarker"
allowevents="true"
xbl:inherits="open,enablehistory"/>
<xul:popupset anonid="popupset" class="autocomplete-result-popupset"/>
</content>
<implementation implements="nsIObserver, nsIDOMEventListener"> <implementation implements="nsIObserver, nsIDOMEventListener">
<constructor><![CDATA[ <constructor><![CDATA[
this._ioService = Components.classes["@mozilla.org/network/io-service;1"] this._ioService = Components.classes["@mozilla.org/network/io-service;1"]
@ -96,91 +51,49 @@
.QueryInterface(Components.interfaces.nsIPrefBranch2); .QueryInterface(Components.interfaces.nsIPrefBranch2);
this._prefs.addObserver("", this, false); this._prefs.addObserver("", this, false);
this._hideProtocols = this._prefs.getCharPref("hideProtocols").split(" ");
this._animateBlend = this._prefs.getBoolPref("animateBlend");
this.clickSelectsAll = this._prefs.getBoolPref("clickSelectsAll"); this.clickSelectsAll = this._prefs.getBoolPref("clickSelectsAll");
this.doubleClickSelectsAll = this._prefs.getBoolPref("doubleClickSelectsAll"); this.doubleClickSelectsAll = this._prefs.getBoolPref("doubleClickSelectsAll");
this.completeDefaultIndex = this._prefs.getBoolPref("autoFill"); this.completeDefaultIndex = this._prefs.getBoolPref("autoFill");
this._inputBox = document.getAnonymousElementByAttribute(this, "anonid", "textbox-input-box");
this._presentationBox = document.getAnonymousElementByAttribute(this, "anonid", "presentation-box");
this._overflowEllipsis = document.getAnonymousElementByAttribute(this, "anonid", "overflow-ellipsis");
this._prePath = document.getAnonymousElementByAttribute(this, "anonid", "prePath");
this._protocol = document.getAnonymousElementByAttribute(this, "anonid", "protocol");
this._subDomain = document.getAnonymousElementByAttribute(this, "anonid", "subdomain");
this._domain = document.getAnonymousElementByAttribute(this, "anonid", "domain");
this._port = document.getAnonymousElementByAttribute(this, "anonid", "port");
this._path = document.getAnonymousElementByAttribute(this, "anonid", "path");
this._urlTooltip = document.getElementById("urlTooltip"); this._urlTooltip = document.getElementById("urlTooltip");
this.inputField.controllers.insertControllerAt(0, this._copyCutController); this.inputField.controllers.insertControllerAt(0, this._copyCutController);
this.inputField.addEventListener("mousedown", this, false); this.inputField.addEventListener("mousedown", this, false);
this.inputField.addEventListener("mousemove", this, false);
this._blendingTimers = []; this.inputField.addEventListener("mouseout", this, false);
]]></constructor> ]]></constructor>
<destructor><![CDATA[ <destructor><![CDATA[
this._prefs.removeObserver("", this); this._prefs.removeObserver("", this);
this._prefs = null; this._prefs = null;
this._ioService = null; this._ioService = null;
this._tldService = null;
this.inputField.controllers.removeController(this._copyCutController); this.inputField.controllers.removeController(this._copyCutController);
this.inputField.removeEventListener("mousedown", this, false); this.inputField.removeEventListener("mousedown", this, false);
this.inputField.removeEventListener("mousemove", this, false);
this.inputField.removeEventListener("mouseout", this, false);
]]></destructor> ]]></destructor>
<!-- initially empty fields:
<field name="_uri"/>
<field name="_protocolHidden"/>
<field name="_focused"/>
<field name="_mouseover"/>
<field name="_tooltipTimer"/>
<field name="_tldService"/>
<field name="_formatted"/>
-->
<property name="plain" onget="return !this._formatted">
<setter><![CDATA[
this._formatted = !val;
while (this._blendingTimers.length)
clearTimeout(this._blendingTimers.pop());
if (val) {
this._inputBox.style.removeProperty("opacity");
this._presentationBox.hidden = true;
} else {
this._inputBox.style.setProperty("opacity", "0", "important");
}
this._presentationBox.style.removeProperty("opacity");
this._hideURLTooltip();
return val;
]]></setter>
</property>
<property name="tldService" readonly="true">
<getter><![CDATA[
if (!this._tldService) {
this._tldService =
Components.classes["@mozilla.org/network/effective-tld-service;1"]
.getService(Components.interfaces.nsIEffectiveTLDService);
}
return this._tldService;
]]></getter>
</property>
<property name="_contentIsCropped"
onget="return !this._overflowEllipsis.hidden;"
onset="this._overflowEllipsis.hidden = !val; return val;"/>
<property name="value" <property name="value"
onget="return this.inputField.value;"> onget="return this.inputField.value;">
<setter><![CDATA[ <setter><![CDATA[
this.mIgnoreInput = true; this.mIgnoreInput = true;
this._syncValue(val);
if (val != "") {
var uri;
try {
uri = this._ioService.newURI(val, null, null);
} catch(e) {}
if (uri) {
val = uri.spec;
try {
// try to decode as UTF-8
val = decodeURI(val);
} catch(e) {}
}
}
this.inputField.value = val;
this.mIgnoreInput = false; this.mIgnoreInput = false;
if (this._focused)
this.plain = true;
else if (!this._mouseover || !this.plain)
this._prettyView(false);
var event = document.createEvent("Events"); var event = document.createEvent("Events");
event.initEvent("ValueChange", true, true); event.initEvent("ValueChange", true, true);
this.inputField.dispatchEvent(event); this.inputField.dispatchEvent(event);
@ -188,165 +101,20 @@
]]></setter> ]]></setter>
</property> </property>
<method name="_syncValue">
<parameter name="aValue"/>
<body><![CDATA[
var value = aValue != null ? aValue : this.value;
if (value == "") {
this._uri = null;
} else {
try {
this._uri = this._ioService.newURI(value, null, null);
// next line throws if .host is not defined
this._uri.host;
} catch(e) {
this._uri = null;
}
}
if (!this._uri) {
this._contentIsCropped = false;
if (aValue != null)
this.inputField.value = aValue;
return;
}
if (!this._focused || aValue != null) {
value = this._uri.spec;
try {
// try to decode as UTF-8
value = decodeURI(value);
} catch(e) {}
this.inputField.value = value;
}
this._protocol.setAttribute("value", this._uri.scheme + "://");
this._protocolHidden = this._hideProtocols.indexOf(this._uri.scheme) > -1;
var host = this._uri.host;
if (host) {
var subdomain;
var port = (this._uri.port > -1) ? ":" + this._uri.port : "";
if (this._uri.hostPort[0] == "[") {
// IPv6 address
subdomain = "[";
port = "]" + port;
}
else if (0 && !/^[.0-9]+$/.test(host)) {
//XXX subdomain detection disabled (bug 386727)
//XXX subdomain detection disabled for IP addresses (bug 364129)
// getEffectiveTLDLength might convert our host and return a misleading length.
// To avoid this, pass the ASCII host, count the dots of its effective TLD
// and use that number to operate on our actual host.
var asciiHost = this._uri.asciiHost;
var domainSegments = host.split(".");
var cSubdomain = domainSegments.length -
asciiHost.slice(asciiHost.length -
this.tldService.getEffectiveTLDLength(asciiHost))
.split(".").length - 1;
if (cSubdomain > 0) {
host = domainSegments;
subdomain = host.splice(0, cSubdomain).join(".") + ".";
host = host.join(".");
}
} else {
subdomain = "";
}
this._subDomain.setAttribute("value", subdomain);
this._domain.setAttribute("value", host);
this._port.setAttribute("value", port);
} else {
this._subDomain.removeAttribute("value");
this._domain.removeAttribute("value");
this._port.removeAttribute("value");
}
var path = this._uri.path;
try {
// try to decode as UTF-8
path = decodeURI(path);
} catch(e) {}
this._path.setAttribute("value", path);
]]></body>
</method>
<method name="_initPrettyView">
<body><![CDATA[
this._plain = false;
this._protocol.hidden = false;
this._presentationBox.hidden = false;
this._prePath.width = "";
if (this._protocolHidden) {
this._prePath.width = this._prePath.boxObject.width;
this._protocol.hidden = true;
}
]]></body>
</method>
<method name="_prettyView">
<parameter name="aAnimateBlend"/>
<body><![CDATA[
if (!this._uri) {
this.plain = true;
return;
}
if (!aAnimateBlend || !this._animateBlend) {
this._initPrettyView();
this.plain = false;
return;
}
const INITIAL_DELAY = 150;
const FRAME_LENGTH = 60;
const DECLINATION_REL = .2;
const DECLINATION_ABS = .15;
var inputBox = this._inputBox;
var presentationBox = this._presentationBox;
var self = this;
var opacity = parseFloat(document.defaultView.getComputedStyle(inputBox, null).opacity);
var delay = INITIAL_DELAY;
function processFrame(opacity, init) {
inputBox.style.setProperty("opacity", opacity, "important");
presentationBox.style.setProperty("opacity", 1-opacity, "important");
if (init)
self._initPrettyView();
if (!opacity)
self.plain = false;
}
while (opacity > 0) {
opacity -= opacity * DECLINATION_REL + DECLINATION_ABS;
if (opacity < 0)
opacity = 0;
this._blendingTimers.push(setTimeout(processFrame, delay, opacity, delay == INITIAL_DELAY));
delay += FRAME_LENGTH;
}
]]></body>
</method>
<method name="_initURLTooltip"> <method name="_initURLTooltip">
<parameter name="aCallback"/>
<parameter name="aObject"/>
<parameter name="aCrop"/>
<body><![CDATA[ <body><![CDATA[
if (this.focused)
return;
if (this._tooltipTimer) if (this._tooltipTimer)
clearTimeout(this._tooltipTimer); clearTimeout(this._tooltipTimer);
this._tooltipTimer = setTimeout(function(self) { this._tooltipTimer = setTimeout(function (self) {
self._tooltipTimer = 0; self._tooltipTimer = 0;
var tooltipText = aCallback.apply(aObject); var label = self._urlTooltip.firstChild;
if (tooltipText) { label.value = self.value;
var label = self._urlTooltip.firstChild; var bO = self.boxObject;
label.value = tooltipText; self._urlTooltip.maxWidth = bO.width;
label.crop = aCrop || "center"; self._urlTooltip.showPopup(self, bO.screenX, bO.screenY + bO.height, "tooltip");
var bO = self.boxObject; }, 700, this);
self._urlTooltip.maxWidth = bO.width;
self._urlTooltip.showPopup(self, bO.screenX, bO.screenY + bO.height, "tooltip");
}
}, 400, this);
]]></body> ]]></body>
</method> </method>
@ -411,12 +179,6 @@
<body><![CDATA[ <body><![CDATA[
if (aTopic == "nsPref:changed") { if (aTopic == "nsPref:changed") {
switch(aData) { switch(aData) {
case "hideProtocols":
this._hideProtocols = this._prefs.getCharPref(aData).split(" ");
this._syncValue();
if (!this.plain)
this._prettyView(false);
break;
case "clickSelectsAll": case "clickSelectsAll":
case "doubleClickSelectsAll": case "doubleClickSelectsAll":
this[aData] = this._prefs.getBoolPref(aData); this[aData] = this._prefs.getBoolPref(aData);
@ -424,9 +186,6 @@
case "autoFill": case "autoFill":
this.completeDefaultIndex = this._prefs.getBoolPref(aData); this.completeDefaultIndex = this._prefs.getBoolPref(aData);
break; break;
case "animateBlend":
this._animateBlend = this._prefs.getBoolPref(aData);
break;
} }
} }
]]></body> ]]></body>
@ -435,71 +194,27 @@
<method name="handleEvent"> <method name="handleEvent">
<parameter name="aEvent"/> <parameter name="aEvent"/>
<body><![CDATA[ <body><![CDATA[
if (aEvent.type == "mousedown" && switch (aEvent.type) {
aEvent.button == 0 && aEvent.detail == 2 && case "mousedown":
this.doubleClickSelectsAll) { if (this.doubleClickSelectsAll &&
this.editor.selectAll(); aEvent.button == 0 && aEvent.detail == 2) {
aEvent.preventDefault(); this.editor.selectAll();
aEvent.preventDefault();
}
break;
case "mousemove":
this._initURLTooltip();
break;
case "mouseout":
this._hideURLTooltip();
break;
} }
]]></body> ]]></body>
</method> </method>
</implementation> </implementation>
<handlers> <handlers>
<handler event="input" <handler event="focus" phase="capturing" action="this._hideURLTooltip();"/>
action="this._syncValue();"/>
<handler event="mousemove"><![CDATA[
if (!this._focused && this._contentIsCropped)
this._initURLTooltip(function() {
return this.plain ? this.value : null;
}, this, "start");
]]></handler>
<handler event="mouseover"><![CDATA[
if (this._mouseover)
return;
if (!this.plain) {
// do nothing if we're over the favicon, history dropmarker et al
var pBO = this._presentationBox.boxObject;
if (event.screenX < pBO.screenX || event.screenX > pBO.screenX + pBO.width)
return;
}
this._mouseover = true;
setTimeout(function(self) {
if (self._mouseover) {
self.plain = true;
if (!self._focused && self._contentIsCropped)
self._initURLTooltip(function() {
return this.plain ? this.value : null;
}, self, "start");
}
}, 60, this);
]]></handler>
<handler event="mouseout" phase="target"><![CDATA[
this._mouseover = false;
if (!this._focused && this.plain)
this._prettyView(true);
else
this._hideURLTooltip();
]]></handler>
<handler event="focus" phase="capturing"><![CDATA[
if (!this._focused) {
this._focused = true;
this.plain = true;
}
]]></handler>
<handler event="blur" phase="capturing"><![CDATA[
if (this._focused && !this._dontBlur) {
this._focused = false;
this._syncValue();
if (!this._mouseover)
this._prettyView(true);
}
]]></handler>
</handlers> </handlers>
</binding> </binding>

Просмотреть файл

@ -1532,7 +1532,7 @@ nsIEProfileMigrator::CopyCookies(PRBool aReplace)
{ {
// IE cookies are stored in files named <username>@domain[n].txt // IE cookies are stored in files named <username>@domain[n].txt
// (in <username>'s Cookies folder. isn't the naming redundant?) // (in <username>'s Cookies folder. isn't the naming redundant?)
PRBool rv = NS_OK; nsresult rv = NS_OK;
nsCOMPtr<nsIFile> cookiesDir; nsCOMPtr<nsIFile> cookiesDir;
nsCOMPtr<nsISimpleEnumerator> cookieFiles; nsCOMPtr<nsISimpleEnumerator> cookieFiles;
@ -1543,8 +1543,33 @@ nsIEProfileMigrator::CopyCookies(PRBool aReplace)
// find the cookies directory // find the cookies directory
NS_GetSpecialDirectory(NS_WIN_COOKIES_DIR, getter_AddRefs(cookiesDir)); NS_GetSpecialDirectory(NS_WIN_COOKIES_DIR, getter_AddRefs(cookiesDir));
if (cookiesDir) if (!cookiesDir)
cookiesDir->GetDirectoryEntries(getter_AddRefs(cookieFiles)); return NS_ERROR_FAILURE;
// Check for Vista's UAC, if so, tack on a "Low" sub dir
nsCOMPtr<nsIWindowsRegKey> regKey =
do_CreateInstance("@mozilla.org/windows-registry-key;1");
if (regKey) {
NS_NAMED_LITERAL_STRING(regPath,"Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System");
if (NS_SUCCEEDED(regKey->Open(nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE,
regPath,
nsIWindowsRegKey::ACCESS_QUERY_VALUE))) {
PRUint32 value;
if (NS_SUCCEEDED(regKey->ReadIntValue(NS_LITERAL_STRING("EnableLUA"),
&value)) &&
value == 1) {
nsAutoString dir;
// For cases where we are running under protected mode, check
// cookiesDir for the Low sub directory. (Simpler than using
// process token calls to check our Vista integrity level.)
cookiesDir->GetLeafName(dir);
if (!dir.EqualsLiteral("Low"))
cookiesDir->Append(NS_LITERAL_STRING("Low"));
}
}
}
cookiesDir->GetDirectoryEntries(getter_AddRefs(cookieFiles));
if (!cookieFiles) if (!cookieFiles)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;

Просмотреть файл

@ -44,6 +44,6 @@ function searchBookmarks(aSearchString) {
if (!aSearchString) if (!aSearchString)
tree.place = tree.place; tree.place = tree.place;
else else
tree.applyFilter(aSearchString, true); tree.applyFilter(aSearchString, true,
[PlacesUtils.bookmarksRootId, PlacesUtils.unfiledRootId]);
} }

Просмотреть файл

@ -67,7 +67,7 @@
oncommand="searchBookmarks(this.value);"/> oncommand="searchBookmarks(this.value);"/>
</hbox> </hbox>
<tree id="bookmarks-view" class="placesTree" type="places" <tree id="bookmarks-view" class="sidebar-placesTree" type="places"
flex="1" flex="1"
hidecolumnpicker="true" hidecolumnpicker="true"
place="place:folder=2&amp;queryType=1" place="place:folder=2&amp;queryType=1"
@ -77,6 +77,6 @@
<treecols> <treecols>
<treecol id="title" flex="1" primary="true" hideheader="true"/> <treecol id="title" flex="1" primary="true" hideheader="true"/>
</treecols> </treecols>
<treechildren id="bookmarks-view-children" view="bookmarks-view" flex="1"/> <treechildren id="bookmarks-view-children" view="bookmarks-view" class="sidebar-placesTreechildren" flex="1"/>
</tree> </tree>
</page> </page>

Просмотреть файл

@ -1030,39 +1030,48 @@ PlacesController.prototype = {
* elsewhere. * elsewhere.
*/ */
getTransferData: function PC_getTransferData(dragAction) { getTransferData: function PC_getTransferData(dragAction) {
var nodes = null; var result = this._view.getResult();
if (dragAction == Ci.nsIDragService.DRAGDROP_ACTION_COPY) var oldViewer = result.viewer;
nodes = this._view.getCopyableSelection(); try {
else result.viewer = null;
nodes = this._view.getDragableSelection(); var nodes = null;
var dataSet = new TransferDataSet(); if (dragAction == Ci.nsIDragService.DRAGDROP_ACTION_COPY)
for (var i = 0; i < nodes.length; ++i) { nodes = this._view.getCopyableSelection();
var node = nodes[i]; else
nodes = this._view.getDragableSelection();
var dataSet = new TransferDataSet();
for (var i = 0; i < nodes.length; ++i) {
var node = nodes[i];
var data = new TransferData(); var data = new TransferData();
function addData(type, overrideURI) { function addData(type, overrideURI) {
data.addDataForFlavour(type, PlacesUtils._wrapString( data.addDataForFlavour(type, PlacesUtils._wrapString(
PlacesUtils.wrapNode(node, type, overrideURI))); PlacesUtils.wrapNode(node, type, overrideURI)));
}
function addURIData(overrideURI) {
addData(PlacesUtils.TYPE_X_MOZ_URL, overrideURI);
addData(PlacesUtils.TYPE_UNICODE, overrideURI);
addData(PlacesUtils.TYPE_HTML, overrideURI);
}
// This order is _important_! It controls how this and other
// applications select data to be inserted based on type.
addData(PlacesUtils.TYPE_X_MOZ_PLACE);
var uri;
// Allow dropping the feed uri of live-bookmark folders
if (PlacesUtils.nodeIsLivemarkContainer(node))
uri = PlacesUtils.livemarks.getFeedURI(node.itemId).spec;
addURIData(uri);
dataSet.push(data);
} }
}
function addURIData(overrideURI) { finally {
addData(PlacesUtils.TYPE_X_MOZ_URL, overrideURI); if (oldViewer)
addData(PlacesUtils.TYPE_UNICODE, overrideURI); result.viewer = oldViewer;
addData(PlacesUtils.TYPE_HTML, overrideURI);
}
// This order is _important_! It controls how this and other
// applications select data to be inserted based on type.
addData(PlacesUtils.TYPE_X_MOZ_PLACE);
var uri;
// Allow dropping the feed uri of live-bookmark folders
if (PlacesUtils.nodeIsLivemarkContainer(node))
uri = PlacesUtils.livemarks.getFeedURI(node.itemId).spec;
addURIData(uri);
dataSet.push(data);
} }
return dataSet; return dataSet;
}, },
@ -1071,63 +1080,69 @@ PlacesController.prototype = {
* Copy Bookmarks and Folders to the clipboard * Copy Bookmarks and Folders to the clipboard
*/ */
copy: function PC_copy() { copy: function PC_copy() {
var nodes = this._view.getCopyableSelection(); var result = this._view.getResult();
var oldViewer = result.viewer;
try {
result.viewer = null;
var nodes = this._view.getCopyableSelection();
var xferable = var xferable = Cc["@mozilla.org/widget/transferable;1"].
Cc["@mozilla.org/widget/transferable;1"]. createInstance(Ci.nsITransferable);
createInstance(Ci.nsITransferable); var foundFolder = false, foundLink = false;
var foundFolder = false, foundLink = false; var copiedFolders = [];
var copiedFolders = []; var placeString = mozURLString = htmlString = unicodeString = "";
var placeString = mozURLString = htmlString = unicodeString = "";
for (var i = 0; i < nodes.length; ++i) { for (var i = 0; i < nodes.length; ++i) {
var node = nodes[i]; var node = nodes[i];
if (this._shouldSkipNode(node, copiedFolders)) if (this._shouldSkipNode(node, copiedFolders))
continue; continue;
if (PlacesUtils.nodeIsFolder(node)) if (PlacesUtils.nodeIsFolder(node))
copiedFolders.push(node); copiedFolders.push(node);
function generateChunk(type, overrideURI) { function generateChunk(type, overrideURI) {
var suffix = i < (nodes.length - 1) ? NEWLINE : ""; var suffix = i < (nodes.length - 1) ? NEWLINE : "";
var uri = overrideURI; var uri = overrideURI;
if (PlacesUtils.nodeIsLivemarkContainer(node)) if (PlacesUtils.nodeIsLivemarkContainer(node))
uri = PlacesUtils.livemarks.getFeedURI(node.itemId).spec uri = PlacesUtils.livemarks.getFeedURI(node.itemId).spec
mozURLString += (PlacesUtils.wrapNode(node, PlacesUtils.TYPE_X_MOZ_URL, mozURLString += (PlacesUtils.wrapNode(node, PlacesUtils.TYPE_X_MOZ_URL,
uri) + suffix); uri) + suffix);
unicodeString += (PlacesUtils.wrapNode(node, PlacesUtils.TYPE_UNICODE, unicodeString += (PlacesUtils.wrapNode(node, PlacesUtils.TYPE_UNICODE,
uri) + suffix); uri) + suffix);
htmlString += (PlacesUtils.wrapNode(node, PlacesUtils.TYPE_HTML, htmlString += (PlacesUtils.wrapNode(node, PlacesUtils.TYPE_HTML,
uri) + suffix); uri) + suffix);
var placeSuffix = i < (nodes.length - 1) ? "," : ""; var placeSuffix = i < (nodes.length - 1) ? "," : "";
return PlacesUtils.wrapNode(node, type, overrideURI) + placeSuffix; return PlacesUtils.wrapNode(node, type, overrideURI) + placeSuffix;
}
// all items wrapped as TYPE_X_MOZ_PLACE
placeString += generateChunk(PlacesUtils.TYPE_X_MOZ_PLACE);
} }
// all items wrapped as TYPE_X_MOZ_PLACE function addData(type, data) {
placeString += generateChunk(PlacesUtils.TYPE_X_MOZ_PLACE); xferable.addDataFlavor(type);
} xferable.setTransferData(type, PlacesUtils._wrapString(data), data.length * 2);
}
// This order is _important_! It controls how this and other applications
// select data to be inserted based on type.
if (placeString)
addData(PlacesUtils.TYPE_X_MOZ_PLACE, placeString);
if (mozURLString)
addData(PlacesUtils.TYPE_X_MOZ_URL, mozURLString);
if (unicodeString)
addData(PlacesUtils.TYPE_UNICODE, unicodeString);
if (htmlString)
addData(PlacesUtils.TYPE_HTML, htmlString);
function addData(type, data) { if (placeString || unicodeString || htmlString || mozURLString) {
xferable.addDataFlavor(type); PlacesUtils.clipboard.setData(xferable, null, Ci.nsIClipboard.kGlobalClipboard);
xferable.setTransferData(type, PlacesUtils._wrapString(data), data.length * 2); }
} }
// This order is _important_! It controls how this and other applications finally {
// select data to be inserted based on type. if (oldViewer)
if (placeString) result.viewer = oldViewer;
addData(PlacesUtils.TYPE_X_MOZ_PLACE, placeString);
if (mozURLString)
addData(PlacesUtils.TYPE_X_MOZ_URL, mozURLString);
if (unicodeString)
addData(PlacesUtils.TYPE_UNICODE, unicodeString);
if (htmlString)
addData(PlacesUtils.TYPE_HTML, htmlString);
if (placeString || unicodeString || htmlString || mozURLString) {
var clipboard =
Cc["@mozilla.org/widget/clipboard;1"].getService(Ci.nsIClipboard);
clipboard.setData(xferable, null, Ci.nsIClipboard.kGlobalClipboard);
} }
}, },
@ -1166,8 +1181,7 @@ PlacesController.prototype = {
return xferable; return xferable;
} }
var clipboard = Cc["@mozilla.org/widget/clipboard;1"]. var clipboard = PlacesUtils.clipboard;
getService(Ci.nsIClipboard);
var ip = this._view.insertionPoint; var ip = this._view.insertionPoint;
if (!ip) if (!ip)
@ -1221,6 +1235,285 @@ PlacesController.prototype = {
} }
}; };
function PlacesMenuDNDObserver(aView, aPopup) {
this._view = aView;
this._popup = aPopup;
this._popup.addEventListener("draggesture", this, false);
this._popup.addEventListener("dragover", this, false);
this._popup.addEventListener("dragdrop", this, false);
this._popup.addEventListener("dragexit", this, false);
}
/**
* XXXmano-please-rewrite-me: This code was ported over from menu.xul in bug 399729.
* Unsurprisngly it's still mostly broken due to bug 337761, thus I didn't bother
* trying to cleaning up this extremely buggy over-folder detection code yet.
*/
PlacesMenuDNDObserver.prototype = {
_view: null,
_popup: null,
// Sub-menus should be opened when the mouse drags over them, and closed
// when the mouse drags off. The overFolder object manages opening and closing
// of folders when the mouse hovers.
_overFolder: {node: null, openTimer: null, hoverTime: 350, closeTimer: null},
// If this menu's parent auto-opened it because it was dragged over, but didn't
// close it because the mouse dragged into it, the menu should close itself
// onDragExit. This timer is set in dragExit to close the menu.
_closeMenuTimer: null,
_setTimer: function TBV_DO_setTimer(time) {
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.initWithCallback(this, time, timer.TYPE_ONE_SHOT);
return timer;
},
// Function to process all timer notifications.
notify: function TBV_DO_notify(timer) {
// Timer to open a submenu that's being dragged over.
if (timer == this._overFolder.openTimer) {
this._overFolder.node.lastChild.setAttribute("autoopened", "true");
this._overFolder.node.lastChild.showPopup(this._overFolder.node);
this._overFolder.openTimer = null;
}
// Timer to close a submenu that's been dragged off of.
if (timer == this._overFolder.closeTimer) {
// Only close the submenu if the mouse isn't being dragged over any
// of its child menus.
var draggingOverChild =
PlacesControllerDragHelper.draggingOverChildNode(this._overFolder.node);
if (draggingOverChild)
this._overFolder.node = null;
this._clearOverFolder();
// Close any parent folders which aren't being dragged over.
// (This is necessary because of the above code that keeps a folder
// open while its children are being dragged over.)
if (!draggingOverChild)
this._closeParentMenus();
}
// Timer to close this menu after the drag exit.
if (timer == this._closeMenuTimer) {
if (!PlacesControllerDragHelper.draggingOverChildNode(this._popup)) {
this._popup.hidePopup();
// Close any parent menus that aren't being dragged over;
// otherwise they'll stay open because they couldn't close
// while this menu was being dragged over.
this._closeParentMenus();
}
}
},
// Helper function to close all parent menus of this menu,
// as long as none of the parent's children are currently being
// dragged over.
_closeParentMenus: function TBV_DO_closeParentMenus() {
var parent = this._popup.parentNode;
while (parent) {
if (parent.nodeName == "menupopup" && parent._resultNode) {
if (PlacesControllerDragHelper.draggingOverChildNode(parent.parentNode))
break;
parent.hidePopup();
}
parent = parent.parentNode;
}
},
// The mouse is no longer dragging over the stored menubutton.
// Close the menubutton, clear out drag styles, and clear all
// timers for opening/closing it.
_clearOverFolder: function TBV_DO_clearOverFolder() {
if (this._overFolder.node && this._overFolder.node.lastChild) {
if (!this._overFolder.node.lastChild.hasAttribute("dragover"))
this._overFolder.node.lastChild.hidePopup();
this._overFolder.node = null;
}
if (this._overFolder.openTimer) {
this._overFolder.openTimer.cancel();
this._overFolder.openTimer = null;
}
if (this._overFolder.closeTimer) {
this._overFolder.closeTimer.cancel();
this._overFolder.closeTimer = null;
}
},
// This function returns information about where to drop when
// dragging over this menu--insertion point, child index to drop
// before, and folder to drop into.
_getDropPoint: function TBV_DO_getDropPoint(event) {
// Can't drop if the menu isn't a folder
var resultNode = this._popup._resultNode;
if (!PlacesUtils.nodeIsFolder(resultNode))
return null;
var dropPoint = { ip: null, beforeIndex: null, folderNode: null };
// Loop through all the nodes to see which one this should
// get dropped in/above/below.
var start = 0;
var end = this._popup.childNodes.length;
if (this._popup == this._view && this._view.localName == "menupopup") {
// Ignore static content at the top and bottom of the menu.
start = this._view._startMarker + 1;
if (this._view._endMarker != -1)
end = this._view._endMarker;
}
for (var i = start; i < end; i++) {
var xulNode = this._popup.childNodes[i];
var nodeY = xulNode.boxObject.y - this._popup.boxObject.y;
var nodeHeight = xulNode.boxObject.height;
if (xulNode.node &&
PlacesUtils.nodeIsFolder(xulNode.node) &&
!PlacesUtils.nodeIsReadOnly(xulNode.node)) {
// This is a folder. If the mouse is in the top 25% of the
// node, drop above the folder. If it's in the middle
// 50%, drop into the folder. If it's past that, drop below.
if (event.clientY < nodeY + (nodeHeight * 0.25)) {
// Drop above this folder.
dropPoint.ip = new InsertionPoint(resultNode.itemId, i - start,
-1);
dropPoint.beforeIndex = i;
return dropPoint;
}
else if (event.clientY < nodeY + (nodeHeight * 0.75)) {
// Drop inside this folder.
dropPoint.ip = new InsertionPoint(xulNode.node.itemId, -1, 1);
dropPoint.beforeIndex = i;
dropPoint.folderNode = xulNode;
return dropPoint;
}
} else {
// This is a non-folder node. If the mouse is above the middle,
// drop above the folder. Otherwise, drop below.
if (event.clientY < nodeY + (nodeHeight / 2)) {
// Drop above this bookmark.
dropPoint.ip = new InsertionPoint(resultNode.itemId, i - start, -1);
dropPoint.beforeIndex = i;
return dropPoint;
}
}
}
// Should drop below the last node.
dropPoint.ip = new InsertionPoint(resultNode.itemId, -1, 1);
dropPoint.beforeIndex = -1;
return dropPoint;
},
// This function clears all of the dragover styles that were set when
// a menuitem was dragged over.
_clearStyles: function TBV_DO_clearStyles() {
this._popup.removeAttribute("dragover");
for (var i = 0; i < this._popup.childNodes.length; i++) {
this._popup.childNodes[i].removeAttribute("dragover-top");
this._popup.childNodes[i].removeAttribute("dragover-bottom");
this._popup.childNodes[i].removeAttribute("dragover-into");
}
},
onDragStart: function TBV_DO_onDragStart(event, xferData, dragAction) {
this._view._selection = event.target.node;
this._view._cachedInsertionPoint = undefined;
if (event.ctrlKey)
dragAction.action = Ci.nsIDragService.DRAGDROP_ACTION_COPY;
xferData.data = this._view.controller.getTransferData(dragAction.action);
},
canDrop: function TBV_DO_canDrop(event, session) {
return PlacesControllerDragHelper.canDrop(this._view, -1);
},
onDragOver: function TBV_DO_onDragOver(event, flavor, session) {
PlacesControllerDragHelper.currentDropTarget = event.target;
var dropPoint = this._getDropPoint(event);
if (dropPoint == null)
return;
this._clearStyles();
if (dropPoint.folderNode) {
// Dragging over a folder; set the appropriate styles.
if (this._overFolder.node != dropPoint.folderNode) {
this._clearOverFolder();
this._overFolder.node = dropPoint.folderNode;
this._overFolder.openTimer = this._setTimer(this._overFolder.hoverTime);
}
dropPoint.folderNode.setAttribute("dragover-into", "true");
}
else {
// Dragging over a menuitem, set dragover-top/bottom to show where
// the item will be dropped and clear out any old folder info.
if (dropPoint.beforeIndex == -1) {
if (this._popup == this._view && this._view.localName == "menupopup" &&
this._popup._endMarker != -1) {
this._popup.childNodes[this._popup._endMarker]
.setAttribute("dragover-top", "true");
}
else
this._popup.lastChild.setAttribute("dragover-bottom", "true");
}
else {
this._popup.childNodes[dropPoint.beforeIndex]
.setAttribute("dragover-top", "true");
}
// Clear out old folder information
this._clearOverFolder();
}
this._popup.setAttribute("dragover", "true");
},
onDrop: function TBV_DO_onDrop(event, dropData, session) {
var dropPoint = this._getDropPoint(event);
if (!dropPoint)
return;
PlacesControllerDragHelper.onDrop(null, this._view, dropPoint.ip);
},
onDragExit: function TBV_DO_onDragExit(event, session) {
PlacesControllerDragHelper.currentDropTarget = null;
this._clearStyles();
// Close any folder being hovered over
if (this._overFolder.node)
this._overFolder.closeTimer = this._setTimer(this._overFolder.hoverTime);
// The autoopened attribute is set when this folder was automatically
// opened after the user dragged over it. If this attribute is set,
// auto-close the folder on drag exit.
if (this._popup.hasAttribute("autoopened"))
this._closeMenuTimer = this._setTimer(this._overFolder.hoverTime);
},
getSupportedFlavours: function TBV_DO_getSupportedFlavours() {
var flavorSet = new FlavourSet();
for (var i = 0; i < this._view.peerDropTypes.length; ++i)
flavorSet.appendFlavour(this._view.peerDropTypes[i]);
return flavorSet;
},
handleEvent: function(aEvent) {
switch (aEvent.type) {
case "draggesture":
if (aEvent.target.localName != "menu" && aEvent.target.node) {
// TODO--allow menu drag if shift (or alt??) key is down
nsDragAndDrop.startDrag(aEvent, this);
}
break;
case "dragover":
nsDragAndDrop.dragOver(aEvent, this);
break;
case "dragdrop":
nsDragAndDrop.drop(aEvent, this);
break;
case "dragexit":
nsDragAndDrop.dragExit(aEvent, this);
break;
}
}
}
/** /**
* Handles drag and drop operations for views. Note that this is view agnostic! * Handles drag and drop operations for views. Note that this is view agnostic!
* You should not use PlacesController._view within these methods, since * You should not use PlacesController._view within these methods, since
@ -1273,9 +1566,9 @@ var PlacesControllerDragHelper = {
* it is being dragged over, false otherwise. * it is being dragged over, false otherwise.
*/ */
canDrop: function PCDH_canDrop(view, orientation) { canDrop: function PCDH_canDrop(view, orientation) {
var parent = view.getResult().root; var root = view.getResult().root;
if (PlacesUtils.nodeIsReadOnly(parent) || if (PlacesUtils.nodeIsReadOnly(root) ||
!PlacesUtils.nodeIsFolder(parent)) !PlacesUtils.nodeIsFolder(root))
return false; return false;
var session = this.getSession(); var session = this.getSession();
@ -1335,21 +1628,21 @@ var PlacesControllerDragHelper = {
var xferable = this._initTransferable(session, targetView, var xferable = this._initTransferable(session, targetView,
insertionPoint.orientation); insertionPoint.orientation);
var dropCount = session.numDropItems; var dropCount = session.numDropItems;
var movedCount = 0; var movedCount = 0;
for (var i = 0; i < dropCount; ++i) { for (var i = 0; i < dropCount; ++i) {
session.getData(xferable, i); session.getData(xferable, i);
var data = { }, flavor = { }; var data = { }, flavor = { };
xferable.getAnyTransferData(flavor, data, { }); xferable.getAnyTransferData(flavor, data, { });
data.value.QueryInterface(Ci.nsISupportsString); data.value.QueryInterface(Ci.nsISupportsString);
// There's only ever one in the D&D case. // There's only ever one in the D&D case.
var unwrapped = PlacesUtils.unwrapNodes(data.value.data, var unwrapped = PlacesUtils.unwrapNodes(data.value.data,
flavor.value)[0]; flavor.value)[0];
var index = insertionPoint.index; var index = insertionPoint.index;
// Adjust insertion index to prevent reversal of dragged items. When you // Adjust insertion index to prevent reversal of dragged items. When you
// drag multiple elts upward: need to increment index or each successive // drag multiple elts upward: need to increment index or each successive
// elt will be inserted at the same index, each above the previous. // elt will be inserted at the same index, each above the previous.
@ -1358,7 +1651,7 @@ var PlacesControllerDragHelper = {
index = index + movedCount; index = index + movedCount;
movedCount++; movedCount++;
} }
transactions.push(PlacesUtils.makeTransaction(unwrapped, transactions.push(PlacesUtils.makeTransaction(unwrapped,
flavor.value, insertionPoint.itemId, flavor.value, insertionPoint.itemId,
index, copy)); index, copy));

Просмотреть файл

@ -571,11 +571,28 @@ var gEditItemOverlay = {
expander.className = "expander-up" expander.className = "expander-up"
expander.setAttribute("tooltiptext", expander.setAttribute("tooltiptext",
expander.getAttribute("tooltiptextup")); expander.getAttribute("tooltiptextup"));
if (!this._folderTree.treeBoxObject.view.isContainerOpen(0))
this._folderTree.treeBoxObject.view.toggleOpenState(0);
this._folderTree.selectFolders([this._getFolderIdFromMenuList()]);
this._folderTree.collapsed = false; this._folderTree.collapsed = false;
this._folderTree.focus(); if (!this._folderTree.place) {
const FOLDER_TREE_PLACE_URI =
"place:folder=2&excludeItems=1&excludeQueries=1&excludeReadOnlyFolders=1";
this._folderTree.place = FOLDER_TREE_PLACE_URI;
}
var currentFolder = this._getFolderIdFromMenuList();
// Don't select anything in the tree if the item is "unfiled"
if (currentFolder == PlacesUtils.unfiledRootId)
this._folderTree.selectFolders([]);
else {
this._folderTree.selectFolders([currentFolder]);
this._folderTree.focus();
}
if ((currentFolder == PlacesUtils.bookmarksRootId ||
currentFolder == PlacesUtils.unfiledRootId) &&
!this._folderTree.treeBoxObject.view.isContainerOpen(0)) {
// Expand the root node if selectFolder didn't
this._folderTree.treeBoxObject.view.toggleOpenState(0);
}
} }
}, },

Просмотреть файл

@ -144,7 +144,6 @@
collapsed="true" collapsed="true"
onselect="gEditItemOverlay.onFolderTreeSelect();" onselect="gEditItemOverlay.onFolderTreeSelect();"
showRoot="true" showRoot="true"
place="place:folder=2&amp;excludeItems=1&amp;excludeQueries=1&amp;excludeReadOnlyFolders=1"
hidecolumnpicker="true" hidecolumnpicker="true"
observes="paneElementsBroadcaster"> observes="paneElementsBroadcaster">
<treecols> <treecols>

Просмотреть файл

@ -114,6 +114,7 @@
</hbox> </hbox>
<tree id="historyTree" <tree id="historyTree"
class="sidebar-placesTree"
flex="1" flex="1"
type="places" type="places"
context="placesContext" context="placesContext"
@ -123,6 +124,6 @@
<treecols> <treecols>
<treecol id="title" flex="1" primary="true" hideheader="true"/> <treecol id="title" flex="1" primary="true" hideheader="true"/>
</treecols> </treecols>
<treechildren flex="1"/> <treechildren class="sidebar-placesTreechildren" flex="1"/>
</tree> </tree>
</page> </page>

Просмотреть файл

@ -80,34 +80,21 @@
<field name="_built">false</field> <field name="_built">false</field>
<field name="_ignoreInvalidateContainer">false</field>
<method name="onPopupShowing"> <method name="onPopupShowing">
<parameter name="aEvent"/>
<body><![CDATA[ <body><![CDATA[
this._ensureInitialized(); var popup = aEvent.target;
var resultNode = popup._resultNode;
if (!this._resultNode.containerOpen) resultNode.containerOpen = true;
this._resultNode.containerOpen = true; if (!popup._built)
if (!this._built) this._rebuild(popup);
this._rebuild(); if (!popup._DNDObserver)
popup._DNDObserver = new PlacesMenuDNDObserver(this, popup);
if (this.popupShowingCallback)
this.popupShowingCallback();
]]></body> ]]></body>
</method> </method>
<field name="_selection">null</field> <field name="_selection">null</field>
<method name="setResultAndNode">
<parameter name="result"/>
<parameter name="resultNode"/>
<body><![CDATA[
this._result = result;
this._resultNode = resultNode;
this._rebuild();
]]></body>
</method>
<!-- nsIPlacesView --> <!-- nsIPlacesView -->
<method name="getResult"> <method name="getResult">
<body><![CDATA[ <body><![CDATA[
@ -118,42 +105,32 @@
<!-- nsIPlacesView --> <!-- nsIPlacesView -->
<method name="getResultNode"> <method name="getResultNode">
<body><![CDATA[ <body><![CDATA[
this._ensureInitialized();
return this._resultNode; return this._resultNode;
]]></body> ]]></body>
</method> </method>
<!-- These are the indices of the start and end
of dynamic content in the menu. For index,
if this is a bookmark menu and it has two
static entries at the top, "Bookmark this page"
and "Bookmark all tabs", _startMarker will be
2. If it has an "open in tabs" item at the end,
_endMarker will be the index of that item.
If there is no static content in the menu,
_startMarker and _endMarker are -1. -->
<field name="_startMarker">-1</field>
<field name="_endMarker">-1</field>
<method name="_cleanMenu"> <method name="_cleanMenu">
<parameter name="aPopup"/>
<body><![CDATA[ <body><![CDATA[
// Find static menuitems that should go at the start // Find static menuitems that should go at the start
// and end of the menu, marked by builder="start" and // and end of the menu, marked by builder="start" and
// builder="end" attributes, and keep track of their indices. // builder="end" attributes, and keep track of their indices.
// All of the items between the start and end should be removed. // All of the items between the start and end should be removed.
var items = []; var items = [];
this._startMarker = -1; aPopup._startMarker = -1;
this._endMarker = -1; aPopup._endMarker = -1;
for (var i = 0; i < this.childNodes.length; ++i) { for (var i = 0; i < aPopup.childNodes.length; ++i) {
var item = this.childNodes[i]; var item = aPopup.childNodes[i];
if (item.getAttribute("builder") == "start") { if (item.getAttribute("builder") == "start") {
this._startMarker = i; aPopup._startMarker = i;
continue; continue;
} }
if (item.getAttribute("builder") == "end") { if (item.getAttribute("builder") == "end") {
this._endMarker = i; aPopup._endMarker = i;
continue; continue;
} }
if ((this._startMarker != -1) && (this._endMarker == -1)) if ((aPopup._startMarker != -1) && (aPopup._endMarker == -1))
items.push(item); items.push(item);
} }
@ -161,8 +138,8 @@
// them and the static content at the end. // them and the static content at the end.
for (var i = 0; i < items.length; ++i) { for (var i = 0; i < items.length; ++i) {
// skip the empty menu item // skip the empty menu item
if (this._emptyMenuItem != items[i]) { if (aPopup._emptyMenuItem != items[i]) {
items[i].parentNode.removeChild(items[i]); aPopup.removeChild(items[i]);
if (this._endMarker > 0) if (this._endMarker > 0)
--this._endMarker; --this._endMarker;
} }
@ -170,18 +147,18 @@
// If no static items were found at the beginning, remove all items before // If no static items were found at the beginning, remove all items before
// the static items at the end. // the static items at the end.
if (this._startMarker == -1) { if (aPopup._startMarker == -1) {
var end = (this._endMarker == -1) ? this.childNodes.length - 1 : this._endMarker - 1; var end = aPopup._endMarker == -1 ?
aPopup.childNodes.length - 1 : aPopup._endMarker - 1;
for (var i = end; i >=0; i--) { for (var i = end; i >=0; i--) {
// skip the empty menu item // skip the empty menu item
if (this._emptyMenuItem != this.childNodes[i]) { if (aPopup._emptyMenuItem != aPopup.childNodes[i]) {
this.removeChild(this.childNodes[i]); aPopup.removeChild(aPopup.childNodes[i]);
if (this._endMarker > 0) if (aPopup._endMarker > 0)
--this._endMarker; --aPopup._endMarker;
} }
} }
} }
//LOG("KIDS = " + this.childNodes.length);
]]></body> ]]></body>
</method> </method>
@ -190,157 +167,78 @@
<body><![CDATA[ <body><![CDATA[
if (PlacesUtils.nodeIsContainer(child.node)) { if (PlacesUtils.nodeIsContainer(child.node)) {
for (var i=0; i < this._containerNodesMap.length; i++) { for (var i=0; i < this._containerNodesMap.length; i++) {
if (this._containerNodesMap[i].resultNode == child.node) if (this._containerNodesMap[i].resultNode == child.node) {
this._containerNodesMap.splice(i, 1); this._containerNodesMap.splice(i, 1);
break;
}
} }
} }
this.removeChild(child); child.parentNode.removeChild(child);
]]></body> ]]></body>
</method> </method>
<method name="insertNewItem"> <method name="insertNewItem">
<parameter name="child"/> <parameter name="aChild"/>
<parameter name="before"/> <parameter name="aParentPopup"/>
<parameter name="aBefore"/>
<body><![CDATA[ <body><![CDATA[
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; var element =
var element = null; PlacesUtils.createMenuItemForNode(aChild, this._containerNodesMap);
if (PlacesUtils.nodeIsURI(child)) {
element = document.createElementNS(XULNS, "menuitem");
element.setAttribute("label", child.title);
element.setAttribute("url", child.uri);
element.setAttribute("statustext", child.uri);
element.className = "menuitem-iconic bookmark-item";
}
else if (PlacesUtils.nodeIsSeparator(child)) {
element = document.createElementNS(XULNS, "menuseparator");
}
else if (PlacesUtils.nodeIsContainer(child)) {
element = document.createElementNS(XULNS, "menu");
element.setAttribute("type", "menu");
element.setAttribute("container", "true");
element.setAttribute("label", child.title);
if (PlacesUtils.nodeIsLivemarkContainer(child)) { if (aBefore)
element.setAttribute("livemark", "true"); aParentPopup.insertBefore(element, aBefore);
var folder = child.itemId; else {
var siteURI = PlacesUtils.livemarks.getSiteURI(folder); // Add the new element to the menu. If there is static content at
if (siteURI) // the end of the menu, add the element before that. Otherwise,
element.setAttribute("siteURI", siteURI.spec); // just add to the end.
} if (aParentPopup._endMarker != -1)
var popup = document.createElementNS(XULNS, "menupopup"); aParentPopup.insertBefore(element,
popup.setAttribute("type", "places"); aParentPopup.childNodes[this._endMarker++]);
element.appendChild(popup); else
#ifndef XP_MACOSX aParentPopup.appendChild(element);
// No context menus on menus on Mac
// The context menu is set here instead of in the xbl constructor
// because it doesn't get initialized properly if set in the constructor.
popup.setAttribute("context", "placesContext");
#endif
popup._result = this._result;
popup._resultNode = asContainer(child);
element.className = "menu-iconic bookmark-item";
#ifdef XP_MACOSX
// If this is a child of the bookmarks menubar, we have to manually attach
// its xbl binding, because it's not a dom node and the style rules don't
// get applied correctly.
if (this._needsBindingAttachment) {
const MENU_URI = "chrome://browser/content/places/menu.xml#places-menupopup";
document.addBinding(popup, MENU_URI);
}
#endif
popup._containerNodesMap = this._containerNodesMap;
this._containerNodesMap.push({ resultNode: child, domNode: popup });
}
if (element) {
element.node = child;
element.node.viewIndex = 0;
if (child.icon)
element.setAttribute("image", child.icon.spec);
if (before)
this.insertBefore(element, before);
else {
// Add the new element to the menu. If there is static content at
// the end of the menu, add the element before that. Otherwise,
// just add to the end.
if (this._endMarker != -1)
this.insertBefore(element, this.childNodes[this._endMarker++]);
else
this.appendChild(element);
}
} }
]]></body> ]]></body>
</method> </method>
#ifdef XP_MACOSX
<field name="_needsBindingAttachment">false</field>
#endif
<field name="_emptyMenuItem">null</field>
<method name="_showEmptyMenuItem"> <method name="_showEmptyMenuItem">
<parameter name="aPopup"/>
<body><![CDATA[ <body><![CDATA[
if (this._emptyMenuItem) { if (aPopup._emptyMenuItem) {
this._emptyMenuItem.hidden = false; aPopup._emptyMenuItem.hidden = false;
return; return;
} }
var label = PlacesUtils.getString("bookmarksMenuEmptyFolder"); var label = PlacesUtils.getString("bookmarksMenuEmptyFolder");
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; aPopup._emptyMenuItem = document.createElement("menuitem");
this._emptyMenuItem = document.createElementNS(XULNS, "menuitem"); aPopup._emptyMenuItem.setAttribute("label", label);
this._emptyMenuItem.setAttribute("label", label); aPopup._emptyMenuItem.setAttribute("disabled", true);
this._emptyMenuItem.setAttribute("disabled", true); aPopup.appendChild(aPopup._emptyMenuItem);
this.appendChild(this._emptyMenuItem);
]]></body> ]]></body>
</method> </method>
<method name="_rebuild"> <method name="_rebuild">
<parameter name="aPopup"/>
<body><![CDATA[ <body><![CDATA[
// Make sure not to hold onto any references to menu nodes when we this._cleanMenu(aPopup);
// rebuild, since rebuilding deletes all the nodes in the menu and
// re-adds them. If we use a reference to a deleted node, all kinds
// of exceptions and asserts will fire.
if (this._DNDObserver._overFolder.node)
this._DNDObserver._clearOverFolder();
this._cleanMenu(); var cc = aPopup._resultNode.childCount;
NS_ASSERT(PlacesUtils.nodeIsContainer(this._resultNode),
"Result-node of a places popup has to be a container node");
#ifdef XP_MACOSX
// On Mac OSX, we need to manually attach the XBL binding for the bookmarks menu,
// because menus in the OSX menubar aren't real DOM nodes, and they don't get styles
// applied.
var currentNode = this.parentNode;
while (currentNode && !this._needsBindingAttachment) {
if (currentNode.id && currentNode.id == "bookmarksMenu")
this._needsBindingAttachment = true;
currentNode = currentNode.parentNode;
}
#endif
NS_ASSERT(this._resultNode.containerOpen,
"container must be opened when _rebuild is called");
var cc = this._resultNode.childCount;
if (cc > 0) { if (cc > 0) {
if (this._emptyMenuItem) if (aPopup._emptyMenuItem)
this._emptyMenuItem.hidden = true; aPopup._emptyMenuItem.hidden = true;
for (var i = 0; i < cc; ++i) { for (var i = 0; i < cc; ++i) {
var child = this._resultNode.getChild(i); var child = aPopup._resultNode.getChild(i);
this.insertNewItem(child, null); this.insertNewItem(child, aPopup, null);
} }
} }
else { else {
// This menu is empty. If there is no static content, add // This menu is empty. If there is no static content, add
// an element to show it is empty. // an element to show it is empty.
if (this._startMarker == -1 && this._endMarker == -1) if (aPopup._startMarker == -1 && aPopup._endMarker == -1)
this._showEmptyMenuItem(); this._showEmptyMenuItem(aPopup);
} }
this._built = true; aPopup._built = true;
]]></body> ]]></body>
</method> </method>
@ -348,72 +246,60 @@
<field name="_viewer"><![CDATA[({ <field name="_viewer"><![CDATA[({
_self: this, _self: this,
_forwardToChildView: _getPopupForContainer:
function PMV__forwardToChildView(aNode, aFunction, aArguments) { function PMV__getPopupForContainer(aNode) {
if (this._self._resultNode == aNode)
return this._self;
for (var i=0; i < this._self._containerNodesMap.length; i++) { for (var i=0; i < this._self._containerNodesMap.length; i++) {
if (this._self._containerNodesMap[i].resultNode == aNode) { if (this._self._containerNodesMap[i].resultNode == aNode)
var childView = this._self._containerNodesMap[i].domNode._viewer; return this._self._containerNodesMap[i].domNode;
childView[aFunction].apply(childView, aArguments);
return;
}
} }
throw("Container view not found"); throw("Container view not found");
}, },
itemInserted: function PMV_itemInserted(aParentNode, aNode, aIndex) { itemInserted: function PMV_itemInserted(aParentNode, aNode, aIndex) {
if (!this._self._built) var popup = this._getPopupForContainer(aParentNode);
if (!popup._built)
return; return;
if (aParentNode == this._self.getResultNode()) { var index = popup._startMarker + 1 + aIndex;
var index = this._self._startMarker + 1 + aIndex; var before = popup.childNodes[index] || null;
var before = this._self.childNodes[index] || null; this._self.insertNewItem(aNode, popup, before);
this._self.insertNewItem(aNode, before); if (popup._emptyMenuItem)
if (this._self._emptyMenuItem) popup._emptyMenuItem.hidden = true;
this._self._emptyMenuItem.hidden = true;
}
else
this._forwardToChildView(aParentNode, "itemInserted", arguments);
}, },
itemRemoved: function PMV_itemRemoved(aParentNode, aNode, aIndex) { itemRemoved: function PMV_itemRemoved(aParentNode, aNode, aIndex) {
if (!this._self._built) var popup = this._getPopupForContainer(aParentNode);
if (!popup._built)
return; return;
if (aParentNode == this._self.getResultNode()) { var children = popup.childNodes;
var children = this._self.childNodes; for (var i = 0; i < children.length; i++) {
if (children[i].node == aNode) {
for (var i = 0; i < children.length; i++) { this._self.removeItem(children[i]);
if (children[i].node == aNode) { if (!popup.hasChildNodes() ||
this._self.removeItem(children[i]); (popup.childNodes.length == 1 &&
if (!this._self.hasChildNodes() || popup.firstChild == popup._emptyMenuItem)) {
(this._self.childNodes.length == 1 && this._self._showEmptyMenuItem(popup);
this._self.firstChild == this._self._emptyMenuItem)) {
this._self._showEmptyMenuItem();
}
} }
} }
} }
else
this._forwardToChildView(aParentNode, "itemRemoved", arguments);
}, },
itemChanged: function PMV_itemChanged(aNode) { itemChanged: function PMV_itemChanged(aNode) {
if (!this._self._built)
return;
// this check can be removed once we fix bug #382397 // this check can be removed once we fix bug #382397
var parentNode = aNode.parent; var parentNode = aNode.parent;
if (!parentNode) if (!parentNode)
return; return;
if (parentNode != this._self.getResultNode()) { var popup = this._getPopupForContainer(parentNode);
this._forwardToChildView(parentNode, "itemChanged", arguments); if (!popup._built)
return; return;
}
var children = popup.childNodes;
var menuitem; var menuitem;
var children = this._self.childNodes;
for (var i = 0; i < children.length; i++) { for (var i = 0; i < children.length; i++) {
if (children[i].node == aNode) { if (children[i].node == aNode) {
menuitem = children[i]; menuitem = children[i];
@ -421,58 +307,40 @@
} }
} }
NS_ASSERT(menuitem, "unable to find menuitem");
if (!menuitem)
return;
var title = aNode.title;
if (PlacesUtils.nodeIsSeparator(aNode)) { if (PlacesUtils.nodeIsSeparator(aNode)) {
// nothing to do when a separator changes // nothing to do when a separator changes
return; return;
} }
else if (PlacesUtils.nodeIsContainer(aNode)) {
if (PlacesUtils.nodeIsLivemarkContainer(aNode)) {
var folder = aNode.itemId;
var siteURIString = PlacesUtils.livemarks.getSiteURI(folder);
if (siteURIString) {
if (menuitem.getAttribute("siteURI") != siteURIString)
menuitem.setAttribute("siteURI", siteURIString);
}
else
menuitem.removeAttribute("siteURI");
}
}
if (aNode.icon) { var iconURI = aNode.icon;
if (menuitem.getAttribute("image") != aNode.icon.spec) if (iconURI) {
menuitem.setAttribute("image", aNode.icon.spec); var spec = iconURI.spec;
if (menuitem.getAttribute("image") != spec)
menuitem.setAttribute("image", spec);
} }
else else
menuitem.removeAttribute("image"); menuitem.removeAttribute("image");
var title = aNode.title;
if (menuitem.getAttribute("label") != title) if (menuitem.getAttribute("label") != title)
menuitem.setAttribute("label", title); menuitem.setAttribute("label", title);
}, },
itemReplaced: itemReplaced:
function PMV_itemReplaced(aParentNode, aOldNode, aNewNode, aIndex) { function PMV_itemReplaced(aParentNode, aOldNode, aNewNode, aIndex) {
if (!this._self._built) var popup = this._getPopupForContainer(aParentNode);
if (!popup._built)
return; return;
if (aParentNode == this._self.getResultNode()) { var children = popup.childNodes;
var children = this._self.childNodes; for (var i = 0; i < children.length; i++) {
for (var i = 0; i < children.length; i++) { if (children[i].node == aOldNode) {
if (children[i].node == aOldNode) { var next = children[i].nextSibling;
var next = children[i].nextSibling; this._self.removeItem(children[i]);
this._self.removeItem(children[i]); this._self.insertNewItem(aNewNode, popup, next);
this._self.insertNewItem(aNewNode, next); return;
return;
}
} }
} }
else
this._forwardToChildView(aParentNode, "itemReplaced", arguments);
}, },
containerOpened: function PMV_containerOpened(aNode) { containerOpened: function PMV_containerOpened(aNode) {
@ -483,18 +351,7 @@
this.invalidateContainer(aNode); this.invalidateContainer(aNode);
}, },
get ignoreInvalidateContainer() {
return this._self._ignoreInvalidateContainer;
},
set ignoreInvalidateContainer(val) {
return this._self._ignoreInvalidateContainer = val;
},
invalidateContainer: function PMV_invalidateContainer(aContainer) { invalidateContainer: function PMV_invalidateContainer(aContainer) {
if (this._self_ignoreInvalidateContainer)
return;
if (!this._self._built) if (!this._self._built)
return; return;
@ -508,22 +365,22 @@
return false; return false;
} }
var viewerToRebuild = null; var popupToRebuild = null;
for (var i=0; i < this._self._containerNodesMap.length; i++) { for (var i=0; i < this._self._containerNodesMap.length; i++) {
var node = this._self._containerNodesMap[i].resultNode; var node = this._self._containerNodesMap[i].resultNode;
if (node == aContainer) if (node == aContainer)
viewerToRebuild = this._self._containerNodesMap[i].domNode._viewer; popupToRebuild = this._self._containerNodesMap[i].domNode;
if (isChildOf(node, aContainer)) if (isChildOf(node, aContainer)) {
this._self._containerNodesMap.splice(i,1); this._self._containerNodesMap.splice(i,1);
i--;
}
} }
if (aContainer.containerOpen) { if (popupToRebuild)
if (viewerToRebuild) popupToRebuild._built = false;
viewerToRebuild._built = false; else
else this._self._built = false;
this._self._built = false;
}
}, },
invalidateAll: function PMV_invalidateAll() { invalidateAll: function PMV_invalidateAll() {
@ -535,21 +392,6 @@
} }
})]]></field> })]]></field>
<!-- Sometimes calling hidePopup() on a menu can leave submenus
open. This calls hidePopup() on the menu and recursively
hides its submenus as well. -->
<method name="hidePopupAndChildPopups">
<body><![CDATA[
for (var i = 0; i < this.childNodes.length; i++) {
if (this.childNodes[i].getAttribute("type") == "menu" &&
this.childNodes[i].lastChild &&
this.childNodes[i].lastChild.getAttribute("type") == "places")
this.childNodes[i].lastChild.hidePopupAndChildPopups();
}
this.hidePopup();
]]></body>
</method>
<!-- nsIPlacesView --> <!-- nsIPlacesView -->
<property name="place"> <property name="place">
<getter><![CDATA[ <getter><![CDATA[
@ -655,6 +497,7 @@
} else { } else {
// If there is another type of node selected, the insertion point // If there is another type of node selected, the insertion point
// is after that node. // is after that node.
folderId = this.selectedNode.parent.itemId;
index = PlacesUtils.getIndexOfNode(this.selectedNode) index = PlacesUtils.getIndexOfNode(this.selectedNode)
} }
} }
@ -686,241 +529,6 @@
]]></body> ]]></body>
</method> </method>
<field name="_DNDObserver"><![CDATA[({
// Inside the _DNDObserver object's functions, this points to
// the _DNDObserver object. _self points to the menu xbl object.
_self: this,
// Subfolders should be opened when the mouse drags over them, and closed
// when the mouse drags off. The overFolder object manages opening and closing
// of folders when the mouse hovers.
_overFolder: {node: null, openTimer: null, hoverTime: 350, closeTimer: null},
// If this menu's parent auto-opened it because it was dragged over, but didn't
// close it because the mouse dragged into it, the menu should close itself
// onDragExit. This timer is set in dragExit to close the menu.
_closeMenuTimer: null,
_setTimer: function TBV_DO_setTimer(time) {
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.initWithCallback(this, time, timer.TYPE_ONE_SHOT);
return timer;
},
// Function to process all timer notifications.
notify: function TBV_DO_notify(timer) {
// Timer to open a submenu that's being dragged over.
if (timer == this._overFolder.openTimer) {
this._overFolder.node.lastChild.setAttribute("autoopened", "true");
this._overFolder.node.lastChild.showPopup(this._overFolder.node);
this._overFolder.openTimer = null;
}
// Timer to close a submenu that's been dragged off of.
if (timer == this._overFolder.closeTimer) {
// Only close the submenu if the mouse isn't being dragged over any
// of its child menus.
var draggingOverChild =
PlacesControllerDragHelper.draggingOverChildNode(this._overFolder.node);
if (draggingOverChild)
this._overFolder.node = null;
this._clearOverFolder();
// Close any parent folders which aren't being dragged over.
// (This is necessary because of the above code that keeps a folder
// open while its children are being dragged over.)
if (!draggingOverChild)
this._closeParentMenus();
}
// Timer to close this menu after the drag exit.
if (timer == this._closeMenuTimer) {
if (!PlacesControllerDragHelper.draggingOverChildNode(this._self)) {
this._self.hidePopupAndChildPopups();
// Close any parent menus that aren't being dragged over;
// otherwise they'll stay open because they couldn't close
// while this menu was being dragged over.
this._closeParentMenus();
}
}
},
// Helper function to close all parent menus of this menu,
// as long as none of the parent's children are currently being
// dragged over.
_closeParentMenus: function TBV_DO_closeParentMenus() {
var parent = this._self.parentNode;
while(parent) {
if (parent.nodeName == "menupopup" &&
parent.getAttribute("type") == "places") {
if (PlacesControllerDragHelper.draggingOverChildNode(parent.parentNode))
break;
parent.hidePopup();
}
parent = parent.parentNode;
}
},
// The mouse is no longer dragging over the stored menubutton.
// Close the menubutton, clear out drag styles, and clear all
// timers for opening/closing it.
_clearOverFolder: function TBV_DO_clearOverFolder() {
if (this._overFolder.node && this._overFolder.node.lastChild) {
if (!this._overFolder.node.lastChild.hasAttribute("dragover"))
this._overFolder.node.lastChild.hidePopupAndChildPopups();
this._overFolder.node = null;
}
if (this._overFolder.openTimer) {
this._overFolder.openTimer.cancel();
this._overFolder.openTimer = null;
}
if (this._overFolder.closeTimer) {
this._overFolder.closeTimer.cancel();
this._overFolder.closeTimer = null;
}
},
// This function returns information about where to drop when
// dragging over this menu--insertion point, child index to drop
// before, and folder to drop into.
_getDropPoint: function TBV_DO_getDropPoint(event) {
// Can't drop if the menu isn't a folder
var resultNode = this._self._resultNode;
if (!PlacesUtils.nodeIsFolder(this._self._result.root) ||
!PlacesUtils.nodeIsFolder(resultNode))
return null;
var dropPoint = { ip: null, beforeIndex: null, folderNode: null };
// Loop through all the nodes to see which one this should
// get dropped in/above/below.
// Ignore static content at the top and bottom of the menu.
var start = (this._self._startMarker != -1) ? (this._self._startMarker + 1) : 0;
var end = (this._self._endMarker != -1) ? this._self._endMarker : this._self.childNodes.length;
for (var i = start; i < end; i++) {
var xulNode = this._self.childNodes[i];
var nodeY = xulNode.boxObject.y - this._self.boxObject.y;
var nodeHeight = xulNode.boxObject.height;
if (xulNode.node &&
PlacesUtils.nodeIsFolder(xulNode.node) &&
!PlacesUtils.nodeIsReadOnly(xulNode.node)) {
// This is a folder. If the mouse is in the top 25% of the
// node, drop above the folder. If it's in the middle
// 50%, drop into the folder. If it's past that, drop below.
if (event.clientY < nodeY + (nodeHeight * 0.25)) {
// Drop above this folder.
dropPoint.ip = new InsertionPoint(resultNode.itemId, i - start,
-1);
dropPoint.beforeIndex = i;
return dropPoint;
}
else if (event.clientY < nodeY + (nodeHeight * 0.75)) {
// Drop inside this folder.
dropPoint.ip = new InsertionPoint(xulNode.node.itemId, -1, 1);
dropPoint.beforeIndex = i;
dropPoint.folderNode = xulNode;
return dropPoint;
}
} else {
// This is a non-folder node. If the mouse is above the middle,
// drop above the folder. Otherwise, drop below.
if (event.clientY < nodeY + (nodeHeight / 2)) {
// Drop above this bookmark.
dropPoint.ip = new InsertionPoint(resultNode.itemId, i - start, -1);
dropPoint.beforeIndex = i;
return dropPoint;
}
}
}
// Should drop below the last node.
dropPoint.ip = new InsertionPoint(resultNode.itemId, -1, 1);
dropPoint.beforeIndex = -1;
return dropPoint;
},
// This function clears all of the dragover styles that were set when
// a menuitem was dragged over.
_clearStyles: function TBV_DO_clearStyles() {
this._self.removeAttribute("dragover");
for (var i = 0; i < this._self.childNodes.length; i++) {
this._self.childNodes[i].removeAttribute("dragover-top");
this._self.childNodes[i].removeAttribute("dragover-bottom");
this._self.childNodes[i].removeAttribute("dragover-into");
}
},
onDragStart: function TBV_DO_onDragStart(event, xferData, dragAction) {
this._self._selection = event.target.node;
this._self._cachedInsertionPoint = undefined;
if (event.ctrlKey)
dragAction.action = Ci.nsIDragService.DRAGDROP_ACTION_COPY;
xferData.data = this._self._controller.getTransferData(dragAction.action);
},
canDrop: function TBV_DO_canDrop(event, session) {
return PlacesControllerDragHelper.canDrop(this._self, -1);
},
onDragOver: function TBV_DO_onDragOver(event, flavor, session) {
PlacesControllerDragHelper.currentDropTarget = event.target;
var dropPoint = this._getDropPoint(event);
if (dropPoint == null)
return;
this._clearStyles();
if (dropPoint.folderNode) {
// Dragging over a folder; set the appropriate styles.
if (this._overFolder.node != dropPoint.folderNode) {
this._clearOverFolder();
this._overFolder.node = dropPoint.folderNode;
this._overFolder.openTimer = this._setTimer(this._overFolder.hoverTime);
}
dropPoint.folderNode.setAttribute("dragover-into", "true");
}
else {
// Dragging over a menuitem, set dragover-top/bottom to show where
// the item will be dropped and clear out any old folder info.
if (dropPoint.beforeIndex == -1) {
if (this._self.endMatch)
this._self.childNodes[this._self.endMatch].setAttribute("dragover-top", "true");
else
this._self.lastChild.setAttribute("dragover-bottom", "true");
}
else {
this._self.childNodes[dropPoint.beforeIndex].setAttribute("dragover-top", "true");
}
// Clear out old folder information
this._clearOverFolder();
}
this._self.setAttribute("dragover", "true");
},
onDrop: function TBV_DO_onDrop(event, dropData, session) {
var dropPoint = this._getDropPoint(event);
if (dropPoint == null)
return;
PlacesControllerDragHelper.onDrop(null, this._self, dropPoint.ip);
},
onDragExit: function TBV_DO_onDragExit(event, session) {
PlacesControllerDragHelper.currentDropTarget = null;
this._clearStyles();
// Close any folder being hovered over
if (this._overFolder.node)
this._overFolder.closeTimer = this._setTimer(this._overFolder.hoverTime);
// The autoopened attribute is set when this folder was automatically
// opened after the user dragged over it. If this attribute is set,
// auto-close the folder on drag exit.
if (this._self.hasAttribute("autoopened"))
this._closeMenuTimer = this._setTimer(this._overFolder.hoverTime);
},
getSupportedFlavours: function TBV_DO_getSupportedFlavours() {
var flavorSet = new FlavourSet();
for (var i = 0; i < this._self.peerDropTypes.length; ++i)
flavorSet.appendFlavour(this._self.peerDropTypes[i]);
return flavorSet;
}
})]]></field>
<property name="selType" readonly="true" onget="return 'single';"/> <property name="selType" readonly="true" onget="return 'single';"/>
<method name="buildContextMenu"> <method name="buildContextMenu">
@ -943,64 +551,48 @@
</method> </method>
</implementation> </implementation>
<handlers> <handlers>
<handler event="popupshowing"> <handler event="popupshowing" phase="capturing">
if (event.target == this) this._ensureInitialized();
this.onPopupShowing(); if (event.target._resultNode)
this.onPopupShowing(event);
</handler> </handler>
<handler event="popuphidden"> <handler event="popuphidden">
if (event.target != this) var popup = event.target;
if (!popup._resultNode)
return; return;
// UI performance: folder queries are cheap, keep the resultnode open // UI performance: folder queries are cheap, keep the resultnode open
// so we don't rebuild its contents whenever the popup is reopened. // so we don't rebuild its contents whenever the popup is reopened.
if (!PlacesUtils.nodeIsFolder(this._resultNode)) { if (!PlacesUtils.nodeIsFolder(popup._resultNode))
this._resultNode.containerOpen = false; popup._resultNode.containerOpen = false;
this._built = false;
}
// The autoopened attribute is set for folders which have been // The autoopened attribute is set for folders which have been
// automatically opened when dragged over. Turn off this attribute // automatically opened when dragged over. Turn off this attribute
// when the folder closes because it is no longer applicable. // when the folder closes because it is no longer applicable.
this.removeAttribute("autoopened"); popup.removeAttribute("autoopened");
</handler> </handler>
<!-- Set selected node on DOMMenuItemActive/contextmenu events <!-- Set selected node on DOMMenuItemActive/contextmenu events
so that they're set up when command and click events fire. --> so that they're set up when command and click events fire. -->
<handler event="DOMMenuItemActive"><![CDATA[ <handler event="DOMMenuItemActive"><![CDATA[
if (event.target.parentNode == this) { // Set the selection to the node that was activated. If that
// Set the selection to the node that was activated. If that // node has a command but no data associated with it, it should
// node has a command but no data associated with it, it should // act on the entire menu.
// act on the entire menu. if (event.target.parentNode._resultNode) {
this._cachedInsertionPoint = undefined; this._cachedInsertionPoint = undefined;
this._selection = event.target.node || this._resultNode; this._selection = event.target.node ||
event.target.parentNode._resultNode;
} }
]]></handler> ]]></handler>
<handler event="contextmenu"><![CDATA[ <handler event="contextmenu"><![CDATA[
// DOMMenuItemActive is not dispatched for disabled menuitems and // DOMMenuItemActive is not dispatched for disabled menuitems and
// menuseparators. Set the selection here manually. // menuseparators. Set the selection here manually.
var popupNode = document.popupNode; var popupNode = document.popupNode;
// |popupNode == this| happens when the area between menuseparators // |popupNode == menupopup| happens when the area between
// is clicked. // menuseparators is clicked.
if (popupNode == this || popupNode.parentNode == this) { this._selection = popupNode.node || popupNode.parentNode._resultNode;
this._selection = popupNode.node || this._resultNode; this._cachedInsertionPoint = undefined;
this._cachedInsertionPoint = undefined;
}
]]></handler>
<handler event="draggesture"><![CDATA[
if (event.target.localName == "menuitem")
// TODO--allow menu drag if shift (or alt??) key is down
nsDragAndDrop.startDrag(event, this._DNDObserver);
]]></handler>
<handler event="dragover"><![CDATA[
nsDragAndDrop.dragOver(event, this._DNDObserver);
]]></handler>
<handler event="dragdrop"><![CDATA[
nsDragAndDrop.drop(event, this._DNDObserver);
]]></handler>
<handler event="dragexit"><![CDATA[
nsDragAndDrop.dragExit(event, this._DNDObserver);
]]></handler> ]]></handler>
</handlers> </handlers>
</binding> </binding>

Просмотреть файл

@ -52,12 +52,9 @@ var gMoveBookmarksDialog = {
this._nodes = window.arguments[0]; this._nodes = window.arguments[0];
this._tm = window.arguments[1]; this._tm = window.arguments[1];
// setTimeout until bug 373944 is fixed // select and expand the root node
setTimeout(function(aSelf) { this.foldersTree.selectFolders([PlacesUtils.bookmarksRootId]);
// select and expand the root node this.foldersTree.selectedNode.containerOpen = true;
aSelf.foldersTree.selectFolders([PlacesUtils.bookmarksRootId]);
aSelf.foldersTree.selectedNode.containerOpen = true;
}, 0, this);
}, },
onOK: function MBD_onOK(aEvent) { onOK: function MBD_onOK(aEvent) {

Просмотреть файл

@ -54,13 +54,6 @@ var PlacesOrganizer = {
_content: null, _content: null,
init: function PO_init() { init: function PO_init() {
var self = this;
// on timeout because of the corresponding setTimeout()
// in the places tree binding's constructor
setTimeout(function() { self._init(); }, 0);
},
_init: function PO__init() {
this._places = document.getElementById("placesList"); this._places = document.getElementById("placesList");
this._content = document.getElementById("placeContent"); this._content = document.getElementById("placeContent");
@ -576,7 +569,8 @@ var PlacesOrganizer = {
// are saved // are saved
if (gEditItemOverlay.itemId != -1) { if (gEditItemOverlay.itemId != -1) {
var focusedElement = document.commandDispatcher.focusedElement; var focusedElement = document.commandDispatcher.focusedElement;
if (focusedElement instanceof HTMLInputElement && if ((focusedElement instanceof HTMLInputElement ||
focusedElement instanceof HTMLTextAreaElement) &&
/^editBMPanel.*/.test(focusedElement.parentNode.parentNode.id)) /^editBMPanel.*/.test(focusedElement.parentNode.parentNode.id))
focusedElement.blur(); focusedElement.blur();
} }

Просмотреть файл

@ -124,7 +124,7 @@
oncommand="close();"/> oncommand="close();"/>
<key id="placesKey_show:debug" <key id="placesKey_show:debug"
key="d" modifiers="accel,shift" key="e" modifiers="accel,shift"
oncommand="PlacesOrganizer.toggleDebugPanel();"/> oncommand="PlacesOrganizer.toggleDebugPanel();"/>
<!-- Command Keys --> <!-- Command Keys -->

Просмотреть файл

@ -54,7 +54,7 @@
<resources> <resources>
<stylesheet src="chrome://browser/skin/places/places.css"/> <stylesheet src="chrome://browser/skin/places/places.css"/>
</resources> </resources>
<content> <content>
<xul:vbox> <xul:vbox>
<xul:hbox class="toolbar-drop-indicator-bar"> <xul:hbox class="toolbar-drop-indicator-bar">
@ -75,9 +75,9 @@
<xul:toolbarbutton type="menu" <xul:toolbarbutton type="menu"
class="chevron" class="chevron"
mousethrough="never" mousethrough="never"
collapsed="true"> collapsed="true"
<xul:menupopup type="places" onpopupshowing="chevronPopupShowing(event);">
anonid="chevronPopup" <xul:menupopup anonid="chevronPopup"
#ifndef XP_MACOSX #ifndef XP_MACOSX
context="placesContext" context="placesContext"
#endif #endif
@ -85,26 +85,17 @@
</xul:toolbarbutton> </xul:toolbarbutton>
</xul:hbox> </xul:hbox>
</content> </content>
<implementation> <implementation>
<constructor><![CDATA[ <constructor><![CDATA[
// Support an asyncinit attribute that causes the view to populate this._init();
// itself only after the window has been shown. This is to ensure we
// do not regress browser window show time (Ts/Txul)
#if 0
if (this.hasAttribute("asyncinit")) {
var self = this;
//setTimeout(function() { self._init(); }, 0);
}
else
#endif
this._init();
]]></constructor> ]]></constructor>
<destructor><![CDATA[ <destructor><![CDATA[
PlacesUtils.annotations.removeObserver(this.genericAnnoObserver); if (this._result) {
this._result.viewer = null; this._result.viewer = null;
this._result = null; this._result = null;
}
]]></destructor> ]]></destructor>
<property name="controller" <property name="controller"
@ -121,8 +112,6 @@
function f(e) { t.updateChevron(e); }, function f(e) { t.updateChevron(e); },
false); false);
PlacesUtils.annotations.addObserver(this.genericAnnoObserver);
if (this.hasAttribute("place")) { if (this.hasAttribute("place")) {
// Do the initial build. // Do the initial build.
this.place = this.place; this.place = this.place;
@ -132,14 +121,12 @@
<field name="_dropIndicatorBar">document.getAnonymousElementByAttribute(this, "class", "toolbar-drop-indicator-bar")</field> <field name="_dropIndicatorBar">document.getAnonymousElementByAttribute(this, "class", "toolbar-drop-indicator-bar")</field>
<field name="_chevron">document.getAnonymousElementByAttribute(this, "class", "chevron")</field> <field name="_chevron">document.getAnonymousElementByAttribute(this, "class", "chevron")</field>
<field name="_selection">null</field>
<field name="_openedMenuButton">null</field>
<field name="_result">null</field>
<field name="_ignoreInvalidateContainer">false</field> <field name="_selection">null</field>
<field name="_openedMenuButton">null</field>
<field name="_result">null</field>
<!-- nsIPlacesView --> <!-- nsIPlacesView -->
<method name="getResult"> <method name="getResult">
@ -164,85 +151,69 @@
while (this.hasChildNodes()) while (this.hasChildNodes())
this.removeChild(this.firstChild); this.removeChild(this.firstChild);
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
var cc = this._result.root.childCount;
for (var i = 0; i < cc; ++i)
this.insertNewItem(this._result.root.getChild(i), null);
var popup = this._chevron.firstChild; var rootNode = this._result.root;
popup.setAttribute("type", "places"); var cc = rootNode.childCount;
// This is set here and not in the XBL constructor for the menu because for (var i = 0; i < cc; ++i)
// it doesn't get initialized properly in the constructor. this.insertNewItem(rootNode.getChild(i), null);
#ifndef XP_MACOSX
// No context menus on menuitems on Mac var chevronPopup = this._chevron.lastChild;
popup.setAttribute("context", "placesContext"); if (chevronPopup.hasAttribute("type")) {
#endif // Otherwise we'll set it when the chevron is enabled (see updateChevron)
popup.place = this.place; chevronPopup.place = this.place;
var t = this; }
popup.popupShowingCallback = function() { t.chevronPopupShowing(); };
while (chevronPopup.hasChildNodes())
chevronPopup.removeChild(chevronPopup.lastChild);
// This needs to be in a timeout to make sure our boxObject has time // This needs to be in a timeout to make sure our boxObject has time
// to get its proper size // to get its proper size
var t = this;
setTimeout(function() { t.updateChevron(); }, 0); setTimeout(function() { t.updateChevron(); }, 0);
]]></body> ]]></body>
</method> </method>
<method name="insertNewItem"> <method name="insertNewItem">
<parameter name="child"/> <parameter name="aChild"/>
<parameter name="before"/> <parameter name="aBefore"/>
<body><![CDATA[ <body><![CDATA[
const XULNS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"; var type = aChild.type;
var title = child.title; var button;
var button = null; if (type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR)
if (PlacesUtils.nodeIsURI(child)) { button = document.createElement("toolbarseparator");
button = document.createElementNS(XULNS, "toolbarbutton"); else {
} else if (PlacesUtils.nodeIsSeparator(child)) { button = document.createElement("toolbarbutton");
button = document.createElementNS(XULNS, "toolbarseparator"); button.className = "bookmark-item";
} else if (PlacesUtils.nodeIsContainer(child)) { button.setAttribute("label", aChild.title);
button = document.createElementNS(XULNS, "toolbarbutton"); var iconURI = aChild.icon;
button.setAttribute("type", "menu"); var iconURISpec = "";
button.setAttribute("container", "true"); if (iconURI) {
if (PlacesUtils.nodeIsLivemarkContainer(child)) { iconURISpec = iconURI.spec;
button.setAttribute("livemark", "true"); button.setAttribute("image", iconURISpec);
var folder = child.itemId;
// duplicate nsLivemarkService.getSiteURI to avoid instantiating
// the service on startup.
var siteURIString;
try {
siteURIString =
PlacesUtils.annotations.getItemAnnotation(folder, "livemark/siteURI");
}
catch (ex) {}
// end duplication
if (siteURIString)
button.setAttribute("siteURI", siteURIString);
} }
var popup = document.createElementNS(XULNS, "menupopup");
popup.setAttribute("type", "places"); if (PlacesUtils.containerTypes.indexOf(type) != -1) {
// This is set here and not in the XBL constructor for the menu because button.setAttribute("type", "menu");
// it doesn't get initialized properly in the constructor. button.setAttribute("container", "true");
if (iconURISpec == "chrome://browser/skin/places/livemarkItem.png")
button.setAttribute("livemark", "true");
var popup = document.createElement("menupopup");
button.appendChild(popup);
popup._result = this._result;
popup._resultNode = asContainer(aChild);
#ifndef XP_MACOSX #ifndef XP_MACOSX
// No context menus on menuitems on Mac popup.setAttribute("context", "placesContext");
popup.setAttribute("context", "placesContext");
#endif #endif
button.appendChild(popup); this._containerNodesMap.push({ resultNode: aChild,
popup._result = this._result; domNode: popup });
popup._resultNode = asContainer(child); }
popup._containerNodesMap = this._containerNodesMap;
this._containerNodesMap.push({ resultNode: child,
domNode: popup });
} }
button.setAttribute("label", title); button.node = aChild;
if (child.icon)
button.setAttribute("image", child.icon.spec);
button.className = "menuitem-iconic bookmark-item";
button.node = child;
button.node.viewIndex = 0; button.node.viewIndex = 0;
if (before) if (aBefore)
this.insertBefore(button, before); this.insertBefore(button, aBefore);
else else
this.appendChild(button); this.appendChild(button);
]]></body> ]]></body>
@ -253,18 +224,24 @@
<body><![CDATA[ <body><![CDATA[
if (PlacesUtils.nodeIsContainer(child.node)) { if (PlacesUtils.nodeIsContainer(child.node)) {
for (var i=0; i < this._containerNodesMap.length; i++) { for (var i=0; i < this._containerNodesMap.length; i++) {
if (this._containerNodesMap[i].resultNode == child.node) if (this._containerNodesMap[i].resultNode == child.node) {
this._containerNodesMap.splice(i, 1); this._containerNodesMap.splice(i, 1);
break;
}
} }
} }
this.removeChild(child); child.parentNode.removeChild(child);
]]></body> ]]></body>
</method> </method>
<method name="chevronPopupShowing"> <method name="chevronPopupShowing">
<parameter name="aEvent"/>
<body><![CDATA[ <body><![CDATA[
var popup = this._chevron.firstChild; var popup = aEvent.target;
if (popup != this._chevron.firstChild)
return;
for (var i = 0; i < popup.childNodes.length; i++) for (var i = 0; i < popup.childNodes.length; i++)
popup.childNodes[i].hidden = !this.childNodes[i].collapsed; popup.childNodes[i].hidden = !this.childNodes[i].collapsed;
]]></body> ]]></body>
@ -281,7 +258,7 @@
return element.boxObject.width + leftMargin + rightMargin; return element.boxObject.width + leftMargin + rightMargin;
]]></body> ]]></body>
</method> </method>
<method name="updateChevron"> <method name="updateChevron">
<parameter name="event"/> <parameter name="event"/>
<body><![CDATA[ <body><![CDATA[
@ -312,10 +289,17 @@
child.collapsed = true; child.collapsed = true;
} }
} }
this._chevron.collapsed = !overflowed; if (!(this._chevron.collapsed = !overflowed)) {
// Attach the popup binding to the chevron popup
var popup = this._chevron.firstChild;
if (!popup.hasAttribute("type")) {
popup.setAttribute("place", this.place);
popup.setAttribute("type", "places");
}
}
]]></body> ]]></body>
</method> </method>
<!-- nsIPlacesView --> <!-- nsIPlacesView -->
<property name="place"> <property name="place">
<getter><![CDATA[ <getter><![CDATA[
@ -414,7 +398,7 @@
var folderId = this._result.root.itemId; var folderId = this._result.root.itemId;
if (this.hasSelection) { if (this.hasSelection) {
if(PlacesUtils.nodeIsFolder(this.selectedNode)) { if (PlacesUtils.nodeIsFolder(this.selectedNode)) {
// If there is a folder selected, the insertion point is the // If there is a folder selected, the insertion point is the
// end of the folder. // end of the folder.
folderId = this.selectedNode.itemId; folderId = this.selectedNode.itemId;
@ -442,23 +426,21 @@
]]></body> ]]></body>
</method> </method>
<!-- Map for containerNodes<->domNodes. There's only one map per <!-- Map for containerNodes<->domNodes. -->
result/viewer, i.e. the field is initialized just for the toolbar,
for sub menus it is set to the root's map -->
<field name="_containerNodesMap">[]</field> <field name="_containerNodesMap">[]</field>
<!-- nsINavHistoryResultViewer --> <!-- nsINavHistoryResultViewer -->
<field name="_viewer"><![CDATA[({ <field name="_viewer"><![CDATA[({
_self: this, _self: this,
_forwardToChildView: _getPopupForContainer:
function TV_V__forwardToChildView(aNode, aFunction, aArguments) { function PMV__getPopupForContainer(aNode) {
if (this._self._resultNode == aNode)
return this._self;
for (var i=0; i < this._self._containerNodesMap.length; i++) { for (var i=0; i < this._self._containerNodesMap.length; i++) {
if (this._self._containerNodesMap[i].resultNode == aNode) { if (this._self._containerNodesMap[i].resultNode == aNode)
var childView = this._self._containerNodesMap[i].domNode._viewer; return this._self._containerNodesMap[i].domNode;
childView[aFunction].apply(childView, aArguments);
return;
}
} }
throw("Container view not found"); throw("Container view not found");
}, },
@ -466,19 +448,26 @@
itemInserted: function TV_V_itemInserted(aParentNode, aNode, aIndex) { itemInserted: function TV_V_itemInserted(aParentNode, aNode, aIndex) {
// don't insert new items into the toolbar // don't insert new items into the toolbar
// if the parent is not the root // if the parent is not the root
if (aParentNode == this._self.getResult().root) { if (aParentNode == this._self.getResultNode()) {
var children = this._self.childNodes; var children = this._self.childNodes;
this._self.insertNewItem(aNode, this._self.insertNewItem(aNode,
aIndex < children.length ? children[aIndex] : null); aIndex < children.length ? children[aIndex] : null);
this._self.updateChevron(); this._self.updateChevron();
} }
else { else {
this._forwardToChildView(aParentNode, "itemInserted", arguments); var popup = this._getPopupForContainer(aParentNode);
if (!popup._built)
return;
var before = popup.childNodes[aIndex] || null;
this._self.insertNewItemToPopup(aNode, popup, before);
if (popup._emptyMenuItem)
popup._emptyMenuItem.hidden = true;
} }
}, },
itemRemoved: function TV_V_itemRemoved(aParentNode, aNode, aIndex) { itemRemoved: function TV_V_itemRemoved(aParentNode, aNode, aIndex) {
if (aParentNode == this._self.getResult().root) { if (aParentNode == this._self.getResultNode()) {
var children = this._self.childNodes; var children = this._self.childNodes;
for (var i = 0; i < children.length; i++) { for (var i = 0; i < children.length; i++) {
if (children[i].node == aNode) { if (children[i].node == aNode) {
@ -488,8 +477,23 @@
} }
} }
} }
else else {
this._forwardToChildView(aParentNode, "itemRemoved", arguments); var popup = this._getPopupForContainer(aParentNode);
if (!popup._built)
return;
var children = popup.childNodes;
for (var i = 0; i < children.length; i++) {
if (children[i].node == aNode) {
this._self.removeItem(children[i]);
if (!popup.hasChildNodes() ||
(popup.childNodes.length == 1 &&
popup.firstChild == popup._emptyMenuItem)) {
this._self._showEmptyMenuItem(popup);
}
}
}
}
}, },
itemChanged: function TV_V_itemChanged(aNode) { itemChanged: function TV_V_itemChanged(aNode) {
@ -498,63 +502,57 @@
if (!parentNode) if (!parentNode)
return; return;
if (parentNode != this._self.getResult().root) { var element;
this._forwardToChildView(parentNode, "itemChanged", arguments); var onToolbar = false;
return; if (parentNode == this._self.getResultNode()) {
} onToolbar = true;
var children = this._self.childNodes;
var button; for (var i = 0; i < children.length; i++) {
if (children[i].node == aNode) {
var children = this._self.childNodes; element = children[i];
for (var i = 0; i < children.length; i++) { break;
if (children[i].node == aNode) { }
button = children[i];
break;
} }
} }
else {
var popup = this._getPopupForContainer(parentNode);
if (!popup._built)
return;
NS_ASSERT(button, "unable to find a toolbar element"); var children = popup.childNodes;
for (var i = 0; i < children.length; i++) {
var title = aNode.title; if (children[i].node == aNode) {
element = children[i];
break;
}
}
}
if (PlacesUtils.nodeIsSeparator(aNode)) { if (PlacesUtils.nodeIsSeparator(aNode)) {
// nothing to do when a separator changes // nothing to do when a separator changes
return; return;
}
else if (PlacesUtils.nodeIsContainer(aNode)) {
if (PlacesUtils.nodeIsLivemarkContainer(aNode)) {
var folder = aNode.itemId;
var siteURIString = "";
var siteURI = PlacesUtils.livemarks.getSiteURI(folder);
if (siteURI)
siteURIString = siteURI.spec;
if (siteURIString) {
if (button.getAttribute("siteURI") != siteURIString)
button.setAttribute("siteURI", siteURIString);
}
else
button.removeAttribute("siteURI");
}
} }
if (aNode.icon) { var iconURI = aNode.icon;
if (button.getAttribute("image") != aNode.icon.spec) if (iconURI) {
button.setAttribute("image", aNode.icon.spec); var spec = iconURI.spec;
if (element.getAttribute("image") != spec)
element.setAttribute("image", spec);
} }
else else
button.removeAttribute("image"); element.removeAttribute("image");
// the only change that might require a chevron update var title = aNode.title;
// is when the title changes if (element.getAttribute("label") != title) {
if (button.getAttribute("label") != title) { element.setAttribute("label", title);
button.setAttribute("label", title); if (onToolbar)
this._self.updateChevron(); this._self.updateChevron();
} }
}, },
itemReplaced: itemReplaced:
function TV_V_itemReplaced(aParentNode, aOldNode, aNewNode, aIndex) { function TV_V_itemReplaced(aParentNode, aOldNode, aNewNode, aIndex) {
if (aParentNode == this._self.getResult().root) { if (aParentNode == this._self.getResultNode()) {
var children = this._self.childNodes; var children = this._self.childNodes;
for (var i = 0; i < children.length; i++) { for (var i = 0; i < children.length; i++) {
if (children[i].node == aOldNode) { if (children[i].node == aOldNode) {
@ -578,17 +576,12 @@
this.invalidateContainer(aNode); this.invalidateContainer(aNode);
}, },
get ignoreInvalidateContainer() {
return this._self._ignoreInvalidateContainer;
},
set ignoreInvalidateContainer(val) {
return this._self._ignoreInvalidateContainer = val;
},
invalidateContainer: function TV_V_invalidateContainer(aContainer) { invalidateContainer: function TV_V_invalidateContainer(aContainer) {
if (this._self._ignoreInvalidateContainer) if (aContainer == this._self.getResultNode()) {
this._self._containerNodesMap.splice(0);
this._self._rebuild();
return; return;
}
function isChildOf(node, container) { function isChildOf(node, container) {
var parent = node.parent; var parent = node.parent;
@ -600,22 +593,20 @@
return false; return false;
} }
var viewerToRebuild = null; var popupToRebuild = null;
for (var i=0; i < this._self._containerNodesMap.length; i++) { for (var i=0; i < this._self._containerNodesMap.length; i++) {
var node = this._self._containerNodesMap[i].resultNode; var node = this._self._containerNodesMap[i].resultNode;
if (node == aContainer) if (node == aContainer)
viewerToRebuild = this._self._containerNodesMap[i].domNode._viewer; popupToRebuild = this._self._containerNodesMap[i].domNode;
if (isChildOf(node, aContainer)) if (isChildOf(node, aContainer)) {
this._self._containerNodesMap.splice(i,1); this._self._containerNodesMap.splice(i,1);
i--;
}
} }
if (aContainer.containerOpen) { if (popupToRebuild)
if (viewerToRebuild) popupToRebuild._built = false;
viewerToRebuild._self._built = false;
else
this._self._rebuild();
}
}, },
invalidateAll: function TV_V_invalidateAll() { invalidateAll: function TV_V_invalidateAll() {
@ -639,22 +630,21 @@
// timer for turning of indicator bar, to get rid of flicker // timer for turning of indicator bar, to get rid of flicker
_ibTimer: null, _ibTimer: null,
_setTimer: function TBV_DO_setTimer(time) { _setTimer: function TBV_DO_setTimer(time) {
var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer);
timer.initWithCallback(this, time, timer.TYPE_ONE_SHOT); timer.initWithCallback(this, time, timer.TYPE_ONE_SHOT);
return timer; return timer;
}, },
// Function to process all timer notifications. // Function to process all timer notifications.
notify: function TBV_DO_notify(timer) { notify: function TBV_DO_notify(timer) {
// Timer to turn off indicator bar. // Timer to turn off indicator bar.
if (timer == this._ibTimer) { if (timer == this._ibTimer) {
ib = this._self._dropIndicatorBar.removeAttribute('dragging'); ib = this._self._dropIndicatorBar.removeAttribute('dragging');
this._ibTimer = null; this._ibTimer = null;
} }
// Timer to open a menubutton that's being dragged over. // Timer to open a menubutton that's being dragged over.
if (timer == this._overFolder.openTimer) { if (timer == this._overFolder.openTimer) {
// Set the autoopen attribute on the folder's menupopup so that // Set the autoopen attribute on the folder's menupopup so that
@ -694,7 +684,7 @@
_clearOverFolder: function TBV_DO_clearOverFolder() { _clearOverFolder: function TBV_DO_clearOverFolder() {
if (this._overFolder.node && this._overFolder.node.lastChild) { if (this._overFolder.node && this._overFolder.node.lastChild) {
if (!this._overFolder.node.lastChild.hasAttribute("dragover")) { if (!this._overFolder.node.lastChild.hasAttribute("dragover")) {
this._overFolder.node.lastChild.hidePopupAndChildPopups(); this._overFolder.node.lastChild.hidePopup();
} }
this._overFolder.node.removeAttribute("dragover"); this._overFolder.node.removeAttribute("dragover");
this._overFolder.node = null; this._overFolder.node = null;
@ -835,14 +825,14 @@
this._clearOverFolder(); this._clearOverFolder();
} }
}, },
onDrop: function TBV_DO_onDrop(event, dropData, session) { onDrop: function TBV_DO_onDrop(event, dropData, session) {
var dropPoint = this._getDropPoint(event); var dropPoint = this._getDropPoint(event);
if (dropPoint == null) if (dropPoint == null)
return; return;
PlacesControllerDragHelper.onDrop(null, this._self, dropPoint.ip); PlacesControllerDragHelper.onDrop(null, this._self, dropPoint.ip);
}, },
onDragExit: function TBV_DO_onDragExit(event, session) { onDragExit: function TBV_DO_onDragExit(event, session) {
// Set timer to turn off indicator bar (if we turn it off // Set timer to turn off indicator bar (if we turn it off
// here, dragenter might be called immediately after, creating // here, dragenter might be called immediately after, creating
@ -855,103 +845,15 @@
this._overFolder.closeTimer = this._setTimer(this._overFolder.hoverTime); this._overFolder.closeTimer = this._setTimer(this._overFolder.hoverTime);
PlacesControllerDragHelper.currentDropTarget = null; PlacesControllerDragHelper.currentDropTarget = null;
}, },
getSupportedFlavours: function TBV_DO_getSupportedFlavours() { getSupportedFlavours: function TBV_DO_getSupportedFlavours() {
var flavorSet = new FlavourSet(); var flavorSet = new FlavourSet();
for (var i = 0; i < this._self.peerDropTypes.length; ++i) for (var i = 0; i < this._self.peerDropTypes.length; ++i)
flavorSet.appendFlavour(this._self.peerDropTypes[i]); flavorSet.appendFlavour(this._self.peerDropTypes[i]);
return flavorSet; return flavorSet;
} }
})]]></field> })]]></field>
<!-- nsIAnnotationObserver -->
<field name="genericAnnoObserver"><![CDATA[({
// A generic nsIAnnotationObserver that provides methods for registering
// annotation-specific observers for this view.
// Inside this observer object's functions, "this" points to this
// observer object, while "_self" points to the toolbar XBL object.
_self: this,
// Observers, indexed by annotation name.
_observers: {},
addObserver: function TBV_GAO_addObserver(annoName, observer) {
if (!this._observers[annoName])
this._observers[annoName] = [];
// Register the observer, but only if it isn't already registered,
// so that we don't call the same observer twice for any given change.
if (this._observers[annoName].indexOf(observer) == -1)
this._observers[annoName].push(observer);
},
removeObserver: function TBV_GAO_removeObserver(annoName, observer) {
NS_ASSERT(this._observers[annoName] &&
this._observers[annoName].indexOf(observer) != -1,
"can't remove annotation observer " + observer +
" for annotation " + annoName + ": not registered");
this._observers[annoName] =
this._observers[annoName].filter(function(i) { observer != i });
if (this._observers[annoName].length == 0)
delete this._observers[annoName];
},
// Determines whether or not a given annotation change applies to
// this view. A change applies if the annotation being changed is one
// we're observing, and the change is happening to a URI currently
// in this view.
_applies: function TBV_GAO_applies(uri, annoName) {
if (!this._observers[annoName])
return false;
return true;
},
onPageAnnotationSet:
function TBV_GAO_onPageAnnotationSet(uri, annoName) {
if (!this._applies(uri, annoName))
return;
for (var i = 0; i < this._observers[annoName].length; i++)
this._observers[annoName][i].onPageAnnotationSet(uri, annoName);
},
onPageAnnotationRemoved:
function TBV_GAO_onPageAnnotationRemoved(uri, annoName) {
if (!this._applies(uri, annoName))
return;
for ( var i = 0; i < this._observers[annoName].length; i++)
this._observers[annoName][i].onPageAnnotationRemoved(uri, annoName);
},
onItemAnnotationSet:
function TBV_GAO_onItemAnnotationSet(aItemId, aAnnoName) {
if (!this._applies(aItemId, aAnnoName))
return;
for (var i = 0; i < this._observers[aAnnoName].length; i++) {
this._observers[aAnnoName][i]
.onItemAnnotationSet(aItemId, aAnnoName);
}
},
onItemAnnotationRemoved:
function TBV_GAO_onItemAnnotationRemoved(aItemId, aAnnoName) {
if (!this._applies(aItemId, aAnnoName))
return;
for (var i = 0; i < this._observers[aAnnoName].length; i++) {
this._observers[aAnnoName][i]
.onItemAnnotationRemoved(aItemId, aAnnoName);
}
}
})]]></field>
<method name="checkForMenuEvent"> <method name="checkForMenuEvent">
<parameter name="event"/> <parameter name="event"/>
<parameter name="action"/> <parameter name="action"/>
@ -998,21 +900,111 @@
<method name="destroyContextMenu"> <method name="destroyContextMenu">
<parameter name="aPopup"/> <parameter name="aPopup"/>
<body> <body><![CDATA[
<![CDATA[ if (window.content)
if (window.content) window.content.focus();
window.content.focus(); ]]></body>
]]> </method>
</body>
<method name="_showEmptyMenuItem">
<parameter name="aPopup"/>
<body><![CDATA[
if (aPopup._emptyMenuItem) {
aPopup._emptyMenuItem.hidden = false;
return;
}
var label = PlacesUtils.getString("bookmarksMenuEmptyFolder");
aPopup._emptyMenuItem = document.createElement("menuitem");
aPopup._emptyMenuItem.setAttribute("label", label);
aPopup._emptyMenuItem.setAttribute("disabled", true);
aPopup.appendChild(aPopup._emptyMenuItem);
]]></body>
</method>
<method name="insertNewItemToPopup">
<parameter name="aChild"/>
<parameter name="aParentPopup"/>
<parameter name="aBefore"/>
<body><![CDATA[
var element =
PlacesUtils.createMenuItemForNode(aChild, this._containerNodesMap);
if (aBefore)
aParentPopup.insertBefore(element, aBefore);
else
aParentPopup.appendChild(element);
]]></body>
</method>
<method name="_containerPopupShowing">
<parameter name="aPopup"/>
<body><![CDATA[
if (aPopup._built)
return;
// remove previous menu items
while (aPopup.hasChildNodes())
aPopup.removeChild(aPopup.firstChild);
// restore the empty-menu item if has been created already
if (aPopup._emptyMenuItem)
aPopup.appendChild(aPopup._emptyMenuItem);
var resultNode = aPopup._resultNode;
if (!resultNode.containerOpen)
resultNode.containerOpen = true;
var cc = resultNode.childCount;
if (cc > 0) {
if (aPopup._emptyMenuItem)
aPopup._emptyMenuItem.hidden = true;
for (var i = 0; i < cc; ++i) {
var child = resultNode.getChild(i);
this.insertNewItemToPopup(child, aPopup, null);
}
}
else {
// add element to show it is empty.
this._showEmptyMenuItem(aPopup);
}
aPopup._built = true;
if (!aPopup._DNDObserver)
aPopup._DNDObserver = new PlacesMenuDNDObserver(this, aPopup);
]]></body>
</method>
<method name="_isChevronChild">
<parameter name="aChild"/>
<body><![CDATA[
if (!this._chevron.firstChild.hasAttribute("type"))
return false;
var parent = aChild.parentNode;
while (parent != this) {
if (parent == this._chevron)
return true;
parent = parent.parentNode;
}
return false;
]]></body>
</method> </method>
</implementation> </implementation>
<handlers> <handlers>
<handler event="mousedown"><![CDATA[ <handler event="mousedown"><![CDATA[
// When the user clicks down on a button, set it as the selection and // When the user clicks down on a button, set it as the selection and
// tell the controller that we are the active view. // tell the controller that we are the active view.
if (event.target.localName == "toolbarbutton" || //
event.target.localName == "toolbarseparator") // Sub-menus are handled by the DOMMenuItemActive handler
this._selection = event.target.node; var target = event.target;
if (target.parentNode != this)
return;
if (target.localName == "toolbarbutton" ||
target.localName == "toolbarseparator")
this._selection = target.node;
else else
this._selection = this.getResult().root; this._selection = this.getResult().root;
this._cachedInsertionPoint = undefined; this._cachedInsertionPoint = undefined;
@ -1033,22 +1025,74 @@
if (!this.checkForMenuEvent(event, "dragExit")) if (!this.checkForMenuEvent(event, "dragExit"))
nsDragAndDrop.dragExit(event, this._DNDObserver); nsDragAndDrop.dragExit(event, this._DNDObserver);
]]></handler> ]]></handler>
<handler event="popupshowing"><![CDATA[ <handler event="popupshowing" phase="capturing"><![CDATA[
var targetParent = event.originalTarget.parentNode; var target = event.originalTarget;
// the chevron has its own view
if (this._isChevronChild(target))
return;
if (target._resultNode)
this._containerPopupShowing(target);
var targetParent = target.parentNode;
if (targetParent.localName == "toolbarbutton" && if (targetParent.localName == "toolbarbutton" &&
!PlacesControllerDragHelper.getSession()) !PlacesControllerDragHelper.getSession())
this._openedMenuButton = targetParent; this._openedMenuButton = targetParent;
]]></handler> ]]></handler>
<handler event="popuphidden"><![CDATA[ <handler event="popuphidden"><![CDATA[
var targetParent = event.originalTarget.parentNode; var target = event.originalTarget;
if (!target._resultNode)
return;
// the chevron has its own view
if (this._isChevronChild(target))
return;
// UI performance: folder queries are cheap, keep the resultnode open
// so we don't rebuild its contents whenever the popup is reopened.
if (!PlacesUtils.nodeIsFolder(target._resultNode))
target._resultNode.containerOpen = false;
var targetParent = target.parentNode;
if (targetParent.localName == "toolbarbutton" && if (targetParent.localName == "toolbarbutton" &&
!PlacesControllerDragHelper.getSession()) !PlacesControllerDragHelper.getSession())
this._openedMenuButton = null; this._openedMenuButton = null;
]]></handler> ]]></handler>
<!-- Set selected node on DOMMenuItemActive/contextmenu events
so that they're set up when command and click events fire. -->
<handler event="DOMMenuItemActive"><![CDATA[
// Set the selection to the node that was activated. If that
// node has a command but no data associated with it, it should
// act on the entire menu.
if (event.target.parentNode._resultNode) {
// the chevron has its own view
if (this._isChevronChild(event.target))
return;
this._cachedInsertionPoint = undefined;
this._selection = event.target.node ||
event.target.parentNode._resultNode;
}
]]></handler>
<handler event="contextmenu"><![CDATA[
// DOMMenuItemActive is not dispatched for disabled menuitems and
// menuseparators. Set the selection here manually.
var popupNode = document.popupNode;
// the chevron has its own view
if (this._isChevronChild(popupNode))
return;
// |popupNode == menupopup| happens when the area between menuseparators
// is clicked.
this._selection = popupNode.node || popupNode.parentNode._resultNode;
this._cachedInsertionPoint = undefined;
]]></handler>
<handler event="mousemove"><![CDATA[ <handler event="mousemove"><![CDATA[
if (this._openedMenuButton == null || PlacesControllerDragHelper.getSession()) if (this._openedMenuButton == null || PlacesControllerDragHelper.getSession())
return; return;
var target = event.originalTarget; var target = event.originalTarget;
if (this._openedMenuButton != target && if (this._openedMenuButton != target &&
target.localName == "toolbarbutton" && target.localName == "toolbarbutton" &&

Просмотреть файл

@ -49,14 +49,9 @@
this._controller = new PlacesController(this); this._controller = new PlacesController(this);
this.controllers.appendController(this._controller); this.controllers.appendController(this._controller);
// Force an initial build. // Force an initial build.
// but do it on setTimeout() for bugs #373719 and bug #373721 if (this.place)
// caused by a change for bug #267833 this.place = this.place;
// note the corresponding setTimeout() in PO_init()
if (this.place) {
var self = this;
setTimeout(function() { self.place = self.place; }, 0);
}
]]></constructor> ]]></constructor>
<destructor><![CDATA[ <destructor><![CDATA[
@ -83,11 +78,13 @@
var resultview = this.getResultView(); var resultview = this.getResultView();
if (resultview) if (resultview)
resultview.removeViewObserver(this._viewObserver); resultview.removeViewObserver(this._viewObserver);
this.treeBoxObject.view = val; this.treeBoxObject.view = val;
if (val) { if (val) {
val.QueryInterface(Ci.nsINavHistoryResultViewer) val.QueryInterface(Ci.nsINavHistoryResultViewer)
.addViewObserver(this._viewObserver, false); .addViewObserver(this._viewObserver, false);
} }
return val;
]]></setter> ]]></setter>
</property> </property>
@ -114,11 +111,11 @@
if (optionsFilter) if (optionsFilter)
options = optionsFilter.filter(queryNode.getQueries({}), options, options = optionsFilter.filter(queryNode.getQueries({}), options,
optionsFilter.historyHandler); optionsFilter.historyHandler);
var query = PlacesUtils.history.getNewQuery(); var query = PlacesUtils.history.getNewQuery();
query.searchTerms = filterString; query.searchTerms = filterString;
query.onlyBookmarked = onlyBookmarks; query.onlyBookmarked = onlyBookmarks;
// Remove "group by folder" from the options list, because // Remove "group by folder" from the options list, because
// nsNavHistory::RecursiveGroup doesn't support it. // nsNavHistory::RecursiveGroup doesn't support it.
function isFolderGrouping(grouping, index, ary) { function isFolderGrouping(grouping, index, ary) {
@ -156,7 +153,8 @@
if (this.showRoot != val) { if (this.showRoot != val) {
this.setAttribute("showRoot", val); this.setAttribute("showRoot", val);
// reload with the last place set // reload with the last place set
this.place = this.place; if (this.place)
this.place = this.place;
} }
return val; return val;
]]></setter> ]]></setter>
@ -278,7 +276,7 @@
<getter><![CDATA[ <getter><![CDATA[
return this.getAttribute("place"); return this.getAttribute("place");
]]></getter> ]]></getter>
<setter><![CDATA[ <setter><![CDATA[
this.setAttribute("place", val); this.setAttribute("place", val);
var queriesRef = { }; var queriesRef = { };

Просмотреть файл

@ -215,6 +215,7 @@ PlacesTreeView.prototype = {
var cc = aContainer.childCount; var cc = aContainer.childCount;
for (var i=0; i < cc; i++) { for (var i=0; i < cc; i++) {
var curChild = aContainer.getChild(i); var curChild = aContainer.getChild(i);
var curChildType = curChild.type;
// collapse all duplicates starting from here // collapse all duplicates starting from here
if (this._collapseDuplicates) { if (this._collapseDuplicates) {
@ -226,6 +227,7 @@ PlacesTreeView.prototype = {
// collapse the first and use the second // collapse the first and use the second
curChild.viewIndex = -1; curChild.viewIndex = -1;
curChild = aContainer.getChild(i+1); curChild = aContainer.getChild(i+1);
curChildType = curChild.type;
} }
else { else {
// collapse the second and use the first // collapse the second and use the first
@ -236,7 +238,7 @@ PlacesTreeView.prototype = {
} }
// don't display separators when sorted // don't display separators when sorted
if (PlacesUtils.nodeIsSeparator(curChild)) { if (curChildType == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR) {
if (this._result.sortingMode != if (this._result.sortingMode !=
Ci.nsINavHistoryQueryOptions.SORT_BY_NONE) { Ci.nsINavHistoryQueryOptions.SORT_BY_NONE) {
curChild.viewIndex = -1; curChild.viewIndex = -1;
@ -249,11 +251,13 @@ PlacesTreeView.prototype = {
aVisible.push(curChild); aVisible.push(curChild);
// recursively do containers // recursively do containers
if (PlacesUtils.nodeIsContainer(curChild)) { if (PlacesUtils.containerTypes.indexOf(curChildType) != -1) {
asContainer(curChild);
var resource = this._getResourceForNode(curChild); var resource = this._getResourceForNode(curChild);
var isopen = resource != null && var isopen = resource != null &&
PlacesUtils.localStore.HasAssertion(resource, openLiteral, trueLiteral, true); PlacesUtils.localStore.HasAssertion(resource, openLiteral,
asContainer(curChild); trueLiteral, true);
if (isopen != curChild.containerOpen) if (isopen != curChild.containerOpen)
aToOpen.push(curChild); aToOpen.push(curChild);
else if (curChild.containerOpen && curChild.childCount > 0) else if (curChild.containerOpen && curChild.childCount > 0)
@ -371,7 +375,7 @@ PlacesTreeView.prototype = {
// now, open any containers that were persisted // now, open any containers that were persisted
for (var i = 0; i < toOpenElements.length; i++) { for (var i = 0; i < toOpenElements.length; i++) {
var item = asContainer(toOpenElements[i]); var item = toOpenElements[i];
var parent = item.parent; var parent = item.parent;
// avoid recursively opening containers // avoid recursively opening containers
while (parent) { while (parent) {
@ -734,20 +738,9 @@ PlacesTreeView.prototype = {
containerClosed: function PTV_containerClosed(aItem) { containerClosed: function PTV_containerClosed(aItem) {
this.invalidateContainer(aItem); this.invalidateContainer(aItem);
},
get ignoreInvalidateContainer() {
return this._ignoreInvalidateContainer;
}, },
set ignoreInvalidateContainer(val) { invalidateContainer: function PTV_invalidateContainer(aItem) {
return this._ignoreInvalidateContainer = val;
},
invalidateContainer: function PTV_invalidateContainer(aItem) {
if (this._ignoreInvalidateContainer)
return;
NS_ASSERT(this._result, "Got a notification but have no result!"); NS_ASSERT(this._result, "Got a notification but have no result!");
if (!this._tree) if (!this._tree)
return; // nothing to do, container is not visible return; // nothing to do, container is not visible
@ -808,8 +801,10 @@ PlacesTreeView.prototype = {
}, },
set result(val) { set result(val) {
this._result = val; if (this._result != val) {
this._finishInit(); this._result = val;
this._finishInit();
}
return val; return val;
}, },
@ -875,7 +870,7 @@ PlacesTreeView.prototype = {
return viewIndex; return viewIndex;
}, },
_getResourceForNode : function PTV_getResourceForNode(aNode) _getResourceForNode: function PTV_getResourceForNode(aNode)
{ {
var uri = aNode.uri; var uri = aNode.uri;
NS_ASSERT(uri, "if there is no uri, we can't persist the open state"); NS_ASSERT(uri, "if there is no uri, we can't persist the open state");
@ -916,7 +911,7 @@ PlacesTreeView.prototype = {
}, },
getCellProperties: function PTV_getCellProperties(aRow, aColumn, aProperties) { getCellProperties: function PTV_getCellProperties(aRow, aColumn, aProperties) {
var columnType = aColumn.id || aColumn.element.getAttribute("anonid") ; var columnType = aColumn.id || aColumn.element.getAttribute("anonid");
if (columnType != "title") if (columnType != "title")
return; return;
@ -933,16 +928,14 @@ PlacesTreeView.prototype = {
this._ensureValidRow(aRow); this._ensureValidRow(aRow);
var node = this._visibleElements[aRow]; var node = this._visibleElements[aRow];
if (PlacesUtils.nodeIsContainer(node)) { if (PlacesUtils.nodeIsContainer(node)) {
// the root node is always expandable
if (!node.parent)
return true;
// treat non-expandable queries as non-containers // treat non-expandable queries as non-containers
if (PlacesUtils.nodeIsQuery(node)) { if (PlacesUtils.nodeIsQuery(node)) {
asQuery(node); asQuery(node);
if (node.queryOptions.expandQueries) return node.queryOptions.expandQueries;
return true;
// the root node is always expandable
if (!node.parent)
return true;
return false;
} }
return true; return true;
} }
@ -954,7 +947,7 @@ PlacesTreeView.prototype = {
if (!PlacesUtils.nodeIsContainer(this._visibleElements[aRow])) if (!PlacesUtils.nodeIsContainer(this._visibleElements[aRow]))
throw Cr.NS_ERROR_INVALID_ARG; throw Cr.NS_ERROR_INVALID_ARG;
return asContainer(this._visibleElements[aRow]).containerOpen; return this._visibleElements[aRow].containerOpen;
}, },
isContainerEmpty: function PTV_isContainerEmpty(aRow) { isContainerEmpty: function PTV_isContainerEmpty(aRow) {
@ -962,7 +955,7 @@ PlacesTreeView.prototype = {
if (!PlacesUtils.nodeIsContainer(this._visibleElements[aRow])) if (!PlacesUtils.nodeIsContainer(this._visibleElements[aRow]))
throw Cr.NS_ERROR_INVALID_ARG; throw Cr.NS_ERROR_INVALID_ARG;
return !asContainer(this._visibleElements[aRow]).hasChildren; return !this._visibleElements[aRow].hasChildren;
}, },
isSeparator: function PTV_isSeparator(aRow) { isSeparator: function PTV_isSeparator(aRow) {
@ -1003,8 +996,15 @@ PlacesTreeView.prototype = {
return false; return false;
} }
return this._visibleElements[aRow].indentLevel == var thisLevel = this._visibleElements[aRow].indentLevel;
this._visibleElements[aRow + 1].indentLevel; for (var i = aAfterIndex + 1; i < this._visibleElements.length; ++i) {
var nextLevel = this._visibleElements[i].indentLevel;
if (nextLevel == thisLevel)
return true;
if (nextLevel < thisLevel)
break;
}
return false;
}, },
getLevel: function PTV_getLevel(aRow) { getLevel: function PTV_getLevel(aRow) {
@ -1133,7 +1133,6 @@ PlacesTreeView.prototype = {
if (!PlacesUtils.nodeIsContainer(node)) if (!PlacesUtils.nodeIsContainer(node))
return; // not a container, nothing to do return; // not a container, nothing to do
asContainer(node);
var resource = this._getResourceForNode(node); var resource = this._getResourceForNode(node);
if (resource) { if (resource) {
const openLiteral = PlacesUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open"); const openLiteral = PlacesUtils.RDF.GetResource("http://home.netscape.com/NC-rdf#open");
@ -1304,5 +1303,4 @@ function PlacesTreeView(aShowRoot) {
this._visibleElements = []; this._visibleElements = [];
this._observers = []; this._observers = [];
this._showRoot = aShowRoot; this._showRoot = aShowRoot;
this._ignoreInvalidateContainer = false;
} }

Просмотреть файл

@ -95,119 +95,92 @@ var PlacesUtils = {
/** /**
* The Bookmarks Service. * The Bookmarks Service.
*/ */
_bookmarks: null,
get bookmarks() { get bookmarks() {
if (!this._bookmarks) { delete this.bookmarks;
this._bookmarks = Cc["@mozilla.org/browser/nav-bookmarks-service;1"]. return this.bookmarks = Cc["@mozilla.org/browser/nav-bookmarks-service;1"].
getService(Ci.nsINavBookmarksService); getService(Ci.nsINavBookmarksService);
}
return this._bookmarks;
}, },
/** /**
* The Nav History Service. * The Nav History Service.
*/ */
_history: null,
get history() { get history() {
if (!this._history) { delete this.history;
this._history = Cc["@mozilla.org/browser/nav-history-service;1"]. return this.history = Cc["@mozilla.org/browser/nav-history-service;1"].
getService(Ci.nsINavHistoryService); getService(Ci.nsINavHistoryService);
}
return this._history;
}, },
/** /**
* The Live Bookmark Service. * The Live Bookmark Service.
*/ */
_livemarks: null,
get livemarks() { get livemarks() {
if (!this._livemarks) { delete this.livemarks;
this._livemarks = Cc["@mozilla.org/browser/livemark-service;2"]. return this.livemarks = Cc["@mozilla.org/browser/livemark-service;2"].
getService(Ci.nsILivemarkService); getService(Ci.nsILivemarkService);
}
return this._livemarks;
}, },
/** /**
* The Annotations Service. * The Annotations Service.
*/ */
_annotations: null,
get annotations() { get annotations() {
if (!this._annotations) { delete this.annotations;
this._annotations = Cc["@mozilla.org/browser/annotation-service;1"]. return this.annotations = Cc["@mozilla.org/browser/annotation-service;1"].
getService(Ci.nsIAnnotationService); getService(Ci.nsIAnnotationService);
}
return this._annotations;
}, },
/** /**
* The Favicons Service * The Favicons Service
*/ */
_favicons: null,
get favicons() { get favicons() {
if (!this._favicons) { delete this.favicons;
this._favicons = Cc["@mozilla.org/browser/favicon-service;1"]. return this.favicons = Cc["@mozilla.org/browser/favicon-service;1"].
getService(Ci.nsIFaviconService); getService(Ci.nsIFaviconService);
}
return this._favicons;
}, },
/** /**
* The Microsummary Service * The Microsummary Service
*/ */
_microsummaries: null,
get microsummaries() { get microsummaries() {
if (!this._microsummaries) delete this.microsummaries;
this._microsummaries = Cc["@mozilla.org/microsummary/service;1"]. return this.microsummaries = Cc["@mozilla.org/microsummary/service;1"].
getService(Ci.nsIMicrosummaryService); getService(Ci.nsIMicrosummaryService);
return this._microsummaries;
}, },
/** /**
* The Places Tagging Service * The Places Tagging Service
*/ */
get tagging() { get tagging() {
if (!this._tagging) delete this.tagging;
this._tagging = Cc["@mozilla.org/browser/tagging-service;1"]. return this.tagging = Cc["@mozilla.org/browser/tagging-service;1"].
getService(Ci.nsITaggingService); getService(Ci.nsITaggingService);
return this._tagging;
}, },
_RDF: null,
get RDF() { get RDF() {
if (!this._RDF) delete this.RDF;
this._RDF = Cc["@mozilla.org/rdf/rdf-service;1"]. return this.RDF = Cc["@mozilla.org/rdf/rdf-service;1"].
getService(Ci.nsIRDFService); getService(Ci.nsIRDFService);
return this._RDF;
}, },
_localStore: null,
get localStore() { get localStore() {
if (!this._localStore) delete this.localStore;
this._localStore = this.RDF.GetDataSource("rdf:local-store"); return this.localStore = this.RDF.GetDataSource("rdf:local-store");
return this._localStore;
}, },
get tm() { get tm() {
return this.ptm.transactionManager; delete this.tm;
return this.tm = this.ptm.transactionManager;
}, },
_ptm: null,
get ptm() { get ptm() {
if (!this._ptm) { delete this.ptm;
this._ptm = Cc["@mozilla.org/browser/placesTransactionsService;1"]. return this.ptm = Cc["@mozilla.org/browser/placesTransactionsService;1"].
getService(Components.interfaces.nsIPlacesTransactionsService); getService(Ci.nsIPlacesTransactionsService);
}
return this._ptm;
}, },
_clipboard: null,
get clipboard() { get clipboard() {
if (!this._clipboard) { delete this.clipboard;
this._clipboard = Cc["@mozilla.org/widget/clipboard;1"]. return this.clipboard = Cc["@mozilla.org/widget/clipboard;1"].
getService(Ci.nsIClipboard); getService(Ci.nsIClipboard);
}
return this._clipboard;
}, },
/** /**
@ -218,9 +191,7 @@ var PlacesUtils = {
*/ */
_uri: function PU__uri(aSpec) { _uri: function PU__uri(aSpec) {
NS_ASSERT(aSpec, "empty URL spec"); NS_ASSERT(aSpec, "empty URL spec");
var ios = Cc["@mozilla.org/network/io-service;1"]. return IO.newURI(aSpec);
getService(Ci.nsIIOService);
return ios.newURI(aSpec, null, null);
}, },
/** /**
@ -239,16 +210,13 @@ var PlacesUtils = {
/** /**
* String bundle helpers * String bundle helpers
*/ */
__bundle: null,
get _bundle() { get _bundle() {
if (!this.__bundle) { const PLACES_STRING_BUNDLE_URI =
const PLACES_STRING_BUNDLE_URI =
"chrome://browser/locale/places/places.properties"; "chrome://browser/locale/places/places.properties";
this.__bundle = Cc["@mozilla.org/intl/stringbundle;1"]. delete this._bundle;
getService(Ci.nsIStringBundleService). return this._bundle = Cc["@mozilla.org/intl/stringbundle;1"].
createBundle(PLACES_STRING_BUNDLE_URI); getService(Ci.nsIStringBundleService).
} createBundle(PLACES_STRING_BUNDLE_URI);
return this.__bundle;
}, },
getFormattedString: function PU_getFormattedString(key, params) { getFormattedString: function PU_getFormattedString(key, params) {
@ -315,14 +283,12 @@ var PlacesUtils = {
* A result node * A result node
* @returns true if the node is a URL item, false otherwise * @returns true if the node is a URL item, false otherwise
*/ */
uriTypes: [Ci.nsINavHistoryResultNode.RESULT_TYPE_URI,
Ci.nsINavHistoryResultNode.RESULT_TYPE_VISIT,
Ci.nsINavHistoryResultNode.RESULT_TYPE_FULL_VISIT],
nodeIsURI: function PU_nodeIsURI(aNode) { nodeIsURI: function PU_nodeIsURI(aNode) {
NS_ASSERT(aNode, "null node"); NS_ASSERT(aNode, "null node");
return this.uriTypes.indexOf(aNode.type) != -1;
const NHRN = Ci.nsINavHistoryResultNode;
var type = aNode.type;
return type == NHRN.RESULT_TYPE_URI ||
type == NHRN.RESULT_TYPE_VISIT ||
type == NHRN.RESULT_TYPE_FULL_VISIT;
}, },
/** /**
@ -333,7 +299,6 @@ var PlacesUtils = {
*/ */
nodeIsQuery: function PU_nodeIsQuery(aNode) { nodeIsQuery: function PU_nodeIsQuery(aNode) {
NS_ASSERT(aNode, "null node"); NS_ASSERT(aNode, "null node");
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY; return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY;
}, },
@ -362,7 +327,6 @@ var PlacesUtils = {
*/ */
nodeIsHost: function PU_nodeIsHost(aNode) { nodeIsHost: function PU_nodeIsHost(aNode) {
NS_ASSERT(aNode, "null node"); NS_ASSERT(aNode, "null node");
return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_HOST; return aNode.type == Ci.nsINavHistoryResultNode.RESULT_TYPE_HOST;
}, },
@ -372,16 +336,14 @@ var PlacesUtils = {
* A result node * A result node
* @returns true if the node is a container item, false otherwise * @returns true if the node is a container item, false otherwise
*/ */
containerTypes: [Ci.nsINavHistoryResultNode.RESULT_TYPE_FOLDER,
Ci.nsINavHistoryResultNode.RESULT_TYPE_QUERY,
Ci.nsINavHistoryResultNode.RESULT_TYPE_HOST,
Ci.nsINavHistoryResultNode.RESULT_TYPE_DAY,
Ci.nsINavHistoryResultNode.RESULT_TYPE_DYNAMIC_CONTAINER],
nodeIsContainer: function PU_nodeIsContainer(aNode) { nodeIsContainer: function PU_nodeIsContainer(aNode) {
NS_ASSERT(aNode, "null node"); NS_ASSERT(aNode, "null node");
return this.containerTypes.indexOf(aNode.type) != -1;
const NHRN = Ci.nsINavHistoryResultNode;
var type = aNode.type;
return type == NHRN.RESULT_TYPE_HOST ||
type == NHRN.RESULT_TYPE_QUERY ||
type == NHRN.RESULT_TYPE_FOLDER ||
type == NHRN.RESULT_TYPE_DAY ||
type == NHRN.RESULT_TYPE_DYNAMIC_CONTAINER;
}, },
/** /**
@ -448,14 +410,22 @@ var PlacesUtils = {
NS_ASSERT(aNode, "null node"); NS_ASSERT(aNode, "null node");
var parent = aNode.parent; var parent = aNode.parent;
if (!parent || !PlacesUtils.nodeIsContainer(parent)) if (!parent)
return -1; return -1;
var wasOpen = parent.containerOpen; var wasOpen = parent.containerOpen;
parent.containerOpen = true; var result, oldViewer;
if (!wasOpen) {
result = parent.parentResult;
oldViewer = result.viewer;
result.viewer = null;
parent.containerOpen = true;
}
var cc = parent.childCount; var cc = parent.childCount;
asContainer(parent);
for (var i = 0; i < cc && parent.getChild(i) != aNode; ++i); for (var i = 0; i < cc && parent.getChild(i) != aNode; ++i);
parent.containerOpen = wasOpen; if (!wasOpen) {
parent.containerOpen = false;
result.viewer = oldViewer;
}
return i < cc ? i : -1; return i < cc ? i : -1;
}, },
@ -650,7 +620,7 @@ var PlacesUtils = {
* @returns A nsITransaction object that performs the copy. * @returns A nsITransaction object that performs the copy.
*/ */
_getURIItemCopyTransaction: function (aData, aContainer, aIndex) { _getURIItemCopyTransaction: function (aData, aContainer, aIndex) {
return this.ptm.createItem(this._uri(aData.uri), aContainer, aIndex, return this.ptm.createItem(IO.newURI(aData.uri), aContainer, aIndex,
aData.title, ""); aData.title, "");
}, },
@ -671,7 +641,7 @@ var PlacesUtils = {
_getBookmarkItemCopyTransaction: _getBookmarkItemCopyTransaction:
function PU__getBookmarkItemCopyTransaction(aData, aContainer, aIndex, function PU__getBookmarkItemCopyTransaction(aData, aContainer, aIndex,
aExcludeAnnotations) { aExcludeAnnotations) {
var itemURL = this._uri(aData.uri); var itemURL = IO.newURI(aData.uri);
var itemTitle = aData.title; var itemTitle = aData.title;
var keyword = aData.keyword; var keyword = aData.keyword;
var annos = aData.annos; var annos = aData.annos;
@ -724,8 +694,8 @@ var PlacesUtils = {
folderItemsTransactions); folderItemsTransactions);
} }
else { // node is a livemark else { // node is a livemark
var feedURI = self._uri(node.uri.feed); var feedURI = IO.newURI(node.uri.feed);
var siteURI = self._uri(node.uri.site); var siteURI = IO.newURI(node.uri.site);
txn = self.ptm.createLivemark(feedURI, siteURI, node.title, txn = self.ptm.createLivemark(feedURI, siteURI, node.title,
aContainer, index, node.annos); aContainer, index, node.annos);
} }
@ -776,8 +746,8 @@ var PlacesUtils = {
for (var i = 0; i < parts.length; i=i+2) { for (var i = 0; i < parts.length; i=i+2) {
var uriString = parts[i]; var uriString = parts[i];
var titleString = parts[i+1]; var titleString = parts[i+1];
// note: this._uri() will throw if uriString is not a valid URI // note: IO.newURI() will throw if uriString is not a valid URI
if (this._uri(uriString)) { if (IO.newURI(uriString)) {
nodes.push({ uri: uriString, nodes.push({ uri: uriString,
title: titleString ? titleString : uriString }); title: titleString ? titleString : uriString });
} }
@ -787,8 +757,8 @@ var PlacesUtils = {
var parts = blob.split("\n"); var parts = blob.split("\n");
for (var i = 0; i < parts.length; i++) { for (var i = 0; i < parts.length; i++) {
var uriString = parts[i]; var uriString = parts[i];
// note: this._uri() will throw if uriString is not a valid URI // note: IO.newURI() will throw if uriString is not a valid URI
if (uriString != "" && this._uri(uriString)) if (uriString != "" && IO.newURI(uriString))
nodes.push({ uri: uriString, title: uriString }); nodes.push({ uri: uriString, title: uriString });
} }
break; break;
@ -826,8 +796,8 @@ var PlacesUtils = {
} }
else if (copy) { else if (copy) {
// Place is a Livemark Container, should be reinstantiated // Place is a Livemark Container, should be reinstantiated
var feedURI = this._uri(data.uri.feed); var feedURI = IO.newURI(data.uri.feed);
var siteURI = this._uri(data.uri.site); var siteURI = IO.newURI(data.uri.site);
return this.ptm.createLivemark(feedURI, siteURI, data.title, container, return this.ptm.createLivemark(feedURI, siteURI, data.title, container,
index, data.annos); index, data.annos);
} }
@ -855,7 +825,7 @@ var PlacesUtils = {
default: default:
if (type == this.TYPE_X_MOZ_URL || type == this.TYPE_UNICODE) { if (type == this.TYPE_X_MOZ_URL || type == this.TYPE_UNICODE) {
var title = (type == this.TYPE_X_MOZ_URL) ? data.title : data.uri; var title = (type == this.TYPE_X_MOZ_URL) ? data.title : data.uri;
return this.ptm.createItem(this._uri(data.uri), container, index, return this.ptm.createItem(IO.newURI(data.uri), container, index,
title); title);
} }
return null; return null;
@ -892,7 +862,6 @@ var PlacesUtils = {
var result = this.history.executeQuery(query, options); var result = this.history.executeQuery(query, options);
result.root.containerOpen = true; result.root.containerOpen = true;
asContainer(result.root);
return result; return result;
}, },
@ -1270,7 +1239,7 @@ var PlacesUtils = {
*/ */
checkURLSecurity: function PU_checkURLSecurity(aURINode) { checkURLSecurity: function PU_checkURLSecurity(aURINode) {
if (!this.nodeIsBookmark(aURINode)) { if (!this.nodeIsBookmark(aURINode)) {
var uri = this._uri(aURINode.uri); var uri = IO.newURI(aURINode.uri);
if (uri.schemeIs("javascript") || uri.schemeIs("data")) { if (uri.schemeIs("javascript") || uri.schemeIs("data")) {
const BRANDING_BUNDLE_URI = "chrome://branding/locale/brand.properties"; const BRANDING_BUNDLE_URI = "chrome://branding/locale/brand.properties";
var brandShortName = Cc["@mozilla.org/intl/stringbundle;1"]. var brandShortName = Cc["@mozilla.org/intl/stringbundle;1"].
@ -1557,15 +1526,27 @@ var PlacesUtils = {
} }
} }
else { else {
let wasOpen = aNode.containerOpen; let result, oldViewer;
if (!wasOpen) try {
aNode.containerOpen = true; let wasOpen = aNode.containerOpen;
for (let i = 0; i < aNode.childCount; ++i) { if (!wasOpen) {
let child = aNode.getChild(i); result = aNode.parentResult;
if (this.nodeIsURI(child)) oldViewer = result.viewer;
urls.push(child.uri); result.viewer = null;
aNode.containerOpen = true;
}
for (let i = 0; i < aNode.childCount; ++i) {
let child = aNode.getChild(i);
if (this.nodeIsURI(child))
urls.push(child.uri);
}
if (!wasOpen)
aNode.containerOpen = false;
}
finally {
if (oldViewer)
result.viewer = oldViewer;
} }
aNode.containerOpen = wasOpen;
} }
return urls; return urls;
@ -1646,22 +1627,70 @@ var PlacesUtils = {
this._openTabset(urlsToOpen, aEvent); this._openTabset(urlsToOpen, aEvent);
}, },
_placesFlavors: null,
get placesFlavors() { get placesFlavors() {
if (!this._placesFlavors) { delete this.placesFlavors;
var placeTypes = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER, var placeTypes = [PlacesUtils.TYPE_X_MOZ_PLACE_CONTAINER,
PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR, PlacesUtils.TYPE_X_MOZ_PLACE_SEPARATOR,
PlacesUtils.TYPE_X_MOZ_PLACE]; PlacesUtils.TYPE_X_MOZ_PLACE];
this._placesFlavors = Cc["@mozilla.org/supports-array;1"]. this.placesFlavors = Cc["@mozilla.org/supports-array;1"].
createInstance(Ci.nsISupportsArray); createInstance(Ci.nsISupportsArray);
for (var i = 0; i < placeTypes.length; ++i) { for (var i = 0; i < placeTypes.length; ++i) {
var cstring = Cc["@mozilla.org/supports-cstring;1"]. var cstring = Cc["@mozilla.org/supports-cstring;1"].
createInstance(Ci.nsISupportsCString); createInstance(Ci.nsISupportsCString);
cstring.data = placeTypes[i]; cstring.data = placeTypes[i];
this._placesFlavors.AppendElement(cstring); this.placesFlavors.AppendElement(cstring);
}
} }
return this._placesFlavors; return this.placesFlavors;
},
/**
* Helper for the toolbar and menu views
*/
createMenuItemForNode: function(aNode, aContainersMap) {
var element;
var type = aNode.type;
if (type == Ci.nsINavHistoryResultNode.RESULT_TYPE_SEPARATOR)
element = document.createElement("menuseparator");
else {
var iconURI = aNode.icon;
var iconURISpec = "";
if (iconURI)
iconURISpec = iconURI.spec;
if (this.uriTypes.indexOf(type) != -1) {
element = document.createElement("menuitem");
element.setAttribute("statustext", aNode.uri);
element.className = "menuitem-iconic bookmark-item";
}
else if (this.containerTypes.indexOf(type) != -1) {
element = document.createElement("menu");
element.setAttribute("container", "true");
if (iconURISpec == "chrome://browser/skin/places/livemarkItem.png")
element.setAttribute("livemark", "true");
var popup = document.createElement("menupopup");
popup._resultNode = asContainer(aNode);
#ifndef XP_MACOSX
// no context menu on mac
popup.setAttribute("context", "placesContext");
#endif
element.appendChild(popup);
if (aContainersMap)
aContainersMap.push({ resultNode: aNode, domNode: popup });
element.className = "menu-iconic bookmark-item";
}
else
throw "Unexpected node";
element.setAttribute("label", aNode.title);
if (iconURISpec)
element.setAttribute("image", iconURISpec);
}
element.node = aNode;
element.node.viewIndex = 0;
return element;
} }
}; };

Просмотреть файл

@ -121,11 +121,13 @@ static NS_DEFINE_CID(kParserCID, NS_PARSER_CID);
#define KEY_MICSUM_GEN_URI_LOWER "micsum_gen_uri" #define KEY_MICSUM_GEN_URI_LOWER "micsum_gen_uri"
#define KEY_DATE_ADDED_LOWER "add_date" #define KEY_DATE_ADDED_LOWER "add_date"
#define KEY_LAST_MODIFIED_LOWER "last_modified" #define KEY_LAST_MODIFIED_LOWER "last_modified"
#define KEY_GENERATED_TITLE_LOWER "generated_title"
#define LOAD_IN_SIDEBAR_ANNO NS_LITERAL_CSTRING("bookmarkProperties/loadInSidebar") #define LOAD_IN_SIDEBAR_ANNO NS_LITERAL_CSTRING("bookmarkProperties/loadInSidebar")
#define DESCRIPTION_ANNO NS_LITERAL_CSTRING("bookmarkProperties/description") #define DESCRIPTION_ANNO NS_LITERAL_CSTRING("bookmarkProperties/description")
#define POST_DATA_ANNO NS_LITERAL_CSTRING("URIProperties/POSTData") #define POST_DATA_ANNO NS_LITERAL_CSTRING("URIProperties/POSTData")
#define LAST_CHARSET_ANNO NS_LITERAL_CSTRING("URIProperties/characterSet") #define LAST_CHARSET_ANNO NS_LITERAL_CSTRING("URIProperties/characterSet")
#define STATIC_TITLE_ANNO NS_LITERAL_CSTRING("bookmarks/staticTitle")
#define BOOKMARKS_MENU_ICON_URI "chrome://browser/skin/places/bookmarksMenu.png" #define BOOKMARKS_MENU_ICON_URI "chrome://browser/skin/places/bookmarksMenu.png"
@ -208,6 +210,13 @@ public:
// and the livemark title is known, we can create it. // and the livemark title is known, we can create it.
nsCOMPtr<nsIURI> mPreviousFeed; nsCOMPtr<nsIURI> mPreviousFeed;
// contains the text content of the previous microsummary, so that when the
// link ends, we can replace the bookmark's title with it and store the user's
// title in the staticTitle annotation.
nsString mPreviousMicrosummaryText;
nsCOMPtr<nsIMicrosummary> mPreviousMicrosummary;
void ConsumeHeading(nsAString* aHeading, ContainerType* aContainerType) void ConsumeHeading(nsAString* aHeading, ContainerType* aContainerType)
{ {
*aHeading = mPreviousText; *aHeading = mPreviousText;
@ -791,6 +800,10 @@ BookmarkContentSink::HandleLinkBegin(const nsIParserNode& node)
// mPreviousText will hold our link text, clear it so that can be appended to // mPreviousText will hold our link text, clear it so that can be appended to
frame.mPreviousText.Truncate(); frame.mPreviousText.Truncate();
// Empty our microsummary items from the previous frame.
frame.mPreviousMicrosummary = nsnull;
frame.mPreviousMicrosummaryText.Truncate();
// get the attributes we care about // get the attributes we care about
nsAutoString href; nsAutoString href;
@ -803,6 +816,7 @@ BookmarkContentSink::HandleLinkBegin(const nsIParserNode& node)
nsAutoString webPanel; nsAutoString webPanel;
nsAutoString itemId; nsAutoString itemId;
nsAutoString micsumGenURI; nsAutoString micsumGenURI;
nsAutoString generatedTitle;
nsAutoString dateAdded; nsAutoString dateAdded;
nsAutoString lastModified; nsAutoString lastModified;
@ -827,6 +841,8 @@ BookmarkContentSink::HandleLinkBegin(const nsIParserNode& node)
webPanel = node.GetValueAt(i); webPanel = node.GetValueAt(i);
} else if (key.LowerCaseEqualsLiteral(KEY_MICSUM_GEN_URI_LOWER)) { } else if (key.LowerCaseEqualsLiteral(KEY_MICSUM_GEN_URI_LOWER)) {
micsumGenURI = node.GetValueAt(i); micsumGenURI = node.GetValueAt(i);
} else if (key.LowerCaseEqualsLiteral(KEY_GENERATED_TITLE_LOWER)) {
generatedTitle = node.GetValueAt(i);
} else if (key.LowerCaseEqualsLiteral(KEY_DATE_ADDED_LOWER)) { } else if (key.LowerCaseEqualsLiteral(KEY_DATE_ADDED_LOWER)) {
dateAdded = node.GetValueAt(i); dateAdded = node.GetValueAt(i);
} else if (key.LowerCaseEqualsLiteral(KEY_LAST_MODIFIED_LOWER)) { } else if (key.LowerCaseEqualsLiteral(KEY_LAST_MODIFIED_LOWER)) {
@ -843,6 +859,7 @@ BookmarkContentSink::HandleLinkBegin(const nsIParserNode& node)
webPanel.Trim(kWhitespace); webPanel.Trim(kWhitespace);
itemId.Trim(kWhitespace); itemId.Trim(kWhitespace);
micsumGenURI.Trim(kWhitespace); micsumGenURI.Trim(kWhitespace);
generatedTitle.Trim(kWhitespace);
dateAdded.Trim(kWhitespace); dateAdded.Trim(kWhitespace);
lastModified.Trim(kWhitespace); lastModified.Trim(kWhitespace);
@ -946,15 +963,12 @@ BookmarkContentSink::HandleLinkBegin(const nsIParserNode& node)
} }
// import microsummary // import microsummary
// Note: expiration and generated title are ignored, and will be recalculated
// by the microsummary service
if (!micsumGenURI.IsEmpty()) { if (!micsumGenURI.IsEmpty()) {
nsCOMPtr<nsIURI> micsumGenURIObject; nsCOMPtr<nsIURI> micsumGenURIObject;
if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(micsumGenURIObject), micsumGenURI))) { if (NS_SUCCEEDED(NS_NewURI(getter_AddRefs(micsumGenURIObject), micsumGenURI))) {
nsCOMPtr<nsIMicrosummary> microsummary;
mMicrosummaryService->CreateMicrosummary(frame.mPreviousLink, micsumGenURIObject, mMicrosummaryService->CreateMicrosummary(frame.mPreviousLink, micsumGenURIObject,
getter_AddRefs(microsummary)); getter_AddRefs(frame.mPreviousMicrosummary));
mMicrosummaryService->SetMicrosummary(frame.mPreviousId, microsummary); frame.mPreviousMicrosummaryText = generatedTitle;
} }
} }
@ -1048,7 +1062,17 @@ BookmarkContentSink::HandleLinkEnd()
printf("Creating bookmark '%s' %lld\n", printf("Creating bookmark '%s' %lld\n",
NS_ConvertUTF16toUTF8(frame.mPreviousText).get(), frame.mPreviousId); NS_ConvertUTF16toUTF8(frame.mPreviousText).get(), frame.mPreviousId);
#endif #endif
mBookmarksService->SetItemTitle(frame.mPreviousId, frame.mPreviousText); if (frame.mPreviousMicrosummary) {
rv = mAnnotationService->SetItemAnnotationString(frame.mPreviousId, STATIC_TITLE_ANNO,
frame.mPreviousText, 0,
nsIAnnotationService::EXPIRE_NEVER);
NS_ASSERTION(NS_SUCCEEDED(rv), "Could not store user's bookmark title!");
mBookmarksService->SetItemTitle(frame.mPreviousId, frame.mPreviousMicrosummaryText);
mMicrosummaryService->SetMicrosummary(frame.mPreviousId, frame.mPreviousMicrosummary);
}
else
mBookmarksService->SetItemTitle(frame.mPreviousId, frame.mPreviousText);
} }
// Set last-modified-date for bookmarks and livemarks here so that the // Set last-modified-date for bookmarks and livemarks here so that the

Просмотреть файл

@ -718,6 +718,14 @@ var feedHandlerInfo = {
this.element(PREF_FEED_SELECTED_ACTION).value = "reader"; this.element(PREF_FEED_SELECTED_ACTION).value = "reader";
}, },
// Whether or not we are currently storing the action selected by the user.
// We use this to suppress notification-triggered updates to the list when
// we make changes that may spawn such updates, specifically when we change
// the action for the feed type, which results in feed preference updates,
// which spawn "pref changed" notifications that would otherwise cause us
// to rebuild the view unnecessarily.
_storingAction: false,
//**************************************************************************// //**************************************************************************//
// nsIMIMEInfo // nsIMIMEInfo
@ -881,7 +889,7 @@ var gApplicationsPane = {
observe: function (aSubject, aTopic, aData) { observe: function (aSubject, aTopic, aData) {
// Rebuild the list when there are changes to preferences that influence // Rebuild the list when there are changes to preferences that influence
// whether or not to show certain entries in the list. // whether or not to show certain entries in the list.
if (aTopic == "nsPref:changed") { if (aTopic == "nsPref:changed" && !this._storingAction) {
// These two prefs alter the list of visible types, so we have to rebuild // These two prefs alter the list of visible types, so we have to rebuild
// that list when they change. // that list when they change.
if (aData == PREF_SHOW_PLUGINS_IN_LIST || if (aData == PREF_SHOW_PLUGINS_IN_LIST ||
@ -1450,6 +1458,17 @@ var gApplicationsPane = {
// Changes // Changes
onSelectAction: function(aActionItem) { onSelectAction: function(aActionItem) {
this._storingAction = true;
try {
this._storeAction(aActionItem);
}
finally {
this._storingAction = false;
}
},
_storeAction: function(aActionItem) {
var typeItem = this._list.selectedItem; var typeItem = this._list.selectedItem;
var handlerInfo = this._handledTypes[typeItem.type]; var handlerInfo = this._handledTypes[typeItem.type];
@ -1499,13 +1518,43 @@ var gApplicationsPane = {
// as we handle it specially ourselves. // as we handle it specially ourselves.
aEvent.stopPropagation(); aEvent.stopPropagation();
var handlerApp;
#ifdef XP_WIN
var params = {};
var handlerInfo = this._handledTypes[this._list.selectedItem.type];
if (handlerInfo.type == TYPE_MAYBE_FEED) {
// MIME info will be null, create a temp object.
params.mimeInfo = this._mimeSvc.getFromTypeAndExtension(handlerInfo.type,
handlerInfo.primaryExtension);
} else {
params.mimeInfo = handlerInfo.wrappedHandlerInfo;
}
params.title = this._prefsBundle.getString("fpTitleChooseApp");
params.description = handlerInfo.description;
params.filename = null;
params.handlerApp = null;
window.openDialog("chrome://global/content/appPicker.xul", null,
"chrome,modal,centerscreen,titlebar,dialog=yes",
params);
if (params.handlerApp &&
params.handlerApp.executable &&
params.handlerApp.executable.isFile()) {
handlerApp = params.handlerApp;
// Add the app to the type's list of possible handlers.
handlerInfo.possibleApplicationHandlers.appendElement(handlerApp, false);
}
#else
var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker); var fp = Cc["@mozilla.org/filepicker;1"].createInstance(Ci.nsIFilePicker);
var winTitle = this._prefsBundle.getString("fpTitleChooseApp"); var winTitle = this._prefsBundle.getString("fpTitleChooseApp");
fp.init(window, winTitle, Ci.nsIFilePicker.modeOpen); fp.init(window, winTitle, Ci.nsIFilePicker.modeOpen);
fp.appendFilters(Ci.nsIFilePicker.filterApps); fp.appendFilters(Ci.nsIFilePicker.filterApps);
var handlerApp;
// Prompt the user to pick an app. If they pick one, and it's a valid // Prompt the user to pick an app. If they pick one, and it's a valid
// selection, then add it to the list of possible handlers. // selection, then add it to the list of possible handlers.
if (fp.show() == Ci.nsIFilePicker.returnOK && fp.file && if (fp.show() == Ci.nsIFilePicker.returnOK && fp.file &&
@ -1519,6 +1568,7 @@ var gApplicationsPane = {
let handlerInfo = this._handledTypes[this._list.selectedItem.type]; let handlerInfo = this._handledTypes[this._list.selectedItem.type];
handlerInfo.possibleApplicationHandlers.appendElement(handlerApp, false); handlerInfo.possibleApplicationHandlers.appendElement(handlerApp, false);
} }
#endif
// Rebuild the actions menu whether the user picked an app or canceled. // Rebuild the actions menu whether the user picked an app or canceled.
// If they picked an app, we want to add the app to the menu and select it. // If they picked an app, we want to add the app to the menu and select it.

Просмотреть файл

@ -85,7 +85,7 @@
style="&prefWin.styleWin;"> style="&prefWin.styleWin;">
#else #else
#ifdef XP_MACOSX #ifdef XP_MACOSX
style="&prefWindow.styleMac;"> style="&prefWin.styleMac;">
#else #else
style="&prefWin.styleGNOME;"> style="&prefWin.styleGNOME;">
#endif #endif

Просмотреть файл

@ -234,9 +234,9 @@ var gSecurityPane = {
var popup = document.getElementById(onloadPopupId); var popup = document.getElementById(onloadPopupId);
if (!popup) { if (!popup) {
var providerBranch = Cc["@mozilla.org/preferences-service;1"] var providerBranch = Cc["@mozilla.org/preferences-service;1"].
.getService(Ci.nsIPrefService) getService(Ci.nsIPrefService).
.getBranch("browser.safebrowsing.provider."); getBranch("browser.safebrowsing.provider.");
// fill in onload phishing list data -- but require a privacy policy // fill in onload phishing list data -- but require a privacy policy
// URL be provided, and require it to be at a chrome URL so it's always // URL be provided, and require it to be at a chrome URL so it's always
@ -374,8 +374,8 @@ var gSecurityPane = {
_masterPasswordSet: function () _masterPasswordSet: function ()
{ {
const Cc = Components.classes, Ci = Components.interfaces; const Cc = Components.classes, Ci = Components.interfaces;
var secmodDB = Cc["@mozilla.org/security/pkcs11moduledb;1"] var secmodDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].
.getService(Ci.nsIPKCS11ModuleDB); getService(Ci.nsIPKCS11ModuleDB);
var slot = secmodDB.findSlotByName(""); var slot = secmodDB.findSlotByName("");
if (slot) { if (slot) {
var status = slot.status; var status = slot.status;
@ -419,9 +419,12 @@ var gSecurityPane = {
*/ */
_removeMasterPassword: function () _removeMasterPassword: function ()
{ {
var secmodDB = Components.classes["@mozilla.org/security/pkcs11moduledb;1"] const Cc = Components.classes, Ci = Components.interfaces;
.getService(Components.interfaces.nsIPKCS11ModuleDB); var secmodDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].
getService(Ci.nsIPKCS11ModuleDB);
if (secmodDB.isFIPSEnabled) { if (secmodDB.isFIPSEnabled) {
var promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"].
getService(Ci.nsIPromptService);
var bundle = document.getElementById("bundlePreferences"); var bundle = document.getElementById("bundlePreferences");
promptService.alert(window, promptService.alert(window,
bundle.getString("pw_change_failed_title"), bundle.getString("pw_change_failed_title"),

Просмотреть файл

@ -38,8 +38,8 @@
var gDataProvider = null; var gDataProvider = null;
// An instance of our application is a PROT_Application object. It // An instance of our application is a PROT_Application object. It
// basically just populates a few globals and instantiates wardens and // basically just populates a few globals and instantiates wardens,
// the listmanager. // the listmanager, and the about:blocked error page.
/** /**
* An instance of our application. There should be exactly one of these. * An instance of our application. There should be exactly one of these.
@ -100,3 +100,30 @@ function PROT_Application() {
PROT_Application.prototype.getReportURL = function(name) { PROT_Application.prototype.getReportURL = function(name) {
return gDataProvider["getReport" + name + "URL"](); return gDataProvider["getReport" + name + "URL"]();
} }
/**
* about:blocked implementation
*/
PROT_Application.prototype.newChannel = function(uri) {
var ioService = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService);
var childURI = ioService.newURI("chrome://browser/content/safebrowsing/blockedSite.xhtml",
null, null);
var channel = ioService.newChannelFromURI(childURI);
channel.originalURI = uri;
return channel;
}
PROT_Application.prototype.getURIFlags = function(uri) {
return Ci.nsIAboutModule.ALLOW_SCRIPT;
}
PROT_Application.prototype.QueryInterface = function(iid) {
if (iid.equals(Ci.nsISupports) ||
iid.equals(Ci.nsIAboutModule))
return this;
Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
return null;
}

Просмотреть файл

@ -0,0 +1,210 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html [
<!ENTITY % htmlDTD PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd">
%htmlDTD;
<!ENTITY % globalDTD SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
%brandDTD;
<!ENTITY % blockedSiteDTD SYSTEM "chrome://browser/locale/safebrowsing/phishing-afterload-warning-message.dtd">
%blockedSiteDTD;
]>
<!-- ***** 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 mozilla.org code.
-
- The Initial Developer of the Original Code is
- Netscape Communications Corporation.
- Portions created by the Initial Developer are Copyright (C) 1998
- the Initial Developer. All Rights Reserved.
-
- Contributor(s):
- Adam Lock <adamlock@netscape.com>
- William R. Price <wrprice@alumni.rice.edu>
- Henrik Skupin <mozilla@hskupin.info>
- Jeff Walden <jwalden+code@mit.edu>
- Johnathan Nightingale <johnath@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
- the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
- in which case the provisions of the GPL or the LGPL are applicable instead
- of those above. If you wish to allow use of your version of this file only
- under the terms of either the GPL or the LGPL, and not to allow others to
- use your version of this file under the terms of the MPL, indicate your
- decision by deleting the provisions above and replace them with the notice
- and other provisions required by the LGPL or the GPL. If you do not delete
- the provisions above, a recipient may use your version of this file under
- the terms of any one of the MPL, the GPL or the LGPL.
-
- ***** END LICENSE BLOCK ***** -->
<html xmlns="http://www.w3.org/1999/xhtml" class="blacklist">
<head>
<link rel="stylesheet" href="chrome://global/skin/netError.css" type="text/css" media="all" />
<link rel="icon" type="image/png" id="favicon" href="chrome://global/skin/icons/blacklist_favicon.png"/>
<script type="application/javascript" src="chrome://global/content/strres.js"/>
<script type="application/javascript"><![CDATA[
// Error url MUST be formatted like this:
// about:blocked?e=error_code&u=url
// Note that this file uses document.documentURI to get
// the URL (with the format from above). This is because
// document.location.href gets the current URI off the docshell,
// which is the URL displayed in the location bar, i.e.
// the URI that the user attempted to load.
function getErrorCode()
{
var url = document.documentURI;
var error = url.search(/e\=/);
var duffUrl = url.search(/\&u\=/);
return decodeURIComponent(url.slice(error + 2, duffUrl));
}
function getURL()
{
var url = document.documentURI;
var index = url.search(/u\=/);
// index == -1 if not found; if so, return an empty string
// instead of what would turn out to be portions of the URI
if (index == -1)
return "";
return decodeURIComponent(url.slice(index + 2));
}
/**
* Attempt to parse the result of getURL and extract a hostname. Fail back
* to getURL so that we always return something meaningful.
*/
function getHostString()
{
var ios = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService);
var url = getURL();
try {
return ios.newURI(url, null, null).host;
} catch (e) {
return url;
}
}
// Elements that tend to need content set
var errorTitleText, errorShortDescText, errorLongDesc, errorLongDescText;
// The string bundles managing strings for various blocked page scenarios
var sb = srGetStrBundle("chrome://browser/locale/safebrowsing/blockedSite.properties");
var brandBundle = srGetStrBundle("chrome://branding/locale/brand.properties");
var brandShortName = brandBundle.GetStringFromName("brandShortName");
function initPage()
{
// Set up the cached elements
errorTitleText = document.getElementById("errorTitleText");
errorShortDescText = document.getElementById("errorShortDescText");
errorLongDesc = document.getElementById("errorLongDesc");
errorLongDescText = document.getElementById("errorLongDescText");
// Handoff to the appropriate initializer, based on error code
switch(getErrorCode()) {
case "malwareBlocked" :
initPage_malware();
break;
case "phishingBlocked" :
initPage_phishing();
break;
}
}
/**
* Initialize custom strings and functionality for blocked malware case
*/
function initPage_malware()
{
document.title = sb.GetStringFromName("malware.title");
errorTitleText.textContent = document.title;
errorShortDescText.textContent = sb.formatStringFromName("malware.shortDesc",
[getHostString()], 1);
errorLongDesc.innerHTML = sb.GetStringFromName("malware.longDesc");
}
/**
* Initialize custom strings and functionality for blocked phishing case
*/
function initPage_phishing()
{
document.title = sb.GetStringFromName("phishing.title");
errorTitleText.textContent = document.title;
errorShortDescText.textContent = sb.formatStringFromName("phishing.shortDesc",
[getHostString()], 1);
var longDesc = sb.GetStringFromName("phishing.longDesc");
// If we have a more-info link for the phishing information, add it in,
// otherwise just use the generic text
var faqURL = Components.classes["@mozilla.org/toolkit/URLFormatterService;1"]
.getService(Components.interfaces.nsIURLFormatter)
.formatURLPref("browser.safebrowsing.warning.infoURL");
if(faqURL && faqURL != "about:blank") {
longDesc += sb.formatStringFromName("phishing.learnMoreLink",
[brandShortName], 1);
errorLongDesc.innerHTML = longDesc;
document.getElementById("faqLink").setAttribute("href", faqURL);
}
else
errorLongDesc.innerHTML = longDesc;
}
]]></script>
</head>
<body dir="&locale.dir;">
<div id="errorPageContainer">
<!-- Error Title -->
<div id="errorTitle">
<h1 id="errorTitleText" />
</div>
<div id="errorLongContent">
<!-- Short Description -->
<div id="errorShortDesc">
<p id="errorShortDescText" />
</div>
<!-- Long Description -->
<div id="errorLongDesc">
<p id="errorLongDescText" />
</div>
<!-- Action buttons -->
<div id="buttons">
<xul:button xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="getMeOutButton" label="&safeb.palm.accept.label;" oncommand="window.home();" />
</div>
</div>
</div>
<!--
- Note: It is important to run the script this way, instead of using
- an onload handler. This is because error pages are loaded as
- LOAD_BACKGROUND, which means that onload handlers will not be executed.
-->
<script type="application/javascript">initPage();</script>
</body>
</html>

Просмотреть файл

@ -64,6 +64,13 @@ function PROT_MalwareWarden() {
"a:1:" + testData.length + "\n" + "a:1:" + testData.length + "\n" +
testData + testData +
"\n"; "\n";
testData = "mozilla.com/firefox/its-a-trap.html";
testUpdate +=
"n:1000\ni:test-phish-simple\nad:1\n" +
"a:1:" + testData.length + "\n" +
testData +
"\n";
var dbService_ = Cc["@mozilla.org/url-classifier/dbservice;1"] var dbService_ = Cc["@mozilla.org/url-classifier/dbservice;1"]
.getService(Ci.nsIUrlClassifierDBService); .getService(Ci.nsIUrlClassifierDBService);

Просмотреть файл

@ -208,7 +208,6 @@ PROT_PhishMsgDisplayerBase.prototype.browserSelected = function() {
this.messageShouldShow_ = true; this.messageShouldShow_ = true;
} }
this.hideLockIcon_(); // Comes back when we are unselected or unloaded
this.addWarningInUrlbar_(); // Goes away when we are unselected or unloaded this.addWarningInUrlbar_(); // Goes away when we are unselected or unloaded
// messageShouldShow might be false if the user dismissed the warning, // messageShouldShow might be false if the user dismissed the warning,
@ -234,7 +233,6 @@ PROT_PhishMsgDisplayerBase.prototype.explicitShow = function() {
*/ */
PROT_PhishMsgDisplayerBase.prototype.browserUnselected = function() { PROT_PhishMsgDisplayerBase.prototype.browserUnselected = function() {
this.removeWarningInUrlbar_(); this.removeWarningInUrlbar_();
this.unhideLockIcon_();
if (this.messageShowing_) if (this.messageShowing_)
this.hideMessage_(); this.hideMessage_();
} }
@ -290,7 +288,6 @@ PROT_PhishMsgDisplayerBase.prototype.done = function() {
// If we were started, we must be the current problem, so these things // If we were started, we must be the current problem, so these things
// must be showing // must be showing
this.removeWarningInUrlbar_(); this.removeWarningInUrlbar_();
this.unhideLockIcon_();
// Could be though that they've closed the warning dialog // Could be though that they've closed the warning dialog
if (this.messageShowing_) if (this.messageShowing_)
@ -327,28 +324,6 @@ PROT_PhishMsgDisplayerBase.prototype.removeIfExists_ = function(orig,
return orig; return orig;
} }
/**
* We don't want to confuse users if they land on a phishy page that uses
* SSL, so ensure that the lock icon never shows when we're showing our
* warning.
*/
PROT_PhishMsgDisplayerBase.prototype.hideLockIcon_ = function() {
var lockIcon = this.doc_.getElementById("lock-icon");
if (!lockIcon)
return;
lockIcon.hidden = true;
}
/**
* Ensure they can see it after our warning is finished.
*/
PROT_PhishMsgDisplayerBase.prototype.unhideLockIcon_ = function() {
var lockIcon = this.doc_.getElementById("lock-icon");
if (!lockIcon)
return;
lockIcon.hidden = false;
}
/** /**
* This method makes our warning icon visible in the location bar. It will * This method makes our warning icon visible in the location bar. It will
* be removed only when the problematic document is navigated awy from * be removed only when the problematic document is navigated awy from
@ -557,26 +532,7 @@ PROT_PhishMsgDisplayerCanvas.inherits(PROT_PhishMsgDisplayerBase);
* Displays the warning message. First we make sure the overlay is loaded * Displays the warning message. First we make sure the overlay is loaded
* then call showMessageAfterOverlay_. * then call showMessageAfterOverlay_.
*/ */
PROT_PhishMsgDisplayerCanvas.prototype.showMessage_ = function() { PROT_PhishMsgDisplayerCanvas.prototype.showMessage_ = function() { }
G_Debug(this, "Showing message.");
// Load the overlay if we haven't already.
var dimmer = this.doc_.getElementById('safebrowsing-dim-area-canvas');
if (!dimmer) {
var onOverlayMerged = BindToObject(this.showMessageAfterOverlay_,
this);
var observer = new G_ObserverWrapper("xul-overlay-merged",
onOverlayMerged);
this.doc_.loadOverlay(
"chrome://browser/content/safebrowsing/warning-overlay.xul",
observer);
} else {
// The overlay is already loaded so we go ahead and call
// showMessageAfterOverlay_.
this.showMessageAfterOverlay_();
}
}
/** /**
* This does the actual work of showing the warning message. * This does the actual work of showing the warning message.
@ -703,34 +659,7 @@ PROT_PhishMsgDisplayerCanvas.prototype.isVisibleElement_ = function(elt) {
/** /**
* Hide the warning message from the user. * Hide the warning message from the user.
*/ */
PROT_PhishMsgDisplayerCanvas.prototype.hideMessage_ = function() { PROT_PhishMsgDisplayerCanvas.prototype.hideMessage_ = function() { }
G_Debug(this, "Hiding phishing warning.");
G_Assert(this, this.messageShowing_, "Hide message called but not showing?");
this.messageShowing_ = false;
this.repainter_.cancel();
this.repainter_ = null;
// Hide the warning popup.
var message = this.doc_.getElementById(this.messageId_);
message.hidden = true;
message.style.display = "none";
var content = this.doc_.getElementById(this.messageContentId_);
content.style.height = "";
content.style.overflow = "";
var tail = this.doc_.getElementById(this.messageTailId_);
tail.hidden = true;
tail.style.display = "none";
// Remove the canvas element from the chrome document.
var pageCanvas = this.doc_.getElementById(this.pageCanvasId_);
pageCanvas.parentNode.removeChild(pageCanvas);
// Hide the dimmer.
var dimarea = this.doc_.getElementById(this.dimAreaId_);
dimarea.hidden = true;
}
/** /**

Просмотреть файл

@ -3,4 +3,5 @@ browser.jar:
* content/browser/safebrowsing/sb-loader.js (content/sb-loader.js) * content/browser/safebrowsing/sb-loader.js (content/sb-loader.js)
+ content/browser/safebrowsing/warning-overlay.xul (content/warning-overlay.xul) + content/browser/safebrowsing/warning-overlay.xul (content/warning-overlay.xul)
+ content/browser/safebrowsing/report-phishing-overlay.xul (content/report-phishing-overlay.xul) + content/browser/safebrowsing/report-phishing-overlay.xul (content/report-phishing-overlay.xul)
+ content/browser/safebrowsing/blockedSite.xhtml (content/blockedSite.xhtml)
% overlay chrome://browser/content/browser.xul chrome://browser/content/safebrowsing/report-phishing-overlay.xul % overlay chrome://browser/content/browser.xul chrome://browser/content/safebrowsing/report-phishing-overlay.xul

Просмотреть файл

@ -61,6 +61,13 @@ SafebrowsingApplicationMod.prototype.registerSelf = function(compMgr, fileSpec,
fileSpec, fileSpec,
loc, loc,
type); type);
compMgr.registerFactoryLocation(this.cid,
"UrlClassifier Blocked Error Page",
"@mozilla.org/network/protocol/about;1?what=blocked",
fileSpec,
loc,
type);
}; };
SafebrowsingApplicationMod.prototype.getClassObject = function(compMgr, cid, iid) { SafebrowsingApplicationMod.prototype.getClassObject = function(compMgr, cid, iid) {

Просмотреть файл

@ -1979,7 +1979,11 @@ SessionStoreService.prototype = {
var cr = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsICrashReporter); var cr = Cc["@mozilla.org/xre/app-info;1"].getService(Ci.nsICrashReporter);
cr.annotateCrashReport("URL", currentUrl); cr.annotateCrashReport("URL", currentUrl);
} }
catch (ex) { debug(ex); } catch (ex) {
// don't make noise when crashreporter is built but not enabled
if (ex.result != Components.results.NS_ERROR_NOT_INITIALIZED)
debug(ex);
}
}, },
/** /**

Просмотреть файл

@ -35,9 +35,9 @@
# ***** END LICENSE BLOCK ***** # ***** END LICENSE BLOCK *****
# Required Plugins: # Required Plugins:
# SetVistaDefaultApp http://nsis.sourceforge.net/SetVistaDefaultApp_plug-in # AppAssocReg http://nsis.sourceforge.net/Application_Association_Registration_plug-in
# ShellLink http://nsis.sourceforge.net/ShellLink_plug-in # ShellLink http://nsis.sourceforge.net/ShellLink_plug-in
# UAC http://nsis.sourceforge.net/UAC_plug-in # UAC http://nsis.sourceforge.net/UAC_plug-in
; Set verbosity to 3 (e.g. no script) to lessen the noise in the build logs ; Set verbosity to 3 (e.g. no script) to lessen the noise in the build logs
!verbose 3 !verbose 3
@ -110,14 +110,18 @@ VIAddVersionKey "FileDescription" "${BrandShortName} Installer"
!insertmacro _LoggingCommon !insertmacro _LoggingCommon
!insertmacro AddDDEHandlerValues !insertmacro AddDDEHandlerValues
!insertmacro ChangeMUIHeaderImage
!insertmacro CloseApp !insertmacro CloseApp
!insertmacro CreateRegKey !insertmacro CreateRegKey
!insertmacro GetPathFromString !insertmacro GetPathFromString
!insertmacro GetParent
!insertmacro IsHandlerForInstallDir !insertmacro IsHandlerForInstallDir
!insertmacro ManualCloseAppPrompt !insertmacro ManualCloseAppPrompt
!insertmacro RegCleanAppHandler !insertmacro RegCleanAppHandler
!insertmacro RegCleanMain !insertmacro RegCleanMain
!insertmacro RegCleanUninstall !insertmacro RegCleanUninstall
!insertmacro SetBrandNameVars
!insertmacro UnloadUAC
!insertmacro WriteRegStr2 !insertmacro WriteRegStr2
!insertmacro WriteRegDWORD2 !insertmacro WriteRegDWORD2
@ -129,6 +133,7 @@ VIAddVersionKey "FileDescription" "${BrandShortName} Installer"
!insertmacro InstallOnInitCommon !insertmacro InstallOnInitCommon
!insertmacro InstallStartCleanupCommon !insertmacro InstallStartCleanupCommon
!insertmacro LeaveDirectoryCommon !insertmacro LeaveDirectoryCommon
!insertmacro OnEndCommon
!insertmacro PreDirectoryCommon !insertmacro PreDirectoryCommon
Name "${BrandFullName}" Name "${BrandFullName}"
@ -164,9 +169,11 @@ ReserveFile summary.ini
* Installation Pages * Installation Pages
*/ */
; Welcome Page ; Welcome Page
!define MUI_PAGE_CUSTOMFUNCTION_PRE preWelcome
!insertmacro MUI_PAGE_WELCOME !insertmacro MUI_PAGE_WELCOME
; License Page ; License Page
!define MUI_PAGE_CUSTOMFUNCTION_SHOW showLicense
!define MUI_LICENSEPAGE_CHECKBOX !define MUI_LICENSEPAGE_CHECKBOX
!insertmacro MUI_PAGE_LICENSE license.rtf !insertmacro MUI_PAGE_LICENSE license.rtf
@ -217,7 +224,7 @@ Section "-InstallStartCleanup"
DetailPrint $(STATUS_CLEANUP) DetailPrint $(STATUS_CLEANUP)
SetDetailsPrint none SetDetailsPrint none
SetOutPath $INSTDIR SetOutPath "$INSTDIR"
${StartInstallLog} "${BrandFullName}" "${AB_CD}" "${AppVersion}" "${GREVersion}" ${StartInstallLog} "${BrandFullName}" "${AB_CD}" "${AppVersion}" "${GREVersion}"
; Try to delete the app's main executable and if we can't delete it try to ; Try to delete the app's main executable and if we can't delete it try to
@ -229,8 +236,8 @@ Section "-InstallStartCleanup"
; Create a temporary backup directory. ; Create a temporary backup directory.
GetTempFileName $TmpVal "$TEMP" GetTempFileName $TmpVal "$TEMP"
${DeleteFile} $TmpVal ${DeleteFile} "$TmpVal"
SetOutPath $TmpVal SetOutPath "$TmpVal"
${If} ${FileExists} "$INSTDIR\${FileMainEXE}" ${If} ${FileExists} "$INSTDIR\${FileMainEXE}"
ClearErrors ClearErrors
@ -266,7 +273,7 @@ Section "-InstallStartCleanup"
StrCpy $R1 "xpicleanup.exe" StrCpy $R1 "xpicleanup.exe"
Call CheckInUse Call CheckInUse
SetOutPath $INSTDIR SetOutPath "$INSTDIR"
RmDir /r "$TmpVal" RmDir /r "$TmpVal"
ClearErrors ClearErrors
@ -389,6 +396,11 @@ Section "-Application" APP_IDX
StrCpy $TmpVal "HKLM" ; used primarily for logging StrCpy $TmpVal "HKLM" ; used primarily for logging
${RegCleanMain} "Software\Mozilla" ${RegCleanMain} "Software\Mozilla"
${RegCleanUninstall} ${RegCleanUninstall}
ReadRegStr $0 HKLM "Software\mozilla.org\Mozilla" "CurrentVersion"
${If} "$0" != "${GREVersion}"
WriteRegStr HKLM "Software\mozilla.org\Mozilla" "CurrentVersion" "${GREVersion}"
${EndIf}
${EndIf} ${EndIf}
${RemoveDeprecatedKeys} ${RemoveDeprecatedKeys}
@ -533,8 +545,9 @@ Function CheckInUse
MessageBox MB_RETRYCANCEL|MB_ICONQUESTION "$0" IDRETRY retry MessageBox MB_RETRYCANCEL|MB_ICONQUESTION "$0" IDRETRY retry
Delete "$TmpVal\$R1" Delete "$TmpVal\$R1"
CopyFiles /SILENT "$TmpVal\*" "$INSTDIR\" CopyFiles /SILENT "$TmpVal\*" "$INSTDIR\"
SetOutPath $INSTDIR SetOutPath "$INSTDIR"
RmDir /r "$TmpVal" RmDir /r "$TmpVal"
${OnEndCommon}
Quit Quit
${EndIf} ${EndIf}
${EndIf} ${EndIf}
@ -612,19 +625,16 @@ Function CopyFile
FunctionEnd FunctionEnd
Function LaunchApp Function LaunchApp
ClearErrors
${GetParameters} $0 ${GetParameters} $0
${If} $0 != "" ${GetOptions} "$0" "/UAC:" $1
ClearErrors ${If} ${Errors}
${GetOptions} "$0" "/UAC:" $1 ${ManualCloseAppPrompt} "${WindowClass}" "$(WARN_MANUALLY_CLOSE_APP_LAUNCH)"
${Unless} ${Errors} Exec "$INSTDIR\${FileMainEXE}"
GetFunctionAddress $0 LaunchAppFromElevatedProcess ${Else}
UAC::ExecCodeSegment $0 GetFunctionAddress $0 LaunchAppFromElevatedProcess
Quit UAC::ExecCodeSegment $0
${EndUnless}
${EndIf} ${EndIf}
${ManualCloseAppPrompt} "${WindowClass}" "$(WARN_MANUALLY_CLOSE_APP_LAUNCH)"
Exec "$INSTDIR\${FileMainEXE}"
FunctionEnd FunctionEnd
Function LaunchAppFromElevatedProcess Function LaunchAppFromElevatedProcess
@ -635,6 +645,10 @@ Function LaunchAppFromElevatedProcess
${StrFilter} "${FileMainEXE}" "+" "" "" $R9 ${StrFilter} "${FileMainEXE}" "+" "" "" $R9
ReadRegStr $0 HKLM "Software\Clients\StartMenuInternet\$R9\DefaultIcon" "" ReadRegStr $0 HKLM "Software\Clients\StartMenuInternet\$R9\DefaultIcon" ""
${GetPathFromString} "$0" $0 ${GetPathFromString} "$0" $0
${GetParent} "$0" $1
; Set our current working directory to the application's install directory
; otherwise the 7-Zip temp directory will be in use and won't be deleted.
SetOutPath "$1"
Exec "$0" Exec "$0"
FunctionEnd FunctionEnd
@ -653,7 +667,23 @@ FunctionEnd
BrandingText " " BrandingText " "
################################################################################ ################################################################################
# Page pre and leave functions # Page pre, show, and leave functions
Function preWelcome
${If} ${FileExists} "$EXEDIR\localized\distribution\modern-wizard.bmp"
Delete "$PLUGINSDIR\modern-wizard.bmp"
CopyFiles /SILENT "$EXEDIR\localized\distribution\modern-wizard.bmp" "$PLUGINSDIR\modern-wizard.bmp"
${EndIf}
FunctionEnd
Function showLicense
${If} ${FileExists} "$EXEDIR\localized\distribution\modern-header.bmp"
${AndIf} $hHeaderBitmap == ""
Delete "$PLUGINSDIR\modern-header.bmp"
CopyFiles /SILENT "$EXEDIR\localized\distribution\modern-header.bmp" "$PLUGINSDIR\modern-header.bmp"
${ChangeMUIHeaderImage} "$PLUGINSDIR\modern-header.bmp"
${EndIf}
FunctionEnd
Function preOptions Function preOptions
!insertmacro MUI_HEADER_TEXT "$(OPTIONS_PAGE_TITLE)" "$(OPTIONS_PAGE_SUBTITLE)" !insertmacro MUI_HEADER_TEXT "$(OPTIONS_PAGE_TITLE)" "$(OPTIONS_PAGE_SUBTITLE)"
@ -758,6 +788,9 @@ FunctionEnd
# Initialization Functions # Initialization Functions
Function .onInit Function .onInit
StrCpy $LANGUAGE 0
${SetBrandNameVars} "$EXEDIR\localized\distribution\setup.ini"
${InstallOnInitCommon} "$(WARN_UNSUPPORTED_MSG)" ${InstallOnInitCommon} "$(WARN_UNSUPPORTED_MSG)"
!insertmacro MUI_INSTALLOPTIONS_EXTRACT "options.ini" !insertmacro MUI_INSTALLOPTIONS_EXTRACT "options.ini"
@ -768,8 +801,6 @@ Function .onInit
!insertmacro createComponentsINI !insertmacro createComponentsINI
!insertmacro createShortcutsINI !insertmacro createShortcutsINI
StrCpy $LANGUAGE 0
; There must always be nonlocalized and localized directories. ; There must always be nonlocalized and localized directories.
${GetSize} "$EXEDIR\nonlocalized\" "/S=0K" $R5 $R7 $R8 ${GetSize} "$EXEDIR\nonlocalized\" "/S=0K" $R5 $R7 $R8
${GetSize} "$EXEDIR\localized\" "/S=0K" $R6 $R7 $R8 ${GetSize} "$EXEDIR\localized\" "/S=0K" $R6 $R7 $R8
@ -784,12 +815,12 @@ Function .onInit
; Hide DOMi in the components page if it isn't available. ; Hide DOMi in the components page if it isn't available.
SectionSetText ${DOMI_IDX} "" SectionSetText ${DOMI_IDX} ""
${EndIf} ${EndIf}
; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if
; the user clicks the back button
StrCpy $hHeaderBitmap ""
FunctionEnd FunctionEnd
Function .OnInstFailed Function .onGUIEnd
UAC::Unload ${OnEndCommon}
FunctionEnd
Function .OnInstSuccess
UAC::Unload
FunctionEnd FunctionEnd

Просмотреть файл

@ -55,6 +55,11 @@
${SetStartMenuInternet} ${SetStartMenuInternet}
${FixShellIconHandler} ${FixShellIconHandler}
${SetUninstallKeys} ${SetUninstallKeys}
ReadRegStr $0 HKLM "Software\mozilla.org\Mozilla" "CurrentVersion"
${If} "$0" != "${GREVersion}"
WriteRegStr HKLM "Software\mozilla.org\Mozilla" "CurrentVersion" "${GREVersion}"
${EndIf}
${EndIf} ${EndIf}
${RemoveDeprecatedKeys} ${RemoveDeprecatedKeys}
@ -110,7 +115,7 @@
; Only register as the handler on Vista if the app registry name exists ; Only register as the handler on Vista if the app registry name exists
; under the RegisteredApplications registry key. ; under the RegisteredApplications registry key.
${Unless} ${Errors} ${Unless} ${Errors}
SetVistaDefaultApp::SetAsDefault "${AppRegName}" AppAssocReg::SetAppAsDefaultAll "${AppRegName}"
${EndUnless} ${EndUnless}
${EndIf} ${EndIf}
!endif !endif

Просмотреть файл

@ -35,9 +35,9 @@
# ***** END LICENSE BLOCK ***** # ***** END LICENSE BLOCK *****
# Required Plugins: # Required Plugins:
# SetVistaDefaultApp http://nsis.sourceforge.net/SetVistaDefaultApp_plug-in # AppAssocReg http://nsis.sourceforge.net/Application_Association_Registration_plug-in
# ShellLink http://nsis.sourceforge.net/ShellLink_plug-in # ShellLink http://nsis.sourceforge.net/ShellLink_plug-in
# UAC http://nsis.sourceforge.net/UAC_plug-in # UAC http://nsis.sourceforge.net/UAC_plug-in
; Set verbosity to 3 (e.g. no script) to lessen the noise in the build logs ; Set verbosity to 3 (e.g. no script) to lessen the noise in the build logs
!verbose 3 !verbose 3
@ -62,10 +62,10 @@ Var TmpVal
; The following includes are provided by NSIS. ; The following includes are provided by NSIS.
!include FileFunc.nsh !include FileFunc.nsh
!include LogicLib.nsh !include LogicLib.nsh
!include MUI.nsh
!include TextFunc.nsh !include TextFunc.nsh
!include WinMessages.nsh !include WinMessages.nsh
!include WordFunc.nsh !include WordFunc.nsh
!include MUI.nsh
; WinVer.nsh was added in the same release that RequestExecutionLevel so check ; WinVer.nsh was added in the same release that RequestExecutionLevel so check
; if ___WINVER__NSH___ is defined to determine if RequestExecutionLevel is ; if ___WINVER__NSH___ is defined to determine if RequestExecutionLevel is
@ -74,7 +74,7 @@ Var TmpVal
!ifdef ___WINVER__NSH___ !ifdef ___WINVER__NSH___
RequestExecutionLevel user RequestExecutionLevel user
!else !else
!warning "Uninstaller will be created without Vista compatibility.$\n \ !warning "Installer will be created without Vista compatibility.$\n \
Upgrade your NSIS installation to at least version 2.22 to resolve." Upgrade your NSIS installation to at least version 2.22 to resolve."
!endif !endif
@ -104,10 +104,13 @@ VIAddVersionKey "FileDescription" "${BrandShortName} Helper"
!insertmacro RegCleanAppHandler !insertmacro RegCleanAppHandler
!insertmacro RegCleanMain !insertmacro RegCleanMain
!insertmacro RegCleanUninstall !insertmacro RegCleanUninstall
!insertmacro UnloadUAC
!insertmacro WriteRegDWORD2 !insertmacro WriteRegDWORD2
!insertmacro WriteRegStr2 !insertmacro WriteRegStr2
!insertmacro un.ChangeMUIHeaderImage
!insertmacro un.CleanVirtualStore !insertmacro un.CleanVirtualStore
!insertmacro un.DeleteRelativeProfiles
!insertmacro un.GetLongPath !insertmacro un.GetLongPath
!insertmacro un.GetSecondInstallPath !insertmacro un.GetSecondInstallPath
!insertmacro un.ManualCloseAppPrompt !insertmacro un.ManualCloseAppPrompt
@ -118,12 +121,16 @@ VIAddVersionKey "FileDescription" "${BrandShortName} Helper"
!insertmacro un.RegCleanUninstall !insertmacro un.RegCleanUninstall
!insertmacro un.RegCleanProtocolHandler !insertmacro un.RegCleanProtocolHandler
!insertmacro un.RemoveQuotesFromPath !insertmacro un.RemoveQuotesFromPath
!insertmacro un.SetBrandNameVars
!include shared.nsh !include shared.nsh
; Helper macros for ui callbacks. Insert these after shared.nsh ; Helper macros for ui callbacks. Insert these after shared.nsh
!insertmacro OnEndCommon
!insertmacro UninstallOnInitCommon !insertmacro UninstallOnInitCommon
!insertmacro un.OnEndCommon
Name "${BrandFullName}" Name "${BrandFullName}"
OutFile "helper.exe" OutFile "helper.exe"
InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})" "InstallLocation" InstallDirRegKey HKLM "Software\Microsoft\Windows\CurrentVersion\Uninstall\${BrandFullNameInternal} (${AppVersion})" "InstallLocation"
@ -152,11 +159,11 @@ ShowUnInstDetails nevershow
* Uninstall Pages * Uninstall Pages
*/ */
; Welcome Page ; Welcome Page
!define MUI_PAGE_CUSTOMFUNCTION_PRE un.preWelcome
!insertmacro MUI_UNPAGE_WELCOME !insertmacro MUI_UNPAGE_WELCOME
; Uninstall Confirm Page ; Uninstall Confirm Page
!define MUI_PAGE_CUSTOMFUNCTION_LEAVE un.leaveConfirm UninstPage custom un.preConfirm un.leaveConfirm
!insertmacro MUI_UNPAGE_CONFIRM
; Remove Files Page ; Remove Files Page
!insertmacro MUI_UNPAGE_INSTFILES !insertmacro MUI_UNPAGE_INSTFILES
@ -201,6 +208,11 @@ Section "Uninstall"
ClearErrors ClearErrors
${EndIf} ${EndIf}
${MUI_INSTALLOPTIONS_READ} $0 "unconfirm.ini" "Field 3" "State"
${If} "$0" == "1"
${un.DeleteRelativeProfiles} "Mozilla\Firefox"
${EndIf}
SetShellVarContext current ; Set SHCTX to HKCU SetShellVarContext current ; Set SHCTX to HKCU
${un.RegCleanMain} "Software\Mozilla" ${un.RegCleanMain} "Software\Mozilla"
${un.RegCleanUninstall} ${un.RegCleanUninstall}
@ -354,10 +366,50 @@ FunctionEnd
BrandingText " " BrandingText " "
################################################################################ ################################################################################
# Page pre and leave functions # Page pre, show, and leave functions
Function un.preWelcome
${If} ${FileExists} "$INSTDIR\distribution\modern-wizard.bmp"
Delete "$PLUGINSDIR\modern-wizard.bmp"
CopyFiles /SILENT "$INSTDIR\distribution\modern-wizard.bmp" "$PLUGINSDIR\modern-wizard.bmp"
${EndIf}
FunctionEnd
Function un.preConfirm
${If} ${FileExists} "$INSTDIR\distribution\modern-header.bmp"
${AndIf} $hHeaderBitmap == ""
Delete "$PLUGINSDIR\modern-header.bmp"
CopyFiles /SILENT "$INSTDIR\distribution\modern-header.bmp" "$PLUGINSDIR\modern-header.bmp"
${un.ChangeMUIHeaderImage} "$PLUGINSDIR\modern-header.bmp"
${EndIf}
!insertmacro un.createUnConfirmINI
!insertmacro MUI_HEADER_TEXT "$(UN_CONFIRM_PAGE_TITLE)" "$(UN_CONFIRM_PAGE_SUBTITLE)"
; The Summary custom page has a textbox that will automatically receive
; focus. This sets the focus to the Install button instead.
!insertmacro MUI_INSTALLOPTIONS_INITDIALOG "unconfirm.ini"
GetDlgItem $0 $HWNDPARENT 1
${MUI_INSTALLOPTIONS_READ} $1 "unconfirm.ini" "Field 4" "HWND"
SetCtlColors $1 0x000000 0xFFFFEE
ShowWindow $1 ${SW_HIDE}
System::Call "user32::SetFocus(i r0, i 0x0007, i,i)i"
!insertmacro MUI_INSTALLOPTIONS_SHOW
FunctionEnd
; Checks if the app being uninstalled is running.
Function un.leaveConfirm Function un.leaveConfirm
${MUI_INSTALLOPTIONS_READ} $0 "unconfirm.ini" "Settings" "State"
StrCmp $0 "3" +1 continue
${MUI_INSTALLOPTIONS_READ} $0 "unconfirm.ini" "Field 3" "State"
${MUI_INSTALLOPTIONS_READ} $1 "unconfirm.ini" "Field 4" "HWND"
StrCmp $0 1 +1 +3
ShowWindow $1 ${SW_SHOW}
Abort
ShowWindow $1 ${SW_HIDE}
Abort
continue:
; Try to delete the app executable and if we can't delete it try to find the ; Try to delete the app executable and if we can't delete it try to find the
; app's message window and prompt the user to close the app. This allows ; app's message window and prompt the user to close the app. This allows
; running an instance that is located in another directory. If for whatever ; running an instance that is located in another directory. If for whatever
@ -415,5 +467,19 @@ Function un.onInit
${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}" ${Unless} ${FileExists} "$INSTDIR\${FileMainEXE}"
Abort Abort
${EndUnless} ${EndUnless}
StrCpy $LANGUAGE 0 StrCpy $LANGUAGE 0
${un.SetBrandNameVars} "$INSTDIR\distribution\setup.ini"
; Initialize $hHeaderBitmap to prevent redundant changing of the bitmap if
; the user clicks the back button
StrCpy $hHeaderBitmap ""
FunctionEnd
Function .onGUIEnd
${OnEndCommon}
FunctionEnd
Function un.onGUIEnd
${un.OnEndCommon}
FunctionEnd FunctionEnd

Просмотреть файл

@ -193,6 +193,10 @@ include $(call EXPAND_LOCALE_SRCDIR,toolkit/locales)/installer/windows/charset.m
repackage-win32-installer: WIN32_INSTALLER_OUT=$(_ABS_DIST)/install/sea/$(PKG_BASENAME).installer.exe repackage-win32-installer: WIN32_INSTALLER_OUT=$(_ABS_DIST)/install/sea/$(PKG_BASENAME).installer.exe
repackage-win32-installer: $(WIN32_INSTALLER_IN) $(SUBMAKEFILES) repackage-win32-installer: $(WIN32_INSTALLER_IN) $(SUBMAKEFILES)
ifneq (en-US,$(AB_CD))
@echo "Verifying $(AB_CD) installer variable usage"
@$(PERL) $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/check-locales.pl $(LOCALE_SRCDIR)/installer
endif
@echo "Repackaging $(WIN32_INSTALLER_IN) into $(WIN32_INSTALLER_OUT)." @echo "Repackaging $(WIN32_INSTALLER_IN) into $(WIN32_INSTALLER_OUT)."
ifdef MOZ_BRANDING_DIRECTORY ifdef MOZ_BRANDING_DIRECTORY
$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY) export $(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY) export

Просмотреть файл

@ -273,19 +273,19 @@
<!ENTITY thisFrameMenu.label "This Frame"> <!ENTITY thisFrameMenu.label "This Frame">
<!ENTITY thisFrameMenu.accesskey "h"> <!ENTITY thisFrameMenu.accesskey "h">
<!ENTITY textZoomEnlargeCmd.label "Increase"> <!ENTITY fullZoomEnlargeCmd.label "Zoom In">
<!ENTITY textZoomEnlargeCmd.accesskey "I"> <!ENTITY fullZoomEnlargeCmd.accesskey "I">
<!ENTITY textZoomEnlargeCmd.commandkey "+"> <!ENTITY fullZoomEnlargeCmd.commandkey "+">
<!ENTITY textZoomEnlargeCmd.commandkey2 "="> <!-- + is above this key on many keyboards --> <!ENTITY fullZoomEnlargeCmd.commandkey2 "="> <!-- + is above this key on many keyboards -->
<!ENTITY textZoomReduceCmd.label "Decrease"> <!ENTITY fullZoomReduceCmd.label "Zoom Out">
<!ENTITY textZoomReduceCmd.accesskey "D"> <!ENTITY fullZoomReduceCmd.accesskey "O">
<!ENTITY textZoomReduceCmd.commandkey "-"> <!ENTITY fullZoomReduceCmd.commandkey "-">
<!ENTITY textZoomResetCmd.commandkey "0"> <!ENTITY fullZoomResetCmd.commandkey "0">
<!ENTITY textZoomResetCmd.label "Normal"> <!ENTITY fullZoomResetCmd.label "Reset">
<!ENTITY textZoomResetCmd.accesskey "N"> <!ENTITY fullZoomResetCmd.accesskey "R">
<!ENTITY textSize.label "Text Size"> <!ENTITY fullZoom.label "Zoom">
<!ENTITY textSize.accesskey "z"> <!ENTITY fullZoom.accesskey "Z">
<!ENTITY newTabButton.tooltip "Open a new tab"> <!ENTITY newTabButton.tooltip "Open a new tab">
<!ENTITY newWindowButton.tooltip "Open a new window"> <!ENTITY newWindowButton.tooltip "Open a new window">
@ -345,3 +345,5 @@
<!ENTITY editBookmark.done.label "Done"> <!ENTITY editBookmark.done.label "Done">
<!ENTITY editBookmark.delete.label "Delete"> <!ENTITY editBookmark.delete.label "Delete">
<!ENTITY identity.moreInfoLinkText "Tell me more about this web site...">

Просмотреть файл

@ -83,12 +83,23 @@ refreshBlocked.goButton.accesskey=A
refreshBlocked.refreshLabel=%S prevented this page from automatically reloading. refreshBlocked.refreshLabel=%S prevented this page from automatically reloading.
refreshBlocked.redirectLabel=%S prevented this page from automatically redirecting to another page. refreshBlocked.redirectLabel=%S prevented this page from automatically redirecting to another page.
# Chromeless popup handling
chromelessWindow.warningMessage=The web site at %S has hidden your toolbars.
chromelessWindow.warningNoLocation=This web site has hidden your toolbars.
chromelessWindow.showToolbarsButton=Show Toolbars
chromelessWindow.accessKey=S
# Star button # Star button
starButtonOn.tooltip=Edit this bookmark starButtonOn.tooltip=Edit this bookmark
starButtonOff.tooltip=Bookmark this page starButtonOff.tooltip=Bookmark this page
# Identity information
identity.domainverified.title=Location Verified
identity.domainverified.body=You are currently visiting:
identity.domainverified.supplemental=Information identifying the owner of this web site may not have been validated.
identity.identified.title=Identity Verified
identity.identified.body=This web site is owned by:
identity.identified.verifier=Verified by: %S
identity.identified.state_and_country=%S, %S
identity.identified.title_with_country=%S (%S)
identity.unknown.title=Identity Unknown
identity.unknown.body=This web site does not supply identity information.
identity.encrypted=Your connection to this web site is encrypted to prevent eavesdropping.
identity.unencrypted=Your connection to this web site is not encrypted.

Просмотреть файл

@ -4,7 +4,7 @@
<!-- When making changes to prefWindow.styleWin test both Windows Classic and <!-- When making changes to prefWindow.styleWin test both Windows Classic and
Luna since widget heights are different based on the OS theme --> Luna since widget heights are different based on the OS theme -->
<!ENTITY prefWin.styleWin "width: 42em; min-height: 44em;"> <!ENTITY prefWin.styleWin "width: 42em; min-height: 44em;">
<!ENTITY prefWindow.styleMac "width: 47em;"> <!ENTITY prefWin.styleMac "width: 47em; min-height: 45em;">
<!ENTITY prefWin.styleGNOME "width: 42em; min-height: 44.5em;"> <!ENTITY prefWin.styleGNOME "width: 42em; min-height: 44.5em;">
<!ENTITY paneMain.title "Main"> <!ENTITY paneMain.title "Main">

Просмотреть файл

@ -0,0 +1,11 @@
malware.title=Suspected Attack Site!
malware.shortDesc=The web site at %S has been reported as an attack site and has been blocked based on your security preferences.
malware.longDesc=<p>Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.</p>\n<p>Web site owners who believe their site has been reported as an attack site in error may <a href='http://www.stopbadware.org/home/reviewinfo' >request a review</a>.</p>
phishing.title=Suspected Web Forgery!
phishing.shortDesc=The web site at %S has been reported as a web forgery designed to trick users into sharing personal or financial information.
phishing.longDesc=<p>Entering any personal information on this page may result in identity theft or other fraud.</p><p>These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.</p>
# Localization note (phishing.learnMoreLink): please leave the <a id="faqLink" href=""> text
# as-is. A localized href is pulled in from user preferences automatically.
phishing.learnMoreLink=<p>You can find out more about <a id="faqLink" href="">how %S protects you</a> from phishing attacks.</p>

Просмотреть файл

@ -60,3 +60,4 @@ externalProtocolUnknown=<Unknown>
externalProtocolChkMsg=Remember my choice for all links of this type. externalProtocolChkMsg=Remember my choice for all links of this type.
externalProtocolLaunchBtn=Launch application externalProtocolLaunchBtn=Launch application
malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences. malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences.
phishingBlocked=The web site at %S has been reported as a web forgery designed to trick users into sharing personal or financial information.

Просмотреть файл

@ -123,6 +123,17 @@
</ul> </ul>
"> ">
<!ENTITY nssBadCert.title "Secure Connection Failed">
<!ENTITY nssBadCert.longDesc "
<ul>
<li>This could be a problem with the server's configuration, or it could be
someone trying to impersonate the server.</li>
<li>If you have connected to this server successfully in the past, the error may
be temporary, and you can try again later.</li>
<li>You can see and change your current list of servers with known security problems
in your advanced encryption settings.</li>
</ul>
">
<!ENTITY sharedLongDesc " <!ENTITY sharedLongDesc "
<ul> <ul>
@ -140,3 +151,9 @@
<p>Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.</p> <p>Attack sites try to install programs that steal private information, use your computer to attack others, or damage your system.</p>
<p>Web site owners who believe their site has been reported as an attack site in error may <a href='http://www.stopbadware.org/home/reviewinfo' >request a review</a>.</p> <p>Web site owners who believe their site has been reported as an attack site in error may <a href='http://www.stopbadware.org/home/reviewinfo' >request a review</a>.</p>
"> ">
<!ENTITY phishingBlocked.title "Suspected Web Forgery!">
<!ENTITY phishingBlocked.longDesc "
<p>Entering any personal information on this page may result in identity theft or other fraud.</p>
<p>These types of web forgeries are used in scams known as phishing attacks, in which fraudulent web pages and emails are used to imitate sources you may trust.</p>
">

Просмотреть файл

@ -41,60 +41,68 @@
# Accesskeys are defined by prefixing the letter that is to be used for the # Accesskeys are defined by prefixing the letter that is to be used for the
# accesskey with an ampersand (e.g. &). # accesskey with an ampersand (e.g. &).
# Do not replace ${BrandShortName} or ${BrandFullName} with a custom string. # Do not replace $BrandShortName, $BrandFullName, or $BrandFullNameDA with a
# custom string and always use the same one as used by the en-US files.
# $BrandFullNameDA allows the string to contain an ampersand (e.g. DA stands
# for double ampersand) and prevents the letter following the ampersand from
# being used as an accesskey.
# You can use \n to create a newline in the string but only when the string # You can use \n to create a newline in the string but only when the string
# from en-US contains a \n. # from en-US contains a \n.
REG_APP_DESC=${BrandShortName} delivers safe, easy web browsing. A familiar user interface, enhanced security features including protection from online identity theft, and integrated search let you get the most out of the web. REG_APP_DESC=$BrandShortName delivers safe, easy web browsing. A familiar user interface, enhanced security features including protection from online identity theft, and integrated search let you get the most out of the web.
OPTIONAL_COMPONENTS_TITLE=Choose Optional Components OPTIONAL_COMPONENTS_TITLE=Choose Optional Components
OPTIONAL_COMPONENTS_SUBTITLE=Choose which features of $(^NameDA) you want to install. OPTIONAL_COMPONENTS_SUBTITLE=Choose which features of $BrandShortName you want to install.
OPTIONAL_COMPONENTS_LABEL=Optional Components: OPTIONAL_COMPONENTS_LABEL=Optional Components:
APP_DESC=Required files for the ${BrandShortName} application
DOMI_TITLE=DOM Inspector DOMI_TITLE=DOM Inspector
DOMI_TEXT=Inspects the structure and properties of a window and its contents. DOMI_TEXT=Inspects the structure and properties of a window and its contents.
QFA_TITLE=Quality Feedback Agent CONTEXT_OPTIONS=$BrandShortName &Options
QFA_TEXT=Sends information about program crashes to Mozilla. CONTEXT_SAFE_MODE=$BrandShortName &Safe Mode
CONTEXT_OPTIONS=${BrandShortName} &Options
CONTEXT_SAFE_MODE=${BrandShortName} &Safe Mode
SAFE_MODE=Safe Mode SAFE_MODE=Safe Mode
OPTIONS_PAGE_TITLE=Setup Type OPTIONS_PAGE_TITLE=Setup Type
OPTIONS_PAGE_SUBTITLE=Choose setup options OPTIONS_PAGE_SUBTITLE=Choose setup options
SHORTCUTS_PAGE_TITLE=Set Up Shortcuts SHORTCUTS_PAGE_TITLE=Set Up Shortcuts
SHORTCUTS_PAGE_SUBTITLE=Create Program Icons SHORTCUTS_PAGE_SUBTITLE=Create Program Icons
SUMMARY_PAGE_TITLE=Summary SUMMARY_PAGE_TITLE=Summary
SUMMARY_PAGE_SUBTITLE=Ready to start installing ${BrandShortName} SUMMARY_PAGE_SUBTITLE=Ready to start installing $BrandShortName
SUMMARY_INSTALLED_TO=${BrandShortName} will be installed to the following location: SUMMARY_INSTALLED_TO=$BrandShortName will be installed to the following location:
SUMMARY_CLICK=Click Install to continue. SUMMARY_CLICK=Click Install to continue.
SURVEY_TEXT=&Tell us what you thought of ${BrandShortName} SURVEY_TEXT=&Tell us what you thought of $BrandShortName
LAUNCH_TEXT=&Launch ${BrandFullName} now LAUNCH_TEXT=&Launch $BrandShortName now
WARN_APP_RUNNING_INSTALL=${BrandFullName} must be closed to proceed with the installation.\n\nClick "OK" to exit ${BrandFullName} automatically and continue. WARN_APP_RUNNING_INSTALL=$BrandShortName must be closed to proceed with the installation.\n\nClick "OK" to exit $BrandShortName automatically and continue.
CREATE_ICONS_DESC=Create icons for ${BrandShortName}: CREATE_ICONS_DESC=Create icons for $BrandShortName:
ICONS_DESKTOP=On my &Desktop ICONS_DESKTOP=On my &Desktop
ICONS_STARTMENU=In my &Start Menu Programs folder ICONS_STARTMENU=In my &Start Menu Programs folder
ICONS_QUICKLAUNCH=In my &Quick Launch bar ICONS_QUICKLAUNCH=In my &Quick Launch bar
WARN_MANUALLY_CLOSE_APP_UNINSTALL=${BrandFullName} must be closed to proceed with the uninstall.\n\nPlease close ${BrandFullName} to continue. WARN_MANUALLY_CLOSE_APP_UNINSTALL=$BrandShortName must be closed to proceed with the uninstall.\n\nPlease close $BrandShortName to continue.
WARN_MANUALLY_CLOSE_APP_LAUNCH=${BrandFullName} is already running.\n\nPlease close ${BrandFullName} prior to launching the version you have just installed. WARN_MANUALLY_CLOSE_APP_LAUNCH=$BrandShortName is already running.\n\nPlease close $BrandShortName prior to launching the version you have just installed.
WARN_WRITE_ACCESS=You don't have access to write to the installation directory.\n\nClick OK to select a different directory. WARN_WRITE_ACCESS=You don't have access to write to the installation directory.\n\nClick OK to select a different directory.
WARN_DISK_SPACE=You don't have sufficient disk space to install to this location.\n\nClick OK to select a different location. WARN_DISK_SPACE=You don't have sufficient disk space to install to this location.\n\nClick OK to select a different location.
WARN_UNSUPPORTED_MSG=Sorry, ${BrandShortName} can't be installed. This version of ${BrandShortName} requires ${MinUnsupportedVer} or newer. WARN_UNSUPPORTED_MSG=Sorry, $BrandShortName can't be installed. This version of $BrandShortName requires ${MinUnsupportedVer} or newer.
WARN_RESTART_REQUIRED_UNINSTALL=Your computer must be restarted to complete a previous uninstall of ${BrandShortName}. Do you want to reboot now? WARN_RESTART_REQUIRED_UNINSTALL=Your computer must be restarted to complete a previous uninstall of $BrandShortName. Do you want to reboot now?
ERROR_CREATE_DIRECTORY=Error creating directory:\n\n$0\n\nClick Cancel to stop the installation or\nRetry to try again. ERROR_CREATE_DIRECTORY=Error creating directory:\n\n$0\n\nClick Cancel to stop the installation or\nRetry to try again.
STATUS_INSTALL_APP=Installing ${BrandShortName}... UN_CONFIRM_PAGE_TITLE=Uninstall $BrandFullName
UN_CONFIRM_PAGE_SUBTITLE=Remove $BrandFullName from your computer.
UN_CONFIRM_UNINSTALLED_FROM=$BrandShortName will be uninstalled from the following location:
UN_CONFIRM_CLICK=Click Uninstall to continue.
UN_REMOVE_PROFILES=&Remove my $BrandShortName personal data and customizations
UN_REMOVE_PROFILES_DESC=This will permanently remove your bookmarks, saved passwords, cookies and customizations. You may wish to keep this information if you plan on installing another version of $BrandShortName in the future.
STATUS_INSTALL_APP=Installing $BrandShortName...
STATUS_INSTALL_LANG=Installing Language Files (${AB_CD})... STATUS_INSTALL_LANG=Installing Language Files (${AB_CD})...
STATUS_INSTALL_OPTIONAL=Installing Optional Components... STATUS_INSTALL_OPTIONAL=Installing Optional Components...
STATUS_UNINSTALL_MAIN=Uninstalling ${BrandShortName}... STATUS_UNINSTALL_MAIN=Uninstalling $BrandShortName...
STATUS_CLEANUP=A Little Housekeeping... STATUS_CLEANUP=A Little Housekeeping...
# _DESC strings support approximately 65 characters per line. # _DESC strings support approximately 65 characters per line.
# One line # One line
OPTIONS_SUMMARY=Choose the type of setup you prefer, then click Next. OPTIONS_SUMMARY=Choose the type of setup you prefer, then click Next.
# One line # One line
OPTION_STANDARD_DESC=${BrandShortName} will be installed with the most common options. OPTION_STANDARD_DESC=$BrandShortName will be installed with the most common options.
OPTION_STANDARD_RADIO=&Standard OPTION_STANDARD_RADIO=&Standard
# One line # One line
OPTION_COMPLETE_DESC=${BrandShortName} will be installed with all available options. OPTION_COMPLETE_DESC=$BrandShortName will be installed with all available options.
OPTION_COMPLETE_RADIO=C&omplete OPTION_COMPLETE_RADIO=C&omplete
# Two lines # Two lines
OPTION_CUSTOM_DESC=You may choose individual options to be installed. Recommended for experienced users. OPTION_CUSTOM_DESC=You may choose individual options to be installed. Recommended for experienced users.

Просмотреть файл

@ -44,54 +44,55 @@
# Accesskeys are defined by prefixing the letter that is to be used for the # Accesskeys are defined by prefixing the letter that is to be used for the
# accesskey with an ampersand (e.g. &). # accesskey with an ampersand (e.g. &).
# Do not replace $(^NameDA) or $(^Name) with a custom string. # Do not replace $BrandShortName, $BrandFullName, or $BrandFullNameDA with a
# custom string and always use the same one as used by the en-US files.
# Do not change $(^NameDA) to $(^Name) or $(^Name) to $(^NameDA). NameDA allows # $BrandFullNameDA allows the string to contain an ampersand (e.g. DA stands
# Name to contain an ampersand (e.g. DA stands for double ampersand) and # for double ampersand) and prevents the letter following the ampersand from
# prevents the letter following the ampersand being used as an accesskey. # being used as an accesskey.
# You can use \n to create a newline in the string but only when the string # You can use \n to create a newline in the string but only when the string
# from en-US contains a \n. # from en-US contains a \n.
MUI_TEXT_WELCOME_INFO_TITLE=Welcome to the $(^NameDA) Setup Wizard
MUI_TEXT_WELCOME_INFO_TEXT=This wizard will guide you through the installation of $(^NameDA).\n\nIt is recommended that you close all other applications before starting Setup. This will make it possible to update relevant system files without having to reboot your computer.\n\n$_CLICK MUI_TEXT_WELCOME_INFO_TITLE=Welcome to the $BrandFullNameDA Setup Wizard
MUI_TEXT_WELCOME_INFO_TEXT=This wizard will guide you through the installation of $BrandFullNameDA.\n\nIt is recommended that you close all other applications before starting Setup. This will make it possible to update relevant system files without having to reboot your computer.\n\n$_CLICK
MUI_TEXT_LICENSE_TITLE=License Agreement MUI_TEXT_LICENSE_TITLE=License Agreement
MUI_TEXT_LICENSE_SUBTITLE=Please review the license terms before installing $(^NameDA). MUI_TEXT_LICENSE_SUBTITLE=Please review the license terms before installing $BrandFullNameDA.
MUI_INNERTEXT_LICENSE_TOP=Press Page Down to see the rest of the agreement. MUI_INNERTEXT_LICENSE_TOP=Press Page Down to see the rest of the agreement.
MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX=If you accept the terms of the agreement, click the check box below. You must accept the agreement to install $(^NameDA). $_CLICK MUI_INNERTEXT_LICENSE_BOTTOM_CHECKBOX=If you accept the terms of the agreement, click the check box below. You must accept the agreement to install $BrandFullNameDA. $_CLICK
MUI_INNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS=If you accept the terms of the agreement, select the first option below. You must accept the agreement to install $(^NameDA). $_CLICK MUI_INNERTEXT_LICENSE_BOTTOM_RADIOBUTTONS=If you accept the terms of the agreement, select the first option below. You must accept the agreement to install $BrandFullNameDA. $_CLICK
MUI_TEXT_COMPONENTS_TITLE=Choose Components MUI_TEXT_COMPONENTS_TITLE=Choose Components
MUI_TEXT_COMPONENTS_SUBTITLE=Choose which features of $(^NameDA) you want to install. MUI_TEXT_COMPONENTS_SUBTITLE=Choose which features of $BrandFullNameDA you want to install.
MUI_INNERTEXT_COMPONENTS_DESCRIPTION_TITLE=Description MUI_INNERTEXT_COMPONENTS_DESCRIPTION_TITLE=Description
MUI_INNERTEXT_COMPONENTS_DESCRIPTION_INFO=Position your mouse over a component to see its description. MUI_INNERTEXT_COMPONENTS_DESCRIPTION_INFO=Position your mouse over a component to see its description.
MUI_TEXT_DIRECTORY_TITLE=Choose Install Location MUI_TEXT_DIRECTORY_TITLE=Choose Install Location
MUI_TEXT_DIRECTORY_SUBTITLE=Choose the folder in which to install $(^NameDA). MUI_TEXT_DIRECTORY_SUBTITLE=Choose the folder in which to install $BrandFullNameDA.
MUI_TEXT_INSTALLING_TITLE=Installing MUI_TEXT_INSTALLING_TITLE=Installing
MUI_TEXT_INSTALLING_SUBTITLE=Please wait while $(^NameDA) is being installed. MUI_TEXT_INSTALLING_SUBTITLE=Please wait while $BrandFullNameDA is being installed.
MUI_TEXT_FINISH_TITLE=Installation Complete MUI_TEXT_FINISH_TITLE=Installation Complete
MUI_TEXT_FINISH_SUBTITLE=Setup was completed successfully. MUI_TEXT_FINISH_SUBTITLE=Setup was completed successfully.
MUI_TEXT_ABORT_TITLE=Installation Aborted MUI_TEXT_ABORT_TITLE=Installation Aborted
MUI_TEXT_ABORT_SUBTITLE=Setup was not completed successfully. MUI_TEXT_ABORT_SUBTITLE=Setup was not completed successfully.
MUI_BUTTONTEXT_FINISH=&Finish MUI_BUTTONTEXT_FINISH=&Finish
MUI_TEXT_FINISH_INFO_TITLE=Completing the $(^NameDA) Setup Wizard MUI_TEXT_FINISH_INFO_TITLE=Completing the $BrandFullNameDA Setup Wizard
MUI_TEXT_FINISH_INFO_TEXT=$(^NameDA) has been installed on your computer.\n\nClick Finish to close this wizard. MUI_TEXT_FINISH_INFO_TEXT=$BrandFullNameDA has been installed on your computer.\n\nClick Finish to close this wizard.
MUI_TEXT_FINISH_INFO_REBOOT=Your computer must be restarted in order to complete the installation of $(^NameDA). Do you want to reboot now? MUI_TEXT_FINISH_INFO_REBOOT=Your computer must be restarted in order to complete the installation of $BrandFullNameDA. Do you want to reboot now?
MUI_TEXT_FINISH_REBOOTNOW=Reboot now MUI_TEXT_FINISH_REBOOTNOW=Reboot now
MUI_TEXT_FINISH_REBOOTLATER=I want to manually reboot later MUI_TEXT_FINISH_REBOOTLATER=I want to manually reboot later
MUI_TEXT_STARTMENU_TITLE=Choose Start Menu Folder MUI_TEXT_STARTMENU_TITLE=Choose Start Menu Folder
MUI_TEXT_STARTMENU_SUBTITLE=Choose a Start Menu folder for the $(^NameDA) shortcuts. MUI_TEXT_STARTMENU_SUBTITLE=Choose a Start Menu folder for the $BrandFullNameDA shortcuts.
MUI_INNERTEXT_STARTMENU_TOP=Select the Start Menu folder in which you would like to create the program's shortcuts. You can also enter a name to create a new folder. MUI_INNERTEXT_STARTMENU_TOP=Select the Start Menu folder in which you would like to create the program's shortcuts. You can also enter a name to create a new folder.
MUI_TEXT_ABORTWARNING=Are you sure you want to quit $(^Name) Setup? MUI_TEXT_ABORTWARNING=Are you sure you want to quit $BrandFullName Setup?
MUI_UNTEXT_WELCOME_INFO_TITLE=Welcome to the $(^NameDA) Uninstall Wizard MUI_UNTEXT_WELCOME_INFO_TITLE=Welcome to the $BrandFullNameDA Uninstall Wizard
MUI_UNTEXT_WELCOME_INFO_TEXT=This wizard will guide you through the uninstallation of $(^NameDA).\n\nBefore starting the uninstallation, make sure $(^NameDA) is not running.\n\n$_CLICK MUI_UNTEXT_WELCOME_INFO_TEXT=This wizard will guide you through the uninstallation of $BrandFullNameDA.\n\nBefore starting the uninstallation, make sure $BrandFullNameDA is not running.\n\n$_CLICK
MUI_UNTEXT_CONFIRM_TITLE=Uninstall $(^NameDA) MUI_UNTEXT_CONFIRM_TITLE=Uninstall $BrandFullNameDA
MUI_UNTEXT_CONFIRM_SUBTITLE=Remove $(^NameDA) from your computer. MUI_UNTEXT_CONFIRM_SUBTITLE=Remove $BrandFullNameDA from your computer.
MUI_UNTEXT_UNINSTALLING_TITLE=Uninstalling MUI_UNTEXT_UNINSTALLING_TITLE=Uninstalling
MUI_UNTEXT_UNINSTALLING_SUBTITLE=Please wait while $(^NameDA) is being uninstalled. MUI_UNTEXT_UNINSTALLING_SUBTITLE=Please wait while $BrandFullNameDA is being uninstalled.
MUI_UNTEXT_FINISH_TITLE=Uninstallation Complete MUI_UNTEXT_FINISH_TITLE=Uninstallation Complete
MUI_UNTEXT_FINISH_SUBTITLE=Uninstall was completed successfully. MUI_UNTEXT_FINISH_SUBTITLE=Uninstall was completed successfully.
MUI_UNTEXT_ABORT_TITLE=Uninstallation Aborted MUI_UNTEXT_ABORT_TITLE=Uninstallation Aborted
MUI_UNTEXT_ABORT_SUBTITLE=Uninstall was not completed successfully. MUI_UNTEXT_ABORT_SUBTITLE=Uninstall was not completed successfully.
MUI_UNTEXT_FINISH_INFO_TITLE=Completing the $(^NameDA) Uninstall Wizard MUI_UNTEXT_FINISH_INFO_TITLE=Completing the $BrandFullNameDA Uninstall Wizard
MUI_UNTEXT_FINISH_INFO_TEXT=$(^NameDA) has been uninstalled from your computer.\n\nClick Finish to close this wizard. MUI_UNTEXT_FINISH_INFO_TEXT=$BrandFullNameDA has been uninstalled from your computer.\n\nClick Finish to close this wizard.
MUI_UNTEXT_FINISH_INFO_REBOOT=Your computer must be restarted in order to complete the uninstallation of $(^NameDA). Do you want to reboot now? MUI_UNTEXT_FINISH_INFO_REBOOT=Your computer must be restarted in order to complete the uninstallation of $BrandFullNameDA. Do you want to reboot now?
MUI_UNTEXT_ABORTWARNING=Are you sure you want to quit $(^Name) Uninstall? MUI_UNTEXT_ABORTWARNING=Are you sure you want to quit $BrandFullName Uninstall?

Просмотреть файл

@ -41,11 +41,11 @@
# Accesskeys are defined by prefixing the letter that is to be used for the # Accesskeys are defined by prefixing the letter that is to be used for the
# accesskey with an ampersand (e.g. &). # accesskey with an ampersand (e.g. &).
# Do not replace $(^NameDA) or $(^Name) with a custom string. # Do not replace $BrandShortName, $BrandFullName, or $BrandFullNameDA with a
# custom string and always use the same one as used by the en-US files.
# Do not change $(^NameDA) to $(^Name) or $(^Name) to $(^NameDA). NameDA allows # $BrandFullNameDA allows the string to contain an ampersand (e.g. DA stands
# Name to contain an ampersand (e.g. DA stands for double ampersand) and # for double ampersand) and prevents the letter following the ampersand from
# prevents the letter following the ampersand being used as an accesskey. # being used as an accesskey.
# You can use \n to create a newline in the string but only when the string # You can use \n to create a newline in the string but only when the string
# from en-US contains a \n. # from en-US contains a \n.
@ -55,8 +55,8 @@
# and end of a strong enclose the add and additional double quote to the # and end of a strong enclose the add and additional double quote to the
# beginning and end of the string (e.g. ""This will include quotes""). # beginning and end of the string (e.g. ""This will include quotes"").
SetupCaption=$(^Name) Setup SetupCaption=$BrandFullName Setup
UninstallCaption=$(^Name) Uninstall UninstallCaption=$BrandFullName Uninstall
BackBtn=< &Back BackBtn=< &Back
NextBtn=&Next > NextBtn=&Next >
AcceptBtn=I &accept the terms in the License Agreement AcceptBtn=I &accept the terms in the License Agreement
@ -71,15 +71,15 @@ ClickNext=Click Next to continue.
ClickInstall=Click Install to start the installation. ClickInstall=Click Install to start the installation.
ClickUninstall=Click Uninstall to start the uninstallation. ClickUninstall=Click Uninstall to start the uninstallation.
Completed=Completed Completed=Completed
LicenseTextRB=Please review the license agreement before installing $(^NameDA). If you accept all terms of the agreement, select the first option below. $_CLICK LicenseTextRB=Please review the license agreement before installing $BrandFullNameDA. If you accept all terms of the agreement, select the first option below. $_CLICK
ComponentsText=Check the components you want to install and uncheck the components you don't want to install. $_CLICK ComponentsText=Check the components you want to install and uncheck the components you don't want to install. $_CLICK
ComponentsSubText2_NoInstTypes=Select components to install: ComponentsSubText2_NoInstTypes=Select components to install:
DirText=Setup will install $(^NameDA) in the following folder. To install in a different folder, click Browse and select another folder. $_CLICK DirText=Setup will install $BrandFullNameDA in the following folder. To install in a different folder, click Browse and select another folder. $_CLICK
DirSubText=Destination Folder DirSubText=Destination Folder
DirBrowseText=Select the folder to install $(^NameDA) in: DirBrowseText=Select the folder to install $BrandFullNameDA in:
SpaceAvailable="Space available: " SpaceAvailable="Space available: "
SpaceRequired="Space required: " SpaceRequired="Space required: "
UninstallingText=$(^NameDA) will be uninstalled from the following folder. $_CLICK UninstallingText=$BrandFullNameDA will be uninstalled from the following folder. $_CLICK
UninstallingSubText=Uninstalling from: UninstallingSubText=Uninstalling from:
FileError=Error opening file for writing: \r\n\r\n$0\r\n\r\nClick Abort to stop the installation,\r\nRetry to try again, or\r\nIgnore to skip this file. FileError=Error opening file for writing: \r\n\r\n$0\r\n\r\nClick Abort to stop the installation,\r\nRetry to try again, or\r\nIgnore to skip this file.
FileError_NoIgnore=Error opening file for writing: \r\n\r\n$0\r\n\r\nClick Retry to try again, or\r\nCancel to stop the installation. FileError_NoIgnore=Error opening file for writing: \r\n\r\n$0\r\n\r\nClick Retry to try again, or\r\nCancel to stop the installation.

Просмотреть файл

@ -37,6 +37,7 @@
#ifdef MOZ_SAFE_BROWSING #ifdef MOZ_SAFE_BROWSING
locale/browser/safebrowsing/phishing-afterload-warning-message.dtd (%chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd) locale/browser/safebrowsing/phishing-afterload-warning-message.dtd (%chrome/browser/safebrowsing/phishing-afterload-warning-message.dtd)
locale/browser/safebrowsing/report-phishing.dtd (%chrome/browser/safebrowsing/report-phishing.dtd) locale/browser/safebrowsing/report-phishing.dtd (%chrome/browser/safebrowsing/report-phishing.dtd)
locale/browser/safebrowsing/blockedSite.properties (%chrome/browser/safebrowsing/blockedSite.properties)
#endif #endif
locale/browser/feeds/subscribe.dtd (%chrome/browser/feeds/subscribe.dtd) locale/browser/feeds/subscribe.dtd (%chrome/browser/feeds/subscribe.dtd)
locale/browser/feeds/subscribe.properties (%chrome/browser/feeds/subscribe.properties) locale/browser/feeds/subscribe.properties (%chrome/browser/feeds/subscribe.properties)

Просмотреть файл

@ -831,7 +831,7 @@ toolbar[iconsize="small"] #paste-button:hover:active {
#urlbar { #urlbar {
margin-top: 5px; margin-top: 5px;
margin-bottom: 5px; margin-bottom: 5px;
-moz-margin-start: 4px; -moz-margin-start: 0px;
-moz-margin-end: 0px; -moz-margin-end: 0px;
width: 7em; width: 7em;
min-width: 7em; min-width: 7em;
@ -839,33 +839,6 @@ toolbar[iconsize="small"] #paste-button:hover:active {
font: icon !important; font: icon !important;
} }
.formatted-url {
-moz-box-align: center;
margin: 0 3px;
/*XXX Gecko 1.9 quirk*/
-moz-padding-start: 1px;
color: -moz-fieldtext;
}
#urlbar[level="high"] .formatted-url ,
#urlbar[level="low"] .formatted-url {
color: black;
}
.formatted-url * {
margin: 0;
padding: 0;
cursor: text;
}
.formatted-url-ellipsis {
-moz-margin-start: 1px;
}
.formatted-url-prePath {
-moz-box-pack: center;
}
#urlbar[level="high"] > .autocomplete-textbox-container, #urlbar[level="high"] > .autocomplete-textbox-container,
#urlbar[level="low"] > .autocomplete-textbox-container #urlbar[level="low"] > .autocomplete-textbox-container
{ {
@ -883,46 +856,6 @@ toolbar[iconsize="small"] #paste-button:hover:active {
background: url("chrome://browser/skin/Secure-background.gif") #FFFED8 repeat-x; background: url("chrome://browser/skin/Secure-background.gif") #FFFED8 repeat-x;
} }
#urlbar #lock-icon {
height: 18px;
margin: -1px;
}
#urlbar[level="high"] #lock-icon {
list-style-image: url("chrome://browser/skin/Secure.png");
-moz-image-region: rect(0px, 18px, 18px, 0px);
}
#urlbar[level="high"] #lock-icon:hover {
-moz-image-region: rect(18px, 18px, 36px, 0px);
}
#urlbar[level="high"] #lock-icon:active {
-moz-image-region: rect(36px, 18px, 54px, 0px);
}
#urlbar[level="low"] #lock-icon {
list-style-image: url("chrome://browser/skin/Secure.png");
-moz-image-region: rect(0px, 18px, 18px, 0px);
}
#urlbar[level="low"] #lock-icon:hover {
-moz-image-region: rect(18px, 18px, 36px, 0px);
}
#urlbar[level="low"] #lock-icon:active {
-moz-image-region: rect(36px, 18px, 54px, 0px);
}
#urlbar[level="broken"] #lock-icon {
list-style-image: url("chrome://browser/skin/Security-broken.png");
-moz-image-region: rect(0px, 18px, 18px, 0px);
}
#urlbar[level="broken"] #lock-icon:hover {
-moz-image-region: rect(18px, 18px, 36px, 0px);
}
#urlbar[level="broken"] #lock-icon:active {
-moz-image-region: rect(36px, 18px, 54px, 0px);
}
#urlbar-container { #urlbar-container {
-moz-padding-end: 5px; -moz-padding-end: 5px;
} }
@ -1707,3 +1640,116 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
-moz-border-left-colors: ThreeDLightShadow ThreeDHighlight !important; -moz-border-left-colors: ThreeDLightShadow ThreeDHighlight !important;
} }
/* ::::: Identity Indicator Styling ::::: */
/* Location bar visuals*/
#identity-box {
/* Extend our margins out so that our highlight/separator bar covers the
location bar properly */
margin: -1px 0 -2px;
padding: 1px 2px 2px 0;
border-right: 1px solid #888;
background-color: white;
opacity: 0.9;
}
#identity-box:hover {
opacity: 1.0;
}
#identity-box.verifiedIdentity {
background-color: #BFA;
}
#urlbar[level="high"] > #identity-box,
#urlbar[level="low"] > #identity-box {
/* urlbar adds padding when security level is set, which we need to
counteract here so that we still fill the background. */
margin: -2px;
padding: 1px 2px 2px;
}
#identity-icon-label {
padding: 2px 2px 0;
margin: 0;
color: black;
vertical-align: middle;
}
.unknownIdentity > #identity-icon-label {
display: none;
}
/* Popup Icons */
#identity-popup-icon {
height: 64px;
width: 64px;
padding: 0;
margin: 10px 0 0;
list-style-image: url("chrome://browser/skin/identity.png");
-moz-image-region: rect(0px, 64px, 64px, 0px);
}
.verifiedDomain > #identity-popup-container > #identity-popup-icon {
-moz-image-region: rect(64px, 64px, 128px, 0px);
}
.verifiedIdentity > #identity-popup-container > #identity-popup-icon {
-moz-image-region: rect(128px, 64px, 192px, 0px);
}
/* Popup Title */
#identity-popup-title {
font-size: 120%;
font-weight: bold;
}
.verifiedIdentity > #identity-popup-title {
color: #6A6;
}
.unknownIdentity > #identity-popup-title {
color: #999;
}
.verifiedDomain > #identity-popup-title {
color: black;
}
/* Popup Body Text */
#identity-popup-content-box > description,
#identity-popup-encryption-label {
white-space: -moz-pre-wrap;
color: black;
padding-left: 10px;
}
#identity-popup-content {
padding-top: 5px;
margin-bottom: 0;
max-width: 200px;
}
.verifiedIdentity > #identity-popup-content,
.verifiedDomain > #identity-popup-content {
font-size: 140%;
font-weight: bold;
max-width: 300px;
}
#identity-popup-encryption {
margin: 10px 0;
}
.verifiedIdentity > #identity-popup-encryption > * > #identity-popup-encryption-icon,
.verifiedDomain > #identity-popup-encryption > * >#identity-popup-encryption-icon {
list-style-image: url("chrome://browser/skin/Secure.png");
-moz-image-region: rect(0px, 18px, 18px, 0px);
}
/* Popup Bounding Box */
#identity-popup-container {
background-image: none;
background-color: white;
min-width: 280px;
padding: 10px;
}

Просмотреть файл

@ -10,6 +10,7 @@ classic.jar:
skin/classic/browser/find.png skin/classic/browser/find.png
skin/classic/browser/find-bar-background.png skin/classic/browser/find-bar-background.png
skin/classic/browser/Go.png skin/classic/browser/Go.png
skin/classic/browser/identity.png
skin/classic/browser/Info.png skin/classic/browser/Info.png
skin/classic/browser/page-livemarks.png skin/classic/browser/page-livemarks.png
skin/classic/browser/livemark-item.png skin/classic/browser/livemark-item.png

Просмотреть файл

@ -1,3 +1,26 @@
/* Sidebars */
.sidebar-placesTree {
-moz-appearance: none;
border: 0;
margin: 0;
border-top: 1px solid ThreeDShadow;
}
.sidebar-placesTreechildren::-moz-tree-cell(leaf) ,
.sidebar-placesTreechildren::-moz-tree-image(leaf) {
cursor: pointer;
}
.sidebar-placesTreechildren::-moz-tree-cell-text(leaf, hover) {
cursor: pointer;
text-decoration: underline;
}
.sidebar-placesTreechildren::-moz-tree-cell(separator) {
cursor: default;
}
/* Toolbar */ /* Toolbar */
#placesToolbar { #placesToolbar {
border-bottom: none; border-bottom: none;

Просмотреть файл

@ -856,7 +856,7 @@ toolbar[iconsize="small"] #paste-button:not([disabled="true"]):hover:active {
margin-bottom: 2px; margin-bottom: 2px;
margin-top: 2px; margin-top: 2px;
-moz-margin-end: 0px; -moz-margin-end: 0px;
-moz-margin-start: 3px; -moz-margin-start: 0px;
width: 7em; width: 7em;
min-width: 7em; min-width: 7em;
@ -868,33 +868,6 @@ toolbar[iconsize="small"] #paste-button:not([disabled="true"]):hover:active {
border-width: 1px; border-width: 1px;
} }
.formatted-url {
-moz-box-align: center;
margin: 0 3px;
/*XXX Gecko 1.9 quirk*/
-moz-padding-start: 1px;
color: -moz-fieldtext;
}
#urlbar[level="high"] .formatted-url ,
#urlbar[level="low"] .formatted-url {
color: black;
}
.formatted-url * {
margin: 0;
padding: 0;
cursor: text;
}
.formatted-url-ellipsis {
-moz-margin-start: 1px;
}
.formatted-url-prePath {
-moz-box-pack: center;
}
#urlbar-container { #urlbar-container {
-moz-box-orient: horizontal; -moz-box-orient: horizontal;
-moz-box-align: stretch; -moz-box-align: stretch;
@ -1746,43 +1719,6 @@ toolbar[mode="text"] > #window-controls > toolbarbutton > .toolbarbutton-text {
color: #000000; color: #000000;
} }
#urlbar[level="high"] #lock-icon {
-moz-image-region: rect(0px, 18px, 18px, 0px);
list-style-image: url("chrome://browser/skin/Secure.png");
}
#urlbar[level="high"] #lock-icon:hover {
-moz-image-region: rect(18px, 18px, 36px, 0px);
list-style-image: url("chrome://browser/skin/Secure.png");
}
#urlbar[level="high"] #lock-icon:active {
-moz-image-region: rect(36px, 18px, 54px, 0px);
list-style-image: url("chrome://browser/skin/Secure.png");
}
#urlbar[level="low"] #lock-icon {
-moz-image-region: rect(0px, 18px, 18px, 0px);
list-style-image: url("chrome://browser/skin/Secure.png");
}
#urlbar[level="low"] #lock-icon:hover {
-moz-image-region: rect(18px, 18px, 36px, 0px);
list-style-image: url("chrome://browser/skin/Secure.png");
}
#urlbar[level="low"] #lock-icon:active {
-moz-image-region: rect(36px, 18px, 54px, 0px);
list-style-image: url("chrome://browser/skin/Secure.png");
}
#urlbar[level="broken"] #lock-icon {
-moz-image-region: rect(0px, 18px, 18px, 0px);
list-style-image: url("chrome://browser/skin/Security-broken.png");
}
#urlbar[level="broken"] #lock-icon:hover {
-moz-image-region: rect(18px, 18px, 36px, 0px);
list-style-image: url("chrome://browser/skin/Security-broken.png");
}
#urlbar[level="broken"] #lock-icon:active {
-moz-image-region: rect(36px, 18px, 54px, 0px);
list-style-image: url("chrome://browser/skin/Security-broken.png");
}
%ifdef MOZ_WIDGET_GTK2 %ifdef MOZ_WIDGET_GTK2
#urlbar > .autocomplete-textbox-container { #urlbar > .autocomplete-textbox-container {
-moz-binding: url(chrome://browser/skin/browser.xml#autocomplete-security-wrapper); -moz-binding: url(chrome://browser/skin/browser.xml#autocomplete-security-wrapper);
@ -1895,3 +1831,117 @@ toolbarbutton.bookmark-item[dragover="true"][open="true"] {
.bookmark-item[dragover-bottom="true"] { .bookmark-item[dragover-bottom="true"] {
-moz-border-bottom-colors: #000000; -moz-border-bottom-colors: #000000;
} }
/* ::::: Identity Indicator Styling ::::: */
/* Location bar visuals*/
#identity-box {
cursor: help;
background-color: ThreeDFace;
%ifdef MOZ_WIDGET_GTK2
-moz-border-end: 1px solid ThreeDShadow;
%else
-moz-appearance: toolbox;
outline: 1px solid ThreeDShadow;
%endif
}
#identity-box.verifiedIdentity {
%ifdef MOZ_WIDGET_GTK2
border-color: highlight;
%else
outline-color: highlight;
%endif
}
#identity-box:hover {
%ifdef MOZ_WIDGET_GTK2
border-color: ThreeDDarkShadow;
%else
outline-color: ThreeDDarkShadow;
%endif
}
#identity-icon-label {
padding: 0 2px;
margin: 0;
cursor: inherit;
}
.unknownIdentity > #identity-icon-label {
display: none;
}
/* Popup Icons */
#identity-popup-icon {
height: 64px;
width: 64px;
padding: 0;
margin: 10px 0 0;
list-style-image: url("chrome://browser/skin/identity.png");
-moz-image-region: rect(0px, 64px, 64px, 0px);
}
.verifiedDomain > #identity-popup-container > #identity-popup-icon {
-moz-image-region: rect(64px, 64px, 128px, 0px);
}
.verifiedIdentity > #identity-popup-container > #identity-popup-icon {
-moz-image-region: rect(128px, 64px, 192px, 0px);
}
/* Popup Title */
#identity-popup-title {
font-size: 120%;
font-weight: bold;
}
.verifiedIdentity > #identity-popup-title {
color: #6A6;
}
.unknownIdentity > #identity-popup-title {
color: #999;
}
.verifiedDomain > #identity-popup-title {
color: black;
}
/* Popup Body Text */
#identity-popup-content-box > description,
#identity-popup-encryption-label {
white-space: -moz-pre-wrap;
color: black;
padding-left: 10px;
}
#identity-popup-content {
padding-top: 5px;
margin-bottom: 0;
max-width: 200px;
}
.verifiedIdentity > #identity-popup-content,
.verifiedDomain > #identity-popup-content {
font-size: 140%;
font-weight: bold;
max-width: 300px;
}
#identity-popup-encryption {
margin: 10px 0;
}
.verifiedIdentity > #identity-popup-encryption > * > #identity-popup-encryption-icon,
.verifiedDomain > #identity-popup-encryption > * >#identity-popup-encryption-icon {
list-style-image: url("chrome://browser/skin/Secure.png");
-moz-image-region: rect(0px, 18px, 18px, 0px);
}
/* Popup Bounding Box */
#identity-popup-container {
background-image: none;
background-color: white;
min-width: 280px;
padding: 10px;
}

Просмотреть файл

@ -6,6 +6,7 @@ classic.jar:
skin/classic/browser/endcap-bkgnd-hover.png skin/classic/browser/endcap-bkgnd-hover.png
* skin/classic/browser/engineManager.css (engineManager.css) * skin/classic/browser/engineManager.css (engineManager.css)
skin/classic/browser/Info.png skin/classic/browser/Info.png
skin/classic/browser/identity.png
skin/classic/browser/pageInfo.css skin/classic/browser/pageInfo.css
skin/classic/browser/pageInfo.png skin/classic/browser/pageInfo.png
skin/classic/browser/page-livemarks.png skin/classic/browser/page-livemarks.png

Просмотреть файл

@ -1,15 +1,26 @@
/* Sidebars */ /* Sidebars */
page > .placesTree > treechildren::-moz-tree-cell(leaf) , .sidebar-placesTree {
page > .placesTree > treechildren::-moz-tree-image(leaf) { -moz-appearance: none;
border: 0;
margin: 0;
border-top: 1px solid ThreeDShadow;
}
.sidebar-placesTreechildren::-moz-tree-cell(leaf) ,
.sidebar-placesTreechildren::-moz-tree-image(leaf) {
cursor: pointer; cursor: pointer;
} }
page > .placesTree > treechildren::-moz-tree-cell-text(leaf, hover) { .sidebar-placesTreechildren::-moz-tree-cell-text(leaf, hover) {
cursor: pointer; cursor: pointer;
text-decoration: underline; text-decoration: underline;
} }
.sidebar-placesTreechildren::-moz-tree-cell(separator) {
cursor: default;
}
/* Toolbar */ /* Toolbar */
#placesToolbar { #placesToolbar {
border: none; border: none;

Просмотреть файл

@ -284,9 +284,12 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
/** /**
* Returns OK if aSourceURI and target have the same "origin" * Returns OK if aSourceURI and target have the same "origin"
* (scheme, host, and port). * (scheme, host, and port).
* ReportError flag suppresses error reports for functions that
* don't need reporting.
*/ */
void checkSameOriginURI(in nsIURI aSourceURI, void checkSameOriginURI(in nsIURI aSourceURI,
in nsIURI aTargetURI); in nsIURI aTargetURI,
in boolean reportError);
/** /**
* Returns OK if aSourcePrincipal and aTargetPrincipal * Returns OK if aSourcePrincipal and aTargetPrincipal

Просмотреть файл

@ -446,13 +446,8 @@ nsScriptSecurityManager::GetChannelPrincipal(nsIChannel* aChannel,
// OK, get the principal from the URI. Make sure this does the same thing // OK, get the principal from the URI. Make sure this does the same thing
// as nsDocument::Reset and nsXULDocument::StartDocumentLoad. // as nsDocument::Reset and nsXULDocument::StartDocumentLoad.
nsCOMPtr<nsIURI> uri; nsCOMPtr<nsIURI> uri;
nsLoadFlags loadFlags = 0; nsresult rv = NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
nsresult rv = aChannel->GetLoadFlags(&loadFlags); NS_ENSURE_SUCCESS(rv, rv);
if (NS_SUCCEEDED(rv) && (loadFlags & nsIChannel::LOAD_REPLACE)) {
aChannel->GetURI(getter_AddRefs(uri));
} else {
aChannel->GetOriginalURI(getter_AddRefs(uri));
}
return GetCodebasePrincipal(uri, aPrincipal); return GetCodebasePrincipal(uri, aPrincipal);
} }
@ -681,12 +676,15 @@ nsScriptSecurityManager::CheckSameOrigin(JSContext* cx,
NS_IMETHODIMP NS_IMETHODIMP
nsScriptSecurityManager::CheckSameOriginURI(nsIURI* aSourceURI, nsScriptSecurityManager::CheckSameOriginURI(nsIURI* aSourceURI,
nsIURI* aTargetURI) nsIURI* aTargetURI,
PRBool reportError)
{ {
if (!SecurityCompareURIs(aSourceURI, aTargetURI)) if (!SecurityCompareURIs(aSourceURI, aTargetURI))
{ {
ReportError(nsnull, NS_LITERAL_STRING("CheckSameOriginError"), if (reportError) {
ReportError(nsnull, NS_LITERAL_STRING("CheckSameOriginError"),
aSourceURI, aTargetURI); aSourceURI, aTargetURI);
}
return NS_ERROR_DOM_BAD_URI; return NS_ERROR_DOM_BAD_URI;
} }
return NS_OK; return NS_OK;

Просмотреть файл

@ -1,6 +1,6 @@
#!/usr/bin/python #!/usr/bin/python
NSPR_CO_TAG = 'NSPR_HEAD_20071009' NSPR_CO_TAG = 'NSPR_HEAD_20071016'
NSS_CO_TAG = 'NSS_3_12_ALPHA_2' NSS_CO_TAG = 'NSS_3_12_ALPHA_2'
NSPR_DIRS = ('nsprpub',) NSPR_DIRS = ('nsprpub',)

Просмотреть файл

@ -1048,6 +1048,15 @@ ifdef NO_LD_ARCHIVE_FLAGS
SUB_SHLOBJS = $(SUB_LOBJS) SUB_SHLOBJS = $(SUB_LOBJS)
endif endif
ifdef HAVE_DTRACE
ifdef DTRACE_PROBE_OBJ
ifndef DTRACE_LIB_DEPENDENT
$(DTRACE_PROBE_OBJ): $(OBJS)
dtrace -G -C -32 -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ) $(OBJS)
endif
endif
endif
# On Darwin (Mac OS X), dwarf2 debugging uses debug info left in .o files, # On Darwin (Mac OS X), dwarf2 debugging uses debug info left in .o files,
# so instead of deleting .o files after repacking them into a dylib, we make # so instead of deleting .o files after repacking them into a dylib, we make
# symlinks back to the originals. The symlinks are a no-op for stabs debugging, # symlinks back to the originals. The symlinks are a no-op for stabs debugging,
@ -1078,17 +1087,17 @@ ifdef SHARED_LIBRARY_LIBS
@for lib in $(SHARED_LIBRARY_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done @for lib in $(SHARED_LIBRARY_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done
endif # SHARED_LIBRARY_LIBS endif # SHARED_LIBRARY_LIBS
endif # NO_LD_ARCHIVE_FLAGS endif # NO_LD_ARCHIVE_FLAGS
ifdef NEED_DTRACE_PROBE_OBJ ifdef DTRACE_LIB_DEPENDENT
@rm -f $(PROBE_LOBJS) @rm -f $(PROBE_LOBJS)
@for lib in $(MOZILLA_PROBE_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done @for lib in $(MOZILLA_PROBE_LIBS); do $(AR_EXTRACT) $${lib}; $(CLEANUP2); done
dtrace -G -C -32 -s $(MOZILLA_DTRACE_SRC) -o $(NEED_DTRACE_PROBE_OBJ) $(PROBE_LOBJS) dtrace -G -C -32 -s $(MOZILLA_DTRACE_SRC) -o $(DTRACE_PROBE_OBJ) $(PROBE_LOBJS)
@for lib in $(MOZILLA_PROBE_LIBS); do \ @for lib in $(MOZILLA_PROBE_LIBS); do \
ofiles=`$(AR_LIST) $${lib}`; \ ofiles=`$(AR_LIST) $${lib}`; \
$(AR_DELETE) $${lib} $$ofiles; \ $(AR_DELETE) $${lib} $$ofiles; \
done done
$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(NEED_DTRACE_PROBE_OBJ) $(PROBE_LOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE) $(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(LOBJS) $(SUB_SHLOBJS) $(DTRACE_PROBE_OBJ) $(PROBE_LOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
@rm -f $(PROBE_LOBJS) @rm -f $(PROBE_LOBJS)
@rm -f $(NEED_DTRACE_PROBE_OBJ) @rm -f $(DTRACE_PROBE_OBJ)
@for lib in $(MOZILLA_PROBE_LIBS); do \ @for lib in $(MOZILLA_PROBE_LIBS); do \
if [ -L $${lib} ]; then rm -f `readlink $${lib}`; fi; \ if [ -L $${lib} ]; then rm -f `readlink $${lib}`; fi; \
done done
@ -1096,7 +1105,7 @@ ifdef NEED_DTRACE_PROBE_OBJ
else else
$(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(DTRACE_PROBE_OBJ) $(LOBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE) $(MKSHLIB) $(SHLIB_LDSTARTFILE) $(OBJS) $(DTRACE_PROBE_OBJ) $(LOBJS) $(SUB_SHLOBJS) $(RESFILE) $(LDFLAGS) $(EXTRA_DSO_LDOPTS) $(OS_LIBS) $(EXTRA_LIBS) $(DEF_FILE) $(SHLIB_LDENDFILE)
endif # NEED_DTRACE_PROBE_OBJ endif # DTRACE_LIB_DEPENDENT
ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH)) ifeq (_WINNT,$(GNU_CC)_$(OS_ARCH))
ifdef MSMANIFEST_TOOL ifdef MSMANIFEST_TOOL

Просмотреть файл

@ -557,6 +557,8 @@ public:
PRInt16* aImageBlockingStatus = nsnull); PRInt16* aImageBlockingStatus = nsnull);
/** /**
* Method to start an image load. This does not do any security checks. * Method to start an image load. This does not do any security checks.
* This method will attempt to make aURI immutable; a caller that wants to
* keep a mutable version around should pass in a clone.
* *
* @param aURI uri of the image to be loaded * @param aURI uri of the image to be loaded
* @param aLoadingDocument the document we belong to * @param aLoadingDocument the document we belong to
@ -750,42 +752,6 @@ public:
*/ */
static nsIContentPolicy *GetContentPolicy(); static nsIContentPolicy *GetContentPolicy();
/**
* Make sure that whatever value *aPtr contains at any given moment is
* protected from JS GC until we remove the GC root. A call to this that
* succeeds MUST be matched by a call to RemoveJSGCRoot to avoid leaking.
*/
static nsresult AddJSGCRoot(jsval* aPtr, const char* aName) {
return AddJSGCRoot((void*)aPtr, aName);
}
/**
* Make sure that whatever object *aPtr is pointing to at any given moment is
* protected from JS GC until we remove the GC root. A call to this that
* succeeds MUST be matched by a call to RemoveJSGCRoot to avoid leaking.
*/
static nsresult AddJSGCRoot(JSObject** aPtr, const char* aName) {
return AddJSGCRoot((void*)aPtr, aName);
}
/**
* Make sure that whatever object *aPtr is pointing to at any given moment is
* protected from JS GC until we remove the GC root. A call to this that
* succeeds MUST be matched by a call to RemoveJSGCRoot to avoid leaking.
*/
static nsresult AddJSGCRoot(void* aPtr, const char* aName);
/**
* Remove aPtr as a JS GC root
*/
static nsresult RemoveJSGCRoot(jsval* aPtr) {
return RemoveJSGCRoot((void*)aPtr);
}
static nsresult RemoveJSGCRoot(JSObject** aPtr) {
return RemoveJSGCRoot((void*)aPtr);
}
static nsresult RemoveJSGCRoot(void* aPtr);
/** /**
* Quick helper to determine whether there are any mutation listeners * Quick helper to determine whether there are any mutation listeners
* of a given type that apply to this content or any of its ancestors. * of a given type that apply to this content or any of its ancestors.
@ -950,7 +916,7 @@ public:
PRBool aTryReuse); PRBool aTryReuse);
/** /**
* Get the textual contents of a node. This is a concatination of all * Get the textual contents of a node. This is a concatenation of all
* textnodes that are direct or (depending on aDeep) indirect children * textnodes that are direct or (depending on aDeep) indirect children
* of the node. * of the node.
* *
@ -1000,40 +966,73 @@ public:
*/ */
static void DestroyAnonymousContent(nsCOMPtr<nsIContent>* aContent); static void DestroyAnonymousContent(nsCOMPtr<nsIContent>* aContent);
static nsresult HoldScriptObject(PRUint32 aLangID, void *aObject); /**
static nsresult DropScriptObject(PRUint32 aLangID, void *aObject); * Keep script object aNewObject, held by aScriptObjectHolder, alive.
*
class ScriptObjectHolder * NOTE: This currently only supports objects that hold script objects of one
* scripting language.
*
* @param aLangID script language ID of aNewObject
* @param aScriptObjectHolder the object that holds aNewObject
* @param aTracer the tracer for aScriptObject
* @param aNewObject the script object to hold
* @param aWasHoldingObjects whether aScriptObjectHolder was already holding
* script objects (ie. HoldScriptObject was called
* on it before, without a corresponding call to
* DropScriptObjects)
*/
static nsresult HoldScriptObject(PRUint32 aLangID, void* aScriptObjectHolder,
nsScriptObjectTracer* aTracer,
void* aNewObject, PRBool aWasHoldingObjects)
{ {
public: if (aLangID == nsIProgrammingLanguage::JAVASCRIPT) {
ScriptObjectHolder(PRUint32 aLangID) : mLangID(aLangID), return aWasHoldingObjects ? NS_OK :
mObject(nsnull) HoldJSObjects(aScriptObjectHolder, aTracer);
{
MOZ_COUNT_CTOR(ScriptObjectHolder);
} }
~ScriptObjectHolder()
{ return HoldScriptObject(aLangID, aNewObject);
MOZ_COUNT_DTOR(ScriptObjectHolder); }
if (mObject)
DropScriptObject(mLangID, mObject); /**
* Drop any script objects that aScriptObjectHolder is holding.
*
* NOTE: This currently only supports objects that hold script objects of one
* scripting language.
*
* @param aLangID script language ID of the objects that
* @param aScriptObjectHolder the object that holds script object that we want
* to drop
* @param aTracer the tracer for aScriptObject
*/
static nsresult DropScriptObjects(PRUint32 aLangID, void* aScriptObjectHolder,
nsScriptObjectTracer* aTracer)
{
if (aLangID == nsIProgrammingLanguage::JAVASCRIPT) {
return DropJSObjects(aScriptObjectHolder);
} }
nsresult set(void *aObject)
{ aTracer->Trace(aScriptObjectHolder, DropScriptObject, nsnull);
NS_ASSERTION(aObject, "unexpected null object");
NS_ASSERTION(!mObject, "already have an object"); return NS_OK;
nsresult rv = HoldScriptObject(mLangID, aObject); }
if (NS_SUCCEEDED(rv)) {
mObject = aObject; /**
} * Keep the JS objects held by aScriptObjectHolder alive.
return rv; *
} * @param aScriptObjectHolder the object that holds JS objects that we want to
void traverse(nsCycleCollectionTraversalCallback &cb) * keep alive
{ * @param aTracer the tracer for aScriptObject
cb.NoteScriptChild(mLangID, mObject); */
} static nsresult HoldJSObjects(void* aScriptObjectHolder,
PRUint32 mLangID; nsScriptObjectTracer* aTracer);
void *mObject;
}; /**
* Drop the JS objects held by aScriptObjectHolder.
*
* @param aScriptObjectHolder the object that holds JS objects that we want to
* drop
*/
static nsresult DropJSObjects(void* aScriptObjectHolder);
/** /**
* Convert nsIContent::IME_STATUS_* to nsIKBStateControll::IME_STATUS_* * Convert nsIContent::IME_STATUS_* to nsIKBStateControll::IME_STATUS_*
@ -1120,6 +1119,10 @@ private:
static nsIDOMScriptObjectFactory *GetDOMScriptObjectFactory(); static nsIDOMScriptObjectFactory *GetDOMScriptObjectFactory();
static nsresult HoldScriptObject(PRUint32 aLangID, void* aObject);
PR_STATIC_CALLBACK(void) DropScriptObject(PRUint32 aLangID, void *aObject,
void *aClosure);
static nsIDOMScriptObjectFactory *sDOMScriptObjectFactory; static nsIDOMScriptObjectFactory *sDOMScriptObjectFactory;
static nsIXPConnect *sXPConnect; static nsIXPConnect *sXPConnect;
@ -1161,14 +1164,9 @@ private:
// Holds pointers to nsISupports* that should be released at shutdown // Holds pointers to nsISupports* that should be released at shutdown
static nsVoidArray* sPtrsToPtrsToRelease; static nsVoidArray* sPtrsToPtrsToRelease;
// For now, we don't want to automatically clean this up in Shutdown(), since
// consumers might unfortunately end up wanting to use it after that
static nsIJSRuntimeService* sJSRuntimeService;
static JSRuntime* sJSScriptRuntime;
static PRInt32 sJSScriptRootCount;
static nsIScriptRuntime* sScriptRuntimes[NS_STID_ARRAY_UBOUND]; static nsIScriptRuntime* sScriptRuntimes[NS_STID_ARRAY_UBOUND];
static PRInt32 sScriptRootCount[NS_STID_ARRAY_UBOUND]; static PRInt32 sScriptRootCount[NS_STID_ARRAY_UBOUND];
static PRUint32 sJSGCThingRootCount;
#ifdef IBMBIDI #ifdef IBMBIDI
static nsIBidiKeyboard* sBidiKeyboard; static nsIBidiKeyboard* sBidiKeyboard;
@ -1178,6 +1176,14 @@ private:
}; };
#define NS_HOLD_JS_OBJECTS(obj, clazz) \
nsContentUtils::HoldJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz), \
&NS_CYCLE_COLLECTION_NAME(clazz))
#define NS_DROP_JS_OBJECTS(obj, clazz) \
nsContentUtils::DropJSObjects(NS_CYCLE_COLLECTION_UPCAST(obj, clazz))
class nsCxPusher class nsCxPusher
{ {
public: public:
@ -1200,33 +1206,38 @@ public:
nsAutoGCRoot(jsval* aPtr, nsresult* aResult) : nsAutoGCRoot(jsval* aPtr, nsresult* aResult) :
mPtr(aPtr) mPtr(aPtr)
{ {
mResult = *aResult = mResult = *aResult = AddJSGCRoot(aPtr, "nsAutoGCRoot");
nsContentUtils::AddJSGCRoot(aPtr, "nsAutoGCRoot");
} }
// aPtr should be the pointer to the JSObject* we want to protect // aPtr should be the pointer to the JSObject* we want to protect
nsAutoGCRoot(JSObject** aPtr, nsresult* aResult) : nsAutoGCRoot(JSObject** aPtr, nsresult* aResult) :
mPtr(aPtr) mPtr(aPtr)
{ {
mResult = *aResult = mResult = *aResult = AddJSGCRoot(aPtr, "nsAutoGCRoot");
nsContentUtils::AddJSGCRoot(aPtr, "nsAutoGCRoot");
} }
// aPtr should be the pointer to the thing we want to protect // aPtr should be the pointer to the thing we want to protect
nsAutoGCRoot(void* aPtr, nsresult* aResult) : nsAutoGCRoot(void* aPtr, nsresult* aResult) :
mPtr(aPtr) mPtr(aPtr)
{ {
mResult = *aResult = mResult = *aResult = AddJSGCRoot(aPtr, "nsAutoGCRoot");
nsContentUtils::AddJSGCRoot(aPtr, "nsAutoGCRoot");
} }
~nsAutoGCRoot() { ~nsAutoGCRoot() {
if (NS_SUCCEEDED(mResult)) { if (NS_SUCCEEDED(mResult)) {
nsContentUtils::RemoveJSGCRoot(mPtr); RemoveJSGCRoot(mPtr);
} }
} }
static void Shutdown();
private: private:
static nsresult AddJSGCRoot(void *aPtr, const char* aName);
static nsresult RemoveJSGCRoot(void *aPtr);
static nsIJSRuntimeService* sJSRuntimeService;
static JSRuntime* sJSScriptRuntime;
void* mPtr; void* mPtr;
nsresult mResult; nsresult mResult;
}; };

Просмотреть файл

@ -100,8 +100,11 @@ enum {
NODE_IS_INSERTION_PARENT = 0x00001000U, NODE_IS_INSERTION_PARENT = 0x00001000U,
// Keep track of whether this node is in the middle of binding teardown
NODE_IS_IN_BINDING_TEARDOWN = 0x00002000U,
// Four bits for the script-type ID // Four bits for the script-type ID
NODE_SCRIPT_TYPE_OFFSET = 13, NODE_SCRIPT_TYPE_OFFSET = 14,
NODE_SCRIPT_TYPE_SIZE = 4, NODE_SCRIPT_TYPE_SIZE = 4,

Просмотреть файл

@ -73,9 +73,9 @@ public:
* into AppendText calls. * into AppendText calls.
* *
* The current strategy is that we break the overall text into * The current strategy is that we break the overall text into
* whitespace-delimited "words". Then for words that contain a "complex" * whitespace-delimited "words". Then those words are passed to the nsILineBreaker
* character (currently CJK or Thai), we break within the word using complex * service for deeper analysis if they contain a "complex" character as described
* rules (JISx4051 or Pango). * below.
*/ */
class nsLineBreaker { class nsLineBreaker {
public: public:
@ -102,9 +102,9 @@ public:
(0xff00 <= u && u <= 0xffef); // Halfwidth and Fullwidth Forms (0xff00 <= u && u <= 0xffef); // Halfwidth and Fullwidth Forms
} }
// Normally, break opportunities exist at the end of each run of whitespace // Break opportunities exist at the end of each run of breakable whitespace
// (see IsSpace above). Break opportunities can also exist inside runs of // (see IsSpace above). Break opportunities can also exist between pairs of
// non-whitespace, as determined by nsILineBreaker. We pass a whitespace- // non-whitespace characters, as determined by nsILineBreaker. We pass a whitespace-
// delimited word to nsILineBreaker if it contains at least one character // delimited word to nsILineBreaker if it contains at least one character
// matching IsComplexChar. // matching IsComplexChar.
// We provide flags to control on a per-chunk basis where breaks are allowed. // We provide flags to control on a per-chunk basis where breaks are allowed.
@ -114,22 +114,38 @@ public:
// We operate on text after whitespace processing has been applied, so // We operate on text after whitespace processing has been applied, so
// other characters (e.g. tabs and newlines) may have been converted to // other characters (e.g. tabs and newlines) may have been converted to
// spaces. // spaces.
/**
* Flags passed with each chunk of text.
*/
enum { enum {
/** /*
* Allow a break opportunity at the start of this chunk of text. * Do not introduce a break opportunity at the start of this chunk of text.
*/ */
BREAK_ALLOW_INITIAL = 0x01, BREAK_SUPPRESS_INITIAL = 0x01,
/** /**
* Allow a break opportunity in the interior of this chunk of text. * Do not introduce a break opportunity in the interior of this chunk of text.
* Also, whitespace in this chunk is treated as non-breakable.
*/ */
BREAK_ALLOW_INSIDE = 0x02 BREAK_SUPPRESS_INSIDE = 0x02,
/**
* The sink currently is already set up to have no breaks in it;
* if no breaks are possible, nsLineBreaker does not need to call
* SetBreaks on it. This is useful when handling large quantities of
* preformatted text; the textruns will never have any breaks set on them,
* and there is no need to ever actually scan the text for breaks, except
* at the end of textruns in case context is needed for following breakable
* text.
*/
BREAK_SKIP_SETTING_NO_BREAKS = 0x04
}; };
/** /**
* Append "invisible whitespace". This acts like whitespace, but there is * Append "invisible whitespace". This acts like whitespace, but there is
* no actual text associated with it. * no actual text associated with it. Only the BREAK_SUPPRESS_INSIDE flag
* is relevant here.
*/ */
nsresult AppendInvisibleWhitespace(); nsresult AppendInvisibleWhitespace(PRUint32 aFlags);
/** /**
* Feed Unicode text into the linebreaker for analysis. aLength must be * Feed Unicode text into the linebreaker for analysis. aLength must be
@ -184,8 +200,11 @@ private:
nsAutoTArray<TextItem,2> mTextItems; nsAutoTArray<TextItem,2> mTextItems;
PRPackedBool mCurrentWordContainsComplexChar; PRPackedBool mCurrentWordContainsComplexChar;
// True if the previous character was whitespace // True if the previous character was breakable whitespace
PRPackedBool mAfterSpace; PRPackedBool mAfterBreakableSpace;
// True if a break must be allowed at the current position because
// a run of breakable whitespace ends here
PRPackedBool mBreakHere;
}; };
#endif /*NSLINEBREAKER_H_*/ #endif /*NSLINEBREAKER_H_*/

Просмотреть файл

@ -180,15 +180,15 @@ nsILineBreaker *nsContentUtils::sLineBreaker;
nsIWordBreaker *nsContentUtils::sWordBreaker; nsIWordBreaker *nsContentUtils::sWordBreaker;
nsICaseConversion *nsContentUtils::sCaseConv; nsICaseConversion *nsContentUtils::sCaseConv;
nsVoidArray *nsContentUtils::sPtrsToPtrsToRelease; nsVoidArray *nsContentUtils::sPtrsToPtrsToRelease;
nsIJSRuntimeService *nsContentUtils::sJSRuntimeService;
JSRuntime *nsContentUtils::sJSScriptRuntime;
PRInt32 nsContentUtils::sJSScriptRootCount = 0;
nsIScriptRuntime *nsContentUtils::sScriptRuntimes[NS_STID_ARRAY_UBOUND]; nsIScriptRuntime *nsContentUtils::sScriptRuntimes[NS_STID_ARRAY_UBOUND];
PRInt32 nsContentUtils::sScriptRootCount[NS_STID_ARRAY_UBOUND]; PRInt32 nsContentUtils::sScriptRootCount[NS_STID_ARRAY_UBOUND];
PRUint32 nsContentUtils::sJSGCThingRootCount;
#ifdef IBMBIDI #ifdef IBMBIDI
nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nsnull; nsIBidiKeyboard *nsContentUtils::sBidiKeyboard = nsnull;
#endif #endif
nsIJSRuntimeService *nsAutoGCRoot::sJSRuntimeService;
JSRuntime *nsAutoGCRoot::sJSScriptRuntime;
PRBool nsContentUtils::sInitialized = PR_FALSE; PRBool nsContentUtils::sInitialized = PR_FALSE;
@ -671,7 +671,8 @@ nsContentUtils::Shutdown()
NS_IF_RELEASE(sStringBundleService); NS_IF_RELEASE(sStringBundleService);
NS_IF_RELEASE(sConsoleService); NS_IF_RELEASE(sConsoleService);
NS_IF_RELEASE(sDOMScriptObjectFactory); NS_IF_RELEASE(sDOMScriptObjectFactory);
NS_IF_RELEASE(sXPConnect); if (sJSGCThingRootCount == 0 && sXPConnect)
NS_RELEASE(sXPConnect);
NS_IF_RELEASE(sSecurityManager); NS_IF_RELEASE(sSecurityManager);
NS_IF_RELEASE(sThreadJSContextStack); NS_IF_RELEASE(sThreadJSContextStack);
NS_IF_RELEASE(sNameSpaceManager); NS_IF_RELEASE(sNameSpaceManager);
@ -721,6 +722,8 @@ nsContentUtils::Shutdown()
sEventListenerManagersHash.ops = nsnull; sEventListenerManagersHash.ops = nsnull;
} }
} }
nsAutoGCRoot::Shutdown();
} }
static PRBool IsCallerTrustedForCapability(const char* aCapability) static PRBool IsCallerTrustedForCapability(const char* aCapability)
@ -2157,6 +2160,9 @@ nsContentUtils::LoadImage(nsIURI* aURI, nsIDocument* aLoadingDocument,
nsIURI *documentURI = aLoadingDocument->GetDocumentURI(); nsIURI *documentURI = aLoadingDocument->GetDocumentURI();
// Make the URI immutable so people won't change it under us
NS_TryToSetImmutable(aURI);
// We don't use aLoadingPrincipal for anything here yet... but we // We don't use aLoadingPrincipal for anything here yet... but we
// will. See bug 377092. // will. See bug 377092.
@ -2669,7 +2675,7 @@ nsContentUtils::GetContentPolicy()
// static // static
nsresult nsresult
nsContentUtils::AddJSGCRoot(void* aPtr, const char* aName) nsAutoGCRoot::AddJSGCRoot(void* aPtr, const char* aName)
{ {
if (!sJSScriptRuntime) { if (!sJSScriptRuntime) {
nsresult rv = CallGetService("@mozilla.org/js/xpc/RuntimeService;1", nsresult rv = CallGetService("@mozilla.org/js/xpc/RuntimeService;1",
@ -2687,25 +2693,16 @@ nsContentUtils::AddJSGCRoot(void* aPtr, const char* aName)
PRBool ok; PRBool ok;
ok = ::JS_AddNamedRootRT(sJSScriptRuntime, aPtr, aName); ok = ::JS_AddNamedRootRT(sJSScriptRuntime, aPtr, aName);
if (!ok) { if (!ok) {
if (sJSScriptRootCount == 0) {
// We just got the runtime... Just null things out, since no
// one's expecting us to have a runtime yet
NS_RELEASE(sJSRuntimeService);
sJSScriptRuntime = nsnull;
}
NS_WARNING("JS_AddNamedRootRT failed"); NS_WARNING("JS_AddNamedRootRT failed");
return NS_ERROR_OUT_OF_MEMORY; return NS_ERROR_OUT_OF_MEMORY;
} }
// We now have one more root we added to the runtime
++sJSScriptRootCount;
return NS_OK; return NS_OK;
} }
/* static */ /* static */
nsresult nsresult
nsContentUtils::RemoveJSGCRoot(void* aPtr) nsAutoGCRoot::RemoveJSGCRoot(void* aPtr)
{ {
if (!sJSScriptRuntime) { if (!sJSScriptRuntime) {
NS_NOTREACHED("Trying to remove a JS GC root when none were added"); NS_NOTREACHED("Trying to remove a JS GC root when none were added");
@ -2714,11 +2711,6 @@ nsContentUtils::RemoveJSGCRoot(void* aPtr)
::JS_RemoveRootRT(sJSScriptRuntime, aPtr); ::JS_RemoveRootRT(sJSScriptRuntime, aPtr);
if (--sJSScriptRootCount == 0) {
NS_RELEASE(sJSRuntimeService);
sJSScriptRuntime = nsnull;
}
return NS_OK; return NS_OK;
} }
@ -3522,6 +3514,8 @@ nsresult
nsContentUtils::HoldScriptObject(PRUint32 aLangID, void *aObject) nsContentUtils::HoldScriptObject(PRUint32 aLangID, void *aObject)
{ {
NS_ASSERTION(aObject, "unexpected null object"); NS_ASSERTION(aObject, "unexpected null object");
NS_ASSERTION(aLangID != nsIProgrammingLanguage::JAVASCRIPT,
"Should use HoldJSObjects.");
nsresult rv; nsresult rv;
PRUint32 langIndex = NS_STID_INDEX(aLangID); PRUint32 langIndex = NS_STID_INDEX(aLangID);
@ -3548,17 +3542,47 @@ nsContentUtils::HoldScriptObject(PRUint32 aLangID, void *aObject)
} }
/* static */ /* static */
nsresult void
nsContentUtils::DropScriptObject(PRUint32 aLangID, void *aObject) nsContentUtils::DropScriptObject(PRUint32 aLangID, void *aObject,
void *aClosure)
{ {
NS_ASSERTION(aObject, "unexpected null object"); NS_ASSERTION(aObject, "unexpected null object");
NS_ASSERTION(aLangID != nsIProgrammingLanguage::JAVASCRIPT,
"Should use DropJSObjects.");
PRUint32 langIndex = NS_STID_INDEX(aLangID); PRUint32 langIndex = NS_STID_INDEX(aLangID);
NS_LOG_RELEASE(sScriptRuntimes[langIndex], sScriptRootCount[langIndex] - 1, NS_LOG_RELEASE(sScriptRuntimes[langIndex], sScriptRootCount[langIndex] - 1,
"HoldScriptObject"); "HoldScriptObject");
nsresult rv = sScriptRuntimes[langIndex]->DropScriptObject(aObject); sScriptRuntimes[langIndex]->DropScriptObject(aObject);
if (--sScriptRootCount[langIndex] == 0) { if (--sScriptRootCount[langIndex] == 0) {
NS_RELEASE(sScriptRuntimes[langIndex]); NS_RELEASE(sScriptRuntimes[langIndex]);
} }
}
/* static */
nsresult
nsContentUtils::HoldJSObjects(void* aScriptObjectHolder,
nsScriptObjectTracer* aTracer)
{
PRBool newHolder;
nsresult rv = sXPConnect->AddJSHolder(aScriptObjectHolder, aTracer);
NS_ENSURE_SUCCESS(rv, rv);
++sJSGCThingRootCount;
NS_LOG_ADDREF(sXPConnect, sJSGCThingRootCount, "HoldJSObjects",
sizeof(void*));
return NS_OK;
}
/* static */
nsresult
nsContentUtils::DropJSObjects(void* aScriptObjectHolder)
{
NS_LOG_RELEASE(sXPConnect, sJSGCThingRootCount - 1, "HoldJSObjects");
nsresult rv = sXPConnect->RemoveJSHolder(aScriptObjectHolder);
if (--sJSGCThingRootCount == 0 && !sInitialized) {
NS_RELEASE(sXPConnect);
}
return rv; return rv;
} }
@ -3640,7 +3664,7 @@ nsContentUtils::CheckSecurityBeforeLoad(nsIURI* aURIToLoad,
nsCOMPtr<nsIURI> loadingURI; nsCOMPtr<nsIURI> loadingURI;
rv = aLoadingPrincipal->GetURI(getter_AddRefs(loadingURI)); rv = aLoadingPrincipal->GetURI(getter_AddRefs(loadingURI));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
return sSecurityManager->CheckSameOriginURI(loadingURI, aURIToLoad); return sSecurityManager->CheckSameOriginURI(loadingURI, aURIToLoad, PR_TRUE);
} }
/* static */ /* static */
@ -3698,10 +3722,26 @@ nsContentUtils::IsNativeAnonymous(nsIContent* aContent)
return PR_TRUE; return PR_TRUE;
} }
NS_ASSERTION(!aContent->IsNativeAnonymous(), // Nasty hack to work around spell-check resolving style on
// native-anonymous content that's already been torn down. Don't assert
// !IsNativeAnonymous() if aContent->GetCurrentDoc() is null. The caller
// will get "wrong" style data, but it's just asking for that sort of thing
// anyway.
NS_ASSERTION(!aContent->IsNativeAnonymous() ||
!aContent->GetCurrentDoc() ||
(aContent->GetParent() &&
aContent->GetParent()->NodeInfo()->
Equals(nsGkAtoms::use, kNameSpaceID_SVG)),
"Native anonymous node with wrong binding parent"); "Native anonymous node with wrong binding parent");
aContent = bindingParent; aContent = bindingParent;
} }
return PR_FALSE; return PR_FALSE;
} }
/* static */
void
nsAutoGCRoot::Shutdown()
{
NS_IF_RELEASE(sJSRuntimeService);
}

Просмотреть файл

@ -134,7 +134,7 @@ nsCrossSiteListenerProxy::OnStartRequest(nsIRequest* aRequest,
nsCOMPtr<nsIURI> finalURI; nsCOMPtr<nsIURI> finalURI;
channel->GetURI(getter_AddRefs(finalURI)); channel->GetURI(getter_AddRefs(finalURI));
rv = nsContentUtils::GetSecurityManager()-> rv = nsContentUtils::GetSecurityManager()->
CheckSameOriginURI(mRequestingURI, finalURI); CheckSameOriginURI(mRequestingURI, finalURI, PR_FALSE);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
mAcceptState = eAccept; mAcceptState = eAccept;
return ForwardRequest(PR_FALSE); return ForwardRequest(PR_FALSE);

Просмотреть файл

@ -1161,13 +1161,7 @@ nsDocument::Reset(nsIChannel* aChannel, nsILoadGroup* aLoadGroup)
// Note: this code is duplicated in nsXULDocument::StartDocumentLoad and // Note: this code is duplicated in nsXULDocument::StartDocumentLoad and
// nsScriptSecurityManager::GetChannelPrincipal. // nsScriptSecurityManager::GetChannelPrincipal.
// Note: this should match nsDocShell::OnLoadingSite // Note: this should match nsDocShell::OnLoadingSite
nsLoadFlags loadFlags = 0; NS_GetFinalChannelURI(aChannel, getter_AddRefs(uri));
nsresult rv = aChannel->GetLoadFlags(&loadFlags);
if (NS_SUCCEEDED(rv) && (loadFlags & nsIChannel::LOAD_REPLACE)) {
aChannel->GetURI(getter_AddRefs(uri));
} else {
aChannel->GetOriginalURI(getter_AddRefs(uri));
}
nsIScriptSecurityManager *securityManager = nsIScriptSecurityManager *securityManager =
nsContentUtils::GetSecurityManager(); nsContentUtils::GetSecurityManager();

Просмотреть файл

@ -792,6 +792,9 @@ protected:
nsString mBaseTarget; nsString mBaseTarget;
// Our update nesting level
PRUint32 mUpdateNestLevel;
private: private:
friend class nsUnblockOnloadEvent; friend class nsUnblockOnloadEvent;
@ -833,9 +836,6 @@ private:
// Member to store out last-selected stylesheet set. // Member to store out last-selected stylesheet set.
nsString mLastStyleSheetSet; nsString mLastStyleSheetSet;
// Our update nesting level
PRUint32 mUpdateNestLevel;
}; };

Просмотреть файл

@ -838,6 +838,7 @@ GK_ATOM(thead, "thead")
GK_ATOM(thumb, "thumb") GK_ATOM(thumb, "thumb")
GK_ATOM(title, "title") GK_ATOM(title, "title")
GK_ATOM(titlebar, "titlebar") GK_ATOM(titlebar, "titlebar")
GK_ATOM(titlebarcolor, "titlebarcolor")
GK_ATOM(titletip, "titletip") GK_ATOM(titletip, "titletip")
GK_ATOM(toggled, "toggled") GK_ATOM(toggled, "toggled")
GK_ATOM(token, "token") GK_ATOM(token, "token")

Просмотреть файл

@ -42,7 +42,7 @@
nsLineBreaker::nsLineBreaker() nsLineBreaker::nsLineBreaker()
: mCurrentWordContainsComplexChar(PR_FALSE), : mCurrentWordContainsComplexChar(PR_FALSE),
mAfterSpace(PR_FALSE) mAfterBreakableSpace(PR_FALSE), mBreakHere(PR_FALSE)
{ {
} }
@ -72,10 +72,10 @@ nsLineBreaker::FlushCurrentWord()
TextItem* ti = &mTextItems[i]; TextItem* ti = &mTextItems[i];
NS_ASSERTION(ti->mLength > 0, "Zero length word contribution?"); NS_ASSERTION(ti->mLength > 0, "Zero length word contribution?");
if (!(ti->mFlags & BREAK_ALLOW_INITIAL) && ti->mSinkOffset == 0) { if ((ti->mFlags & BREAK_SUPPRESS_INITIAL) && ti->mSinkOffset == 0) {
breakState[offset] = PR_FALSE; breakState[offset] = PR_FALSE;
} }
if (!(ti->mFlags & BREAK_ALLOW_INSIDE)) { if (ti->mFlags & BREAK_SUPPRESS_INSIDE) {
PRUint32 exclude = ti->mSinkOffset == 0 ? 1 : 0; PRUint32 exclude = ti->mSinkOffset == 0 ? 1 : 0;
memset(breakState.Elements() + offset + exclude, PR_FALSE, ti->mLength - exclude); memset(breakState.Elements() + offset + exclude, PR_FALSE, ti->mLength - exclude);
} }
@ -107,7 +107,7 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUnichar* aText, PRUint32
// Continue the current word // Continue the current word
if (mCurrentWord.Length() > 0) { if (mCurrentWord.Length() > 0) {
NS_ASSERTION(!mAfterSpace, "These should not be set"); NS_ASSERTION(!mAfterBreakableSpace && !mBreakHere, "These should not be set");
while (offset < aLength && !IsSpace(aText[offset])) { while (offset < aLength && !IsSpace(aText[offset])) {
mCurrentWord.AppendElement(aText[offset]); mCurrentWord.AppendElement(aText[offset]);
@ -137,8 +137,14 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUnichar* aText, PRUint32
} }
PRUint32 start = offset; PRUint32 start = offset;
if (!aSink && !aFlags) { PRBool noBreaksNeeded = !aSink ||
// Skip to the space before the last word, since we don't need the breaks ((aFlags & BREAK_SUPPRESS_INITIAL) && (aFlags & BREAK_SUPPRESS_INSIDE) &&
!mBreakHere && !mAfterBreakableSpace && (aFlags & BREAK_SKIP_SETTING_NO_BREAKS));
if (noBreaksNeeded) {
// Skip to the space before the last word, since either the break data
// here is not needed, or no breaks are set in the sink and there cannot
// be any breaks in this chunk; all we need is the context for the next
// chunk (if any)
offset = aLength; offset = aLength;
while (offset > start) { while (offset > start) {
--offset; --offset;
@ -152,16 +158,17 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUnichar* aText, PRUint32
for (;;) { for (;;) {
PRUnichar ch = aText[offset]; PRUnichar ch = aText[offset];
PRBool isSpace = IsSpace(ch); PRBool isSpace = IsSpace(ch);
PRBool isBreakableSpace = isSpace && !(aFlags & BREAK_SUPPRESS_INSIDE);
if (aSink) { if (aSink) {
breakState[offset] = mAfterSpace && !isSpace && breakState[offset] = mBreakHere || (mAfterBreakableSpace && !isBreakableSpace);
(aFlags & (offset == 0 ? BREAK_ALLOW_INITIAL : BREAK_ALLOW_INSIDE));
} }
mAfterSpace = isSpace; mBreakHere = PR_FALSE;
mAfterBreakableSpace = isBreakableSpace;
if (isSpace) { if (isSpace) {
if (offset > wordStart && wordHasComplexChar) { if (offset > wordStart && wordHasComplexChar) {
if (aSink && (aFlags & BREAK_ALLOW_INSIDE)) { if (aSink && !(aFlags & BREAK_SUPPRESS_INSIDE)) {
// Save current start-of-word state because GetJISx4051Breaks will // Save current start-of-word state because GetJISx4051Breaks will
// set it to false // set it to false
PRPackedBool currentStart = breakState[wordStart]; PRPackedBool currentStart = breakState[wordStart];
@ -198,7 +205,7 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUnichar* aText, PRUint32
} }
} }
if (aSink) { if (!noBreaksNeeded) {
aSink->SetBreaks(start, offset - start, breakState.Elements() + start); aSink->SetBreaks(start, offset - start, breakState.Elements() + start);
} }
return NS_OK; return NS_OK;
@ -214,7 +221,7 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUint8* aText, PRUint32 aL
// Continue the current word // Continue the current word
if (mCurrentWord.Length() > 0) { if (mCurrentWord.Length() > 0) {
NS_ASSERTION(!mAfterSpace, "These should not be set"); NS_ASSERTION(!mAfterBreakableSpace && !mBreakHere, "These should not be set");
while (offset < aLength && !IsSpace(aText[offset])) { while (offset < aLength && !IsSpace(aText[offset])) {
mCurrentWord.AppendElement(aText[offset]); mCurrentWord.AppendElement(aText[offset]);
@ -247,8 +254,14 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUint8* aText, PRUint32 aL
} }
PRUint32 start = offset; PRUint32 start = offset;
if (!aSink && !aFlags) { PRBool noBreaksNeeded = !aSink ||
// Skip to the space before the last word, since we don't need the breaks ((aFlags & BREAK_SUPPRESS_INITIAL) && (aFlags & BREAK_SUPPRESS_INSIDE) &&
!mBreakHere && !mAfterBreakableSpace && (aFlags & BREAK_SKIP_SETTING_NO_BREAKS));
if (noBreaksNeeded) {
// Skip to the space before the last word, since either the break data
// here is not needed, or no breaks are set in the sink and there cannot
// be any breaks in this chunk; all we need is the context for the next
// chunk (if any)
offset = aLength; offset = aLength;
while (offset > start) { while (offset > start) {
--offset; --offset;
@ -262,16 +275,17 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUint8* aText, PRUint32 aL
for (;;) { for (;;) {
PRUint8 ch = aText[offset]; PRUint8 ch = aText[offset];
PRBool isSpace = IsSpace(ch); PRBool isSpace = IsSpace(ch);
PRBool isBreakableSpace = isSpace && !(aFlags & BREAK_SUPPRESS_INSIDE);
if (aSink) { if (aSink) {
breakState[offset] = mAfterSpace && !isSpace && breakState[offset] = mBreakHere || (mAfterBreakableSpace && !isBreakableSpace);
(aFlags & (offset == 0 ? BREAK_ALLOW_INITIAL : BREAK_ALLOW_INSIDE));
} }
mAfterSpace = isSpace; mBreakHere = PR_FALSE;
mAfterBreakableSpace = isBreakableSpace;
if (isSpace) { if (isSpace) {
if (offset > wordStart && wordHasComplexChar) { if (offset > wordStart && wordHasComplexChar) {
if (aSink && (aFlags & BREAK_ALLOW_INSIDE)) { if (aSink && !(aFlags & BREAK_SUPPRESS_INSIDE)) {
// Save current start-of-word state because GetJISx4051Breaks will // Save current start-of-word state because GetJISx4051Breaks will
// set it to false // set it to false
PRPackedBool currentStart = breakState[wordStart]; PRPackedBool currentStart = breakState[wordStart];
@ -311,18 +325,22 @@ nsLineBreaker::AppendText(nsIAtom* aLangGroup, const PRUint8* aText, PRUint32 aL
} }
} }
if (aSink) { if (!noBreaksNeeded) {
aSink->SetBreaks(start, offset - start, breakState.Elements() + start); aSink->SetBreaks(start, offset - start, breakState.Elements() + start);
} }
return NS_OK; return NS_OK;
} }
nsresult nsresult
nsLineBreaker::AppendInvisibleWhitespace() { nsLineBreaker::AppendInvisibleWhitespace(PRUint32 aFlags) {
// Treat as "invisible whitespace"
nsresult rv = FlushCurrentWord(); nsresult rv = FlushCurrentWord();
if (NS_FAILED(rv)) if (NS_FAILED(rv))
return rv; return rv;
mAfterSpace = PR_TRUE;
PRBool isBreakableSpace = !(aFlags & BREAK_SUPPRESS_INSIDE);
if (mAfterBreakableSpace && !isBreakableSpace) {
mBreakHere = PR_TRUE;
}
mAfterBreakableSpace = isBreakableSpace;
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -194,7 +194,7 @@ nsSyncLoader::LoadDocument(nsIChannel* aChannel,
nsIScriptSecurityManager::STANDARD); nsIScriptSecurityManager::STANDARD);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = securityManager->CheckSameOriginURI(aLoaderURI, docURI); rv = securityManager->CheckSameOriginURI(aLoaderURI, docURI, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
} }
@ -378,7 +378,7 @@ nsSyncLoader::OnChannelRedirect(nsIChannel *aOldChannel,
nsIScriptSecurityManager *securityManager = nsIScriptSecurityManager *securityManager =
nsContentUtils::GetSecurityManager(); nsContentUtils::GetSecurityManager();
rv = securityManager->CheckSameOriginURI(oldURI, newURI); rv = securityManager->CheckSameOriginURI(oldURI, newURI, PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
mChannel = aNewChannel; mChannel = aNewChannel;

Просмотреть файл

@ -56,6 +56,7 @@
#include "prprf.h" #include "prprf.h"
#include "nsIDOMEventListener.h" #include "nsIDOMEventListener.h"
#include "nsIJSContextStack.h" #include "nsIJSContextStack.h"
#include "nsJSEnvironment.h"
#include "nsIScriptSecurityManager.h" #include "nsIScriptSecurityManager.h"
#include "nsWeakPtr.h" #include "nsWeakPtr.h"
#include "nsICharsetAlias.h" #include "nsICharsetAlias.h"
@ -1149,7 +1150,8 @@ IsSameOrigin(nsIPrincipal* aPrincipal, nsIChannel* aChannel)
rv = aChannel->GetURI(getter_AddRefs(channelURI)); rv = aChannel->GetURI(getter_AddRefs(channelURI));
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
rv = nsContentUtils::GetSecurityManager()->CheckSameOriginURI(codebase, channelURI); rv = nsContentUtils::GetSecurityManager()->
CheckSameOriginURI(codebase, channelURI, PR_FALSE);
return NS_SUCCEEDED(rv); return NS_SUCCEEDED(rv);
} }
@ -1778,6 +1780,7 @@ nsXMLHttpRequest::RequestCompleted()
ChangeState(XML_HTTP_REQUEST_OPENED); ChangeState(XML_HTTP_REQUEST_OPENED);
} }
nsJSContext::MaybeCC(PR_FALSE);
return rv; return rv;
} }
@ -2320,6 +2323,7 @@ nsXMLHttpRequest::Error(nsIDOMEvent* aEvent)
NotifyEventListeners(errorEventListeners, event); NotifyEventListeners(errorEventListeners, event);
} }
nsJSContext::MaybeCC(PR_FALSE);
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -2465,6 +2465,13 @@ nsCanvasRenderingContext2D::GetImageData()
PRUint8 g = *row++; PRUint8 g = *row++;
PRUint8 b = *row++; PRUint8 b = *row++;
#endif #endif
// Convert to non-premultiplied color
if (a != 0) {
r = (r * 255) / a;
g = (g * 255) / a;
b = (b * 255) / a;
}
*dest++ = INT_TO_JSVAL(r); *dest++ = INT_TO_JSVAL(r);
*dest++ = INT_TO_JSVAL(g); *dest++ = INT_TO_JSVAL(g);
*dest++ = INT_TO_JSVAL(b); *dest++ = INT_TO_JSVAL(b);
@ -2588,6 +2595,11 @@ nsCanvasRenderingContext2D::PutImageData()
else if (JSVAL_IS_DOUBLE(va)) ia = (PRUint8) (*JSVAL_TO_DOUBLE(va)); else if (JSVAL_IS_DOUBLE(va)) ia = (PRUint8) (*JSVAL_TO_DOUBLE(va));
else return NS_ERROR_DOM_SYNTAX_ERR; else return NS_ERROR_DOM_SYNTAX_ERR;
// Convert to premultiplied color (losslessly if the input came from getImageData)
ir = (ir*ia + 254) / 255;
ig = (ig*ia + 254) / 255;
ib = (ib*ia + 254) / 255;
#ifdef IS_LITTLE_ENDIAN #ifdef IS_LITTLE_ENDIAN
*imgPtr++ = ib; *imgPtr++ = ib;
*imgPtr++ = ig; *imgPtr++ = ig;

Просмотреть файл

@ -136,6 +136,9 @@
#include "nsEventDispatcher.h" #include "nsEventDispatcher.h"
#include "nsPresShellIterator.h" #include "nsPresShellIterator.h"
#include "nsServiceManagerUtils.h"
#include "nsITimer.h"
#ifdef XP_MACOSX #ifdef XP_MACOSX
#include <Events.h> #include <Events.h>
#endif #endif
@ -144,6 +147,8 @@
//#define DEBUG_DOCSHELL_FOCUS //#define DEBUG_DOCSHELL_FOCUS
#endif #endif
#define NS_USER_INTERACTION_INTERVAL 5000 // ms
static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID); static NS_DEFINE_CID(kFrameTraversalCID, NS_FRAMETRAVERSAL_CID);
@ -171,12 +176,48 @@ static PRUint32 sESMInstanceCount = 0;
static PRInt32 sChromeAccessModifier = 0, sContentAccessModifier = 0; static PRInt32 sChromeAccessModifier = 0, sContentAccessModifier = 0;
PRInt32 nsEventStateManager::sUserInputEventDepth = 0; PRInt32 nsEventStateManager::sUserInputEventDepth = 0;
static PRUint32 gMouseOrKeyboardEventCounter = 0;
static nsITimer* gUserInteractionTimer = nsnull;
static nsITimerCallback* gUserInteractionTimerCallback = nsnull;
class nsUITimerCallback : public nsITimerCallback
{
public:
nsUITimerCallback() : mPreviousCount(0) {}
NS_DECL_ISUPPORTS
NS_DECL_NSITIMERCALLBACK
private:
PRUint32 mPreviousCount;
};
NS_IMPL_ISUPPORTS1(nsUITimerCallback, nsITimerCallback)
// If aTimer is nsnull, this method always sends "user-interaction-inactive"
// notification.
NS_IMETHODIMP
nsUITimerCallback::Notify(nsITimer* aTimer)
{
nsresult rv;
nsCOMPtr<nsIObserverService> obs =
do_GetService("@mozilla.org/observer-service;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
if ((gMouseOrKeyboardEventCounter == mPreviousCount) || !aTimer) {
gMouseOrKeyboardEventCounter = 0;
obs->NotifyObservers(nsnull, "user-interaction-inactive", nsnull);
} else {
obs->NotifyObservers(nsnull, "user-interaction-active", nsnull);
}
mPreviousCount = gMouseOrKeyboardEventCounter;
return NS_OK;
}
enum { enum {
MOUSE_SCROLL_N_LINES, MOUSE_SCROLL_N_LINES,
MOUSE_SCROLL_PAGE, MOUSE_SCROLL_PAGE,
MOUSE_SCROLL_HISTORY, MOUSE_SCROLL_HISTORY,
MOUSE_SCROLL_TEXTSIZE, MOUSE_SCROLL_TEXTSIZE,
MOUSE_SCROLL_PIXELS MOUSE_SCROLL_PIXELS,
MOUSE_SCROLL_FULLZOOM
}; };
struct AccessKeyInfo { struct AccessKeyInfo {
@ -431,6 +472,18 @@ nsEventStateManager::nsEventStateManager()
mTabbedThroughDocument(PR_FALSE), mTabbedThroughDocument(PR_FALSE),
mAccessKeys(nsnull) mAccessKeys(nsnull)
{ {
if (sESMInstanceCount == 0) {
gUserInteractionTimerCallback = new nsUITimerCallback();
if (gUserInteractionTimerCallback) {
NS_ADDREF(gUserInteractionTimerCallback);
CallCreateInstance("@mozilla.org/timer;1", &gUserInteractionTimer);
if (gUserInteractionTimer) {
gUserInteractionTimer->InitWithCallback(gUserInteractionTimerCallback,
NS_USER_INTERACTION_INTERVAL,
nsITimer::TYPE_REPEATING_SLACK);
}
}
}
++sESMInstanceCount; ++sESMInstanceCount;
} }
@ -509,6 +562,14 @@ nsEventStateManager::~nsEventStateManager()
if(sESMInstanceCount == 0) { if(sESMInstanceCount == 0) {
NS_IF_RELEASE(gLastFocusedContent); NS_IF_RELEASE(gLastFocusedContent);
NS_IF_RELEASE(gLastFocusedDocument); NS_IF_RELEASE(gLastFocusedDocument);
if (gUserInteractionTimerCallback) {
gUserInteractionTimerCallback->Notify(nsnull);
NS_RELEASE(gUserInteractionTimerCallback);
}
if (gUserInteractionTimer) {
gUserInteractionTimer->Cancel();
NS_RELEASE(gUserInteractionTimer);
}
} }
delete mAccessKeys; delete mAccessKeys;
@ -724,6 +785,25 @@ nsEventStateManager::PreHandleEvent(nsPresContext* aPresContext,
if (!mCurrentTarget) return NS_ERROR_NULL_POINTER; if (!mCurrentTarget) return NS_ERROR_NULL_POINTER;
} }
// Do not take account NS_MOUSE_ENTER/EXIT so that loading a page
// when user is not active doesn't change the state to active.
if (NS_IS_TRUSTED_EVENT(aEvent) &&
((aEvent->eventStructType == NS_MOUSE_EVENT &&
static_cast<nsMouseEvent*>(aEvent)->reason == nsMouseEvent::eReal &&
aEvent->message != NS_MOUSE_ENTER &&
aEvent->message != NS_MOUSE_EXIT) ||
aEvent->eventStructType == NS_MOUSE_SCROLL_EVENT ||
aEvent->eventStructType == NS_KEY_EVENT)) {
if (gMouseOrKeyboardEventCounter == 0) {
nsCOMPtr<nsIObserverService> obs =
do_GetService("@mozilla.org/observer-service;1");
if (obs) {
obs->NotifyObservers(nsnull, "user-interaction-active", nsnull);
}
}
++gMouseOrKeyboardEventCounter;
}
*aStatus = nsEventStatus_eIgnore; *aStatus = nsEventStatus_eIgnore;
nsMouseWheelTransaction::OnEvent(aEvent); nsMouseWheelTransaction::OnEvent(aEvent);
@ -1859,8 +1939,10 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
} // GenerateDragGesture } // GenerateDragGesture
nsresult nsresult
nsEventStateManager::ChangeTextSize(PRInt32 change) nsEventStateManager::GetMarkupDocumentViewer(nsIMarkupDocumentViewer** aMv)
{ {
*aMv = nsnull;
if(!gLastFocusedDocument) return NS_ERROR_FAILURE; if(!gLastFocusedDocument) return NS_ERROR_FAILURE;
nsPIDOMWindow* ourWindow = gLastFocusedDocument->GetWindow(); nsPIDOMWindow* ourWindow = gLastFocusedDocument->GetWindow();
@ -1894,6 +1976,19 @@ nsEventStateManager::ChangeTextSize(PRInt32 change)
nsCOMPtr<nsIMarkupDocumentViewer> mv(do_QueryInterface(cv)); nsCOMPtr<nsIMarkupDocumentViewer> mv(do_QueryInterface(cv));
if(!mv) return NS_ERROR_FAILURE; if(!mv) return NS_ERROR_FAILURE;
*aMv = mv;
NS_IF_ADDREF(*aMv);
return NS_OK;
}
nsresult
nsEventStateManager::ChangeTextSize(PRInt32 change)
{
nsCOMPtr<nsIMarkupDocumentViewer> mv;
nsresult rv = GetMarkupDocumentViewer(getter_AddRefs(mv));
NS_ENSURE_SUCCESS(rv, rv);
float textzoom; float textzoom;
mv->GetTextZoom(&textzoom); mv->GetTextZoom(&textzoom);
textzoom += ((float)change) / 10; textzoom += ((float)change) / 10;
@ -1903,6 +1998,27 @@ nsEventStateManager::ChangeTextSize(PRInt32 change)
return NS_OK; return NS_OK;
} }
nsresult
nsEventStateManager::ChangeFullZoom(PRInt32 change)
{
nsCOMPtr<nsIMarkupDocumentViewer> mv;
nsresult rv = GetMarkupDocumentViewer(getter_AddRefs(mv));
NS_ENSURE_SUCCESS(rv, rv);
float fullzoom;
float zoomMin = ((float)nsContentUtils::GetIntPref("fullZoom.minPercent", 50)) / 100;
float zoomMax = ((float)nsContentUtils::GetIntPref("fullZoom.maxPercent", 300)) / 100;
mv->GetFullZoom(&fullzoom);
fullzoom += ((float)change) / 10;
if (fullzoom < zoomMin)
fullzoom = zoomMin;
else if (fullzoom > zoomMax)
fullzoom = zoomMax;
mv->SetFullZoom(fullzoom);
return NS_OK;
}
void void
nsEventStateManager::DoScrollHistory(PRInt32 direction) nsEventStateManager::DoScrollHistory(PRInt32 direction)
{ {
@ -1934,6 +2050,21 @@ nsEventStateManager::DoScrollTextsize(nsIFrame *aTargetFrame,
} }
} }
void
nsEventStateManager::DoScrollFullZoom(nsIFrame *aTargetFrame,
PRInt32 adjustment)
{
// Exclude form controls and XUL content.
nsIContent *content = aTargetFrame->GetContent();
if (content &&
!content->IsNodeOfType(nsINode::eHTML_FORM_CONTROL) &&
!content->IsNodeOfType(nsINode::eXUL))
{
// negative adjustment to increase zoom, positive to decrease
ChangeFullZoom((adjustment > 0) ? -1 : 1);
}
}
static nsIFrame* static nsIFrame*
GetParentFrameToScroll(nsPresContext* aPresContext, nsIFrame* aFrame) GetParentFrameToScroll(nsPresContext* aPresContext, nsIFrame* aFrame)
{ {
@ -2317,6 +2448,12 @@ nsEventStateManager::PostHandleEvent(nsPresContext* aPresContext,
} }
break; break;
case MOUSE_SCROLL_FULLZOOM:
{
DoScrollFullZoom(aTargetFrame, msEvent->delta);
}
break;
default: // Including -1 (do nothing) default: // Including -1 (do nothing)
break; break;
} }

Просмотреть файл

@ -51,6 +51,7 @@
#include "nsCOMArray.h" #include "nsCOMArray.h"
#include "nsIFrame.h" #include "nsIFrame.h"
#include "nsCycleCollectionParticipant.h" #include "nsCycleCollectionParticipant.h"
#include "nsIMarkupDocumentViewer.h"
class nsIScrollableView; class nsIScrollableView;
class nsIPresShell; class nsIPresShell;
@ -304,7 +305,10 @@ protected:
void ForceViewUpdate(nsIView* aView); void ForceViewUpdate(nsIView* aView);
void DoScrollHistory(PRInt32 direction); void DoScrollHistory(PRInt32 direction);
void DoScrollTextsize(nsIFrame *aTargetFrame, PRInt32 adjustment); void DoScrollTextsize(nsIFrame *aTargetFrame, PRInt32 adjustment);
void DoScrollFullZoom(nsIFrame *aTargetFrame, PRInt32 adjustment);
nsresult GetMarkupDocumentViewer(nsIMarkupDocumentViewer** aMv);
nsresult ChangeTextSize(PRInt32 change); nsresult ChangeTextSize(PRInt32 change);
nsresult ChangeFullZoom(PRInt32 change);
// end mousewheel functions // end mousewheel functions
// routines for the d&d gesture tracking state machine // routines for the d&d gesture tracking state machine

Просмотреть файл

@ -764,16 +764,10 @@ nsFSMultipartFormData::AddNameValuePair(nsIDOMHTMLElement* aSource,
// XXX: name parameter should be encoded per RFC 2231 // XXX: name parameter should be encoded per RFC 2231
// RFC 2388 specifies that RFC 2047 be used, but I think it's not // RFC 2388 specifies that RFC 2047 be used, but I think it's not
// consistent with MIME standard. // consistent with MIME standard.
// NOTE: The ordering of these headers, and in particular which comes first
// and which comes last, is important. See comments in
// nsFSMultipartFormData::AddNameFilePair
mPostDataChunk += NS_LITERAL_CSTRING("--") + mBoundary mPostDataChunk += NS_LITERAL_CSTRING("--") + mBoundary
+ NS_LITERAL_CSTRING(CRLF) + NS_LITERAL_CSTRING(CRLF)
+ NS_LITERAL_CSTRING("Content-Disposition: form-data; name=\"") + NS_LITERAL_CSTRING("Content-Disposition: form-data; name=\"")
+ nameStr + NS_LITERAL_CSTRING("\"" CRLF) + nameStr + NS_LITERAL_CSTRING("\"" CRLF CRLF)
+ NS_LITERAL_CSTRING("Content-Type: text/plain; charset=")
+ mCharset
+ NS_LITERAL_CSTRING(CRLF CRLF)
+ valueStr + NS_LITERAL_CSTRING(CRLF); + valueStr + NS_LITERAL_CSTRING(CRLF);
return NS_OK; return NS_OK;
@ -800,23 +794,12 @@ nsFSMultipartFormData::AddNameFilePair(nsIDOMHTMLElement* aSource,
+ NS_LITERAL_CSTRING(CRLF); + NS_LITERAL_CSTRING(CRLF);
if (!mBackwardsCompatibleSubmit) { if (!mBackwardsCompatibleSubmit) {
// XXX Is there any way to tell when "8bit" or "7bit" etc may be // XXX Is there any way to tell when "8bit" or "7bit" etc may be
// XXXbz See bug 58189 for why we try to send it and bug 83065 for why we
// don't just always do it. It seems like a better solution would be to
// just make sure we send this header before the Content-Type header (to
// deal with the PHP brain-deadness described in bug 83065), but to send it
// anyway. However, we need to make sure it comes after the
// Content-Disposition header, because other server-side packages make the
// equally brain-dead assumption that Content-Disposition is the first
// header in every part. See bug 116346 for that fun.
mPostDataChunk += mPostDataChunk +=
NS_LITERAL_CSTRING("Content-Transfer-Encoding: binary" CRLF); NS_LITERAL_CSTRING("Content-Transfer-Encoding: binary" CRLF);
} }
// XXX: name/filename parameter should be encoded per RFC 2231 // XXX: name/filename parameter should be encoded per RFC 2231
// RFC 2388 specifies that RFC 2047 be used, but I think it's not // RFC 2388 specifies that RFC 2047 be used, but I think it's not
// consistent with the MIME standard. // consistent with the MIME standard.
// NOTE: The Content-Disposition MUST come first and the Content-Type last to
// satisfy non-MIME-compliant server-side parsers. See comment above on
// Content-Transfer-Encoding.
mPostDataChunk += mPostDataChunk +=
NS_LITERAL_CSTRING("Content-Disposition: form-data; name=\"") NS_LITERAL_CSTRING("Content-Disposition: form-data; name=\"")
+ nameStr + NS_LITERAL_CSTRING("\"; filename=\"") + nameStr + NS_LITERAL_CSTRING("\"; filename=\"")
@ -1160,9 +1143,6 @@ GetSubmissionFromForm(nsGenericHTMLElement* aForm,
nsCOMPtr<nsISaveAsCharset> encoder; nsCOMPtr<nsISaveAsCharset> encoder;
nsFormSubmission::GetEncoder(aForm, charset, getter_AddRefs(encoder)); nsFormSubmission::GetEncoder(aForm, charset, getter_AddRefs(encoder));
if (!encoder)
charset.AssignLiteral("UTF-8");
// Get form processor // Get form processor
nsCOMPtr<nsIFormProcessor> formProcessor = nsCOMPtr<nsIFormProcessor> formProcessor =
do_GetService(kFormProcessorCID, &rv); do_GetService(kFormProcessorCID, &rv);

Просмотреть файл

@ -1703,30 +1703,21 @@ nsHTMLDocument::SetDomain(const nsAString& aDomain)
nsAutoString current; nsAutoString current;
if (NS_FAILED(GetDomain(current))) if (NS_FAILED(GetDomain(current)))
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
PRBool ok = PR_FALSE; PRBool ok = current.Equals(aDomain);
if (current.Equals(aDomain)) { if (current.Length() > aDomain.Length() &&
ok = PR_TRUE; StringEndsWith(current, aDomain, nsCaseInsensitiveStringComparator()) &&
} else if (aDomain.Length() < current.Length()) { current.CharAt(current.Length() - aDomain.Length() - 1) == '.') {
nsAutoString suffix; // Using only a TLD is forbidden (bug 368700)
current.Right(suffix, aDomain.Length()); nsCOMPtr<nsIEffectiveTLDService> tldService =
PRUnichar c = current.CharAt(current.Length() - aDomain.Length() - 1); do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
if (suffix.Equals(aDomain, nsCaseInsensitiveStringComparator()) && if (!tldService)
(c == '.')) { return NS_ERROR_NOT_AVAILABLE;
// Using only a TLD is forbidden (bug 368700)
nsCOMPtr<nsIEffectiveTLDService> tldService =
do_GetService(NS_EFFECTIVETLDSERVICE_CONTRACTID);
if (!tldService)
return NS_ERROR_NOT_AVAILABLE;
NS_ConvertUTF16toUTF8 str(aDomain); // try to get the base domain; if this works, we're ok
PRUint32 tldLength; NS_ConvertUTF16toUTF8 str(aDomain);
nsresult rv = tldService->GetEffectiveTLDLength(str, &tldLength); nsCAutoString etld;
if (NS_FAILED(rv)) nsresult rv = tldService->GetBaseDomainFromHost(str, 0, etld);
return rv; ok = NS_SUCCEEDED(rv);
if (tldLength < str.Length())
ok = PR_TRUE;
}
} }
if (!ok) { if (!ok) {
// Error: illegal domain // Error: illegal domain
@ -2219,6 +2210,7 @@ nsHTMLDocument::OpenCommon(const nsACString& aContentType, PRBool aReplace)
if (root) { if (root) {
// Tear down the frames for the root element. // Tear down the frames for the root element.
MOZ_AUTO_DOC_UPDATE(this, UPDATE_CONTENT_MODEL, PR_TRUE);
nsNodeUtils::ContentRemoved(this, root, 0); nsNodeUtils::ContentRemoved(this, root, 0);
// Put the root element back into the document, we don't notify // Put the root element back into the document, we don't notify
@ -3740,6 +3732,16 @@ nsHTMLDocument::GetDesignMode(nsAString & aDesignMode)
return NS_OK; return NS_OK;
} }
void
nsHTMLDocument::EndUpdate(nsUpdateType aUpdateType)
{
nsDocument::EndUpdate(aUpdateType);
if (mUpdateNestLevel == 0 && mContentEditableCount > 0 != IsEditingOn()) {
EditingStateChanged();
}
}
nsresult nsresult
nsHTMLDocument::ChangeContentEditableCount(nsIContent *aElement, nsHTMLDocument::ChangeContentEditableCount(nsIContent *aElement,
PRInt32 aChange) PRInt32 aChange)
@ -3749,7 +3751,8 @@ nsHTMLDocument::ChangeContentEditableCount(nsIContent *aElement,
mContentEditableCount += aChange; mContentEditableCount += aChange;
if (mParser) { if (mParser ||
(mUpdateNestLevel > 0 && mContentEditableCount > 0 != IsEditingOn())) {
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -212,6 +212,8 @@ public:
mDisableCookieAccess = PR_TRUE; mDisableCookieAccess = PR_TRUE;
} }
void EndUpdate(nsUpdateType aUpdateType);
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLDocument, nsDocument) NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLDocument, nsDocument)
protected: protected:

Просмотреть файл

@ -184,28 +184,22 @@ GetValueFromString(const nsAString &aValueAsString,
float *aValue, float *aValue,
PRUint16 *aUnitType) PRUint16 *aUnitType)
{ {
char *str = ToNewCString(aValueAsString); NS_ConvertUTF16toUTF8 value(aValueAsString);
if (!str) const char *str = value.get();
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = NS_ERROR_FAILURE; if (NS_IsAsciiWhitespace(*str))
return NS_ERROR_FAILURE;
if (*str) { char *rest;
char *rest; *aValue = float(PR_strtod(str, &rest));
*aValue = static_cast<float>(PR_strtod(str, &rest)); if (rest != str) {
if (rest != str) { *aUnitType = GetUnitTypeForString(rest);
*aUnitType = GetUnitTypeForString(nsCRT::strtok(rest, if (IsValidUnitType(*aUnitType)) {
"\x20\x9\xD\xA", return NS_OK;
&rest));
if (IsValidUnitType(*aUnitType)) {
rv = NS_OK;
}
} }
} }
nsMemory::Free(str); return NS_ERROR_FAILURE;
return rv;
} }
float float

Просмотреть файл

@ -52,12 +52,18 @@ nsSVGInteger::SetBaseValueString(const nsAString &aValueAsString,
nsSVGElement *aSVGElement, nsSVGElement *aSVGElement,
PRBool aDoSetAttr) PRBool aDoSetAttr)
{ {
nsAutoString s; NS_ConvertUTF16toUTF8 value(aValueAsString);
s.Assign(aValueAsString); const char *str = value.get();
PRInt32 err;
PRInt32 val = s.ToInteger(&err); if (NS_IsAsciiWhitespace(*str))
nsresult rv = static_cast<nsresult>(err); return NS_ERROR_FAILURE;
NS_ENSURE_SUCCESS(rv, rv);
char *rest;
PRInt32 val = strtol(str, &rest, 10);
if (rest == str || *rest != '\0') {
return NS_ERROR_FAILURE;
}
mBaseVal = mAnimVal = val; mBaseVal = mAnimVal = val;
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -145,28 +145,22 @@ GetValueFromString(const nsAString &aValueAsString,
float *aValue, float *aValue,
PRUint16 *aUnitType) PRUint16 *aUnitType)
{ {
char *str = ToNewCString(aValueAsString); NS_ConvertUTF16toUTF8 value(aValueAsString);
if (!str) const char *str = value.get();
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = NS_ERROR_FAILURE; if (NS_IsAsciiWhitespace(*str))
return NS_ERROR_FAILURE;
if (*str) { char *rest;
char *rest; *aValue = float(PR_strtod(str, &rest));
*aValue = static_cast<float>(PR_strtod(str, &rest)); if (rest != str) {
if (rest != str) { *aUnitType = GetUnitTypeForString(rest);
*aUnitType = GetUnitTypeForString(nsCRT::strtok(rest, if (IsValidUnitType(*aUnitType)) {
"\x20\x9\xD\xA", return NS_OK;
&rest));
if (IsValidUnitType(*aUnitType)) {
rv = NS_OK;
}
} }
} }
nsMemory::Free(str); return NS_ERROR_FAILURE;
return rv;
} }
float float

Просмотреть файл

@ -54,12 +54,18 @@ nsSVGNumber2::SetBaseValueString(const nsAString &aValueAsString,
nsSVGElement *aSVGElement, nsSVGElement *aSVGElement,
PRBool aDoSetAttr) PRBool aDoSetAttr)
{ {
nsAutoString s; NS_ConvertUTF16toUTF8 value(aValueAsString);
s.Assign(aValueAsString); const char *str = value.get();
PRInt32 err;
float val = s.ToFloat(&err); if (NS_IsAsciiWhitespace(*str))
nsresult rv = static_cast<nsresult>(err); return NS_ERROR_FAILURE;
NS_ENSURE_SUCCESS(rv, rv);
char *rest;
float val = float(PR_strtod(str, &rest));
if (rest == str || *rest != '\0') {
return NS_ERROR_FAILURE;
}
mBaseVal = mAnimVal = val; mBaseVal = mAnimVal = val;
return NS_OK; return NS_OK;
} }

Просмотреть файл

@ -915,7 +915,10 @@ nsBindingManager::DoProcessAttachedQueue()
mProcessAttachedQueueEvent = nsnull; mProcessAttachedQueueEvent = nsnull;
if (mDocument) { if (mDocument) {
mDocument->UnblockOnload(PR_TRUE); // Hold a strong reference while calling UnblockOnload since that might
// run script.
nsCOMPtr<nsIDocument> doc = mDocument;
doc->UnblockOnload(PR_TRUE);
} }
} }
@ -933,6 +936,11 @@ nsBindingManager::ProcessAttachedQueue()
mAttachedStack.RemoveElementAt(lastItem); mAttachedStack.RemoveElementAt(lastItem);
NS_ASSERTION(binding, "null item in attached stack?"); NS_ASSERTION(binding, "null item in attached stack?");
nsresult rv = binding->EnsureScriptAPI();
if (NS_FAILED(rv)) {
return;
}
binding->ExecuteAttachedHandler(); binding->ExecuteAttachedHandler();
} }

Просмотреть файл

@ -186,6 +186,11 @@ XBLResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags,
return JS_FALSE; return JS_FALSE;
} }
if (content->HasFlag(NODE_IS_IN_BINDING_TEARDOWN)) {
// Don't evaluate fields now!
return JS_TRUE;
}
// This mirrors code in nsXBLProtoImpl::InstallImplementation // This mirrors code in nsXBLProtoImpl::InstallImplementation
nsIDocument* doc = content->GetOwnerDoc(); nsIDocument* doc = content->GetOwnerDoc();
if (!doc) { if (!doc) {
@ -272,7 +277,8 @@ nsXBLBinding::nsXBLBinding(nsXBLPrototypeBinding* aBinding)
: mPrototypeBinding(aBinding), : mPrototypeBinding(aBinding),
mInsertionPointTable(nsnull), mInsertionPointTable(nsnull),
mIsStyleBinding(PR_TRUE), mIsStyleBinding(PR_TRUE),
mMarkedForDeath(PR_FALSE) mMarkedForDeath(PR_FALSE),
mInstalledAPI(PR_FALSE)
{ {
NS_ASSERTION(mPrototypeBinding, "Must have a prototype binding!"); NS_ASSERTION(mPrototypeBinding, "Must have a prototype binding!");
// Grab a ref to the document info so the prototype binding won't die // Grab a ref to the document info so the prototype binding won't die
@ -300,7 +306,7 @@ TraverseKey(nsISupports* aKey, nsInsertionPointList* aData, void* aClosure)
return PL_DHASH_NEXT; return PL_DHASH_NEXT;
} }
NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLBinding) NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLBinding)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLBinding) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLBinding)
// XXX Probably can't unlink mPrototypeBinding->XBLDocumentInfo(), because // XXX Probably can't unlink mPrototypeBinding->XBLDocumentInfo(), because
// mPrototypeBinding is weak. // mPrototypeBinding is weak.
@ -375,18 +381,6 @@ nsXBLBinding::SetBoundElement(nsIContent* aElement)
mNextBinding->SetBoundElement(aElement); mNextBinding->SetBoundElement(aElement);
} }
nsXBLBinding*
nsXBLBinding::GetFirstBindingWithConstructor()
{
if (mPrototypeBinding->GetConstructor())
return this;
if (mNextBinding)
return mNextBinding->GetFirstBindingWithConstructor();
return nsnull;
}
PRBool PRBool
nsXBLBinding::HasStyleSheets() const nsXBLBinding::HasStyleSheets() const
{ {
@ -800,6 +794,22 @@ nsXBLBinding::GenerateAnonymousContent()
} }
} }
nsresult
nsXBLBinding::EnsureScriptAPI()
{
if (mInstalledAPI) {
return NS_OK;
}
// Set mInstalledAPI right away since we'll recurse into here from
// nsElementSH::PostCreate when InstallImplementation is called.
mInstalledAPI = PR_TRUE;
InstallEventHandlers();
return InstallImplementation();
}
void void
nsXBLBinding::InstallEventHandlers() nsXBLBinding::InstallEventHandlers()
{ {
@ -1039,25 +1049,19 @@ void
nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument) nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocument)
{ {
if (aOldDocument != aNewDocument) { if (aOldDocument != aNewDocument) {
if (mNextBinding) // Only style bindings get their prototypes unhooked. First do ourselves.
mNextBinding->ChangeDocument(aOldDocument, aNewDocument);
// Only style bindings get their prototypes unhooked.
if (mIsStyleBinding) { if (mIsStyleBinding) {
// Now the binding dies. Unhook our prototypes. // Now the binding dies. Unhook our prototypes.
nsIContent* interfaceElement = if (mPrototypeBinding->HasImplementation()) {
mPrototypeBinding->GetImmediateChild(nsGkAtoms::implementation); nsIScriptGlobalObject *global = aOldDocument->GetScopeObject();
if (interfaceElement) {
nsIScriptGlobalObject *global = aOldDocument->GetScriptGlobalObject();
if (global) { if (global) {
nsIScriptContext *context = global->GetContext(); nsCOMPtr<nsIScriptContext> context = global->GetContext();
if (context) { if (context) {
JSContext *jscontext = (JSContext *)context->GetNativeContext(); JSContext *cx = (JSContext *)context->GetNativeContext();
nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper; nsCOMPtr<nsIXPConnectJSObjectHolder> wrapper;
nsresult rv = nsContentUtils::XPConnect()-> nsresult rv = nsContentUtils::XPConnect()->
WrapNative(jscontext, global->GetGlobalJSObject(), WrapNative(cx, global->GetGlobalJSObject(),
mBoundElement, NS_GET_IID(nsISupports), mBoundElement, NS_GET_IID(nsISupports),
getter_AddRefs(wrapper)); getter_AddRefs(wrapper));
if (NS_FAILED(rv)) if (NS_FAILED(rv))
@ -1070,16 +1074,62 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen
// XXX Stay in sync! What if a layered binding has an // XXX Stay in sync! What if a layered binding has an
// <interface>?! // <interface>?!
// XXXbz what does that comment mean, really? It seems to date
// back to when there was such a thing as an <interface>, whever
// that was...
// XXX Sanity check to make sure our class name matches // Find the right prototype.
// Pull ourselves out of the proto chain. JSObject* base = scriptObject;
JSObject* ourProto = ::JS_GetPrototype(jscontext, scriptObject); JSObject* proto;
if (ourProto) JSAutoRequest ar(cx);
{ for ( ; true; base = proto) { // Will break out on null proto
JSObject* grandProto = ::JS_GetPrototype(jscontext, ourProto); proto = ::JS_GetPrototype(cx, base);
::JS_SetPrototype(jscontext, scriptObject, grandProto); if (!proto) {
break;
}
JSClass* clazz = ::JS_GetClass(cx, proto);
if (!clazz ||
(~clazz->flags &
(JSCLASS_HAS_PRIVATE | JSCLASS_PRIVATE_IS_NSISUPPORTS)) ||
JSCLASS_RESERVED_SLOTS(clazz) != 1) {
// Clearly not the right class
continue;
}
nsCOMPtr<nsIXBLDocumentInfo> docInfo =
do_QueryInterface(static_cast<nsISupports*>
(::JS_GetPrivate(cx, proto)));
if (!docInfo) {
// Not the proto we seek
continue;
}
jsval protoBinding;
if (!::JS_GetReservedSlot(cx, proto, 0, &protoBinding)) {
NS_ERROR("Really shouldn't happen");
continue;
}
if (JSVAL_TO_PRIVATE(protoBinding) != mPrototypeBinding) {
// Not the right binding
continue;
}
// Alright! This is the right prototype. Pull it out of the
// proto chain.
JSObject* grandProto = ::JS_GetPrototype(cx, proto);
::JS_SetPrototype(cx, base, grandProto);
break;
} }
// Do this after unhooking the proto to avoid extra walking along
// the proto chain as the JS engine tries to resolve the properties
// we're removing.
mBoundElement->SetFlags(NODE_IS_IN_BINDING_TEARDOWN);
mPrototypeBinding->UndefineFields(cx, scriptObject);
mBoundElement->UnsetFlags(NODE_IS_IN_BINDING_TEARDOWN);
// Don't remove the reference from the document to the // Don't remove the reference from the document to the
// wrapper here since it'll be removed by the element // wrapper here since it'll be removed by the element
// itself when that's taken out of the document. // itself when that's taken out of the document.
@ -1088,7 +1138,14 @@ nsXBLBinding::ChangeDocument(nsIDocument* aOldDocument, nsIDocument* aNewDocumen
} }
} }
// Then do our ancestors. This reverses the construction order, so that at
// all times things are consistent as far as everyone is concerned.
if (mNextBinding) {
mNextBinding->ChangeDocument(aOldDocument, aNewDocument);
}
// Update the anonymous content. // Update the anonymous content.
// XXXbz why not only for style bindings?
nsIContent *anonymous = mContent; nsIContent *anonymous = mContent;
if (anonymous) { if (anonymous) {
// Also kill the default content within all our insertion points. // Also kill the default content within all our insertion points.

Просмотреть файл

@ -120,15 +120,13 @@ public:
void GenerateAnonymousContent(); void GenerateAnonymousContent();
void InstallAnonymousContent(nsIContent* aAnonParent, nsIContent* aElement); void InstallAnonymousContent(nsIContent* aAnonParent, nsIContent* aElement);
void InstallEventHandlers(); nsresult EnsureScriptAPI();
nsresult InstallImplementation();
void ExecuteAttachedHandler(); void ExecuteAttachedHandler();
void ExecuteDetachedHandler(); void ExecuteDetachedHandler();
void UnhookEventHandlers(); void UnhookEventHandlers();
nsIAtom* GetBaseTag(PRInt32* aNameSpaceID); nsIAtom* GetBaseTag(PRInt32* aNameSpaceID);
nsXBLBinding* GetFirstBindingWithConstructor();
nsXBLBinding* RootBinding(); nsXBLBinding* RootBinding();
nsXBLBinding* GetFirstStyleBinding(); nsXBLBinding* GetFirstStyleBinding();
@ -169,6 +167,12 @@ public:
// MEMBER VARIABLES // MEMBER VARIABLES
protected: protected:
// These two functions recursively install the event handlers
// and implementation on this binding and its base class bindings.
// External callers should call EnsureScriptAPI instead.
void InstallEventHandlers();
nsresult InstallImplementation();
nsAutoRefCnt mRefCnt; nsAutoRefCnt mRefCnt;
nsXBLPrototypeBinding* mPrototypeBinding; // Weak, but we're holding a ref to the docinfo nsXBLPrototypeBinding* mPrototypeBinding; // Weak, but we're holding a ref to the docinfo
nsCOMPtr<nsIContent> mContent; // Strong. Our anonymous content stays around with us. nsCOMPtr<nsIContent> mContent; // Strong. Our anonymous content stays around with us.
@ -181,6 +185,7 @@ protected:
PRPackedBool mIsStyleBinding; PRPackedBool mIsStyleBinding;
PRPackedBool mMarkedForDeath; PRPackedBool mMarkedForDeath;
PRPackedBool mInstalledAPI;
}; };
#endif // nsXBLBinding_h_ #endif // nsXBLBinding_h_

Просмотреть файл

@ -452,6 +452,21 @@ UnlinkProtos(nsHashKey *aKey, void *aData, void* aClosure)
return kHashEnumerateNext; return kHashEnumerateNext;
} }
struct ProtoTracer
{
TraceCallback mCallback;
void *mClosure;
};
static PRIntn PR_CALLBACK
TraceProtos(nsHashKey *aKey, void *aData, void* aClosure)
{
ProtoTracer* closure = static_cast<ProtoTracer*>(aClosure);
nsXBLPrototypeBinding *proto = static_cast<nsXBLPrototypeBinding*>(aData);
proto->Trace(closure->mCallback, closure->mClosure);
return kHashEnumerateNext;
}
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLDocumentInfo) NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLDocumentInfo)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXBLDocumentInfo) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXBLDocumentInfo)
if (tmp->mBindingTable) { if (tmp->mBindingTable) {
@ -466,7 +481,14 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXBLDocumentInfo)
tmp->mBindingTable->Enumerate(TraverseProtos, &cb); tmp->mBindingTable->Enumerate(TraverseProtos, &cb);
} }
cb.NoteXPCOMChild(static_cast<nsIScriptGlobalObject*>(tmp->mGlobalObject)); cb.NoteXPCOMChild(static_cast<nsIScriptGlobalObject*>(tmp->mGlobalObject));
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsXBLDocumentInfo)
if (tmp->mBindingTable) {
ProtoTracer closure = { aCallback, aClosure };
tmp->mBindingTable->Enumerate(TraceProtos, &closure);
}
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXBLDocumentInfo) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXBLDocumentInfo)
NS_INTERFACE_MAP_ENTRY(nsIXBLDocumentInfo) NS_INTERFACE_MAP_ENTRY(nsIXBLDocumentInfo)
@ -507,7 +529,10 @@ nsXBLDocumentInfo::~nsXBLDocumentInfo()
mGlobalObject->SetScriptContext(nsIProgrammingLanguage::JAVASCRIPT, nsnull); mGlobalObject->SetScriptContext(nsIProgrammingLanguage::JAVASCRIPT, nsnull);
mGlobalObject->ClearGlobalObjectOwner(); // just in case mGlobalObject->ClearGlobalObjectOwner(); // just in case
} }
delete mBindingTable; if (mBindingTable) {
NS_DROP_JS_OBJECTS(this, nsXBLDocumentInfo);
delete mBindingTable;
}
} }
NS_IMETHODIMP NS_IMETHODIMP
@ -541,8 +566,13 @@ DeletePrototypeBinding(nsHashKey* aKey, void* aData, void* aClosure)
NS_IMETHODIMP NS_IMETHODIMP
nsXBLDocumentInfo::SetPrototypeBinding(const nsACString& aRef, nsXBLPrototypeBinding* aBinding) nsXBLDocumentInfo::SetPrototypeBinding(const nsACString& aRef, nsXBLPrototypeBinding* aBinding)
{ {
if (!mBindingTable) if (!mBindingTable) {
mBindingTable = new nsObjectHashtable(nsnull, nsnull, DeletePrototypeBinding, nsnull); mBindingTable = new nsObjectHashtable(nsnull, nsnull, DeletePrototypeBinding, nsnull);
if (!mBindingTable)
return NS_ERROR_OUT_OF_MEMORY;
NS_HOLD_JS_OBJECTS(this, nsXBLDocumentInfo);
}
const nsPromiseFlatCString& flat = PromiseFlatCString(aRef); const nsPromiseFlatCString& flat = PromiseFlatCString(aRef);
nsCStringKey key(flat.get()); nsCStringKey key(flat.get());

Просмотреть файл

@ -72,8 +72,8 @@ public:
// nsIScriptGlobalObjectOwner methods // nsIScriptGlobalObjectOwner methods
virtual nsIScriptGlobalObject* GetScriptGlobalObject(); virtual nsIScriptGlobalObject* GetScriptGlobalObject();
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXBLDocumentInfo, NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsXBLDocumentInfo,
nsIXBLDocumentInfo) nsIXBLDocumentInfo)
private: private:
nsCOMPtr<nsIDocument> mDocument; nsCOMPtr<nsIDocument> mDocument;

Просмотреть файл

@ -64,7 +64,7 @@ nsXBLInsertionPoint::Release()
return mRefCnt; return mRefCnt;
} }
NS_IMPL_CYCLE_COLLECTION_NATIVE_CLASS(nsXBLInsertionPoint) NS_IMPL_CYCLE_COLLECTION_CLASS(nsXBLInsertionPoint)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLInsertionPoint) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_NATIVE(nsXBLInsertionPoint)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mElements) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMARRAY(mElements)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDefaultContentTemplate) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDefaultContentTemplate)

Просмотреть файл

@ -200,7 +200,7 @@ nsXBLProtoImpl::CompilePrototypeMembers(nsXBLPrototypeBinding* aBinding)
} }
void void
nsXBLProtoImpl::Traverse(nsCycleCollectionTraversalCallback &cb) const nsXBLProtoImpl::Trace(TraceCallback aCallback, void *aClosure) const
{ {
// If we don't have a class object then we either didn't compile members // If we don't have a class object then we either didn't compile members
// or we only have fields, in both cases there are no cycles through our // or we only have fields, in both cases there are no cycles through our
@ -211,7 +211,7 @@ nsXBLProtoImpl::Traverse(nsCycleCollectionTraversalCallback &cb) const
nsXBLProtoImplMember *member; nsXBLProtoImplMember *member;
for (member = mMembers; member; member = member->GetNext()) { for (member = mMembers; member; member = member->GetNext()) {
member->Traverse(cb); member->Trace(aCallback, aClosure);
} }
} }
@ -254,6 +254,19 @@ nsXBLProtoImpl::ResolveAllFields(JSContext *cx, JSObject *obj) const
return PR_TRUE; return PR_TRUE;
} }
void
nsXBLProtoImpl::UndefineFields(JSContext *cx, JSObject *obj) const
{
JSAutoRequest ar(cx);
for (nsXBLProtoImplField* f = mFields; f; f = f->GetNext()) {
nsDependentString name(f->GetName());
jsval dummy;
::JS_DeleteUCProperty2(cx, obj,
reinterpret_cast<const jschar*>(name.get()),
name.Length(), &dummy);
}
}
void void
nsXBLProtoImpl::DestroyMembers(nsXBLProtoImplMember* aBrokenMember) nsXBLProtoImpl::DestroyMembers(nsXBLProtoImplMember* aBrokenMember)
{ {

Просмотреть файл

@ -90,7 +90,7 @@ public:
mFields = aFieldList; mFields = aFieldList;
} }
void Traverse(nsCycleCollectionTraversalCallback &cb) const; void Trace(TraceCallback aCallback, void *aClosure) const;
void Unlink(); void Unlink();
nsXBLProtoImplField* FindField(const nsString& aFieldName) const; nsXBLProtoImplField* FindField(const nsString& aFieldName) const;
@ -99,6 +99,10 @@ public:
// return means a JS exception was set. // return means a JS exception was set.
PRBool ResolveAllFields(JSContext *cx, JSObject *obj) const; PRBool ResolveAllFields(JSContext *cx, JSObject *obj) const;
// Undefine all our fields from object |obj| (which should be a
// JSObject for a bound element).
void UndefineFields(JSContext* cx, JSObject* obj) const;
PRBool CompiledMembers() const { PRBool CompiledMembers() const {
return mClassObject != nsnull; return mClassObject != nsnull;
} }

Просмотреть файл

@ -47,11 +47,11 @@
#include "nsIJSRuntimeService.h" #include "nsIJSRuntimeService.h"
#include "nsIServiceManager.h" #include "nsIServiceManager.h"
#include "nsReadableUtils.h" #include "nsReadableUtils.h"
#include "nsCycleCollectionParticipant.h"
class nsIScriptContext; class nsIScriptContext;
struct JSRuntime; struct JSRuntime;
class nsIJSRuntimeService; class nsIJSRuntimeService;
class nsCycleCollectionTraversalCallback;
struct nsXBLTextWithLineNumber struct nsXBLTextWithLineNumber
{ {
@ -114,7 +114,7 @@ public:
const nsCString& aClassStr, const nsCString& aClassStr,
void* aClassObject)=0; void* aClassObject)=0;
virtual void Traverse(nsCycleCollectionTraversalCallback &cb) const = 0; virtual void Trace(TraceCallback aCallback, void *aClosure) const = 0;
protected: protected:
friend class nsAutoGCRoot; friend class nsAutoGCRoot;

Просмотреть файл

@ -72,8 +72,6 @@ nsXBLProtoImplMethod::Destroy(PRBool aIsCompiled)
NS_PRECONDITION(aIsCompiled == mIsCompiled, NS_PRECONDITION(aIsCompiled == mIsCompiled,
"Incorrect aIsCompiled in nsXBLProtoImplMethod::Destroy"); "Incorrect aIsCompiled in nsXBLProtoImplMethod::Destroy");
if (aIsCompiled) { if (aIsCompiled) {
if (mJSMethodObject)
nsContentUtils::RemoveJSGCRoot(&mJSMethodObject);
mJSMethodObject = nsnull; mJSMethodObject = nsnull;
} }
else { else {
@ -263,8 +261,6 @@ nsXBLProtoImplMethod::CompileMember(nsIScriptContext* aContext, const nsCString&
if (methodObject) { if (methodObject) {
// Root the compiled prototype script object. // Root the compiled prototype script object.
rv = nsContentUtils::AddJSGCRoot(&mJSMethodObject,
"nsXBLProtoImplMethod::mJSMethodObject");
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
mJSMethodObject = nsnull; mJSMethodObject = nsnull;
} }
@ -277,11 +273,13 @@ nsXBLProtoImplMethod::CompileMember(nsIScriptContext* aContext, const nsCString&
} }
void void
nsXBLProtoImplMethod::Traverse(nsCycleCollectionTraversalCallback &cb) const nsXBLProtoImplMethod::Trace(TraceCallback aCallback, void *aClosure) const
{ {
NS_ASSERTION(mIsCompiled, "Shouldn't traverse uncompiled method"); NS_ASSERTION(mIsCompiled, "Shouldn't traverse uncompiled method");
cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, mJSMethodObject); if (mJSMethodObject) {
aCallback(nsIProgrammingLanguage::JAVASCRIPT, mJSMethodObject, aClosure);
}
} }
nsresult nsresult

Просмотреть файл

@ -129,7 +129,7 @@ public:
const nsCString& aClassStr, const nsCString& aClassStr,
void* aClassObject); void* aClassObject);
virtual void Traverse(nsCycleCollectionTraversalCallback &cb) const; virtual void Trace(TraceCallback aCallback, void *aClosure) const;
protected: protected:
union { union {

Просмотреть файл

@ -87,14 +87,14 @@ nsXBLProtoImplProperty::Destroy(PRBool aIsCompiled)
"Incorrect aIsCompiled in nsXBLProtoImplProperty::Destroy"); "Incorrect aIsCompiled in nsXBLProtoImplProperty::Destroy");
if ((mJSAttributes & JSPROP_GETTER) && mJSGetterObject) { if ((mJSAttributes & JSPROP_GETTER) && mJSGetterObject) {
nsContentUtils::RemoveJSGCRoot(&mJSGetterObject); mJSGetterObject = nsnull;
} }
else { else {
delete mGetterText; delete mGetterText;
} }
if ((mJSAttributes & JSPROP_SETTER) && mJSSetterObject) { if ((mJSAttributes & JSPROP_SETTER) && mJSSetterObject) {
nsContentUtils::RemoveJSGCRoot(&mJSSetterObject); mJSSetterObject = nsnull;
} }
else { else {
delete mSetterText; delete mSetterText;
@ -268,9 +268,6 @@ nsXBLProtoImplProperty::CompileMember(nsIScriptContext* aContext, const nsCStrin
if (mJSGetterObject && NS_SUCCEEDED(rv)) { if (mJSGetterObject && NS_SUCCEEDED(rv)) {
mJSAttributes |= JSPROP_GETTER | JSPROP_SHARED; mJSAttributes |= JSPROP_GETTER | JSPROP_SHARED;
// Root the compiled prototype script object.
rv = nsContentUtils::AddJSGCRoot(&mJSGetterObject,
"nsXBLProtoImplProperty::mJSGetterObject");
} }
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
mJSGetterObject = nsnull; mJSGetterObject = nsnull;
@ -320,9 +317,6 @@ nsXBLProtoImplProperty::CompileMember(nsIScriptContext* aContext, const nsCStrin
if (mJSSetterObject && NS_SUCCEEDED(rv)) { if (mJSSetterObject && NS_SUCCEEDED(rv)) {
mJSAttributes |= JSPROP_SETTER | JSPROP_SHARED; mJSAttributes |= JSPROP_SETTER | JSPROP_SHARED;
// Root the compiled prototype script object.
rv = nsContentUtils::AddJSGCRoot(&mJSSetterObject,
"nsXBLProtoImplProperty::mJSSetterObject");
} }
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
mJSSetterObject = nsnull; mJSSetterObject = nsnull;
@ -345,15 +339,15 @@ nsXBLProtoImplProperty::CompileMember(nsIScriptContext* aContext, const nsCStrin
} }
void void
nsXBLProtoImplProperty::Traverse(nsCycleCollectionTraversalCallback &cb) const nsXBLProtoImplProperty::Trace(TraceCallback aCallback, void *aClosure) const
{ {
NS_ASSERTION(mIsCompiled, "Shouldn't traverse uncompiled method"); NS_ASSERTION(mIsCompiled, "Shouldn't traverse uncompiled method");
if (mJSAttributes & JSPROP_GETTER) { if ((mJSAttributes & JSPROP_GETTER) && mJSGetterObject) {
cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, mJSGetterObject); aCallback(nsIProgrammingLanguage::JAVASCRIPT, mJSGetterObject, aClosure);
} }
if (mJSAttributes & JSPROP_SETTER) { if ((mJSAttributes & JSPROP_SETTER) && mJSSetterObject) {
cb.NoteScriptChild(nsIProgrammingLanguage::JAVASCRIPT, mJSSetterObject); aCallback(nsIProgrammingLanguage::JAVASCRIPT, mJSSetterObject, aClosure);
} }
} }

Просмотреть файл

@ -72,7 +72,7 @@ public:
const nsCString& aClassStr, const nsCString& aClassStr,
void* aClassObject); void* aClassObject);
virtual void Traverse(nsCycleCollectionTraversalCallback &cb) const; virtual void Trace(TraceCallback aCallback, void *aClosure) const;
protected: protected:
union { union {

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше