This commit is contained in:
Andreas Gal 2008-09-30 16:35:52 -07:00
commit e4e61b7b12
497 changed files with 9873 additions and 28616 deletions

View File

@ -13,3 +13,11 @@ f197b51bbc29a30860e750ee87fd0a047a024f2e FIREFOX_3_1a2_RELEASE
269af1ed75649989575d41f53a12048015c6d50e FENNEC_M8
920a4326d1087b174c2fa2b9a8358e12c697022c SEAMONKEY_2_0a1_BUILD1
920a4326d1087b174c2fa2b9a8358e12c697022c SEAMONKEY_2_0a1_RELEASE
f197b51bbc29a30860e750ee87fd0a047a024f2e UPDATE_PACKAGING_R5
f197b51bbc29a30860e750ee87fd0a047a024f2e -m
f197b51bbc29a30860e750ee87fd0a047a024f2e Adding UPDATE_PACKAGING_R5 tag in order to make patcher work.
15cb5d25db054d2d0b56869a2f6351388bfcddcd THUNDERBIRD_3_0b1_RELEASE
15cb5d25db054d2d0b56869a2f6351388bfcddcd THUNDERBIRD_3_0b1_BUILD1
0000000000000000000000000000000000000000 -m
0000000000000000000000000000000000000000 Adding UPDATE_PACKAGING_R5 tag in order to make patcher work.
f197b51bbc29a30860e750ee87fd0a047a024f2e UPDATE_PACKAGING_R6

View File

@ -49,6 +49,7 @@ default alldep all::
$(RM) -rf $(DIST)/include
$(RM) -rf $(DIST)/private
$(RM) -rf $(DIST)/public
$(RM) -rf $(DIST)/bin/components
$(RM) -rf _tests
TIERS += base

View File

@ -721,7 +721,11 @@ LoadGtkModule(GnomeAccessibilityModule& aModule)
//try to load the module with "gtk-2.0/modules" appended
char *curLibPath = PR_GetLibraryPath();
nsCAutoString libPath(curLibPath);
#if defined(LINUX) && defined(__x86_64__)
libPath.Append(":/usr/lib64:/usr/lib");
#else
libPath.Append(":/usr/lib");
#endif
MAI_LOG_DEBUG(("Current Lib path=%s\n", libPath.get()));
PR_FreeLibraryName(curLibPath);

View File

@ -182,9 +182,6 @@ endif
ifeq ($(OS_ARCH),WINNT)
OS_LIBS += $(call EXPAND_LIBNAME,comctl32 comdlg32 uuid shell32 ole32 oleaut32 version winspool)
OS_LIBS += $(call EXPAND_LIBNAME,usp10 msimg32)
ifdef MOZ_ENABLE_GLITZ
OS_LIBS += $(call EXPAND_LIBNAME,opengl32)
endif
RCINCLUDE = splash.rc
ifndef GNU_CC

View File

@ -416,7 +416,8 @@ var PlacesCommandHook = {
}
// Revert the contents of the location bar
handleURLBarRevert();
if (gURLBar)
gURLBar.handleRevert();
// dock the panel to the star icon when possible, otherwise dock
// it to the content area

View File

@ -838,6 +838,7 @@ function prepareForStartup() {
// binding can't fire trusted ones (runs with page privileges).
gBrowser.addEventListener("PluginNotFound", gMissingPluginInstaller.newMissingPlugin, true, true);
gBrowser.addEventListener("PluginBlocklisted", gMissingPluginInstaller.newMissingPlugin, true, true);
gBrowser.addEventListener("PluginDisabled", gMissingPluginInstaller.newDisabledPlugin, true, true);
gBrowser.addEventListener("NewPluginInstalled", gMissingPluginInstaller.refreshBrowser, false);
gBrowser.addEventListener("NewTab", BrowserOpenTab, false);
window.addEventListener("AppCommand", HandleAppCommandEvent, true);
@ -1684,34 +1685,6 @@ function loadURI(uri, referrer, postData, allowThirdPartyFixup)
}
}
function BrowserLoadURL(aTriggeringEvent, aPostData) {
var url = gURLBar.value;
if (aTriggeringEvent instanceof MouseEvent) {
if (aTriggeringEvent.button == 2)
return; // Do nothing for right clicks
// We have a mouse event (from the go button), so use the standard
// UI link behaviors
openUILink(url, aTriggeringEvent, false, false,
true /* allow third party fixup */, aPostData);
return;
}
if (aTriggeringEvent && aTriggeringEvent.altKey) {
handleURLBarRevert();
content.focus();
gBrowser.loadOneTab(url, null, null, aPostData, false,
true /* allow third party fixup */);
aTriggeringEvent.preventDefault();
aTriggeringEvent.stopPropagation();
}
else
loadURI(url, null, aPostData, true /* allow third party fixup */);
focusElement(content);
}
function getShortcutOrURI(aURL, aPostDataRef) {
var shortcutURL = null;
var keyword = aURL;
@ -1993,119 +1966,6 @@ function losslessDecodeURI(aURI) {
return value;
}
// Replace the urlbar's value with the url of the page.
function handleURLBarRevert() {
var throbberElement = document.getElementById("navigator-throbber");
var isScrolling = gURLBar.popupOpen;
gBrowser.userTypedValue = null;
// don't revert to last valid url unless page is NOT loading
// and user is NOT key-scrolling through autocomplete list
if ((!throbberElement || !throbberElement.hasAttribute("busy")) && !isScrolling) {
URLBarSetURI();
// If the value isn't empty and the urlbar has focus, select the value.
if (gURLBar.value && gURLBar.hasAttribute("focused"))
gURLBar.select();
}
// tell widget to revert to last typed text only if the user
// was scrolling when they hit escape
return !isScrolling;
}
function handleURLBarCommand(aTriggeringEvent) {
if (!gURLBar.value)
return;
var postData = { };
canonizeUrl(aTriggeringEvent, postData);
try {
addToUrlbarHistory(gURLBar.value);
} catch (ex) {
// Things may go wrong when adding url to session history,
// but don't let that interfere with the loading of the url.
}
BrowserLoadURL(aTriggeringEvent, postData.value);
}
function canonizeUrl(aTriggeringEvent, aPostDataRef) {
if (!gURLBar || !gURLBar.value)
return;
var url = gURLBar.value;
// Only add the suffix when the URL bar value isn't already "URL-like".
// Since this function is called from handleURLBarCommand, which receives
// both mouse (from the go button) and keyboard events, we also make sure not
// to do the fixup unless we get a keyboard event, to match user expectations.
if (!/^\s*(www|https?)\b|\/\s*$/i.test(url) &&
(aTriggeringEvent instanceof KeyEvent)) {
#ifdef XP_MACOSX
var accel = aTriggeringEvent.metaKey;
#else
var accel = aTriggeringEvent.ctrlKey;
#endif
var shift = aTriggeringEvent.shiftKey;
var suffix = "";
switch (true) {
case (accel && shift):
suffix = ".org/";
break;
case (shift):
suffix = ".net/";
break;
case (accel):
try {
suffix = gPrefService.getCharPref("browser.fixup.alternate.suffix");
if (suffix.charAt(suffix.length - 1) != "/")
suffix += "/";
} catch(e) {
suffix = ".com/";
}
break;
}
if (suffix) {
// trim leading/trailing spaces (bug 233205)
url = url.replace(/^\s+/, "").replace(/\s+$/, "");
// Tack www. and suffix on. If user has appended directories, insert
// suffix before them (bug 279035). Be careful not to get two slashes.
// Also, don't add the suffix if it's in the original url (bug 233853).
var firstSlash = url.indexOf("/");
var existingSuffix = url.indexOf(suffix.substring(0, suffix.length - 1));
// * Logic for slash and existing suffix (example)
// No slash, no suffix: Add suffix (mozilla)
// No slash, yes suffix: Add slash (mozilla.com)
// Yes slash, no suffix: Insert suffix (mozilla/stuff)
// Yes slash, suffix before slash: Do nothing (mozilla.com/stuff)
// Yes slash, suffix after slash: Insert suffix (mozilla/?stuff=.com)
if (firstSlash >= 0) {
if (existingSuffix == -1 || existingSuffix > firstSlash)
url = url.substring(0, firstSlash) + suffix +
url.substring(firstSlash + 1);
} else
url = url + (existingSuffix == -1 ? suffix : "/");
url = "http://www." + url;
}
}
gURLBar.value = getShortcutOrURI(url, aPostDataRef);
// Also update this so the browser display keeps the new value (bug 310651)
gBrowser.userTypedValue = gURLBar.value;
}
function UpdateUrlbarSearchSplitterState()
{
var splitter = document.getElementById("urlbar-search-splitter");
@ -2641,42 +2501,6 @@ var bookmarksButtonObserver = {
}
}
var newTabButtonObserver = {
onDragOver: function(aEvent, aFlavour, aDragSession)
{
var statusTextFld = document.getElementById("statusbar-display");
statusTextFld.label = gNavigatorBundle.getString("droponnewtabbutton");
aEvent.target.setAttribute("dragover", "true");
return true;
},
onDragExit: function (aEvent, aDragSession)
{
var statusTextFld = document.getElementById("statusbar-display");
statusTextFld.label = "";
aEvent.target.removeAttribute("dragover");
},
onDrop: function (aEvent, aXferData, aDragSession)
{
var xferData = aXferData.data.split("\n");
var draggedText = xferData[0] || xferData[1];
var postData = {};
var url = getShortcutOrURI(draggedText, postData);
if (url) {
nsDragAndDrop.dragDropSecurityCheck(aEvent, aDragSession, url);
// allow third-party services to fixup this URL
openNewTabWith(url, null, postData.value, aEvent, true);
}
},
getSupportedFlavours: function ()
{
var flavourSet = new FlavourSet();
flavourSet.appendFlavour("text/unicode");
flavourSet.appendFlavour("text/x-moz-url");
flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
return flavourSet;
}
}
var newWindowButtonObserver = {
onDragOver: function(aEvent, aFlavour, aDragSession)
{
@ -3085,20 +2909,11 @@ function FillHistoryMenu(aParent) {
return true;
}
function addToUrlbarHistory(aUrlToAdd)
{
if (!aUrlToAdd)
return;
if (aUrlToAdd.search(/[\x00-\x1F]/) != -1) // don't store bad URLs
return;
try {
if (aUrlToAdd.indexOf(" ") == -1) {
PlacesUIUtils.markPageAsTyped(aUrlToAdd);
}
}
catch(ex) {
}
function addToUrlbarHistory(aUrlToAdd) {
if (aUrlToAdd &&
aUrlToAdd.indexOf(" ") == -1 &&
!/[\x00-\x1F]/.test(aUrlToAdd))
PlacesUIUtils.markPageAsTyped(aUrlToAdd);
}
function toJavaScriptConsole()
@ -3211,7 +3026,7 @@ function BrowserCustomizeToolbar()
#else
window.openDialog(customizeURL,
"CustomizeToolbar",
"chrome,all,dependent",
"chrome,titlebar,toolbar,resizable,dependent",
gNavToolbox);
#endif
}
@ -4868,6 +4683,7 @@ function middleMousePaste(event)
var url = readFromClipboard();
if (!url)
return;
var postData = { };
url = getShortcutOrURI(url, postData);
if (!url)
@ -4878,6 +4694,7 @@ function middleMousePaste(event)
} catch (ex) {
// Things may go wrong when adding url to session history,
// but don't let that interfere with the loading of the url.
Cu.reportError(ex);
}
openUILink(url,
@ -5610,7 +5427,7 @@ var MailIntegration = {
}
};
function BrowserOpenAddonsMgr()
function BrowserOpenAddonsMgr(aPane)
{
const EMTYPE = "Extension:Manager";
var wm = Components.classes["@mozilla.org/appshell/window-mediator;1"]
@ -5618,12 +5435,17 @@ function BrowserOpenAddonsMgr()
var theEM = wm.getMostRecentWindow(EMTYPE);
if (theEM) {
theEM.focus();
if (aPane)
theEM.showView(aPane);
return;
}
const EMURL = "chrome://mozapps/content/extensions/extensions.xul";
const EMFEATURES = "chrome,menubar,extra-chrome,toolbar,dialog=no,resizable";
window.openDialog(EMURL, "", EMFEATURES);
if (aPane)
window.openDialog(EMURL, "", EMFEATURES, aPane);
else
window.openDialog(EMURL, "", EMFEATURES);
}
function escapeNameValuePair(aName, aValue, aIsFormUrlEncoded)
@ -5702,9 +5524,6 @@ function SwitchDocumentDirection(aWindow) {
SwitchDocumentDirection(aWindow.frames[run]);
}
function missingPluginInstaller(){
}
function getPluginInfo(pluginElement)
{
var tagMimetype;
@ -5740,6 +5559,9 @@ function getPluginInfo(pluginElement)
return {mimetype: tagMimetype, pluginsPage: pluginsPage};
}
function missingPluginInstaller(){
}
missingPluginInstaller.prototype.installSinglePlugin = function(aEvent){
var missingPluginsArray = {};
@ -5752,7 +5574,12 @@ missingPluginInstaller.prototype.installSinglePlugin = function(aEvent){
{plugins: missingPluginsArray, browser: gBrowser.selectedBrowser});
}
aEvent.preventDefault();
aEvent.stopPropagation();
}
missingPluginInstaller.prototype.managePlugins = function(aEvent){
BrowserOpenAddonsMgr("plugins");
aEvent.stopPropagation();
}
missingPluginInstaller.prototype.newMissingPlugin = function(aEvent){
@ -5770,7 +5597,7 @@ missingPluginInstaller.prototype.newMissingPlugin = function(aEvent){
!(aEvent.target instanceof HTMLObjectElement)) {
aEvent.target.addEventListener("click",
gMissingPluginInstaller.installSinglePlugin,
false);
true);
}
try {
@ -5778,17 +5605,8 @@ missingPluginInstaller.prototype.newMissingPlugin = function(aEvent){
return;
} catch (ex) {} // if the pref is missing, treat it as false, which shows the infobar
const browsers = gBrowser.mPanelContainer.childNodes;
var contentWindow = aEvent.target.ownerDocument.defaultView.top;
var i = 0;
for (; i < browsers.length; i++) {
if (gBrowser.getBrowserAtIndex(i).contentWindow == contentWindow)
break;
}
var browser = gBrowser.getBrowserAtIndex(i);
var browser = gBrowser.getBrowserForDocument(aEvent.target.ownerDocument
.defaultView.top.document);
if (!browser.missingPlugins)
browser.missingPlugins = {};
@ -5801,22 +5619,23 @@ missingPluginInstaller.prototype.newMissingPlugin = function(aEvent){
// If there is already a missing plugin notification then do nothing
if (notificationBox.getNotificationWithValue("missing-plugins"))
return;
var bundle_browser = document.getElementById("bundle_browser");
var blockedNotification = notificationBox.getNotificationWithValue("blocked-plugins");
const priority = notificationBox.PRIORITY_WARNING_MEDIUM;
const iconURL = "chrome://mozapps/skin/plugins/pluginGeneric-16.png";
var priority = notificationBox.PRIORITY_WARNING_MEDIUM;
if (aEvent.type == "PluginBlocklisted" && !blockedNotification) {
var messageString = bundle_browser.getString("blockedpluginsMessage.title");
var buttons = [{
label: bundle_browser.getString("blockedpluginsMessage.infoButton.label"),
accessKey: bundle_browser.getString("blockedpluginsMessage.infoButton.accesskey"),
if (aEvent.type == "PluginBlocklisted") {
if (blockedNotification)
return;
let iconURL = "chrome://mozapps/skin/plugins/pluginBlocked-16.png";
let messageString = gNavigatorBundle.getString("blockedpluginsMessage.title");
let buttons = [{
label: gNavigatorBundle.getString("blockedpluginsMessage.infoButton.label"),
accessKey: gNavigatorBundle.getString("blockedpluginsMessage.infoButton.accesskey"),
popup: null,
callback: blocklistInfo
}, {
label: bundle_browser.getString("blockedpluginsMessage.searchButton.label"),
accessKey: bundle_browser.getString("blockedpluginsMessage.searchButton.accesskey"),
label: gNavigatorBundle.getString("blockedpluginsMessage.searchButton.label"),
accessKey: gNavigatorBundle.getString("blockedpluginsMessage.searchButton.accesskey"),
popup: null,
callback: pluginsMissing
}];
@ -5824,25 +5643,36 @@ missingPluginInstaller.prototype.newMissingPlugin = function(aEvent){
notificationBox.appendNotification(messageString, "blocked-plugins",
iconURL, priority, buttons);
}
if (aEvent.type == "PluginNotFound") {
else if (aEvent.type == "PluginNotFound") {
// Cancel any notification about blocklisting
if (blockedNotification)
blockedNotification.close();
var messageString = bundle_browser.getString("missingpluginsMessage.title");
var buttons = [{
label: bundle_browser.getString("missingpluginsMessage.button.label"),
accessKey: bundle_browser.getString("missingpluginsMessage.button.accesskey"),
let iconURL = "chrome://mozapps/skin/plugins/pluginGeneric-16.png";
let messageString = gNavigatorBundle.getString("missingpluginsMessage.title");
let buttons = [{
label: gNavigatorBundle.getString("missingpluginsMessage.button.label"),
accessKey: gNavigatorBundle.getString("missingpluginsMessage.button.accesskey"),
popup: null,
callback: pluginsMissing
}];
notificationBox.appendNotification(messageString, "missing-plugins",
iconURL, priority, buttons);
}
}
missingPluginInstaller.prototype.newDisabledPlugin = function(aEvent){
// Since we are expecting also untrusted events, make sure
// that the target is a plugin
if (!(aEvent.target instanceof Components.interfaces.nsIObjectLoadingContent))
return;
aEvent.target.addEventListener("click",
gMissingPluginInstaller.managePlugins,
true);
}
missingPluginInstaller.prototype.refreshBrowser = function(aEvent) {
var browser = aEvent.target;
var notificationBox = gBrowser.getNotificationBox(browser);
@ -6164,6 +5994,7 @@ function undoCloseMiddleClick(aEvent) {
* Re-open a closed tab.
* @param aIndex
* The index of the tab (via nsSessionStore.getClosedTabData)
* @returns a reference to the reopened tab.
*/
function undoCloseTab(aIndex) {
// wallpaper patch to prevent an unnecessary blank tab (bug 343895)
@ -6176,14 +6007,17 @@ function undoCloseTab(aIndex) {
!gBrowser.selectedTab.hasAttribute("busy"))
blankTabToRemove = gBrowser.selectedTab;
var tab = null;
var ss = Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
if (ss.getClosedTabCount(window) == 0)
return;
ss.undoCloseTab(window, aIndex || 0);
if (blankTabToRemove)
gBrowser.removeTab(blankTabToRemove);
if (ss.getClosedTabCount(window) > (aIndex || 0)) {
tab = ss.undoCloseTab(window, aIndex || 0);
if (blankTabToRemove)
gBrowser.removeTab(blankTabToRemove);
}
return tab;
}
/**
@ -6575,7 +6409,7 @@ var gIdentityHandler = {
return; // Left click, space or enter only
// Revert the contents of the location bar, see bug 406779
handleURLBarRevert();
gURLBar.handleRevert();
// Make sure that the display:none style we set in xul is removed now that
// the popup is actually needed

View File

@ -349,8 +349,8 @@
maxrows="6"
newlines="stripsurroundingwhitespace"
oninput="gBrowser.userTypedValue = this.value;"
ontextentered="return handleURLBarCommand(param);"
ontextreverted="return handleURLBarRevert();"
ontextentered="this.handleCommand(param);"
ontextreverted="return this.handleRevert();"
pageproxystate="invalid"
onsearchbegin="LocationBarHelpers._searchBegin();"
onsearchcomplete="LocationBarHelpers._searchComplete();"
@ -395,7 +395,7 @@
chromedir="&locale.dir;"
class="urlbar-icon"
tooltiptext="&goEndCap.tooltip;"
onclick="handleURLBarCommand(event);"/>
onclick="gURLBar.handleCommand(event);"/>
</hbox>
</textbox>
</toolbaritem>
@ -446,14 +446,6 @@
ondragdrop="nsDragAndDrop.drop(event, bookmarksButtonObserver);"
ondragexit="nsDragAndDrop.dragExit(event, bookmarksButtonObserver);"/>
<toolbarbutton id="new-tab-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
label="&tabCmd.label;"
command="cmd_newNavigatorTab"
tooltiptext="&newTabButton.tooltip;"
ondragover="nsDragAndDrop.dragOver(event, newTabButtonObserver);"
ondragdrop="nsDragAndDrop.drop(event, newTabButtonObserver);"
ondragexit="nsDragAndDrop.dragExit(event, newTabButtonObserver);"/>
<toolbarbutton id="new-window-button" class="toolbarbutton-1 chromeclass-toolbar-additional"
label="&newNavigatorCmd.label;"
command="key_newNavigator"

View File

@ -24,10 +24,10 @@
display: none;
}
.tabbrowser-tabs:not([closebuttons="noclose"]):not([closebuttons="closeatend"]) > .tabbrowser-tab[selected="true"] > .tab-close-button {
.tabbrowser-tabs:not([closebuttons="noclose"]):not([closebuttons="closeatend"]) > .tabbrowser-tab[selected="true"]:not(:only-child) > .tab-close-button {
display: -moz-box;
}
.tabbrowser-tabs[closebuttons="alltabs"] > .tabbrowser-tab > .tab-close-button {
.tabbrowser-tabs[closebuttons="alltabs"] > .tabbrowser-tab:not(:only-child) > .tab-close-button {
display: -moz-box;
}

View File

@ -71,10 +71,10 @@
</xul:hbox>
<xul:hbox class="tabbrowser-strip" collapsed="true" tooltip="_child" context="_child"
anonid="strip"
ondraggesture="nsDragAndDrop.startDrag(event, this.parentNode.parentNode); event.stopPropagation();"
ondragover="nsDragAndDrop.dragOver(event, this.parentNode.parentNode); event.stopPropagation();"
ondragdrop="nsDragAndDrop.drop(event, this.parentNode.parentNode); event.stopPropagation();"
ondragexit="nsDragAndDrop.dragExit(event, this.parentNode.parentNode); event.stopPropagation();">
ondragstart="this.parentNode.parentNode._onDragStart(event); event.stopPropagation();"
ondragover="this.parentNode.parentNode._onDragOver(event); event.stopPropagation();"
ondrop="this.parentNode.parentNode._onDrop(event); event.stopPropagation();"
ondragleave="this.parentNode.parentNode._onDragLeave(event); event.stopPropagation();">
<xul:tooltip onpopupshowing="return this.parentNode.parentNode.parentNode.createTooltip(event);"/>
<xul:menupopup anonid="tabContextMenu" onpopupshowing="this.parentNode.parentNode.parentNode.updatePopupMenu(this);">
<xul:menuitem id="context_newTab" label="&newTab.label;" accesskey="&newTab.accesskey;"
@ -1778,55 +1778,91 @@
</getter>
</property>
<!-- Drag and drop observer API -->
<method name="onDragStart">
<method name="_onDragStart">
<parameter name="aEvent"/>
<parameter name="aXferData"/>
<parameter name="aDragAction"/>
<body>
<![CDATA[
if (aEvent.target.localName == "tab" &&
var target = aEvent.target;
if (target.localName == "tab" &&
aEvent.originalTarget.localName != "toolbarbutton") {
aXferData.data = new TransferData();
var dt = aEvent.dataTransfer;
dt.mozSetDataAt("application/x-moz-node", target, 0);
var URI = this.getBrowserForTab(aEvent.target).currentURI;
if (URI) {
aXferData.data.addDataForFlavour("text/x-moz-url", URI.spec + "\n" + aEvent.target.label);
aXferData.data.addDataForFlavour("text/unicode", URI.spec);
aXferData.data.addDataForFlavour("text/html", '<a href="' + URI.spec + '">' + aEvent.target.label + '</a>');
var spec = URI.spec;
dt.mozSetDataAt("text/x-moz-url", spec + "\n" + aEvent.target.label, 0);
dt.mozSetDataAt("text/uri-list", spec + "\n" + aEvent.target.label, 0);
dt.mozSetDataAt("text/plain", spec, 0);
dt.mozSetDataAt("text/html", '<a href="' + spec + '">' + aEvent.target.label + '</a>', 0);
} else {
aXferData.data.addDataForFlavour("text/unicode", "about:blank");
dt.mozSetDataAt("text/plain", "about:blank", 0);
}
}
]]>
</body>
</method>
<method name="canDrop">
<field name="mDragTime">0</field>
<field name="mDragOverDelay">350</field>
<field name="_supportedLinkDropTypes"><![CDATA[
["text/x-moz-url", "text/uri-list", "text/plain", "application/x-moz-file"]
]]></field>
<method name="_setEffectAllowedForDataTransfer">
<parameter name="aEvent"/>
<parameter name="aDragSession"/>
<body>
<![CDATA[
if (aDragSession.sourceNode &&
aDragSession.sourceNode.parentNode == this.mTabContainer &&
(aEvent.screenX >= aDragSession.sourceNode.boxObject.screenX &&
aEvent.screenX <= (aDragSession.sourceNode.boxObject.screenX +
aDragSession.sourceNode.boxObject.width)))
return false;
return true;
var dt = aEvent.dataTransfer;
// Disallow dropping multiple items
if (dt.mozItemCount > 1)
return dt.effectAllowed = "none";
var types = dt.mozTypesAt(0);
var sourceNode = null;
// tabs are always added as the first type
if (types[0] == "application/x-moz-node") {
var sourceNode = dt.mozGetDataAt("application/x-moz-node", 0);
if (sourceNode instanceof XULElement &&
sourceNode.localName == "tab" &&
(sourceNode.parentNode == this.mTabContainer ||
(sourceNode.ownerDocument.defaultView instanceof ChromeWindow &&
sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser"))) {
if (sourceNode.parentNode == this.mTabContainer &&
(aEvent.screenX >= sourceNode.boxObject.screenX &&
aEvent.screenX <= (sourceNode.boxObject.screenX +
sourceNode.boxObject.width))) {
return dt.effectAllowed = "none";
}
return dt.effectAllowed = "copyMove";
}
}
for (var i=0; i < this._supportedLinkDropTypes.length; i++) {
if (types.contains(this._supportedLinkDropTypes[i])) {
// Here we need to to do this manually
return dt.effectAllowed = dt.dropEffect = "link";
}
}
return dt.effectAllowed = "none";
]]>
</body>
</method>
<field name="mDragTime">0</field>
<field name="mDragOverDelay">350</field>
<method name="onDragOver">
<method name="_onDragOver">
<parameter name="aEvent"/>
<parameter name="aFlavour"/>
<parameter name="aDragSession"/>
<body>
<![CDATA[
var effects = this._setEffectAllowedForDataTransfer(aEvent);
var ib = this.mTabDropIndicatorBar;
if (effects == "none") {
ib.collapsed = "true";
return;
}
aEvent.preventDefault();
var tabStrip = this.mTabContainer.mTabstrip;
var ltr = (window.getComputedStyle(this.parentNode, null).direction
== "ltr");
@ -1843,6 +1879,7 @@
break;
case "scrollbutton-down":
case "alltabs-button":
case "newtab-button":
pixelsToScroll = tabStrip.scrollIncrement;
break;
}
@ -1850,9 +1887,7 @@
tabStrip.scrollByPixels((ltr ? 1 : -1) * pixelsToScroll);
}
var isTabDrag = (aDragSession.sourceNode &&
aDragSession.sourceNode.parentNode == this.mTabContainer);
if (!isTabDrag && aEvent.target.localName == "tab") {
if (effects == "link" && aEvent.target.localName == "tab") {
if (!this.mDragTime)
this.mDragTime = Date.now();
if (Date.now() >= this.mDragTime + this.mDragOverDelay)
@ -1911,27 +1946,27 @@
ind.style.MozMarginStart = newMargin + 'px';
ib.collapsed = !aDragSession.canDrop;
ib.collapsed = false;
]]>
</body>
</method>
<method name="onDrop">
<method name="_onDrop">
<parameter name="aEvent"/>
<parameter name="aXferData"/>
<parameter name="aDragSession"/>
<body>
<![CDATA[
var isCopy = aEvent.dataTransfer.dropEffect == "copy";
var dt = aEvent.dataTransfer;
var dropEffect = dt.dropEffect;
var draggedTab;
if (aDragSession.sourceNode && aDragSession.sourceNode.localName == "tab" &&
(aDragSession.sourceNode.parentNode == this.mTabContainer ||
aDragSession.sourceNode.ownerDocument.defaultView instanceof ChromeWindow &&
aDragSession.sourceNode.ownerDocument.documentElement.getAttribute("windowtype") == "navigator:browser"))
draggedTab = aDragSession.sourceNode;
if (draggedTab && (isCopy || draggedTab.parentNode == this.mTabContainer)) {
if (dropEffect != "link") { // copy or move
draggedTab = dt.mozGetDataAt("application/x-moz-node", 0);
NS_ASSERT(draggedTab && draggedTab.localName == "tab",
"copy or move action without a tab");
}
if (draggedTab && (dropEffect == "copy" || draggedTab.parentNode == this.mTabContainer)) {
var newIndex = this.getNewIndex(aEvent);
if (isCopy) {
if (dropEffect == "copy") {
// copy the dropped tab (wherever it's from)
var newTab = this.duplicateTab(draggedTab);
this.moveTabTo(newTab, newIndex);
@ -1969,7 +2004,20 @@
this.setTabTitle(newTab);
}
else {
var url = transferUtils.retrieveURLFromData(aXferData.data, aXferData.flavour.contentType);
var url;
for (var i=0; i < this._supportedLinkDropTypes.length; i++) {
let dataType = this._supportedLinkDropTypes[i];
// uri-list: for now, support dropping of the first URL
// only
var isURLList = dataType == "text/uri-list";
let urlData = isURLList ?
dt.mozGetDataAt("URL", 0) : dt.mozGetDataAt(dataType, 0);
if (urlData) {
url = transferUtils.retrieveURLFromData(urlData, isURLList ? "text/plain" : dataType);
break;
}
}
NS_ASSERT(url, "In the drop event, at least one mime-type should match our supported types");
// valid urls don't contain spaces ' '; if we have a space it isn't a valid url.
// Also disallow dropping javascript: or data: urls--bail out
@ -1977,7 +2025,12 @@
/^\s*(javascript|data):/.test(url))
return;
nsDragAndDrop.dragDropSecurityCheck(aEvent, aDragSession, url);
// XXXmano: temporary fix until dragDropSecurityCheck make the
// drag-session an optional paramter
var dragService = Cc["@mozilla.org/widget/dragservice;1"].
getService(Ci.nsIDragService);
var dragSession = dragService.getCurrentSession();
nsDragAndDrop.dragDropSecurityCheck(aEvent, dragSession, url);
var bgLoad = true;
try {
@ -1988,7 +2041,7 @@
if (aEvent.shiftKey)
bgLoad = !bgLoad;
if (document.getBindingParent(aEvent.originalTarget).localName != "tab" || isCopy) {
if (document.getBindingParent(aEvent.originalTarget).localName != "tab" || dropEffect == "copy") {
// We're adding a new tab.
newIndex = this.getNewIndex(aEvent);
newTab = this.loadOneTab(getShortcutOrURI(url), null, null, null, bgLoad, false);
@ -2010,16 +2063,14 @@
</body>
</method>
<method name="onDragExit">
<method name="_onDragLeave">
<parameter name="aEvent"/>
<parameter name="aDragSession"/>
<body>
<![CDATA[
this.mDragTime = 0;
if (aDragSession.sourceNode &&
aDragSession.sourceNode.parentNode == this.mTabContainer &&
aDragSession.canDrop) {
var dropEffect = aEvent.dataTransfer.dropEffect;
if (dropEffect == "move" || dropEffect == "copy") {
var target = aEvent.relatedTarget;
while (target && target != this.mStrip)
target = target.parentNode;
@ -2031,18 +2082,6 @@
</body>
</method>
<method name="getSupportedFlavours">
<body>
<![CDATA[
var flavourSet = new FlavourSet();
flavourSet.appendFlavour("text/x-moz-url");
flavourSet.appendFlavour("text/unicode");
flavourSet.appendFlavour("application/x-moz-file", "nsIFile");
return flavourSet;
]]>
</body>
</method>
<method name="moveTabTo">
<parameter name="aTab"/>
<parameter name="aIndex"/>
@ -2696,6 +2735,9 @@
class="tabbrowser-arrowscrollbox">
<children/>
</xul:arrowscrollbox>
<xul:toolbarbutton class="tabs-newtab-button" anonid="newtab-button"
command="cmd_newNavigatorTab" chromedir="&locale.dir;"
tooltiptext="&newTabButton.tooltip;"/>
<xul:stack align="center" pack="end" chromedir="&locale.dir;">
<xul:hbox flex="1" class="tabs-alltabs-box" anonid="alltabs-box"/>
<xul:hbox flex="1" class="tabs-alltabs-box-animate" anonid="alltabs-box-animate"/>

View File

@ -122,6 +122,10 @@ function runMultipleEnginesTestAndFinalize() {
is(browser.engines[0].uri, "http://first.mozilla.com/search.xml", "first engine wins");
gTestPage.close();
// Reset the default link handler
DOMLinkHandler.handleEvent = gBrowserHandler;
finish();
}

View File

@ -70,6 +70,146 @@
this.inputField.removeEventListener("mouseout", this, false);
]]></destructor>
<method name="handleRevert">
<body><![CDATA[
var throbberElement = document.getElementById("navigator-throbber");
var isScrolling = this.popupOpen;
gBrowser.userTypedValue = null;
// don't revert to last valid url unless page is NOT loading
// and user is NOT key-scrolling through autocomplete list
if ((!throbberElement || !throbberElement.hasAttribute("busy")) && !isScrolling) {
URLBarSetURI();
// If the value isn't empty and the urlbar has focus, select the value.
if (this.value && this.hasAttribute("focused"))
this.select();
}
// tell widget to revert to last typed text only if the user
// was scrolling when they hit escape
return !isScrolling;
]]></body>
</method>
<method name="handleCommand">
<parameter name="aTriggeringEvent"/>
<body><![CDATA[
if (aTriggeringEvent instanceof MouseEvent && aTriggeringEvent.button == 2)
return; // Do nothing for right clicks
var [url, postData] = this._canonizeURL(aTriggeringEvent);
if (!url)
return;
this.value = url;
gBrowser.userTypedValue = url;
try {
addToUrlbarHistory(url);
} catch (ex) {
// Things may go wrong when adding url to session history,
// but don't let that interfere with the loading of the url.
Cu.reportError(ex);
}
if (aTriggeringEvent instanceof MouseEvent) {
// We have a mouse event (from the go button), so use the standard
// UI link behaviors
openUILink(url, aTriggeringEvent, false, false,
true /* allow third party fixup */, postData);
return;
}
if (aTriggeringEvent && aTriggeringEvent.altKey) {
this.handleRevert();
content.focus();
gBrowser.loadOneTab(url, null, null, postData, false,
true /* allow third party fixup */);
aTriggeringEvent.preventDefault();
aTriggeringEvent.stopPropagation();
}
else
loadURI(url, null, postData, true /* allow third party fixup */);
focusElement(content);
]]></body>
</method>
<method name="_canonizeURL">
<parameter name="aTriggeringEvent"/>
<body><![CDATA[
var url = this.value;
if (!url)
return ["", null];
// Only add the suffix when the URL bar value isn't already "URL-like",
// and only if we get a keyboard event, to match user expectations.
if (!/^\s*(www|https?)\b|\/\s*$/i.test(url) &&
(aTriggeringEvent instanceof KeyEvent)) {
#ifdef XP_MACOSX
let accel = aTriggeringEvent.metaKey;
#else
let accel = aTriggeringEvent.ctrlKey;
#endif
let shift = aTriggeringEvent.shiftKey;
let suffix = "";
switch (true) {
case (accel && shift):
suffix = ".org/";
break;
case (shift):
suffix = ".net/";
break;
case (accel):
try {
suffix = gPrefService.getCharPref("browser.fixup.alternate.suffix");
if (suffix.charAt(suffix.length - 1) != "/")
suffix += "/";
} catch(e) {
suffix = ".com/";
}
break;
}
if (suffix) {
// trim leading/trailing spaces (bug 233205)
url = url.trim();
// Tack www. and suffix on. If user has appended directories, insert
// suffix before them (bug 279035). Be careful not to get two slashes.
// Also, don't add the suffix if it's in the original url (bug 233853).
let firstSlash = url.indexOf("/");
let existingSuffix = url.indexOf(suffix.substring(0, suffix.length - 1));
// * Logic for slash and existing suffix (example)
// No slash, no suffix: Add suffix (mozilla)
// No slash, yes suffix: Add slash (mozilla.com)
// Yes slash, no suffix: Insert suffix (mozilla/stuff)
// Yes slash, suffix before slash: Do nothing (mozilla.com/stuff)
// Yes slash, suffix after slash: Insert suffix (mozilla/?stuff=.com)
if (firstSlash >= 0) {
if (existingSuffix == -1 || existingSuffix > firstSlash)
url = url.substring(0, firstSlash) + suffix +
url.substring(firstSlash + 1);
} else
url = url + (existingSuffix == -1 ? suffix : "/");
url = "http://www." + url;
}
}
var postData = {};
url = getShortcutOrURI(url, postData);
return [url, postData.value];
]]></body>
</method>
<method name="_initURLTooltip">
<body><![CDATA[
if (this.focused || this.value == "")
@ -124,7 +264,7 @@
} catch (ex) {
return;
}
handleURLBarCommand();
this.handleCommand();
}
]]></body>
</method>

View File

@ -392,7 +392,7 @@ var FeedConverterFactory = {
if (iid.equals(Ci.nsIFactory) ||
iid.equals(Ci.nsISupports))
return this;
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
throw Cr.NS_ERROR_NO_INTERFACE;
},
};

View File

@ -42,6 +42,11 @@ const MAX_FOLDER_ITEM_IN_MENU_LIST = 5;
var gEditItemOverlay = {
_uri: null,
_itemId: -1,
_itemIds: [],
_uris: [],
_tags: [],
_allTags: [],
_multiEdit: false,
_itemType: -1,
_readOnly: false,
_microsummaries: null,
@ -53,6 +58,10 @@ var gEditItemOverlay = {
return this._itemId;
},
get multiEdit() {
return this._multiEdit;
},
/**
* Determines the initial data for the item edited or added by this dialog
*/
@ -91,14 +100,15 @@ var gEditItemOverlay = {
this._hiddenRows.indexOf("feedLocation") != -1;
this._element("siteLocationRow").collapsed = !this._isLivemark ||
this._hiddenRows.indexOf("siteLocation") != -1;
this._element("selectionCount").hidden = !this._multiEdit;
},
/**
* Initialize the panel
* @param aFor
* Either a places-itemId (of a bookmark, folder or a live bookmark),
* or a URI object (in which case, the panel would be initialized in
* read-only mode).
* an array of itemIds (used for bulk tagging), or a URI object (in
* which case, the panel would be initialized in read-only mode).
* @param [optional] aInfo
* JS object which stores additional info for the panel
* initialization. The following properties may bet set:
@ -110,6 +120,20 @@ var gEditItemOverlay = {
* read-only (view) mode even if the given item is editable.
*/
initPanel: function EIO_initPanel(aFor, aInfo) {
var aItemIdList;
if (aFor.length) {
aItemIdList = aFor;
aFor = aItemIdList[0];
}
else if (this._multiEdit) {
this._multiEdit = false;
this._tags = [];
this._uris = [];
this._allTags = [];
this._itemIds = [];
this._element("selectionCount").hidden = true;
}
this._folderMenuList = this._element("folderMenuList");
this._folderTree = this._element("folderTree");
@ -162,10 +186,27 @@ var gEditItemOverlay = {
this._isLivemark = false;
this._initTextField("locationField", this._uri.spec);
this._initTextField("tagsField",
PlacesUtils.tagging
.getTagsForURI(this._uri, {}).join(", "),
false);
if (!aItemIdList) {
var tags = PlacesUtils.tagging.getTagsForURI(this._uri, {}).join(", ");
this._initTextField("tagsField", tags, false);
}
else {
this._multiEdit = true;
this._allTags = [];
this._itemIds = aItemIdList;
var nodeToCheck = 0;
for (var i = 0; i < this._itemIds.length; i++) {
this._uris[i] = PlacesUtils.bookmarks.getBookmarkURI(this._itemIds[i], {});
this._tags[i] = PlacesUtils.tagging.getTagsForURI(this._uris[i], {});
if (this._tags[i].length < this._tags[nodeToCheck].length)
nodeToCheck = i;
}
this._getCommonTags(nodeToCheck);
this._initTextField("tagsField", this._allTags.join(", "), false);
this._element("itemsCountText").value =
PlacesUIUtils.getFormattedString("detailsPane.multipleItems",
[this._itemIds.length]);
}
// tags selector
this._rebuildTagsSelectorList();
@ -185,6 +226,24 @@ var gEditItemOverlay = {
}
},
_getCommonTags: function(aArrIndex) {
var tempArray = this._tags[aArrIndex];
var isAllTag;
for (var k = 0; k < tempArray.length; k++) {
isAllTag = true;
for (var j = 0; j < this._tags.length; j++) {
if (j == aArrIndex)
continue;
if (this._tags[j].indexOf(tempArray[k]) == -1) {
isAllTag = false;
break;
}
}
if (isAllTag)
this._allTags.push(tempArray[k]);
}
},
_initTextField: function(aTextFieldId, aValue, aReadOnly) {
var field = this._element(aTextFieldId);
field.readOnly = aReadOnly !== undefined ? aReadOnly : this._readOnly;
@ -462,6 +521,11 @@ var gEditItemOverlay = {
}
this._itemId = -1;
this._uri = null;
this._uris = [];
this._tags = [];
this._allTags = [];
this._itemIds = [];
this._multiEdit = false;
},
onTagsFieldBlur: function EIO_onTagsFieldBlur() {
@ -469,6 +533,13 @@ var gEditItemOverlay = {
},
_updateTags: function EIO__updateTags() {
if (this._multiEdit)
this._updateMultipleTagsForItems();
else
this._updateSingleTagForItem();
},
_updateSingleTagForItem: function EIO__updateSingleTagForItem() {
var currentTags = PlacesUtils.tagging.getTagsForURI(this._uri, { });
var tags = this._getTagsArrayFromTagField();
if (tags.length > 0 || currentTags.length > 0) {
@ -495,6 +566,49 @@ var gEditItemOverlay = {
}
},
_updateMultipleTagsForItems: function EIO__updateMultipleTagsForItems() {
var tags = this._getTagsArrayFromTagField();
if (tags.length > 0 || this._allTags.length > 0) {
var tagsToRemove = [];
var tagsToAdd = [];
var i;
for (i = 0; i < this._allTags.length; i++) {
if (tags.indexOf(this._allTags[i]) == -1)
tagsToRemove.push(this._allTags[i]);
}
for (i = 0; i < this._tags.length; i++) {
tagsToAdd[i] = [];
for (var j = 0; j < tags.length; j++) {
if (this._tags[i].indexOf(tags[j]) == -1)
tagsToAdd[i].push(tags[j]);
}
}
PlacesUIUtils.ptm.beginBatch();
if (tagsToAdd.length > 0) {
var tagTxn;
for (i = 0; i < this._uris.length; i++) {
if (tagsToAdd[i].length > 0) {
tagTxn = PlacesUIUtils.ptm.tagURI(this._uris[i], tagsToAdd[i]);
PlacesUIUtils.ptm.doTransaction(tagTxn);
}
}
}
if (tagsToRemove.length > 0) {
var untagTxn;
for (var i = 0; i < this._uris.length; i++) {
untagTxn = PlacesUIUtils.ptm.untagURI(this._uris[i], tagsToRemove);
PlacesUIUtils.ptm.doTransaction(untagTxn);
}
}
PlacesUIUtils.ptm.endBatch();
this._allTags = tags;
this._tags = [];
for (i = 0; i < this._uris.length; i++)
this._tags[i] = PlacesUtils.tagging.getTagsForURI(this._uris[i], {});
}
},
onNamePickerInput: function EIO_onNamePickerInput() {
var title = this._element("namePicker").value;
this._element("userEnteredName").label = title;
@ -822,8 +936,10 @@ var gEditItemOverlay = {
// Update the tags field when items are checked/unchecked in the listbox
var tags = this._getTagsArrayFromTagField();
if (aEvent.target.checked)
tags.push(aEvent.target.label);
if (aEvent.target.checked) {
if (tags.indexOf(aEvent.target.label) == -1)
tags.push(aEvent.target.label);
}
else {
var indexOfItem = tags.indexOf(aEvent.target.label);
if (indexOfItem != -1)

View File

@ -166,6 +166,14 @@
<spacer flex="1"/>
</hbox>
<row align="center" id="editBMPanel_selectionCount" hidden="true">
<spacer flex="3"/>
<vbox id="editBMPanel_itemsCountBox" align="center">
<label id="editBMPanel_itemsCountText"/>
</vbox>
<spacer flex="3"/>
</row>
<row align="center" id="editBMPanel_tagsRow">
<label value="&editBookmarkOverlay.tags.label;"
accesskey="&editBookmarkOverlay.tags.accesskey;"

View File

@ -661,6 +661,11 @@
<body><![CDATA[
PlacesUIUtils.cleanPlacesPopup(aPopup);
// If this is a livemark container check if the status menuitem has
// to be added or removed.
if (PlacesUtils.nodeIsLivemarkContainer(aPopup._resultNode))
PlacesUIUtils.ensureLivemarkStatusMenuItem(aPopup);
var cc = aPopup._resultNode.childCount;
if (cc > 0) {
if (aPopup._emptyMenuItem)
@ -804,9 +809,13 @@
if (menuitem.getAttribute("label") != title)
menuitem.setAttribute("label", title);
if (!menuitem.hasAttribute("livemark") &&
PlacesUtils.nodeIsLivemarkContainer(aNode))
menuitem.setAttribute("livemark", "true");
if (PlacesUtils.nodeIsLivemarkContainer(aNode)) {
if (!menuitem.hasAttribute("livemark"))
menuitem.setAttribute("livemark", "true");
// If this is a livemark container check if the status menuitem has
// to be added or removed.
PlacesUIUtils.ensureLivemarkStatusMenuItem(menuitem.firstChild);
}
},
itemReplaced:

View File

@ -229,7 +229,7 @@ var PlacesOrganizer = {
this._setSearchScopeForNode(node);
if (this._places.treeBoxObject.focused)
this._fillDetailsPane(node);
this._fillDetailsPane([node]);
},
/**
@ -319,8 +319,9 @@ var PlacesOrganizer = {
*/
onTreeFocus: function PO_onTreeFocus(aEvent) {
var currentView = aEvent.currentTarget;
var selectedNode = currentView.selectedNode;
this._fillDetailsPane(selectedNode);
var selectedNodes = currentView.selectedNode ? [currentView.selectedNode] :
this._content.getSelectionNodes();
this._fillDetailsPane(selectedNodes);
},
openFlatContainer: function PO_openFlatContainerFlatContainer(aContainer) {
@ -593,6 +594,13 @@ var PlacesOrganizer = {
#ifdef XP_WIN
var infoBoxExpanderLabel = document.getElementById("infoBoxExpanderLabel");
#endif
if (!aNode) {
infoBoxExpander.hidden = true;
#ifdef XP_WIN
infoBoxExpanderLabel.hidden = true;
#endif
return;
}
if (aNode.itemId != -1 &&
((PlacesUtils.nodeIsFolder(aNode) &&
!PlacesUtils.nodeIsLivemarkContainer(aNode)) ||
@ -628,13 +636,13 @@ var PlacesOrganizer = {
onContentTreeSelect: function PO_onContentTreeSelect() {
if (this._content.treeBoxObject.focused)
this._fillDetailsPane(this._content.selectedNode);
this._fillDetailsPane(this._content.getSelectionNodes());
},
_fillDetailsPane: function PO__fillDetailsPane(aSelectedNode) {
_fillDetailsPane: function PO__fillDetailsPane(aNodeList) {
var infoBox = document.getElementById("infoBox");
var detailsDeck = document.getElementById("detailsDeck");
var aSelectedNode = aNodeList.length == 1 ? aNodeList[0] : null;
// If a textbox within a panel is focused, force-blur it so its contents
// are saved
if (gEditItemOverlay.itemId != -1) {
@ -644,9 +652,10 @@ var PlacesOrganizer = {
/^editBMPanel.*/.test(focusedElement.parentNode.parentNode.id))
focusedElement.blur();
// don't update the panel if we are already editing this node
// don't update the panel if we are already editing this node unless we're
// in multi-edit mode
if (aSelectedNode && gEditItemOverlay.itemId == aSelectedNode.itemId &&
detailsDeck.selectedIndex == 1)
detailsDeck.selectedIndex == 1 && !gEditItemOverlay.multiEdit)
return;
}
@ -661,6 +670,7 @@ var PlacesOrganizer = {
gEditItemOverlay.initPanel(asQuery(aSelectedNode).folderItemId,
{ hiddenRows: ["folderPicker"],
forceReadOnly: true });
}
else {
var itemId = PlacesUtils.getConcreteItemId(aSelectedNode);
@ -670,6 +680,31 @@ var PlacesOrganizer = {
}
this._detectAndSetDetailsPaneMinimalState(aSelectedNode);
}
else if (!aSelectedNode && aNodeList[0]) {
var itemIds = [];
for (var i = 0; i < aNodeList.length; i++) {
if (!PlacesUtils.nodeIsBookmark(aNodeList[i])) {
detailsDeck.selectedIndex = 0;
var selectItemDesc = document.getElementById("selectItemDescription");
var itemsCountLabel = document.getElementById("itemsCountText");
selectItemDesc.hidden = false;
itemsCountLabel.value =
PlacesUIUtils.getFormattedString("detailsPane.multipleItems",
[aNodeList.length]);
return;
}
itemIds[i] = PlacesUtils.getConcreteItemId(aNodeList[i]);
}
detailsDeck.selectedIndex = 1;
gEditItemOverlay.initPanel(itemIds,
{ hiddenRows: ["folderPicker",
"loadInSidebar",
"location",
"keyword",
"description",
"name"]});
this._detectAndSetDetailsPaneMinimalState(aSelectedNode);
}
else {
detailsDeck.selectedIndex = 0;
var selectItemDesc = document.getElementById("selectItemDescription");

View File

@ -619,9 +619,13 @@
this._self.updateChevron();
}
if (!element.hasAttribute("livemark") &&
PlacesUtils.nodeIsLivemarkContainer(aNode))
element.setAttribute("livemark", "true");
if (PlacesUtils.nodeIsLivemarkContainer(aNode)) {
if (!element.hasAttribute("livemark"))
element.setAttribute("livemark", "true");
// If this is a livemark container check if the status menuitem has
// to be added or removed.
PlacesUIUtils.ensureLivemarkStatusMenuItem(element.firstChild);
}
},
itemReplaced:
@ -1101,6 +1105,11 @@
<body><![CDATA[
PlacesUIUtils.cleanPlacesPopup(aPopup);
// If this is a livemark container check if the status menuitem has
// to be added or removed.
if (PlacesUtils.nodeIsLivemarkContainer(aPopup._resultNode))
PlacesUIUtils.ensureLivemarkStatusMenuItem(aPopup);
var resultNode = aPopup._resultNode;
if (!resultNode.containerOpen)
resultNode.containerOpen = true;

View File

@ -1227,5 +1227,46 @@ var PlacesUIUtils = {
this.leftPaneFolderId;
delete this.allBookmarksFolderId;
return this.allBookmarksFolderId = this.leftPaneQueries["AllBookmarks"];
},
/**
* Add, update or remove the livemark status menuitem.
* @param aPopup
* The livemark container popup
*/
ensureLivemarkStatusMenuItem:
function PU_ensureLivemarkStatusMenuItem(aPopup) {
var itemId = aPopup._resultNode.itemId;
var lmStatus = null;
if (PlacesUtils.annotations
.itemHasAnnotation(itemId, "livemark/loadfailed"))
lmStatus = "bookmarksLivemarkFailed";
else if (PlacesUtils.annotations
.itemHasAnnotation(itemId, "livemark/loading"))
lmStatus = "bookmarksLivemarkLoading";
if (lmStatus && !aPopup._lmStatusMenuItem) {
// Create the status menuitem and cache it in the popup object.
aPopup._lmStatusMenuItem = document.createElement("menuitem");
aPopup._lmStatusMenuItem.setAttribute("lmStatus", lmStatus);
aPopup._lmStatusMenuItem.setAttribute("label", this.getString(lmStatus));
aPopup._lmStatusMenuItem.setAttribute("disabled", true);
aPopup.insertBefore(aPopup._lmStatusMenuItem,
aPopup.childNodes[aPopup._startMarker + 1]);
aPopup._startMarker++;
}
else if (lmStatus &&
aPopup._lmStatusMenuItem.getAttribute("lmStatus") != lmStatus) {
// Status has changed, update the cached status menuitem.
aPopup._lmStatusMenuItem.setAttribute("label",
this.getString(lmStatus));
}
else if (!lmStatus && aPopup._lmStatusMenuItem){
// No status, remove the cached menuitem.
aPopup.removeChild(aPopup._lmStatusMenuItem);
aPopup._lmStatusMenuItem = null;
aPopup._startMarker--;
}
}
};

View File

@ -406,14 +406,10 @@ function run_test() {
var txn12 = ptSvc.createLivemark(uri("http://feeduri.com"), uri("http://siteuri.com"), "Livemark1", root);
txn12.doTransaction();
// Funky stuff going on here.
// In placesCreateLivemarkTxn, livemarks.createLivemark actually returns observer._itemAddedId -1
// instead of observer._itemAddedId. Check w. someone.
do_check_true(lmsvc.isLivemark(observer._itemAddedId-1));
do_check_eq(lmsvc.getSiteURI(observer._itemAddedId-1).spec, "http://siteuri.com/");
do_check_eq(lmsvc.getFeedURI(observer._itemAddedId-1).spec, "http://feeduri.com/");
var lvmkId = observer._itemAddedId-1;
do_check_true(lmsvc.isLivemark(observer._itemAddedId));
do_check_eq(lmsvc.getSiteURI(observer._itemAddedId).spec, "http://siteuri.com/");
do_check_eq(lmsvc.getFeedURI(observer._itemAddedId).spec, "http://feeduri.com/");
var lvmkId = observer._itemAddedId;
// editLivemarkSiteURI
var txn13 = ptSvc.editLivemarkSiteURI(lvmkId, uri("http://NEWsiteuri.com/"));

View File

@ -208,9 +208,9 @@ var gMainPane = {
* 2 - The default download location is elsewhere as specified in
* browser.download.dir.
* browser.download.downloadDir
* depreciated.
* deprecated.
* browser.download.defaultFolder
* depreciated.
* deprecated.
*/
/**

View File

@ -58,7 +58,7 @@ interface nsIDOMNode;
* |getBrowser().tabContainer| such as e.g. |getBrowser().selectedTab|.
*/
[scriptable, uuid(58d17e12-a80f-11dc-8314-0800200c9a66)]
[scriptable, uuid(91f6d650-898d-11dd-ad8b-0800200c9a66)]
interface nsISessionStore : nsISupports
{
/**
@ -134,8 +134,9 @@ interface nsISessionStore : nsISupports
/**
* @param aWindow is the browser window to reopen a closed tab in.
* @param aIndex is the index of the tab to be restored (FIFO ordered).
* @returns a reference to the reopened tab.
*/
void undoCloseTab(in nsIDOMWindow aWindow, in unsigned long aIndex);
nsIDOMNode undoCloseTab(in nsIDOMWindow aWindow, in unsigned long aIndex);
/**
* @param aWindow is the window to get the value for.

View File

@ -777,6 +777,7 @@ SessionStoreService.prototype = {
},
undoCloseTab: function sss_undoCloseTab(aWindow, aIndex) {
var tab = null;
var closedTabs = this._windows[aWindow.__SSi]._closedTabs;
// default to the most-recently closed tab
@ -790,21 +791,23 @@ SessionStoreService.prototype = {
var closedTabState = closedTab.state;
// create a new tab
closedTabState._tab = browser.addTab();
tab = closedTabState._tab = browser.addTab();
// restore the tab's position
browser.moveTabTo(closedTabState._tab, closedTab.pos);
browser.moveTabTo(tab, closedTab.pos);
// restore tab content
this.restoreHistoryPrecursor(aWindow, [closedTabState], 1, 0, 0);
// focus the tab's content area
var content = browser.getBrowserForTab(closedTabState._tab).contentWindow;
var content = browser.getBrowserForTab(tab).contentWindow;
aWindow.setTimeout(function() { content.focus(); }, 0);
}
else {
Components.returnCode = Cr.NS_ERROR_INVALID_ARG;
}
return tab;
},
getWindowValue: function sss_getWindowValue(aWindow, aKey) {
@ -953,6 +956,9 @@ SessionStoreService.prototype = {
else if (tabData.extData)
delete tabData.extData;
if (history && browser.docShell instanceof Ci.nsIDocShell)
this._serializeSessionStorage(tabData, history, browser.docShell, aFullData);
return tabData;
},
@ -1069,6 +1075,52 @@ SessionStoreService.prototype = {
return entry;
},
/**
* Updates all sessionStorage "super cookies"
* @param aTabData
* The data object for a specific tab
* @param aHistory
* That tab's session history
* @param aDocShell
* That tab's docshell (containing the sessionStorage)
* @param aFullData
* always return privacy sensitive data (use with care)
*/
_serializeSessionStorage:
function sss_serializeSessionStorage(aTabData, aHistory, aDocShell, aFullData) {
let storageData = {};
let hasContent = false;
for (let i = 0; i < aHistory.count; i++) {
let uri = aHistory.getEntryAtIndex(i, false).URI.clone();
// sessionStorage is saved per domain (cf. nsDocShell::GetSessionStorageForURI)
if (uri instanceof Ci.nsIURL)
uri.path = "";
if (storageData[uri.spec] || !(aFullData || this._checkPrivacyLevel(uri.schemeIs("https"))))
continue;
let storage = aDocShell.getSessionStorageForURI(uri);
if (!storage || storage.length == 0)
continue;
let data = storageData[uri.spec] = {};
for (let j = 0; j < storage.length; j++) {
try {
let key = storage.key(j);
let item = storage.getItem(key);
data[key] = { value: item.value };
if (uri.schemeIs("https") && item.secure)
data[key].secure = true;
}
catch (ex) { /* XXXzeniko this currently throws for secured items (cf. bug 442048) */ }
}
hasContent = true;
}
if (hasContent)
aTabData.storage = storageData;
},
/**
* go through all tabs and store the current scroll positions
* and innerHTML content of WYSIWYG editors
@ -1614,6 +1666,9 @@ SessionStoreService.prototype = {
for (let name in tabData.attributes)
tab.setAttribute(name, tabData.attributes[name]);
if (tabData.storage && browser.docShell instanceof Ci.nsIDocShell)
this._deserializeSessionStorage(tabData.storage, browser.docShell);
// notify the tabbrowser that the tab chrome has been restored
var event = aWindow.document.createEvent("Events");
event.initEvent("SSTabRestoring", true, false);
@ -1733,6 +1788,29 @@ SessionStoreService.prototype = {
return shEntry;
},
/**
* restores all sessionStorage "super cookies"
* @param aStorageData
* Storage data to be restored
* @param aDocShell
* A tab's docshell (containing the sessionStorage)
*/
_deserializeSessionStorage: function sss_deserializeSessionStorage(aStorageData, aDocShell) {
let ioService = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
for (let url in aStorageData) {
let uri = ioService.newURI(url, null, null);
let storage = aDocShell.getSessionStorageForURI(uri);
for (let key in aStorageData[url]) {
try {
storage.setItem(key, aStorageData[url][key].value);
if (uri.schemeIs("https"))
storage.getItem(key).secure = aStorageData[url][key].secure || false;
}
catch (ex) { Cu.reportError(ex); } // throws e.g. for URIs that can't have sessionStorage
}
}
},
/**
* Restore properties to a loaded document
*/

View File

@ -45,12 +45,16 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_BROWSER_TEST_FILES = \
browser_339445.js \
browser_339445_sample.html \
browser_346337.js \
browser_346337_sample.html \
browser_350525.js \
browser_367052.js \
browser_393716.js \
browser_448741.js \
browser_454908.js \
browser_454908_sample.html \
$(NULL)
libs:: $(_BROWSER_TEST_FILES)

View File

@ -1,5 +1,4 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* ***** BEGIN LICENSE BLOCK *****
/* ***** 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
@ -12,15 +11,14 @@
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is thebes
* The Original Code is sessionstore test code.
*
* The Initial Developer of the Original Code is
* mozilla.org
* Portions created by the Initial Developer are Copyright (C) 2005
* Simon Bünzli <zeniko@gmail.com>.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Vladimir Vukicevic <vladimir@pobox.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
@ -36,46 +34,31 @@
*
* ***** END LICENSE BLOCK ***** */
#include "gfxGlitzSurface.h"
gfxGlitzSurface::gfxGlitzSurface(glitz_drawable_t *drawable, glitz_surface_t *surface, PRBool takeOwnership)
: mGlitzDrawable (drawable), mGlitzSurface(surface), mOwnsSurface(takeOwnership)
{
cairo_surface_t *surf = cairo_glitz_surface_create (mGlitzSurface);
Init(surf);
function test() {
/** Test for Bug 339445 **/
waitForExplicitFinish();
let testURL = "http://localhost:8888/browser/" +
"browser/components/sessionstore/test/browser/browser_339445_sample.html"
let tab = gBrowser.addTab(testURL);
tab.linkedBrowser.addEventListener("load", function(aEvent) {
let doc = tab.linkedBrowser.contentDocument;
is(doc.getElementById("storageTestItem").textContent, "PENDING",
"sessionStorage value has been set");
let tab2 = gBrowser.duplicateTab(tab);
tab2.linkedBrowser.addEventListener("load", function(aEvent) {
let doc2 = tab2.linkedBrowser.contentDocument;
is(doc2.getElementById("storageTestItem").textContent, "SUCCESS",
"sessionStorage value has been duplicated");
// clean up
gBrowser.removeTab(tab2);
gBrowser.removeTab(tab);
finish();
}, true);
}, true);
}
gfxGlitzSurface::~gfxGlitzSurface()
{
if (mOwnsSurface) {
if (mGlitzSurface) {
glitz_surface_flush(mGlitzSurface);
glitz_surface_destroy(mGlitzSurface);
}
if (mGlitzDrawable) {
glitz_drawable_flush(mGlitzDrawable);
glitz_drawable_finish(mGlitzDrawable);
glitz_drawable_destroy(mGlitzDrawable);
}
}
}
void
gfxGlitzSurface::SwapBuffers()
{
glitz_drawable_swap_buffers (GlitzDrawable());
}
unsigned long
gfxGlitzSurface::Width()
{
return glitz_drawable_get_width (GlitzDrawable());
}
unsigned long
gfxGlitzSurface::Height()
{
return glitz_drawable_get_height (GlitzDrawable());
}

View File

@ -0,0 +1,17 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<title>Test for bug 339445</title>
storageTestItem = <span id="storageTestItem">FAIL</span>
<!--
storageTestItem's textContent will be one of the following:
* FAIL : sessionStorage wasn't available
* PENDING : the test value has been initialized on first load
* SUCCESS : the test value was correctly retrieved
-->
<script type="application/javascript">
document.getElementById("storageTestItem").textContent =
sessionStorage["storageTestItem"] || "PENDING";
sessionStorage["storageTestItem"] = "SUCCESS";
</script>

View File

@ -113,9 +113,7 @@ function test() {
tabbrowser.removeTab(tab2);
tabbrowser.removeTab(tab);
undoCloseTab();
tab = tabbrowser.selectedTab;
tab = undoCloseTab();
tab.linkedBrowser.addEventListener("load", function(aEvent) {
for (let xpath in fieldList)
if (fieldList[xpath])

View File

@ -85,8 +85,8 @@ function test() {
ok(newcount > count, "after closing a tab, getClosedTabCount has been incremented");
// undoCloseTab
ok(test(function() ss.undoCloseTab(window, 0)), "undoCloseTab doesn't throw")
tab = tabbrowser.selectedTab;
tab = test(function() ss.undoCloseTab(window, 0));
ok(tab, "undoCloseTab doesn't throw")
tab.linkedBrowser.addEventListener("load", function(aEvent) {
is(this.currentURI.spec, testURL, "correct tab was reopened");

View File

@ -0,0 +1,79 @@
/* ***** 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 sessionstore test code.
*
* The Initial Developer of the Original Code is
* Simon Bünzli <zeniko@gmail.com>.
* Portions created by the Initial Developer are Copyright (C) 2008
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* 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 ***** */
function test() {
/** Test for Bug 454908 **/
waitForExplicitFinish();
let fieldValues = {
username: "User " + Math.random(),
passwd: "pwd" + Date.now()
};
// make sure we do save form data
let privacy_level = gPrefService.getIntPref("browser.sessionstore.privacy_level");
gPrefService.setIntPref("browser.sessionstore.privacy_level", 0);
let testURL = "chrome://mochikit/content/browser/" +
"browser/components/sessionstore/test/browser/browser_454908_sample.html";
let tab = gBrowser.addTab(testURL);
tab.linkedBrowser.addEventListener("load", function(aEvent) {
let doc = tab.linkedBrowser.contentDocument;
for (let id in fieldValues)
doc.getElementById(id).value = fieldValues[id];
gBrowser.removeTab(tab);
undoCloseTab();
tab = gBrowser.selectedTab;
tab.linkedBrowser.addEventListener("load", function(aEvent) {
let doc = tab.linkedBrowser.contentDocument;
for (let id in fieldValues) {
let node = doc.getElementById(id);
if (node.type == "password")
is(node.value, "", "password wasn't saved/restored");
else
is(node.value, fieldValues[id], "username was saved/restored");
}
// clean up
gPrefService.setIntPref("browser.sessionstore.privacy_level", privacy_level);
gBrowser.removeTab(tab);
finish();
}, true);
}, true);
}

View File

@ -0,0 +1,8 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">
<title>Test for bug 454908</title>
<h3>Dummy Login</h3>
<form>
<p>Username: <input type="text" id="username">
<p>Password: <input type="password" id="passwd">
</form>

View File

@ -328,7 +328,8 @@ nsGNOMEShellService::GetShouldCheckDefaultBrowser(PRBool* aResult)
if (pserve)
pserve->GetBranch("", getter_AddRefs(prefs));
prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult);
if (prefs)
prefs->GetBoolPref(PREF_CHECKDEFAULTBROWSER, aResult);
return NS_OK;
}
@ -341,7 +342,8 @@ nsGNOMEShellService::SetShouldCheckDefaultBrowser(PRBool aShouldCheck)
if (pserve)
pserve->GetBranch("", getter_AddRefs(prefs));
prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck);
if (prefs)
prefs->SetBoolPref(PREF_CHECKDEFAULTBROWSER, aShouldCheck);
return NS_OK;
}

View File

@ -309,7 +309,6 @@ you can use these alternative items. Otherwise, their values should be empty. -
<!ENTITY fullZoom.label "Zoom">
<!ENTITY fullZoom.accesskey "Z">
<!ENTITY newTabButton.tooltip "Open a new tab">
<!ENTITY newWindowButton.tooltip "Open a new window">
<!ENTITY sidebarCloseButton.tooltip "Close sidebar">

View File

@ -5,7 +5,6 @@ openFile=Open File
droponbookmarksbutton=Drop a link to bookmark it
dropondownloadsbutton=Drop a link or file to download it
droponnewtabbutton=Drop a link or file to open it in a new tab
droponnewwindowbutton=Drop a link or file to open it in a new window
droponhomebutton=Drop a link or file to make it your home page
droponhometitle=Set Home Page

View File

@ -29,6 +29,9 @@ bookmarksRestoreFilterExtension=*.json
bookmarksRestoreFormatError=Unsupported file type.
bookmarksRestoreParseError=Unable to process the backup file.
bookmarksLivemarkLoading=Live Bookmark loading…
bookmarksLivemarkFailed=Live Bookmark feed failed to load.
headerTextPrefix1=Showing
headerTextPrefix2=Search Results for
headerTextPrefix3=Advanced Search

View File

@ -16,3 +16,4 @@
<!ENTITY bookmarkThisTab.accesskey "B">
<!ENTITY undoCloseTab.label "Undo Close Tab">
<!ENTITY undoCloseTab.accesskey "U">
<!ENTITY newTabButton.tooltip "Open a new tab">

View File

@ -594,13 +594,6 @@ toolbar[mode="full"] .toolbarbutton-menubutton-button {
list-style-image: url("moz-icon://stock/gtk-print?size=toolbar&state=disabled");
}
#new-tab-button {
-moz-image-region: rect(0px 96px 24px 72px);
}
#new-tab-button[disabled="true"] {
-moz-image-region: rect(24px 96px 48px 72px);
}
#new-window-button {
-moz-image-region: rect(0px 120px 24px 96px);
}
@ -731,13 +724,6 @@ toolbar[iconsize="small"] #print-button[disabled="true"] {
list-style-image: url("moz-icon://stock/gtk-print?size=menu&state=disabled");
}
toolbar[iconsize="small"] #new-tab-button {
-moz-image-region: rect(0px 64px 16px 48px);
}
toolbar[iconsize="small"] #new-tab-button[disabled="true"] {
-moz-image-region: rect(16px 64px 32px 48px);
}
toolbar[iconsize="small"] #new-window-button {
-moz-image-region: rect(0px 80px 16px 64px);
}
@ -1303,6 +1289,16 @@ tabpanels {
outline: none !important;
}
/* New tab button */
.tabs-newtab-button {
list-style-image: url(chrome://browser/skin/tabbrowser/newtab.png);
border: none;
}
.tabs-newtab-button > .toolbarbutton-icon {
margin: -1px 0 0;
}
/* Tabstrip close button */
.tabs-closebutton {
list-style-image: url("moz-icon://stock/gtk-close?size=menu");
@ -1310,7 +1306,7 @@ tabpanels {
}
.tabs-closebutton > .toolbarbutton-icon {
margin: -3px !important;
margin: 0;
}
/* Tabbrowser arrowscrollbox arrows */

View File

@ -56,8 +56,7 @@ classic.jar:
skin/classic/browser/preferences/Options.png (preferences/Options.png)
* skin/classic/browser/preferences/preferences.css (preferences/preferences.css)
skin/classic/browser/preferences/applications.css (preferences/applications.css)
skin/classic/browser/tabbrowser/tab-arrow-end.png (tabbrowser/tab-arrow-end.png)
skin/classic/browser/tabbrowser/tab-arrow-start.png (tabbrowser/tab-arrow-start.png)
skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
skin/classic/browser/tabbrowser/tabDragIndicator.png (tabbrowser/tabDragIndicator.png)
icon.png
preview.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 804 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 255 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

View File

@ -108,7 +108,7 @@
toolbarbutton.bookmark-item {
font-weight: bold;
margin: 0 1px;
padding: 0;
padding: 0 0 1px 0;
-moz-padding-start: 7px;
min-width: 0;
max-width: 13em;
@ -750,18 +750,6 @@ toolbar[iconsize="small"] #unified-back-forward-button > #back-forward-dropmarke
-moz-image-region: rect(46px, 324px, 69px, 288px);
}
/* ----- DEFAULT NEW-TAB BUTTON ----- */
#new-tab-button {
-moz-image-region: rect(0px, 360px, 23px, 324px);
}
#new-tab-button[disabled="true"] {
-moz-image-region: rect(23px, 360px, 46px, 324px);
}
#new-tab-button:hover:active {
-moz-image-region: rect(46px, 360px, 69px, 324px);
}
/* ----- DEFAULT NEW-WINDOW BUTTON ----- */
#new-window-button {
@ -1854,35 +1842,42 @@ tabbrowser > tabbox > tabpanels {
/**
* All Tabs Button
* New Tab & All Tabs Buttons
*/
.tabs-alltabs-box {
margin: 0;
width: 25px;
}
.tabs-newtab-button ,
.tabs-alltabs-button {
list-style-image: url("chrome://browser/skin/tabbrowser/alltabs-box-bkgnd-icon.png");
-moz-border-start: 2px solid;
-moz-border-end: none;
-moz-border-left-colors: rgba(0,0,0,0.25) rgba(255,255,255,0.15);
-moz-border-right-colors: rgba(0,0,0,0.25) rgba(255,255,255,0.15);
margin: 0;
padding: 2px 0 0 0;
padding: 0 4px;
}
.tabs-newtab-button {
list-style-image: url(chrome://browser/skin/tabbrowser/newtab.png);
}
.tabs-alltabs-button {
padding-top: 2px;
list-style-image: url(chrome://browser/skin/tabbrowser/alltabs-box-bkgnd-icon.png);
}
.tabs-newtab-button:hover ,
.tabs-alltabs-button:hover {
background-color: rgba(0,0,0,0.10);
}
.tabs-newtab-button:hover:active,
.tabs-alltabs-button:hover:active,
.tabs-alltabs-button[open="true"] {
background-color: rgba(0,0,0,0.20);
}
.tabs-alltabs-button > .toolbarbutton-menu-dropmarker {
display: none;
}
.tabs-alltabs-button > .toolbarbutton-text {
.tabs-newtab-button > .toolbarbutton-text ,
.tabs-alltabs-button > .toolbarbutton-menu-dropmarker ,
.tabs-alltabs-button > .toolbarbutton-text {
display: none;
}

View File

@ -118,6 +118,7 @@ classic.jar:
skin/classic/browser/tabbrowser/alltabs-box-bkgnd-icon.png (tabbrowser/alltabs-box-bkgnd-icon.png)
skin/classic/browser/tabbrowser/alltabs-box-overflow-bkgnd.png (tabbrowser/alltabs-box-overflow-bkgnd.png)
skin/classic/browser/tabbrowser/alltabs-box-overflow-bkgnd-animate.png (tabbrowser/alltabs-box-overflow-bkgnd-animate.png)
skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
skin/classic/browser/tabbrowser/tab-arrow-start.png (tabbrowser/tab-arrow-start.png)
skin/classic/browser/tabbrowser/tab-arrow-start-bkgnd.png (tabbrowser/tab-arrow-start-bkgnd.png)
skin/classic/browser/tabbrowser/tab-arrow-start-bkgnd-animate.png (tabbrowser/tab-arrow-start-bkgnd-animate.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

View File

@ -650,24 +650,6 @@ toolbar[iconsize="small"][mode="icons"] #back-forward-dropmarker[chromedir="rtl"
-moz-image-region: rect(96px 216px 120px 192px);
}
/* new tab button */
toolbar:not([iconsize="small"]) #new-tab-button > .toolbarbutton-icon {
padding-left: 1px;
}
#new-tab-button {
-moz-image-region: rect(0px 240px 24px 216px);
}
#new-tab-button:not([disabled="true"]):hover {
-moz-image-region: rect(24px 240px 48px 216px);
}
#new-tab-button[disabled="true"] {
-moz-image-region: rect(48px 240px 72px 216px);
}
#new-tab-button:not([disabled="true"]):hover:active {
-moz-image-region: rect(96px 240px 120px 216px);
}
/* new window button */
toolbar:not([iconsize="small"]) #new-window-button > .toolbarbutton-icon {
@ -956,24 +938,6 @@ toolbar[iconsize="small"] #print-button:not([disabled="true"]):hover:active {
-moz-image-region: rect(64px 144px 80px 128px);
}
/* new tab button */
toolbar[iconsize="small"] #new-tab-button > .toolbarbutton-icon {
padding-left: 1px;
}
toolbar[iconsize="small"] #new-tab-button {
-moz-image-region: rect(0px 160px 16px 144px);
}
toolbar[iconsize="small"] #new-tab-button:not([disabled="true"]):hover {
-moz-image-region: rect(16px 160px 32px 144px);
}
toolbar[iconsize="small"] #new-tab-button[disabled="true"] {
-moz-image-region: rect(32px 160px 48px 144px);
}
toolbar[iconsize="small"] #new-tab-button:not([disabled="true"]):hover:active {
-moz-image-region: rect(64px 160px 80px 144px);
}
/* new window button */
toolbar[iconsize="small"] #new-window-button {
@ -1502,9 +1466,10 @@ tabpanels {
outline: none !important;
}
/* Tab scrollbox arrow and all-tabs buttons */
/* Tab scrollbox arrow, new tab and all-tabs buttons */
.tabbrowser-arrowscrollbox > .scrollbutton-up,
.tabbrowser-arrowscrollbox > .scrollbutton-down,
.tabs-newtab-button,
.tabs-alltabs-button {
-moz-appearance: none;
width: 18px;
@ -1522,6 +1487,7 @@ tabpanels {
.tabbrowser-arrowscrollbox > .scrollbutton-up:not([disabled="true"]):hover,
.tabbrowser-arrowscrollbox > .scrollbutton-down:not([disabled="true"]):hover,
.tabs-newtab-button:hover,
.tabs-alltabs-button:hover {
border-top-width: 1px;
padding-top: 1px;
@ -1565,6 +1531,7 @@ tabpanels {
}
.tabbrowser-arrowscrollbox > .scrollbutton-down,
.tabs-newtab-button,
.tabs-alltabs-button {
border-right-style: none;
-moz-border-radius-topleft: 2px;
@ -1575,6 +1542,7 @@ tabpanels {
}
.tabbrowser-arrowscrollbox > .scrollbutton-down[chromedir="rtl"],
.tabs-newtab-button[chromedir="rtl"],
.tabs-container > stack[chromedir="rtl"] > .tabs-alltabs-button {
border-left-style: none;
border-right-style: solid;
@ -1592,6 +1560,13 @@ tabpanels {
-moz-margin-end: 2px;
}
.tabs-newtab-button > .toolbarbutton-icon {
list-style-image: url(chrome://browser/skin/tabbrowser/newtab.png);
margin: 3px 0 0;
-moz-margin-end: 2px;
}
.tabs-newtab-button > .toolbarbutton-text,
.tabs-alltabs-button > .toolbarbutton-text,
.tabs-alltabs-button > .toolbarbutton-icon {
display: none;

View File

@ -76,6 +76,7 @@ classic.jar:
skin/classic/browser/preferences/applications.css (preferences/applications.css)
skin/classic/browser/tabbrowser/alltabs-box-overflow-end-bkgnd-animate.png (tabbrowser/alltabs-box-overflow-end-bkgnd-animate.png)
skin/classic/browser/tabbrowser/alltabs-box-overflow-start-bkgnd-animate.png (tabbrowser/alltabs-box-overflow-start-bkgnd-animate.png)
skin/classic/browser/tabbrowser/newtab.png (tabbrowser/newtab.png)
skin/classic/browser/tabbrowser/tab-arrow-end.png (tabbrowser/tab-arrow-end.png)
skin/classic/browser/tabbrowser/tab-arrow-start.png (tabbrowser/tab-arrow-start.png)
skin/classic/browser/tabbrowser/tabbrowser-tabs-bkgnd.png (tabbrowser/tabbrowser-tabs-bkgnd.png)
@ -165,6 +166,7 @@ classic.jar:
skin/classic/aero/browser/preferences/applications.css (preferences/applications.css)
skin/classic/aero/browser/tabbrowser/alltabs-box-overflow-end-bkgnd-animate.png (tabbrowser/alltabs-box-overflow-end-bkgnd-animate.png)
skin/classic/aero/browser/tabbrowser/alltabs-box-overflow-start-bkgnd-animate.png (tabbrowser/alltabs-box-overflow-start-bkgnd-animate.png)
skin/classic/aero/browser/tabbrowser/newtab.png (tabbrowser/newtab-aero.png)
skin/classic/aero/browser/tabbrowser/tab-arrow-end.png (tabbrowser/tab-arrow-end-aero.png)
skin/classic/aero/browser/tabbrowser/tab-arrow-start.png (tabbrowser/tab-arrow-start-aero.png)
skin/classic/aero/browser/tabbrowser/tabbrowser-tabs-bkgnd.png (tabbrowser/tabbrowser-tabs-bkgnd.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 395 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 413 B

View File

@ -104,6 +104,12 @@ ifeq ($(host_os), cygwin)
AUTOMATION_PPARGS += -DIS_CYGWIN=1
endif
ifeq ($(ENABLE_TESTS), 1)
AUTOMATION_PPARGS += -DIS_TEST_BUILD=1
else
AUTOMATION_PPARGS += -DIS_TEST_BUILD=0
endif
_LEAKTEST_DIR = $(DEPTH)/_leaktest
_LEAKTEST_FILES = \

View File

@ -108,6 +108,12 @@ ifeq ($(host_os), cygwin)
AUTOMATION_PPARGS += -DIS_CYGWIN=1
endif
ifeq ($(ENABLE_TESTS), 1)
AUTOMATION_PPARGS += -DIS_TEST_BUILD=1
else
AUTOMATION_PPARGS += -DIS_TEST_BUILD=0
endif
automation.py: automation.py.in
$(PYTHON) $(topsrcdir)/config/Preprocessor.py \
$(AUTOMATION_PPARGS) $(DEFINES) $(ACDEFINES) $^ > $@
@ -124,3 +130,6 @@ GARBAGE += automation.py profileserver.py genpgocert.py
libs:: $(_PGO_FILES)
$(INSTALL) $^ $(_PROFILE_DIR)
tools::
$(PYTHON) $(DEPTH)/_profile/pgo/genpgocert.py --gen-server

View File

@ -83,6 +83,7 @@ UNIXISH = not IS_WIN32 and not IS_MAC
#expand DEFAULT_APP = "./" + __BROWSER_PATH__
#expand CERTS_DIR = __CERTS_DIR__
#expand IS_TEST_BUILD = __IS_TEST_BUILD__
###########
# LOGGING #
@ -443,15 +444,17 @@ def environment(env = None):
###############
def runApp(testURL, env, app, profileDir, extraArgs):
# create certificate database for the profile
certificateStatus = fillCertificateDB(profileDir)
if certificateStatus != 0:
log.info("ERROR FAIL Certificate integration")
return certificateStatus
ssltunnel = DIST_BIN + "/ssltunnel" + BIN_SUFFIX
ssltunnelProcess = Process(ssltunnel, [os.path.join(CERTS_DIR, "ssltunnel.cfg")], environment())
log.info("SSL tunnel pid: %d", ssltunnelProcess.pid)
if (IS_TEST_BUILD):
# create certificate database for the profile
certificateStatus = fillCertificateDB(profileDir)
if certificateStatus != 0:
log.info("ERROR FAIL Certificate integration")
return certificateStatus
# start ssltunnel to provide https:// URLs capability
ssltunnel = DIST_BIN + "/ssltunnel" + BIN_SUFFIX
ssltunnelProcess = Process(ssltunnel, [os.path.join(CERTS_DIR, "ssltunnel.cfg")], environment())
log.info("SSL tunnel pid: %d", ssltunnelProcess.pid)
"Run the app, returning the time at which it was started."
# mark the start
@ -484,6 +487,7 @@ def runApp(testURL, env, app, profileDir, extraArgs):
if status != 0:
log.info("ERROR FAIL Exited with code %d during test run", status)
ssltunnelProcess.kill()
if (IS_TEST_BUILD):
ssltunnelProcess.kill()
return start

View File

@ -790,6 +790,7 @@ typedef struct
#endif
#define SHGetSpecialFolderPathW SHGetSpecialFolderPath
#define SHGetFileInfoW SHGetFileInfo
// On Windows CE, there are some functions that are wide, but there
// isn't a function named "functionW".

View File

@ -438,6 +438,9 @@ MOZCE_SHUNT_API wchar_t *_wfullpath(wchar_t *abspath, const wchar_t *relpath, in
MOZCE_SHUNT_API HWND GetAncestor(HWND hwnd, UINT gaFlags);
MOZCE_SHUNT_API int _chdir (const char *dirname);
MOZCE_SHUNT_API int _wchdir (const wchar_t *dirname);
#ifdef __cplusplus
};
#endif

View File

@ -158,6 +158,18 @@ MOZCE_SHUNT_API int remove(const char* inPath)
return retval;
}
MOZCE_SHUNT_API int setmode(FILE*, int)
{
return 0;
}
MOZCE_SHUNT_API int _chdir (const char *dirname)
{
return 0;
}
MOZCE_SHUNT_API int _wchdir (const wchar_t *dirname)
{
return 0;
}
MOZCE_SHUNT_API char* getcwd(char* buff, size_t size)
{
WINCE_LOG_API_CALL("getcwd called.\n");

View File

@ -1193,6 +1193,30 @@ MOZCE_SHUNT_API DWORD SetNamedSecurityInfoW(unsigned short* pObjectName,
}
MOZCE_SHUNT_API void FatalAppExitW(UINT uAction, LPCWSTR lpMessageText)
{
if ( ::MessageBoxW(NULL, lpMessageText, L"Runtime Error", MB_OKCANCEL | MB_ICONERROR) == IDCANCEL )
return;
exit(-1);
}
MOZCE_SHUNT_API int clock()
{
return -1;
}
MOZCE_SHUNT_API int GetDIBits(HDC hdc, HBITMAP hbmp, UINT uStartScan, UINT cScanLines,
LPVOID lpvBits, LPBITMAPINFO lpbi, UINT uUsage)
{
#if 0
return GetBitmapBits(hbmp,lpbi->bmiHeader.biSize, lpvBits);
#else
return 0;
#endif
}
#if 0
{

View File

@ -37,7 +37,7 @@
DEVENV_FLAG=-
CC=cl
CC=cl -O2
MOZCE_DEVENV=vs$(MOZ_MSVCVERSION)

View File

@ -15,41 +15,41 @@ main(int argc, char **argv)
args[i++] = "/LIBPATH:\"" WCE_CRT "\"";
args[i++] = "/LIBPATH:\"" SHUNT_LIB "\"";
args[i++] = "winsock.lib";
args[i++] = "corelibc.lib";
args[i++] = "coredll.lib";
args[i++] = "ceshell.lib";
args[i++] = "ole32.lib";
args[i++] = "mmtimer.lib";
args[i++] = "mozce_shunt.lib";
args[i++] = "/NODEFAULTLIB:LIBC";
args[i++] = "/NODEFAULTLIB:OLDNAMES";
args[i++] = "/NODEFAULTLIB:MSVCRT";
// if -DLL is not passed, then change the entry to 'main'
while(argv[j])
{
if (strncmp(argv[j], "-DLL", 4) == 0 || strncmp(argv[j], "/DLL", 4) == 0)
{
k = 1;
while(argv[j]) {
}
if (strncmp(argv[j], "-entry", 6) == 0 || strncmp(argv[j], "/entry", 6) == 0 || strncmp(argv[j], "-ENTRY", 6) == 0 || strncmp(argv[j], "/ENTRY",6 ) == 0)
{
k = 1;
}
if (strncmp(argv[j], "-subsystem:", 11) == 0 || strncmp(argv[j], "/subsystem:", 11) == 0 || strncmp(argv[j], "-SUBSYSTEM:", 11) == 0 || strncmp(argv[j], "/SUBSYSTEM:", 11) == 0)
{
s = 1;
}
if (strncmp(argv[j], "-DLL", 4) == 0 ||
strncmp(argv[j], "/DLL", 4) == 0) {
k = 1;
}
if (strncmp(argv[j], "-entry", 6) == 0 ||
strncmp(argv[j], "/entry", 6) == 0 ||
strncmp(argv[j], "-ENTRY", 6) == 0 ||
strncmp(argv[j], "/ENTRY",6 ) == 0) {
k = 1;
}
if (strncmp(argv[j], "-subsystem:", 11) == 0 ||
strncmp(argv[j], "/subsystem:", 11) == 0 ||
strncmp(argv[j], "-SUBSYSTEM:", 11) == 0 ||
strncmp(argv[j], "/SUBSYSTEM:", 11) == 0) {
s = 1;
}
j++;
}
}
if (k==0)
args[i++] = "/ENTRY:main";
if (s==0){
args[i++] = "/subsystem:\"WINDOWSCE,5.02\"";
}

View File

@ -11,6 +11,7 @@ cl arm-wince-as.c
cl arm-wince-gcc.c
cl arm-wince-lib.c
cl arm-wince-link.c
cl arm-wince-res.c
rm *.obj
rm *.ilk

View File

@ -7,10 +7,12 @@
#endif
#define WCE_BIN "c:\\Program Files\\Microsoft Visual Studio 8\\VC\\ce\\bin\\x86_arm\\"
#define WCE_RC_BIN "C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0a\\bin\\"
#define WCE_CRT "c:\\Program Files\\Microsoft Visual Studio 8\\VC/ce\\lib\\armv4i"
#define WCE_INC "C:\\Program Files\\Windows Mobile 6 SDK\\Smartphone\\Include\\Armv4i"
#define WCE_LIB "C:\\Program Files\\Windows Mobile 6 SDK\\Smartphone\\Lib\\Armv4i"
#define WCE_INC "c:\\Program Files\\Windows Mobile 6 SDK\\Smartphone\\Include\\Armv4i"
#define WCE_LIB "c:\\Program Files\\Windows Mobile 6 SDK\\Smartphone\\Lib\\Armv4i"
//#define WCE_RC_BIN "c:\\Program Files\\Microsoft Visual Studio 8\\VC\\bin\\"
#define WCE_RC_BIN "c:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\bin\\"
#define SHUNT_LIB TOPSRCDIR "/build/wince/shunt/build/vs8/"
#define SHUNT_INC TOPSRCDIR "/build/wince/shunt/include/"
@ -21,7 +23,7 @@
#define LINK_PATH WCE_BIN "link.exe"
#define RC_PATH WCE_RC_BIN "rc.exe"
#define MAX_NOLEAK_BUFFERS 100
#define MAX_NOLEAK_BUFFERS 1000
char noleak_buffers[MAX_NOLEAK_BUFFERS][1024];
static int next_buffer = 0;

View File

@ -15,37 +15,37 @@ main(int argc, char **argv)
args[i++] = "/LIBPATH:\"" WCE_CRT "\"";
args[i++] = "/LIBPATH:\"" SHUNT_LIB "\"";
args[i++] = "winsock.lib";
args[i++] = "corelibc.lib";
args[i++] = "coredll.lib";
args[i++] = "ceshell.lib";
args[i++] = "ole32.lib";
args[i++] = "mmtimer.lib";
args[i++] = "mozce_shunt.lib";
args[i++] = "/NODEFAULTLIB:LIBC";
args[i++] = "/NODEFAULTLIB:OLDNAMES";
args[i++] = "/NODEFAULTLIB:MSVCRT";
// if -DLL is not passed, then change the entry to 'main'
while(argv[j])
{
if (strncmp(argv[j], "-DLL", 4) == 0 || strncmp(argv[j], "/DLL", 4) == 0)
{
k = 1;
while(argv[j]) {
}
if (strncmp(argv[j], "-entry", 6) == 0 || strncmp(argv[j], "/entry", 6) == 0 || strncmp(argv[j], "-ENTRY", 6) == 0 || strncmp(argv[j], "/ENTRY",6 ) == 0)
{
k = 1;
}
if (strncmp(argv[j], "-subsystem:", 11) == 0 || strncmp(argv[j], "/subsystem:", 11) == 0 || strncmp(argv[j], "-SUBSYSTEM:", 11) == 0 || strncmp(argv[j], "/SUBSYSTEM:", 11) == 0)
{
s = 1;
}
if (strncmp(argv[j], "-DLL", 4) == 0 ||
strncmp(argv[j], "/DLL", 4) == 0) {
k = 1;
}
if (strncmp(argv[j], "-entry", 6) == 0 ||
strncmp(argv[j], "/entry", 6) == 0 ||
strncmp(argv[j], "-ENTRY", 6) == 0 ||
strncmp(argv[j], "/ENTRY",6 ) == 0) {
k = 1;
}
if (strncmp(argv[j], "-subsystem:", 11) == 0 ||
strncmp(argv[j], "/subsystem:", 11) == 0 ||
strncmp(argv[j], "-SUBSYSTEM:", 11) == 0 ||
strncmp(argv[j], "/SUBSYSTEM:", 11) == 0) {
s = 1;
}
j++;
}
}
if (k==0)
args[i++] = "/ENTRY:main";

View File

@ -7,7 +7,8 @@
#endif
#define WCE_BIN "c:\\Program Files\\Microsoft Visual Studio 9.0\\VC\\ce\\bin\\x86_arm\\"
#define WCE_RC_BIN "c:\\Program Files\\Microsoft SDKs\\Windows\\v6.0a\\bin\\"
//#define WCE_RC_BIN "c:\\Program Files\\Microsoft SDKs\\Windows\\v6.0a\\bin\\"
#define WCE_RC_BIN "c:\\Program Files\\Microsoft Visual Studio 9.0\\VC\\bin\\"
#define WCE_CRT "c:\\Program Files\\Microsoft Visual Studio 9.0\\VC\\ce\\lib\\armv4i"
#define WCE_INC "c:\\Program Files\\Windows Mobile 6 SDK\\Smartphone\\Include\\Armv4i"
#define WCE_LIB "c:\\Program Files\\Windows Mobile 6 SDK\\Smartphone\\Lib\\Armv4i"
@ -22,7 +23,7 @@
#define LINK_PATH WCE_BIN "link.exe"
#define RC_PATH WCE_RC_BIN "rc.exe"
#define MAX_NOLEAK_BUFFERS 100
#define MAX_NOLEAK_BUFFERS 1000
char noleak_buffers[MAX_NOLEAK_BUFFERS][1024];
static int next_buffer = 0;

View File

@ -380,6 +380,12 @@ class JarMaker(object):
return getModTime(os.path.join(self.basepath, aPath))
def getOutput(self, name):
out = self.ensureDirFor(name)
# remove previous link or file
try:
os.remove(out)
except OSError, e:
if e.errno != 2:
raise
return open(out, 'wb')
def ensureDirFor(self, name):
out = os.path.join(self.basepath, name)
@ -394,6 +400,12 @@ class JarMaker(object):
'''
def symlink(self, src, dest):
out = self.ensureDirFor(dest)
# remove previous link or file
try:
os.remove(out)
except OSError, e:
if e.errno != 2:
raise
os.symlink(src, out)
def main():

View File

@ -62,6 +62,8 @@ TARGETS = $(HOST_PROGRAM) $(PLSRCS:.pl=) $(SIMPLE_PROGRAMS)
ifndef CROSS_COMPILE
ifdef USE_ELF_DYNSTR_GC
TARGETS += elf-dynstr-gc
MAKE_DIRS += $(MDDEPDIR)
GARBAGE_DIRS += $(MDDEPDIR)
endif
endif

View File

@ -341,6 +341,9 @@ NS_USE_NATIVE = @NS_USE_NATIVE@
CC = @CC@
CXX = @CXX@
CC_VERSION = @CC_VERSION@
CXX_VERSION = @CXX_VERSION@
GNU_AS = @GNU_AS@
GNU_LD = @GNU_LD@
GNU_CC = @GNU_CC@
@ -497,7 +500,6 @@ MOZ_TOOLKIT_REGISTRY_CFLAGS = \
CAIRO_FT_CFLAGS = @CAIRO_FT_CFLAGS@
MOZ_ENABLE_CAIRO_FT = @MOZ_ENABLE_CAIRO_FT@
MOZ_ENABLE_GLITZ = @MOZ_ENABLE_GLITZ@
MOZ_ENABLE_GTK2 = @MOZ_ENABLE_GTK2@
MOZ_ENABLE_QT = @MOZ_ENABLE_QT@
MOZ_ENABLE_PHOTON = @MOZ_ENABLE_PHOTON@
@ -520,8 +522,6 @@ MOZ_GTHREAD_LIBS = @MOZ_GTHREAD_LIBS@
FT2_CFLAGS = @FT2_CFLAGS@
FT2_LIBS = @FT2_LIBS@
MOZ_XFT_CFLAGS = @MOZ_XFT_CFLAGS@
MOZ_XFT_LIBS = @MOZ_XFT_LIBS@
MOZ_PANGO_CFLAGS = @MOZ_PANGO_CFLAGS@
MOZ_PANGO_LIBS = @MOZ_PANGO_LIBS@

View File

@ -82,7 +82,6 @@ STATIC_EXTRA_LIBS += $(MOZ_CAIRO_LIBS)
ifdef MOZ_ENABLE_GTK2
STATIC_EXTRA_LIBS += $(XLDFLAGS) $(XT_LIBS) -lgthread-2.0
STATIC_EXTRA_LIBS += $(MOZ_XFT_LIBS)
STATIC_EXTRA_LIBS += $(MOZ_PANGO_LIBS)
endif

View File

@ -120,7 +120,6 @@ LIBIDL_VERSION=0.6.3
PERL_VERSION=5.006
LIBART_VERSION=2.3.4
CAIRO_VERSION=1.6.0
GLITZ_VERSION=0.4.0
PANGO_VERSION=1.10.0
GTK2_VERSION=2.10.0
MAKE_VERSION=3.78
@ -2462,10 +2461,11 @@ dnl the qsort routine under solaris is faulty
# $ORIGIN/.. is for shared libraries under components/ to locate shared
# libraries one level up (e.g. libnspr4.so)
LDFLAGS="$LDFLAGS -z ignore -R '\$\$ORIGIN:\$\$ORIGIN/..'"
LIBS="-lCrun -lCstd $LIBS"
MOZ_MEMORY=1
if test -z "$GNU_CC"; then
NS_USE_NATIVE=1
MOZ_FIX_LINK_PATHS='-R $(LIBXUL_DIST)/bin'
MOZ_FIX_LINK_PATHS=
AC_DEFINE(NSCAP_DISABLE_DEBUG_PTR_TYPES)
if test "$CPU_ARCH" != "sparc"; then
@ -4313,16 +4313,6 @@ fi
AC_SUBST(SYSTEM_HUNSPELL)
dnl check whether to enable glitz
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(glitz,
[ --enable-glitz Enable Glitz for use with Cairo],
MOZ_ENABLE_GLITZ=1,
MOZ_ENABLE_GLITZ= )
if test "$MOZ_ENABLE_GLITZ"; then
AC_DEFINE(MOZ_ENABLE_GLITZ)
fi
dnl ========================================================
dnl Java SDK support
dnl ========================================================
@ -4769,6 +4759,7 @@ cairo-qt)
MOZ_GFX_TOOLKIT=cairo
MOZ_ENABLE_QT=1
MOZ_ENABLE_XREMOTE=1
USE_ELF_DYNSTR_GC=
AC_DEFINE(MOZ_X11)
MOZ_X11=1
@ -4913,7 +4904,6 @@ AC_SUBST(TK_LIBS)
AC_SUBST(MOZ_ENABLE_GTK2)
AC_SUBST(MOZ_ENABLE_PHOTON)
AC_SUBST(MOZ_ENABLE_COCOA)
AC_SUBST(MOZ_ENABLE_GLITZ)
AC_SUBST(MOZ_ENABLE_QT)
AC_SUBST(MOZ_ENABLE_XREMOTE)
AC_SUBST(MOZ_GTK2_CFLAGS)
@ -5004,23 +4994,17 @@ MOZ_ARG_DISABLE_BOOL(pango,
dnl ========================================================
dnl = Xft and Pango
dnl = Pango
dnl ========================================================
if test "$MOZ_ENABLE_GTK2"
then
if test "$MOZ_X11"; then
PKG_CHECK_MODULES(MOZ_XFT, xft)
AC_SUBST(MOZ_XFT_CFLAGS)
AC_SUBST(MOZ_XFT_LIBS)
fi
AC_SUBST(MOZ_PANGO)
PKG_CHECK_MODULES(_PANGOCHK, pango >= $PANGO_VERSION)
if test "$MOZ_PANGO"
then
PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangocairo >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION)
PKG_CHECK_MODULES(MOZ_PANGO, pango >= $PANGO_VERSION pangoft2 >= $PANGO_VERSION)
AC_SUBST(MOZ_PANGO_CFLAGS)
AC_SUBST(MOZ_PANGO_LIBS)
AC_DEFINE(MOZ_PANGO)
@ -5164,7 +5148,7 @@ dnl ========================================================
dnl = dbus support
dnl ========================================================
if test "$MOZ_ENABLE_GTK2" || "$MOZ_ENABLE_QT"
if test "$MOZ_ENABLE_GTK2" || test "$MOZ_ENABLE_QT"
then
MOZ_ENABLE_DBUS=1
@ -7138,9 +7122,9 @@ MOZ_ARG_DISABLE_BOOL(md,
if test "$_cpp_md_flag"; then
COMPILER_DEPEND=1
if test "$OS_ARCH" = "OpenVMS"; then
_DEPEND_CFLAGS='$(subst =, ,$(filter-out %/.pp,-MM=-MD=-MF=$(MDDEPDIR)/$(*F).pp))'
_DEPEND_CFLAGS='$(subst =, ,$(filter-out %/.pp,-MM=-MD=-MF=$(MDDEPDIR)/$(basename $(@F)).pp))'
else
_DEPEND_CFLAGS='$(filter-out %/.pp,-Wp,-MD,$(MDDEPDIR)/$(*F).pp)'
_DEPEND_CFLAGS='$(filter-out %/.pp,-Wp,-MD,$(MDDEPDIR)/$(basename $(@F)).pp)'
fi
dnl Sun Studio on Solaris use -xM instead of -MD, see config/rules.mk
if test -z "$GNU_CC" && test -z "$GNU_CXX" && test "$OS_ARCH" = "SunOS"; then
@ -7349,7 +7333,7 @@ fi
if test -z "$SKIP_PATH_CHECKS"; then
if test -z "${GLIB_CFLAGS}" || test -z "${GLIB_LIBS}" ; then
if test "$MOZ_ENABLE_GTK2"; then
if test "$MOZ_ENABLE_GTK2" || test "$USE_ELF_DYNSTR_GC" ; then
PKG_CHECK_MODULES(GLIB, glib-2.0 >= 1.3.7 gobject-2.0)
else
AM_PATH_GLIB(${GLIB_VERSION})
@ -7455,9 +7439,6 @@ if test "$MOZ_TREE_CAIRO"; then
CAIRO_FT_CFLAGS="-I${MZFTCFGFT2}/include"
CAIRO_FT_LIBS="-L${MZFTCFGFT2}/lib -lmozft -lmzfntcfg"
fi
if test "$MOZ_ENABLE_GLITZ"; then
GLITZ_SURFACE_FEATURE="#define CAIRO_HAS_GLITZ_SURFACE 1"
fi
if test "$MOZ_WIDGET_TOOLKIT" = "beos"; then
PKG_CHECK_MODULES(CAIRO_FT, fontconfig freetype2)
BEOS_SURFACE_FEATURE="#define CAIRO_HAS_BEOS_SURFACE 1"
@ -7486,7 +7467,6 @@ if test "$MOZ_TREE_CAIRO"; then
AC_SUBST(WIN32_SURFACE_FEATURE)
AC_SUBST(OS2_SURFACE_FEATURE)
AC_SUBST(BEOS_SURFACE_FEATURE)
AC_SUBST(GLITZ_SURFACE_FEATURE)
AC_SUBST(DIRECTFB_SURFACE_FEATURE)
AC_SUBST(FT_FONT_FEATURE)
AC_SUBST(WIN32_FONT_FEATURE)
@ -7496,25 +7476,12 @@ if test "$MOZ_TREE_CAIRO"; then
if test "$_WIN32_MSVC"; then
MOZ_CAIRO_LIBS='$(DEPTH)/gfx/cairo/cairo/src/mozcairo.lib $(DEPTH)/gfx/cairo/libpixman/src/mozlibpixman.lib'
if test "$MOZ_ENABLE_GLITZ"; then
MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS "'$(DEPTH)/gfx/cairo/glitz/src/mozglitz.lib $(DEPTH)/gfx/cairo/glitz/src/wgl/mozglitzwgl.lib'
fi
else
MOZ_CAIRO_LIBS='$(DEPTH)/gfx/cairo/cairo/src/$(LIB_PREFIX)mozcairo.$(LIB_SUFFIX) $(DEPTH)/gfx/cairo/libpixman/src/$(LIB_PREFIX)mozlibpixman.$(LIB_SUFFIX)'" $CAIRO_FT_LIBS"
if test "$MOZ_X11"; then
MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS $XLDFLAGS -lXrender -lfreetype -lfontconfig"
fi
if test "$MOZ_ENABLE_GLITZ"; then
MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS "'-L$(DEPTH)/gfx/cairo/glitz/src -lmozglitz'
if test "$MOZ_X11"; then
MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS "'-L$(DEPTH)/gfx/cairo/glitz/src/glx -lmozglitzglx -lGL'
fi
if test "$MOZ_WIDGET_TOOLKIT" = "windows"; then
MOZ_CAIRO_LIBS="$MOZ_CAIRO_LIBS "'-L$(DEPTH)/gfx/cairo/glitz/src/wgl -lmozglitzwgl'
fi
fi
fi
CAIRO_FEATURES_H=gfx/cairo/cairo/src/cairo-features.h

View File

@ -695,7 +695,7 @@ public:
*aResult = niMgr->GetNodeInfo(aName, aNodeInfo->GetPrefixAtom(),
aNodeInfo->NamespaceID()).get();
return *aResult ? NS_OK : NS_ERROR_FAILURE;
return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
/**
@ -709,7 +709,7 @@ public:
*aResult = niMgr->GetNodeInfo(aNodeInfo->NameAtom(), aPrefix,
aNodeInfo->NamespaceID()).get();
return *aResult ? NS_OK : NS_ERROR_FAILURE;
return *aResult ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
/**
@ -807,6 +807,13 @@ public:
*/
static PRBool IsChromeDoc(nsIDocument *aDocument);
/**
* Returns true if aDocument belongs to a chrome docshell for
* display purposes. Returns false for null documents or documents
* which do not belong to a docshell.
*/
static PRBool IsInChromeDocshell(nsIDocument *aDocument);
/**
* Release *aSupportsPtr when the shutdown notification is received
*/

View File

@ -50,7 +50,7 @@
#include "nsIDocument.h"
#include "nsTPtrArray.h"
#include "nsContentUtils.h"
#include "nsReadableUtils.h"
#ifdef MOZ_SVG
#include "nsISVGValue.h"
#endif
@ -203,19 +203,35 @@ nsAttrValue::SetTo(const nsAttrValue& aOther)
}
MiscContainer* otherCont = aOther.GetMiscContainer();
if (!EnsureEmptyMiscContainer()) {
return;
}
MiscContainer* cont = GetMiscContainer();
switch (otherCont->mType) {
case eInteger:
{
cont->mInteger = otherCont->mInteger;
break;
}
case eEnum:
{
cont->mEnumValue = otherCont->mEnumValue;
break;
}
case ePercent:
{
cont->mPercent = otherCont->mPercent;
break;
}
case eColor:
{
if (EnsureEmptyMiscContainer()) {
MiscContainer* cont = GetMiscContainer();
cont->mColor = otherCont->mColor;
cont->mType = eColor;
}
cont->mColor = otherCont->mColor;
break;
}
case eCSSStyleRule:
{
SetTo(otherCont->mCSSStyleRule);
NS_ADDREF(cont->mCSSStyleRule = otherCont->mCSSStyleRule);
break;
}
case eAtomArray:
@ -223,13 +239,15 @@ nsAttrValue::SetTo(const nsAttrValue& aOther)
if (!EnsureEmptyAtomArray() ||
!GetAtomArrayValue()->AppendObjects(*otherCont->mAtomArray)) {
Reset();
return;
}
break;
}
#ifdef MOZ_SVG
case eSVGValue:
{
SetTo(otherCont->mSVGValue);
NS_ADDREF(cont->mSVGValue = otherCont->mSVGValue);
break;
}
#endif
default:
@ -238,30 +256,29 @@ nsAttrValue::SetTo(const nsAttrValue& aOther)
break;
}
}
void* otherPtr =
reinterpret_cast<void*>(otherCont->mStringBits & NS_ATTRVALUE_POINTERVALUE_MASK);
if (otherPtr) {
if (static_cast<ValueBaseType>(otherCont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) ==
eStringBase) {
static_cast<nsStringBuffer*>(otherPtr)->AddRef();
} else {
static_cast<nsIAtom*>(otherPtr)->AddRef();
}
cont->mStringBits = otherCont->mStringBits;
}
// Note, set mType after switch-case, otherwise EnsureEmptyAtomArray doesn't
// work correctly.
cont->mType = otherCont->mType;
}
void
nsAttrValue::SetTo(const nsAString& aValue)
{
ResetIfSet();
if (!aValue.IsEmpty()) {
PRUint32 len = aValue.Length();
nsStringBuffer* buf = nsStringBuffer::FromString(aValue);
if (buf && (buf->StorageSize()/sizeof(PRUnichar) - 1) == len) {
buf->AddRef();
SetPtrValueAndType(buf, eStringBase);
return;
}
buf = nsStringBuffer::Alloc((len + 1) * sizeof(PRUnichar));
if (!buf) {
return;
}
PRUnichar *data = static_cast<PRUnichar*>(buf->Data());
CopyUnicodeTo(aValue, 0, data, len);
data[len] = PRUnichar(0);
nsStringBuffer* buf = GetStringBuffer(aValue);
if (buf) {
SetPtrValueAndType(buf, eStringBase);
}
}
@ -270,7 +287,7 @@ void
nsAttrValue::SetTo(PRInt16 aInt)
{
ResetIfSet();
SetIntValueAndType(aInt, eInteger);
SetIntValueAndType(aInt, eInteger, nsnull);
}
void
@ -306,6 +323,27 @@ nsAttrValue::SwapValueWith(nsAttrValue& aOther)
void
nsAttrValue::ToString(nsAString& aResult) const
{
MiscContainer* cont = nsnull;
if (BaseType() == eOtherBase) {
cont = GetMiscContainer();
void* ptr =
reinterpret_cast<void*>(cont->mStringBits & NS_ATTRVALUE_POINTERVALUE_MASK);
if (ptr) {
if (static_cast<ValueBaseType>(cont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) ==
eStringBase) {
nsStringBuffer* str = static_cast<nsStringBuffer*>(ptr);
if (str) {
str->ToString(str->StorageSize()/sizeof(PRUnichar) - 1, aResult);
return;
}
} else {
nsIAtom *atom = static_cast<nsIAtom*>(ptr);
atom->ToString(aResult);
return;
}
}
}
switch(Type()) {
case eString:
{
@ -328,7 +366,7 @@ nsAttrValue::ToString(nsAString& aResult) const
case eInteger:
{
nsAutoString intStr;
intStr.AppendInt(GetIntInternal());
intStr.AppendInt(GetIntegerValue());
aResult = intStr;
break;
@ -344,12 +382,16 @@ nsAttrValue::ToString(nsAString& aResult) const
case eEnum:
{
PRInt16 val = GetEnumValue();
PRUint32 allEnumBits =
cont ? cont->mEnumValue : static_cast<PRUint32>(GetIntInternal());
const EnumTable* table = sEnumTableArray->
ElementAt(GetIntInternal() & NS_ATTRVALUE_ENUMTABLEINDEX_MASK);
ElementAt(allEnumBits & NS_ATTRVALUE_ENUMTABLEINDEX_MASK);
while (table->tag) {
if (table->value == val) {
aResult.AssignASCII(table->tag);
if (allEnumBits & NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER) {
ToUpperCase(aResult);
}
return;
}
table++;
@ -362,7 +404,7 @@ nsAttrValue::ToString(nsAString& aResult) const
case ePercent:
{
nsAutoString intStr;
intStr.AppendInt(GetIntInternal());
intStr.AppendInt(cont ? cont->mPercent : GetIntInternal());
aResult = intStr + NS_LITERAL_STRING("%");
break;
@ -378,24 +420,6 @@ nsAttrValue::ToString(nsAString& aResult) const
break;
}
case eAtomArray:
{
MiscContainer* cont = GetMiscContainer();
PRInt32 count = cont->mAtomArray->Count();
if (count) {
cont->mAtomArray->ObjectAt(0)->ToString(aResult);
nsAutoString tmp;
PRInt32 i;
for (i = 1; i < count; ++i) {
cont->mAtomArray->ObjectAt(i)->ToString(tmp);
aResult.Append(NS_LITERAL_STRING(" ") + tmp);
}
}
else {
aResult.Truncate();
}
break;
}
#ifdef MOZ_SVG
case eSVGValue:
{
@ -408,7 +432,11 @@ nsAttrValue::ToString(nsAString& aResult) const
nsAutoString str;
str.AppendFloat(GetFloatValue());
aResult = str;
break;
}
default:
{
aResult.Truncate();
break;
}
}
@ -426,23 +454,17 @@ PRBool
nsAttrValue::GetColorValue(nscolor& aColor) const
{
NS_PRECONDITION(Type() == eColor || Type() == eString, "wrong type");
switch (BaseType()) {
switch (Type()) {
case eString:
{
return GetPtr() && NS_ColorNameToRGB(GetStringValue(), &aColor);
}
case eOtherBase:
case eColor:
{
aColor = GetMiscContainer()->mColor;
break;
}
case eIntegerBase:
{
aColor = static_cast<nscolor>(GetIntInternal());
break;
}
default:
{
NS_NOTREACHED("unexpected basetype");
@ -514,7 +536,24 @@ nsAttrValue::HashValue() const
}
MiscContainer* cont = GetMiscContainer();
if (static_cast<ValueBaseType>(cont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK)
== eAtomBase) {
return cont->mStringBits - 0;
}
switch (cont->mType) {
case eInteger:
{
return cont->mInteger;
}
case eEnum:
{
return cont->mEnumValue;
}
case ePercent:
{
return cont->mPercent;
}
case eColor:
{
return cont->mColor;
@ -575,7 +614,30 @@ nsAttrValue::Equals(const nsAttrValue& aOther) const
return PR_FALSE;
}
PRBool needsStringComparison = PR_FALSE;
switch (thisCont->mType) {
case eInteger:
{
if (thisCont->mInteger == otherCont->mInteger) {
needsStringComparison = PR_TRUE;
}
break;
}
case eEnum:
{
if (thisCont->mEnumValue == otherCont->mEnumValue) {
needsStringComparison = PR_TRUE;
}
break;
}
case ePercent:
{
if (thisCont->mPercent == otherCont->mPercent) {
needsStringComparison = PR_TRUE;
}
break;
}
case eColor:
{
return thisCont->mColor == otherCont->mColor;
@ -601,7 +663,8 @@ nsAttrValue::Equals(const nsAttrValue& aOther) const
return PR_FALSE;
}
}
return PR_TRUE;
needsStringComparison = PR_TRUE;
break;
}
#ifdef MOZ_SVG
case eSVGValue:
@ -615,6 +678,19 @@ nsAttrValue::Equals(const nsAttrValue& aOther) const
return PR_FALSE;
}
}
if (needsStringComparison) {
if (thisCont->mStringBits == otherCont->mStringBits) {
return PR_TRUE;
}
if ((static_cast<ValueBaseType>(thisCont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) ==
eStringBase) &&
(static_cast<ValueBaseType>(otherCont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) ==
eStringBase)) {
return nsCheapString(reinterpret_cast<nsStringBuffer*>(thisCont->mStringBits)).Equals(
nsCheapString(reinterpret_cast<nsStringBuffer*>(otherCont->mStringBits)));
}
}
return PR_FALSE;
}
PRBool
@ -741,14 +817,16 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue)
nsAString::const_iterator iter, end;
aValue.BeginReading(iter);
aValue.EndReading(end);
PRBool hasSpace = PR_FALSE;
// skip initial whitespace
while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) {
hasSpace = PR_TRUE;
++iter;
}
if (iter == end) {
ResetIfSet();
SetTo(aValue);
return;
}
@ -767,11 +845,13 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue)
// skip whitespace
while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) {
hasSpace = PR_TRUE;
++iter;
}
if (iter == end) {
// we only found one classname so don't bother storing a list
if (iter == end && !hasSpace) {
// we only found one classname and there was no whitespace so
// don't bother storing a list
ResetIfSet();
nsIAtom* atom = nsnull;
classAtom.swap(atom);
@ -791,7 +871,7 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue)
}
// parse the rest of the classnames
do {
while (iter != end) {
start = iter;
do {
@ -809,8 +889,9 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue)
while (iter != end && nsContentUtils::IsHTMLWhitespace(*iter)) {
++iter;
}
} while (iter != end);
}
SetMiscAtomOrString(&aValue);
return;
}
@ -828,6 +909,45 @@ nsAttrValue::ParseStringOrAtom(const nsAString& aValue)
}
}
void
nsAttrValue::SetIntValueAndType(PRInt32 aValue, ValueType aType,
const nsAString* aStringValue)
{
if (aStringValue || aValue > NS_ATTRVALUE_INTEGERTYPE_MAXVALUE ||
aValue < NS_ATTRVALUE_INTEGERTYPE_MINVALUE) {
if (EnsureEmptyMiscContainer()) {
MiscContainer* cont = GetMiscContainer();
switch (aType) {
case eInteger:
{
cont->mInteger = aValue;
break;
}
case ePercent:
{
cont->mPercent = aValue;
break;
}
case eEnum:
{
cont->mEnumValue = aValue;
break;
}
default:
{
NS_NOTREACHED("unknown integer type");
break;
}
}
cont->mType = aType;
SetMiscAtomOrString(aStringValue);
}
} else {
NS_ASSERTION(!mBits, "Reset before calling SetIntValueAndType!");
mBits = (aValue * NS_ATTRVALUE_INTEGERTYPE_MULTIPLIER) | aType;
}
}
PRBool
nsAttrValue::ParseEnumValue(const nsAString& aValue,
const EnumTable* aTable,
@ -853,7 +973,16 @@ nsAttrValue::ParseEnumValue(const nsAString& aValue,
PRInt32 value = (aTable->value << NS_ATTRVALUE_ENUMTABLEINDEX_BITS) +
index;
SetIntValueAndType(value, eEnum);
PRBool equals = aCaseSensitive || aValue.EqualsASCII(aTable->tag);
if (!equals) {
nsAutoString tag;
tag.AssignASCII(aTable->tag);
ToUpperCase(tag);
if ((equals = tag.Equals(aValue))) {
value |= NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER;
}
}
SetIntValueAndType(value, eEnum, equals ? nsnull : &aValue);
NS_ASSERTION(GetEnumValue() == aTable->value,
"failed to store enum properly");
@ -872,28 +1001,31 @@ nsAttrValue::ParseSpecialIntValue(const nsAString& aString,
ResetIfSet();
PRInt32 ec;
PRBool strict;
PRBool isPercent = PR_FALSE;
nsAutoString tmp(aString);
PRInt32 val = tmp.ToInteger(&ec);
PRInt32 originalVal = StringToInteger(aString, &strict, &ec, aCanBePercent, &isPercent);
if (NS_FAILED(ec)) {
return PR_FALSE;
}
val = PR_MAX(val, 0);
val = PR_MIN(val, NS_ATTRVALUE_INTEGERTYPE_MAXVALUE);
PRInt32 val = PR_MAX(originalVal, 0);
// % (percent)
// XXX RFindChar means that 5%x will be parsed!
if (aCanBePercent && tmp.RFindChar('%') >= 0) {
if (aCanBePercent && (isPercent || tmp.RFindChar('%') >= 0)) {
if (val > 100) {
val = 100;
}
SetIntValueAndType(val, ePercent);
return PR_TRUE;
isPercent = PR_TRUE;
}
// Straight number is interpreted as integer
SetIntValueAndType(val, eInteger);
strict = strict && (originalVal == val);
SetIntValueAndType(val,
isPercent ? ePercent : eInteger,
strict ? nsnull : &aString);
return PR_TRUE;
}
@ -901,21 +1033,21 @@ PRBool
nsAttrValue::ParseIntWithBounds(const nsAString& aString,
PRInt32 aMin, PRInt32 aMax)
{
NS_PRECONDITION(aMin < aMax &&
aMin >= NS_ATTRVALUE_INTEGERTYPE_MINVALUE &&
aMax <= NS_ATTRVALUE_INTEGERTYPE_MAXVALUE, "bad boundaries");
NS_PRECONDITION(aMin < aMax, "bad boundaries");
ResetIfSet();
PRInt32 ec;
PRInt32 val = PromiseFlatString(aString).ToInteger(&ec);
PRBool strict;
PRInt32 originalVal = StringToInteger(aString, &strict, &ec);
if (NS_FAILED(ec)) {
return PR_FALSE;
}
val = PR_MAX(val, aMin);
PRInt32 val = PR_MAX(originalVal, aMin);
val = PR_MIN(val, aMax);
SetIntValueAndType(val, eInteger);
strict = strict && (originalVal == val);
SetIntValueAndType(val, eInteger, strict ? nsnull : &aString);
return PR_TRUE;
}
@ -954,13 +1086,7 @@ nsAttrValue::ParseColor(const nsAString& aString, nsIDocument* aDocument)
}
}
PRInt32 colAsInt = static_cast<PRInt32>(color);
PRInt32 tmp = colAsInt * NS_ATTRVALUE_INTEGERTYPE_MULTIPLIER;
if (tmp / NS_ATTRVALUE_INTEGERTYPE_MULTIPLIER == colAsInt) {
ResetIfSet();
SetIntValueAndType(colAsInt, eColor);
}
else if (EnsureEmptyMiscContainer()) {
if (EnsureEmptyMiscContainer()) {
MiscContainer* cont = GetMiscContainer();
cont->mColor = color;
cont->mType = eColor;
@ -978,8 +1104,57 @@ PRBool nsAttrValue::ParseFloatValue(const nsAString& aString)
if (NS_FAILED(ec)) {
return PR_FALSE;
}
SetFloatValue(val);
return PR_TRUE;
if (EnsureEmptyMiscContainer()) {
MiscContainer* cont = GetMiscContainer();
cont->mFloatValue = val;
cont->mType = eFloatValue;
nsAutoString serializedFloat;
serializedFloat.AppendFloat(val);
SetMiscAtomOrString(serializedFloat.Equals(aString) ? nsnull : &aString);
return PR_TRUE;
}
return PR_FALSE;
}
void
nsAttrValue::SetMiscAtomOrString(const nsAString* aValue)
{
NS_ASSERTION(GetMiscContainer(), "Must have MiscContainer!");
NS_ASSERTION(!GetMiscContainer()->mStringBits,
"Trying to re-set atom or string!");
if (aValue) {
PRUint32 len = aValue->Length();
NS_ASSERTION(len, "Empty string?");
MiscContainer* cont = GetMiscContainer();
if (len <= NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM) {
nsIAtom* atom = NS_NewAtom(*aValue);
if (atom) {
cont->mStringBits = reinterpret_cast<PtrBits>(atom) | eAtomBase;
}
} else {
nsStringBuffer* buf = GetStringBuffer(*aValue);
if (buf) {
cont->mStringBits = reinterpret_cast<PtrBits>(buf) | eStringBase;
}
}
}
}
void
nsAttrValue::ResetMiscAtomOrString()
{
MiscContainer* cont = GetMiscContainer();
void* ptr = reinterpret_cast<void*>(cont->mStringBits & NS_ATTRVALUE_POINTERVALUE_MASK);
if (ptr) {
if (static_cast<ValueBaseType>(cont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) ==
eStringBase) {
static_cast<nsStringBuffer*>(ptr)->Release();
} else {
static_cast<nsIAtom*>(ptr)->Release();
}
cont->mStringBits = 0;
}
}
PRBool
@ -987,6 +1162,7 @@ nsAttrValue::EnsureEmptyMiscContainer()
{
MiscContainer* cont;
if (BaseType() == eOtherBase) {
ResetMiscAtomOrString();
cont = GetMiscContainer();
switch (cont->mType) {
case eCSSStyleRule:
@ -1022,6 +1198,7 @@ nsAttrValue::EnsureEmptyMiscContainer()
}
cont->mType = eColor;
cont->mStringBits = 0;
cont->mColor = 0;
return PR_TRUE;
@ -1031,6 +1208,7 @@ PRBool
nsAttrValue::EnsureEmptyAtomArray()
{
if (Type() == eAtomArray) {
ResetMiscAtomOrString();
GetAtomArrayValue()->Clear();
return PR_TRUE;
}
@ -1052,3 +1230,99 @@ nsAttrValue::EnsureEmptyAtomArray()
return PR_TRUE;
}
nsStringBuffer*
nsAttrValue::GetStringBuffer(const nsAString& aValue) const
{
PRUint32 len = aValue.Length();
if (!len) {
return nsnull;
}
nsStringBuffer* buf = nsStringBuffer::FromString(aValue);
if (buf && (buf->StorageSize()/sizeof(PRUnichar) - 1) == len) {
buf->AddRef();
return buf;
}
buf = nsStringBuffer::Alloc((len + 1) * sizeof(PRUnichar));
if (!buf) {
return nsnull;
}
PRUnichar *data = static_cast<PRUnichar*>(buf->Data());
CopyUnicodeTo(aValue, 0, data, len);
data[len] = PRUnichar(0);
return buf;
}
PRInt32
nsAttrValue::StringToInteger(const nsAString& aValue, PRBool* aStrict,
PRInt32* aErrorCode,
PRBool aCanBePercent,
PRBool* aIsPercent) const
{
*aStrict = PR_FALSE;
*aErrorCode = NS_ERROR_ILLEGAL_VALUE;
if (aCanBePercent) {
*aIsPercent = PR_FALSE;
}
nsAString::const_iterator iter, end;
aValue.BeginReading(iter);
aValue.EndReading(end);
PRBool negate = PR_FALSE;
PRInt32 value = 0;
if (iter != end) {
if (*iter == PRUnichar('-')) {
negate = PR_TRUE;
++iter;
}
if (iter != end) {
if ((*iter >= PRUnichar('1') || (*iter == PRUnichar('0') && !negate)) &&
*iter <= PRUnichar('9')) {
value = *iter - PRUnichar('0');
++iter;
*aStrict = (value != 0 || iter == end ||
(aCanBePercent && *iter == PRUnichar('%')));
while (iter != end && *aStrict) {
if (*iter >= PRUnichar('0') && *iter <= PRUnichar('9')) {
value = (value * 10) + (*iter - PRUnichar('0'));
++iter;
if (iter != end && value > ((PR_INT32_MAX / 10) - 9)) {
*aStrict = PR_FALSE;
}
} else if (aCanBePercent && *iter == PRUnichar('%')) {
++iter;
if (iter == end) {
*aIsPercent = PR_TRUE;
} else {
*aStrict = PR_FALSE;
}
} else {
*aStrict = PR_FALSE;
}
}
if (*aStrict) {
if (negate) {
value = -value;
}
if (!aCanBePercent || !*aIsPercent) {
*aErrorCode = NS_OK;
#ifdef DEBUG
nsAutoString stringValue;
stringValue.AppendInt(value);
if (aCanBePercent && *aIsPercent) {
stringValue.AppendLiteral("%");
}
NS_ASSERTION(stringValue.Equals(aValue), "Wrong conversion!");
#endif
return value;
}
}
}
}
}
nsAutoString tmp(aValue);
return tmp.ToInteger(aErrorCode);
}

View File

@ -71,8 +71,10 @@ template<class E> class nsTPtrArray;
#define NS_ATTRVALUE_INTEGERTYPE_MINVALUE (-NS_ATTRVALUE_INTEGERTYPE_MAXVALUE - 1)
#define NS_ATTRVALUE_ENUMTABLEINDEX_BITS (32 - 16 - NS_ATTRVALUE_INTEGERTYPE_BITS)
#define NS_ATTRVALUE_ENUMTABLEINDEX_MAXVALUE ((1 << NS_ATTRVALUE_ENUMTABLEINDEX_BITS) - 1)
#define NS_ATTRVALUE_ENUMTABLEINDEX_MASK (PtrBits((1 << NS_ATTRVALUE_ENUMTABLEINDEX_BITS) - 1))
#define NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER (1 << (NS_ATTRVALUE_ENUMTABLEINDEX_BITS - 1))
#define NS_ATTRVALUE_ENUMTABLEINDEX_MAXVALUE (NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER - 1)
#define NS_ATTRVALUE_ENUMTABLEINDEX_MASK \
(PtrBits((((1 << NS_ATTRVALUE_ENUMTABLEINDEX_BITS) - 1) &~ NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER)))
/**
* A class used to construct a nsString from a nsStringBuffer (we might
@ -110,8 +112,8 @@ public:
eColor = 0x07, // 0111
eEnum = 0x0B, // 1011 This should eventually die
ePercent = 0x0F, // 1111
// Values below here won't matter, they'll be stored in the 'misc' struct
// anyway
// Values below here won't matter, they'll be always stored in the 'misc'
// struct.
eCSSStyleRule = 0x10,
eAtomArray = 0x11
#ifdef MOZ_SVG
@ -224,8 +226,7 @@ public:
* @return whether the value could be parsed
*/
PRBool ParseIntValue(const nsAString& aString) {
return ParseIntWithBounds(aString, NS_ATTRVALUE_INTEGERTYPE_MINVALUE,
NS_ATTRVALUE_INTEGERTYPE_MAXVALUE);
return ParseIntWithBounds(aString, PR_INT32_MIN, PR_INT32_MAX);
}
/**
@ -237,7 +238,7 @@ public:
* @return whether the value could be parsed
*/
PRBool ParseIntWithBounds(const nsAString& aString, PRInt32 aMin,
PRInt32 aMax = NS_ATTRVALUE_INTEGERTYPE_MAXVALUE);
PRInt32 aMax = PR_INT32_MAX);
/**
* Parse a string into a color.
@ -268,8 +269,16 @@ private:
struct MiscContainer
{
ValueType mType;
// mStringBits points to either nsIAtom* or nsStringBuffer* and is used when
// mType isn't mCSSStyleRule or eSVGValue.
// Note eStringBase and eAtomBase is used also to handle the type of
// mStringBits.
PtrBits mStringBits;
union {
PRInt32 mInteger;
nscolor mColor;
PRUint32 mEnumValue;
PRInt32 mPercent;
nsICSSStyleRule* mCSSStyleRule;
nsCOMArray<nsIAtom>* mAtomArray;
#ifdef MOZ_SVG
@ -282,8 +291,10 @@ private:
inline ValueBaseType BaseType() const;
inline void SetPtrValueAndType(void* aValue, ValueBaseType aType);
inline void SetIntValueAndType(PRInt32 aValue, ValueType aType);
inline void SetFloatValue(float aValue);
void SetIntValueAndType(PRInt32 aValue, ValueType aType,
const nsAString* aStringValue);
void SetMiscAtomOrString(const nsAString* aValue);
void ResetMiscAtomOrString();
inline void ResetIfSet();
inline void* GetPtr() const;
@ -292,6 +303,14 @@ private:
PRBool EnsureEmptyMiscContainer();
PRBool EnsureEmptyAtomArray();
nsStringBuffer* GetStringBuffer(const nsAString& aValue) const;
// aStrict is set PR_TRUE if stringifying the return value equals with
// aValue.
PRInt32 StringToInteger(const nsAString& aValue,
PRBool* aStrict,
PRInt32* aErrorCode,
PRBool aCanBePercent = PR_FALSE,
PRBool* aIsPercent = nsnull) const;
static nsTPtrArray<const EnumTable>* sEnumTableArray;
@ -313,7 +332,9 @@ inline PRInt32
nsAttrValue::GetIntegerValue() const
{
NS_PRECONDITION(Type() == eInteger, "wrong type");
return GetIntInternal();
return (BaseType() == eIntegerBase)
? GetIntInternal()
: GetMiscContainer()->mInteger;
}
inline PRInt16
@ -322,16 +343,21 @@ nsAttrValue::GetEnumValue() const
NS_PRECONDITION(Type() == eEnum, "wrong type");
// We don't need to worry about sign extension here since we're
// returning an PRInt16 which will cut away the top bits.
return static_cast<PRInt16>
(GetIntInternal() >> NS_ATTRVALUE_ENUMTABLEINDEX_BITS);
return static_cast<PRInt16>((
(BaseType() == eIntegerBase)
? static_cast<PRUint32>(GetIntInternal())
: GetMiscContainer()->mEnumValue)
>> NS_ATTRVALUE_ENUMTABLEINDEX_BITS);
}
inline float
nsAttrValue::GetPercentValue() const
{
NS_PRECONDITION(Type() == ePercent, "wrong type");
return static_cast<float>(GetIntInternal()) /
100.0f;
return ((BaseType() == eIntegerBase)
? GetIntInternal()
: GetMiscContainer()->mPercent)
/ 100.0f;
}
inline nsCOMArray<nsIAtom>*
@ -378,28 +404,6 @@ nsAttrValue::SetPtrValueAndType(void* aValue, ValueBaseType aType)
mBits = reinterpret_cast<PtrBits>(aValue) | aType;
}
inline void
nsAttrValue::SetIntValueAndType(PRInt32 aValue, ValueType aType)
{
#ifdef DEBUG
{
PRInt32 tmp = aValue * NS_ATTRVALUE_INTEGERTYPE_MULTIPLIER;
NS_ASSERTION(tmp / NS_ATTRVALUE_INTEGERTYPE_MULTIPLIER == aValue,
"Integer too big to fit");
}
#endif
mBits = (aValue * NS_ATTRVALUE_INTEGERTYPE_MULTIPLIER) | aType;
}
inline void
nsAttrValue::SetFloatValue(float aValue)
{
if (EnsureEmptyMiscContainer()) {
MiscContainer* cont = GetMiscContainer();
cont->mFloatValue = aValue;
cont->mType = eFloatValue;
}
}
inline void
nsAttrValue::ResetIfSet()
{

View File

@ -2903,6 +2903,24 @@ nsContentUtils::IsChromeDoc(nsIDocument *aDocument)
return aDocument->NodePrincipal() == systemPrincipal;
}
// static
PRBool
nsContentUtils::IsInChromeDocshell(nsIDocument *aDocument)
{
if (!aDocument) {
return PR_FALSE;
}
nsCOMPtr<nsISupports> docContainer = aDocument->GetContainer();
nsCOMPtr<nsIDocShellTreeItem> docShell(do_QueryInterface(docContainer));
PRInt32 itemType = nsIDocShellTreeItem::typeContent;
if (docShell) {
docShell->GetItemType(&itemType);
}
return itemType == nsIDocShellTreeItem::typeChrome;
}
// static
nsIContentPolicy*
nsContentUtils::GetContentPolicy()

View File

@ -149,7 +149,7 @@ nsDOMAttribute::SetOwnerDocument(nsIDocument* aDocument)
newNodeInfo = aDocument->NodeInfoManager()->
GetNodeInfo(mNodeInfo->NameAtom(), mNodeInfo->GetPrefixAtom(),
mNodeInfo->NamespaceID());
NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
NS_ASSERTION(newNodeInfo, "GetNodeInfo lies");
mNodeInfo.swap(newNodeInfo);

View File

@ -386,7 +386,7 @@ nsDOMAttributeMap::Item(PRUint32 aIndex, nsIDOMNode** aReturn)
nsCOMPtr<nsINodeInfo> ni;
ni = mContent->NodeInfo()->NodeInfoManager()->
GetNodeInfo(name->LocalName(), name->GetPrefix(), name->NamespaceID());
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
return GetAttribute(ni, aReturn);
}
@ -455,7 +455,7 @@ nsDOMAttributeMap::GetNamedItemNSInternal(const nsAString& aNamespaceURI,
nsCOMPtr<nsINodeInfo> ni;
ni = mContent->NodeInfo()->NodeInfoManager()->
GetNodeInfo(nameAtom, name->GetPrefix(), nameSpaceID);
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
return GetAttribute(ni, aReturn, aRemove);
}

View File

@ -87,7 +87,7 @@ NS_NewDOMDocumentType(nsIDOMDocumentType** aDocType,
nsCOMPtr<nsINodeInfo> ni;
ni = nimgr->GetNodeInfo(nsGkAtoms::documentTypeNodeName, nsnull,
kNameSpaceID_None);
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
*aDocType = new nsDOMDocumentType(ni, aName, aEntities, aNotations,
aPublicId, aSystemId, aInternalSubset);
@ -260,7 +260,7 @@ nsDOMDocumentType::BindToTree(nsIDocument *aDocument, nsIContent *aParent,
newNodeInfo = nimgr->GetNodeInfo(mNodeInfo->NameAtom(),
mNodeInfo->GetPrefixAtom(),
mNodeInfo->NamespaceID());
NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
mNodeInfo.swap(newNodeInfo);

View File

@ -2201,7 +2201,7 @@ nsDocument::GetElementsByClassNameHelper(nsINode* aRootNode,
if (attrValue.Type() == nsAttrValue::eAtomArray) {
classes->AppendObjects(*(attrValue.GetAtomArrayValue()));
} else if (!attrValue.IsEmptyString()) {
} else if (attrValue.Type() == nsAttrValue::eAtom) {
classes->AppendObject(attrValue.GetAtomValue());
}
@ -5727,9 +5727,7 @@ nsDocument::FlushPendingNotifications(mozFlushType aType)
// Should we be flushing pending binding constructors in here?
nsPIDOMWindow *window = GetWindow();
if (aType <= Flush_ContentAndNotify || !window) {
if (aType <= Flush_ContentAndNotify) {
// Nothing to do here
return;
}
@ -6187,7 +6185,7 @@ nsDocument::CreateElem(nsIAtom *aName, nsIAtom *aPrefix, PRInt32 aNamespaceID,
nsCOMPtr<nsINodeInfo> nodeInfo;
nodeInfo = mNodeInfoManager->GetNodeInfo(aName, aPrefix, aNamespaceID);
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
return NS_NewElement(aResult, elementType, nodeInfo, PR_FALSE);
}

View File

@ -167,7 +167,7 @@ NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
nsCOMPtr<nsINodeInfo> nodeInfo;
nodeInfo = aNodeInfoManager->GetNodeInfo(nsGkAtoms::documentFragmentNodeName,
nsnull, kNameSpaceID_None);
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(nodeInfo, NS_ERROR_OUT_OF_MEMORY);
nsDocumentFragment *it = new nsDocumentFragment(nodeInfo);
if (!it) {

View File

@ -4297,7 +4297,7 @@ nsGenericElement::SetAttrAndNotify(PRInt32 aNamespaceID,
nsCOMPtr<nsINodeInfo> ni;
ni = mNodeInfo->NodeInfoManager()->GetNodeInfo(aName, aPrefix,
aNamespaceID);
NS_ENSURE_TRUE(ni, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(ni, NS_ERROR_OUT_OF_MEMORY);
rv = mAttrsAndChildren.SetAndTakeAttr(ni, aParsedValue);
}

View File

@ -257,7 +257,7 @@ nsNodeInfoManager::GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix,
{
nsCOMPtr<nsIAtom> name = do_GetAtom(aName);
*aNodeInfo = nsNodeInfoManager::GetNodeInfo(name, aPrefix, aNamespaceID).get();
return *aNodeInfo ? NS_OK : NS_ERROR_FAILURE;
return *aNodeInfo ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
@ -301,7 +301,7 @@ nsNodeInfoManager::GetNodeInfo(const nsAString& aQualifiedName,
}
*aNodeInfo = GetNodeInfo(nameAtom, prefixAtom, nsid).get();
return *aNodeInfo ? NS_OK : NS_ERROR_FAILURE;
return *aNodeInfo ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
}
already_AddRefed<nsINodeInfo>

View File

@ -519,7 +519,7 @@ nsNodeUtils::CloneAndAdopt(nsINode *aNode, PRBool aClone, PRBool aDeep,
newNodeInfo = nodeInfoManager->GetNodeInfo(nodeInfo->NameAtom(),
nodeInfo->GetPrefixAtom(),
nodeInfo->NamespaceID());
NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_FAILURE);
NS_ENSURE_TRUE(newNodeInfo, NS_ERROR_OUT_OF_MEMORY);
nodeInfo = newNodeInfo;
}

View File

@ -308,21 +308,39 @@ GetDocumentFromScriptContext(nsIScriptContext *aScriptContext)
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXHREventTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXHREventTarget)
if (tmp->mOwner) {
nsCOMPtr<nsIDocument> doc =
do_QueryInterface(tmp->mOwner->GetExtantDocument());
if (doc) {
cb.NoteXPCOMChild(doc->GetReference(tmp));
}
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnLoadListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnAbortListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnLoadStartListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnProgressListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mListenerManager)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsXHREventTarget)
if (tmp->mOwner) {
nsCOMPtr<nsIDocument> doc =
do_QueryInterface(tmp->mOwner->GetExtantDocument());
if (doc) {
doc->RemoveReference(tmp);
}
}
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnLoadListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnAbortListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnLoadStartListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnProgressListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mListenerManager)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsXHREventTarget)
@ -580,18 +598,18 @@ nsXHREventTarget::GetSystemEventGroup(nsIDOMEventGroup** aGroup)
return rv;
}
nsresult
nsXHREventTarget::GetContextForEventHandlers(nsIScriptContext** aContext)
{
nsresult rv = CheckInnerWindowCorrectness();
NS_ENSURE_SUCCESS(rv, rv);
NS_IF_ADDREF(*aContext = mScriptContext);
return NS_OK;
}
/////////////////////////////////////////////
NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLHttpRequestUpload)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXMLHttpRequestUpload, nsXHREventTarget)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLHttpRequestUpload, nsXHREventTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXMLHttpRequestUpload)
NS_INTERFACE_MAP_BEGIN(nsXMLHttpRequestUpload)
NS_INTERFACE_MAP_ENTRY(nsIXMLHttpRequestUpload)
NS_INTERFACE_MAP_ENTRY_CONTENT_CLASSINFO(XMLHttpRequestUpload)
NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
@ -599,12 +617,6 @@ NS_INTERFACE_MAP_END_INHERITING(nsXHREventTarget)
NS_IMPL_ADDREF_INHERITED(nsXMLHttpRequestUpload, nsXHREventTarget)
NS_IMPL_RELEASE_INHERITED(nsXMLHttpRequestUpload, nsXHREventTarget)
nsresult
nsXMLHttpRequestUpload::GetContextForEventHandlers(nsIScriptContext** aContext)
{
return mOwner->GetContextForEventHandlers(aContext);
}
/////////////////////////////////////////////
//
//
@ -735,7 +747,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLHttpRequest,
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannel)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mReadRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mScriptContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnUploadProgressListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnReadystatechangeListener)
@ -744,8 +755,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLHttpRequest,
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mChannelEventSink)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mProgressEventSink)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOwner)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mUpload,
nsIXMLHttpRequestUpload)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
@ -757,7 +766,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXMLHttpRequest,
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannel)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mReadRequest)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mScriptContext)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnUploadProgressListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnReadystatechangeListener)
@ -766,8 +774,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsXMLHttpRequest,
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mChannelEventSink)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mProgressEventSink)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOwner)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mUpload)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -2577,21 +2583,15 @@ nsXMLHttpRequest::GetInterface(const nsIID & aIID, void **aResult)
return QueryInterface(aIID, aResult);
}
nsresult
nsXMLHttpRequest::GetContextForEventHandlers(nsIScriptContext** aContext)
{
nsresult rv = CheckInnerWindowCorrectness();
NS_ENSURE_SUCCESS(rv, rv);
NS_IF_ADDREF(*aContext = mScriptContext);
return NS_OK;
}
NS_IMETHODIMP
nsXMLHttpRequest::GetUpload(nsIXMLHttpRequestUpload** aUpload)
{
*aUpload = nsnull;
nsCOMPtr<nsIScriptContext> scriptContext;
nsresult rv = GetContextForEventHandlers(getter_AddRefs(scriptContext));
NS_ENSURE_SUCCESS(rv, rv);
if (!mUpload) {
mUpload = new nsXMLHttpRequestUpload(this);
mUpload = new nsXMLHttpRequestUpload(mOwner, scriptContext);
NS_ENSURE_TRUE(mUpload, NS_ERROR_OUT_OF_MEMORY);
}
NS_ADDREF(*aUpload = mUpload);

View File

@ -117,7 +117,7 @@ public:
virtual nsresult RemoveEventListenerByIID(nsIDOMEventListener *aListener,
const nsIID& aIID);
virtual nsresult GetSystemEventGroup(nsIDOMEventGroup** aGroup);
virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext) = 0;
virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext);
PRBool HasListenersFor(const nsAString& aType)
{
@ -129,6 +129,18 @@ public:
nsresult GetInnerEventListener(nsRefPtr<nsDOMEventListenerWrapper>& aWrapper,
nsIDOMEventListener** aListener);
nsresult CheckInnerWindowCorrectness()
{
if (mOwner) {
NS_ASSERTION(mOwner->IsInnerWindow(), "Should have inner window here!\n");
nsPIDOMWindow* outer = mOwner->GetOuterWindow();
if (!outer || outer->GetCurrentInnerWindow() != mOwner) {
return NS_ERROR_FAILURE;
}
}
return NS_OK;
}
protected:
nsRefPtr<nsDOMEventListenerWrapper> mOnLoadListener;
nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
@ -137,23 +149,26 @@ protected:
nsRefPtr<nsDOMEventListenerWrapper> mOnProgressListener;
nsCOMPtr<nsIEventListenerManager> mListenerManager;
PRUint32 mLang;
// These may be null (native callers or xpcshell).
nsCOMPtr<nsIScriptContext> mScriptContext;
nsCOMPtr<nsPIDOMWindow> mOwner; // Inner window.
};
class nsXMLHttpRequestUpload : public nsXHREventTarget,
public nsIXMLHttpRequestUpload
{
public:
nsXMLHttpRequestUpload(nsPIDOMEventTarget* aOwner) : mOwner(aOwner) {}
nsXMLHttpRequestUpload(nsPIDOMWindow* aOwner,
nsIScriptContext* aScriptContext)
{
mOwner = aOwner;
mScriptContext = aScriptContext;
}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsXMLHttpRequestUpload,
nsXHREventTarget)
NS_FORWARD_NSIXMLHTTPREQUESTEVENTTARGET(nsXHREventTarget::)
NS_FORWARD_NSIDOMEVENTTARGET(nsXHREventTarget::)
NS_FORWARD_NSIDOMNSEVENTTARGET(nsXHREventTarget::)
NS_DECL_NSIXMLHTTPREQUESTUPLOAD
virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext);
protected:
nsCOMPtr<nsPIDOMEventTarget> mOwner;
};
class nsXMLHttpRequest : public nsXHREventTarget,
@ -217,8 +232,6 @@ public:
NS_IMETHOD Initialize(nsISupports* aOwner, JSContext* cx, JSObject* obj,
PRUint32 argc, jsval* argv);
virtual nsresult GetContextForEventHandlers(nsIScriptContext** aContext);
// This creates a trusted readystatechange event, which is not cancelable and
// doesn't bubble.
@ -288,18 +301,6 @@ protected:
*/
nsresult CheckChannelForCrossSiteRequest();
nsresult CheckInnerWindowCorrectness()
{
if (mOwner) {
NS_ASSERTION(mOwner->IsInnerWindow(), "Should have inner window here!\n");
nsPIDOMWindow* outer = mOwner->GetOuterWindow();
if (!outer || outer->GetCurrentInnerWindow() != mOwner) {
return NS_ERROR_FAILURE;
}
}
return NS_OK;
}
nsCOMPtr<nsISupports> mContext;
nsCOMPtr<nsIPrincipal> mPrincipal;
nsCOMPtr<nsIChannel> mChannel;
@ -307,10 +308,6 @@ protected:
nsCOMPtr<nsIRequest> mReadRequest;
nsCOMPtr<nsIDOMDocument> mDocument;
// These may be null (native callers or xpcshell).
nsCOMPtr<nsIScriptContext> mScriptContext;
nsCOMPtr<nsPIDOMWindow> mOwner; // Inner window.
nsRefPtr<nsDOMEventListenerWrapper> mOnUploadProgressListener;
nsRefPtr<nsDOMEventListenerWrapper> mOnReadystatechangeListener;

View File

@ -82,6 +82,7 @@ _TEST_FILES = test_bug5141.html \
file_bug218236_multipart.txt^headers^ \
test_bug218277.html \
test_bug238409.html \
test_bug254337.html \
test_bug276037-1.html \
test_bug276037-2.xhtml \
test_bug308484.html \
@ -123,6 +124,7 @@ _TEST_FILES = test_bug5141.html \
test_bug375314.html \
test_bug378969.html \
test_bug382113.html \
test_bug382871.html \
test_bug383430.html \
test_bug390219.html \
test_bug390735.html \
@ -194,6 +196,7 @@ _TEST_FILES = test_bug5141.html \
test_bug451376.html \
test_text_replaceWholeText.html \
test_text_wholeText.html \
test_bug433533.html \
wholeTexty-helper.xml \
test_bug444030.xhtml \
test_NodeIterator_basics_filters.xhtml \
@ -212,6 +215,8 @@ _TEST_FILES = test_bug5141.html \
test_bug368972.html \
test_bug450160.html \
test_bug454326.html \
test_bug457746.html \
bug457746.sjs \
$(NULL)
libs:: $(_TEST_FILES)

View File

@ -0,0 +1,11 @@
function handleRequest(request, response)
{
response.setHeader("Content-Type", "text/plain; charset=ISO-8859-1", false);
const body = [0xC1];
var bos = Components.classes["@mozilla.org/binaryoutputstream;1"]
.createInstance(Components.interfaces.nsIBinaryOutputStream);
bos.setOutputStream(response.bodyOutputStream);
bos.writeByteArray(body, body.length);
}

View File

@ -0,0 +1,43 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=254337
-->
<head>
<title>Test for Bug 254337</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>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=254337">Mozilla Bug 254337</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 254337 **/
var el = document.createElement("div");
el.setAttribute("class", "foobar1");
is(el.className, "foobar1", "Wrong className!");
el.className += " foobar2 ";
is(el.className, "foobar1 foobar2 ", "Appending to className didn't work!");
el.className += "foobar3";
is(el.className, "foobar1 foobar2 foobar3", "Appending to className didn't work!");
var el = document.createElement("div");
el.setAttribute("class", " foobar1 ");
is(el.className, " foobar1 ", "Wrong className!");
el.className += "foobar2";
is(el.className, " foobar1 foobar2", "Appending to className didn't work!");
el.setAttribute("class", " ");
is(el.getAttribute("class"), " ", "class attribute didn't store the right value!");
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,50 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=382871
-->
<head>
<title>Test for Bug 382871</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>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=382871">Mozilla Bug 382871</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 382871 **/
function loadHandler(evt) {
ok("randomProperty" in evt.target);
ok("randomProperty" in evt.target.upload);
SimpleTest.finish();
}
function runTest() {
var xhr = new XMLHttpRequest();
xhr.onload = loadHandler;
xhr.randomProperty = true;
xhr.upload.randomProperty = true;
xhr.open("GET", "test_bug382871.html");
xhr.send();
xhr = null;
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils)
.garbageCollect();
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(runTest);
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,245 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=433533
-->
<head>
<title>Test for Bug 433533</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>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=433533">Mozilla Bug 433533</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
/** Test for Bug 433533 **/
var input = document.createElement("input");
input.setAttribute("type", "hidden");
is(input.getAttribute("type"), "hidden", "Setting type attribute didn't work!");
input.setAttribute("type", "hiDDen");
is(input.getAttribute("type"), "hiDDen", "Type attribute didn't store the original value");
is(input.type, "hidden", "Wrong input.type!");
input.setAttribute("type", "HIDDEN");
is(input.getAttribute("type"), "HIDDEN", "Type attribute didn't store the original value");
is(input.type, "hidden", "Wrong input.type!");
var td = document.createElement("td");
td.setAttribute("scope", "rOW");
is(td.getAttribute("scope"), "rOW", "Scope attribute didn't store the original value");
td.setAttribute("scope", "row");
is(td.getAttribute("scope"), "row", "Scope attribute didn't store the original value");
td.setAttribute("colspan", "100k");
is(td.getAttribute("colspan"), "100k", "Colspan attribute didn't store the original value");
td.setAttribute("colspan", " 100 ");
is(td.getAttribute("colspan"), " 100 ", "Colspan attribute didn't store the original value");
td.setAttribute("colspan", "100");
is(td.getAttribute("colspan"), "100", "Colspan attribute didn't store the original value");
// Note, if colspan is negative, it is set to 1, because of backwards compatibility.
// @see nsHTMLTableCellElement::ParseAttribute
td.setAttribute("colspan", "-100k");
is(td.getAttribute("colspan"), "1", "Colspan attribute didn't store the original value");
td.setAttribute("colspan", " -100 ");
is(td.getAttribute("colspan"), "1", "Colspan attribute didn't store the original value");
td.setAttribute("colspan", "-100");
is(td.getAttribute("colspan"), "1", "Colspan attribute didn't store the original value");
td.setAttribute("colspan", "foobar");
is(td.getAttribute("colspan"), "foobar", "Colspan attribute didn't store the original value");
var iframe = document.createElement("iframe");
iframe.setAttribute("marginwidth", "50%");
is(iframe.getAttribute("marginwidth"), "50%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "50");
is(iframe.getAttribute("marginwidth"), "50",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "0");
is(iframe.getAttribute("marginwidth"), "0",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "0%");
is(iframe.getAttribute("marginwidth"), "0%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "9999999999999999999999");
is(iframe.getAttribute("marginwidth"), "9999999999999999999999",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "9999999999999999999999%");
is(iframe.getAttribute("marginwidth"), "9999999999999999999999%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-9999999999999999999999");
is(iframe.getAttribute("marginwidth"), "-9999999999999999999999",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-9999999999999999999999%");
is(iframe.getAttribute("marginwidth"), "-9999999999999999999999%",
"Marginwidth attribute didn't store the original value");
// Test PRInt32 min/max value
iframe.setAttribute("marginwidth", "2147483647");
is(iframe.getAttribute("marginwidth"), "2147483647",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "2147483647%");
is(iframe.getAttribute("marginwidth"), "2147483647%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-2147483648");
is(iframe.getAttribute("marginwidth"), "-2147483648",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-2147483648%");
is(iframe.getAttribute("marginwidth"), "-2147483648%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "2147483646");
is(iframe.getAttribute("marginwidth"), "2147483646",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "2147483647%");
is(iframe.getAttribute("marginwidth"), "2147483647%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-2147483647");
is(iframe.getAttribute("marginwidth"), "-2147483647",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-2147483647%");
is(iframe.getAttribute("marginwidth"), "-2147483647%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "2147483648");
is(iframe.getAttribute("marginwidth"), "2147483648",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "2147483648%");
is(iframe.getAttribute("marginwidth"), "2147483648%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-2147483649");
is(iframe.getAttribute("marginwidth"), "-2147483649",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-2147483649%");
is(iframe.getAttribute("marginwidth"), "-2147483649%",
"Marginwidth attribute didn't store the original value");
// some values 0 > x > NS_ATTRVALUE_INTEGERTYPE_MAXVALUE
iframe.setAttribute("marginwidth", "134217726");
is(iframe.getAttribute("marginwidth"), "134217726",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "134217727");
is(iframe.getAttribute("marginwidth"), "134217727",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "134217728");
is(iframe.getAttribute("marginwidth"), "134217728",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "134217729");
is(iframe.getAttribute("marginwidth"), "134217729",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "134217726%");
is(iframe.getAttribute("marginwidth"), "134217726%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "134217727%");
is(iframe.getAttribute("marginwidth"), "134217727%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "134217728%");
is(iframe.getAttribute("marginwidth"), "134217728%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "134217729%");
is(iframe.getAttribute("marginwidth"), "134217729%",
"Marginwidth attribute didn't store the original value");
// some values 0 < x < NS_ATTRVALUE_INTEGERTYPE_MINVALUE
iframe.setAttribute("marginwidth", "-134217727");
is(iframe.getAttribute("marginwidth"), "-134217727",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-134217728");
is(iframe.getAttribute("marginwidth"), "-134217728",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-134217729");
is(iframe.getAttribute("marginwidth"), "-134217729",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-134217730");
is(iframe.getAttribute("marginwidth"), "-134217730",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-134217727%");
is(iframe.getAttribute("marginwidth"), "-134217727%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-134217728%");
is(iframe.getAttribute("marginwidth"), "-134217728%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-134217729%");
is(iframe.getAttribute("marginwidth"), "-134217729%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-134217730%");
is(iframe.getAttribute("marginwidth"), "-134217730%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-0");
is(iframe.getAttribute("marginwidth"), "-0",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-0%");
is(iframe.getAttribute("marginwidth"), "-0%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", " 0 ");
is(iframe.getAttribute("marginwidth"), " 0 ",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", " 0% ");
is(iframe.getAttribute("marginwidth"), " 0% ",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-50%");
is(iframe.getAttribute("marginwidth"), "-50%",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "-50");
is(iframe.getAttribute("marginwidth"), "-50",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", " -50% ");
is(iframe.getAttribute("marginwidth"), " -50% ",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", " -50 ");
is(iframe.getAttribute("marginwidth"), " -50 ",
"Marginwidth attribute didn't store the original value");
iframe.setAttribute("marginwidth", "foobar");
is(iframe.getAttribute("marginwidth"), "foobar",
"Marginwidth attribute didn't store the original value");
var bd = document.createElement("body");
bd.setAttribute("bgcolor", "red");
is(bd.getAttribute("bgcolor"), "red", "Bgcolor attribute didn't store the original value");
bd.setAttribute("bgcolor", " red ");
todo(bd.getAttribute("bgcolor") == " red ", "Bgcolor attribute didn't store the original value");
td.setAttribute("colspan", "100k");
is(td.getAttribute("colspan"), "100k", "Colspan attribute didn't store the original value");
bd.setAttribute("bgcolor", "red");
is(bd.bgColor, "#ff0000", ".bgColor didn't return the right value!");
bd.setAttribute("bgcolor", " red ");
is(bd.bgColor, "#ff0000", ".bgColor didn't return the right value!");
bd.setAttribute("bgcolor", "#ff0000");
is(bd.bgColor, "#ff0000", ".bgColor didn't return the right value!");
var video = document.createElement("video");
video.setAttribute("playbackrate", "1");
is(video.getAttribute('playbackrate'), "1",
"Playbackrate attribute didn't store the original value");
video.setAttribute("playbackrate", "1.5");
is(video.getAttribute('playbackrate'), "1.5",
"Playbackrate attribute didn't store the original value");
video.setAttribute("playbackrate", "999999999999999999");
is(video.getAttribute('playbackrate'), "999999999999999999",
"Playbackrate attribute didn't store the original value");
video.setAttribute("playbackrate", "-999999999999999999");
is(video.getAttribute('playbackrate'), "-999999999999999999",
"Playbackrate attribute didn't store the original value");
video.setAttribute("playbackrate", "foo");
is(video.getAttribute('playbackrate'), "foo",
"Playbackrate attribute didn't store the original value");
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,39 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=457746
-->
<head>
<title>Test for Bug 457746</title>
<script type="application/javascript" src="/MochiKit/MochiKit.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=457746">Mozilla Bug 457746</a>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
/** Test for Bug 457746 **/
SimpleTest.waitForExplicitFinish();
var xhr = new XMLHttpRequest();
xhr.open("GET", "bug457746.sjs");
xhr.send("");
xhr.abort();
xhr.open("GET", "bug457746.sjs");
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
is(xhr.responseText, "\u00c1", "Broken encoding conversion?");
SimpleTest.finish();
}
}
xhr.send("");
</script>
</pre>
</body>
</html>

View File

@ -20,6 +20,7 @@
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Eric Butler <zantifon@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
@ -103,6 +104,7 @@
#include "gfxPlatform.h"
#include "gfxFont.h"
#include "gfxTextRunCache.h"
#include "gfxBlur.h"
#include "nsFrameManager.h"
@ -316,7 +318,6 @@ public:
virtual ~nsCanvasRenderingContext2D();
nsresult Redraw();
void SetThebesColor(nscolor c);
// nsICanvasRenderingContextInternal
NS_IMETHOD SetCanvasElement(nsICanvasElement* aParentCanvas);
@ -334,11 +335,6 @@ public:
// nsIDOMCanvasRenderingContext2D interface
NS_DECL_NSIDOMCANVASRENDERINGCONTEXT2D
protected:
// destroy thebes/image stuff, in preparation for possibly recreating
void Destroy();
// Some helpers. Doesn't modify acolor on failure.
enum Style {
STYLE_STROKE = 0,
STYLE_FILL,
@ -346,11 +342,21 @@ protected:
STYLE_MAX
};
protected:
// destroy thebes/image stuff, in preparation for possibly recreating
void Destroy();
// Some helpers. Doesn't modify acolor on failure.
nsresult SetStyleFromVariant(nsIVariant* aStyle, Style aWhichStyle);
void StyleColorToString(const nscolor& aColor, nsAString& aStr);
void DirtyAllStyles();
void ApplyStyle(Style aWhichStyle);
/**
* applies the given style as the current source. If the given style is
* a solid color, aUseGlobalAlpha indicates whether to multiply the alpha
* by global alpha, and is ignored otherwise.
*/
void ApplyStyle(Style aWhichStyle, PRBool aUseGlobalAlpha = PR_TRUE);
// If aPrincipal is not subsumed by this canvas element, then
// we make the canvas write-only so bad guys can't extract the pixel
@ -384,6 +390,95 @@ protected:
*/
PRBool mIsFrameInvalid;
/**
* Returns true iff the the given operator should affect areas of the
* destination where the source is transparent. Among other things, this
* implies that a fully transparent source would still affect the canvas.
*/
PRBool OperatorAffectsUncoveredAreas(gfxContext::GraphicsOperator op) const
{
return PR_FALSE;
// XXX certain operators cause 2d.composite.uncovered.* tests to fail
#if 0
return op == gfxContext::OPERATOR_IN ||
op == gfxContext::OPERATOR_OUT ||
op == gfxContext::OPERATOR_DEST_IN ||
op == gfxContext::OPERATOR_DEST_ATOP ||
op == gfxContext::OPERATOR_SOURCE;
#endif
}
/**
* Returns true iff a shadow should be drawn along with a
* drawing operation.
*/
PRBool NeedToDrawShadow()
{
ContextState& state = CurrentState();
// special case the default values as a "don't draw shadows" mode
PRBool doDraw = state.colorStyles[STYLE_SHADOW] != 0 ||
state.shadowOffset.x != 0 ||
state.shadowOffset.y != 0;
PRBool isColor = CurrentState().StyleIsColor(STYLE_SHADOW);
// if not using one of the cooky operators, can avoid drawing a shadow
// if the color is fully transparent
return (doDraw || !isColor) && (!isColor ||
NS_GET_A(state.colorStyles[STYLE_SHADOW]) != 0 ||
OperatorAffectsUncoveredAreas(mThebes->CurrentOperator()));
}
/**
* Checks the current state to determine if an intermediate surface would
* be necessary to complete a drawing operation. Does not check the
* condition pertaining to global alpha and patterns since that does not
* pertain to all drawing operations.
*/
PRBool NeedToUseIntermediateSurface()
{
// certain operators always need an intermediate surface, except
// with quartz since quartz does compositing differently than cairo
return mThebes->OriginalSurface()->GetType() != gfxASurface::SurfaceTypeQuartz &&
OperatorAffectsUncoveredAreas(mThebes->CurrentOperator());
// XXX there are other unhandled cases but they should be investigated
// first to ensure we aren't using an intermediate surface unecessarily
}
/**
* Returns true iff the current source is such that global alpha would not
* be handled correctly without the use of an intermediate surface.
*/
PRBool NeedIntermediateSurfaceToHandleGlobalAlpha(Style aWhichStyle)
{
return CurrentState().globalAlpha != 1.0 && !CurrentState().StyleIsColor(aWhichStyle);
}
/**
* Initializes the drawing of a shadow onto the canvas. The returned context
* should have the shadow shape drawn onto it, and then ShadowFinalize
* should be called. The return value is null if an error occurs.
* @param extents The extents of the shadow object, in device space.
* @param blur A newly contructed gfxAlphaBoxBlur, made with the default
* constructor and left uninitialized.
* @remark The lifetime of the return value is tied to the lifetime of
* the gfxAlphaBoxBlur, so it does not need to be ref counted.
*/
gfxContext* ShadowInitialize(const gfxRect& extents, gfxAlphaBoxBlur& blur);
/**
* Completes a shadow drawing operation.
* @param blur The gfxAlphaBoxBlur that was passed to ShadowInitialize.
*/
void ShadowFinalize(gfxAlphaBoxBlur& blur);
/**
* Draws the current path in the given style. Takes care of
* any shadow drawing and will use intermediate surfaces as needed.
*/
nsresult DrawPath(Style style);
/**
* Draws a rectangle in the given style; used by FillRect and StrokeRect.
*/
@ -437,12 +532,16 @@ protected:
// state stack handling
class ContextState {
public:
ContextState() : globalAlpha(1.0),
ContextState() : shadowOffset(0.0, 0.0),
globalAlpha(1.0),
shadowBlur(0.0),
textAlign(TEXT_ALIGN_START),
textBaseline(TEXT_BASELINE_ALPHABETIC) { }
ContextState(const ContextState& other)
: globalAlpha(other.globalAlpha),
: shadowOffset(other.shadowOffset),
globalAlpha(other.globalAlpha),
shadowBlur(other.shadowBlur),
font(other.font),
fontGroup(other.fontGroup),
textAlign(other.textAlign),
@ -471,7 +570,18 @@ protected:
patternStyles[whichStyle] = nsnull;
}
/**
* returns true iff the given style is a solid color.
*/
inline PRBool StyleIsColor(Style whichStyle) const
{
return !(patternStyles[whichStyle] ||
gradientStyles[whichStyle]);
}
gfxPoint shadowOffset;
float globalAlpha;
float shadowBlur;
nsString font;
nsRefPtr<gfxFontGroup> fontGroup;
@ -711,16 +821,20 @@ nsCanvasRenderingContext2D::DoDrawImageSecurityCheck(nsIPrincipal* aPrincipal,
}
void
nsCanvasRenderingContext2D::ApplyStyle(Style aWhichStyle)
nsCanvasRenderingContext2D::ApplyStyle(Style aWhichStyle,
PRBool aUseGlobalAlpha)
{
if (mLastStyle == aWhichStyle &&
!mDirtyStyle[aWhichStyle])
!mDirtyStyle[aWhichStyle] &&
aUseGlobalAlpha)
{
// nothing to do, this is already the set style
return;
}
mDirtyStyle[aWhichStyle] = PR_FALSE;
// if not using global alpha, don't optimize with dirty bit
if (aUseGlobalAlpha)
mDirtyStyle[aWhichStyle] = PR_FALSE;
mLastStyle = aWhichStyle;
nsCanvasPattern* pattern = CurrentState().patternStyles[aWhichStyle];
@ -739,7 +853,11 @@ nsCanvasRenderingContext2D::ApplyStyle(Style aWhichStyle)
return;
}
SetThebesColor(CurrentState().colorStyles[aWhichStyle]);
gfxRGBA color(CurrentState().colorStyles[aWhichStyle]);
if (aUseGlobalAlpha)
color.a *= CurrentState().globalAlpha;
mThebes->SetColor(color);
}
nsresult
@ -756,15 +874,6 @@ nsCanvasRenderingContext2D::Redraw()
return NS_OK;
}
void
nsCanvasRenderingContext2D::SetThebesColor(nscolor c)
{
gfxRGBA color(c);
color.a *= CurrentState().globalAlpha;
mThebes->SetColor(color);
}
NS_IMETHODIMP
nsCanvasRenderingContext2D::SetDimensions(PRInt32 width, PRInt32 height)
{
@ -803,10 +912,10 @@ nsCanvasRenderingContext2D::SetDimensions(PRInt32 width, PRInt32 height)
ContextState *state = mStyleStack.AppendElement();
state->globalAlpha = 1.0;
for (int i = 0; i < STYLE_MAX; i++)
state->colorStyles[i] = NS_RGB(0,0,0);
mLastStyle = STYLE_MAX;
state->colorStyles[STYLE_FILL] = NS_RGB(0,0,0);
state->colorStyles[STYLE_STROKE] = NS_RGB(0,0,0);
state->colorStyles[STYLE_SHADOW] = NS_RGBA(0,0,0,0);
DirtyAllStyles();
mThebes->SetOperator(gfxContext::OPERATOR_CLEAR);
@ -1240,14 +1349,14 @@ nsCanvasRenderingContext2D::SetShadowOffsetX(float x)
{
if (!FloatValidate(x))
return NS_ERROR_DOM_SYNTAX_ERR;
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
CurrentState().shadowOffset.x = x;
return NS_OK;
}
NS_IMETHODIMP
nsCanvasRenderingContext2D::GetShadowOffsetX(float *x)
{
*x = 0.0f;
*x = static_cast<float>(CurrentState().shadowOffset.x);
return NS_OK;
}
@ -1256,14 +1365,14 @@ nsCanvasRenderingContext2D::SetShadowOffsetY(float y)
{
if (!FloatValidate(y))
return NS_ERROR_DOM_SYNTAX_ERR;
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
CurrentState().shadowOffset.y = y;
return NS_OK;
}
NS_IMETHODIMP
nsCanvasRenderingContext2D::GetShadowOffsetY(float *y)
{
*y = 0.0f;
*y = static_cast<float>(CurrentState().shadowOffset.y);
return NS_OK;
}
@ -1272,28 +1381,190 @@ nsCanvasRenderingContext2D::SetShadowBlur(float blur)
{
if (!FloatValidate(blur))
return NS_ERROR_DOM_SYNTAX_ERR;
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
if (blur < 0.0)
return NS_OK;
CurrentState().shadowBlur = blur;
return NS_OK;
}
NS_IMETHODIMP
nsCanvasRenderingContext2D::GetShadowBlur(float *blur)
{
*blur = 0.0f;
*blur = CurrentState().shadowBlur;
return NS_OK;
}
NS_IMETHODIMP
nsCanvasRenderingContext2D::SetShadowColor(const nsAString& color)
nsCanvasRenderingContext2D::SetShadowColor(const nsAString& colorstr)
{
// XXX ERRMSG we need to report an error to developers here! (bug 329026)
nscolor color;
nsresult rv = mCSSParser->ParseColorString(nsString(colorstr), nsnull, 0, &color);
if (NS_FAILED(rv)) {
// Error reporting happens inside the CSS parser
return NS_OK;
}
CurrentState().SetColorStyle(STYLE_SHADOW, color);
mDirtyStyle[STYLE_SHADOW] = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsCanvasRenderingContext2D::GetShadowColor(nsAString& color)
{
color.SetIsVoid(PR_TRUE);
StyleColorToString(CurrentState().colorStyles[STYLE_SHADOW], color);
return NS_OK;
}
static void
CopyContext(gfxContext* dest, gfxContext* src)
{
dest->Multiply(src->CurrentMatrix());
nsRefPtr<gfxPath> path = src->CopyPath();
dest->NewPath();
dest->AppendPath(path);
nsRefPtr<gfxPattern> pattern = src->GetPattern();
dest->SetPattern(pattern);
dest->SetLineWidth(src->CurrentLineWidth());
dest->SetLineCap(src->CurrentLineCap());
dest->SetLineJoin(src->CurrentLineJoin());
dest->SetMiterLimit(src->CurrentMiterLimit());
dest->SetFillRule(src->CurrentFillRule());
dest->SetAntialiasMode(src->CurrentAntialiasMode());
}
static const gfxFloat SIGMA_MAX = 25;
gfxContext*
nsCanvasRenderingContext2D::ShadowInitialize(const gfxRect& extents, gfxAlphaBoxBlur& blur)
{
gfxIntSize blurRadius;
gfxFloat sigma = CurrentState().shadowBlur > 8 ? sqrt(CurrentState().shadowBlur) : CurrentState().shadowBlur / 2;
// limit to avoid overly huge temp images
if (sigma > SIGMA_MAX)
sigma = SIGMA_MAX;
blurRadius = gfxAlphaBoxBlur::CalculateBlurRadius(gfxPoint(sigma, sigma));
// calculate extents
gfxRect drawExtents = extents;
// intersect with clip to avoid making overly huge temp images
gfxMatrix matrix = mThebes->CurrentMatrix();
mThebes->IdentityMatrix();
gfxRect clipExtents = mThebes->GetClipExtents();
mThebes->SetMatrix(matrix);
// outset by the blur radius so that blurs can leak onto the canvas even
// when the shape is outside the clipping area
clipExtents.Outset(blurRadius.height, blurRadius.width,
blurRadius.height, blurRadius.width);
drawExtents = drawExtents.Intersect(clipExtents - CurrentState().shadowOffset);
gfxContext* ctx = blur.Init(drawExtents, blurRadius);
if (!ctx)
return nsnull;
return ctx;
}
void
nsCanvasRenderingContext2D::ShadowFinalize(gfxAlphaBoxBlur& blur)
{
ApplyStyle(STYLE_SHADOW);
// canvas matrix was already applied, don't apply it twice, but do
// apply the shadow offset
gfxMatrix matrix = mThebes->CurrentMatrix();
mThebes->IdentityMatrix();
mThebes->Translate(CurrentState().shadowOffset);
blur.Paint(mThebes);
mThebes->SetMatrix(matrix);
}
nsresult
nsCanvasRenderingContext2D::DrawPath(Style style)
{
/*
* Need an intermediate surface when:
* - globalAlpha != 1 and gradients/patterns are used (need to paint_with_alpha)
* - certain operators are used and are not on mac (quartz/cairo composite operators don't quite line up)
*/
PRBool doUseIntermediateSurface = NeedToUseIntermediateSurface() ||
NeedIntermediateSurfaceToHandleGlobalAlpha(style);
PRBool doDrawShadow = NeedToDrawShadow();
if (doDrawShadow) {
gfxMatrix matrix = mThebes->CurrentMatrix();
mThebes->IdentityMatrix();
// calculate extents of path
gfxRect drawExtents;
if (style == STYLE_FILL)
drawExtents = mThebes->GetUserFillExtent();
else // STYLE_STROKE
drawExtents = mThebes->GetUserStrokeExtent();
mThebes->SetMatrix(matrix);
gfxAlphaBoxBlur blur;
// no need for a ref here, the blur owns the context
gfxContext* ctx = ShadowInitialize(drawExtents, blur);
if (ctx) {
ApplyStyle(style, PR_FALSE);
CopyContext(ctx, mThebes);
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
if (style == STYLE_FILL)
ctx->Fill();
else
ctx->Stroke();
ShadowFinalize(blur);
}
}
if (doUseIntermediateSurface) {
nsRefPtr<gfxPath> path = mThebes->CopyPath();
// if the path didn't copy correctly then we can't restore it, so bail
if (!path)
return NS_ERROR_FAILURE;
// draw onto a pushed group
mThebes->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
// XXX for some reason clipping messes up the path when push/popping
// copying the path seems to fix it, for unknown reasons
mThebes->NewPath();
mThebes->AppendPath(path);
// don't want operators to be applied twice
mThebes->SetOperator(gfxContext::OPERATOR_SOURCE);
}
ApplyStyle(style);
if (style == STYLE_FILL)
mThebes->Fill();
else
mThebes->Stroke();
if (doUseIntermediateSurface) {
mThebes->PopGroupToSource();
DirtyAllStyles();
mThebes->Paint(CurrentState().StyleIsColor(style) ? 1.0 : CurrentState().globalAlpha);
}
return NS_OK;
}
@ -1307,17 +1578,13 @@ nsCanvasRenderingContext2D::ClearRect(float x, float y, float w, float h)
if (!FloatValidate(x,y,w,h))
return NS_ERROR_DOM_SYNTAX_ERR;
nsRefPtr<gfxPath> path = mThebes->CopyPath();
gfxContextPathAutoSaveRestore pathSR(mThebes);
gfxContextAutoSaveRestore autoSR(mThebes);
mThebes->Save();
mThebes->SetOperator(gfxContext::OPERATOR_CLEAR);
mThebes->NewPath();
mThebes->Rectangle(gfxRect(x, y, w, h));
mThebes->Fill();
mThebes->Restore();
mThebes->NewPath();
mThebes->AppendPath(path);
return Redraw();
}
@ -1328,19 +1595,14 @@ nsCanvasRenderingContext2D::DrawRect(const gfxRect& rect, Style style)
if (!FloatValidate(rect.pos.x, rect.pos.y, rect.size.width, rect.size.height))
return NS_ERROR_DOM_SYNTAX_ERR;
nsRefPtr<gfxPath> path = mThebes->CopyPath();
gfxContextPathAutoSaveRestore pathSR(mThebes);
mThebes->NewPath();
mThebes->Rectangle(rect);
ApplyStyle(style);
if (style == STYLE_FILL)
mThebes->Fill();
else // STYLE_STROKE
mThebes->Stroke();
mThebes->NewPath();
mThebes->AppendPath(path);
nsresult rv = DrawPath(style);
if (NS_FAILED(rv))
return rv;
return Redraw();
}
@ -1378,16 +1640,18 @@ nsCanvasRenderingContext2D::ClosePath()
NS_IMETHODIMP
nsCanvasRenderingContext2D::Fill()
{
ApplyStyle(STYLE_FILL);
mThebes->Fill();
nsresult rv = DrawPath(STYLE_FILL);
if (NS_FAILED(rv))
return rv;
return Redraw();
}
NS_IMETHODIMP
nsCanvasRenderingContext2D::Stroke()
{
ApplyStyle(STYLE_STROKE);
mThebes->Stroke();
nsresult rv = DrawPath(STYLE_STROKE);
if (NS_FAILED(rv))
return rv;
return Redraw();
}
@ -1883,20 +2147,26 @@ struct NS_STACK_CLASS nsCanvasBidiProcessor : public nsBidiPresUtils::BidiProces
mTextRun = gfxTextRunCache::MakeTextRun(text,
length,
mFontgrp,
mCtx->mThebes,
mThebes,
mAppUnitsPerDevPixel,
direction==NSBIDI_RTL ? gfxTextRunFactory::TEXT_IS_RTL : 0);
}
virtual nscoord GetWidth()
{
PRBool tightBoundingBox = PR_FALSE;
gfxTextRun::Metrics textRunMetrics = mTextRun->MeasureText(0,
mTextRun->GetLength(),
tightBoundingBox,
mCtx->mThebes,
mDoMeasureBoundingBox,
mThebes,
nsnull);
// this only measures the height; the total width is gotten from the
// the return value of ProcessText.
if (mDoMeasureBoundingBox) {
textRunMetrics.mBoundingBox.Scale(1.0 / mAppUnitsPerDevPixel);
mBoundingBox = mBoundingBox.Union(textRunMetrics.mBoundingBox);
}
return static_cast<nscoord>(textRunMetrics.mAdvanceWidth/gfxFloat(mAppUnitsPerDevPixel));
}
@ -1911,7 +2181,7 @@ struct NS_STACK_CLASS nsCanvasBidiProcessor : public nsBidiPresUtils::BidiProces
// stroke or fill the text depending on operation
if (mOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_STROKE)
mTextRun->DrawToPath(mCtx->mThebes,
mTextRun->DrawToPath(mThebes,
point,
0,
mTextRun->GetLength(),
@ -1919,7 +2189,7 @@ struct NS_STACK_CLASS nsCanvasBidiProcessor : public nsBidiPresUtils::BidiProces
nsnull);
else
// mOp == TEXT_DRAW_OPERATION_FILL
mTextRun->Draw(mCtx->mThebes,
mTextRun->Draw(mThebes,
point,
0,
mTextRun->GetLength(),
@ -1931,8 +2201,9 @@ struct NS_STACK_CLASS nsCanvasBidiProcessor : public nsBidiPresUtils::BidiProces
// current text run
gfxTextRunCache::AutoTextRun mTextRun;
// pointer to the context
nsCanvasRenderingContext2D* mCtx;
// pointer to the context, may not be the canvas's context
// if an intermediate surface is being used
gfxContext* mThebes;
// position of the left side of the string, alphabetic baseline
gfxPoint mPt;
@ -1945,6 +2216,12 @@ struct NS_STACK_CLASS nsCanvasBidiProcessor : public nsBidiPresUtils::BidiProces
// operation (fill or stroke)
nsCanvasRenderingContext2D::TextDrawOperation mOp;
// union of bounding boxes of all runs, needed for shadows
gfxRect mBoundingBox;
// true iff the bounding box should be measured
PRBool mDoMeasureBoundingBox;
};
nsresult
@ -2002,22 +2279,28 @@ nsCanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
NS_STYLE_DIRECTION_RTL;
}
// don't need to take care of these with stroke since Stroke() does that
PRBool doDrawShadow = aOp == TEXT_DRAW_OPERATION_FILL && NeedToDrawShadow();
PRBool doUseIntermediateSurface = aOp == TEXT_DRAW_OPERATION_FILL &&
(NeedToUseIntermediateSurface() || NeedIntermediateSurfaceToHandleGlobalAlpha(STYLE_FILL));
nsCanvasBidiProcessor processor;
GetAppUnitsValues(&processor.mAppUnitsPerDevPixel, NULL);
processor.mPt = gfxPoint(aX, aY);
processor.mCtx = this;
processor.mThebes = mThebes;
processor.mOp = aOp;
processor.mBoundingBox = gfxRect(0, 0, 0, 0);
// need to measure size if using an intermediate surface for drawing
processor.mDoMeasureBoundingBox = doDrawShadow;
processor.mFontgrp = GetCurrentFontStyle();
NS_ASSERTION(processor.mFontgrp, "font group is null");
nscoord totalWidth;
// currently calls bidi algo twice since it needs the full width before
// rendering anything. Can probably restructure function to avoid this if
// it's cheaper to store all the runs locally rather than do bidi resolution
// twice.
// calls bidi algo twice since it needs the full text width and the
// bounding boxes before rendering anything
rv = bidiUtils->ProcessText(textToDraw.get(),
textToDraw.Length(),
isRTL ? NSBIDI_RTL : NSBIDI_LTR,
@ -2084,13 +2367,18 @@ nsCanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
processor.mPt.y += anchorY;
// correct bounding box to get it to be the correct size/position
processor.mBoundingBox.size.width = totalWidth;
processor.mBoundingBox.MoveBy(processor.mPt);
processor.mPt.x *= processor.mAppUnitsPerDevPixel;
processor.mPt.y *= processor.mAppUnitsPerDevPixel;
// if text is over aMaxWidth, then scale the text horizontally such that its
// width is precisely aMaxWidth
gfxContextAutoSaveRestore autoSR;
if (aMaxWidth > 0 && totalWidth > aMaxWidth) {
mThebes->Save();
autoSR.SetContext(mThebes);
// translate the anchor point to 0, then scale and translate back
gfxPoint trans(aX, 0);
mThebes->Translate(trans);
@ -2098,13 +2386,59 @@ nsCanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
mThebes->Translate(-trans);
}
nsRefPtr<gfxPath> path;
// don't ever need to measure the bounding box twice
processor.mDoMeasureBoundingBox = PR_FALSE;
if (doDrawShadow) {
// for some reason the box is too tight, probably rounding error
processor.mBoundingBox.Outset(2.0);
// this is unnecessarily big is max-width scaling is involved, but it
// will still produce correct output
gfxRect drawExtents = mThebes->UserToDevice(processor.mBoundingBox);
gfxAlphaBoxBlur blur;
gfxContext* ctx = ShadowInitialize(drawExtents, blur);
if (ctx) {
CopyContext(ctx, mThebes);
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
processor.mThebes = ctx;
rv = bidiUtils->ProcessText(textToDraw.get(),
textToDraw.Length(),
isRTL ? NSBIDI_RTL : NSBIDI_LTR,
presShell->GetPresContext(),
processor,
nsBidiPresUtils::MODE_DRAW,
nsnull,
0,
nsnull);
if (NS_FAILED(rv))
return rv;
ShadowFinalize(blur);
}
processor.mThebes = mThebes;
}
gfxContextPathAutoSaveRestore pathSR(mThebes, PR_FALSE);
// back up path if stroking
if (aOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_STROKE)
path = mThebes->CopyPath();
else
pathSR.Save();
// doUseIntermediateSurface is mutually exclusive to op == STROKE
else {
if (doUseIntermediateSurface) {
mThebes->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
// don't want operators to be applied twice
mThebes->SetOperator(gfxContext::OPERATOR_SOURCE);
}
ApplyStyle(STYLE_FILL);
}
rv = bidiUtils->ProcessText(textToDraw.get(),
textToDraw.Length(),
@ -2116,22 +2450,23 @@ nsCanvasRenderingContext2D::DrawOrMeasureText(const nsAString& aRawText,
0,
nsnull);
// stroke and restore path
if (aOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_STROKE) {
ApplyStyle(STYLE_STROKE);
mThebes->Stroke();
mThebes->NewPath();
mThebes->AppendPath(path);
// this needs to be restored before function can return
if (doUseIntermediateSurface) {
mThebes->PopGroupToSource();
DirtyAllStyles();
}
// have to restore the context if was modified for maxWidth
if (aMaxWidth > 0 && totalWidth > aMaxWidth)
mThebes->Restore();
if (NS_FAILED(rv))
return rv;
if (aOp == nsCanvasRenderingContext2D::TEXT_DRAW_OPERATION_STROKE) {
// DrawPath takes care of all shadows and composite oddities
rv = DrawPath(STYLE_STROKE);
if (NS_FAILED(rv))
return rv;
} else if (doUseIntermediateSurface)
mThebes->Paint(CurrentState().StyleIsColor(STYLE_FILL) ? 1.0 : CurrentState().globalAlpha);
return Redraw();
}
@ -2529,6 +2864,8 @@ nsCanvasRenderingContext2D::DrawImage()
return rv;
DoDrawImageSecurityCheck(principal, forceWriteOnly);
gfxContextPathAutoSaveRestore pathSR(mThebes, PR_FALSE);
#define GET_ARG(dest,whicharg) \
do { if (!ConvertJSValToDouble(dest, ctx, whicharg)) { rv = NS_ERROR_INVALID_ARG; goto FINISH; } } while (0)
@ -2593,14 +2930,51 @@ nsCanvasRenderingContext2D::DrawImage()
pattern = new gfxPattern(imgsurf);
pattern->SetMatrix(matrix);
path = mThebes->CopyPath();
pathSR.Save();
mThebes->Save();
mThebes->Translate(gfxPoint(dx, dy));
mThebes->SetPattern(pattern);
mThebes->Clip(gfxRect(0, 0, dw, dh));
mThebes->Paint(CurrentState().globalAlpha);
mThebes->Restore();
{
gfxContextAutoSaveRestore autoSR(mThebes);
mThebes->Translate(gfxPoint(dx, dy));
mThebes->SetPattern(pattern);
gfxRect clip(0, 0, dw, dh);
if (NeedToDrawShadow()) {
gfxRect drawExtents = mThebes->UserToDevice(clip);
gfxAlphaBoxBlur blur;
gfxContext* ctx = ShadowInitialize(drawExtents, blur);
if (ctx) {
CopyContext(ctx, mThebes);
ctx->SetOperator(gfxContext::OPERATOR_SOURCE);
ctx->Clip(clip);
ctx->Paint();
ShadowFinalize(blur);
}
}
PRBool doUseIntermediateSurface = NeedToUseIntermediateSurface();
mThebes->SetPattern(pattern);
DirtyAllStyles();
if (doUseIntermediateSurface) {
// draw onto a pushed group
mThebes->PushGroup(gfxASurface::CONTENT_COLOR_ALPHA);
mThebes->Clip(clip);
// don't want operators to be applied twice
mThebes->SetOperator(gfxContext::OPERATOR_SOURCE);
mThebes->Paint();
mThebes->PopGroupToSource();
} else
mThebes->Clip(clip);
mThebes->Paint(CurrentState().globalAlpha);
}
#if 1
// XXX cairo bug workaround; force a clip update on mThebes.
@ -2613,9 +2987,6 @@ nsCanvasRenderingContext2D::DrawImage()
mThebes->UpdateSurfaceClip();
#endif
mThebes->NewPath();
mThebes->AppendPath(path);
FINISH:
if (NS_SUCCEEDED(rv))
rv = Redraw();
@ -3327,9 +3698,9 @@ nsCanvasRenderingContext2D::PutImageData()
if (!imgsurf || imgsurf->CairoStatus())
return NS_ERROR_FAILURE;
nsRefPtr<gfxPath> path = mThebes->CopyPath();
gfxContextPathAutoSaveRestore pathSR(mThebes);
gfxContextAutoSaveRestore autoSR(mThebes);
mThebes->Save();
mThebes->IdentityMatrix();
mThebes->Translate(gfxPoint(x, y));
mThebes->NewPath();
@ -3337,10 +3708,6 @@ nsCanvasRenderingContext2D::PutImageData()
mThebes->SetSource(imgsurf, gfxPoint(0, 0));
mThebes->SetOperator(gfxContext::OPERATOR_SOURCE);
mThebes->Fill();
mThebes->Restore();
mThebes->NewPath();
mThebes->AppendPath(path);
return Redraw();
}

View File

@ -49,7 +49,7 @@ ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = ctx.createPattern(canvas2, 'no-repeat');
ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
ctx.fillRect(0, 0, 100, 50);
todo_isPixel(ctx, 50,25, 2,253,0,255, "50,25", "2,253,0,255", 2);
isPixel(ctx, 50,25, 2,253,0,255, "50,25", "2,253,0,255", 2);
SimpleTest.finish();

View File

@ -42,7 +42,7 @@ ctx.fillRect(0, 0, 100, 50);
ctx.fillStyle = ctx.createPattern(document.getElementById('red.png'), 'no-repeat');
ctx.globalAlpha = 0.01; // avoid any potential alpha=0 optimisations
ctx.fillRect(0, 0, 100, 50);
todo_isPixel(ctx, 50,25, 2,253,0,255, "50,25", "2,253,0,255", 2);
isPixel(ctx, 50,25, 2,253,0,255, "50,25", "2,253,0,255", 2);
SimpleTest.finish();

View File

@ -43,7 +43,7 @@ ctx.shadowColor = 'rgba(0, 0, 255, 0.5)';
ctx.shadowOffsetY = 50;
ctx.fillRect(0, -50, 100, 50);
todo_isPixel(ctx, 50,25, 127,0,127,255, "50,25", "127,0,127,255", 2);
isPixel(ctx, 50,25, 127,0,127,255, "50,25", "127,0,127,255", 2);
SimpleTest.finish();

View File

@ -45,7 +45,7 @@ ctx.shadowOffsetY = 50;
ctx.globalAlpha = 0.5;
ctx.fillRect(0, -50, 100, 50);
todo_isPixel(ctx, 50,25, 127,0,127,255, "50,25", "127,0,127,255", 2);
isPixel(ctx, 50,25, 127,0,127,255, "50,25", "127,0,127,255", 2);
SimpleTest.finish();

View File

@ -45,7 +45,7 @@ ctx.shadowOffsetY = 50;
ctx.globalAlpha = 0.707;
ctx.fillRect(0, -50, 100, 50);
todo_isPixel(ctx, 50,25, 127,0,127,255, "50,25", "127,0,127,255", 2);
isPixel(ctx, 50,25, 127,0,127,255, "50,25", "127,0,127,255", 2);
SimpleTest.finish();

View File

@ -44,7 +44,7 @@ ctx.shadowColor = '#00f';
ctx.shadowOffsetY = 50;
ctx.fillRect(0, -50, 100, 50);
todo_isPixel(ctx, 50,25, 127,0,127,255, "50,25", "127,0,127,255", 2);
isPixel(ctx, 50,25, 127,0,127,255, "50,25", "127,0,127,255", 2);
SimpleTest.finish();

View File

@ -14,14 +14,14 @@ var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
ctx.shadowBlur = 1;
todo(ctx.shadowBlur === 1, "ctx.shadowBlur === 1");
ok(ctx.shadowBlur === 1, "ctx.shadowBlur === 1");
ctx.shadowBlur = 0.5;
todo(ctx.shadowBlur === 0.5, "ctx.shadowBlur === 0.5");
ok(ctx.shadowBlur === 0.5, "ctx.shadowBlur === 0.5");
ctx.shadowBlur = 1e6;
todo(ctx.shadowBlur === 1e6, "ctx.shadowBlur === 1e6");
ok(ctx.shadowBlur === 1e6, "ctx.shadowBlur === 1e6");
ctx.shadowBlur = 1;
ctx.shadowBlur = -2;
todo(ctx.shadowBlur === 1, "ctx.shadowBlur === 1");
ok(ctx.shadowBlur === 1, "ctx.shadowBlur === 1");
ctx.shadowBlur = 0;
ok(ctx.shadowBlur === 0, "ctx.shadowBlur === 0");

View File

@ -14,9 +14,9 @@ var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
ctx.shadowColor = 'lime';
todo(ctx.shadowColor === '#00ff00', "ctx.shadowColor === '#00ff00'");
ok(ctx.shadowColor === '#00ff00', "ctx.shadowColor === '#00ff00'");
ctx.shadowColor = 'RGBA(0,255, 0,0)';
todo(ctx.shadowColor === 'rgba(0, 255, 0, 0.0)', "ctx.shadowColor === 'rgba(0, 255, 0, 0.0)'");
ok(ctx.shadowColor === 'rgba(0, 255, 0, 0.0)', "ctx.shadowColor === 'rgba(0, 255, 0, 0.0)'");
SimpleTest.finish();

View File

@ -15,11 +15,11 @@ var ctx = canvas.getContext('2d');
ctx.shadowColor = '#00ff00';
ctx.shadowColor = 'bogus';
todo(ctx.shadowColor === '#00ff00', "ctx.shadowColor === '#00ff00'");
ok(ctx.shadowColor === '#00ff00', "ctx.shadowColor === '#00ff00'");
ctx.shadowColor = ctx;
todo(ctx.shadowColor === '#00ff00', "ctx.shadowColor === '#00ff00'");
ok(ctx.shadowColor === '#00ff00', "ctx.shadowColor === '#00ff00'");
ctx.shadowColor = undefined;
todo(ctx.shadowColor === '#00ff00', "ctx.shadowColor === '#00ff00'");
ok(ctx.shadowColor === '#00ff00', "ctx.shadowColor === '#00ff00'");
SimpleTest.finish();

View File

@ -15,20 +15,20 @@ var ctx = canvas.getContext('2d');
ctx.shadowOffsetX = 1;
ctx.shadowOffsetY = 2;
todo(ctx.shadowOffsetX === 1, "ctx.shadowOffsetX === 1");
todo(ctx.shadowOffsetY === 2, "ctx.shadowOffsetY === 2");
ok(ctx.shadowOffsetX === 1, "ctx.shadowOffsetX === 1");
ok(ctx.shadowOffsetY === 2, "ctx.shadowOffsetY === 2");
ctx.shadowOffsetX = 0.5;
ctx.shadowOffsetY = 0.25;
todo(ctx.shadowOffsetX === 0.5, "ctx.shadowOffsetX === 0.5");
todo(ctx.shadowOffsetY === 0.25, "ctx.shadowOffsetY === 0.25");
ok(ctx.shadowOffsetX === 0.5, "ctx.shadowOffsetX === 0.5");
ok(ctx.shadowOffsetY === 0.25, "ctx.shadowOffsetY === 0.25");
ctx.shadowOffsetX = -0.5;
ctx.shadowOffsetY = -0.25;
todo(ctx.shadowOffsetX === -0.5, "ctx.shadowOffsetX === -0.5");
todo(ctx.shadowOffsetY === -0.25, "ctx.shadowOffsetY === -0.25");
ok(ctx.shadowOffsetX === -0.5, "ctx.shadowOffsetX === -0.5");
ok(ctx.shadowOffsetY === -0.25, "ctx.shadowOffsetY === -0.25");
ctx.shadowOffsetX = 1e6;
ctx.shadowOffsetY = 1e6;
todo(ctx.shadowOffsetX === 1e6, "ctx.shadowOffsetX === 1e6");
todo(ctx.shadowOffsetY === 1e6, "ctx.shadowOffsetY === 1e6");
ok(ctx.shadowOffsetX === 1e6, "ctx.shadowOffsetX === 1e6");
ok(ctx.shadowOffsetY === 1e6, "ctx.shadowOffsetY === 1e6");
SimpleTest.finish();

View File

@ -50,7 +50,7 @@ ctx.shadowOffsetY = 50;
ctx.shadowColor = '#00f';
ctx.drawImage(canvas2, 0, -50);
todo_isPixel(ctx, 50,25, 127,0,127,255, "50,25", "127,0,127,255", 2);
isPixel(ctx, 50,25, 127,0,127,255, "50,25", "127,0,127,255", 2);
SimpleTest.finish();

View File

@ -50,7 +50,7 @@ ctx.shadowColor = '#0f0';
ctx.shadowOffsetY = 50;
ctx.drawImage(canvas2, 0, -50);
todo_isPixel(ctx, 50,25, 0,255,0,255, "50,25", "0,255,0,255", 0);
isPixel(ctx, 50,25, 0,255,0,255, "50,25", "0,255,0,255", 0);
SimpleTest.finish();

View File

@ -55,8 +55,8 @@ ctx.shadowColor = '#f00';
ctx.drawImage(canvas2, -50, -50);
isPixel(ctx, 25,25, 0,255,0,255, "25,25", "0,255,0,255", 0);
todo_isPixel(ctx, 50,25, 0,255,0,255, "50,25", "0,255,0,255", 0);
todo_isPixel(ctx, 75,25, 0,255,0,255, "75,25", "0,255,0,255", 0);
isPixel(ctx, 50,25, 0,255,0,255, "50,25", "0,255,0,255", 0);
isPixel(ctx, 75,25, 0,255,0,255, "75,25", "0,255,0,255", 0);
SimpleTest.finish();

View File

@ -52,7 +52,7 @@ ctx.fillRect(0, 0, 50, 50);
ctx.restore();
isPixel(ctx, 25,25, 0,255,0,255, "25,25", "0,255,0,255", 0);
todo_isPixel(ctx, 75,25, 0,255,0,255, "75,25", "0,255,0,255", 0);
isPixel(ctx, 75,25, 0,255,0,255, "75,25", "0,255,0,255", 0);
SimpleTest.finish();

View File

@ -52,7 +52,7 @@ ctx.shadowOffsetX = 50;
ctx.fillRect(-50, 0, 50, 50);
ctx.restore();
todo_isPixel(ctx, 25,25, 0,255,0,255, "25,25", "0,255,0,255", 0);
isPixel(ctx, 25,25, 0,255,0,255, "25,25", "0,255,0,255", 0);
isPixel(ctx, 75,25, 0,255,0,255, "75,25", "0,255,0,255", 0);
SimpleTest.finish();

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