зеркало из https://github.com/mozilla/gecko-dev.git
Merge from cvs-trunk-mirror
--HG-- rename : js/src/jsdtoa.c => js/src/jsdtoa.cpp
This commit is contained in:
Коммит
842500992f
|
@ -150,6 +150,7 @@ pref("extensions.update.interval", 86400); // Check for updates to Extensions a
|
|||
// Non-symmetric (not shared by extensions) extension-specific [update] preferences
|
||||
pref("extensions.getMoreExtensionsURL", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/%APP%/%VERSION%/extensions/");
|
||||
pref("extensions.getMoreThemesURL", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/%APP%/%VERSION%/themes/");
|
||||
pref("extensions.getMorePluginsURL", "https://%LOCALE%.add-ons.mozilla.com/%LOCALE%/%APP%/%VERSION%/plugins/");
|
||||
pref("extensions.dss.enabled", false); // Dynamic Skin Switching
|
||||
pref("extensions.dss.switchPending", false); // Non-dynamic switch pending after next
|
||||
// restart.
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
# the Initial Developer. All Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
# Ehsan Akhgari <ehsan.akhgari@gmail.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -204,7 +205,8 @@
|
|||
<menuseparator/>
|
||||
<menuitem label="&viewFrameSourceCmd.label;"
|
||||
accesskey="&viewFrameSourceCmd.accesskey;"
|
||||
oncommand="gContextMenu.viewFrameSource();"/>
|
||||
oncommand="gContextMenu.viewFrameSource();"
|
||||
observes="isFrameImage"/>
|
||||
<menuitem label="&viewFrameInfoCmd.label;"
|
||||
accesskey="&viewFrameInfoCmd.accesskey;"
|
||||
oncommand="gContextMenu.viewFrameInfo();"/>
|
||||
|
@ -214,15 +216,18 @@
|
|||
<menuitem id="context-viewpartialsource-selection"
|
||||
label="&viewPartialSourceForSelectionCmd.label;"
|
||||
accesskey="&viewPartialSourceCmd.accesskey;"
|
||||
oncommand="gContextMenu.viewPartialSource('selection');"/>
|
||||
oncommand="gContextMenu.viewPartialSource('selection');"
|
||||
observes="isImage"/>
|
||||
<menuitem id="context-viewpartialsource-mathml"
|
||||
label="&viewPartialSourceForMathMLCmd.label;"
|
||||
accesskey="&viewPartialSourceCmd.accesskey;"
|
||||
oncommand="gContextMenu.viewPartialSource('mathml');"/>
|
||||
oncommand="gContextMenu.viewPartialSource('mathml');"
|
||||
observes="isImage"/>
|
||||
<menuitem id="context-viewsource"
|
||||
label="&viewPageSourceCmd.label;"
|
||||
accesskey="&viewPageSourceCmd.accesskey;"
|
||||
oncommand="BrowserViewSourceOfDocument(content.document);"/>
|
||||
oncommand="BrowserViewSourceOfDocument(content.document);"
|
||||
observes="isImage"/>
|
||||
<menuitem id="context-viewinfo"
|
||||
label="&viewPageInfoCmd.label;"
|
||||
accesskey="&viewPageInfoCmd.accesskey;"
|
||||
|
|
|
@ -387,10 +387,10 @@ var BookmarksEventHandler = {
|
|||
var view = PlacesUtils.getViewForNode(target);
|
||||
if (PlacesUtils.nodeIsFolder(view.selectedNode)) {
|
||||
// Don't open the root folder in tabs when the empty area on the toolbar
|
||||
// is middle-clicked or when a non-bookmark item in a bookmarks menupopup
|
||||
// middle-clicked.
|
||||
// is middle-clicked or when a non-bookmark item except for Open in Tabs)
|
||||
// in a bookmarks menupopup is middle-clicked.
|
||||
if (!view.controller.rootNodeIsSelected())
|
||||
view.controller.openLinksInTabs();
|
||||
view.controller.openSelectionInTabs(aEvent);
|
||||
}
|
||||
else
|
||||
this.onCommand(aEvent);
|
||||
|
@ -430,12 +430,10 @@ var BookmarksEventHandler = {
|
|||
// load all the menuitems in tabs.
|
||||
|
||||
var target = aEvent.originalTarget;
|
||||
if (target.hasAttribute("openInTabs"))
|
||||
PlacesUtils.getViewForNode(target).controller.openLinksInTabs();
|
||||
else if (target.hasAttribute("siteURI"))
|
||||
if (target.hasAttribute("siteURI"))
|
||||
openUILink(target.getAttribute("siteURI"), aEvent);
|
||||
// If this is a normal bookmark, just load the bookmark's URI.
|
||||
else
|
||||
else if (!target.hasAttribute("openInTabs"))
|
||||
PlacesUtils.getViewForNode(target)
|
||||
.controller
|
||||
.openSelectedNodeWithEvent(aEvent);
|
||||
|
@ -498,6 +496,9 @@ var BookmarksEventHandler = {
|
|||
if (hasMultipleEntries) {
|
||||
var openInTabs = document.createElement("menuitem");
|
||||
openInTabs.setAttribute("openInTabs", "true");
|
||||
openInTabs.setAttribute("onclick", "checkForMiddleClick(this, event)");
|
||||
openInTabs.setAttribute("oncommand",
|
||||
"PlacesUtils.openContainerNodeInTabs(this.parentNode.getResultNode(), event);");
|
||||
openInTabs.setAttribute("label",
|
||||
gNavigatorBundle.getString("menuOpenAllInTabs.label"));
|
||||
target.appendChild(openInTabs);
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
# Ben Goodger <ben@bengoodger.com> (v2.0)
|
||||
# Blake Ross <blakeross@telocity.com>
|
||||
# Shawn Wilsher <me@shawnwilsher.com>
|
||||
# Ehsan Akhgari <ehsan.akhgari@gmail.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -155,6 +156,7 @@
|
|||
oncommand="gPopupBlockerObserver.dontShowMessage();"/>
|
||||
<broadcaster id="blockedPopupsSeparator"/>
|
||||
<broadcaster id="isImage"/>
|
||||
<broadcaster id="isFrameImage"/>
|
||||
</broadcasterset>
|
||||
|
||||
<keyset id="mainKeyset">
|
||||
|
|
|
@ -238,7 +238,7 @@ function SetClickAndHoldHandlers()
|
|||
false);
|
||||
aElm.addEventListener("mouseout",
|
||||
MayStopClickAndHoldTimer,
|
||||
false);
|
||||
false);
|
||||
|
||||
// don't propagate onclick and oncommand events after
|
||||
// click-and-hold opened the drop-down menu
|
||||
|
@ -3183,6 +3183,20 @@ var FullScreen =
|
|||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if |aMimeType| is text-based, false otherwise.
|
||||
*
|
||||
* @param aMimeType
|
||||
* The MIME type to check.
|
||||
*/
|
||||
function mimeTypeIsTextBased(aMimeType)
|
||||
{
|
||||
return /^text\/|\+xml$/.test(aMimeType) ||
|
||||
aMimeType == "application/x-javascript" ||
|
||||
aMimeType == "application/xml" ||
|
||||
aMimeType == "mozilla.application/cached-xul";
|
||||
}
|
||||
|
||||
function nsBrowserStatusHandler()
|
||||
{
|
||||
this.init();
|
||||
|
@ -3281,14 +3295,6 @@ nsBrowserStatusHandler.prototype =
|
|||
}
|
||||
},
|
||||
|
||||
mimeTypeIsTextBased : function(contentType)
|
||||
{
|
||||
return /^text\/|\+xml$/.test(contentType) ||
|
||||
contentType == "application/x-javascript" ||
|
||||
contentType == "application/xml" ||
|
||||
contentType == "mozilla.application/cached-xul";
|
||||
},
|
||||
|
||||
onLinkIconAvailable : function(aBrowser)
|
||||
{
|
||||
if (gProxyFavIcon &&
|
||||
|
@ -3408,7 +3414,7 @@ nsBrowserStatusHandler.prototype =
|
|||
this.setDefaultStatus(msg);
|
||||
|
||||
// Disable menu entries for images, enable otherwise
|
||||
if (content.document && this.mimeTypeIsTextBased(content.document.contentType))
|
||||
if (content.document && mimeTypeIsTextBased(content.document.contentType))
|
||||
this.isImage.removeAttribute('disabled');
|
||||
else
|
||||
this.isImage.setAttribute('disabled', 'true');
|
||||
|
@ -3471,13 +3477,23 @@ nsBrowserStatusHandler.prototype =
|
|||
if (newIndexOfHash != -1)
|
||||
newSpec = newSpec.substr(0, newSpec.indexOf("#"));
|
||||
if (newSpec != oldSpec) {
|
||||
gBrowser.getNotificationBox(selectedBrowser).removeAllNotifications(true);
|
||||
// Remove all the notifications, except for those which want to
|
||||
// persist across the first location change.
|
||||
var nBox = gBrowser.getNotificationBox(selectedBrowser);
|
||||
for (var n = nBox.allNotifications.length - 1; n >= 0; n--) {
|
||||
var notify = nBox.allNotifications[n];
|
||||
if (notify.ignoreFirstLocationChange)
|
||||
notify.ignoreFirstLocationChange = false;
|
||||
else if (!notify.ignoreLocationChangeTimeout ||
|
||||
(Date.now() / 1000) > notify.ignoreLocationChangeTimeout)
|
||||
nBox.removeNotification(notify);
|
||||
}
|
||||
}
|
||||
}
|
||||
selectedBrowser.lastURI = aLocationURI;
|
||||
|
||||
// Disable menu entries for images, enable otherwise
|
||||
if (content.document && this.mimeTypeIsTextBased(content.document.contentType))
|
||||
if (content.document && mimeTypeIsTextBased(content.document.contentType))
|
||||
this.isImage.removeAttribute('disabled');
|
||||
else
|
||||
this.isImage.setAttribute('disabled', 'true');
|
||||
|
@ -5370,6 +5386,9 @@ HistoryMenu.populateUndoSubmenu = function PHM_populateUndoSubmenu() {
|
|||
for (var i = 0; i < undoItems.length; i++) {
|
||||
var m = undoPopup.appendChild(document.createElement("menuitem"));
|
||||
m.setAttribute("label", undoItems[i].title);
|
||||
if (undoItems[i].image)
|
||||
m.setAttribute("image", undoItems[i].image);
|
||||
m.setAttribute("class", "menuitem-iconic bookmark-item");
|
||||
m.setAttribute("value", i);
|
||||
m.setAttribute("oncommand", "undoCloseTab(" + i + ");");
|
||||
m.addEventListener("click", undoCloseMiddleClick, false);
|
||||
|
|
|
@ -40,6 +40,7 @@
|
|||
# Michael Ventnor <ventnors_dogs234@yahoo.com.au>
|
||||
# Simon Bünzli <zeniko@gmail.com>
|
||||
# Gijs Kruitbosch <gijskruitbosch@gmail.com>
|
||||
# Ehsan Akhgari <ehsan.akhgari@gmail.com>
|
||||
#
|
||||
# Alternatively, the contents of this file may be used under the terms of
|
||||
# either the GNU General Public License Version 2 or later (the "GPL"), or
|
||||
|
@ -59,6 +60,7 @@ function nsContextMenu(aXulMenu, aBrowser) {
|
|||
this.target = null;
|
||||
this.browser = null;
|
||||
this.menu = null;
|
||||
this.isFrameImage = false;
|
||||
this.onTextInput = false;
|
||||
this.onKeywordField = false;
|
||||
this.onImage = false;
|
||||
|
@ -97,6 +99,8 @@ nsContextMenu.prototype = {
|
|||
this.menu = aPopup;
|
||||
this.browser = aBrowser;
|
||||
|
||||
this.isFrameImage = document.getElementById("isFrameImage");
|
||||
|
||||
// Get contextual info.
|
||||
this.setTarget(document.popupNode, document.popupRangeParent,
|
||||
document.popupRangeOffset);
|
||||
|
@ -213,6 +217,14 @@ nsContextMenu.prototype = {
|
|||
this.showItem("frame", this.inFrame);
|
||||
this.showItem("frame-sep", this.inFrame);
|
||||
|
||||
// Hide menu entries for images, show otherwise
|
||||
if (this.inFrame) {
|
||||
if (mimeTypeIsTextBased(this.target.ownerDocument.contentType))
|
||||
this.isFrameImage.removeAttribute('hidden');
|
||||
else
|
||||
this.isFrameImage.setAttribute('hidden', 'true');
|
||||
}
|
||||
|
||||
// BiDi UI
|
||||
this.showItem("context-sep-bidi", top.gBidiUI);
|
||||
this.showItem("context-bidi-text-direction-toggle",
|
||||
|
|
|
@ -338,7 +338,7 @@ function loadPageInfo()
|
|||
onLoadPermission();
|
||||
|
||||
/* Call registered overlay init functions */
|
||||
onLoadRegistry.map(function(func) { func(); });
|
||||
onLoadRegistry.forEach(function(func) { func(); });
|
||||
}
|
||||
|
||||
function resetPageInfo()
|
||||
|
@ -363,7 +363,7 @@ function resetPageInfo()
|
|||
feedListbox.removeChild(feedListbox.firstChild);
|
||||
|
||||
/* Call registered overlay reset functions */
|
||||
onResetRegistry.map(function(func) { func(); });
|
||||
onResetRegistry.forEach(function(func) { func(); });
|
||||
|
||||
/* And let's rebuild the data */
|
||||
loadPageInfo();
|
||||
|
@ -378,7 +378,7 @@ function onUnloadPageInfo()
|
|||
}
|
||||
|
||||
/* Call registered overlay unload functions */
|
||||
onUnloadRegistry.map(function(func) { func(); });
|
||||
onUnloadRegistry.forEach(function(func) { func(); });
|
||||
}
|
||||
|
||||
function doHelpButton()
|
||||
|
@ -524,13 +524,13 @@ function processFrames()
|
|||
{
|
||||
if (gFrameList.length) {
|
||||
var doc = gFrameList[0];
|
||||
onProcessFrame.map(function(func) { func(doc); });
|
||||
onProcessFrame.forEach(function(func) { func(doc); });
|
||||
var iterator = doc.createTreeWalker(doc, NodeFilter.SHOW_ELEMENT, grabAll, true);
|
||||
gFrameList.shift();
|
||||
setTimeout(doGrab, 16, iterator);
|
||||
}
|
||||
else
|
||||
onFinished.map(function(func) { func(); });
|
||||
onFinished.forEach(function(func) { func(); });
|
||||
}
|
||||
|
||||
function doGrab(iterator)
|
||||
|
@ -629,7 +629,7 @@ function grabAll(elem)
|
|||
else if (elem instanceof HTMLEmbedElement)
|
||||
addImage(elem.src, gStrings.mediaEmbed, "", elem, false);
|
||||
|
||||
onProcessElement.map(function(func) { func(elem); });
|
||||
onProcessElement.forEach(function(func) { func(elem); });
|
||||
|
||||
return NodeFilter.FILTER_ACCEPT;
|
||||
}
|
||||
|
|
|
@ -157,8 +157,7 @@ Sanitizer.prototype = {
|
|||
var searchBar = windows.getNext().document.getElementById("searchbar");
|
||||
if (searchBar) {
|
||||
searchBar.value = "";
|
||||
searchBar.textbox.editor.enableUndo(false);
|
||||
searchBar.textbox.editor.enableUndo(true);
|
||||
searchBar.textbox.editor.transactionManager.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -518,13 +518,32 @@
|
|||
}
|
||||
// completely ignore right-clicks
|
||||
else if (aEvent.button != 2) {
|
||||
var url = controller.getValueAt(this.tree.view.selection.currentIndex);
|
||||
if (gURLBar && this.mInput == gURLBar) {
|
||||
// handle address bar click
|
||||
var url = controller.getValueAt(this.tree.view.selection.currentIndex);
|
||||
|
||||
// close the autocomplete popup and revert the entered address
|
||||
this.closePopup();
|
||||
controller.handleEscape();
|
||||
// respect the usual clicking subtleties
|
||||
openUILink(url, aEvent);
|
||||
// close the autocomplete popup and revert the entered address
|
||||
this.closePopup();
|
||||
controller.handleEscape();
|
||||
// respect the usual clicking subtleties
|
||||
openUILink(url, aEvent);
|
||||
}
|
||||
else if (this.mInput._getParentSearchbar) {
|
||||
// handle search bar click
|
||||
var search = controller.getValueAt(this.tree.view.selection.currentIndex);
|
||||
var textbox = this.mInput;
|
||||
|
||||
// close the autocomplete popup and copy the selected value to the search box
|
||||
this.closePopup();
|
||||
textbox.value = search;
|
||||
// open the search results according to the clicking subtlety
|
||||
var where = whereToOpenLink(aEvent, false, true);
|
||||
textbox._getParentSearchbar().doSearch(search, where);
|
||||
}
|
||||
else {
|
||||
// everybody else (i.e. browser content) gets unmodified behavior
|
||||
controller.handleEnter();
|
||||
}
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
|
|
@ -247,8 +247,9 @@ FeedConverter.prototype = {
|
|||
*/
|
||||
onDataAvailable: function FC_onDataAvailable(request, context, inputStream,
|
||||
sourceOffset, count) {
|
||||
this._processor.onDataAvailable(request, context, inputStream,
|
||||
sourceOffset, count);
|
||||
if (this._processor)
|
||||
this._processor.onDataAvailable(request, context, inputStream,
|
||||
sourceOffset, count);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -291,7 +292,8 @@ FeedConverter.prototype = {
|
|||
* See nsIRequestObserver.idl
|
||||
*/
|
||||
onStopRequest: function FC_onStopReqeust(request, context, status) {
|
||||
this._processor.onStopRequest(request, context, status);
|
||||
if (this._processor)
|
||||
this._processor.onStopRequest(request, context, status);
|
||||
},
|
||||
|
||||
/**
|
||||
|
|
|
@ -119,34 +119,6 @@ PlacesController.prototype = {
|
|||
case "placesCmd_open:window":
|
||||
case "placesCmd_open:tab":
|
||||
return this._view.selectedURINode;
|
||||
case "placesCmd_open:tabs":
|
||||
// We can open multiple links if the current selection is either:
|
||||
// a) a single folder which contains at least one link
|
||||
// b) multiple links
|
||||
var node = this._view.selectedNode;
|
||||
if (!node)
|
||||
return false;
|
||||
|
||||
if (this._view.hasSingleSelection && PlacesUtils.nodeIsFolder(node)) {
|
||||
var contents = PlacesUtils.getFolderContents(node.itemId, false, false).root;
|
||||
for (var i = 0; i < contents.childCount; ++i) {
|
||||
var child = contents.getChild(i);
|
||||
if (PlacesUtils.nodeIsURI(child))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
var oneLinkIsSelected = false;
|
||||
var nodes = this._view.getSelectionNodes();
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
if (PlacesUtils.nodeIsURI(nodes[i])) {
|
||||
if (oneLinkIsSelected)
|
||||
return true;
|
||||
oneLinkIsSelected = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case "placesCmd_new:folder":
|
||||
case "placesCmd_new:livemark":
|
||||
return this._canInsert() &&
|
||||
|
@ -275,9 +247,6 @@ PlacesController.prototype = {
|
|||
case "placesCmd_open:tab":
|
||||
this.openSelectedNodeIn("tab");
|
||||
break;
|
||||
case "placesCmd_open:tabs":
|
||||
this.openLinksInTabs();
|
||||
break;
|
||||
case "placesCmd_new:folder":
|
||||
this.newItem("folder");
|
||||
break;
|
||||
|
@ -670,6 +639,21 @@ PlacesController.prototype = {
|
|||
}
|
||||
}
|
||||
|
||||
// Set Open Folder/Links In Tabs items enabled state if they're visible
|
||||
if (anyVisible) {
|
||||
var openContainerInTabsItem = document.getElementById("placesContext_openContainer:tabs");
|
||||
if (!openContainerInTabsItem.hidden) {
|
||||
openContainerInTabsItem.disabled =
|
||||
PlacesUtils.getURLsForContainerNode(this._view.selectedNode)
|
||||
.length == 0;
|
||||
}
|
||||
else {
|
||||
// see selectiontype rule in the overlay
|
||||
var openLinksInTabsItem = document.getElementById("placesContext_openLinks:tabs");
|
||||
openLinksInTabsItem.disabled = openLinksInTabsItem.hidden;
|
||||
}
|
||||
}
|
||||
|
||||
return anyVisible;
|
||||
},
|
||||
|
||||
|
@ -829,103 +813,13 @@ PlacesController.prototype = {
|
|||
|
||||
/**
|
||||
* Opens the links in the selected folder, or the selected links in new tabs.
|
||||
* XXXben this needs to handle the case when there are no open browser windows
|
||||
* XXXben this function is really long, should be split apart. The codepaths
|
||||
* seem different between load folder in tabs and load selection in
|
||||
* tabs, too.
|
||||
* See: https://bugzilla.mozilla.org/show_bug.cgi?id=331908
|
||||
*/
|
||||
openLinksInTabs: function PC_openLinksInTabs() {
|
||||
openSelectionInTabs: function PC_openLinksInTabs(aEvent) {
|
||||
var node = this._view.selectedNode;
|
||||
if (this._view.hasSingleSelection && PlacesUtils.nodeIsFolder(node)) {
|
||||
// Check prefs to see whether to open over existing tabs.
|
||||
var doReplace = getBoolPref("browser.tabs.loadFolderAndReplace");
|
||||
var loadInBackground = getBoolPref("browser.tabs.loadBookmarksInBackground");
|
||||
// Get the start index to open tabs at
|
||||
|
||||
// XXX todo: no-browser-window-case
|
||||
var browserWindow = getTopWin();
|
||||
var browser = browserWindow.getBrowser();
|
||||
var tabPanels = browser.browsers;
|
||||
var tabCount = tabPanels.length;
|
||||
var firstIndex;
|
||||
// If browser.tabs.loadFolderAndReplace pref is set, load over all the
|
||||
// tabs starting with the first one.
|
||||
if (doReplace)
|
||||
firstIndex = 0;
|
||||
// If the pref is not set, only load over the blank tabs at the end, if any.
|
||||
else {
|
||||
for (firstIndex = tabCount - 1; firstIndex >= 0; --firstIndex) {
|
||||
var br = browser.browsers[firstIndex];
|
||||
if (br.currentURI.spec != "about:blank" ||
|
||||
br.webProgress.isLoadingDocument)
|
||||
break;
|
||||
}
|
||||
++firstIndex;
|
||||
}
|
||||
|
||||
// Open each uri in the folder in a tab.
|
||||
var index = firstIndex;
|
||||
var urlsToOpen = [];
|
||||
var contents = PlacesUtils.getFolderContents(node.itemId, false, false).root;
|
||||
for (var i = 0; i < contents.childCount; ++i) {
|
||||
var child = contents.getChild(i);
|
||||
if (PlacesUtils.nodeIsURI(child))
|
||||
urlsToOpen.push(child.uri);
|
||||
}
|
||||
|
||||
if (!this._confirmOpenTabs(urlsToOpen.length))
|
||||
return;
|
||||
|
||||
for (var i = 0; i < urlsToOpen.length; ++i) {
|
||||
if (index < tabCount)
|
||||
tabPanels[index].loadURI(urlsToOpen[i]);
|
||||
// Otherwise, create a new tab to load the uri into.
|
||||
else
|
||||
browser.addTab(urlsToOpen[i]);
|
||||
++index;
|
||||
}
|
||||
|
||||
// If no bookmarks were loaded, just bail.
|
||||
if (index == firstIndex)
|
||||
return;
|
||||
|
||||
// focus the first tab if prefs say to
|
||||
if (!loadInBackground || doReplace) {
|
||||
// Select the first tab in the group.
|
||||
// Set newly selected tab after quick timeout, otherwise hideous focus problems
|
||||
// can occur because new presshell is not ready to handle events
|
||||
function selectNewForegroundTab(browser, tab) {
|
||||
browser.selectedTab = tab;
|
||||
}
|
||||
var tabs = browser.mTabContainer.childNodes;
|
||||
setTimeout(selectNewForegroundTab, 0, browser, tabs[firstIndex]);
|
||||
}
|
||||
|
||||
// Close any remaining open tabs that are left over.
|
||||
// (Always skipped when we append tabs)
|
||||
for (var i = tabCount - 1; i >= index; --i)
|
||||
browser.removeTab(tabs[i]);
|
||||
|
||||
// and focus the content
|
||||
browserWindow.content.focus();
|
||||
}
|
||||
else {
|
||||
var urlsToOpen = [];
|
||||
var nodes = this._view.getSelectionNodes();
|
||||
|
||||
for (var i = 0; i < nodes.length; ++i) {
|
||||
if (PlacesUtils.nodeIsURI(nodes[i]))
|
||||
urlsToOpen.push(nodes[i].uri);
|
||||
}
|
||||
|
||||
if (!this._confirmOpenTabs(urlsToOpen.length))
|
||||
return;
|
||||
|
||||
for (var i = 0; i < urlsToOpen.length; ++i) {
|
||||
getTopWin().openNewTabWith(urlsToOpen[i], null, null);
|
||||
}
|
||||
}
|
||||
if (this._view.hasSingleSelection && PlacesUtils.nodeIsContainer(node))
|
||||
PlacesUtils.openContainerNodeInTabs(this._view.selectedNode, aEvent);
|
||||
else
|
||||
PlacesUtils.openURINodesInTabs(this._view.getSelectionNodes(), aEvent);
|
||||
},
|
||||
|
||||
/**
|
||||
|
@ -1488,7 +1382,6 @@ function goUpdatePlacesCommands() {
|
|||
goUpdateCommand("placesCmd_open");
|
||||
goUpdateCommand("placesCmd_open:window");
|
||||
goUpdateCommand("placesCmd_open:tab");
|
||||
goUpdateCommand("placesCmd_open:tabs");
|
||||
goUpdateCommand("placesCmd_new:folder");
|
||||
goUpdateCommand("placesCmd_new:bookmark");
|
||||
goUpdateCommand("placesCmd_new:livemark");
|
||||
|
|
|
@ -192,10 +192,6 @@ var PlacesOrganizer = {
|
|||
// Items are only excluded on the left pane
|
||||
var options = node.queryOptions.clone();
|
||||
options.excludeItems = false;
|
||||
// Unset excludeQueries so incremental update is enabled for the content
|
||||
// pane.
|
||||
// XXXmano: remove that once we unset excludeQueries for the left pane.
|
||||
options.excludeQueries = false;
|
||||
|
||||
this._content.load(queries,
|
||||
OptionsFilter.filter(queries, options, null));
|
||||
|
@ -343,6 +339,57 @@ var PlacesOrganizer = {
|
|||
}
|
||||
gEditItemOverlay.uninitPanel();
|
||||
deck.selectedIndex = 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* Save the current search (or advanced query) to the bookmarks root.
|
||||
*/
|
||||
saveSearch: function PP_saveSearch() {
|
||||
// Get the place: uri for the query.
|
||||
// If the advanced query builder is showing, use that.
|
||||
var queries = [];
|
||||
var options = this.getCurrentOptions();
|
||||
options.excludeQueries = true;
|
||||
var advancedSearch = document.getElementById("advancedSearch");
|
||||
if (!advancedSearch.collapsed) {
|
||||
queries = PlacesQueryBuilder.queries;
|
||||
}
|
||||
// If not, use the value of the search box.
|
||||
else if (PlacesSearchBox.value && PlacesSearchBox.value.length > 0) {
|
||||
var query = PlacesUtils.history.getNewQuery();
|
||||
query.searchTerms = PlacesSearchBox.value;
|
||||
queries.push(query);
|
||||
}
|
||||
// if there is no query, do nothing.
|
||||
else {
|
||||
// XXX should probably have a dialog here to explain that the user needs to search first.
|
||||
return;
|
||||
}
|
||||
var placeSpec = PlacesUtils.history.queriesToQueryString(queries,
|
||||
queries.length,
|
||||
options);
|
||||
var placeURI = IO.newURI(placeSpec);
|
||||
|
||||
// Prompt the user for a name for the query.
|
||||
// XXX - using prompt service for now; will need to make
|
||||
// a real dialog and localize when we're sure this is the UI we want.
|
||||
var title = PlacesUtils.getString("saveSearch.title");
|
||||
var inputLabel = PlacesUtils.getString("saveSearch.inputLabel");
|
||||
var defaultText = PlacesUtils.getString("saveSearch.defaultText");
|
||||
|
||||
var prompts = Cc["@mozilla.org/embedcomp/prompt-service;1"].
|
||||
getService(Ci.nsIPromptService);
|
||||
var check = {value: false};
|
||||
var input = {value: defaultText};
|
||||
var save = prompts.prompt(null, title, inputLabel, input, null, check);
|
||||
|
||||
// Don't add the query if the user cancels or clears the seach name.
|
||||
if (!save || input.value == "")
|
||||
return;
|
||||
|
||||
// Add the place: uri as a bookmark under the places root.
|
||||
var txn = PlacesUtils.ptm.createItem(placeURI, PlacesUtils.bookmarks.bookmarksRoot, PlacesUtils.bookmarks.DEFAULT_INDEX, input.value);
|
||||
PlacesUtils.ptm.commitTransaction(txn);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -384,8 +431,10 @@ var PlacesSearchBox = {
|
|||
PO.setHeaderText(PO.HEADER_TYPE_SEARCH, filterString);
|
||||
break;
|
||||
case "bookmarks":
|
||||
if (filterString != "")
|
||||
if (filterString) {
|
||||
content.applyFilter(filterString, true);
|
||||
PO.setHeaderText(PO.HEADER_TYPE_SEARCH, filterString);
|
||||
}
|
||||
else
|
||||
PlacesOrganizer.onPlaceSelected();
|
||||
break;
|
||||
|
@ -445,6 +494,8 @@ var PlacesSearchBox = {
|
|||
},
|
||||
set filterCollection(collectionName) {
|
||||
this.searchFilter.setAttribute("collection", collectionName);
|
||||
if (this.searchFilter.value)
|
||||
return; // don't overwrite pre-existing search terms
|
||||
var newGrayText = null;
|
||||
if (collectionName == "collection")
|
||||
newGrayText = PlacesOrganizer._places.selectedNode.title;
|
||||
|
@ -484,6 +535,9 @@ var PlacesSearchBox = {
|
|||
*/
|
||||
var PlacesQueryBuilder = {
|
||||
|
||||
queries: [],
|
||||
queryOptions: null,
|
||||
|
||||
_numRows: 0,
|
||||
|
||||
/**
|
||||
|
@ -906,7 +960,7 @@ var PlacesQueryBuilder = {
|
|||
doSearch: function PQB_doSearch() {
|
||||
// Create the individual queries.
|
||||
var queryType = document.getElementById("advancedSearchType").selectedItem.value;
|
||||
var queries = [];
|
||||
this.queries = [];
|
||||
if (queryType == "and")
|
||||
queries.push(PlacesUtils.history.getNewQuery());
|
||||
var updated = 0;
|
||||
|
@ -922,7 +976,7 @@ var PlacesQueryBuilder = {
|
|||
// If they're being OR-ed, add a separate query for each row.
|
||||
var query;
|
||||
if (queryType == "and")
|
||||
query = queries[0];
|
||||
query = this.queries[0];
|
||||
else
|
||||
query = PlacesUtils.history.getNewQuery();
|
||||
|
||||
|
@ -930,15 +984,15 @@ var PlacesQueryBuilder = {
|
|||
this._queryBuilders[querySubject](query, prefix);
|
||||
|
||||
if (queryType == "or")
|
||||
queries.push(query);
|
||||
this.queries.push(query);
|
||||
|
||||
++updated;
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure we're getting uri results, not visits
|
||||
var options = PlacesOrganizer.getCurrentOptions();
|
||||
options.resultType = options.RESULT_TYPE_URI;
|
||||
this.options = PlacesOrganizer.getCurrentOptions();
|
||||
this.options.resultType = options.RESULT_TYPE_URI;
|
||||
|
||||
// XXXben - find some public way of doing this!
|
||||
PlacesOrganizer._content.load(queries,
|
||||
|
|
|
@ -86,7 +86,8 @@
|
|||
oncommand="PlacesOrganizer.exportBookmarks();"/>
|
||||
<command id="OrganizerCommand_import"
|
||||
oncommand="PlacesOrganizer.importBookmarks();"/>
|
||||
<command id="OrganizerCommand_search:save"/>
|
||||
<command id="OrganizerCommand_search:save"
|
||||
oncommand="PlacesOrganizer.saveSearch();"/>
|
||||
<command id="OrganizerCommand_search:moreCriteria"
|
||||
oncommand="PlacesQueryBuilder.addRow();"/>
|
||||
</commandset>
|
||||
|
|
|
@ -71,8 +71,7 @@
|
|||
oncommand="goDoCommand('placesCmd_open:window');"/>
|
||||
<command id="placesCmd_open:tab"
|
||||
oncommand="goDoCommand('placesCmd_open:tab');"/>
|
||||
<command id="placesCmd_open:tabs"
|
||||
oncommand="goDoCommand('placesCmd_open:tabs');"/>
|
||||
|
||||
<command id="placesCmd_new:bookmark"
|
||||
oncommand="goDoCommand('placesCmd_new:bookmark');"/>
|
||||
<command id="placesCmd_new:livemark"
|
||||
|
@ -121,14 +120,18 @@
|
|||
accesskey="&cmd.open_tab.accesskey;"
|
||||
selectiontype="single"
|
||||
selection="link"/>
|
||||
<menuitem id="placesContext_openFolder:tabs"
|
||||
command="placesCmd_open:tabs"
|
||||
<menuitem id="placesContext_openContainer:tabs"
|
||||
oncommand="var view = PlacesUtils.getViewForNode(document.popupNode);
|
||||
view.controller.openSelectionInTabs(event);"
|
||||
onclick="checkForMiddleClick(this, event);"
|
||||
label="&cmd.open_all_in_tabs.label;"
|
||||
accesskey="&cmd.open_all_in_tabs.accesskey;"
|
||||
selectiontype="single"
|
||||
selection="folder"/>
|
||||
selection="folder|host|query"/>
|
||||
<menuitem id="placesContext_openLinks:tabs"
|
||||
command="placesCmd_open:tabs"
|
||||
oncommand="var view = PlacesUtils.getViewForNode(document.popupNode);
|
||||
view.controller.openSelectionInTabs(event);"
|
||||
onclick="checkForMiddleClick(this, event);"
|
||||
label="&cmd.open_all_in_tabs.label;"
|
||||
accesskey="&cmd.open_all_in_tabs.accesskey;"
|
||||
selectiontype="multiple"
|
||||
|
@ -155,25 +158,25 @@
|
|||
command="cmd_cut"
|
||||
label="&cutCmd.label;"
|
||||
accesskey="&cutCmd.accesskey;"
|
||||
selection="separator|link|folder|mixed"
|
||||
selection="separator|link|folder|mixed|query"
|
||||
forcehideselection="livemarkChild"/>
|
||||
<menuitem id="placesContext_copy"
|
||||
command="cmd_copy"
|
||||
label="©Cmd.label;"
|
||||
accesskey="©Cmd.accesskey;"
|
||||
selection="separator|link|folder"/>
|
||||
selection="separator|link|folder|query"/>
|
||||
<menuitem id="placesContext_paste"
|
||||
command="cmd_paste"
|
||||
label="&pasteCmd.label;"
|
||||
accesskey="&pasteCmd.accesskey;"
|
||||
selection="mutable"/>
|
||||
selection="mutable|query"/>
|
||||
<menuseparator id="placesContext_editSeparator"/>
|
||||
<menuitem id="placesContext_delete"
|
||||
command="cmd_delete"
|
||||
label="&deleteCmd.label;"
|
||||
accesskey="&deleteCmd.accesskey;"
|
||||
closemenu="single"
|
||||
selection="host|separator|link|folder|day"
|
||||
selection="host|separator|link|folder|day|query"
|
||||
forcehideselection="livemarkChild"/>
|
||||
<menuseparator id="placesContext_deleteSeparator"/>
|
||||
<menuitem id="placesContext_reload"
|
||||
|
|
|
@ -1235,7 +1235,7 @@ var PlacesUtils = {
|
|||
* a DOM node
|
||||
* @return the closet ancestor places view if exists, null otherwsie.
|
||||
*/
|
||||
getViewForNode: function(aNode) {
|
||||
getViewForNode: function PU_getViewForNode(aNode) {
|
||||
var node = aNode;
|
||||
while (node) {
|
||||
// XXXmano: Use QueryInterface(nsIPlacesView) once we implement it...
|
||||
|
@ -1502,15 +1502,116 @@ var PlacesUtils = {
|
|||
var bmkIds = this.bookmarks.getBookmarkIdsForURI(aURI, {});
|
||||
for each (var bk in bmkIds) {
|
||||
// Find the first folder which isn't a tag container
|
||||
var folder = this.bookmarks.getFolderIdForItem(bk);
|
||||
if (folder == this.placesRootId)
|
||||
var parent = this.bookmarks.getFolderIdForItem(bk);
|
||||
if (parent == this.placesRootId)
|
||||
return bk;
|
||||
var parent = this.bookmarks.getFolderIdForItem(folder)
|
||||
if (parent != this.tagRootId &&
|
||||
var grandparent = this.bookmarks.getFolderIdForItem(parent);
|
||||
if (grandparent != this.tagRootId &&
|
||||
!this.annotations.itemHasAnnotation(parent, "livemark/feedURI"))
|
||||
return bk;
|
||||
}
|
||||
return -1;
|
||||
},
|
||||
|
||||
getURLsForContainerNode: function PU_getURLsForContainerNode(aNode) {
|
||||
let urls = [];
|
||||
if (this.nodeIsFolder(aNode) && asQuery(aNode).queryOptions.excludeItems) {
|
||||
// grab manually
|
||||
let contents = this.getFolderContents(node.itemId, false, false).root;
|
||||
for (let i = 0; i < contents.childCount; ++i) {
|
||||
let child = contents.getChild(i);
|
||||
if (this.nodeIsURI(child))
|
||||
urls.push(node.uri);
|
||||
}
|
||||
}
|
||||
else {
|
||||
let wasOpen = aNode.containerOpen;
|
||||
if (!wasOpen)
|
||||
aNode.containerOpen = true;
|
||||
for (let i = 0; i < aNode.childCount; ++i) {
|
||||
let child = aNode.getChild(i);
|
||||
if (this.nodeIsURI(child))
|
||||
urls.push(child.uri);
|
||||
}
|
||||
aNode.containerOpen = wasOpen;
|
||||
}
|
||||
|
||||
return urls;
|
||||
},
|
||||
|
||||
/**
|
||||
* Gives the user a chance to cancel loading lots of tabs at once
|
||||
*/
|
||||
_confirmOpenInTabs: function PU__confirmOpenInTabs(numTabsToOpen) {
|
||||
var pref = Cc["@mozilla.org/preferences-service;1"].
|
||||
getService(Ci.nsIPrefBranch);
|
||||
|
||||
const kWarnOnOpenPref = "browser.tabs.warnOnOpen";
|
||||
var reallyOpen = true;
|
||||
if (pref.getBoolPref(kWarnOnOpenPref)) {
|
||||
if (numTabsToOpen >= pref.getIntPref("browser.tabs.maxOpenBeforeWarn")) {
|
||||
var promptService = Cc["@mozilla.org/embedcomp/prompt-service;1"].
|
||||
getService(Ci.nsIPromptService);
|
||||
|
||||
// default to true: if it were false, we wouldn't get this far
|
||||
var warnOnOpen = { value: true };
|
||||
|
||||
var messageKey = "tabs.openWarningMultipleBranded";
|
||||
var openKey = "tabs.openButtonMultiple";
|
||||
const BRANDING_BUNDLE_URI = "chrome://branding/locale/brand.properties";
|
||||
var brandShortName = Cc["@mozilla.org/intl/stringbundle;1"].
|
||||
getService(Ci.nsIStringBundleService).
|
||||
createBundle(BRANDING_BUNDLE_URI).
|
||||
GetStringFromName("brandShortName");
|
||||
|
||||
var buttonPressed = promptService.confirmEx(window,
|
||||
this.getString("tabs.openWarningTitle"),
|
||||
this.getFormattedString(messageKey, [numTabsToOpen, brandShortName]),
|
||||
(promptService.BUTTON_TITLE_IS_STRING * promptService.BUTTON_POS_0)
|
||||
+ (promptService.BUTTON_TITLE_CANCEL * promptService.BUTTON_POS_1),
|
||||
this.getString(openKey), null, null,
|
||||
this.getFormattedString("tabs.openWarningPromptMeBranded",
|
||||
[brandShortName]), warnOnOpen);
|
||||
|
||||
reallyOpen = (buttonPressed == 0);
|
||||
// don't set the pref unless they press OK and it's false
|
||||
if (reallyOpen && !warnOnOpen.value)
|
||||
pref.setBoolPref(kWarnOnOpenPref, false);
|
||||
}
|
||||
}
|
||||
return reallyOpen;
|
||||
},
|
||||
|
||||
_openTabset: function PU__openTabset(aURLs, aEvent) {
|
||||
var browserWindow = getTopWin();
|
||||
var where = browserWindow ?
|
||||
whereToOpenLink(aEvent, false, true) : "window";
|
||||
if (where == "window") {
|
||||
window.openDialog(getBrowserURL(), "_blank",
|
||||
"chrome,all,dialog=no", aURLs.join("|"));
|
||||
return;
|
||||
}
|
||||
|
||||
var loadInBackground = where == "tabshifted" ? true : false;
|
||||
var replaceCurrentTab = where == "tab" ? false : true;
|
||||
browserWindow.getBrowser().loadTabs(aURLs, loadInBackground,
|
||||
replaceCurrentTab);
|
||||
},
|
||||
|
||||
openContainerNodeInTabs: function PU_openContainerInTabs(aNode, aEvent) {
|
||||
var urlsToOpen = this.getURLsForContainerNode(aNode);
|
||||
if (!this._confirmOpenInTabs(urlsToOpen.length))
|
||||
return;
|
||||
this._openTabset(urlsToOpen, aEvent);
|
||||
},
|
||||
|
||||
openURINodesInTabs: function PU_openURINodesInTabs(aNodes, aEvent) {
|
||||
var urlsToOpen = [];
|
||||
for (var i=0; i < aNodes.length; i++) {
|
||||
if (this.nodeIsURI(aNodes[i]))
|
||||
urlsToOpen.push(aNodes[i].uri);
|
||||
}
|
||||
this._openTabset(urlsToOpen, aEvent);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -178,8 +178,10 @@ var gMainPane = {
|
|||
* True if the Download Manager should be closed when all downloads
|
||||
* complete, false if it should be left open.
|
||||
* browser.download.useDownloadDir - bool
|
||||
* True if downloads are saved with no save-as UI shown, false if
|
||||
* the user should always be asked where to save a file.
|
||||
* True - Save files directly to the folder configured via the
|
||||
* browser.download.folderList preference.
|
||||
* False - Always ask the user where to save a file and default to
|
||||
* browser.download.lastDir when displaying a folder picker dialog.
|
||||
* browser.download.dir - local file handle
|
||||
* A local folder the user may have selected for downloaded files to be
|
||||
* saved. Migration of other browser settings may also set this path.
|
||||
|
|
|
@ -75,12 +75,12 @@
|
|||
#endif
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
#ifdef USE_WIN_TITLE_STYLE
|
||||
style="&prefWindow.styleWin;">
|
||||
style="&prefWin.styleWin;">
|
||||
#else
|
||||
#ifdef XP_MACOSX
|
||||
style="&prefWindow.styleMac;">
|
||||
#else
|
||||
style="&prefWindow.styleGNOME;">
|
||||
style="&prefWin.styleGNOME;">
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
|
|
@ -553,6 +553,7 @@ SessionStoreService.prototype = {
|
|||
this._windows[aWindow.__SSi]._closedTabs.unshift({
|
||||
state: tabState,
|
||||
title: aTab.getAttribute("label"),
|
||||
image: aTab.getAttribute("image"),
|
||||
pos: aTab._tPos
|
||||
});
|
||||
var length = this._windows[aWindow.__SSi]._closedTabs.length;
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
# Contributor(s):
|
||||
# Blake Ross <blake@blakeross.com>
|
||||
# Ben Goodger <ben@mozilla.org>
|
||||
# Dao Gottwald <dao@design-noir.de>
|
||||
# Dão Gottwald <dao@design-noir.de>
|
||||
#
|
||||
# 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
|
||||
|
@ -37,79 +37,68 @@
|
|||
#
|
||||
# ***** END LICENSE BLOCK *****
|
||||
|
||||
const kXUL_NS = "http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul";
|
||||
const kHTML_NS = "http://www.w3.org/1999/xhtml";
|
||||
const kIShellService = Components.interfaces.nsIShellService;
|
||||
#ifdef XP_MACOSX
|
||||
const kIMacShellService = Components.interfaces.nsIMacShellService;
|
||||
#endif
|
||||
var Ci = Components.interfaces;
|
||||
|
||||
var gSetBackground = {
|
||||
_position : kIShellService.BACKGROUND_STRETCH,
|
||||
_monitor : null,
|
||||
_image : null,
|
||||
_backgroundColor : 0,
|
||||
|
||||
#ifndef XP_MACOSX
|
||||
// Converts a color string in the format "#RRGGBB" to an integer.
|
||||
_hexStringToLong: function (aString)
|
||||
{
|
||||
return parseInt(aString.substring(1,3), 16) << 16 |
|
||||
parseInt(aString.substring(3,5), 16) << 8 |
|
||||
parseInt(aString.substring(5,7), 16);
|
||||
},
|
||||
|
||||
_rgbToHex: function(aR, aG, aB)
|
||||
{
|
||||
var rHex = aR.toString(16).toUpperCase();
|
||||
var gHex = aG.toString(16).toUpperCase();
|
||||
var bHex = aB.toString(16).toUpperCase();
|
||||
|
||||
if (rHex.length == 1) rHex ='0' + rHex;
|
||||
if (gHex.length == 1) gHex ='0' + gHex;
|
||||
if (bHex.length == 1) bHex ='0' + bHex;
|
||||
|
||||
return '#' + rHex + gHex + bHex;
|
||||
},
|
||||
_position : "",
|
||||
_backgroundColor : 0,
|
||||
#else
|
||||
_position : "STRETCH",
|
||||
#endif
|
||||
_screenWidth : 0,
|
||||
_screenHeight : 0,
|
||||
_image : null,
|
||||
_canvas : null,
|
||||
|
||||
get _shell()
|
||||
{
|
||||
return Components.classes["@mozilla.org/browser/shell-service;1"]
|
||||
.getService(Components.interfaces.nsIShellService);
|
||||
.getService(Ci.nsIShellService);
|
||||
},
|
||||
|
||||
load: function ()
|
||||
{
|
||||
this._monitor = document.getElementById("monitor");
|
||||
this._canvas = document.getElementById("screen");
|
||||
this._screenWidth = screen.width;
|
||||
this._screenHeight = screen.height;
|
||||
#ifdef XP_MACOSX
|
||||
document.documentElement.getButton("accept").hidden = true;
|
||||
#endif
|
||||
this.init(window.arguments[0]);
|
||||
if (this._screenWidth / this._screenHeight >= 1.6)
|
||||
document.getElementById("monitor").setAttribute("aspectratio", "16:10");
|
||||
|
||||
// make sure that the correct dimensions will be used
|
||||
setTimeout(function(self) {
|
||||
self.init(window.arguments[0]);
|
||||
}, 0, this);
|
||||
},
|
||||
|
||||
init: function (aImage)
|
||||
{
|
||||
this._image = aImage;
|
||||
|
||||
// set the size of the coordinate space
|
||||
this._canvas.width = this._canvas.clientWidth;
|
||||
this._canvas.height = this._canvas.clientHeight;
|
||||
|
||||
var ctx = this._canvas.getContext("2d");
|
||||
ctx.scale(this._canvas.clientWidth / this._screenWidth, this._canvas.clientHeight / this._screenHeight);
|
||||
|
||||
#ifndef XP_MACOSX
|
||||
this._initColor();
|
||||
var position = parseInt(document.getElementById("menuPosition").value);
|
||||
#else
|
||||
// Make sure to reset the button state in case the user has already
|
||||
// set an image as their desktop background.
|
||||
// set an image as their desktop background.
|
||||
var setDesktopBackground = document.getElementById("setDesktopBackground");
|
||||
setDesktopBackground.hidden = false;
|
||||
var bundle = document.getElementById("backgroundBundle");
|
||||
setDesktopBackground.label = bundle.getString("DesktopBackgroundSet");
|
||||
setDesktopBackground.disabled = false;
|
||||
|
||||
var showDesktopPreferences = document.getElementById("showDesktopPreferences");
|
||||
showDesktopPreferences.hidden = true;
|
||||
|
||||
var position = kIShellService.BACKGROUND_STRETCH;
|
||||
document.getElementById("showDesktopPreferences").hidden = true;
|
||||
#endif
|
||||
this.updatePosition(position);
|
||||
this.updatePosition();
|
||||
},
|
||||
|
||||
#ifndef XP_MACOSX
|
||||
|
@ -128,126 +117,87 @@ var gSetBackground = {
|
|||
var colorpicker = document.getElementById("desktopColor");
|
||||
colorpicker.color = this._backgroundColor;
|
||||
},
|
||||
#endif
|
||||
|
||||
updateColor: function (aColor)
|
||||
{
|
||||
this._backgroundColor = aColor;
|
||||
this._canvas.style.backgroundColor = aColor;
|
||||
},
|
||||
|
||||
// Converts a color string in the format "#RRGGBB" to an integer.
|
||||
_hexStringToLong: function (aString)
|
||||
{
|
||||
return parseInt(aString.substring(1,3), 16) << 16 |
|
||||
parseInt(aString.substring(3,5), 16) << 8 |
|
||||
parseInt(aString.substring(5,7), 16);
|
||||
},
|
||||
|
||||
_rgbToHex: function (aR, aG, aB)
|
||||
{
|
||||
return "#" + [aR, aG, aB].map(function(aInt) aInt.toString(16).replace(/^(.)$/, "0$1"))
|
||||
.join("").toUpperCase();
|
||||
},
|
||||
#else
|
||||
observe: function (aSubject, aTopic, aData)
|
||||
{
|
||||
if (aTopic == "shell:desktop-background-changed") {
|
||||
var setDesktopBackground = document.getElementById("setDesktopBackground");
|
||||
setDesktopBackground.hidden = true;
|
||||
document.getElementById("setDesktopBackground").hidden = true;
|
||||
document.getElementById("showDesktopPreferences").hidden = false;
|
||||
|
||||
var showDesktopPreferences = document.getElementById("showDesktopPreferences");
|
||||
showDesktopPreferences.hidden = false;
|
||||
|
||||
var os = Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Components.interfaces.nsIObserverService);
|
||||
os.removeObserver(this, "shell:desktop-background-changed");
|
||||
Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService)
|
||||
.removeObserver(this, "shell:desktop-background-changed");
|
||||
}
|
||||
},
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
setDesktopBackground: function()
|
||||
showDesktopPrefs: function()
|
||||
{
|
||||
var os = Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Components.interfaces.nsIObserverService);
|
||||
os.addObserver(this, "shell:desktop-background-changed", false);
|
||||
this._shell.openApplication(Ci.nsIMacShellService.APPLICATION_DESKTOP);
|
||||
},
|
||||
#endif
|
||||
|
||||
setDesktopBackground: function ()
|
||||
{
|
||||
#ifndef XP_MACOSX
|
||||
document.persist("menuPosition", "value");
|
||||
this._shell.desktopBackgroundColor = this._hexStringToLong(this._backgroundColor);
|
||||
#else
|
||||
Components.classes["@mozilla.org/observer-service;1"]
|
||||
.getService(Ci.nsIObserverService)
|
||||
.addObserver(this, "shell:desktop-background-changed", false);
|
||||
|
||||
var bundle = document.getElementById("backgroundBundle");
|
||||
var setDesktopBackground = document.getElementById("setDesktopBackground");
|
||||
setDesktopBackground.disabled = true;
|
||||
setDesktopBackground.label = bundle.getString("DesktopBackgroundDownloading");
|
||||
|
||||
this._shell.setDesktopBackground(this._image, this._position);
|
||||
},
|
||||
|
||||
showDesktopPrefs: function()
|
||||
{
|
||||
this._shell.openApplication(kIMacShellService.APPLICATION_DESKTOP);
|
||||
},
|
||||
#else
|
||||
setDesktopBackground: function ()
|
||||
{
|
||||
this._shell.setDesktopBackground(this._image, this._position);
|
||||
this._shell.desktopBackgroundColor = this._hexStringToLong(this._backgroundColor);
|
||||
document.persist("menuPosition", "value");
|
||||
},
|
||||
#endif
|
||||
this._shell.setDesktopBackground(this._image,
|
||||
Ci.nsIShellService["BACKGROUND_" + this._position]);
|
||||
},
|
||||
|
||||
updateColor: function (color)
|
||||
updatePosition: function ()
|
||||
{
|
||||
var ctx = this._canvas.getContext("2d");
|
||||
ctx.clearRect(0, 0, this._screenWidth, this._screenHeight);
|
||||
|
||||
#ifndef XP_MACOSX
|
||||
this._backgroundColor = color;
|
||||
this._monitor.style.backgroundColor = color;
|
||||
this._position = document.getElementById("menuPosition").value;
|
||||
#endif
|
||||
},
|
||||
|
||||
updatePosition: function (aPosition)
|
||||
{
|
||||
if (this._monitor.hasChildNodes())
|
||||
this._monitor.removeChild(this._monitor.firstChild);
|
||||
|
||||
this._position = aPosition;
|
||||
if (this._position == kIShellService.BACKGROUND_TILE)
|
||||
this._tileImage();
|
||||
else if (this._position == kIShellService.BACKGROUND_STRETCH)
|
||||
this._stretchImage();
|
||||
else
|
||||
this._centerImage();
|
||||
},
|
||||
|
||||
_createImage: function ()
|
||||
{
|
||||
const nsIImageLoadingContent = Components.interfaces.nsIImageLoadingContent;
|
||||
if (!(this._image instanceof nsIImageLoadingContent))
|
||||
return false;
|
||||
|
||||
var request = this._image.QueryInterface(nsIImageLoadingContent)
|
||||
.getRequest(nsIImageLoadingContent.CURRENT_REQUEST);
|
||||
if (!request)
|
||||
return false;
|
||||
|
||||
var imgURI = this._image.currentURI;
|
||||
if (imgURI.schemeIs("javascript"))
|
||||
return false;
|
||||
|
||||
var img = document.createElementNS(kXUL_NS, "image");
|
||||
img.setAttribute("src", imgURI.spec);
|
||||
return img;
|
||||
},
|
||||
|
||||
_stretchImage: function ()
|
||||
{
|
||||
var img = this._createImage();
|
||||
img.width = this._monitor.boxObject.width;
|
||||
img.height = this._monitor.boxObject.height;
|
||||
this._monitor.appendChild(img);
|
||||
},
|
||||
|
||||
_tileImage: function ()
|
||||
{
|
||||
var canvas = document.createElementNS(kHTML_NS, "canvas");
|
||||
var width = this._monitor.boxObject.width;
|
||||
var height = this._monitor.boxObject.height;
|
||||
canvas.width = width;
|
||||
canvas.height = height;
|
||||
|
||||
var ctx = canvas.getContext("2d");
|
||||
ctx.fillStyle = ctx.createPattern(this._image, "repeat");
|
||||
ctx.scale(width / screen.width, height / screen.height);
|
||||
ctx.fillRect(0, 0, screen.width, screen.height);
|
||||
|
||||
this._monitor.appendChild(canvas);
|
||||
},
|
||||
|
||||
_centerImage: function ()
|
||||
{
|
||||
var img = this._createImage();
|
||||
// Use naturalHeight/Width here so we don't scale an image improperly in
|
||||
// the preview window if the image is resized in the browser window.
|
||||
var width = this._image.naturalWidth * this._monitor.boxObject.width / screen.width;
|
||||
var height = this._image.naturalHeight * this._monitor.boxObject.height / screen.height;
|
||||
img.width = Math.floor(width);
|
||||
img.height = Math.floor(height);
|
||||
this._monitor.appendChild(img);
|
||||
switch (this._position) {
|
||||
case "TILE":
|
||||
ctx.save();
|
||||
ctx.fillStyle = ctx.createPattern(this._image, "repeat");
|
||||
ctx.fillRect(0, 0, this._screenWidth, this._screenHeight);
|
||||
ctx.restore();
|
||||
break;
|
||||
case "STRETCH":
|
||||
ctx.drawImage(this._image, 0, 0, this._screenWidth, this._screenHeight);
|
||||
break;
|
||||
case "CENTER":
|
||||
var x = (this._screenWidth - this._image.naturalWidth) / 2;
|
||||
var y = (this._screenHeight - this._image.naturalHeight) / 2;
|
||||
ctx.drawImage(this._image, x, y);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -23,6 +23,7 @@
|
|||
# Contributor(s):
|
||||
# Blake Ross <blake@blakeross.com>
|
||||
# Ben Goodger <ben@mozilla.org>
|
||||
# Dão Gottwald <dao@design-noir.de>
|
||||
#
|
||||
# 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
|
||||
|
@ -47,9 +48,8 @@
|
|||
<?xul-overlay href="chrome://browser/content/macBrowserOverlay.xul"?>
|
||||
#endif
|
||||
|
||||
<dialog xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
id="aboutDialog"
|
||||
<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
windowtype="Shell:SetDesktopBackground"
|
||||
#ifndef XP_MACOSX
|
||||
buttons="accept,cancel"
|
||||
|
@ -60,27 +60,24 @@
|
|||
onload="gSetBackground.load();"
|
||||
ondialogaccept="gSetBackground.setDesktopBackground();"
|
||||
title="&setDesktopBackground.title;"
|
||||
style="width: 30em;">
|
||||
|
||||
style="width: 30em;">
|
||||
|
||||
<stringbundle id="backgroundBundle"
|
||||
src="chrome://browser/locale/shellservice.properties"/>
|
||||
<script type="application/x-javascript"
|
||||
src="chrome://browser/content/utilityOverlay.js"/>
|
||||
<script type="application/x-javascript"
|
||||
src="chrome://browser/content/setDesktopBackground.js"/>
|
||||
<script type="application/x-javascript"
|
||||
src="chrome://global/content/contentAreaUtils.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/utilityOverlay.js"/>
|
||||
<script type="application/javascript" src="chrome://browser/content/setDesktopBackground.js"/>
|
||||
<script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/>
|
||||
|
||||
#ifndef XP_MACOSX
|
||||
<hbox align="center" id="foo">
|
||||
<hbox align="center">
|
||||
<label value="&position.label;"/>
|
||||
<menulist id="menuPosition"
|
||||
label="&position.label;"
|
||||
oncommand="gSetBackground.updatePosition(parseInt(this.value));">
|
||||
oncommand="gSetBackground.updatePosition();">
|
||||
<menupopup>
|
||||
<menuitem label="¢er.label;" value="3"/>
|
||||
<menuitem label="&tile.label;" value="1"/>
|
||||
<menuitem label="&stretch.label;" value="2"/>
|
||||
<menuitem label="¢er.label;" value="CENTER"/>
|
||||
<menuitem label="&tile.label;" value="TILE"/>
|
||||
<menuitem label="&stretch.label;" value="STRETCH"/>
|
||||
</menupopup>
|
||||
</menulist>
|
||||
<spacer flex="1"/>
|
||||
|
@ -93,8 +90,9 @@
|
|||
<groupbox align="center">
|
||||
<caption label="&preview.label;"/>
|
||||
<stack>
|
||||
<vbox id="monitor" align="center" pack="center"/>
|
||||
<image id="monitorImage"/>
|
||||
<!-- if width and height are not present, they default to 300x150 and stretch the stack -->
|
||||
<html:canvas id="screen" width="1" height="1"/>
|
||||
<image id="monitor"/>
|
||||
</stack>
|
||||
</groupbox>
|
||||
|
||||
|
|
|
@ -77,3 +77,7 @@ status_foldercount = %S object(s)
|
|||
|
||||
SelectImport=Import Bookmarks File
|
||||
EnterExport=Export Bookmarks File
|
||||
|
||||
saveSearch.title=Save Search
|
||||
saveSearch.inputLabel=Name:
|
||||
saveSearch.defaultText=New Query
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
<!ENTITY prefWindow.titleGNOME "&brandShortName; Preferences">
|
||||
<!-- When making changes to prefWindow.styleWin test both Windows Classic and
|
||||
Luna since widget heights are different based on the OS theme -->
|
||||
<!ENTITY prefWindow.styleWin "width: 42em; height: 44em;">
|
||||
<!ENTITY prefWin.styleWin "width: 42em; min-height: 44em;">
|
||||
<!ENTITY prefWindow.styleMac "width: 47em;">
|
||||
<!ENTITY prefWindow.styleGNOME "width: 42em; height: 38.5em;">
|
||||
<!ENTITY prefWin.styleGNOME "width: 42em; min-height: 44.5em;">
|
||||
|
||||
<!ENTITY paneMain.title "Main">
|
||||
<!ENTITY paneTabs.title "Tabs">
|
||||
|
|
|
@ -59,3 +59,4 @@ externalProtocolPrompt=An external application must be launched to handle %1$S:
|
|||
externalProtocolUnknown=<Unknown>
|
||||
externalProtocolChkMsg=Remember my choice for all links of this type.
|
||||
externalProtocolLaunchBtn=Launch application
|
||||
malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences.
|
||||
|
|
|
@ -32,6 +32,7 @@ classic.jar:
|
|||
skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png)
|
||||
skin/classic/browser/setDesktopBackground.css
|
||||
skin/classic/browser/monitor.png
|
||||
skin/classic/browser/monitor_16-10.png
|
||||
skin/classic/browser/places/places.css (places/places.css)
|
||||
skin/classic/browser/places/query.png (places/query.png)
|
||||
skin/classic/browser/places/livemarkItem.png (places/livemarkItem.png)
|
||||
|
|
Двоичные данные
browser/themes/pinstripe/browser/monitor.png
Двоичные данные
browser/themes/pinstripe/browser/monitor.png
Двоичный файл не отображается.
До Ширина: | Высота: | Размер: 7.9 KiB После Ширина: | Высота: | Размер: 7.6 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 8.8 KiB |
|
@ -1,12 +1,14 @@
|
|||
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||
@namespace html url("http://www.w3.org/1999/xhtml");
|
||||
|
||||
html|canvas#screen {
|
||||
margin: 12px 11px 38px;
|
||||
}
|
||||
|
||||
#monitor {
|
||||
margin: 18px 20px 38px 13px;
|
||||
width: 153px;
|
||||
height: 114px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#monitorImage {
|
||||
list-style-image: url("chrome://browser/skin/monitor.png");
|
||||
}
|
||||
|
||||
#monitor[aspectratio="16:10"] {
|
||||
list-style-image: url("chrome://browser/skin/monitor_16-10.png");
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ classic.jar:
|
|||
skin/classic/browser/Search-provider-mid-bottom.png
|
||||
skin/classic/browser/setDesktopBackground.css
|
||||
skin/classic/browser/monitor.png
|
||||
skin/classic/browser/monitor_16-10.png
|
||||
skin/classic/browser/feeds/feedIcon.png (feeds/feedIcon.png)
|
||||
skin/classic/browser/feeds/feedIcon16.png (feeds/feedIcon16.png)
|
||||
skin/classic/browser/feeds/subscribe.css (feeds/subscribe.css)
|
||||
|
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 6.6 KiB |
|
@ -268,5 +268,5 @@ filefield[disabled="true"] .fileFieldIcon {
|
|||
/* bottom-most box containing a groupbox in a prefpane. Prevents the bottom
|
||||
of the groupbox from being cutoff */
|
||||
.bottomBox {
|
||||
padding-bottom: 2px;
|
||||
padding-bottom: 4px;
|
||||
}
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||
@namespace html url("http://www.w3.org/1999/xhtml");
|
||||
|
||||
#monitor {
|
||||
html|canvas#screen {
|
||||
margin: 12px 11px 32px;
|
||||
width: 153px;
|
||||
height: 114px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#monitorImage {
|
||||
#monitor {
|
||||
list-style-image: url("chrome://browser/skin/monitor.png");
|
||||
}
|
||||
|
||||
#noPreviewAvailable {
|
||||
background-color: white !important;
|
||||
font-size: 12px !important;
|
||||
#monitor[aspectratio="16:10"] {
|
||||
list-style-image: url("chrome://browser/skin/monitor_16-10.png");
|
||||
}
|
||||
|
|
|
@ -392,6 +392,10 @@ then
|
|||
export XSUNTRANSPORT XSUNSMESIZE
|
||||
fi
|
||||
|
||||
# Disable Gnome crash dialog
|
||||
GNOME_DISABLE_CRASH_DIALOG=1
|
||||
export GNOME_DISABLE_CRASH_DIALOG
|
||||
|
||||
if [ "$moz_debug" -eq 1 ]
|
||||
then
|
||||
echo "MOZILLA_FIVE_HOME=$MOZILLA_FIVE_HOME"
|
||||
|
|
|
@ -300,6 +300,7 @@ kernel/image.h
|
|||
kernel/OS.h
|
||||
key.h
|
||||
keyt.h
|
||||
keythi.h
|
||||
LAction.h
|
||||
langinfo.h
|
||||
LApplication.h
|
||||
|
|
|
@ -4318,7 +4318,8 @@ minimal)
|
|||
MOZ_PROFILELOCKING=
|
||||
MOZ_PROFILESHARING=
|
||||
MOZ_SPELLCHECK=
|
||||
MOZ_STORAGE=
|
||||
MOZ_STORAGE=1
|
||||
MOZ_PLACES=
|
||||
MOZ_SVG=
|
||||
MOZ_UNIVERSALCHARDET=
|
||||
MOZ_UPDATER=
|
||||
|
|
|
@ -674,12 +674,15 @@ nsNode3Tearoff::IsDefaultNamespace(const nsAString& aNamespaceURI,
|
|||
//----------------------------------------------------------------------
|
||||
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_1(nsNSElementTearoff, mContent)
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsNSElementTearoff)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMNSElement)
|
||||
NS_INTERFACE_MAP_ENTRIES_CYCLE_COLLECTION(nsNSElementTearoff)
|
||||
NS_INTERFACE_MAP_END_AGGREGATED(mContent)
|
||||
|
||||
NS_IMPL_ADDREF(nsNSElementTearoff)
|
||||
NS_IMPL_RELEASE(nsNSElementTearoff)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsNSElementTearoff)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsNSElementTearoff)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsNSElementTearoff::GetElementsByClassName(const nsAString& aClasses,
|
||||
|
|
|
@ -1055,10 +1055,12 @@ _elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const \
|
|||
class nsNSElementTearoff : public nsIDOMNSElement
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
|
||||
NS_DECL_NSIDOMNSELEMENT
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS(nsNSElementTearoff)
|
||||
|
||||
nsNSElementTearoff(nsGenericElement *aContent) : mContent(aContent)
|
||||
{
|
||||
}
|
||||
|
|
|
@ -53,13 +53,14 @@ _TEST_FILES = test_bug1682.html \
|
|||
bug199692-nested-d2.html \
|
||||
test_bug172261.html \
|
||||
test_bug255820.html \
|
||||
test_bug259332.html \
|
||||
test_bug311681.html \
|
||||
test_bug311681.xhtml \
|
||||
test_bug324378.html \
|
||||
test_bug332848.xhtml \
|
||||
test_bug359657.html \
|
||||
test_bug380383.html \
|
||||
test_bug386495.html \
|
||||
test_bug259332.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,77 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html id="a" id="b">
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=324378
|
||||
-->
|
||||
<head id="c" id="d">
|
||||
<head id="j" foo="k" foo="l">
|
||||
<title>Test for Bug 324378</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body id="e" id="f">
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=324378">Mozilla Bug 324378</a>
|
||||
<script>
|
||||
var html = document.documentElement;
|
||||
is(document.getElementsByTagName("html").length, 1,
|
||||
"Unexpected number of htmls");
|
||||
is(document.getElementsByTagName("html")[0], html,
|
||||
"Unexpected <html> element");
|
||||
is(document.getElementsByTagName("head").length, 1,
|
||||
"Unexpected number of heads");
|
||||
is(html.getElementsByTagName("head").length, 1,
|
||||
"Unexpected number of heads in <html>");
|
||||
is(document.getElementsByTagName("body").length, 1,
|
||||
"Unexpected number of bodies");
|
||||
is(html.getElementsByTagName("body").length, 1,
|
||||
"Unexpected number of bodies in <html>");
|
||||
var head = document.getElementsByTagName("head")[0];
|
||||
var body = document.getElementsByTagName("body")[0];
|
||||
</script>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
<html id="g" foo="h" foo="i">
|
||||
<body id="m" foo="n" foo="o">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 324378 **/
|
||||
is(document.getElementsByTagName("html").length, 1,
|
||||
"Unexpected number of htmls after additions");
|
||||
is(document.getElementsByTagName("html")[0], html,
|
||||
"Unexpected <html> element");
|
||||
is(document.documentElement, html,
|
||||
"Unexpected root node");
|
||||
is(document.getElementsByTagName("head").length, 1,
|
||||
"Unexpected number of heads after additions");
|
||||
is(document.getElementsByTagName("head")[0], head,
|
||||
"Unexpected <head> element");
|
||||
is(document.getElementsByTagName("body").length, 1,
|
||||
"Unexpected number of bodies after additions");
|
||||
is(document.getElementsByTagName("body")[0], body,
|
||||
"Unexpected <body> element");
|
||||
|
||||
is(html.id, "a", "Unexpected <html> id");
|
||||
is(head.id, "c", "Unexpected <head> id");
|
||||
is(body.id, "e", "Unexpected <body> id");
|
||||
is($("a"), html, "Unexpected node with id=a");
|
||||
is($("b"), null, "Unexpected node with id=b");
|
||||
is($("c"), head, "Unexpected node with id=c");
|
||||
is($("d"), null, "Unexpected node with id=d");
|
||||
is($("e"), body, "Unexpected node with id=e");
|
||||
is($("f"), null, "Unexpected node with id=f");
|
||||
is($("g"), null, "Unexpected node with id=g");
|
||||
is($("j"), null, "Unexpected node with id=j");
|
||||
is($("m"), null, "Unexpected node with id=m");
|
||||
|
||||
is(html.getAttribute("foo"), "h", "Unexpected 'foo' value on <html>");
|
||||
is(head.getAttribute("foo"), "k", "Unexpected 'foo' value on <head>");
|
||||
is(body.getAttribute("foo"), "n", "Unexpected 'foo' value on <body>");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -41,6 +41,7 @@
|
|||
|
||||
#include "nscore.h"
|
||||
#include "nsDebug.h"
|
||||
#include "nsTraceRefcnt.h"
|
||||
#include "prtypes.h"
|
||||
#include "txDouble.h"
|
||||
|
||||
|
@ -49,11 +50,17 @@ class nsAString;
|
|||
class txObject
|
||||
{
|
||||
public:
|
||||
txObject()
|
||||
{
|
||||
MOZ_COUNT_CTOR(txObject);
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes this txObject
|
||||
*/
|
||||
virtual ~txObject()
|
||||
{
|
||||
MOZ_COUNT_DTOR(txObject);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -70,6 +70,15 @@ class txXPathNode;
|
|||
class Expr
|
||||
{
|
||||
public:
|
||||
Expr()
|
||||
{
|
||||
MOZ_COUNT_CTOR(Expr);
|
||||
}
|
||||
virtual ~Expr()
|
||||
{
|
||||
MOZ_COUNT_DTOR(Expr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates this Expr based on the given context node and processor state
|
||||
* @param context the context node for evaluation of this Expr
|
||||
|
@ -405,7 +414,15 @@ private:
|
|||
class txNodeTest
|
||||
{
|
||||
public:
|
||||
virtual ~txNodeTest() {}
|
||||
txNodeTest()
|
||||
{
|
||||
MOZ_COUNT_CTOR(txNodeTest);
|
||||
}
|
||||
virtual ~txNodeTest()
|
||||
{
|
||||
MOZ_COUNT_DTOR(txNodeTest);
|
||||
}
|
||||
|
||||
/*
|
||||
* Virtual methods
|
||||
* pretty much a txPattern, but not supposed to be used
|
||||
|
|
|
@ -72,10 +72,14 @@ public:
|
|||
txAExprResult(txResultRecycler* aRecycler) : mRecycler(aRecycler)
|
||||
{
|
||||
}
|
||||
virtual ~txAExprResult()
|
||||
{
|
||||
}
|
||||
|
||||
void AddRef()
|
||||
{
|
||||
++mRefCnt;
|
||||
NS_LOG_ADDREF(this, mRefCnt, "txAExprResult", sizeof(*this));
|
||||
}
|
||||
|
||||
void Release(); // Implemented in txResultRecycler.cpp
|
||||
|
|
|
@ -290,7 +290,9 @@ txResultRecycler::getNonSharedNodeSet(txNodeSet* aNodeSet, txNodeSet** aResult)
|
|||
void
|
||||
txAExprResult::Release()
|
||||
{
|
||||
if (--mRefCnt == 0) {
|
||||
--mRefCnt;
|
||||
NS_LOG_RELEASE(this, mRefCnt, "txAExprResult");
|
||||
if (mRefCnt == 0) {
|
||||
if (mRecycler) {
|
||||
mRecycler->recycle(this);
|
||||
}
|
||||
|
|
|
@ -59,10 +59,13 @@ public:
|
|||
void AddRef()
|
||||
{
|
||||
++mRefCnt;
|
||||
NS_LOG_ADDREF(this, mRefCnt, "txResultRecycler", sizeof(*this));
|
||||
}
|
||||
void Release()
|
||||
{
|
||||
if (--mRefCnt == 0) {
|
||||
--mRefCnt;
|
||||
NS_LOG_RELEASE(this, mRefCnt, "txResultRecycler");
|
||||
if (mRefCnt == 0) {
|
||||
mRefCnt = 1; //stabilize
|
||||
delete this;
|
||||
}
|
||||
|
|
|
@ -53,18 +53,19 @@ class txExecutionState;
|
|||
class txInstruction : public TxObject
|
||||
{
|
||||
public:
|
||||
txInstruction() : mNext(0)
|
||||
txInstruction()
|
||||
{
|
||||
MOZ_COUNT_CTOR(txInstruction);
|
||||
}
|
||||
|
||||
virtual ~txInstruction()
|
||||
{
|
||||
delete mNext;
|
||||
MOZ_COUNT_DTOR(txInstruction);
|
||||
}
|
||||
|
||||
virtual nsresult execute(txExecutionState& aEs) = 0;
|
||||
|
||||
txInstruction* mNext;
|
||||
nsAutoPtr<txInstruction> mNext;
|
||||
};
|
||||
|
||||
#define TX_DECL_TXINSTRUCTION \
|
||||
|
|
|
@ -236,6 +236,14 @@ protected:
|
|||
class txIGlobalParameter
|
||||
{
|
||||
public:
|
||||
txIGlobalParameter()
|
||||
{
|
||||
MOZ_COUNT_CTOR(txIGlobalParameter);
|
||||
}
|
||||
virtual ~txIGlobalParameter()
|
||||
{
|
||||
MOZ_COUNT_DTOR(txIGlobalParameter);
|
||||
}
|
||||
virtual nsresult getValue(txAExprResult** aValue) = 0;
|
||||
};
|
||||
|
||||
|
|
|
@ -72,13 +72,17 @@ txStylesheetCompiler::txStylesheetCompiler(const nsAString& aStylesheetURI,
|
|||
nsrefcnt
|
||||
txStylesheetCompiler::AddRef()
|
||||
{
|
||||
return ++mRefCnt;
|
||||
++mRefCnt;
|
||||
NS_LOG_ADDREF(this, mRefCnt, "txStylesheetCompiler", sizeof(*this));
|
||||
return mRefCnt;
|
||||
}
|
||||
|
||||
nsrefcnt
|
||||
txStylesheetCompiler::Release()
|
||||
{
|
||||
if (--mRefCnt == 0) {
|
||||
--mRefCnt;
|
||||
NS_LOG_RELEASE(this, mRefCnt, "txStylesheetCompiler");
|
||||
if (mRefCnt == 0) {
|
||||
mRefCnt = 1; //stabilize
|
||||
delete this;
|
||||
return 0;
|
||||
|
@ -764,7 +768,7 @@ txStylesheetCompilerState::addInstruction(nsAutoPtr<txInstruction> aInstruction)
|
|||
txInstruction* newInstr = aInstruction;
|
||||
|
||||
*mNextInstrPtr = aInstruction.forget();
|
||||
mNextInstrPtr = &newInstr->mNext;
|
||||
mNextInstrPtr = newInstr->mNext.StartAssignment();
|
||||
|
||||
PRInt32 i, count = mGotoTargetPointers.Count();
|
||||
for (i = 0; i < count; ++i) {
|
||||
|
|
|
@ -51,8 +51,13 @@ class Expr;
|
|||
class txToplevelItem
|
||||
{
|
||||
public:
|
||||
txToplevelItem()
|
||||
{
|
||||
MOZ_COUNT_CTOR(txToplevelItem);
|
||||
}
|
||||
virtual ~txToplevelItem()
|
||||
{
|
||||
MOZ_COUNT_DTOR(txToplevelItem);
|
||||
}
|
||||
|
||||
enum type {
|
||||
|
|
|
@ -96,11 +96,11 @@ nsXULPopupListener::~nsXULPopupListener(void)
|
|||
ClosePopup();
|
||||
}
|
||||
|
||||
NS_IMPL_ADDREF(nsXULPopupListener)
|
||||
NS_IMPL_RELEASE(nsXULPopupListener)
|
||||
NS_IMPL_CYCLE_COLLECTION_2(nsXULPopupListener, mElement, mPopupContent)
|
||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULPopupListener)
|
||||
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsXULPopupListener)
|
||||
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsXULPopupListener)
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXULPopupListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMMouseListener)
|
||||
NS_INTERFACE_MAP_ENTRY(nsIDOMContextMenuListener)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsIDOMEventListener, nsIDOMMouseListener)
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
#include "nsIFrame.h"
|
||||
#include "nsIDOMMouseListener.h"
|
||||
#include "nsIDOMContextMenuListener.h"
|
||||
#include "nsCycleCollectionParticipant.h"
|
||||
|
||||
class nsXULPopupListener : public nsIDOMMouseListener,
|
||||
public nsIDOMContextMenuListener
|
||||
|
@ -66,9 +67,10 @@ public:
|
|||
nsXULPopupListener(nsIDOMElement *aElement, PRBool aIsContext);
|
||||
virtual ~nsXULPopupListener(void);
|
||||
|
||||
public:
|
||||
// nsISupports
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsXULPopupListener,
|
||||
nsIDOMMouseListener)
|
||||
|
||||
// nsIDOMMouseListener
|
||||
NS_IMETHOD MouseDown(nsIDOMEvent* aMouseEvent);
|
||||
|
@ -104,7 +106,7 @@ private:
|
|||
nsresult FireFocusOnTargetContent(nsIDOMNode* aTargetNode);
|
||||
|
||||
// |mElement| is the node to which this listener is attached.
|
||||
nsIDOMElement* mElement; // Weak ref. The element will go away first.
|
||||
nsCOMPtr<nsIDOMElement> mElement;
|
||||
|
||||
// The popup that is getting shown on top of mElement.
|
||||
nsCOMPtr<nsIContent> mPopupContent;
|
||||
|
|
|
@ -113,6 +113,7 @@ XPIDLSRCS = \
|
|||
nsIURIFixup.idl \
|
||||
nsIEditorDocShell.idl \
|
||||
nsIWebPageDescriptor.idl \
|
||||
nsIURIClassifier.idl \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = nsDocShellLoadTypes.h
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "nsIDocumentViewer.h"
|
||||
#include "nsIDocumentLoaderFactory.h"
|
||||
#include "nsCURILoader.h"
|
||||
#include "nsURILoader.h"
|
||||
#include "nsDocShellCID.h"
|
||||
#include "nsLayoutCID.h"
|
||||
#include "nsDOMCID.h"
|
||||
|
@ -105,6 +106,7 @@
|
|||
#include "nsIViewManager.h"
|
||||
#include "nsIScrollableView.h"
|
||||
#include "nsIScriptChannel.h"
|
||||
#include "nsIURIClassifier.h"
|
||||
|
||||
// we want to explore making the document own the load group
|
||||
// so we can associate the document URI with the load group.
|
||||
|
@ -2840,6 +2842,7 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI,
|
|||
PRUint32 formatStrCount = 0;
|
||||
nsresult rv = NS_OK;
|
||||
nsAutoString messageStr;
|
||||
nsCAutoString cssClass;
|
||||
|
||||
// Turn the error code into a human readable error message.
|
||||
if (NS_ERROR_UNKNOWN_PROTOCOL == aError) {
|
||||
|
@ -2980,6 +2983,15 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI,
|
|||
// Bad Content Encoding.
|
||||
error.AssignLiteral("contentEncodingError");
|
||||
break;
|
||||
case NS_ERROR_MALWARE_URI:
|
||||
nsCAutoString host;
|
||||
aURI->GetHost(host);
|
||||
CopyUTF8toUTF16(host, formatStrs[0]);
|
||||
formatStrCount = 1;
|
||||
|
||||
error.AssignLiteral("malwareBlocked");
|
||||
cssClass.AssignLiteral("blacklist");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3021,7 +3033,7 @@ nsDocShell::DisplayLoadError(nsresult aError, nsIURI *aURI,
|
|||
if (mUseErrorPages && aURI && aFailedChannel) {
|
||||
// Display an error page
|
||||
LoadErrorPage(aURI, aURL, error.get(), messageStr.get(),
|
||||
aFailedChannel);
|
||||
cssClass.get(), aFailedChannel);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3046,6 +3058,7 @@ NS_IMETHODIMP
|
|||
nsDocShell::LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL,
|
||||
const PRUnichar *aErrorType,
|
||||
const PRUnichar *aDescription,
|
||||
const char *aCSSClass,
|
||||
nsIChannel* aFailedChannel)
|
||||
{
|
||||
#if defined(PR_LOGGING) && defined(DEBUG)
|
||||
|
@ -3110,12 +3123,17 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL,
|
|||
char *escapedCharset = nsEscape(charset.get(), url_Path);
|
||||
char *escapedError = nsEscape(NS_ConvertUTF16toUTF8(aErrorType).get(), url_Path);
|
||||
char *escapedDescription = nsEscape(NS_ConvertUTF16toUTF8(aDescription).get(), url_Path);
|
||||
char *escapedCSSClass = nsEscape(aCSSClass, url_Path);
|
||||
|
||||
nsCString errorPageUrl("about:neterror?e=");
|
||||
|
||||
errorPageUrl.AppendASCII(escapedError);
|
||||
errorPageUrl.AppendLiteral("&u=");
|
||||
errorPageUrl.AppendASCII(escapedUrl);
|
||||
if (escapedCSSClass && escapedCSSClass[0]) {
|
||||
errorPageUrl.AppendASCII("&s=");
|
||||
errorPageUrl.AppendASCII(escapedCSSClass);
|
||||
}
|
||||
errorPageUrl.AppendLiteral("&c=");
|
||||
errorPageUrl.AppendASCII(escapedCharset);
|
||||
errorPageUrl.AppendLiteral("&d=");
|
||||
|
@ -3125,6 +3143,7 @@ nsDocShell::LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL,
|
|||
nsMemory::Free(escapedError);
|
||||
nsMemory::Free(escapedUrl);
|
||||
nsMemory::Free(escapedCharset);
|
||||
nsMemory::Free(escapedCSSClass);
|
||||
|
||||
nsCOMPtr<nsIURI> errorPageURI;
|
||||
nsresult rv = NS_NewURI(getter_AddRefs(errorPageURI), errorPageUrl);
|
||||
|
@ -3204,10 +3223,10 @@ nsDocShell::Reload(PRUint32 aReloadFlags)
|
|||
NS_IMETHODIMP
|
||||
nsDocShell::Stop(PRUint32 aStopFlags)
|
||||
{
|
||||
if (nsIWebNavigation::STOP_CONTENT & aStopFlags) {
|
||||
// Revoke any pending event related to content viewer restoration
|
||||
mRestorePresentationEvent.Revoke();
|
||||
// Revoke any pending event related to content viewer restoration
|
||||
mRestorePresentationEvent.Revoke();
|
||||
|
||||
if (nsIWebNavigation::STOP_CONTENT & aStopFlags) {
|
||||
// Stop the document loading
|
||||
if (mContentViewer)
|
||||
mContentViewer->Stop();
|
||||
|
@ -3222,6 +3241,11 @@ nsDocShell::Stop(PRUint32 aStopFlags)
|
|||
mRefreshURIList = nsnull;
|
||||
}
|
||||
|
||||
if (mClassifier) {
|
||||
mClassifier->Cancel();
|
||||
mClassifier = nsnull;
|
||||
}
|
||||
|
||||
// XXXbz We could also pass |this| to nsIURILoader::Stop. That will
|
||||
// just call Stop() on us as an nsIDocumentLoader... We need fewer
|
||||
// redundant apis!
|
||||
|
@ -4831,6 +4855,17 @@ nsDocShell::OnRedirectStateChange(nsIChannel* aOldChannel,
|
|||
if (!(aStateFlags & STATE_IS_DOCUMENT))
|
||||
return; // not a toplevel document
|
||||
|
||||
// If this load is being checked by the URI classifier, we need to
|
||||
// query the classifier again for the new URI.
|
||||
if (mClassifier) {
|
||||
mClassifier->SetChannel(aNewChannel);
|
||||
|
||||
// we call the nsClassifierCallback:Run() from the main loop to
|
||||
// give the channel a chance to AsyncOpen() the channel before
|
||||
// we suspend it.
|
||||
NS_DispatchToCurrentThread(mClassifier);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIGlobalHistory3> history3(do_QueryInterface(mGlobalHistory));
|
||||
nsresult result = NS_ERROR_NOT_IMPLEMENTED;
|
||||
if (history3) {
|
||||
|
@ -4880,6 +4915,10 @@ nsDocShell::EndPageLoad(nsIWebProgress * aProgress,
|
|||
// during this load handler.
|
||||
//
|
||||
nsCOMPtr<nsIDocShell> kungFuDeathGrip(this);
|
||||
|
||||
// We're done with the URI classifier for this channel
|
||||
mClassifier = nsnull;
|
||||
|
||||
//
|
||||
// Notify the ContentViewer that the Document has finished loading...
|
||||
//
|
||||
|
@ -7244,8 +7283,34 @@ nsresult nsDocShell::DoChannelLoad(nsIChannel * aChannel,
|
|||
rv = aURILoader->OpenURI(aChannel,
|
||||
(mLoadType == LOAD_LINK),
|
||||
this);
|
||||
|
||||
return rv;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = CheckClassifier(aChannel);
|
||||
if (NS_FAILED(rv)) {
|
||||
aChannel->Cancel(rv);
|
||||
return rv;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsDocShell::CheckClassifier(nsIChannel *aChannel)
|
||||
{
|
||||
nsRefPtr<nsClassifierCallback> classifier = new nsClassifierCallback();
|
||||
if (!classifier) return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
classifier->SetChannel(aChannel);
|
||||
nsresult rv = classifier->Run();
|
||||
if (rv == NS_ERROR_FACTORY_NOT_REGISTERED) {
|
||||
// no URI classifier, ignore this
|
||||
return NS_OK;
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
mClassifier = classifier;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -8992,4 +9057,120 @@ nsDocShell::IsAboutBlank(nsIURI* aURI)
|
|||
aURI->GetSpec(str);
|
||||
return str.EqualsLiteral("about:blank");
|
||||
}
|
||||
|
||||
|
||||
//*****************************************************************************
|
||||
// nsClassifierCallback
|
||||
//*****************************************************************************
|
||||
|
||||
NS_IMPL_THREADSAFE_ISUPPORTS2(nsClassifierCallback,
|
||||
nsIURIClassifierCallback,
|
||||
nsIRunnable)
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClassifierCallback::Run()
|
||||
{
|
||||
if (!mChannel) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_ASSERTION(!mSuspendedChannel,
|
||||
"nsClassifierCallback::Run() called while a "
|
||||
"channel is still suspended.");
|
||||
|
||||
nsCOMPtr<nsIChannel> channel;
|
||||
channel.swap(mChannel);
|
||||
|
||||
// Don't bother to run the classifier on a load that has already failed.
|
||||
// (this might happen after a redirect)
|
||||
PRUint32 status;
|
||||
channel->GetStatus(&status);
|
||||
if (NS_FAILED(status))
|
||||
return NS_OK;
|
||||
|
||||
// Don't bother to run the classifier on a load that's coming from the
|
||||
// cache and doesn't need validaton.
|
||||
nsCOMPtr<nsICachingChannel> cachingChannel = do_QueryInterface(channel);
|
||||
if (cachingChannel) {
|
||||
PRBool fromCache;
|
||||
if (NS_SUCCEEDED(cachingChannel->IsFromCache(&fromCache)) &&
|
||||
fromCache) {
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURI> uri;
|
||||
nsresult rv = channel->GetURI(getter_AddRefs(uri));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// XXX: we need to audit other channels to make sure they can handle
|
||||
// being suspended directly after AsyncOpen()
|
||||
nsCOMPtr<nsIHttpChannel> httpChannel = do_QueryInterface(channel);
|
||||
if (!httpChannel) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIURIClassifier> uriClassifier =
|
||||
do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
PRBool expectCallback;
|
||||
rv = uriClassifier->Classify(uri, this, &expectCallback);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
if (expectCallback) {
|
||||
// Suspend the channel, it will be resumed when we get the classifier
|
||||
// callback.
|
||||
rv = channel->Suspend();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
mSuspendedChannel = channel;
|
||||
#ifdef DEBUG
|
||||
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
|
||||
("nsClassifierCallback[%p]: suspended channel %p",
|
||||
this, mSuspendedChannel.get()));
|
||||
#endif
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsClassifierCallback::OnClassifyComplete(nsresult aErrorCode)
|
||||
{
|
||||
if (mSuspendedChannel) {
|
||||
if (NS_FAILED(aErrorCode)) {
|
||||
#ifdef DEBUG
|
||||
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
|
||||
("nsClassifierCallback[%p]: cancelling channel %p with error code: %d",
|
||||
this, mSuspendedChannel.get(), aErrorCode));
|
||||
#endif
|
||||
mSuspendedChannel->Cancel(aErrorCode);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
|
||||
("nsClassifierCallback[%p]: resuming channel %p from OnClassifyComplete",
|
||||
this, mSuspendedChannel.get()));
|
||||
#endif
|
||||
mSuspendedChannel->Resume();
|
||||
mSuspendedChannel = nsnull;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
nsClassifierCallback::Cancel()
|
||||
{
|
||||
if (mSuspendedChannel) {
|
||||
#ifdef DEBUG
|
||||
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
|
||||
("nsClassifierCallback[%p]: resuming channel %p from Cancel()",
|
||||
this, mSuspendedChannel.get()));
|
||||
#endif
|
||||
mSuspendedChannel->Resume();
|
||||
mSuspendedChannel = nsnull;
|
||||
}
|
||||
|
||||
if (mChannel) {
|
||||
mChannel = nsnull;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -105,6 +105,7 @@
|
|||
#include "nsIObserver.h"
|
||||
#include "nsDocShellLoadTypes.h"
|
||||
#include "nsPIDOMEventTarget.h"
|
||||
#include "nsIURIClassifier.h"
|
||||
|
||||
class nsIScrollableView;
|
||||
|
||||
|
@ -141,6 +142,26 @@ protected:
|
|||
virtual ~nsRefreshTimer();
|
||||
};
|
||||
|
||||
class nsClassifierCallback : public nsIURIClassifierCallback
|
||||
, public nsIRunnable
|
||||
{
|
||||
public:
|
||||
nsClassifierCallback() {}
|
||||
~nsClassifierCallback() {}
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIURICLASSIFIERCALLBACK
|
||||
NS_DECL_NSIRUNNABLE
|
||||
|
||||
void SetChannel(nsIChannel * aChannel)
|
||||
{ mChannel = aChannel; }
|
||||
|
||||
void Cancel();
|
||||
private:
|
||||
nsCOMPtr<nsIChannel> mChannel;
|
||||
nsCOMPtr<nsIChannel> mSuspendedChannel;
|
||||
};
|
||||
|
||||
//*****************************************************************************
|
||||
//*** nsDocShell
|
||||
//*****************************************************************************
|
||||
|
@ -260,6 +281,12 @@ protected:
|
|||
nsIChannel * aChannel);
|
||||
virtual nsresult DoChannelLoad(nsIChannel * aChannel,
|
||||
nsIURILoader * aURILoader);
|
||||
|
||||
// Check the channel load against the URI classifier service (if it
|
||||
// exists). The channel will be suspended until the classification is
|
||||
// complete.
|
||||
nsresult CheckClassifier(nsIChannel *aChannel);
|
||||
|
||||
NS_IMETHOD ScrollIfAnchor(nsIURI * aURI, PRBool * aWasAnchor,
|
||||
PRUint32 aLoadType, nscoord *cx, nscoord *cy);
|
||||
|
||||
|
@ -379,6 +406,7 @@ protected:
|
|||
NS_IMETHOD LoadErrorPage(nsIURI *aURI, const PRUnichar *aURL,
|
||||
const PRUnichar *aPage,
|
||||
const PRUnichar *aDescription,
|
||||
const char *aCSSClass,
|
||||
nsIChannel* aFailedChannel);
|
||||
PRBool IsNavigationAllowed(PRBool aDisplayPrintErrorDialog = PR_TRUE);
|
||||
PRBool IsPrintingOrPP(PRBool aDisplayErrorDialog = PR_TRUE);
|
||||
|
@ -612,6 +640,9 @@ protected:
|
|||
// Secure browser UI object
|
||||
nsCOMPtr<nsISecureBrowserUI> mSecurityUI;
|
||||
|
||||
// Suspends/resumes channels based on the URI classifier.
|
||||
nsRefPtr<nsClassifierCallback> mClassifier;
|
||||
|
||||
// WEAK REFERENCES BELOW HERE.
|
||||
// Note these are intentionally not addrefd. Doing so will create a cycle.
|
||||
// For that reasons don't use nsCOMPtr.
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/* ***** 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
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Dave Camp <dcamp@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 GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
interface nsIURI;
|
||||
interface nsIChannel;
|
||||
|
||||
/**
|
||||
* Callback function for nsIURIClassifier lookups.
|
||||
*/
|
||||
[scriptable, function, uuid(8face46e-0c96-470f-af40-0037dcd797bd)]
|
||||
interface nsIURIClassifierCallback : nsISupports
|
||||
{
|
||||
/**
|
||||
* Called by the URI classifier service when it is done checking a URI.
|
||||
*
|
||||
* Clients are responsible for associating callback objects with classify()
|
||||
* calls.
|
||||
*
|
||||
* @param aErrorCode
|
||||
* The error code with which the channel should be cancelled, or
|
||||
* NS_OK if the load should continue normally.
|
||||
*/
|
||||
void onClassifyComplete(in nsresult aErrorCode);
|
||||
};
|
||||
|
||||
/**
|
||||
* The URI classifier service checks a URI against lists of phishing
|
||||
* and malware sites.
|
||||
*/
|
||||
[scriptable, uuid(2de5c563-1203-43dd-a212-f5d56d530b6f)]
|
||||
interface nsIURIClassifier : nsISupports
|
||||
{
|
||||
/**
|
||||
* Classify a URI.
|
||||
*
|
||||
* @param aURI
|
||||
* The URI that should be checked by the URI classifier.
|
||||
* @param aCallback
|
||||
* The URI classifier will call this callback when the URI has been
|
||||
* classified.
|
||||
*
|
||||
* @return <code>false</code> if classification is not necessary. The
|
||||
* callback will not be called.
|
||||
* <code>true</code> if classification will be performed. The
|
||||
* callback will be called.
|
||||
*/
|
||||
boolean classify(in nsIURI aURI,
|
||||
in nsIURIClassifierCallback aCallback);
|
||||
};
|
|
@ -85,6 +85,7 @@
|
|||
#include "nsIDocShellTreeNode.h"
|
||||
#include "nsIDocShellTreeOwner.h"
|
||||
#include "nsCURILoader.h"
|
||||
#include "nsURILoader.h"
|
||||
#include "nsIDOMWindowInternal.h"
|
||||
#include "nsEscape.h"
|
||||
#include "nsIPlatformCharset.h"
|
||||
|
@ -124,6 +125,8 @@
|
|||
#include "nsIScriptSecurityManager.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
|
||||
#include "nsIURIClassifier.h"
|
||||
|
||||
#ifdef NS_DEBUG
|
||||
/**
|
||||
* Note: the log module is created during initialization which
|
||||
|
@ -815,7 +818,7 @@ nsWebShell::OnLinkClickSync(nsIContent *aContent,
|
|||
PRBool isExposed;
|
||||
nsresult rv = extProtService->IsExposedProtocol(scheme.get(), &isExposed);
|
||||
if (NS_SUCCEEDED(rv) && !isExposed) {
|
||||
return extProtService->LoadUrl(aURI);
|
||||
return extProtService->LoadURI(aURI, this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1191,6 +1194,7 @@ nsresult nsWebShell::EndPageLoad(nsIWebProgress *aProgress,
|
|||
aStatus == NS_ERROR_UNKNOWN_SOCKET_TYPE ||
|
||||
aStatus == NS_ERROR_NET_INTERRUPT ||
|
||||
aStatus == NS_ERROR_NET_RESET ||
|
||||
aStatus == NS_ERROR_MALWARE_URI ||
|
||||
NS_ERROR_GET_MODULE(aStatus) == NS_ERROR_MODULE_SECURITY) {
|
||||
DisplayLoadError(aStatus, url, nsnull, channel);
|
||||
}
|
||||
|
|
|
@ -49,6 +49,12 @@
|
|||
#define NS_WEBNAVIGATION_INFO_CONTRACTID \
|
||||
"@mozilla.org/webnavigation-info;1"
|
||||
|
||||
/**
|
||||
* Contract ID for a service implementing nsIURIClassifier that identifies
|
||||
* phishing and malware sites.
|
||||
*/
|
||||
#define NS_URICLASSIFIERSERVICE_CONTRACTID "@mozilla.org/uriclassifierservice"
|
||||
|
||||
/**
|
||||
* An observer service topic that can be listened to to catch creation
|
||||
* of content browsing areas (both toplevel ones and subframes). The
|
||||
|
|
|
@ -67,7 +67,7 @@
|
|||
// or optionally, to specify an alternate CSS class to allow for
|
||||
// custom styling and favicon:
|
||||
//
|
||||
// moz-neterror:page?c=classname&e=error&u=url&d=desc
|
||||
// moz-neterror:page?e=error&u=url&s=classname&d=desc
|
||||
|
||||
// Note that this file uses document.documentURI to get
|
||||
// the URL (with the format from above). This is because
|
||||
|
@ -86,14 +86,13 @@
|
|||
function getCSSClass()
|
||||
{
|
||||
var url = document.documentURI;
|
||||
var classParam = url.search(/c\=/);
|
||||
|
||||
// c is optional, if classParam == -1 just return nothing
|
||||
if (classParam == -1)
|
||||
var matches = url.match(/s\=([^&]+)\&/);
|
||||
// s is optional, if no match just return nothing
|
||||
if (!matches || matches.length < 2)
|
||||
return "";
|
||||
|
||||
var rest = url.search(/\&/);
|
||||
return decodeURIComponent(url.slice(classParam + 2, rest));
|
||||
|
||||
// parenthetical match is the second entry
|
||||
return decodeURIComponent(matches[1]);
|
||||
}
|
||||
|
||||
function getDescription()
|
||||
|
|
|
@ -45,6 +45,8 @@ include $(topsrcdir)/config/rules.mk
|
|||
|
||||
_BROWSER_TEST_FILES = \
|
||||
browser_bug349769.js \
|
||||
browser_bug388121-1.js \
|
||||
browser_bug388121-2.js \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_BROWSER_TEST_FILES)
|
||||
|
|
|
@ -11,6 +11,7 @@ function test() {
|
|||
|
||||
function testLoad(event) {
|
||||
newBrowser.removeEventListener("load", testLoad, true);
|
||||
is (event.target, newBrowser.contentDocument, "Unexpected target");
|
||||
var prin = newBrowser.contentDocument.nodePrincipal;
|
||||
isnot(prin, null, "Loaded principal must not be null when adding " + uri);
|
||||
isnot(prin, undefined, "Loaded principal must not be undefined when loading " + uri);
|
||||
|
|
|
@ -0,0 +1,27 @@
|
|||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
var newTab;
|
||||
var newBrowser;
|
||||
const secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"].
|
||||
getService(Components.interfaces.nsIScriptSecurityManager);
|
||||
|
||||
function testLoad(event) {
|
||||
newBrowser.removeEventListener("load", testLoad, true);
|
||||
is (event.target, newBrowser.contentDocument, "Unexpected target");
|
||||
var prin = newBrowser.contentDocument.nodePrincipal;
|
||||
isnot(prin, null, "Loaded principal must not be null");
|
||||
isnot(prin, undefined, "Loaded principal must not be undefined");
|
||||
is(secMan.isSystemPrincipal(prin), false,
|
||||
"Loaded principal must not be system");
|
||||
gBrowser.removeTab(newTab);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
newTab = gBrowser.addTab();
|
||||
newBrowser = gBrowser.getBrowserForTab(newTab);
|
||||
newBrowser.contentWindow.location.href = "about:blank"
|
||||
newBrowser.addEventListener("load", testLoad, true);
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
var w;
|
||||
const secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"].
|
||||
getService(Components.interfaces.nsIScriptSecurityManager);
|
||||
var iteration = 1;
|
||||
const uris = ["", "about:blank"];
|
||||
var uri;
|
||||
var origDoc;
|
||||
|
||||
function testLoad() {
|
||||
if (w.document == origDoc) {
|
||||
// Go back to polling
|
||||
setTimeout(testLoad, 10);
|
||||
return;
|
||||
}
|
||||
var prin = w.document.nodePrincipal;
|
||||
isnot(prin, null, "Loaded principal must not be null when adding " + uri);
|
||||
isnot(prin, undefined, "Loaded principal must not be undefined when loading " + uri);
|
||||
is(secMan.isSystemPrincipal(prin), false,
|
||||
"Loaded principal must not be system when loading " + uri);
|
||||
w.close();
|
||||
|
||||
if (iteration == uris.length) {
|
||||
finish();
|
||||
} else {
|
||||
++iteration;
|
||||
doTest();
|
||||
}
|
||||
}
|
||||
|
||||
function doTest() {
|
||||
uri = uris[iteration - 1];
|
||||
w = window.open(uri, "_blank", "width=10,height=10");
|
||||
var prin = w.document.nodePrincipal;
|
||||
if (!uri) {
|
||||
uri = undefined;
|
||||
}
|
||||
isnot(prin, null, "Forced principal must not be null when loading " + uri);
|
||||
isnot(prin, undefined,
|
||||
"Forced principal must not be undefined when loading " + uri);
|
||||
is(secMan.isSystemPrincipal(prin), false,
|
||||
"Forced principal must not be system when loading " + uri);
|
||||
if (uri == undefined) {
|
||||
// No actual load here, so just move along.
|
||||
w.close();
|
||||
++iteration;
|
||||
doTest();
|
||||
} else {
|
||||
origDoc = w.document;
|
||||
// Need to poll, because load listeners on the content window won't
|
||||
// survive the load.
|
||||
setTimeout(testLoad, 10);
|
||||
}
|
||||
}
|
||||
|
||||
doTest();
|
||||
}
|
|
@ -59,3 +59,4 @@ externalProtocolPrompt=An external application must be launched to handle %1$S:
|
|||
externalProtocolUnknown=<Unknown>
|
||||
externalProtocolChkMsg=Remember my choice for all links of this type.
|
||||
externalProtocolLaunchBtn=Launch application
|
||||
malwareBlocked=The site at %S has been reported as an attack site and has been blocked based on your security preferences.
|
||||
|
|
|
@ -255,7 +255,9 @@ main(int argc, char **argv)
|
|||
gtk_signal_connect(GTK_OBJECT(single), "new_window_orphan",
|
||||
GTK_SIGNAL_FUNC(new_window_orphan_cb), NULL);
|
||||
|
||||
gtk_moz_embed_push_startup();
|
||||
gtk_main();
|
||||
gtk_moz_embed_pop_startup();
|
||||
}
|
||||
|
||||
static TestGtkBrowser *
|
||||
|
|
|
@ -43,9 +43,7 @@
|
|||
#include "nsRect.h"
|
||||
#include "gfxRect.h"
|
||||
|
||||
#ifdef MOZ_CAIRO_GFX
|
||||
class gfxASurface;
|
||||
#endif
|
||||
|
||||
class nsIDeviceContext;
|
||||
|
||||
|
@ -72,13 +70,6 @@ typedef enum {
|
|||
#define nsImageUpdateFlags_kColorMapChanged 0x1
|
||||
#define nsImageUpdateFlags_kBitsChanged 0x2
|
||||
|
||||
#ifndef MOZ_CAIRO_GFX
|
||||
// The following platforms store image data rows bottom-up.
|
||||
#if defined(XP_WIN) || defined(XP_OS2) || defined(XP_MACOSX)
|
||||
#define MOZ_PLATFORM_IMAGES_BOTTOM_TO_TOP
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// IID for the nsIImage interface
|
||||
// fd31e1f2-bd46-47f1-b8b6-b94ce954f9ce
|
||||
#define NS_IIMAGE_IID \
|
||||
|
|
|
@ -1226,7 +1226,7 @@ public:
|
|||
* be treated as invisible and zero-width.
|
||||
*/
|
||||
static PRBool IsInvalidChar(PRUnichar ch) {
|
||||
return ch == '\t' || ch == '\r' || ch == '\n' ||
|
||||
return ch == '\t' || ch == '\r' || ch == '\n' || ch == '\f' ||
|
||||
ch == 0x200B/*ZWSP*/ || ch == 0x2028/*LSEP*/ || ch == 0x2029/*PSEP*/;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
#include "gfxRect.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "nsMathUtils.h"
|
||||
|
||||
gfxRect
|
||||
gfxRect::Intersect(const gfxRect& aRect) const
|
||||
|
@ -76,10 +76,10 @@ gfxRect::Union(const gfxRect& aRect) const
|
|||
void
|
||||
gfxRect::Round()
|
||||
{
|
||||
gfxFloat x0 = floor(X() + 0.5);
|
||||
gfxFloat y0 = floor(Y() + 0.5);
|
||||
gfxFloat x1 = floor(XMost() + 0.5);
|
||||
gfxFloat y1 = floor(YMost() + 0.5);
|
||||
gfxFloat x0 = NS_round(X());
|
||||
gfxFloat y0 = NS_round(Y());
|
||||
gfxFloat x1 = NS_round(XMost());
|
||||
gfxFloat y1 = NS_round(YMost());
|
||||
|
||||
pos.x = x0;
|
||||
pos.y = y0;
|
||||
|
|
|
@ -243,9 +243,6 @@ TextRunWordCache::LookupWord(gfxTextRun *aTextRun, gfxFont *aFirstFont,
|
|||
if (fontEntry->mTextRun) {
|
||||
existingEntry = fontEntry;
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
++aTextRun->mCachedWords;
|
||||
#endif
|
||||
PR_LOG(gWordCacheLog, PR_LOG_DEBUG, ("%p(%d-%d,%d): added using font", aTextRun, aStart, aEnd - aStart, aHash));
|
||||
key.mFontOrGroup = aTextRun->GetFontGroup();
|
||||
CacheHashEntry *groupEntry = mCache.GetEntry(key);
|
||||
|
@ -273,6 +270,9 @@ TextRunWordCache::LookupWord(gfxTextRun *aTextRun, gfxFont *aFirstFont,
|
|||
return PR_TRUE;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
++aTextRun->mCachedWords;
|
||||
#endif
|
||||
// Set up the cache entry so that if later in this textrun we hit this
|
||||
// entry, we'll copy within our own textrun
|
||||
fontEntry->mTextRun = aTextRun;
|
||||
|
|
|
@ -49,14 +49,11 @@ NS_GetComplexLineBreaks(const PRUnichar* aText, PRUint32 aLength,
|
|||
{
|
||||
NS_ASSERTION(aText, "aText shouldn't be null");
|
||||
|
||||
memset(aBreakBefore, PR_FALSE, aLength * sizeof(PRPackedBool));
|
||||
|
||||
nsAutoTArray<PangoLogAttr, 2000> attrBuffer;
|
||||
if (!attrBuffer.AppendElements(aLength + 1))
|
||||
{
|
||||
// out of memory, behave as if there were no complex line breaker
|
||||
for (PRUint32 i = 0; i < aLength; ++i) {
|
||||
aBreakBefore[i] = PR_FALSE;
|
||||
}
|
||||
}
|
||||
return;
|
||||
|
||||
NS_ConvertUTF16toUTF8 aUTF8(aText, aLength);
|
||||
|
||||
|
|
|
@ -2350,8 +2350,13 @@ js_dtoa(double d, int mode, JSBool biasUp, int ndigits,
|
|||
*s++ = '0' + (char)L;
|
||||
if (d < eps)
|
||||
goto ret1;
|
||||
if (1. - d < eps)
|
||||
if (1. - d < eps) {
|
||||
#ifdef DEBUG
|
||||
/* Clear d to avoid precision warning. */
|
||||
d = 0;
|
||||
#endif
|
||||
goto bump_up;
|
||||
}
|
||||
if (++i >= ilim)
|
||||
break;
|
||||
eps *= 10.;
|
||||
|
@ -2367,8 +2372,13 @@ js_dtoa(double d, int mode, JSBool biasUp, int ndigits,
|
|||
d -= L;
|
||||
*s++ = '0' + (char)L;
|
||||
if (i == ilim) {
|
||||
if (d > 0.5 + eps)
|
||||
if (d > 0.5 + eps) {
|
||||
#ifdef DEBUG
|
||||
/* Clear d to avoid precision warning. */
|
||||
d = 0;
|
||||
#endif
|
||||
goto bump_up;
|
||||
}
|
||||
else if (d < 0.5 - eps) {
|
||||
while(*--s == '0') ;
|
||||
s++;
|
||||
|
|
|
@ -487,8 +487,17 @@ nsBidiPresUtils::InitLogicalArray(nsIFrame* aCurrentFrame)
|
|||
for (nsIFrame* childFrame = aCurrentFrame; childFrame;
|
||||
childFrame = childFrame->GetNextSibling()) {
|
||||
|
||||
nsIFrame* frame = (nsGkAtoms::placeholderFrame == childFrame->GetType()) ?
|
||||
nsPlaceholderFrame::GetRealFrameFor(childFrame) : childFrame;
|
||||
// If the real frame for a placeholder is an inline container, we need to
|
||||
// drill down into it and include its contents in Bidi resolution. If it
|
||||
// isn't an inline container, we just use the placeholder.
|
||||
nsIFrame* frame = childFrame;
|
||||
if (nsGkAtoms::placeholderFrame == childFrame->GetType()) {
|
||||
nsIFrame* realFrame =
|
||||
nsPlaceholderFrame::GetRealFrameForPlaceholder(childFrame);
|
||||
if (realFrame->IsFrameOfType(nsIFrame::eBidiInlineContainer)) {
|
||||
frame = realFrame;
|
||||
}
|
||||
}
|
||||
|
||||
PRUnichar ch = 0;
|
||||
if (frame->IsFrameOfType(nsIFrame::eBidiInlineContainer)) {
|
||||
|
|
|
@ -1647,12 +1647,13 @@ static void
|
|||
MoveChildrenTo(nsFrameManager* aFrameManager,
|
||||
nsIFrame* aNewParent,
|
||||
nsIFrame* aFrameList,
|
||||
nsIFrame* aFrameListEnd,
|
||||
nsFrameConstructorState* aState,
|
||||
nsFrameConstructorState* aOuterState)
|
||||
{
|
||||
PRBool setHasChildWithView = PR_FALSE;
|
||||
|
||||
while (aFrameList) {
|
||||
while (aFrameList && aFrameList != aFrameListEnd) {
|
||||
if (!setHasChildWithView
|
||||
&& (aFrameList->GetStateBits() & (NS_FRAME_HAS_VIEW | NS_FRAME_HAS_CHILD_WITH_VIEW))) {
|
||||
setHasChildWithView = PR_TRUE;
|
||||
|
@ -12465,7 +12466,8 @@ nsCSSFrameConstructor::ConstructInline(nsFrameConstructorState& aState,
|
|||
// parent block of the inline, but its parent pointer will be the anonymous
|
||||
// block we create... AdjustFloatParentPtrs() deals with this by moving the
|
||||
// float from the outer state |aState| to the inner |state|.
|
||||
MoveChildrenTo(state.mFrameManager, blockFrame, list2, &state, &aState);
|
||||
MoveChildrenTo(state.mFrameManager, blockFrame, list2, nsnull, &state,
|
||||
&aState);
|
||||
|
||||
// list3's frames belong to another inline frame
|
||||
nsIFrame* inlineFrame = nsnull;
|
||||
|
@ -12553,7 +12555,8 @@ nsCSSFrameConstructor::MoveFramesToEndOfIBSplit(nsFrameConstructorState& aState,
|
|||
}
|
||||
|
||||
// Reparent (cheaply) the frames in list3
|
||||
if (!inlineFrame->GetFirstChild(nsnull) &&
|
||||
nsIFrame* existingFirstChild = inlineFrame->GetFirstChild(nsnull);
|
||||
if (!existingFirstChild &&
|
||||
(inlineFrame->GetStateBits() & NS_FRAME_FIRST_REFLOW)) {
|
||||
inlineFrame->SetInitialChildList(nsnull, aFramesToMove);
|
||||
} else {
|
||||
|
@ -12561,7 +12564,7 @@ nsCSSFrameConstructor::MoveFramesToEndOfIBSplit(nsFrameConstructorState& aState,
|
|||
}
|
||||
nsFrameConstructorState* startState = aTargetState ? &aState : nsnull;
|
||||
MoveChildrenTo(aState.mFrameManager, inlineFrame, aFramesToMove,
|
||||
aTargetState, startState);
|
||||
existingFirstChild, aTargetState, startState);
|
||||
SetFrameIsSpecial(inlineFrame, nsnull);
|
||||
return inlineFrame;
|
||||
}
|
||||
|
|
|
@ -4437,7 +4437,7 @@ nsCSSRendering::PaintDecorationLine(gfxContext* aGfxContext,
|
|||
|
||||
// round to device pixels for suppressing the AA.
|
||||
gfxFloat x = NS_round(aPt.x);
|
||||
gfxFloat y = NS_round(aPt.y + aAscent - offset);
|
||||
gfxFloat y = NS_round(aPt.y + aAscent) - NS_round(offset);
|
||||
gfxFloat width = NS_round(aLineSize.width);
|
||||
gfxFloat height = NS_round(aLineSize.height);
|
||||
// The y position should be set to the middle of the line.
|
||||
|
|
|
@ -374,6 +374,7 @@ private:
|
|||
nsresult GetDocumentSelection(nsISelection **aSelection);
|
||||
|
||||
nsresult GetClipboardEventTarget(nsIDOMNode **aEventTarget);
|
||||
nsresult FireClipboardEvent(PRUint32 msg, PRBool* aPreventDefault);
|
||||
|
||||
#ifdef NS_PRINTING
|
||||
// Called when the DocViewer is notified that the state
|
||||
|
@ -2317,26 +2318,10 @@ NS_IMETHODIMP DocumentViewerImpl::SelectAll()
|
|||
|
||||
NS_IMETHODIMP DocumentViewerImpl::CopySelection()
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
// Fire the copy event.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
||||
rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent evt(PR_TRUE, NS_COPY);
|
||||
nsEventDispatcher::Dispatch(eventTarget, mPresContext, &evt, nsnull,
|
||||
&status);
|
||||
// if event handler return'd false (PreventDefault)
|
||||
if (status == nsEventStatus_eConsumeNoDefault)
|
||||
// Skip default behavior, return OK.
|
||||
return NS_OK;
|
||||
// It's possible the oncopy handler closed the window.
|
||||
if (!mPresShell)
|
||||
return NS_OK;
|
||||
}
|
||||
PRBool preventDefault;
|
||||
nsresult rv = FireClipboardEvent(NS_COPY, &preventDefault);
|
||||
if (NS_FAILED(rv) || preventDefault)
|
||||
return rv;
|
||||
|
||||
return mPresShell->DoCopy();
|
||||
}
|
||||
|
@ -2389,36 +2374,54 @@ nsresult DocumentViewerImpl::GetClipboardEventTarget(nsIDOMNode** aEventTarget)
|
|||
return nsCopySupport::GetClipboardEventTarget(sel, aEventTarget);
|
||||
}
|
||||
|
||||
nsresult DocumentViewerImpl::FireClipboardEvent(PRUint32 msg,
|
||||
PRBool* aPreventDefault)
|
||||
{
|
||||
*aPreventDefault = PR_FALSE;
|
||||
|
||||
NS_ENSURE_TRUE(mPresContext, NS_ERROR_NOT_INITIALIZED);
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
// It seems to be unsafe to fire an event handler during reflow (bug 393696)
|
||||
PRBool isReflowing = PR_TRUE;
|
||||
nsresult rv = mPresShell->IsReflowLocked(&isReflowing);
|
||||
if (NS_FAILED(rv) || isReflowing)
|
||||
return NS_OK;
|
||||
|
||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
||||
rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
if (NS_FAILED(rv))
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
return NS_OK;
|
||||
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent evt(PR_TRUE, msg);
|
||||
nsEventDispatcher::Dispatch(eventTarget, mPresContext, &evt, nsnull,
|
||||
&status);
|
||||
// if event handler return'd false (PreventDefault)
|
||||
if (status == nsEventStatus_eConsumeNoDefault)
|
||||
*aPreventDefault = PR_TRUE;
|
||||
|
||||
// Ensure that the calling function can use mPresShell -- if the event
|
||||
// handler closed this window, mPresShell will be gone.
|
||||
NS_ENSURE_STATE(mPresShell);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP DocumentViewerImpl::GetCopyable(PRBool *aCopyable)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aCopyable);
|
||||
*aCopyable = PR_FALSE;
|
||||
|
||||
NS_ENSURE_TRUE(mPresShell, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
// Fire the beforecopy event. If the event handler requests to prevent
|
||||
// default behavior, set *aCopyable = true. (IE-style behavior)
|
||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
||||
nsresult rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent evt(PR_TRUE, NS_BEFORECOPY);
|
||||
nsEventDispatcher::Dispatch(eventTarget, mPresContext, &evt, nsnull,
|
||||
&status);
|
||||
// if event handler return'd false (PreventDefault)
|
||||
if (status == nsEventStatus_eConsumeNoDefault) {
|
||||
*aCopyable = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
// It's possible the onbeforecopy handler closed the window.
|
||||
if (!mPresShell)
|
||||
return NS_OK;
|
||||
}
|
||||
nsresult rv = FireClipboardEvent(NS_BEFORECOPY, aCopyable);
|
||||
if (NS_FAILED(rv) || *aCopyable)
|
||||
return rv;
|
||||
|
||||
nsCOMPtr<nsISelection> selection;
|
||||
rv = mPresShell->GetSelectionForCopy(getter_AddRefs(selection));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
|
||||
PRBool isCollapsed;
|
||||
selection->GetIsCollapsed(&isCollapsed);
|
||||
|
@ -2429,21 +2432,10 @@ NS_IMETHODIMP DocumentViewerImpl::GetCopyable(PRBool *aCopyable)
|
|||
|
||||
NS_IMETHODIMP DocumentViewerImpl::CutSelection()
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresContext, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
// Fire the cut event.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
||||
rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsEvent evt(PR_TRUE, NS_CUT);
|
||||
nsEventDispatcher::Dispatch(eventTarget, mPresContext, &evt);
|
||||
// should skip default behavior here if event handler returns false, but
|
||||
// there is no default behavior to worry about.
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
// preventDefault's value is ignored because cut from the document has no
|
||||
// default behaviour.
|
||||
PRBool preventDefault;
|
||||
return FireClipboardEvent(NS_CUT, &preventDefault);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP DocumentViewerImpl::GetCutable(PRBool *aCutable)
|
||||
|
@ -2451,46 +2443,17 @@ NS_IMETHODIMP DocumentViewerImpl::GetCutable(PRBool *aCutable)
|
|||
NS_ENSURE_ARG_POINTER(aCutable);
|
||||
*aCutable = PR_FALSE;
|
||||
|
||||
NS_ENSURE_TRUE(mPresContext, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
// Fire the beforecut event. If the event handler requests to prevent
|
||||
// default behavior, set *aCutable = true. (IE-style behavior)
|
||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
||||
nsresult rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent evt(PR_TRUE, NS_BEFORECUT);
|
||||
nsEventDispatcher::Dispatch(eventTarget, mPresContext, &evt, nsnull,
|
||||
&status);
|
||||
// if event handler return'd false (PreventDefault)
|
||||
if (status == nsEventStatus_eConsumeNoDefault) {
|
||||
*aCutable = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
*aCutable = PR_FALSE; // mm, will this ever be called for an editable document?
|
||||
return NS_OK;
|
||||
// If event handler requests to prevent default behavior, enable
|
||||
// the cut command -- pass aCutable in as aPreventDefault.
|
||||
return FireClipboardEvent(NS_BEFORECUT, aCutable);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP DocumentViewerImpl::Paste()
|
||||
{
|
||||
NS_ENSURE_TRUE(mPresContext, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
// Fire the paste event.
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
||||
rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsEvent evt(PR_TRUE, NS_PASTE);
|
||||
nsEventDispatcher::Dispatch(eventTarget, mPresContext, &evt);
|
||||
// should skip default behavior here if event handler returns false, but
|
||||
// there is no default behavior to worry about.
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
// preventDefault's value is ignored because paste into the document has no
|
||||
// default behaviour.
|
||||
PRBool preventDefault;
|
||||
return FireClipboardEvent(NS_PASTE, &preventDefault);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP DocumentViewerImpl::GetPasteable(PRBool *aPasteable)
|
||||
|
@ -2498,27 +2461,9 @@ NS_IMETHODIMP DocumentViewerImpl::GetPasteable(PRBool *aPasteable)
|
|||
NS_ENSURE_ARG_POINTER(aPasteable);
|
||||
*aPasteable = PR_FALSE;
|
||||
|
||||
NS_ENSURE_TRUE(mPresContext, NS_ERROR_NOT_INITIALIZED);
|
||||
|
||||
// Fire the beforepaste event. If the event handler requests to prevent
|
||||
// default behavior, set *aPasteable = true. (IE-style behavior)
|
||||
nsCOMPtr<nsIDOMNode> eventTarget;
|
||||
nsresult rv = GetClipboardEventTarget(getter_AddRefs(eventTarget));
|
||||
// On failure to get event target, just forget about it and don't fire.
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
nsEventStatus status = nsEventStatus_eIgnore;
|
||||
nsEvent evt(PR_TRUE, NS_BEFOREPASTE);
|
||||
nsEventDispatcher::Dispatch(eventTarget, mPresContext, &evt, nsnull,
|
||||
&status);
|
||||
// if event handler return'd false (PreventDefault)
|
||||
if (status == nsEventStatus_eConsumeNoDefault) {
|
||||
*aPasteable = PR_TRUE;
|
||||
return NS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
*aPasteable = PR_FALSE;
|
||||
return NS_OK;
|
||||
// If event handler requests to prevent default behavior, enable
|
||||
// the paste command -- pass aPasteable in as aPreventDefault.
|
||||
return FireClipboardEvent(NS_BEFOREPASTE, aPasteable);
|
||||
}
|
||||
|
||||
/* AString getContents (in string mimeType, in boolean selectionOnly); */
|
||||
|
|
|
@ -4401,7 +4401,14 @@ PresShell::DoFlushPendingNotifications(mozFlushType aType,
|
|||
// batching if we only have style reresolve
|
||||
viewManager->BeginUpdateViewBatch();
|
||||
|
||||
mFrameConstructor->ProcessPendingRestyles();
|
||||
// Force flushing of any pending content notifications that might have
|
||||
// queued up while our event was pending. That will ensure that we don't
|
||||
// construct frames for content right now that's still waiting to be
|
||||
// notified on,
|
||||
mDocument->FlushPendingNotifications(Flush_ContentAndNotify);
|
||||
if (!mIsDestroying) {
|
||||
mFrameConstructor->ProcessPendingRestyles();
|
||||
}
|
||||
|
||||
if (aType >= Flush_Layout && !mIsDestroying) {
|
||||
mFrameConstructor->RecalcQuotesAndCounters();
|
||||
|
|
|
@ -611,6 +611,7 @@ nsBlockFrame::MarkIntrinsicWidthsDirty()
|
|||
nsBlockFrame* dirtyBlock = NS_STATIC_CAST(nsBlockFrame*, GetFirstContinuation());
|
||||
dirtyBlock->mMinWidth = NS_INTRINSIC_WIDTH_UNKNOWN;
|
||||
dirtyBlock->mPrefWidth = NS_INTRINSIC_WIDTH_UNKNOWN;
|
||||
dirtyBlock->AddStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
|
||||
|
||||
nsBlockFrameSuper::MarkIntrinsicWidthsDirty();
|
||||
}
|
||||
|
@ -635,10 +636,10 @@ nsBlockFrame::GetMinWidth(nsIRenderingContext *aRenderingContext)
|
|||
AutoNoisyIndenter indent(gNoisyIntrinsic);
|
||||
#endif
|
||||
|
||||
ResolveBidi();
|
||||
InlineMinWidthData data;
|
||||
for (nsBlockFrame* curFrame = this; curFrame;
|
||||
curFrame = NS_STATIC_CAST(nsBlockFrame*, curFrame->GetNextContinuation())) {
|
||||
curFrame->ResolveBidi();
|
||||
for (line_iterator line = curFrame->begin_lines(), line_end = curFrame->end_lines();
|
||||
line != line_end; ++line)
|
||||
{
|
||||
|
@ -706,10 +707,10 @@ nsBlockFrame::GetPrefWidth(nsIRenderingContext *aRenderingContext)
|
|||
AutoNoisyIndenter indent(gNoisyIntrinsic);
|
||||
#endif
|
||||
|
||||
ResolveBidi();
|
||||
InlinePrefWidthData data;
|
||||
for (nsBlockFrame* curFrame = this; curFrame;
|
||||
curFrame = NS_STATIC_CAST(nsBlockFrame*, curFrame->GetNextContinuation())) {
|
||||
curFrame->ResolveBidi();
|
||||
for (line_iterator line = curFrame->begin_lines(), line_end = curFrame->end_lines();
|
||||
line != line_end; ++line)
|
||||
{
|
||||
|
@ -3172,7 +3173,7 @@ nsBlockFrame::ReflowInlineFrames(nsBlockReflowState& aState,
|
|||
// Then the nsLineLayout object was shrunk to 156 bytes by
|
||||
// removing some internal buffers. Given that it is so much
|
||||
// smaller, the complexity of 2 different ways of allocating
|
||||
// no longer makes sense. Now we always allocate on the stack
|
||||
// no longer makes sense. Now we always allocate on the stack.
|
||||
nsLineLayout lineLayout(aState.mPresContext,
|
||||
aState.mReflowState.mSpaceManager,
|
||||
&aState.mReflowState, &aLine);
|
||||
|
@ -6175,6 +6176,9 @@ nsBlockFrame::Init(nsIContent* aContent,
|
|||
|
||||
nsresult rv = nsBlockFrameSuper::Init(aContent, aParent, aPrevInFlow);
|
||||
|
||||
if (!aPrevInFlow)
|
||||
AddStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
@ -6589,28 +6593,41 @@ nsBlockFrame::BlockNeedsSpaceManager(nsIFrame* aBlock)
|
|||
return (aBlock->GetStateBits() & NS_BLOCK_SPACE_MGR) ||
|
||||
(parent && !parent->IsFloatContainingBlock());
|
||||
}
|
||||
|
||||
// XXX keep the text-run data in the first-in-flow of the block
|
||||
|
||||
|
||||
#ifdef IBMBIDI
|
||||
nsresult
|
||||
nsBlockFrame::ResolveBidi()
|
||||
{
|
||||
NS_ASSERTION(!GetPrevInFlow(),
|
||||
"ResolveBidi called on non-first continuation");
|
||||
|
||||
if (!(GetStateBits() & NS_BLOCK_NEEDS_BIDI_RESOLUTION))
|
||||
return NS_OK;
|
||||
|
||||
RemoveStateBits(NS_BLOCK_NEEDS_BIDI_RESOLUTION);
|
||||
|
||||
nsPresContext* presContext = PresContext();
|
||||
if (!presContext->BidiEnabled()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
if (mLines.empty()) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsBidiPresUtils* bidiUtils = presContext->GetBidiUtils();
|
||||
if (!bidiUtils)
|
||||
return NS_OK;
|
||||
return NS_ERROR_NULL_POINTER;
|
||||
|
||||
return bidiUtils->Resolve(this, mLines.front()->mFirstChild,
|
||||
IsVisualFormControl(presContext));
|
||||
for (nsBlockFrame* curFrame = this;
|
||||
curFrame; curFrame = NS_STATIC_CAST(nsBlockFrame*,
|
||||
curFrame->GetNextContinuation())) {
|
||||
if (!curFrame->mLines.empty()) {
|
||||
nsresult rv = bidiUtils->Resolve(curFrame,
|
||||
curFrame->mLines.front()->mFirstChild,
|
||||
IsVisualFormControl(presContext));
|
||||
if (NS_FAILED(rv))
|
||||
return rv;
|
||||
}
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRBool
|
||||
|
|
|
@ -109,6 +109,7 @@ class nsIntervalSet;
|
|||
*/
|
||||
|
||||
// see nsHTMLParts.h for the public block state bits
|
||||
#define NS_BLOCK_NEEDS_BIDI_RESOLUTION 0x00100000
|
||||
#define NS_BLOCK_HAS_LINE_CURSOR 0x01000000
|
||||
#define NS_BLOCK_HAS_OVERFLOW_LINES 0x02000000
|
||||
#define NS_BLOCK_HAS_OVERFLOW_OUT_OF_FLOWS 0x04000000
|
||||
|
|
|
@ -688,7 +688,7 @@ nsBlockReflowState::CanPlaceFloat(const nsSize& aFloatSize,
|
|||
}
|
||||
|
||||
// See if there is now enough height for the float.
|
||||
if (yb < mY + mAvailSpaceRect.height) {
|
||||
if (yb <= mY + mAvailSpaceRect.height) {
|
||||
// Winner. The bottom Y coordinate of the float is in
|
||||
// this band.
|
||||
break;
|
||||
|
|
|
@ -5617,12 +5617,8 @@ nsIFrame::IsFocusable(PRInt32 *aTabIndex, PRBool aWithMouse)
|
|||
// will be enough to make them keyboard scrollable.
|
||||
nsCOMPtr<nsIScrollableFrame> scrollFrame = do_QueryInterface(this);
|
||||
if (scrollFrame) {
|
||||
nsIScrollableFrame::ScrollbarStyles styles =
|
||||
scrollFrame->GetScrollbarStyles();
|
||||
if (styles.mVertical == NS_STYLE_OVERFLOW_SCROLL ||
|
||||
styles.mVertical == NS_STYLE_OVERFLOW_AUTO ||
|
||||
styles.mHorizontal == NS_STYLE_OVERFLOW_SCROLL ||
|
||||
styles.mHorizontal == NS_STYLE_OVERFLOW_AUTO) {
|
||||
nsMargin margin = scrollFrame->GetActualScrollbarSizes();
|
||||
if (margin.top || margin.right || margin.bottom || margin.left) {
|
||||
// Scroll bars will be used for overflow
|
||||
isFocusable = PR_TRUE;
|
||||
tabIndex = 0;
|
||||
|
|
|
@ -68,7 +68,7 @@ class nsIChannel;
|
|||
#define NS_BLOCK_FRAME_HAS_OUTSIDE_BULLET 0x40000000
|
||||
// These are the bits that get inherited from a block frame to its
|
||||
// next-in-flows and are not private to blocks
|
||||
#define NS_BLOCK_FLAGS_MASK 0xF0F00000
|
||||
#define NS_BLOCK_FLAGS_MASK 0xF0E00000
|
||||
|
||||
// Factory methods for creating html layout objects
|
||||
|
||||
|
|
|
@ -466,7 +466,9 @@ public:
|
|||
const nsRect& aDirtyRect);
|
||||
// helper: paint quirks-mode CSS text decorations
|
||||
void PaintTextDecorations(gfxContext* aCtx, const gfxRect& aDirtyRect,
|
||||
const gfxPoint& aFramePt, nsTextPaintStyle& aTextStyle,
|
||||
const gfxPoint& aFramePt,
|
||||
const gfxPoint& aTextBaselinePt,
|
||||
nsTextPaintStyle& aTextStyle,
|
||||
PropertyProvider& aProvider);
|
||||
// helper: paint text frame when we're impacted by at least one selection.
|
||||
// Return PR_FALSE if the text was not painted and we should continue with
|
||||
|
@ -3732,6 +3734,7 @@ FillClippedRect(gfxContext* aCtx, nsPresContext* aPresContext,
|
|||
void
|
||||
nsTextFrame::PaintTextDecorations(gfxContext* aCtx, const gfxRect& aDirtyRect,
|
||||
const gfxPoint& aFramePt,
|
||||
const gfxPoint& aTextBaselinePt,
|
||||
nsTextPaintStyle& aTextPaintStyle,
|
||||
PropertyProvider& aProvider)
|
||||
{
|
||||
|
@ -3798,7 +3801,7 @@ nsTextFrame::PaintTextDecorations(gfxContext* aCtx, const gfxRect& aDirtyRect,
|
|||
PRInt32 app = aTextPaintStyle.PresContext()->AppUnitsPerDevPixel();
|
||||
|
||||
// XXX aFramePt is in AppUnits, shouldn't it be nsFloatPoint?
|
||||
gfxPoint pt(aFramePt.x / app, aFramePt.y / app);
|
||||
gfxPoint pt(aFramePt.x / app, (aTextBaselinePt.y - mAscent) / app);
|
||||
gfxSize size(GetRect().width / app, 0);
|
||||
gfxFloat ascent = mAscent / app;
|
||||
|
||||
|
@ -4174,15 +4177,15 @@ nsTextFrame::PaintTextSelectionDecorations(gfxContext* aCtx,
|
|||
aProvider, mTextRun);
|
||||
gfxFloat xOffset, hyphenWidth;
|
||||
PRUint32 offset, length;
|
||||
PRInt32 app = aTextPaintStyle.PresContext()->AppUnitsPerDevPixel();
|
||||
// XXX aTextBaselinePt is in AppUnits, shouldn't it be nsFloatPoint?
|
||||
gfxPoint pt(0.0, (aTextBaselinePt.y - mAscent) / app);
|
||||
SelectionType type;
|
||||
while (iterator.GetNextSegment(&xOffset, &offset, &length, &hyphenWidth, &type)) {
|
||||
gfxFloat advance = hyphenWidth +
|
||||
mTextRun->GetAdvanceWidth(offset, length, &aProvider);
|
||||
if (type == aSelectionType) {
|
||||
PRInt32 app = aTextPaintStyle.PresContext()->AppUnitsPerDevPixel();
|
||||
// XXX aTextBaselinePt is in AppUnits, shouldn't it be nsFloatPoint?
|
||||
gfxPoint pt((aTextBaselinePt.x + xOffset) / app,
|
||||
(aTextBaselinePt.y - mAscent) / app);
|
||||
pt.x = (aTextBaselinePt.x + xOffset) / app;
|
||||
gfxFloat width = PR_ABS(advance) / app;
|
||||
DrawSelectionDecorations(aCtx, aSelectionType, aTextPaintStyle,
|
||||
pt, width, mAscent / app, decorationMetrics,
|
||||
|
@ -4205,7 +4208,8 @@ nsTextFrame::PaintTextWithSelection(gfxContext* aCtx,
|
|||
SelectionType allTypes;
|
||||
PaintTextWithSelectionColors(aCtx, aFramePt, aTextBaselinePt, aDirtyRect,
|
||||
aProvider, aTextPaintStyle, details, &allTypes);
|
||||
PaintTextDecorations(aCtx, aDirtyRect, aFramePt, aTextPaintStyle, aProvider);
|
||||
PaintTextDecorations(aCtx, aDirtyRect, aFramePt, aTextBaselinePt,
|
||||
aTextPaintStyle, aProvider);
|
||||
PRInt32 i;
|
||||
// Iterate through just the selection types that paint decorations and
|
||||
// paint decorations for any that actually occur in this frame. Paint
|
||||
|
@ -4297,7 +4301,8 @@ nsTextFrame::PaintText(nsIRenderingContext* aRenderingContext, nsPoint aPt,
|
|||
0, hyphenTextRun->GetLength(), &dirtyRect, nsnull, nsnull);
|
||||
}
|
||||
}
|
||||
PaintTextDecorations(ctx, dirtyRect, framePt, textPaintStyle, provider);
|
||||
PaintTextDecorations(ctx, dirtyRect, framePt, textBaselinePt,
|
||||
textPaintStyle, provider);
|
||||
}
|
||||
|
||||
PRInt16
|
||||
|
@ -5603,20 +5608,9 @@ nsTextFrame::Reflow(nsPresContext* aPresContext,
|
|||
// This is corrected for in nsLineLayout::TrimWhiteSpaceIn.
|
||||
PRInt32 numJustifiableCharacters =
|
||||
provider.ComputeJustifiableCharacters(offset, charsFit);
|
||||
// Currently canTrimTrailingWhitespace is always true here
|
||||
// because of the !textStyle->WhiteSpaceIsSignificant() test,
|
||||
// but that could change...
|
||||
if (canTrimTrailingWhitespace) {
|
||||
// Count trimmed spaces and add them to the cluster count
|
||||
PRUint32 charIndex = transformedOffset + transformedCharsFit;
|
||||
while (charIndex > transformedOffset &&
|
||||
mTextRun->GetChar(charIndex - 1) == ' ') {
|
||||
--charIndex;
|
||||
}
|
||||
}
|
||||
|
||||
NS_ASSERTION(numJustifiableCharacters <= charsFit,
|
||||
"Justifiable characters combined???");
|
||||
"Bad justifiable character count");
|
||||
lineLayout.SetTextJustificationWeights(numJustifiableCharacters,
|
||||
charsFit - numJustifiableCharacters);
|
||||
}
|
||||
|
|
|
@ -48,6 +48,9 @@ _TEST_FILES = test_bug323656.html \
|
|||
test_bug344830.html \
|
||||
bug344830_testembed.svg \
|
||||
test_bug382429.html \
|
||||
test_bug384527.html \
|
||||
test_bug385751.html \
|
||||
test_bug389630.html \
|
||||
test_bug391747.html \
|
||||
$(NULL)
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=384527
|
||||
-->
|
||||
<head style="display: inline-table;">
|
||||
<title>Test for Bug 384527</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<style style="display: block; direction: rtl;">
|
||||
style::first-letter {float: right;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=384527">Mozilla Bug 384527</a>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
function do_Test()
|
||||
{
|
||||
/** Test for Bug 384527 **/
|
||||
ok(true, "Should not crash");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
setTimeout(do_Test, 500);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=385751
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 385751</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<style>#content:first-letter {float: right; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=385751">Mozilla Bug 385751</a>
|
||||
<div id="content"><span style="direction: rtl; unicode-bidi: embed;">*::first
|
||||
m</span></div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
function do_Test()
|
||||
{
|
||||
/** Test for Bug 385751 **/
|
||||
ok(true, "Should not crash");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
setTimeout(do_Test, 500);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=389630
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 389630</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
<style>.fl:first-letter { }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=389630">Mozilla Bug 389630</a>
|
||||
<div id="content" style="direction: rtl;"><table><tr><td width="1"><div id="div" class="fl"><font><span>x y</span></font></div></td></tr></table></div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
function boom()
|
||||
{
|
||||
/** Test for Bug 389630 **/
|
||||
document.getElementById("div").className = "";
|
||||
ok(true, "Should not crash");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
setTimeout(boom, 500);
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<html><body><form>
|
||||
<img src="solidblue.png" vspace="20" border="1">
|
||||
</form></body></html>
|
|
@ -0,0 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<html><body><form>
|
||||
<input type="image" src="solidblue.png" vspace="20" border="1">
|
||||
</form></body></html>
|
|
@ -0,0 +1,4 @@
|
|||
<!DOCTYPE html>
|
||||
<html><body><form>
|
||||
<input vspace="20" border="1" src="solidblue.png" type="image">
|
||||
</form></body></html>
|
|
@ -0,0 +1,18 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
function boom()
|
||||
{
|
||||
var k = document.getElementById("k");
|
||||
k.appendChild(document.createTextNode(" "));
|
||||
}
|
||||
</script>
|
||||
</head>
|
||||
|
||||
<body onload="boom();">
|
||||
|
||||
<span><span id="k"><div></div></span><span style="float: right;"></span></span>
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
|
@ -90,6 +90,8 @@ fails-if(MOZ_WIDGET_TOOLKIT=="cocoa") == 28811-2a.html 28811-2-ref.html # bug 38
|
|||
== 201215-1.html 201215-1-ref.html
|
||||
== 206516-1.html 206516-1-ref.html
|
||||
== 210876-1.html 210876-1-ref.html
|
||||
== 214077-1a.html 214077-1-ref.html
|
||||
== 214077-1b.html 214077-1-ref.html
|
||||
== 218473-1.html 218473-1-ref.html
|
||||
== 234964-1.html 234964-1-ref.html
|
||||
== 234964-2.html 234964-2-ref.html
|
||||
|
@ -373,3 +375,4 @@ random-if(MOZ_WIDGET_TOOLKIT=="cocoa") == 379316-2.html 379316-2-ref.html # bug
|
|||
== 393671-1.html 393671-1-ref.html
|
||||
== 393671-2.html 393671-2-ref.html
|
||||
== 393671-3.html 393671-3-ref.html
|
||||
== 394111-1.html about:blank # Really an assertion test rather than a rendering test
|
||||
|
|
|
@ -1359,9 +1359,8 @@ gfxASurface *
|
|||
nsSVGUtils::GetThebesComputationalSurface()
|
||||
{
|
||||
if (!mThebesComputationalSurface) {
|
||||
nsRefPtr<gfxASurface> surface =
|
||||
gfxPlatform::GetPlatform()->CreateOffscreenSurface(gfxIntSize(1, 1),
|
||||
gfxASurface::ImageFormatARGB32);
|
||||
nsRefPtr<gfxImageSurface> surface =
|
||||
new gfxImageSurface(gfxIntSize(1, 1), gfxASurface::ImageFormatARGB32);
|
||||
NS_ASSERTION(surface && !surface->CairoStatus(),
|
||||
"Could not create offscreen surface");
|
||||
mThebesComputationalSurface = surface;
|
||||
|
|
|
@ -341,6 +341,36 @@ nsMenuBarFrame::CurrentMenuIsBeingDestroyed()
|
|||
mCurrentMenu = nsnull;
|
||||
}
|
||||
|
||||
class nsMenuBarSwitchMenu : public nsRunnable
|
||||
{
|
||||
public:
|
||||
nsMenuBarSwitchMenu(nsIContent *aOldMenu,
|
||||
nsIContent *aNewMenu,
|
||||
PRBool aSelectFirstItem)
|
||||
: mOldMenu(aOldMenu), mNewMenu(aNewMenu), mSelectFirstItem(aSelectFirstItem)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
nsXULPopupManager* pm = nsXULPopupManager::GetInstance();
|
||||
if (!pm)
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
|
||||
if (mOldMenu)
|
||||
pm->HidePopup(mOldMenu, PR_FALSE, PR_FALSE, PR_FALSE);
|
||||
if (mNewMenu)
|
||||
pm->ShowMenu(mNewMenu, mSelectFirstItem, PR_FALSE);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsCOMPtr<nsIContent> mOldMenu;
|
||||
nsCOMPtr<nsIContent> mNewMenu;
|
||||
PRBool mSelectFirstItem;
|
||||
};
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsMenuBarFrame::ChangeMenuItem(nsMenuFrame* aMenuItem,
|
||||
PRBool aSelectFirstItem)
|
||||
|
@ -353,6 +383,8 @@ nsMenuBarFrame::ChangeMenuItem(nsMenuFrame* aMenuItem,
|
|||
if (pm && pm->HasContextMenu(nsnull))
|
||||
return NS_OK;
|
||||
|
||||
nsIContent* aOldMenu = nsnull, *aNewMenu = nsnull;
|
||||
|
||||
// Unset the current child.
|
||||
PRBool wasOpen = PR_FALSE;
|
||||
if (mCurrentMenu) {
|
||||
|
@ -361,7 +393,7 @@ nsMenuBarFrame::ChangeMenuItem(nsMenuFrame* aMenuItem,
|
|||
if (wasOpen) {
|
||||
nsMenuPopupFrame* popupFrame = mCurrentMenu->GetPopup();
|
||||
if (popupFrame)
|
||||
pm->HidePopup(popupFrame->GetContent(), PR_FALSE, PR_FALSE, PR_TRUE);
|
||||
aOldMenu = popupFrame->GetContent();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -376,10 +408,14 @@ nsMenuBarFrame::ChangeMenuItem(nsMenuFrame* aMenuItem,
|
|||
NS_ENSURE_TRUE(weakNewMenu.IsAlive(), NS_OK);
|
||||
mCurrentMenu = aMenuItem;
|
||||
if (wasOpen && !aMenuItem->IsDisabled())
|
||||
pm->ShowMenu(content, aSelectFirstItem, PR_TRUE);
|
||||
aNewMenu = content;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
// use an event so that hiding and showing can be done synchronously, which
|
||||
// avoids flickering
|
||||
nsCOMPtr<nsIRunnable> event =
|
||||
new nsMenuBarSwitchMenu(aOldMenu, aNewMenu, aSelectFirstItem);
|
||||
return NS_DispatchToCurrentThread(event);
|
||||
}
|
||||
|
||||
nsMenuFrame*
|
||||
|
|
|
@ -142,7 +142,8 @@ nsTextBoxFrame::AttributeChanged(PRInt32 aNameSpaceID,
|
|||
}
|
||||
|
||||
nsTextBoxFrame::nsTextBoxFrame(nsIPresShell* aShell, nsStyleContext* aContext):
|
||||
nsLeafBoxFrame(aShell, aContext), mCropType(CropRight),mAccessKeyInfo(nsnull)
|
||||
nsLeafBoxFrame(aShell, aContext), mCropType(CropRight), mAccessKeyInfo(nsnull),
|
||||
mNeedsReflowCallback(PR_FALSE)
|
||||
{
|
||||
mState |= NS_STATE_NEED_LAYOUT;
|
||||
MarkIntrinsicWidthsDirty();
|
||||
|
@ -249,7 +250,6 @@ nsTextBoxFrame::UpdateAccesskey(nsWeakFrame& aWeakThis)
|
|||
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::accesskey, accesskey);
|
||||
}
|
||||
|
||||
mReflowCallbackPosted = PR_FALSE;
|
||||
if (!accesskey.Equals(mAccessKey)) {
|
||||
// Need to get clean mTitle.
|
||||
mContent->GetAttr(kNameSpaceID_None, nsGkAtoms::value, mTitle);
|
||||
|
@ -306,15 +306,10 @@ nsTextBoxFrame::UpdateAttributes(nsIAtom* aAttribute,
|
|||
doUpdateTitle = PR_TRUE;
|
||||
}
|
||||
|
||||
if (!mReflowCallbackPosted &&
|
||||
(aAttribute == nsnull || aAttribute == nsGkAtoms::accesskey)) {
|
||||
mReflowCallbackPosted = PR_TRUE;
|
||||
if (aAttribute == nsnull || aAttribute == nsGkAtoms::accesskey) {
|
||||
mNeedsReflowCallback = PR_TRUE;
|
||||
// Ensure that layout is refreshed and reflow callback called.
|
||||
aResize = PR_TRUE;
|
||||
nsIReflowCallback* cb = new nsAsyncAccesskeyUpdate(this);
|
||||
if (cb) {
|
||||
PresContext()->PresShell()->PostReflowCallback(cb);
|
||||
}
|
||||
}
|
||||
|
||||
if (doUpdateTitle) {
|
||||
|
@ -446,16 +441,18 @@ nsTextBoxFrame::PaintTitle(nsIRenderingContext& aRenderingContext,
|
|||
|
||||
nscoord offset;
|
||||
nscoord size;
|
||||
nscoord baseline;
|
||||
fontMet->GetMaxAscent(baseline);
|
||||
nscoord ascent;
|
||||
fontMet->GetMaxAscent(ascent);
|
||||
PRBool isRTL = vis->mDirection == NS_STYLE_DIRECTION_RTL;
|
||||
|
||||
nscoord baseline =
|
||||
presContext->RoundAppUnitsToNearestDevPixels(textRect.y + ascent);
|
||||
nsRefPtr<gfxContext> ctx = (gfxContext*)
|
||||
aRenderingContext.GetNativeGraphicData(nsIRenderingContext::NATIVE_THEBES_CONTEXT);
|
||||
gfxPoint pt(presContext->AppUnitsToGfxUnits(textRect.x),
|
||||
presContext->AppUnitsToGfxUnits(textRect.y));
|
||||
gfxFloat width = presContext->AppUnitsToGfxUnits(textRect.width);
|
||||
gfxFloat baselinePixel = presContext->AppUnitsToGfxUnits(baseline);
|
||||
gfxFloat ascentPixel = presContext->AppUnitsToGfxUnits(ascent);
|
||||
if (decorations & (NS_FONT_DECORATION_OVERLINE | NS_FONT_DECORATION_UNDERLINE)) {
|
||||
fontMet->GetUnderline(offset, size);
|
||||
gfxFloat offsetPixel = presContext->AppUnitsToGfxUnits(offset);
|
||||
|
@ -463,7 +460,7 @@ nsTextBoxFrame::PaintTitle(nsIRenderingContext& aRenderingContext,
|
|||
if (decorations & NS_FONT_DECORATION_OVERLINE) {
|
||||
nsCSSRendering::PaintDecorationLine(ctx, overColor,
|
||||
pt, gfxSize(width, sizePixel),
|
||||
baselinePixel, baselinePixel,
|
||||
ascentPixel, ascentPixel,
|
||||
sizePixel,
|
||||
NS_STYLE_TEXT_DECORATION_OVERLINE,
|
||||
NS_STYLE_BORDER_STYLE_SOLID,
|
||||
|
@ -472,7 +469,7 @@ nsTextBoxFrame::PaintTitle(nsIRenderingContext& aRenderingContext,
|
|||
if (decorations & NS_FONT_DECORATION_UNDERLINE) {
|
||||
nsCSSRendering::PaintDecorationLine(ctx, underColor,
|
||||
pt, gfxSize(width, sizePixel),
|
||||
baselinePixel, offsetPixel,
|
||||
ascentPixel, offsetPixel,
|
||||
sizePixel,
|
||||
NS_STYLE_TEXT_DECORATION_UNDERLINE,
|
||||
NS_STYLE_BORDER_STYLE_SOLID,
|
||||
|
@ -485,7 +482,7 @@ nsTextBoxFrame::PaintTitle(nsIRenderingContext& aRenderingContext,
|
|||
gfxFloat sizePixel = presContext->AppUnitsToGfxUnits(size);
|
||||
nsCSSRendering::PaintDecorationLine(ctx, underColor,
|
||||
pt, gfxSize(width, sizePixel),
|
||||
baselinePixel, offsetPixel,
|
||||
ascentPixel, offsetPixel,
|
||||
sizePixel,
|
||||
NS_STYLE_TEXT_DECORATION_LINE_THROUGH,
|
||||
NS_STYLE_BORDER_STYLE_SOLID,
|
||||
|
@ -515,7 +512,7 @@ nsTextBoxFrame::PaintTitle(nsIRenderingContext& aRenderingContext,
|
|||
posResolve.logicalIndex = mAccessKeyInfo->mAccesskeyIndex;
|
||||
rv = bidiUtils->RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), direction,
|
||||
presContext, aRenderingContext,
|
||||
textRect.x, textRect.y + baseline,
|
||||
textRect.x, baseline,
|
||||
&posResolve,
|
||||
1);
|
||||
mAccessKeyInfo->mBeforeWidth = posResolve.visualLeftTwips;
|
||||
|
@ -524,7 +521,7 @@ nsTextBoxFrame::PaintTitle(nsIRenderingContext& aRenderingContext,
|
|||
{
|
||||
rv = bidiUtils->RenderText(mCroppedTitle.get(), mCroppedTitle.Length(), direction,
|
||||
presContext, aRenderingContext,
|
||||
textRect.x, textRect.y + baseline);
|
||||
textRect.x, baseline);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -544,7 +541,7 @@ nsTextBoxFrame::PaintTitle(nsIRenderingContext& aRenderingContext,
|
|||
mAccessKeyInfo->mBeforeWidth = 0;
|
||||
}
|
||||
|
||||
aRenderingContext.DrawString(mCroppedTitle, textRect.x, textRect.y + baseline);
|
||||
aRenderingContext.DrawString(mCroppedTitle, textRect.x, baseline);
|
||||
}
|
||||
|
||||
if (mAccessKeyInfo && mAccessKeyInfo->mAccesskeyIndex != kNotFound) {
|
||||
|
@ -889,6 +886,14 @@ nsTextBoxFrame::UpdateAccessIndex()
|
|||
NS_IMETHODIMP
|
||||
nsTextBoxFrame::DoLayout(nsBoxLayoutState& aBoxLayoutState)
|
||||
{
|
||||
if (mNeedsReflowCallback) {
|
||||
nsIReflowCallback* cb = new nsAsyncAccesskeyUpdate(this);
|
||||
if (cb) {
|
||||
PresContext()->PresShell()->PostReflowCallback(cb);
|
||||
}
|
||||
mNeedsReflowCallback = PR_FALSE;
|
||||
}
|
||||
|
||||
mState |= NS_STATE_NEED_LAYOUT;
|
||||
|
||||
return nsLeafBoxFrame::DoLayout(aBoxLayoutState);
|
||||
|
|
|
@ -130,7 +130,7 @@ private:
|
|||
nscoord mTitleWidth;
|
||||
nsAccessKeyInfo* mAccessKeyInfo;
|
||||
PRPackedBool mNeedsRecalc;
|
||||
PRPackedBool mReflowCallbackPosted;
|
||||
PRPackedBool mNeedsReflowCallback;
|
||||
nsSize mTextSize;
|
||||
nscoord mAscent;
|
||||
|
||||
|
|
|
@ -3797,7 +3797,7 @@ NS_IMETHODIMP nsTreeBodyFrame::EnsureCellIsVisible(PRInt32 aRow, nsITreeColumn*
|
|||
rv = col->GetWidthInTwips(this, &columnWidth);
|
||||
if(NS_FAILED(rv)) return rv;
|
||||
|
||||
if (!col->GetNext())
|
||||
if (col->IsLastVisible(this))
|
||||
columnWidth -= mAdjustWidth; // this is one case we don't want to adjust
|
||||
|
||||
// If the start of the column is before the
|
||||
|
|
|
@ -112,6 +112,28 @@ nsTreeColumn::GetFrame()
|
|||
return shell->GetPrimaryFrameFor(mContent);
|
||||
}
|
||||
|
||||
PRBool
|
||||
nsTreeColumn::IsLastVisible(nsTreeBodyFrame* aBodyFrame)
|
||||
{
|
||||
NS_ASSERTION(GetFrame(aBodyFrame), "should have checked for this already");
|
||||
|
||||
// cyclers are fixed width, don't adjust them
|
||||
if (IsCycler())
|
||||
return PR_FALSE;
|
||||
|
||||
// we're certainly not the last visible if we're not visible
|
||||
if (GetFrame(aBodyFrame)->GetRect().width == 0)
|
||||
return PR_FALSE;
|
||||
|
||||
// try to find a visible successor
|
||||
for (nsTreeColumn *next = GetNext(); next; next = next->GetNext()) {
|
||||
nsIFrame* frame = next->GetFrame(aBodyFrame);
|
||||
if (frame && frame->GetRect().width > 0)
|
||||
return PR_FALSE;
|
||||
}
|
||||
return PR_TRUE;
|
||||
}
|
||||
|
||||
nsresult
|
||||
nsTreeColumn::GetRect(nsTreeBodyFrame* aBodyFrame, nscoord aY, nscoord aHeight, nsRect* aResult)
|
||||
{
|
||||
|
@ -124,7 +146,7 @@ nsTreeColumn::GetRect(nsTreeBodyFrame* aBodyFrame, nscoord aY, nscoord aHeight,
|
|||
*aResult = frame->GetRect();
|
||||
aResult->y = aY;
|
||||
aResult->height = aHeight;
|
||||
if (!GetNext())
|
||||
if (IsLastVisible(aBodyFrame))
|
||||
aResult->width += aBodyFrame->mAdjustWidth;
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -150,7 +172,7 @@ nsTreeColumn::GetWidthInTwips(nsTreeBodyFrame* aBodyFrame, nscoord* aResult)
|
|||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
*aResult = frame->GetRect().width;
|
||||
if (!GetNext())
|
||||
if (IsLastVisible(aBodyFrame))
|
||||
*aResult += aBodyFrame->mAdjustWidth;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -64,6 +64,8 @@ public:
|
|||
protected:
|
||||
nsIFrame* GetFrame();
|
||||
nsIFrame* GetFrame(nsTreeBodyFrame* aBodyFrame);
|
||||
// Don't call this if GetWidthInTwips or GetRect fails
|
||||
PRBool IsLastVisible(nsTreeBodyFrame* aBodyFrame);
|
||||
|
||||
/**
|
||||
* Returns a rect with x and width taken from the frame's rect and specified
|
||||
|
|
|
@ -1,11 +0,0 @@
|
|||
/* pngasmrd.h - assembler version of utilities to read a PNG file
|
||||
*
|
||||
* libpng 1.2.5 - October 2, 2002
|
||||
* For conditions of distribution and use, see copyright notice in png.h
|
||||
* Copyright (c) 2002 Glenn Randers-Pehrson
|
||||
*
|
||||
*/
|
||||
|
||||
/* This file is obsolete in libpng-1.0.9 and later; its contents now appear
|
||||
* at the end of pngconf.h.
|
||||
*/
|
|
@ -78,7 +78,8 @@ NS_IMPL_ISUPPORTS6(imgRequest, imgILoad,
|
|||
imgRequest::imgRequest() :
|
||||
mLoading(PR_FALSE), mProcessing(PR_FALSE), mHadLastPart(PR_FALSE),
|
||||
mNetworkStatus(0), mImageStatus(imgIRequest::STATUS_NONE), mState(0),
|
||||
mCacheId(0), mValidator(nsnull), mIsMultiPartChannel(PR_FALSE)
|
||||
mCacheId(0), mValidator(nsnull), mIsMultiPartChannel(PR_FALSE),
|
||||
mImageSniffers("image-sniffing-services")
|
||||
{
|
||||
/* member initializers and constructor code */
|
||||
}
|
||||
|
@ -928,6 +929,24 @@ void
|
|||
imgRequest::SniffMimeType(const char *buf, PRUint32 len)
|
||||
{
|
||||
imgLoader::GetMimeTypeFromContent(buf, len, mContentType);
|
||||
|
||||
// The vast majority of the time, imgLoader will find a gif/jpeg/png image
|
||||
// and fill mContentType with the sniffed MIME type.
|
||||
if (!mContentType.IsEmpty())
|
||||
return;
|
||||
|
||||
// When our sniffing fails, we want to query registered image decoders
|
||||
// to see if they can identify the image. If we always trusted the server
|
||||
// to send the right MIME, images sent as text/plain would not be rendered.
|
||||
const nsCOMArray<nsIContentSniffer>& sniffers = mImageSniffers.GetEntries();
|
||||
PRUint32 length = sniffers.Count();
|
||||
for (PRUint32 i = 0; i < length; ++i) {
|
||||
nsresult rv =
|
||||
sniffers[i]->GetMIMETypeFromContent(nsnull, (const PRUint8 *) buf, len, mContentType);
|
||||
if (NS_SUCCEEDED(rv) && !mContentType.IsEmpty()) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nsresult
|
||||
|
|
|
@ -47,11 +47,13 @@
|
|||
#include "imgIDecoderObserver.h"
|
||||
|
||||
#include "nsICacheEntryDescriptor.h"
|
||||
#include "nsIContentSniffer.h"
|
||||
#include "nsIRequest.h"
|
||||
#include "nsIProperties.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIURI.h"
|
||||
|
||||
#include "nsCategoryCache.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsString.h"
|
||||
#include "nsVoidArray.h"
|
||||
|
@ -173,6 +175,8 @@ private:
|
|||
|
||||
imgCacheValidator *mValidator;
|
||||
PRBool mIsMultiPartChannel;
|
||||
|
||||
nsCategoryCache<nsIContentSniffer> mImageSniffers;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -179,4 +179,11 @@ interface nsIPrefService : nsISupports
|
|||
*/
|
||||
#define NS_PREFSERVICE_RESET_TOPIC_ID "prefservice:before-reset"
|
||||
|
||||
/**
|
||||
* Notification sent when after reading app-provided default
|
||||
* preferences, but before user profile override defaults or extension
|
||||
* defaults are loaded.
|
||||
*/
|
||||
#define NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID "prefservice:after-app-defaults"
|
||||
|
||||
%}
|
||||
|
|
|
@ -717,6 +717,32 @@ pref_LoadPrefsInDir(nsIFile* aDir, char const *const *aSpecialFiles, PRUint32 aS
|
|||
return rv;
|
||||
}
|
||||
|
||||
static nsresult pref_LoadPrefsInDirList(const char *listId)
|
||||
{
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIProperties> dirSvc(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> dirList;
|
||||
dirSvc->Get(listId,
|
||||
NS_GET_IID(nsISimpleEnumerator),
|
||||
getter_AddRefs(dirList));
|
||||
if (dirList) {
|
||||
PRBool hasMore;
|
||||
while (NS_SUCCEEDED(dirList->HasMoreElements(&hasMore)) && hasMore) {
|
||||
nsCOMPtr<nsISupports> elem;
|
||||
dirList->GetNext(getter_AddRefs(elem));
|
||||
if (elem) {
|
||||
nsCOMPtr<nsIFile> dir = do_QueryInterface(elem);
|
||||
if (dir) {
|
||||
// Do we care if a file provided by this process fails to load?
|
||||
pref_LoadPrefsInDir(dir, nsnull, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
// Initialize default preference JavaScript buffers from
|
||||
|
@ -773,30 +799,19 @@ static nsresult pref_InitInitialObjects()
|
|||
NS_WARNING("Error parsing application default preferences.");
|
||||
}
|
||||
|
||||
// xxxbsmedberg: TODO load default prefs from a category
|
||||
// but the architecture is not quite there yet
|
||||
rv = pref_LoadPrefsInDirList(NS_APP_PREFS_DEFAULTS_DIR_LIST);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
nsCOMPtr<nsIProperties> dirSvc(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv));
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
NS_CreateServicesFromCategory(NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID,
|
||||
nsnull, NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID);
|
||||
|
||||
nsCOMPtr<nsISimpleEnumerator> dirList;
|
||||
dirSvc->Get(NS_APP_PREFS_DEFAULTS_DIR_LIST,
|
||||
NS_GET_IID(nsISimpleEnumerator),
|
||||
getter_AddRefs(dirList));
|
||||
if (dirList) {
|
||||
PRBool hasMore;
|
||||
while (NS_SUCCEEDED(dirList->HasMoreElements(&hasMore)) && hasMore) {
|
||||
nsCOMPtr<nsISupports> elem;
|
||||
dirList->GetNext(getter_AddRefs(elem));
|
||||
if (elem) {
|
||||
nsCOMPtr<nsIFile> dir = do_QueryInterface(elem);
|
||||
if (dir) {
|
||||
// Do we care if a file provided by this process fails to load?
|
||||
pref_LoadPrefsInDir(dir, nsnull, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
nsCOMPtr<nsIObserverService> observerService =
|
||||
do_GetService("@mozilla.org/observer-service;1", &rv);
|
||||
|
||||
if (NS_FAILED(rv) || !observerService)
|
||||
return rv;
|
||||
|
||||
return NS_OK;
|
||||
observerService->NotifyObservers(nsnull, NS_PREFSERVICE_APPDEFAULTS_TOPIC_ID, nsnull);
|
||||
|
||||
return pref_LoadPrefsInDirList(NS_EXT_PREFS_DEFAULTS_DIR_LIST);
|
||||
}
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче