mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-12-02 01:48:05 +00:00
Merge.
This commit is contained in:
commit
e4e61b7b12
8
.hgtags
8
.hgtags
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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"/>
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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;"
|
||||
|
@ -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:
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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--;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -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/"));
|
||||
|
@ -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.
|
||||
*/
|
||||
|
||||
/**
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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)
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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>
|
@ -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])
|
||||
|
@ -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");
|
||||
|
@ -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);
|
||||
}
|
@ -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>
|
@ -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;
|
||||
}
|
||||
|
@ -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">
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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">
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
BIN
browser/themes/gnomestripe/browser/tabbrowser/newtab.png
Normal file
BIN
browser/themes/gnomestripe/browser/tabbrowser/newtab.png
Normal file
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 |
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
BIN
browser/themes/pinstripe/browser/tabbrowser/newtab.png
Normal file
BIN
browser/themes/pinstripe/browser/tabbrowser/newtab.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 395 B |
@ -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;
|
||||
|
@ -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)
|
||||
|
BIN
browser/themes/winstripe/browser/tabbrowser/newtab-aero.png
Normal file
BIN
browser/themes/winstripe/browser/tabbrowser/newtab-aero.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 395 B |
BIN
browser/themes/winstripe/browser/tabbrowser/newtab.png
Normal file
BIN
browser/themes/winstripe/browser/tabbrowser/newtab.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 413 B |
@ -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 = \
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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".
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -37,7 +37,7 @@
|
||||
|
||||
DEVENV_FLAG=-
|
||||
|
||||
CC=cl
|
||||
CC=cl -O2
|
||||
|
||||
MOZCE_DEVENV=vs$(MOZ_MSVCVERSION)
|
||||
|
||||
|
@ -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\"";
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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";
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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():
|
||||
|
@ -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
|
||||
|
||||
|
@ -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@
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
51
configure.in
51
configure.in
@ -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
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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()
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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>
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
11
content/base/test/bug457746.sjs
Normal file
11
content/base/test/bug457746.sjs
Normal 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);
|
||||
}
|
||||
|
43
content/base/test/test_bug254337.html
Normal file
43
content/base/test/test_bug254337.html
Normal 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>
|
||||
|
50
content/base/test/test_bug382871.html
Normal file
50
content/base/test/test_bug382871.html
Normal 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>
|
||||
|
245
content/base/test/test_bug433533.html
Normal file
245
content/base/test/test_bug433533.html
Normal 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>
|
||||
|
39
content/base/test/test_bug457746.html
Normal file
39
content/base/test/test_bug457746.html
Normal 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>
|
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user