diff --git a/browser/Makefile.in b/browser/Makefile.in index 32267a8eb79..6b6adf719fa 100644 --- a/browser/Makefile.in +++ b/browser/Makefile.in @@ -54,9 +54,6 @@ include $(topsrcdir)/config/rules.mk ifeq ($(OS_ARCH),WINNT) ifdef MOZ_INSTALLER -ifdef MOZ_BRANDING_DIRECTORY -DEFINES += -DOFFICIAL_BRANDING=1 -endif # For Windows build the uninstaller during the application build since the # uninstaller is included with the application for mar file generation. diff --git a/browser/app/Makefile.in b/browser/app/Makefile.in index 2229ea21850..3ed1bea610a 100644 --- a/browser/app/Makefile.in +++ b/browser/app/Makefile.in @@ -51,9 +51,6 @@ PREF_JS_EXPORTS = $(srcdir)/profile/firefox.js \ $(srcdir)/profile/channel-prefs.js \ $(NULL) -ifndef MOZ_BRANDING_DIRECTORY -PREF_JS_EXPORTS += $(srcdir)/firefox-branding.js -endif # hardcode en-US for the moment AB_CD = en-US @@ -226,7 +223,7 @@ endif ifdef DEBUG RCFLAGS += -DDEBUG endif -RCFLAGS += -DFIREFOX_ICO=\"$(DIST)/branding/firefox.ico\" -DDOCUMENT_ICO=\"$(DIST)/branding/document.ico\" +RCFLAGS += -DFIREFOX_ICO=\"$(DIST)/branding/firefox-os2.ico\" -DDOCUMENT_ICO=\"$(DIST)/branding/document-os2.ico\" endif include $(topsrcdir)/config/rules.mk @@ -299,58 +296,23 @@ endif endif # LIBXUL_SDK -ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT))) - -ICON_FILES = \ - $(DIST)/branding/mozicon128.png \ - $(DIST)/branding/document.png \ - $(NULL) - -libs:: $(ICON_FILES) - $(INSTALL) $(IFLAGS1) $^ $(DIST)/bin/icons - -install:: - $(SYSINSTALL) $(IFLAGS1) $(ICON_FILES) $(DESTDIR)$(mozappdir)/icons -endif - ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2) libs:: - $(INSTALL) $(IFLAGS1) $(DIST)/branding/default16.png $(DIST)/bin/chrome/icons/default - $(INSTALL) $(IFLAGS1) $(DIST)/branding/default32.png $(DIST)/bin/chrome/icons/default - $(INSTALL) $(IFLAGS1) $(DIST)/branding/default48.png $(DIST)/bin/chrome/icons/default + $(INSTALL) $(IFLAGS1) $(DIST)/branding/mozicon128.png $(DIST)/bin/icons + $(INSTALL) $(IFLAGS1) $(DIST)/branding/document.png $(DIST)/bin/icons + $(INSTALL) $(IFLAGS1) $(DIST)/branding/default16.png $(DIST)/bin/chrome/icons/default + $(INSTALL) $(IFLAGS1) $(DIST)/branding/default32.png $(DIST)/bin/chrome/icons/default + $(INSTALL) $(IFLAGS1) $(DIST)/branding/default48.png $(DIST)/bin/chrome/icons/default endif -export:: -ifndef MOZ_BRANDING_DIRECTORY - $(NSINSTALL) -D $(DIST)/branding -ifneq (,$(filter WINNT WINCE,$(OS_ARCH))) - cp $(srcdir)/firefox.ico $(DIST)/branding/firefox.ico - cp $(srcdir)/firefox.ico $(DIST)/branding/app.ico - cp $(srcdir)/document.ico $(DIST)/branding/document.ico -endif -ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT))) - cp $(srcdir)/macbuild/firefox.icns $(DIST)/branding/firefox.icns - cp $(srcdir)/macbuild/document.icns $(DIST)/branding/document.icns - cp $(srcdir)/macbuild/dsstore $(DIST)/branding/dsstore - cp $(srcdir)/macbuild/background.png $(DIST)/branding/background.png - cp $(srcdir)/macbuild/disk.icns $(DIST)/branding/disk.icns -endif -ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT))) - cp $(srcdir)/mozicon128.png $(DIST)/branding/mozicon128.png - cp $(srcdir)/document.png $(DIST)/branding/document.png -endif -ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2) - cp $(srcdir)/default16.png $(DIST)/branding/default16.png - cp $(srcdir)/default32.png $(DIST)/branding/default32.png - cp $(srcdir)/default48.png $(DIST)/branding/default48.png -endif -ifeq ($(OS_ARCH),OS2) - cp $(srcdir)/firefox-os2.ico $(DIST)/branding/firefox.ico - cp $(srcdir)/firefox-os2.ico $(DIST)/branding/app.ico - cp $(srcdir)/document-os2.ico $(DIST)/branding/document.ico +ifdef MOZ_SPLASHSCREEN +ifeq ($(MOZ_WIDGET_TOOLKIT),windows) +libs:: + $(INSTALL) $(IFLAGS1) $(DIST)/branding/splash.bmp $(DIST)/bin endif endif + libs:: touch $(DIST)/bin/.autoreg diff --git a/browser/base/Makefile.in b/browser/base/Makefile.in index db489e799bd..96dc7f0ae67 100644 --- a/browser/base/Makefile.in +++ b/browser/base/Makefile.in @@ -64,10 +64,6 @@ DEFINES += \ -DPRE_RELEASE_SUFFIX="$(PRE_RELEASE_SUFFIX)" \ $(NULL) -ifndef MOZ_BRANDING_DIRECTORY -DEFINES += -DMOZ_USE_GENERIC_BRANDING -endif - ifneq (,$(filter windows gtk2 mac cocoa, $(MOZ_WIDGET_TOOLKIT))) DEFINES += -DHAVE_SHELL_SERVICE=1 endif @@ -76,16 +72,6 @@ ifdef MOZ_UPDATER DEFINES += -DMOZ_UPDATER=1 endif -ifndef MOZ_BRANDING_DIRECTORY -libs locale:: - $(SYSINSTALL) $(IFLAGS1) $(srcdir)/content/browserconfig.properties $(DIST)/bin - $(SYSINSTALL) $(IFLAGS1) $(srcdir)/content/old-homepage-default.properties $(DIST)/bin - -install:: - $(SYSINSTALL) $(IFLAGS1) $(srcdir)/content/browserconfig.properties $(DESTDIR)$(mozappdir) - $(SYSINSTALL) $(IFLAGS1) $(srcdir)/content/old-homepage-default.properties $(DESTDIR)$(mozappdir) -endif - ifneq (,$(filter windows mac cocoa gtk2, $(MOZ_WIDGET_TOOLKIT))) ifneq ($(OS_ARCH),WINCE) DEFINES += -DCONTEXT_COPY_IMAGE_CONTENTS=1 diff --git a/browser/base/content/old-homepage-default.properties b/browser/base/content/old-homepage-default.properties deleted file mode 100644 index e9e47c85a48..00000000000 --- a/browser/base/content/old-homepage-default.properties +++ /dev/null @@ -1,2 +0,0 @@ -# Do NOT localize or otherwise change these values -browser.startup.homepage=http://www.mozilla.org/projects/bonecho/ diff --git a/browser/base/content/pageinfo/pageInfo.js b/browser/base/content/pageinfo/pageInfo.js index 84d627c753b..adedce7601a 100644 --- a/browser/base/content/pageinfo/pageInfo.js +++ b/browser/base/content/pageinfo/pageInfo.js @@ -596,11 +596,14 @@ function addImage(url, type, alt, elem, isBg) function grabAll(elem) { - // check for background images, any node may have one - var ComputedStyle = elem.ownerDocument.defaultView.getComputedStyle(elem, ""); - var url = ComputedStyle && ComputedStyle.getPropertyCSSValue("background-image"); - if (url && url.primitiveType == CSSPrimitiveValue.CSS_URI) - addImage(url.getStringValue(), gStrings.mediaBGImg, gStrings.notSet, elem, true); + // check for background images, any node may have multiple + var computedStyle = elem.ownerDocument.defaultView.getComputedStyle(elem, ""); + if (computedStyle) { + Array.forEach(computedStyle.getPropertyCSSValue("background-image"), function (url) { + if (url.primitiveType == CSSPrimitiveValue.CSS_URI) + addImage(url.getStringValue(), gStrings.mediaBGImg, gStrings.notSet, elem, true); + }); + } // one swi^H^H^Hif-else to rule them all if (elem instanceof HTMLImageElement) diff --git a/browser/base/jar.mn b/browser/base/jar.mn index a5a1b81ef01..7633a8e01ff 100644 --- a/browser/base/jar.mn +++ b/browser/base/jar.mn @@ -60,14 +60,6 @@ browser.jar: * content/browser/softwareUpdateOverlay.xul (content/softwareUpdateOverlay.xul) #endif * content/browser/viewSourceOverlay.xul (content/viewSourceOverlay.xul) -#ifdef MOZ_USE_GENERIC_BRANDING -% content branding %content/branding/ xpcnativewrappers=yes - content/branding/about.png (branding/about.png) - content/branding/aboutCredits.png (branding/aboutCredits.png) - content/branding/aboutFooter.png (branding/aboutFooter.png) - content/branding/icon48.png (branding/icon48.png) - content/branding/icon64.png (branding/icon64.png) -#endif # the following files are browser-specific overrides * content/browser/license.html (/toolkit/content/license.html) % override chrome://global/content/license.html chrome://browser/content/license.html diff --git a/browser/branding/nightly/Makefile.in b/browser/branding/nightly/Makefile.in new file mode 100644 index 00000000000..6fcbf624cba --- /dev/null +++ b/browser/branding/nightly/Makefile.in @@ -0,0 +1,101 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is Mozilla Corporation. +# Portions created by the Initial Developer are Copyright (C) 2009 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Justin Dolske (original author) +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# 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 ***** + +DEPTH = ../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +DIRS = \ + content \ + locales \ + $(NULL) + +PREF_JS_EXPORTS = $(srcdir)/pref/firefox-branding.js + +include $(topsrcdir)/config/rules.mk + +WINDOWS_BRANDING_FILES = \ + firefox.ico \ + document.ico \ + branding.nsi \ + wizHeader.bmp \ + wizHeaderRTL.bmp \ + wizWatermark.bmp \ + $(NULL) + +ifdef MOZ_SPLASHSCREEN +WINDOWS_BRANDING_FILES += splash.bmp +endif + +OSX_BRANDING_FILES = \ + background.png \ + firefox.icns \ + disk.icns \ + document.icns \ + dsstore \ + $(NULL) + +LINUX_BRANDING_FILES = \ + default16.png \ + default32.png \ + default48.png \ + document.png \ + mozicon128.png \ + $(NULL) + +OS2_BRANDING_FILES = \ + firefox-os2.ico \ + document-os2.ico \ + $(NULL) + +export:: + $(NSINSTALL) -D $(DIST)/branding +ifeq ($(MOZ_WIDGET_TOOLKIT),windows) + cp $(addprefix $(srcdir)/, $(WINDOWS_BRANDING_FILES)) $(DIST)/branding/ +endif +ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa) + cp $(addprefix $(srcdir)/, $(OSX_BRANDING_FILES)) $(DIST)/branding/ +endif +ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2) + cp $(addprefix $(srcdir)/, $(LINUX_BRANDING_FILES)) $(DIST)/branding/ + $(NSINSTALL) -D $(DIST)/install +endif +ifeq ($(OS_ARCH),OS2) + cp $(addprefix $(srcdir)/, $(OS2_BRANDING_FILES)) $(DIST)/branding/ +endif diff --git a/browser/app/macbuild/background.png b/browser/branding/nightly/background.png similarity index 100% rename from browser/app/macbuild/background.png rename to browser/branding/nightly/background.png diff --git a/browser/installer/windows/nsis/branding.nsi b/browser/branding/nightly/branding.nsi similarity index 100% rename from browser/installer/windows/nsis/branding.nsi rename to browser/branding/nightly/branding.nsi diff --git a/browser/branding/nightly/configure.sh b/browser/branding/nightly/configure.sh old mode 100755 new mode 100644 diff --git a/browser/branding/nightly/content/Makefile.in b/browser/branding/nightly/content/Makefile.in new file mode 100644 index 00000000000..827181f9b49 --- /dev/null +++ b/browser/branding/nightly/content/Makefile.in @@ -0,0 +1,11 @@ +# Branding Makefile +# - jars chrome artwork + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ + +include $(DEPTH)/config/autoconf.mk + +include $(topsrcdir)/config/rules.mk diff --git a/browser/base/branding/about.png b/browser/branding/nightly/content/about.png similarity index 100% rename from browser/base/branding/about.png rename to browser/branding/nightly/content/about.png diff --git a/browser/base/branding/aboutCredits.png b/browser/branding/nightly/content/aboutCredits.png similarity index 100% rename from browser/base/branding/aboutCredits.png rename to browser/branding/nightly/content/aboutCredits.png diff --git a/browser/base/branding/aboutFooter.png b/browser/branding/nightly/content/aboutFooter.png similarity index 100% rename from browser/base/branding/aboutFooter.png rename to browser/branding/nightly/content/aboutFooter.png diff --git a/browser/base/branding/icon48.png b/browser/branding/nightly/content/icon48.png similarity index 100% rename from browser/base/branding/icon48.png rename to browser/branding/nightly/content/icon48.png diff --git a/browser/base/branding/icon64.png b/browser/branding/nightly/content/icon64.png similarity index 100% rename from browser/base/branding/icon64.png rename to browser/branding/nightly/content/icon64.png diff --git a/browser/branding/nightly/content/jar.mn b/browser/branding/nightly/content/jar.mn new file mode 100644 index 00000000000..1d035774ee8 --- /dev/null +++ b/browser/branding/nightly/content/jar.mn @@ -0,0 +1,7 @@ +browser.jar: +% content branding %content/branding/ xpcnativewrappers=yes + content/branding/about.png (about.png) + content/branding/aboutCredits.png (aboutCredits.png) + content/branding/aboutFooter.png (aboutFooter.png) + content/branding/icon48.png (icon48.png) + content/branding/icon64.png (icon64.png) diff --git a/browser/app/default16.png b/browser/branding/nightly/default16.png similarity index 100% rename from browser/app/default16.png rename to browser/branding/nightly/default16.png diff --git a/browser/app/default32.png b/browser/branding/nightly/default32.png similarity index 100% rename from browser/app/default32.png rename to browser/branding/nightly/default32.png diff --git a/browser/app/default48.png b/browser/branding/nightly/default48.png similarity index 100% rename from browser/app/default48.png rename to browser/branding/nightly/default48.png diff --git a/browser/app/macbuild/disk.icns b/browser/branding/nightly/disk.icns similarity index 100% rename from browser/app/macbuild/disk.icns rename to browser/branding/nightly/disk.icns diff --git a/browser/app/document-os2.ico b/browser/branding/nightly/document-os2.ico similarity index 100% rename from browser/app/document-os2.ico rename to browser/branding/nightly/document-os2.ico diff --git a/browser/app/macbuild/document.icns b/browser/branding/nightly/document.icns similarity index 100% rename from browser/app/macbuild/document.icns rename to browser/branding/nightly/document.icns diff --git a/browser/app/document.ico b/browser/branding/nightly/document.ico similarity index 100% rename from browser/app/document.ico rename to browser/branding/nightly/document.ico diff --git a/browser/app/document.png b/browser/branding/nightly/document.png similarity index 100% rename from browser/app/document.png rename to browser/branding/nightly/document.png diff --git a/browser/app/macbuild/dsstore b/browser/branding/nightly/dsstore old mode 100755 new mode 100644 similarity index 100% rename from browser/app/macbuild/dsstore rename to browser/branding/nightly/dsstore diff --git a/browser/app/firefox-os2.ico b/browser/branding/nightly/firefox-os2.ico similarity index 100% rename from browser/app/firefox-os2.ico rename to browser/branding/nightly/firefox-os2.ico diff --git a/browser/app/macbuild/firefox.icns b/browser/branding/nightly/firefox.icns similarity index 100% rename from browser/app/macbuild/firefox.icns rename to browser/branding/nightly/firefox.icns diff --git a/browser/app/firefox.ico b/browser/branding/nightly/firefox.ico similarity index 100% rename from browser/app/firefox.ico rename to browser/branding/nightly/firefox.ico diff --git a/browser/branding/nightly/locales/Makefile.in b/browser/branding/nightly/locales/Makefile.in new file mode 100644 index 00000000000..128825e7509 --- /dev/null +++ b/browser/branding/nightly/locales/Makefile.in @@ -0,0 +1,55 @@ +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is the Mozilla Browser code. +# +# The Initial Developer of the Original Code is +# Benjamin Smedberg +# Portions created by the Initial Developer are Copyright (C) 2004 +# 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 ***** + +DEPTH = ../../../.. +topsrcdir = @top_srcdir@ +srcdir = @srcdir@ +VPATH = @srcdir@ +relativesrcdir = browser/branding/nightly/locales + +include $(DEPTH)/config/autoconf.mk + +DEFINES += -DAB_CD=$(AB_CD) -DMOZ_DISTRIBUTION_ID_UNQUOTED=$(MOZ_DISTRIBUTION_ID) + +include $(topsrcdir)/config/rules.mk + +libs:: + @$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \ + $(srcdir)/browserconfig.properties > $(FINAL_TARGET)/browserconfig.properties + +install:: + @$(PYTHON) $(topsrcdir)/config/Preprocessor.py $(DEFINES) $(ACDEFINES) \ + $(srcdir)/browserconfig.properties > $(DESTDIR)$(mozappdir)/browserconfig.properties diff --git a/browser/base/content/browserconfig.properties b/browser/branding/nightly/locales/browserconfig.properties similarity index 100% rename from browser/base/content/browserconfig.properties rename to browser/branding/nightly/locales/browserconfig.properties diff --git a/browser/locales/en-US/chrome/branding/brand.dtd b/browser/branding/nightly/locales/en-US/brand.dtd similarity index 100% rename from browser/locales/en-US/chrome/branding/brand.dtd rename to browser/branding/nightly/locales/en-US/brand.dtd diff --git a/browser/locales/en-US/chrome/branding/brand.properties b/browser/branding/nightly/locales/en-US/brand.properties similarity index 100% rename from browser/locales/en-US/chrome/branding/brand.properties rename to browser/branding/nightly/locales/en-US/brand.properties diff --git a/browser/branding/nightly/locales/jar.mn b/browser/branding/nightly/locales/jar.mn new file mode 100644 index 00000000000..0ba09759c1a --- /dev/null +++ b/browser/branding/nightly/locales/jar.mn @@ -0,0 +1,6 @@ +#filter substitution + +@AB_CD@.jar: +% locale branding @AB_CD@ %locale/branding/ + locale/branding/brand.dtd (%brand.dtd) +* locale/branding/brand.properties (%brand.properties) diff --git a/browser/app/mozicon128.png b/browser/branding/nightly/mozicon128.png similarity index 100% rename from browser/app/mozicon128.png rename to browser/branding/nightly/mozicon128.png diff --git a/browser/app/firefox-branding.js b/browser/branding/nightly/pref/firefox-branding.js similarity index 100% rename from browser/app/firefox-branding.js rename to browser/branding/nightly/pref/firefox-branding.js diff --git a/browser/branding/nightly/splash.bmp b/browser/branding/nightly/splash.bmp new file mode 100644 index 00000000000..98e8da4e8a9 Binary files /dev/null and b/browser/branding/nightly/splash.bmp differ diff --git a/browser/installer/windows/wizHeader.bmp b/browser/branding/nightly/wizHeader.bmp similarity index 100% rename from browser/installer/windows/wizHeader.bmp rename to browser/branding/nightly/wizHeader.bmp diff --git a/browser/installer/windows/wizHeaderRTL.bmp b/browser/branding/nightly/wizHeaderRTL.bmp similarity index 100% rename from browser/installer/windows/wizHeaderRTL.bmp rename to browser/branding/nightly/wizHeaderRTL.bmp diff --git a/browser/installer/windows/wizWatermark.bmp b/browser/branding/nightly/wizWatermark.bmp similarity index 100% rename from browser/installer/windows/wizWatermark.bmp rename to browser/branding/nightly/wizWatermark.bmp diff --git a/browser/branding/unofficial/Makefile.in b/browser/branding/unofficial/Makefile.in index d524c712c59..6fcbf624cba 100644 --- a/browser/branding/unofficial/Makefile.in +++ b/browser/branding/unofficial/Makefile.in @@ -1,7 +1,38 @@ -# Branding Makefile -# - jars chrome artwork -# - copies artwork to appropriate places in objdir for bundling into app -# resources +# ***** BEGIN LICENSE BLOCK ***** +# Version: MPL 1.1/GPL 2.0/LGPL 2.1 +# +# The contents of this file are subject to the Mozilla Public License Version +# 1.1 (the "License"); you may not use this file except in compliance with +# the License. You may obtain a copy of the License at +# http://www.mozilla.org/MPL/ +# +# Software distributed under the License is distributed on an "AS IS" basis, +# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License +# for the specific language governing rights and limitations under the +# License. +# +# The Original Code is mozilla.org code. +# +# The Initial Developer of the Original Code is Mozilla Corporation. +# Portions created by the Initial Developer are Copyright (C) 2009 +# the Initial Developer. All Rights Reserved. +# +# Contributor(s): +# Justin Dolske (original author) +# +# Alternatively, the contents of this file may be used under the terms of +# either the GNU General Public License Version 2 or later (the "GPL"), or +# 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 ***** DEPTH = ../../.. topsrcdir = @top_srcdir@ @@ -19,40 +50,52 @@ PREF_JS_EXPORTS = $(srcdir)/pref/firefox-branding.js include $(topsrcdir)/config/rules.mk -BROWSER_APP_FILES = \ +WINDOWS_BRANDING_FILES = \ + firefox.ico \ + document.ico \ + branding.nsi \ + wizHeader.bmp \ + wizHeaderRTL.bmp \ + wizWatermark.bmp \ + $(NULL) + +ifdef MOZ_SPLASHSCREEN +WINDOWS_BRANDING_FILES += splash.bmp +endif + +OSX_BRANDING_FILES = \ + background.png \ + firefox.icns \ + disk.icns \ + document.icns \ + dsstore \ + $(NULL) + +LINUX_BRANDING_FILES = \ default16.png \ default32.png \ default48.png \ + document.png \ mozicon128.png \ - firefox.ico \ - document.ico \ + $(NULL) + +OS2_BRANDING_FILES = \ + firefox-os2.ico \ + document-os2.ico \ $(NULL) export:: $(NSINSTALL) -D $(DIST)/branding - cp $(addprefix $(srcdir)/, $(BROWSER_APP_FILES)) $(DIST)/branding/ -ifneq (,$(filter gtk2,$(MOZ_WIDGET_TOOLKIT))) - cp $(srcdir)/document.png $(DIST)/branding/document.png +ifeq ($(MOZ_WIDGET_TOOLKIT),windows) + cp $(addprefix $(srcdir)/, $(WINDOWS_BRANDING_FILES)) $(DIST)/branding/ +endif +ifeq ($(MOZ_WIDGET_TOOLKIT),cocoa) + cp $(addprefix $(srcdir)/, $(OSX_BRANDING_FILES)) $(DIST)/branding/ +endif +ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2) + cp $(addprefix $(srcdir)/, $(LINUX_BRANDING_FILES)) $(DIST)/branding/ $(NSINSTALL) -D $(DIST)/install endif -ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT))) - cp $(srcdir)/firefox.icns $(DIST)/branding/firefox.icns - cp $(srcdir)/document.icns $(DIST)/branding/document.icns - cp $(srcdir)/dsstore $(DIST)/branding/dsstore - cp $(srcdir)/background.png $(DIST)/branding/background.png - cp $(srcdir)/disk.icns $(DIST)/branding/disk.icns -endif -ifneq (,$(filter WINNT WINCE,$(OS_ARCH))) - cp $(srcdir)/firefox.ico $(DIST)/branding/app.ico -endif -ifeq ($(OS_ARCH),WINNT) - cp $(srcdir)/branding.nsi $(DIST)/branding/branding.nsi - cp $(srcdir)/wizHeader.bmp $(DIST)/branding/wizHeader.bmp - cp $(srcdir)/wizHeaderRTL.bmp $(DIST)/branding/wizHeaderRTL.bmp - cp $(srcdir)/wizWatermark.bmp $(DIST)/branding/wizWatermark.bmp -endif ifeq ($(OS_ARCH),OS2) - cp $(srcdir)/firefox-os2.ico $(DIST)/branding/firefox.ico - cp $(srcdir)/firefox-os2.ico $(DIST)/branding/app.ico - cp $(srcdir)/document-os2.ico $(DIST)/branding/document.ico + cp $(addprefix $(srcdir)/, $(OS2_BRANDING_FILES)) $(DIST)/branding/ endif diff --git a/browser/branding/unofficial/configure.sh b/browser/branding/unofficial/configure.sh old mode 100755 new mode 100644 diff --git a/browser/branding/unofficial/dsstore b/browser/branding/unofficial/dsstore old mode 100755 new mode 100644 diff --git a/browser/branding/unofficial/locales/jar.mn b/browser/branding/unofficial/locales/jar.mn index 077b5508220..0ba09759c1a 100644 --- a/browser/branding/unofficial/locales/jar.mn +++ b/browser/branding/unofficial/locales/jar.mn @@ -2,6 +2,5 @@ @AB_CD@.jar: % locale branding @AB_CD@ %locale/branding/ -# Unofficial branding only exists in en-US - locale/branding/brand.dtd (en-US/brand.dtd) -* locale/branding/brand.properties (en-US/brand.properties) + locale/branding/brand.dtd (%brand.dtd) +* locale/branding/brand.properties (%brand.properties) diff --git a/browser/branding/unofficial/splash.bmp b/browser/branding/unofficial/splash.bmp new file mode 100644 index 00000000000..98e8da4e8a9 Binary files /dev/null and b/browser/branding/unofficial/splash.bmp differ diff --git a/browser/build.mk b/browser/build.mk index da56b0fa5fc..9f2f26f9d6a 100644 --- a/browser/build.mk +++ b/browser/build.mk @@ -45,9 +45,7 @@ ifdef MOZ_EXTENSIONS tier_app_dirs += extensions endif -ifdef MOZ_BRANDING_DIRECTORY tier_app_dirs += $(MOZ_BRANDING_DIRECTORY) -endif tier_app_dirs += browser diff --git a/browser/components/feeds/src/FeedWriter.js b/browser/components/feeds/src/FeedWriter.js index 769e7696a7c..362f748b9d5 100644 --- a/browser/components/feeds/src/FeedWriter.js +++ b/browser/components/feeds/src/FeedWriter.js @@ -845,8 +845,6 @@ FeedWriter.prototype = { // nsIDomEventListener handleEvent: function(event) { - // see comments in init() - event = new XPCNativeWrapper(event); if (event.target.ownerDocument != this._document) { LOG("FeedWriter.handleEvent: Someone passed the feed writer as a listener to the events of another document!"); return; @@ -1152,10 +1150,7 @@ FeedWriter.prototype = { // nsIFeedWriter init: function FW_init(aWindow) { - // Explicitly wrap |window| in an XPCNativeWrapper to make sure - // it's a real native object! This will throw an exception if we - // get a non-native object. - var window = new XPCNativeWrapper(aWindow); + var window = aWindow; this._feedURI = this._getOriginalURI(window); if (!this._feedURI) return; @@ -1332,9 +1327,6 @@ FeedWriter.prototype = { // nsIObserver observe: function FW_observe(subject, topic, data) { - // see init() - subject = new XPCNativeWrapper(subject); - if (!this._window) { // this._window is null unless this.init was called with a trusted // window object. @@ -1401,9 +1393,6 @@ FeedWriter.prototype = { // nsINavHistoryService onPageChanged: function FW_onPageChanged(aURI, aWhat, aValue) { - // see init() - aURI = new XPCNativeWrapper(aURI); - if (aWhat == Ci.nsINavHistoryObserver.ATTRIBUTE_FAVICON) { // Go through the readers menu and look for the corresponding // reader menu-item for the page if any. diff --git a/browser/installer/unix/packages-static b/browser/installer/unix/packages-static index 703a17fc21c..951be4e0461 100644 --- a/browser/installer/unix/packages-static +++ b/browser/installer/unix/packages-static @@ -19,7 +19,6 @@ bin/@PREF_DIR@/firefox-l10n.js bin/defaults/existing-profile-defaults.js ; If you add a new directory you must explicitly call addDirectory in ab-CD.jst bin/browserconfig.properties -bin/old-homepage-default.properties bin/searchplugins/* bin/defaults/profile/bookmarks.html bin/defaults/profile/localstore.rdf diff --git a/browser/installer/windows/Makefile.in b/browser/installer/windows/Makefile.in index 71bc01b540e..7ad40d4a02e 100644 --- a/browser/installer/windows/Makefile.in +++ b/browser/installer/windows/Makefile.in @@ -155,12 +155,3 @@ endif include $(topsrcdir)/config/rules.mk include $(topsrcdir)/toolkit/mozapps/installer/windows/nsis/makensis.mk - -export:: -ifndef MOZ_BRANDING_DIRECTORY - $(NSINSTALL) -D $(DIST)/branding - cp $(srcdir)/nsis/branding.nsi $(DIST)/branding/branding.nsi - cp $(srcdir)/wizHeader.bmp $(DIST)/branding/wizHeader.bmp - cp $(srcdir)/wizHeaderRTL.bmp $(DIST)/branding/wizHeaderRTL.bmp - cp $(srcdir)/wizWatermark.bmp $(DIST)/branding/wizWatermark.bmp -endif diff --git a/browser/installer/windows/packages-static b/browser/installer/windows/packages-static index fdde0d3037b..1c3f42dc454 100644 --- a/browser/installer/windows/packages-static +++ b/browser/installer/windows/packages-static @@ -18,7 +18,6 @@ bin\chrome\@AB_CD@.manifest bin\defaults\pref\firefox-l10n.js bin\defaults\existing-profile-defaults.js bin\browserconfig.properties -bin\old-homepage-default.properties bin\searchplugins\* bin\defaults\profile\bookmarks.html bin\defaults\profile\localstore.rdf diff --git a/browser/locales/Makefile.in b/browser/locales/Makefile.in index 04b6d01dc6d..2792ca49f80 100644 --- a/browser/locales/Makefile.in +++ b/browser/locales/Makefile.in @@ -64,12 +64,10 @@ vpath book%.inc @srcdir@/en-US/profile endif -ifdef MOZ_BRANDING_DIRECTORY SUBMAKEFILES += \ $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/Makefile \ $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales/Makefile \ $(NULL) -endif # This makefile uses variable overrides from the libs-% target to # build non-default locales to non-default dist/ locations. Be aware! @@ -87,10 +85,6 @@ WIN32_INSTALLER_IN ?= $(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe MOZ_LANGPACK_EID=langpack-$(AB_CD)@firefox.mozilla.org -ifndef MOZ_BRANDING_DIRECTORY -DEFINES += -DMOZ_USE_GENERIC_BRANDING -endif - ifeq (,$(filter-out pref,$(MOZ_EXTENSIONS))) DEFINES += -DEXTENSION_PREF endif @@ -188,9 +182,7 @@ libs-%: @$(MAKE) -C ../../extensions/reporter/locales libs AB_CD=$* XPI_NAME=locale-$* BOTH_MANIFESTS=1 @$(MAKE) -C ../../extensions/spellcheck/locales AB_CD=$* XPI_NAME=locale-$* BOTH_MANIFESTS=1 @$(MAKE) libs AB_CD=$* XPI_NAME=locale-$* PREF_DIR=defaults/pref BOTH_MANIFESTS=1 -ifdef MOZ_BRANDING_DIRECTORY @$(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY)/locales AB_CD=$* XPI_NAME=locale-$* BOTH_MANIFESTS=1 -endif @$(MAKE) tests AB_CD=$* ifneq (,$(filter mac cocoa,$(MOZ_WIDGET_TOOLKIT))) @@ -204,11 +196,7 @@ endif repackage-win32-installer: WIN32_INSTALLER_OUT="$(_ABS_DIST)/$(PKG_INST_PATH)$(PKG_INST_BASENAME).exe" repackage-win32-installer: $(WIN32_INSTALLER_IN) $(SUBMAKEFILES) @echo "Repackaging $(WIN32_INSTALLER_IN) into $(WIN32_INSTALLER_OUT)." -ifdef MOZ_BRANDING_DIRECTORY $(MAKE) -C $(DEPTH)/$(MOZ_BRANDING_DIRECTORY) export -else - $(MAKE) -C ../installer/windows export -endif if test ! -d $(_ABS_DIST)/$(PKG_INST_PATH); then \ $(NSINSTALL) -D $(_ABS_DIST)/$(PKG_INST_PATH); \ fi diff --git a/browser/locales/en-US/chrome/browser/browser.properties b/browser/locales/en-US/chrome/browser/browser.properties index 943c0b097a6..d712d08366c 100644 --- a/browser/locales/en-US/chrome/browser/browser.properties +++ b/browser/locales/en-US/chrome/browser/browser.properties @@ -167,7 +167,9 @@ editBookmarkPanel.editBookmarkTitle=Edit This Bookmark # LOCALIZATION NOTE (editBookmark.removeBookmarks.label) # Semi-colon list of plural forms. Replacement for #1 is # the number of bookmarks to be removed. -editBookmark.removeBookmarks.label=Remove Bookmark;Remove Bookmarks (#1) +# If this causes problems with localization you can also do "Remove Bookmarks (#1)" +# instead of "Remove #1 Bookmarks". +editBookmark.removeBookmarks.label=Remove Bookmark;Remove #1 Bookmarks # Geolocation UI diff --git a/browser/locales/jar.mn b/browser/locales/jar.mn index b6f8325034e..405b449adfb 100644 --- a/browser/locales/jar.mn +++ b/browser/locales/jar.mn @@ -75,8 +75,3 @@ % override chrome://global/locale/netError.dtd chrome://browser/locale/netError.dtd % override chrome://global/locale/appstrings.properties chrome://browser/locale/appstrings.properties % override chrome://mozapps/locale/downloads/settingsChange.dtd chrome://browser/locale/downloads/settingsChange.dtd -#ifdef MOZ_USE_GENERIC_BRANDING -% locale branding @AB_CD@ %locale/branding/ - locale/branding/brand.dtd (%chrome/branding/brand.dtd) - locale/branding/brand.properties (%chrome/branding/brand.properties) -#endif diff --git a/browser/makefiles.sh b/browser/makefiles.sh index 272c84961a9..f7390fb4cd7 100644 --- a/browser/makefiles.sh +++ b/browser/makefiles.sh @@ -82,16 +82,11 @@ browser/themes/pinstripe/Makefile browser/themes/winstripe/browser/Makefile browser/themes/winstripe/communicator/Makefile browser/themes/winstripe/Makefile +$MOZ_BRANDING_DIRECTORY/Makefile +$MOZ_BRANDING_DIRECTORY/content/Makefile +$MOZ_BRANDING_DIRECTORY/locales/Makefile " -if test -n "$MOZ_BRANDING_DIRECTORY"; then - add_makefiles " - $MOZ_BRANDING_DIRECTORY/Makefile - $MOZ_BRANDING_DIRECTORY/content/Makefile - $MOZ_BRANDING_DIRECTORY/locales/Makefile - " -fi - if [ "$ENABLE_TESTS" ]; then add_makefiles " browser/base/content/test/Makefile diff --git a/configure.in b/configure.in index 7c8895dda2d..b903ce5a549 100644 --- a/configure.in +++ b/configure.in @@ -5082,6 +5082,14 @@ MOZ_ARG_WITH_STRING(branding, [ --with-branding=dir Use branding from the specified directory.], MOZ_BRANDING_DIRECTORY=$withval) +dnl For Firefox, we always want MOZ_BRANDING_DIRECTORY to point somewhere, so +dnl if it's not set make it point to the default branding location now. Other +dnl products need MOZ_BRANDING_DIRECTORY to NOT be set, in order to use their +dnl default branding (ie, only set it when using non-default branding). +if test "$MOZ_BUILD_APP" = "browser" -a -z "$MOZ_BRANDING_DIRECTORY"; then + MOZ_BRANDING_DIRECTORY=${MOZ_BUILD_APP}/branding/nightly +fi + REAL_BRANDING_DIRECTORY="${MOZ_BRANDING_DIRECTORY}" if test -z "$REAL_BRANDING_DIRECTORY"; then REAL_BRANDING_DIRECTORY=${MOZ_BUILD_APP}/branding/nightly @@ -6283,21 +6291,6 @@ MOZ_ARG_DISABLE_BOOL(zipwriter, MOZ_ZIPWRITER=1 ) AC_SUBST(MOZ_ZIPWRITER) -dnl ======================================================== -dnl = Enable Ultrasparc specific optimizations for JS -dnl ======================================================== -MOZ_ARG_ENABLE_BOOL(js-ultrasparc, -[ --enable-js-ultrasparc Use UltraSPARC optimizations in JS], - JS_ULTRASPARC_OPTS=1, - JS_ULTRASPARC_OPTS= ) - -dnl only enable option for ultrasparcs -if test `echo "$target_os" | grep -c \^solaris 2>/dev/null` = 0 -o \ - "$OS_TEST" != "sun4u"; then - JS_ULTRASPARC_OPTS= -fi -AC_SUBST(JS_ULTRASPARC_OPTS) - dnl ======================================================== dnl = Hildon and OSSO checks dnl ======================================================== diff --git a/content/base/src/nsContentList.cpp b/content/base/src/nsContentList.cpp index 64250249f2e..8a34cddca6e 100644 --- a/content/base/src/nsContentList.cpp +++ b/content/base/src/nsContentList.cpp @@ -130,17 +130,6 @@ nsBaseContentList::GetNodeAt(PRUint32 aIndex) return mElements.SafeObjectAt(aIndex); } -void -nsBaseContentList::AppendElement(nsIContent *aContent) -{ - mElements.AppendObject(aContent); -} - -void -nsBaseContentList::RemoveElement(nsIContent *aContent) -{ - mElements.RemoveObject(aContent); -} PRInt32 nsBaseContentList::IndexOf(nsIContent *aContent, PRBool aDoFlush) @@ -154,20 +143,27 @@ nsBaseContentList::IndexOf(nsIContent* aContent) return IndexOf(aContent, PR_TRUE); } -void -nsBaseContentList::Reset() +void nsBaseContentList::AppendElement(nsIContent *aContent) { - mElements.Clear(); + mElements.AppendObject(aContent); } -// static -void -nsBaseContentList::Shutdown() +void nsBaseContentList::RemoveElement(nsIContent *aContent) { + mElements.RemoveObject(aContent); +} + +void nsBaseContentList::InsertElementAt(nsIContent* aContent, PRInt32 aIndex) +{ + NS_ASSERTION(aContent, "Element to insert must not be null"); + mElements.InsertObjectAt(aContent, aIndex); +} + +//static +void nsBaseContentList::Shutdown() { NS_IF_RELEASE(gCachedContentList); } - // nsFormContentList nsFormContentList::nsFormContentList(nsIDOMHTMLFormElement *aForm, diff --git a/content/base/src/nsContentList.h b/content/base/src/nsContentList.h index c871625b566..897fbcbd89a 100644 --- a/content/base/src/nsContentList.h +++ b/content/base/src/nsContentList.h @@ -89,12 +89,30 @@ public: virtual nsIContent* GetNodeAt(PRUint32 aIndex); virtual PRInt32 IndexOf(nsIContent* aContent); + PRUint32 Length() const { + return mElements.Count(); + } + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsBaseContentList, nsINodeList) void AppendElement(nsIContent *aContent); - void RemoveElement(nsIContent *aContent); + + /** + * Insert the element at a given index, shifting the objects at + * the given index and later to make space. + * @param aContent Element to insert, must not be null + * @param aIndex Index to insert the element at. + */ + void InsertElementAt(nsIContent* aContent, PRInt32 aIndex); + + void RemoveElement(nsIContent *aContent); + + void Reset() { + mElements.Clear(); + } + + virtual PRInt32 IndexOf(nsIContent *aContent, PRBool aDoFlush); - void Reset(); static void Shutdown(); diff --git a/content/html/content/src/nsHTMLFormElement.cpp b/content/html/content/src/nsHTMLFormElement.cpp index 4984f28b344..d33f4dffe01 100644 --- a/content/html/content/src/nsHTMLFormElement.cpp +++ b/content/html/content/src/nsHTMLFormElement.cpp @@ -2253,10 +2253,14 @@ nsFormControlList::AddElementToTable(nsIFormControl* aChild, nsBaseContentList *list = new nsBaseContentList(); NS_ENSURE_TRUE(list, NS_ERROR_OUT_OF_MEMORY); - list->AppendElement(content); + NS_ASSERTION(content->GetParent(), "Item in list without parent"); + + // Determine the ordering between the new and old element. + PRBool newFirst = nsContentUtils::PositionIsBefore(newChild, content); + + list->AppendElement(newFirst ? newChild : content); + list->AppendElement(newFirst ? content : newChild); - // Add the new child too - list->AppendElement(newChild); nsCOMPtr listSupports = do_QueryInterface(static_cast(list)); @@ -2273,12 +2277,31 @@ nsFormControlList::AddElementToTable(nsIFormControl* aChild, nsBaseContentList *list = static_cast ((nsIDOMNodeList *)nodeList.get()); - PRInt32 oldIndex = list->IndexOf(newChild, PR_FALSE); + NS_ASSERTION(list->Length() > 1, + "List should have been converted back to a single element"); - // Add the new child only if it's not in our list already - if (oldIndex < 0) { - list->AppendElement(newChild); + if(nsContentUtils::PositionIsBefore(list->GetNodeAt(list->Length() - 1), newChild)) { + list->AppendElement(newChild); + return NS_OK; } + + // first is the first possible insertion index, last is the last possible + // insertion index + PRUint32 first = 0; + PRUint32 last = list->Length() - 1; + PRUint32 mid; + + //Stop when there is only one index in our range + while (last != first) { + mid = (first + last) / 2; + + if (nsContentUtils::PositionIsBefore(newChild, list->GetNodeAt(mid))) + last = mid; + else + first = mid + 1; + } + + list->InsertElementAt(newChild, first); } } diff --git a/content/html/content/test/Makefile.in b/content/html/content/test/Makefile.in index aad17f2ef5d..975f01c7360 100644 --- a/content/html/content/test/Makefile.in +++ b/content/html/content/test/Makefile.in @@ -83,6 +83,7 @@ _TEST_FILES = test_bug589.html \ test_bug332893-4.html \ test_bug332893-5.html \ test_bug332893-6.html \ + test_bug332893-7.html \ bug340800_iframe.txt \ test_bug340800.html \ test_bug353415-1.html \ diff --git a/content/html/content/test/test_bug332893-4.html b/content/html/content/test/test_bug332893-4.html index b64160d5ac8..91d3cc75dcc 100644 --- a/content/html/content/test/test_bug332893-4.html +++ b/content/html/content/test/test_bug332893-4.html @@ -18,13 +18,13 @@ form1.insertBefore(input2, input1); is(form1.elements["input"].length, "3", "Form 1 'input' has the correct length"); - todo(form1.elements["input"][0].value == "2", "Form 1 element 1 is correct"); - todo(form1.elements["input"][1].value == "1", "Form 1 element 2 is correct"); - todo(form1.elements["input"][2].value == "3", "Form 1 element 3 is correct"); + is(form1.elements["input"][0].value, "2", "Form 1 element 1 is correct"); + is(form1.elements["input"][1].value, "1", "Form 1 element 2 is correct"); + is(form1.elements["input"][2].value, "3", "Form 1 element 3 is correct"); - todo(form1.elements["input"][0].id == "input2", "Form 1 element 1 id is correct"); - todo(form1.elements["input"][1].id == "input1", "Form 1 element 2 id is correct"); - todo(form1.elements["input"][2].id == "input3", "Form 1 element 3 id is correct"); + is(form1.elements["input"][0].id, "input2", "Form 1 element 1 id is correct"); + is(form1.elements["input"][1].id, "input1", "Form 1 element 2 id is correct"); + is(form1.elements["input"][2].id, "input3", "Form 1 element 3 id is correct"); diff --git a/content/html/content/test/test_bug332893-5.html b/content/html/content/test/test_bug332893-5.html index b73332e7b3f..74b54a0ab00 100644 --- a/content/html/content/test/test_bug332893-5.html +++ b/content/html/content/test/test_bug332893-5.html @@ -18,13 +18,13 @@ form1.insertBefore(input2, input1); is(form1.elements["input"].length, "3", "Form 1 'input' has the correct length"); - todo(form1.elements["input"][0].value == "2", "Form 1 element 1 is correct"); - todo(form1.elements["input"][1].value == "1", "Form 1 element 2 is correct"); - todo(form1.elements["input"][2].value == "3", "Form 1 element 3 is correct"); + is(form1.elements["input"][0].value, "2", "Form 1 element 1 is correct"); + is(form1.elements["input"][1].value, "1", "Form 1 element 2 is correct"); + is(form1.elements["input"][2].value, "3", "Form 1 element 3 is correct"); - todo(form1.elements["input"][0].id == "input", "Form 1 element 1 id is correct"); - todo(form1.elements["input"][1].id == "input1", "Form 1 element 2 id is correct"); - todo(form1.elements["input"][2].id == "input3", "Form 1 element 3 id is correct"); + is(form1.elements["input"][0].id, "input", "Form 1 element 1 id is correct"); + is(form1.elements["input"][1].id, "input1", "Form 1 element 2 id is correct"); + is(form1.elements["input"][2].id, "input3", "Form 1 element 3 id is correct"); diff --git a/content/html/content/test/test_bug332893-6.html b/content/html/content/test/test_bug332893-6.html index 2e26be005de..86e483d2b84 100644 --- a/content/html/content/test/test_bug332893-6.html +++ b/content/html/content/test/test_bug332893-6.html @@ -18,11 +18,11 @@ form1.insertBefore(input2, input1); is(form1.elements["input"].length, "3", "Form 1 'input' has the correct length"); - todo(form1.elements["input"][0].value == "2", "Form 1 element 1 is correct"); - todo(form1.elements["input"][1].value == "1", "Form 1 element 2 is correct"); + is(form1.elements["input"][0].value, "2", "Form 1 element 1 is correct"); + is(form1.elements["input"][1].value, "1", "Form 1 element 2 is correct"); - todo(form1.elements["input"][0].id == "input", "Form 1 element 1 id is correct"); - todo(form1.elements["input"][1].id == "input1", "Form 1 element 2 id is correct"); + is(form1.elements["input"][0].id, "input", "Form 1 element 1 id is correct"); + is(form1.elements["input"][1].id, "input1", "Form 1 element 2 id is correct"); diff --git a/content/html/content/test/test_bug332893-7.html b/content/html/content/test/test_bug332893-7.html new file mode 100644 index 00000000000..efa96ff7363 --- /dev/null +++ b/content/html/content/test/test_bug332893-7.html @@ -0,0 +1,70 @@ + + + + Test + + + + +
+ + + + + + + + + + + + + + +
+ + + diff --git a/docshell/test/Makefile.in b/docshell/test/Makefile.in index 8531507cf63..5b011ac7dd2 100644 --- a/docshell/test/Makefile.in +++ b/docshell/test/Makefile.in @@ -76,7 +76,6 @@ _TEST_FILES = \ file_bug385434_1.html \ file_bug385434_2.html \ file_bug385434_3.html \ - file_bug385434_4.html \ $(NULL) libs:: $(_TEST_FILES) diff --git a/docshell/test/chrome/bug298622_window.xul b/docshell/test/chrome/bug298622_window.xul index cc334f17ecb..0402bac669d 100755 --- a/docshell/test/chrome/bug298622_window.xul +++ b/docshell/test/chrome/bug298622_window.xul @@ -75,19 +75,29 @@ // Make sure we unsuppress painting before continuing SimpleTest.executeSoon(nextTest); yield; - + // Search for some text that's on the second page (but not on // the first page), and verify that it can be found. + var findFocused = false; gFindBar = document.getElementById("FindToolbar"); + gFindBar._findField.inputField.onfocus = function () { + findFocused = true; + }; document.getElementById("cmd_find").doCommand(); ok(!gFindBar.hidden, "failed to open findbar"); enterStringIntoFindField("A generic page"); // Make sure the key events above have time to be processed // before continuing - SimpleTest.executeSoon(nextTest); + waitForTrue(function() { + return ( + TestWindow.getWindow().getSelection().toString().toLowerCase() == + "a generic page"); + }, nextTest, 20); yield; + ok(findFocused, + "find input field doesn't have the focus, find operation will fail!"); is(gFindBar._findField.inputField.value, "A generic page", "expected text not present in find input field"); is(TestWindow.getWindow().getSelection().toString().toLowerCase(), @@ -113,6 +123,16 @@ document.getElementById("cmd_find").doCommand(); ok(!gFindBar.hidden, "failed to open findbar"); enterStringIntoFindField("find this"); + + // Make sure the key events above have time to be processed + // before continuing + waitForTrue(function() { + return ( + TestWindow.getWindow().getSelection().toString().toLowerCase() == + "find this"); + }, nextTest, 20); + yield; + is(TestWindow.getWindow().getSelection().toString().toLowerCase(), "find this", "find failed on page loaded from bfcache"); diff --git a/docshell/test/file_bug385434_3.html b/docshell/test/file_bug385434_3.html index 0a889c75d85..984b85f1f3c 100644 --- a/docshell/test/file_bug385434_3.html +++ b/docshell/test/file_bug385434_3.html @@ -7,14 +7,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=385434 - - - -
-Foo - - diff --git a/docshell/test/test_bug385434.html b/docshell/test/test_bug385434.html index 6f24a413d60..108680a5b9b 100644 --- a/docshell/test/test_bug385434.html +++ b/docshell/test/test_bug385434.html @@ -169,6 +169,7 @@ function run_test() { /* * TEST 2 tests that: * works, + * the event is targeted at the window object * the event's cancelable, bubbles settings are correct */ enableIframeLoadCallback(); @@ -180,6 +181,8 @@ function run_test() { eventExpected("frame onhashchange should fire events."); // iframe should set gSampleEvent + is(gSampleEvent.target, frameCw, + "The hashchange event should be targeted to the window."); is(gSampleEvent.type, "hashchange", "Event type should be 'hashchange'."); is(gSampleEvent.cancelable, false, @@ -189,60 +192,13 @@ function run_test() { /* * TEST 3 tests that: - * hashchange is not dispatched if the current document readyState is - * not "complete". + * hashchange is dispatched if the current document readyState is + * not "complete" (bug 504837). */ - enableIframeLoadCallback(); frameCw.document.location = "file_bug385434_3.html"; yield; - noEventExpected("Hashchange shouldn't fire if the document " + - "hasn't finished loading."); - - longWait(); - yield; - noEventExpected("Hashchange shouldn't fire after longWait() if " + - "the document hasn't finished loading."); - - /* - * TEST 4 tests that if we - * - * * Load a page A - * * Register a hashchange callback on A - * * Navigate to A#foo - * * Redirect to a different page, B, before the hashchange event triggered - * by redirecting to A#foo fires, - * - * a hashchange event is not fired on B. - */ - statusMsg("Starting test 4."); - frameCw.document.location = "file_bug385434_4.html"; - longWait(); - yield; - noEventExpected("Test 4 sequence shouldn't trigger a hashchange."); - - /* - * TEST 5 tests that: - * document.window.addEventListener() works for hashchange, - * hashchange is dispatched to window, not to body - */ - - // Make sure the current window doesn't have a hash, as would happen if we - // were running this test interactively and it hung right after we assigned a - // value to window.location.hash - window.location.hash = ""; - - window.addEventListener("hashchange", onIframeHashchange, false); - window.location.hash = "#foo"; - yield; - eventExpected("addEventListener() should work for hashchange."); - window.removeEventListener("hashchange", onIframeHashchange, false); - - document.body.addEventListener("hashchange", onIframeHashchange, false); - enableIframeLoadCallback(); - window.location.hash = "#baz"; - longWait(); - yield; - noEventExpected("hashchange shouldn't be dispatched to ."); + eventExpected("Hashchange should fire even if the document " + + "hasn't finished loading."); SimpleTest.finish(); yield; diff --git a/dom/base/nsDOMClassInfo.cpp b/dom/base/nsDOMClassInfo.cpp index df3f1ecd7d4..2291ed8a17f 100644 --- a/dom/base/nsDOMClassInfo.cpp +++ b/dom/base/nsDOMClassInfo.cpp @@ -1648,7 +1648,7 @@ nsDOMClassInfo::DefineStaticJSVals(JSContext *cx) // static nsresult nsDOMClassInfo::WrapNative(JSContext *cx, JSObject *scope, nsISupports *native, - const nsIID* aIID, jsval *vp, + const nsIID* aIID, PRBool aAllowWrapping, jsval *vp, nsIXPConnectJSObjectHolder **aHolder) { if (!native) { @@ -1662,7 +1662,42 @@ nsDOMClassInfo::WrapNative(JSContext *cx, JSObject *scope, nsISupports *native, NS_ENSURE_TRUE(sXPConnect, NS_ERROR_UNEXPECTED); return sXPConnect->WrapNativeToJSVal(cx, ::JS_GetGlobalForObject(cx, scope), - native, aIID, vp, aHolder); + native, aIID, aAllowWrapping, vp, + aHolder); +} + +static nsresult +CreateExceptionFromResult(JSContext *cx, nsresult aResult) +{ + nsCOMPtr xs = + do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID); + if (!xs) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr xm; + nsresult rv = xs->GetCurrentExceptionManager(getter_AddRefs(xm)); + if (NS_FAILED(rv)) { + return NS_ERROR_FAILURE; + } + + nsCOMPtr exception; + rv = xm->GetExceptionFromProvider(aResult, 0, getter_AddRefs(exception)); + if (NS_FAILED(rv) || !exception) { + return NS_ERROR_FAILURE; + } + + jsval jv; + nsCOMPtr holder; + rv = nsDOMClassInfo::WrapNative(cx, ::JS_GetGlobalObject(cx), exception, + &NS_GET_IID(nsIException), PR_FALSE, &jv, + getter_AddRefs(holder)); + if (NS_FAILED(rv) || JSVAL_IS_NULL(jv)) { + return NS_ERROR_FAILURE; + } + + JS_SetPendingException(cx, jv); + return NS_OK; } // static @@ -1671,36 +1706,9 @@ nsDOMClassInfo::ThrowJSException(JSContext *cx, nsresult aResult) { JSAutoRequest ar(cx); - do { - nsCOMPtr xs = - do_GetService(NS_EXCEPTIONSERVICE_CONTRACTID); - if (!xs) { - break; - } - - nsCOMPtr xm; - nsresult rv = xs->GetCurrentExceptionManager(getter_AddRefs(xm)); - if (NS_FAILED(rv)) { - break; - } - - nsCOMPtr exception; - rv = xm->GetExceptionFromProvider(aResult, 0, getter_AddRefs(exception)); - if (NS_FAILED(rv) || !exception) { - break; - } - - jsval jv; - nsCOMPtr holder; - rv = WrapNative(cx, ::JS_GetGlobalObject(cx), exception, - &NS_GET_IID(nsIException), &jv, getter_AddRefs(holder)); - if (NS_FAILED(rv) || JSVAL_IS_NULL(jv)) { - break; - } - JS_SetPendingException(cx, jv); - + if (NS_SUCCEEDED(CreateExceptionFromResult(cx, aResult))) { return NS_OK; - } while (0); + } // XXX This probably wants to be localized, but that can fail in ways that // are hard to report correctly. @@ -4560,7 +4568,8 @@ nsWindowSH::GlobalScopePolluterNewResolve(JSContext *cx, JSObject *obj, if (result) { jsval v; nsCOMPtr holder; - nsresult rv = WrapNative(cx, obj, result, &v, getter_AddRefs(holder)); + nsresult rv = WrapNative(cx, obj, result, PR_TRUE, &v, + getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, JS_FALSE); if (!::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(jsstr), @@ -4754,7 +4763,7 @@ nsWindowSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, nsCOMPtr holder; rv = WrapNative(cx, frameWin->GetGlobalJSObject(), frame, - &NS_GET_IID(nsIDOMWindow), vp, + &NS_GET_IID(nsIDOMWindow), PR_TRUE, vp, getter_AddRefs(holder)); if (NS_SUCCEEDED(rv) && !win->IsChromeWindow()) { @@ -4876,8 +4885,8 @@ nsWindowSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_ENSURE_TRUE(NS_SUCCEEDED(rv) && location, rv); nsCOMPtr holder; - rv = WrapNative(cx, obj, location, &NS_GET_IID(nsIDOMLocation), vp, - getter_AddRefs(holder)); + rv = WrapNative(cx, obj, location, &NS_GET_IID(nsIDOMLocation), PR_TRUE, + vp, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); rv = location->SetHref(nsDependentJSString(val)); @@ -5125,7 +5134,7 @@ BaseStubConstructor(nsIWeakReference* aWeakOwner, return rv; } - rv = nsDOMGenericSH::WrapNative(cx, obj, native, rval); + rv = nsDOMGenericSH::WrapNative(cx, obj, native, PR_TRUE, rval); return rv; } @@ -5684,8 +5693,8 @@ ResolvePrototype(nsIXPConnect *aXPConnect, nsGlobalWindow *aWin, JSContext *cx, jsval v; rv = nsDOMClassInfo::WrapNative(cx, obj, constructor, - &NS_GET_IID(nsIDOMDOMConstructor), &v, - getter_AddRefs(holder)); + &NS_GET_IID(nsIDOMDOMConstructor), + PR_FALSE, &v, getter_AddRefs(holder)); sDoSecurityCheckInAddProperty = doSecurityCheckInAddProperty; @@ -5876,8 +5885,8 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, nsCOMPtr holder; jsval v; - rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor), &v, - getter_AddRefs(holder)); + rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor), + PR_FALSE, &v, getter_AddRefs(holder)); sDoSecurityCheckInAddProperty = doSecurityCheckInAddProperty; @@ -5909,6 +5918,23 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, rv = GetXPCProto(sXPConnect, cx, aWin, name_struct, getter_AddRefs(proto_holder)); + if (NS_SUCCEEDED(rv) && obj != aWin->GetGlobalJSObject()) { + JSObject* dot_prototype; + rv = proto_holder->GetJSObject(&dot_prototype); + NS_ENSURE_SUCCESS(rv, rv); + + const nsDOMClassInfoData *ci_data; + if (name_struct->mType == nsGlobalNameStruct::eTypeClassConstructor) { + ci_data = &sClassInfoData[name_struct->mDOMClassInfoID]; + } else { + ci_data = name_struct->mData; + } + + return ResolvePrototype(sXPConnect, aWin, cx, obj, class_name, ci_data, + name_struct, nameSpaceManager, dot_prototype, + PR_TRUE, did_resolve); + } + *did_resolve = NS_SUCCEEDED(rv); return rv; @@ -5963,7 +5989,7 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, jsval val; nsCOMPtr holder; rv = WrapNative(cx, obj, constructor, &NS_GET_IID(nsIDOMDOMConstructor), - &val, getter_AddRefs(holder)); + PR_FALSE, &val, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); rv = constructor->Install(cx, obj, val); @@ -6010,7 +6036,8 @@ nsWindowSH::GlobalResolve(nsGlobalWindow *aWin, JSContext *cx, scope = aWin->GetGlobalJSObject(); } - rv = WrapNative(cx, scope, native, &prop_val, getter_AddRefs(holder)); + rv = WrapNative(cx, scope, native, PR_TRUE, &prop_val, + getter_AddRefs(holder)); } NS_ENSURE_SUCCESS(rv, rv); @@ -6301,10 +6328,19 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, jsval v; nsCOMPtr holder; rv = WrapNative(cx, wrapperObj, child_win, - &NS_GET_IID(nsIDOMWindowInternal), &v, + &NS_GET_IID(nsIDOMWindowInternal), PR_TRUE, &v, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); +#ifdef DEBUG + if (!win->IsChromeWindow()) { + NS_ASSERTION(JSVAL_IS_OBJECT(v) && + !strcmp(STOBJ_GET_CLASS(JSVAL_TO_OBJECT(v))->name, + "XPCCrossOriginWrapper"), + "Didn't wrap a window!"); + } +#endif + // Script is accessing a child frame and this access can // potentially come from a context from a different domain. // ::JS_DefineUCProperty() will call @@ -6317,12 +6353,6 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, // property is 'ok' in this case, even if the call comes from // a different context. - if (!win->IsChromeWindow()) { - rv = sXPConnect->GetXOWForObject(cx, win->GetGlobalJSObject(), - JSVAL_TO_OBJECT(v), &v); - NS_ENSURE_SUCCESS(rv, rv); - } - JSAutoRequest ar(cx); PRBool ok = ::JS_DefineUCProperty(cx, obj, chars, @@ -6423,18 +6453,22 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, jsval v; nsCOMPtr holder; - rv = WrapNative(cx, scope, location, &NS_GET_IID(nsIDOMLocation), &v, - getter_AddRefs(holder)); + rv = WrapNative(cx, scope, location, &NS_GET_IID(nsIDOMLocation), PR_TRUE, + &v, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); +#ifdef DEBUG + if (!win->IsChromeWindow()) { + NS_ASSERTION(JSVAL_IS_OBJECT(v) && + !strcmp(STOBJ_GET_CLASS(JSVAL_TO_OBJECT(v))->name, + "XPCCrossOriginWrapper"), + "Didn't wrap a location object!"); + } +#endif + PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty; sDoSecurityCheckInAddProperty = PR_FALSE; - if (!win->IsChromeWindow()) { - rv = sXPConnect->GetXOWForObject(cx, scope, JSVAL_TO_OBJECT(v), &v); - NS_ENSURE_SUCCESS(rv, rv); - } - JSAutoRequest ar(cx); JSBool ok = ::JS_DefineUCProperty(cx, obj, ::JS_GetStringChars(str), @@ -6495,8 +6529,8 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, jsval v; nsCOMPtr holder; - rv = WrapNative(cx, obj, navigator, &NS_GET_IID(nsIDOMNavigator), &v, - getter_AddRefs(holder)); + rv = WrapNative(cx, obj, navigator, &NS_GET_IID(nsIDOMNavigator), PR_TRUE, + &v, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); JSAutoRequest ar(cx); @@ -6519,8 +6553,8 @@ nsWindowSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, jsval v; nsCOMPtr holder; - rv = WrapNative(cx, obj, document, &NS_GET_IID(nsIDOMDocument), &v, - getter_AddRefs(holder)); + rv = WrapNative(cx, obj, document, &NS_GET_IID(nsIDOMDocument), PR_FALSE, + &v, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); // The PostCreate hook for the document will handle defining the @@ -7100,7 +7134,7 @@ nsNodeSH::PreCreate(nsISupports *nativeObj, JSContext *cx, JSObject *globalObj, jsval v; nsCOMPtr holder; - nsresult rv = WrapNative(cx, globalObj, native_parent, &v, + nsresult rv = WrapNative(cx, globalObj, native_parent, PR_FALSE, &v, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); @@ -7161,7 +7195,7 @@ nsNodeSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, } nsCOMPtr holder; - nsresult rv = WrapNative(cx, obj, uri, &NS_GET_IID(nsIURI), vp, + nsresult rv = WrapNative(cx, obj, uri, &NS_GET_IID(nsIURI), PR_TRUE, vp, getter_AddRefs(holder)); return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING; } @@ -7172,7 +7206,7 @@ nsNodeSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, nsCOMPtr holder; nsresult rv = WrapNative(cx, obj, node->NodePrincipal(), - &NS_GET_IID(nsIPrincipal), vp, + &NS_GET_IID(nsIPrincipal), PR_TRUE, vp, getter_AddRefs(holder)); return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING; } @@ -7890,7 +7924,7 @@ nsArraySH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_ENSURE_SUCCESS(rv, rv); if (array_item) { - rv = WrapNative(cx, obj, array_item, vp); + rv = WrapNative(cx, obj, array_item, PR_TRUE, vp); NS_ENSURE_SUCCESS(rv, rv); rv = NS_SUCCESS_I_DID_SOMETHING; @@ -7923,7 +7957,7 @@ nsNodeListSH::PreCreate(nsISupports *nativeObj, JSContext *cx, } jsval v; - nsresult rv = WrapNative(cx, globalObj, native_parent, &v); + nsresult rv = WrapNative(cx, globalObj, native_parent, PR_FALSE, &v); NS_ENSURE_SUCCESS(rv, rv); *parentObj = JSVAL_TO_OBJECT(v); @@ -7998,7 +8032,7 @@ nsNamedArraySH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_ENSURE_SUCCESS(rv, rv); if (item) { - rv = WrapNative(cx, obj, item, vp); + rv = WrapNative(cx, obj, item, PR_TRUE, vp); NS_ENSURE_SUCCESS(rv, rv); rv = NS_SUCCESS_I_DID_SOMETHING; @@ -8109,7 +8143,7 @@ nsContentListSH::PreCreate(nsISupports *nativeObj, JSContext *cx, } jsval v; - nsresult rv = WrapNative(cx, globalObj, native_parent, &v); + nsresult rv = WrapNative(cx, globalObj, native_parent, PR_FALSE, &v); NS_ENSURE_SUCCESS(rv, rv); *parentObj = JSVAL_TO_OBJECT(v); @@ -8206,8 +8240,8 @@ nsDocumentSH::NewResolve(nsIXPConnectWrappedNative *wrapper, JSContext *cx, jsval v; nsCOMPtr holder; - rv = WrapNative(cx, obj, location, &NS_GET_IID(nsIDOMLocation), &v, - getter_AddRefs(holder)); + rv = WrapNative(cx, obj, location, &NS_GET_IID(nsIDOMLocation), PR_TRUE, + &v, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); PRBool doSecurityCheckInAddProperty = sDoSecurityCheckInAddProperty; @@ -8250,7 +8284,7 @@ nsDocumentSH::GetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_ENSURE_TRUE(uri, NS_ERROR_NOT_AVAILABLE); nsCOMPtr holder; - nsresult rv = WrapNative(cx, obj, uri, &NS_GET_IID(nsIURI), vp, + nsresult rv = WrapNative(cx, obj, uri, &NS_GET_IID(nsIURI), PR_TRUE, vp, getter_AddRefs(holder)); return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING; @@ -8282,8 +8316,8 @@ nsDocumentSH::SetProperty(nsIXPConnectWrappedNative *wrapper, JSContext *cx, NS_ENSURE_SUCCESS(rv, rv); nsCOMPtr holder; - rv = WrapNative(cx, obj, location, &NS_GET_IID(nsIDOMLocation), vp, - getter_AddRefs(holder)); + rv = WrapNative(cx, obj, location, &NS_GET_IID(nsIDOMLocation), PR_TRUE, + vp, getter_AddRefs(holder)); return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING; } } @@ -8333,8 +8367,8 @@ nsDocumentSH::PostCreate(nsIXPConnectWrappedNative *wrapper, JSContext *cx, jsval winVal; nsCOMPtr holder; - nsresult rv = WrapNative(cx, obj, win, &NS_GET_IID(nsIDOMWindow), &winVal, - getter_AddRefs(holder)); + nsresult rv = WrapNative(cx, obj, win, &NS_GET_IID(nsIDOMWindow), PR_FALSE, + &winVal, getter_AddRefs(holder)); NS_ENSURE_SUCCESS(rv, rv); NS_NAMED_LITERAL_STRING(doc_str, "document"); @@ -8436,7 +8470,7 @@ nsHTMLDocumentSH::DocumentOpen(JSContext *cx, JSObject *obj, uintN argc, } nsCOMPtr holder; - rv = WrapNative(cx, obj, retval, &NS_GET_IID(nsIDOMDocument), rval, + rv = WrapNative(cx, obj, retval, &NS_GET_IID(nsIDOMDocument), PR_FALSE, rval, getter_AddRefs(holder)); NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to wrap native!"); @@ -8511,7 +8545,7 @@ nsHTMLDocumentSH::GetDocumentAllNodeList(JSContext *cx, JSObject *obj, rv |= domdoc->GetElementsByTagName(NS_LITERAL_STRING("*"), nodeList); nsCOMPtr holder; - rv |= nsDOMClassInfo::WrapNative(cx, obj, *nodeList, &collection, + rv |= nsDOMClassInfo::WrapNative(cx, obj, *nodeList, PR_FALSE, &collection, getter_AddRefs(holder)); // ... and store it in our reserved slot. @@ -8608,7 +8642,7 @@ nsHTMLDocumentSH::DocumentAllGetProperty(JSContext *cx, JSObject *obj, } if (result) { - rv = WrapNative(cx, obj, result, vp); + rv = WrapNative(cx, obj, result, PR_TRUE, vp); if (NS_FAILED(rv)) { nsDOMClassInfo::ThrowJSException(cx, rv); @@ -8875,7 +8909,7 @@ nsHTMLDocumentSH::DocumentAllTagsNewResolve(JSContext *cx, JSObject *obj, if (tags) { jsval v; nsCOMPtr holder; - nsresult rv = nsDOMClassInfo::WrapNative(cx, obj, tags, &v, + nsresult rv = nsDOMClassInfo::WrapNative(cx, obj, tags, PR_TRUE, &v, getter_AddRefs(holder)); if (NS_FAILED(rv)) { nsDOMClassInfo::ThrowJSException(cx, rv); @@ -9034,7 +9068,7 @@ nsHTMLDocumentSH::GetProperty(nsIXPConnectWrappedNative *wrapper, NS_ENSURE_SUCCESS(rv, rv); if (result) { - rv = WrapNative(cx, obj, result, vp); + rv = WrapNative(cx, obj, result, PR_TRUE, vp); if (NS_SUCCEEDED(rv)) { rv = NS_SUCCESS_I_DID_SOMETHING; } @@ -9169,7 +9203,7 @@ nsHTMLFormElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper, if (result) { // Wrap result, result can be either an element or a list of // elements - nsresult rv = WrapNative(cx, obj, result, vp); + nsresult rv = WrapNative(cx, obj, result, PR_TRUE, vp); return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING; } } @@ -9181,7 +9215,7 @@ nsHTMLFormElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper, form->GetElementAt(n, getter_AddRefs(control)); if (control) { - nsresult rv = WrapNative(cx, obj, control, vp); + nsresult rv = WrapNative(cx, obj, control, PR_TRUE, vp); return NS_FAILED(rv) ? rv : NS_SUCCESS_I_DID_SOMETHING; } } @@ -9288,7 +9322,7 @@ nsHTMLSelectElementSH::GetProperty(nsIXPConnectWrappedNative *wrapper, options->Item(n, getter_AddRefs(node)); - rv = WrapNative(cx, obj, node, &NS_GET_IID(nsIDOMNode), vp); + rv = WrapNative(cx, obj, node, &NS_GET_IID(nsIDOMNode), PR_TRUE, vp); if (NS_SUCCEEDED(rv)) { rv = NS_SUCCESS_I_DID_SOMETHING; } @@ -10054,7 +10088,7 @@ nsCSSStyleDeclSH::PreCreate(nsISupports *nativeObj, JSContext *cx, } jsval v; - nsresult rv = WrapNative(cx, globalObj, native_parent, &v); + nsresult rv = WrapNative(cx, globalObj, native_parent, PR_FALSE, &v); NS_ENSURE_SUCCESS(rv, rv); *parentObj = JSVAL_TO_OBJECT(v); diff --git a/dom/base/nsDOMClassInfo.h b/dom/base/nsDOMClassInfo.h index 779650ad2c3..16dc5d2c37f 100644 --- a/dom/base/nsDOMClassInfo.h +++ b/dom/base/nsDOMClassInfo.h @@ -134,19 +134,20 @@ public: static nsresult WrapNative(JSContext *cx, JSObject *scope, nsISupports *native, const nsIID* aIID, - jsval *vp, + PRBool aAllowWrapping, jsval *vp, // If non-null aHolder will keep the jsval alive // while there's a ref to it nsIXPConnectJSObjectHolder** aHolder = nsnull); // Same as the WrapNative above, but use this one if aIID is nsISupports' IID. static nsresult WrapNative(JSContext *cx, JSObject *scope, - nsISupports *native, jsval *vp, + nsISupports *native, PRBool aAllowWrapping, + jsval *vp, // If non-null aHolder will keep the jsval alive // while there's a ref to it nsIXPConnectJSObjectHolder** aHolder = nsnull) { - return WrapNative(cx, scope, native, nsnull, vp, aHolder); + return WrapNative(cx, scope, native, nsnull, aAllowWrapping, vp, aHolder); } static nsresult ThrowJSException(JSContext *cx, nsresult aResult); diff --git a/dom/base/nsGlobalWindow.cpp b/dom/base/nsGlobalWindow.cpp index b04068e578d..54eda780437 100644 --- a/dom/base/nsGlobalWindow.cpp +++ b/dom/base/nsGlobalWindow.cpp @@ -6735,12 +6735,6 @@ nsGlobalWindow::DispatchAsyncHashchange() { FORWARD_TO_INNER(DispatchAsyncHashchange, (), NS_OK); - nsIDocument::ReadyState readyState = mDoc->GetReadyStateEnum(); - - // We only queue up the event if the ready state is currently "complete" - if (readyState != nsIDocument::READYSTATE_COMPLETE) - return NS_OK; - nsCOMPtr event = NS_NEW_RUNNABLE_METHOD(nsGlobalWindow, this, FireHashchange); diff --git a/dom/base/nsJSEnvironment.cpp b/dom/base/nsJSEnvironment.cpp index 5e1721e62bd..72ba57e8cc7 100644 --- a/dom/base/nsJSEnvironment.cpp +++ b/dom/base/nsJSEnvironment.cpp @@ -1882,17 +1882,22 @@ AtomToEventHandlerName(nsIAtom *aName) nsresult nsJSContext::JSObjectFromInterface(nsISupports* aTarget, void *aScope, JSObject **aRet) { - if (!aTarget) { // no target specified is ok + // It is legal to specify a null target. + if (!aTarget) { *aRet = nsnull; return NS_OK; } + // Get the jsobject associated with this target + // We don't wrap here because we trust the JS engine to wrap the target + // later. nsresult rv; jsval v; rv = nsContentUtils::XPConnect()->WrapNativeToJSVal(mContext, (JSObject *)aScope, aTarget, &NS_GET_IID(nsISupports), + PR_FALSE, &v, nsnull); NS_ENSURE_SUCCESS(rv, rv); diff --git a/gfx/thebes/public/gfxWindowsFonts.h b/gfx/thebes/public/gfxWindowsFonts.h index 59d9e504353..1d9dc60a06d 100644 --- a/gfx/thebes/public/gfxWindowsFonts.h +++ b/gfx/thebes/public/gfxWindowsFonts.h @@ -339,7 +339,8 @@ public: FontEntry *GetFontEntry(); static already_AddRefed - GetOrMakeFont(FontEntry *aFontEntry, const gfxFontStyle *aStyle); + GetOrMakeFont(FontEntry *aFontEntry, const gfxFontStyle *aStyle, + PRBool aNeedsBold = PR_FALSE); protected: HFONT MakeHFONT(); @@ -402,7 +403,8 @@ public: virtual gfxWindowsFont *GetFontAt(PRInt32 i); - void GroupFamilyListToArrayList(nsTArray > *list); + void GroupFamilyListToArrayList(nsTArray > *list, + nsTArray *aNeedsBold); void FamilyListToArrayList(const nsString& aFamilies, const nsCString& aLangGroup, nsTArray > *list); @@ -429,6 +431,7 @@ private: nsCString mGenericFamily; nsTArray > mFontEntries; + nsTArray mFontNeedsBold; const char *mItemLangGroup; // used by pref-lang handling code diff --git a/gfx/thebes/src/gfxFont.cpp b/gfx/thebes/src/gfxFont.cpp index 001fdd773c0..ffc3953f4d8 100644 --- a/gfx/thebes/src/gfxFont.cpp +++ b/gfx/thebes/src/gfxFont.cpp @@ -130,17 +130,26 @@ gfxFontEntry *gfxFontFamily::FindFontForStyle(const gfxFontStyle& aFontStyle, PR gfxFontEntry *matchFE; const PRInt8 absDistance = abs(weightDistance); direction = (weightDistance >= 0) ? 1 : -1; - PRInt8 i, k; - for (i = matchBaseWeight, k = 0; i < 10 && i > 0; i += direction) { + PRInt8 i, wghtSteps = 0; + + // account for synthetic bold in lighter case + // if lighter is applied with an inherited bold weight, + // and no actual bold faces exist, synthetic bold is used + // so the matched weight above is actually one step down already + if (weightDistance < 0 && baseWeight > 5 && matchBaseWeight < 6) { + wghtSteps = 1; // if no faces [600, 900] then synthetic bold at 700 + } + + for (i = matchBaseWeight; i < 10 && i > 0; i += direction) { if (weightList[i]) { matchFE = weightList[i]; - k++; + wghtSteps++; } - if (k > absDistance) + if (wghtSteps > absDistance) break; } - if (weightDistance > 0 && k <= absDistance) { + if (weightDistance > 0 && wghtSteps <= absDistance) { aNeedsBold = PR_TRUE; } diff --git a/gfx/thebes/src/gfxWindowsFonts.cpp b/gfx/thebes/src/gfxWindowsFonts.cpp index 6ab6f56718c..aec428abc3e 100644 --- a/gfx/thebes/src/gfxWindowsFonts.cpp +++ b/gfx/thebes/src/gfxWindowsFonts.cpp @@ -1101,8 +1101,17 @@ gfxWindowsFont::FillLogFont(gfxFloat aSize) if (fe->mIsUserFont) { if (fe->IsItalic()) isItalic = PR_FALSE; // avoid synthetic italic - if (fe->IsBold()) + if (fe->IsBold()) { weight = 400; // avoid synthetic bold + } else { + // determine whether synthetic bolding is needed + PRInt8 baseWeight, weightDistance; + GetStyle()->ComputeWeightAndOffset(&baseWeight, &weightDistance); + if ((weightDistance == 0 && baseWeight >= 6) + || (weightDistance > 0)) { + weight = 700; // set to get GDI to synthetic bold this face + } + } } FontEntry::FillLogFont(&mLogFont, fe->Name(), fe->mFontType, isItalic, @@ -1207,12 +1216,27 @@ gfxWindowsFont::SetupCairoFont(gfxContext *aContext) * except for OOM in which case we do nothing and return null. */ already_AddRefed -gfxWindowsFont::GetOrMakeFont(FontEntry *aFontEntry, const gfxFontStyle *aStyle) +gfxWindowsFont::GetOrMakeFont(FontEntry *aFontEntry, const gfxFontStyle *aStyle, + PRBool aNeedsBold) { // because we know the FontEntry has the weight we really want, use it for matching // things in the cache so we don't end up with things like 402 in there. gfxFontStyle style(*aStyle); - style.weight = aFontEntry->mWeight; + + if (aFontEntry->mIsUserFont && !aFontEntry->IsBold()) { + // determine whether synthetic bolding is needed + PRInt8 baseWeight, weightDistance; + aStyle->ComputeWeightAndOffset(&baseWeight, &weightDistance); + + if ((weightDistance == 0 && baseWeight >= 6) || (weightDistance > 0 && aNeedsBold)) { + style.weight = 700; // set to get GDI to synthetic bold this face + } else { + style.weight = aFontEntry->mWeight; + } + } else { + style.weight = aFontEntry->mWeight; + } + // also pre-round the size if there is no size adjust if (style.sizeAdjust == 0.0) style.size = ROUND(style.size); @@ -1246,7 +1270,8 @@ AddFontNameToArray(const nsAString& aName, void -gfxWindowsFontGroup::GroupFamilyListToArrayList(nsTArray > *list) +gfxWindowsFontGroup::GroupFamilyListToArrayList(nsTArray > *list, + nsTArray *aNeedsBold) { nsAutoTArray fonts; ForEachFont(AddFontNameToArray, &fonts); @@ -1257,7 +1282,7 @@ gfxWindowsFontGroup::GroupFamilyListToArrayList(nsTArray > * // first, look up in the user font set gfxFontEntry *gfe; - PRBool needsBold; + PRBool needsBold = PR_FALSE; if (mUserFontSet && (gfe = mUserFontSet->FindFontEntry(fonts[i], mStyle, needsBold))) { // assume for now platform font if not SVG fe = static_cast (gfe); @@ -1271,6 +1296,7 @@ gfxWindowsFontGroup::GroupFamilyListToArrayList(nsTArray > * // if found, add to the list if (fe) { list->AppendElement(fe); + aNeedsBold->AppendElement(static_cast(needsBold)); } } } @@ -1314,7 +1340,7 @@ gfxWindowsFontGroup::GetFontAt(PRInt32 i) if (!mFonts[i]) { nsRefPtr font = - gfxWindowsFont::GetOrMakeFont(mFontEntries[i], &mStyle); + gfxWindowsFont::GetOrMakeFont(mFontEntries[i], &mStyle, mFontNeedsBold[i]); mFonts[i] = font; } @@ -1335,6 +1361,7 @@ gfxWindowsFontGroup::UpdateFontList() // xxx - can probably improve this to detect when all fonts were found, so no need to update list mFonts.Clear(); mFontEntries.Clear(); + mFontNeedsBold.Clear(); InitFontList(); mCurrGeneration = GetGeneration(); } @@ -1344,7 +1371,7 @@ gfxWindowsFontGroup::UpdateFontList() void gfxWindowsFontGroup::InitFontList() { - GroupFamilyListToArrayList(&mFontEntries); + GroupFamilyListToArrayList(&mFontEntries, &mFontNeedsBold); mFonts.AppendElements(mFontEntries.Length()); @@ -1352,10 +1379,11 @@ gfxWindowsFontGroup::InitFontList() // we'll surely need them anyway. while (mFontEntries.Length() > 0) { nsRefPtr font = - gfxWindowsFont::GetOrMakeFont(mFontEntries[0], &mStyle); + gfxWindowsFont::GetOrMakeFont(mFontEntries[0], &mStyle, mFontNeedsBold[0]); if (!font->IsValid()) { mFontEntries.RemoveElementAt(0); mFonts.RemoveElementAt(0); + mFontNeedsBold.RemoveElementAt(0); continue; } mFonts[0] = font; @@ -1394,6 +1422,7 @@ gfxWindowsFontGroup::InitFontList() // just report false for all characters, so the fact that the font // is bogus should not cause problems. mFonts.AppendElements(mFontEntries.Length()); + mFontNeedsBold.AppendElements(mFontEntries.Length()); } // force the underline offset to get recalculated @@ -2400,7 +2429,7 @@ gfxWindowsFontGroup::WhichFontSupportsChar(const nsTArray >& continue; if (fe->HasCharacter(ch)) { nsRefPtr font = - gfxWindowsFont::GetOrMakeFont(fe, &mStyle); + gfxWindowsFont::GetOrMakeFont(fe, &mStyle, mFontNeedsBold[i]); // Check that the font is still usable. if (!font->IsValid()) continue; diff --git a/js/jsd/jsd_val.c b/js/jsd/jsd_val.c index 1619de63c15..9e687e098d9 100644 --- a/js/jsd/jsd_val.c +++ b/js/jsd/jsd_val.c @@ -40,6 +40,22 @@ */ #include "jsd.h" +#include "jsapi.h" +#include "jspubtd.h" + +/* + * Lifted with slight modification from jsobj.h + */ + +#define OBJ_TO_OUTER_OBJECT(cx, obj) \ +do { \ + JSClass *clasp_ = JS_GetClass(cx, obj); \ + if (clasp_->flags & JSCLASS_IS_EXTENDED) { \ + JSExtendedClass *xclasp_ = (JSExtendedClass*) clasp_; \ + if (xclasp_->outerObject) \ + obj = xclasp_->outerObject(cx, obj); \ + } \ +} while(0) #ifdef DEBUG void JSD_ASSERT_VALID_VALUE(JSDValue* jsdval) @@ -294,7 +310,23 @@ jsd_DropValue(JSDContext* jsdc, JSDValue* jsdval) jsval jsd_GetValueWrappedJSVal(JSDContext* jsdc, JSDValue* jsdval) { - return jsdval->val; + JSObject* obj; + JSContext* cx; + jsval val = jsdval->val; + if (!JSVAL_IS_PRIMITIVE(val)) { + cx = JSD_GetDefaultJSContext(jsdc); + obj = JSVAL_TO_OBJECT(val); + OBJ_TO_OUTER_OBJECT(cx, obj); + if (!obj) + { + JS_ClearPendingException(cx); + val = JSVAL_NULL; + } + else + val = OBJECT_TO_JSVAL(obj); + } + + return val; } static JSDProperty* _newProperty(JSDContext* jsdc, JSPropertyDesc* pd, diff --git a/js/src/Makefile.in b/js/src/Makefile.in index 6117113e066..c9bcea5b8c1 100644 --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -279,15 +279,6 @@ EXTRA_DSO_LDOPTS += $(call EXPAND_LIBNAME_PATH,jemalloc,$(DIST)/lib) endif endif -# When using gcc the assembly is inlined in the C-file (see jslock.cpp) -ifeq ($(OS_ARCH),SunOS) -ifneq (86,$(findstring 86,$(OS_TEST))) -ifndef GNU_CC -ASFILES = lock_$(OS_ARCH).s -endif -endif -endif - ifndef BUILD_OPT MOCHAFILE = 1 endif @@ -441,15 +432,12 @@ endif ifeq ($(OS_ARCH),SunOS) ifeq ($(TARGET_CPU),sparc) -ifdef JS_ULTRASPARC_OPTS -DEFINES += -DULTRA_SPARC ifdef GNU_CC -CFLAGS += -Wa,-xarch=v8plus,-DULTRA_SPARC,-P,-L,-D_ASM,-D__STDC__=0 -CXXFLAGS += -Wa,-xarch=v8plus,-DULTRA_SPARC,-P,-L,-D_ASM,-D__STDC__=0,-K,PIC +CFLAGS += -mcpu=v9 +CXXFLAGS += -mcpu=v9 else -ASFLAGS += -xarch=v8plus -DULTRA_SPARC -P -L -D_ASM -D__STDC__=0 -K PIC +ASFLAGS += -xarch=v8plus -P -L -D_ASM -D__STDC__=0 -K PIC endif # GNU_CC -endif # JS_ULTRASPARC_OPTS endif ifeq ($(OS_RELEASE),4.1) diff --git a/js/src/configure.in b/js/src/configure.in index 3d72f58e7e9..c5e7e77055f 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -3905,21 +3905,6 @@ dnl = dnl ======================================================== MOZ_ARG_HEADER(Individual module options) -dnl ======================================================== -dnl = Enable Ultrasparc specific optimizations for JS -dnl ======================================================== -MOZ_ARG_ENABLE_BOOL(js-ultrasparc, -[ --enable-js-ultrasparc Use UltraSPARC optimizations in JS], - JS_ULTRASPARC_OPTS=1, - JS_ULTRASPARC_OPTS= ) - -dnl only enable option for ultrasparcs -if test `echo "$target_os" | grep -c \^solaris 2>/dev/null` = 0 -o \ - "$OS_TEST" != "sun4u"; then - JS_ULTRASPARC_OPTS= -fi -AC_SUBST(JS_ULTRASPARC_OPTS) - dnl ======================================================== dnl = dnl = Debugging Options diff --git a/js/src/jslock.cpp b/js/src/jslock.cpp index 722aada3331..e31c15b9ab0 100644 --- a/js/src/jslock.cpp +++ b/js/src/jslock.cpp @@ -59,6 +59,11 @@ #define ReadWord(W) (W) +#if !defined(__GNUC__) +# define __asm__ asm +# define __volatile__ volatile +#endif + /* Implement NativeCompareAndSwap. */ #if defined(_WIN32) && defined(_M_IX86) @@ -97,7 +102,7 @@ NativeCompareAndSwap(jsword *w, jsword ov, jsword nv) return OSAtomicCompareAndSwapPtrBarrier(ov, nv, w); } -#elif defined(__GNUC__) && defined(__i386__) +#elif defined(__i386) && (defined(__GNUC__) || defined(__SUNPRO_CC)) /* Note: This fails on 386 cpus, cmpxchgl is a >= 486 instruction */ static JS_ALWAYS_INLINE int @@ -116,7 +121,8 @@ NativeCompareAndSwap(jsword *w, jsword ov, jsword nv) return (int)res; } -#elif defined(__GNUC__) && defined(__x86_64__) +#elif defined(__x86_64) && (defined(__GNUC__) || defined(__SUNPRO_CC)) + static JS_ALWAYS_INLINE int NativeCompareAndSwap(jsword *w, jsword ov, jsword nv) { @@ -133,30 +139,24 @@ NativeCompareAndSwap(jsword *w, jsword ov, jsword nv) return (int)res; } -#elif defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC) +#elif defined(__sparc) && (defined(__GNUC__) || defined(__SUNPRO_CC)) static JS_ALWAYS_INLINE int NativeCompareAndSwap(jsword *w, jsword ov, jsword nv) { -#if defined(__GNUC__) unsigned int res; - JS_ASSERT(ov != nv); - asm volatile ("\ -stbar\n\ -cas [%1],%2,%3\n\ -cmp %2,%3\n\ -be,a 1f\n\ -mov 1,%0\n\ -mov 0,%0\n\ -1:" + + __asm__ __volatile__ ( + "stbar\n" + "cas [%1],%2,%3\n" + "cmp %2,%3\n" + "be,a 1f\n" + "mov 1,%0\n" + "mov 0,%0\n" + "1:" : "=r" (res) : "r" (w), "r" (ov), "r" (nv)); return (int)res; -#else /* !__GNUC__ */ - extern int compare_and_swap(jsword*, jsword, jsword); - JS_ASSERT(ov != nv); - return compare_and_swap(w, ov, nv); -#endif } #elif defined(AIX) @@ -210,7 +210,7 @@ js_CompareAndSwap(jsword *w, jsword ov, jsword nv) #elif defined(NSPR_LOCK) # ifdef __GNUC__ -# warning "js_CompareAndSwap is implemented using NSSP lock" +# warning "js_CompareAndSwap is implemented using NSPR lock" # endif JSBool diff --git a/js/src/jslock.h b/js/src/jslock.h index e466131861e..76b27a25cd1 100644 --- a/js/src/jslock.h +++ b/js/src/jslock.h @@ -55,9 +55,9 @@ JS_BEGIN_EXTERN_C #ifdef JS_THREADSAFE #if (defined(_WIN32) && defined(_M_IX86)) || \ - (defined(__GNUC__) && defined(__i386__)) || \ - (defined(__GNUC__) && defined(__x86_64__)) || \ - (defined(SOLARIS) && defined(sparc) && defined(ULTRA_SPARC)) || \ + (defined(__i386) && (defined(__GNUC__) || defined(__SUNPRO_CC))) || \ + (defined(__x86_64) && (defined(__GNUC__) || defined(__SUNPRO_CC))) || \ + (defined(__sparc) && (defined(__GNUC__) || defined(__SUNPRO_CC))) || \ defined(AIX) || \ defined(USE_ARM_KUSER) # define JS_HAS_NATIVE_COMPARE_AND_SWAP 1 diff --git a/js/src/jsobj.h b/js/src/jsobj.h index e0aac4b98ca..2b1f44aecb1 100644 --- a/js/src/jsobj.h +++ b/js/src/jsobj.h @@ -141,6 +141,11 @@ struct JSObjectMap { } \ JS_END_MACRO +/* + * The following macro has been copied to jsd/jsd_val.c. If making changes to + * OBJ_TO_OUTER_OBJECT, please update jsd/jsd_val.c as well. + */ + #define OBJ_TO_OUTER_OBJECT(cx,obj) \ JS_BEGIN_MACRO \ JSClass *clasp_ = OBJ_GET_CLASS(cx, obj); \ diff --git a/js/src/jsstr.cpp b/js/src/jsstr.cpp index 7ca142d32e0..e9440dd82c2 100644 --- a/js/src/jsstr.cpp +++ b/js/src/jsstr.cpp @@ -1796,6 +1796,9 @@ js_StringReplaceHelper(JSContext *cx, uintN argc, JSObject *lambda, rdata.lambda = lambda; rdata.repstr = repstr; if (repstr) { + /* We're about to store pointers into the middle of our string. */ + if (!js_MakeStringImmutable(cx, repstr)) + return JS_FALSE; rdata.dollarEnd = repstr->chars() + repstr->length(); rdata.dollar = js_strchr_limit(repstr->chars(), '$', rdata.dollarEnd); diff --git a/js/src/xpconnect/idl/nsIXPConnect.idl b/js/src/xpconnect/idl/nsIXPConnect.idl index 6f46b50ad16..56eddfe0bc6 100644 --- a/js/src/xpconnect/idl/nsIXPConnect.idl +++ b/js/src/xpconnect/idl/nsIXPConnect.idl @@ -394,7 +394,7 @@ interface nsIXPCFunctionThisTranslator : nsISupports { 0xbd, 0xd6, 0x0, 0x0, 0x64, 0x65, 0x73, 0x74 } } %} -[uuid(f01af951-1e28-4499-9692-5a1432246a04)] +[uuid(b76828b8-3ac5-469e-946d-3401c6a2104d)] interface nsIXPConnect : nsISupports { %{ C++ @@ -465,12 +465,15 @@ interface nsIXPConnect : nsISupports * &NS_GET_IID(nsISupports) but when passing in null certain shortcuts * can be taken because we know without comparing IIDs that the caller is * asking for an nsISupports wrapper. + * If aAllowWrapper, then the returned value will be wrapped in the proper + * type of security wrapper on top of the XPCWrappedNative (if needed). */ void wrapNativeToJSVal(in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, in nsIIDPtr aIID, + in boolean aAllowWrapper, out JSVal aVal, out nsIXPConnectJSObjectHolder aHolder); @@ -702,6 +705,16 @@ interface nsIXPConnect : nsISupports in JSObjectPtr aParent, in JSObjectPtr aWrappedObj); + /** + * Wrap a jsval in a chrome object wrapper. + * @param aJSContext A context to use to create objects. + * @param aParent The parent to create the wrapper with. + * @param aWrappedObj The object to wrap. + */ + [noscript] JSVal getCOWForObject(in JSContextPtr aJSContext, + in JSObjectPtr aParent, + in JSObjectPtr aWrappedObj); + /** * Tells updateXOWs to clear the scope of all of the XOWs it finds. */ diff --git a/js/src/xpconnect/shell/xpcshell.cpp b/js/src/xpconnect/shell/xpcshell.cpp index 604fffd84ab..7c7b21a9621 100644 --- a/js/src/xpconnect/shell/xpcshell.cpp +++ b/js/src/xpconnect/shell/xpcshell.cpp @@ -83,6 +83,9 @@ #ifdef XP_WIN #include #endif +#ifdef __SYMBIAN32__ +#include +#endif #ifndef XPCONNECT_STANDALONE #include "nsIScriptSecurityManager.h" @@ -535,7 +538,7 @@ GC(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval) JS_GC(cx); fprintf(gOutFile, "before %lu, after %lu, break %08lx\n", (unsigned long)preBytes, (unsigned long)rt->gcBytes, -#ifdef XP_UNIX +#if defined(XP_UNIX) && !defined(__SYMBIAN32__) (unsigned long)sbrk(0) #else 0 diff --git a/js/src/xpconnect/src/Makefile.in b/js/src/xpconnect/src/Makefile.in index 21d73c029fb..162bd6a5592 100644 --- a/js/src/xpconnect/src/Makefile.in +++ b/js/src/xpconnect/src/Makefile.in @@ -109,6 +109,7 @@ CPPSRCS = \ xpcJSWeakReference.cpp \ XPCSafeJSObjectWrapper.cpp \ XPCCrossOriginWrapper.cpp \ + XPCChromeObjectWrapper.cpp \ XPCSystemOnlyWrapper.cpp \ XPCWrapper.cpp \ xpcquickstubs.cpp \ diff --git a/js/src/xpconnect/src/XPCChromeObjectWrapper.cpp b/js/src/xpconnect/src/XPCChromeObjectWrapper.cpp new file mode 100644 index 00000000000..4b91b149294 --- /dev/null +++ b/js/src/xpconnect/src/XPCChromeObjectWrapper.cpp @@ -0,0 +1,641 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=2 sw=2 et tw=78 sts=2: */ +/* ***** BEGIN LICENSE BLOCK ***** + * Version: MPL 1.1/GPL 2.0/LGPL 2.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is mozilla.org code. + * + * The Initial Developer of the Original Code is + * The Mozilla Foundation. + * Portions created by the Initial Developer are Copyright (C) 2006 + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Blake Kaplan (original author) + * + * Alternatively, the contents of this file may be used under the terms of + * either the GNU General Public License Version 2 or later (the "GPL"), or + * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), + * in which case the provisions of the GPL or the LGPL are applicable instead + * of those above. If you wish to allow use of your version of this file only + * under the terms of either the GPL or the LGPL, and not to allow others to + * use your version of this file under the terms of the MPL, indicate your + * decision by deleting the provisions above and replace them with the notice + * and other provisions required by the GPL or the LGPL. If you do not delete + * the provisions above, a recipient may use your version of this file under + * the terms of any one of the MPL, the GPL or the LGPL. + * + * ***** END LICENSE BLOCK ***** */ + +#include "xpcprivate.h" +#include "nsDOMError.h" +#include "jsdbgapi.h" +#include "jscntxt.h" // For JSAutoTempValueRooter. +#include "jsobj.h" +#include "XPCNativeWrapper.h" +#include "XPCWrapper.h" + +// This file implements a wrapper around trusted objects that allows them to +// be safely injected into untrusted code. + +static JSBool +XPC_COW_AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +static JSBool +XPC_COW_DelProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +static JSBool +XPC_COW_GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +static JSBool +XPC_COW_SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp); + +static JSBool +XPC_COW_Enumerate(JSContext *cx, JSObject *obj); + +static JSBool +XPC_COW_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, + JSObject **objp); + +static JSBool +XPC_COW_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp); + +static JSBool +XPC_COW_CheckAccess(JSContext *cx, JSObject *obj, jsval id, JSAccessMode mode, + jsval *vp); + +static JSBool +XPC_COW_Equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp); + +static JSObject * +XPC_COW_Iterator(JSContext *cx, JSObject *obj, JSBool keysonly); + +static JSObject * +XPC_COW_WrappedObject(JSContext *cx, JSObject *obj); + +JSExtendedClass sXPC_COW_JSClass = { + // JSClass (JSExtendedClass.base) initialization + { "ChromeObjectWrapper", + JSCLASS_NEW_RESOLVE | JSCLASS_IS_EXTENDED | + JSCLASS_HAS_RESERVED_SLOTS(XPCWrapper::sNumSlots), + XPC_COW_AddProperty, XPC_COW_DelProperty, + XPC_COW_GetProperty, XPC_COW_SetProperty, + XPC_COW_Enumerate, (JSResolveOp)XPC_COW_NewResolve, + XPC_COW_Convert, JS_FinalizeStub, + nsnull, XPC_COW_CheckAccess, + nsnull, nsnull, + nsnull, nsnull, + nsnull, nsnull + }, + + // JSExtendedClass initialization + XPC_COW_Equality, + nsnull, // outerObject + nsnull, // innerObject + XPC_COW_Iterator, + XPC_COW_WrappedObject, + JSCLASS_NO_RESERVED_MEMBERS +}; + +static JSBool +XPC_COW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval); + +// Throws an exception on context |cx|. +static inline JSBool +ThrowException(nsresult rv, JSContext *cx) +{ + return XPCWrapper::ThrowException(rv, cx); +} + +// Like GetWrappedObject, but works on other types of wrappers, too. +// See also js_GetWrappedObject in jsobj.h. +// TODO Move to XPCWrapper? +static inline JSObject * +GetWrappedJSObject(JSContext *cx, JSObject *obj) +{ + JSClass *clasp = STOBJ_GET_CLASS(obj); + if (!(clasp->flags & JSCLASS_IS_EXTENDED)) { + return obj; + } + + JSExtendedClass *xclasp = (JSExtendedClass *)clasp; + if (!xclasp->wrappedObject) { + if (XPCNativeWrapper::IsNativeWrapper(obj)) { + XPCWrappedNative *wn = XPCNativeWrapper::SafeGetWrappedNative(obj); + return wn ? wn->GetFlatJSObject() : nsnull; + } + + return obj; + } + + return xclasp->wrappedObject(cx, obj); +} + +// Get the (possibly non-existant) COW off of an object +// TODO Move to XPCWrapper and share with other wrappers. +static inline +JSObject * +GetWrapper(JSObject *obj) +{ + while (STOBJ_GET_CLASS(obj) != &sXPC_COW_JSClass.base) { + obj = STOBJ_GET_PROTO(obj); + if (!obj) { + break; + } + } + + return obj; +} + +// TODO Templatize, move to XPCWrapper and share with other wrappers! +static inline +JSObject * +GetWrappedObject(JSContext *cx, JSObject *wrapper) +{ + return XPCWrapper::UnwrapGeneric(cx, &sXPC_COW_JSClass, wrapper); +} + +// Forward declaration for the function wrapper. +JSBool +XPC_COW_RewrapForChrome(JSContext *cx, JSObject *wrapperObj, jsval *vp); +JSBool +XPC_COW_RewrapForContent(JSContext *cx, JSObject *wrapperObj, jsval *vp); + +// This function wrapper calls a function from untrusted content into chrome. + +static JSBool +XPC_COW_FunctionWrapper(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + JSObject *wrappedObj; + + // Allow 'this' to be either a COW, in which case we unwrap it or something + // that isn't a COW. We disallow invalid COWs that have no wrapped object. + + wrappedObj = GetWrapper(obj); + if (wrappedObj) { + wrappedObj = GetWrappedObject(cx, wrappedObj); + if (!wrappedObj) { + return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); + } + } else { + wrappedObj = obj; + } + + JSObject *funObj = JSVAL_TO_OBJECT(argv[-2]); + jsval funToCall; + if (!JS_GetReservedSlot(cx, funObj, XPCWrapper::eWrappedFunctionSlot, + &funToCall)) { + return JS_FALSE; + } + + for (uintN i = 0; i < argc; ++i) { + if (!XPC_COW_RewrapForChrome(cx, obj, &argv[i])) { + return JS_FALSE; + } + } + + if (!JS_CallFunctionValue(cx, wrappedObj, funToCall, argc, argv, rval)) { + return JS_FALSE; + } + + return XPC_COW_RewrapForContent(cx, obj, rval); +} + +JSBool +XPC_COW_WrapFunction(JSContext *cx, JSObject *outerObj, JSObject *funobj, + jsval *rval) +{ + jsval funobjVal = OBJECT_TO_JSVAL(funobj); + JSFunction *wrappedFun = + reinterpret_cast(xpc_GetJSPrivate(funobj)); + JSNative native = JS_GetFunctionNative(cx, wrappedFun); + if (!native || native == XPC_COW_FunctionWrapper) { + *rval = funobjVal; + return JS_TRUE; + } + + JSFunction *funWrapper = + JS_NewFunction(cx, XPC_COW_FunctionWrapper, + JS_GetFunctionArity(wrappedFun), 0, + JS_GetGlobalForObject(cx, outerObj), + JS_GetFunctionName(wrappedFun)); + if (!funWrapper) { + return JS_FALSE; + } + + JSObject *funWrapperObj = JS_GetFunctionObject(funWrapper); + *rval = OBJECT_TO_JSVAL(funWrapperObj); + + return JS_SetReservedSlot(cx, funWrapperObj, + XPCWrapper::eWrappedFunctionSlot, + funobjVal); +} + +JSBool +XPC_COW_RewrapForChrome(JSContext *cx, JSObject *wrapperObj, jsval *vp) +{ + jsval v = *vp; + if (JSVAL_IS_PRIMITIVE(v)) { + return JS_TRUE; + } + + // We're rewrapping for chrome, so this is safe. + JSObject *obj = GetWrappedJSObject(cx, JSVAL_TO_OBJECT(v)); + if (!obj) { + *vp = JSVAL_NULL; + return JS_TRUE; + } + + XPCWrappedNative *wn; + if (IS_WRAPPER_CLASS(STOBJ_GET_CLASS(obj)) && + (wn = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj))) { + // Return an explicit XPCNativeWrapper in case "chrome" code happens to be + // XBL code cloned into an untrusted context. + return XPCNativeWrapperCtor(cx, obj, 1, vp, vp); + } + + return XPC_SJOW_Construct(cx, obj, 1, vp, vp); +} + +JSBool +XPC_COW_RewrapForContent(JSContext *cx, JSObject *wrapperObj, jsval *vp) +{ + jsval v = *vp; + if (JSVAL_IS_PRIMITIVE(v)) { + return JS_TRUE; + } + + JSObject *obj = GetWrappedJSObject(cx, JSVAL_TO_OBJECT(v)); + if (!obj) { + *vp = JSVAL_NULL; + return JS_TRUE; + } + + if (JS_ObjectIsFunction(cx, obj)) { + return XPC_COW_WrapFunction(cx, wrapperObj, obj, vp); + } + + return XPC_COW_WrapObject(cx, JS_GetScopeChain(cx), OBJECT_TO_JSVAL(obj), + vp); +} + +static JSBool +XPC_COW_AddProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + obj = GetWrapper(obj); + jsval resolving; + if (!JS_GetReservedSlot(cx, obj, XPCWrapper::sFlagsSlot, &resolving)) { + return JS_FALSE; + } + + if (HAS_FLAGS(resolving, FLAG_RESOLVING)) { + // Allow us to define a property on ourselves. + return JS_TRUE; + } + + // Someone's adding a property to us. We need to protect ourselves from + // getters and setters. + JSObject *wrappedObj = GetWrappedObject(cx, obj); + if (!wrappedObj) { + return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); + } + + jsid interned_id; + JSPropertyDescriptor desc; + + if (!JS_ValueToId(cx, id, &interned_id) || + !XPCWrapper::GetPropertyAttrs(cx, obj, interned_id, JSRESOLVE_QUALIFIED, + JS_TRUE, &desc)) { + return JS_FALSE; + } + + NS_ASSERTION(desc.obj == obj, "The JS engine lies!"); + + if (desc.attrs & (JSPROP_GETTER | JSPROP_SETTER)) { + // Only chrome is allowed to add getters or setters to our object. + if (!AllowedToAct(cx, id)) { + return JS_FALSE; + } + } + + return XPC_COW_RewrapForChrome(cx, obj, vp) && + JS_DefinePropertyById(cx, wrappedObj, interned_id, *vp, + desc.getter, desc.setter, desc.attrs); +} + +static JSBool +XPC_COW_DelProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + JSObject *wrappedObj = GetWrappedObject(cx, obj); + if (!wrappedObj) { + return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); + } + + XPCCallContext ccx(JS_CALLER, cx); + if (!ccx.IsValid()) { + return ThrowException(NS_ERROR_FAILURE, cx); + } + + // Deleting a property is safe. + return XPCWrapper::DelProperty(cx, wrappedObj, id, vp); +} + +static JSBool +XPC_COW_GetOrSetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp, + JSBool isSet) +{ + if (id == GetRTStringByIndex(cx, XPCJSRuntime::IDX_TO_STRING)) { + return JS_TRUE; + } + + obj = GetWrapper(obj); + if (!obj) { + return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); + } + + XPCCallContext ccx(JS_CALLER, cx); + if (!ccx.IsValid()) { + return ThrowException(NS_ERROR_FAILURE, cx); + } + + AUTO_MARK_JSVAL(ccx, vp); + + JSObject *wrappedObj = GetWrappedObject(cx, obj); + if (!wrappedObj) { + return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); + } + + if (id == GetRTStringByIndex(cx, XPCJSRuntime::IDX_PROTO) || + id == GetRTStringByIndex(cx, XPCJSRuntime::IDX_PARENT)) { + // No getting or setting __proto__ or __parent__ on my object. + return ThrowException(NS_ERROR_INVALID_ARG, cx); // XXX better error message + } + + if (!XPC_COW_RewrapForChrome(cx, obj, vp)) { + return JS_FALSE; + } + + jsid interned_id; + if (!JS_ValueToId(cx, id, &interned_id)) { + return JS_FALSE; + } + + JSBool ok = isSet + ? JS_SetPropertyById(cx, wrappedObj, interned_id, vp) + : JS_GetPropertyById(cx, wrappedObj, interned_id, vp); + if (!ok) { + return JS_FALSE; + } + + return XPC_COW_RewrapForContent(cx, obj, vp); +} + +static JSBool +XPC_COW_GetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + return XPC_COW_GetOrSetProperty(cx, obj, id, vp, JS_FALSE); +} + +static JSBool +XPC_COW_SetProperty(JSContext *cx, JSObject *obj, jsval id, jsval *vp) +{ + return XPC_COW_GetOrSetProperty(cx, obj, id, vp, JS_TRUE); +} + +static JSBool +XPC_COW_Enumerate(JSContext *cx, JSObject *obj) +{ + obj = GetWrapper(obj); + JSObject *wrappedObj = GetWrappedObject(cx, obj); + if (!wrappedObj) { + // Nothing to enumerate. + return JS_TRUE; + } + + XPCCallContext ccx(JS_CALLER, cx); + if (!ccx.IsValid()) { + return ThrowException(NS_ERROR_FAILURE, cx); + } + + return XPCWrapper::Enumerate(cx, obj, wrappedObj); +} + +static JSBool +XPC_COW_NewResolve(JSContext *cx, JSObject *obj, jsval id, uintN flags, + JSObject **objp) +{ + obj = GetWrapper(obj); + + JSObject *wrappedObj = GetWrappedObject(cx, obj); + if (!wrappedObj) { + // No wrappedObj means that this is probably the prototype. + *objp = nsnull; + return JS_TRUE; + } + + XPCCallContext ccx(JS_CALLER, cx); + if (!ccx.IsValid()) { + return ThrowException(NS_ERROR_FAILURE, cx); + } + + if (id == GetRTStringByIndex(cx, XPCJSRuntime::IDX_TO_STRING)) { + jsval oldSlotVal; + if (!::JS_GetReservedSlot(cx, obj, XPCWrapper::sFlagsSlot, &oldSlotVal) || + !::JS_SetReservedSlot(cx, obj, XPCWrapper::sFlagsSlot, + INT_TO_JSVAL(JSVAL_TO_INT(oldSlotVal) | + FLAG_RESOLVING))) { + return JS_FALSE; + } + + JSBool ok = JS_DefineFunction(cx, obj, "toString", + XPC_COW_toString, 0, 0) != nsnull; + + if (ok && (ok = ::JS_SetReservedSlot(cx, obj, XPCWrapper::sFlagsSlot, + oldSlotVal))) { + *objp = obj; + } + + return ok; + } + + return XPCWrapper::NewResolve(cx, obj, JS_TRUE, wrappedObj, id, flags, objp); +} + +static JSBool +XPC_COW_Convert(JSContext *cx, JSObject *obj, JSType type, jsval *vp) +{ + // Don't do any work to convert to object. + if (type == JSTYPE_OBJECT) { + *vp = OBJECT_TO_JSVAL(obj); + return JS_TRUE; + } + + JSObject *wrappedObj = GetWrappedObject(cx, obj); + if (!wrappedObj) { + // Converting the prototype to something. + + if (type == JSTYPE_STRING || type == JSTYPE_VOID) { + return XPC_COW_toString(cx, obj, 0, nsnull, vp); + } + + *vp = OBJECT_TO_JSVAL(obj); + return JS_TRUE; + } + + XPCCallContext ccx(JS_CALLER, cx); + if (!ccx.IsValid()) { + return ThrowException(NS_ERROR_FAILURE, cx); + } + + if (!STOBJ_GET_CLASS(wrappedObj)->convert(cx, wrappedObj, type, vp)) { + return JS_FALSE; + } + + return XPC_COW_RewrapForContent(cx, obj, vp); +} + +static JSBool +XPC_COW_CheckAccess(JSContext *cx, JSObject *obj, jsval prop, JSAccessMode mode, + jsval *vp) +{ + // Simply forward checkAccess to our wrapped object. It's already expecting + // untrusted things to ask it about accesses. + + uintN junk; + jsid id; + return JS_ValueToId(cx, prop, &id) && + JS_CheckAccess(cx, GetWrappedObject(cx, obj), id, mode, vp, &junk); +} + +static JSBool +XPC_COW_Equality(JSContext *cx, JSObject *obj, jsval v, JSBool *bp) +{ + // Convert both sides to XPCWrappedNative and see if they match. + if (JSVAL_IS_PRIMITIVE(v)) { + *bp = JS_FALSE; + return JS_TRUE; + } + + JSObject *test = GetWrappedJSObject(cx, JSVAL_TO_OBJECT(v)); + + obj = GetWrappedObject(cx, obj); + if (!obj) { + return ThrowException(NS_ERROR_ILLEGAL_VALUE, cx); + } + XPCWrappedNative *other = + XPCWrappedNative::GetWrappedNativeOfJSObject(cx, test); + if (!other) { + *bp = JS_FALSE; + return JS_TRUE; + } + + XPCWrappedNative *me = XPCWrappedNative::GetWrappedNativeOfJSObject(cx, obj); + obj = me->GetFlatJSObject(); + test = other->GetFlatJSObject(); + return ((JSExtendedClass *)STOBJ_GET_CLASS(obj))-> + equality(cx, obj, OBJECT_TO_JSVAL(test), bp); +} + +static JSObject * +XPC_COW_Iterator(JSContext *cx, JSObject *obj, JSBool keysonly) +{ + JSObject *wrappedObj = GetWrappedObject(cx, obj); + if (!wrappedObj) { + ThrowException(NS_ERROR_INVALID_ARG, cx); + return nsnull; + } + + XPCCallContext ccx(JS_CALLER, cx); + if (!ccx.IsValid()) { + ThrowException(NS_ERROR_FAILURE, cx); + return nsnull; + } + + JSObject *wrapperIter = JS_NewObject(cx, &sXPC_COW_JSClass.base, nsnull, + JS_GetGlobalForObject(cx, obj)); + if (!wrapperIter) { + return nsnull; + } + + JSAutoTempValueRooter tvr(cx, OBJECT_TO_JSVAL(wrapperIter)); + + // Initialize our COW. + jsval v = OBJECT_TO_JSVAL(wrappedObj); + if (!JS_SetReservedSlot(cx, wrapperIter, XPCWrapper::sWrappedObjSlot, v) || + !JS_SetReservedSlot(cx, wrapperIter, XPCWrapper::sFlagsSlot, + JSVAL_ZERO)) { + return nsnull; + } + + return XPCWrapper::CreateIteratorObj(cx, wrapperIter, obj, wrappedObj, + keysonly); +} + +static JSObject * +XPC_COW_WrappedObject(JSContext *cx, JSObject *obj) +{ + return GetWrappedObject(cx, obj); +} + +static JSBool +XPC_COW_toString(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, + jsval *rval) +{ + obj = GetWrapper(obj); + if (!obj) { + return ThrowException(NS_ERROR_UNEXPECTED, cx); + } + + JSObject *wrappedObj = GetWrappedObject(cx, obj); + if (!wrappedObj) { + // Someone's calling toString on our prototype. + NS_NAMED_LITERAL_CSTRING(protoString, "[object XPCCrossOriginWrapper]"); + JSString *str = + JS_NewStringCopyN(cx, protoString.get(), protoString.Length()); + if (!str) { + return JS_FALSE; + } + *rval = STRING_TO_JSVAL(str); + return JS_TRUE; + } + + XPCCallContext ccx(JS_CALLER, cx); + if (!ccx.IsValid()) { + return ThrowException(NS_ERROR_FAILURE, cx); + } + + XPCWrappedNative *wn = + XPCWrappedNative::GetWrappedNativeOfJSObject(cx, wrappedObj); + return XPCWrapper::NativeToString(cx, wn, argc, argv, rval, JS_FALSE); +} + +JSBool +XPC_COW_WrapObject(JSContext *cx, JSObject *parent, jsval v, jsval *vp) +{ + JSObject *wrapperObj = + JS_NewObjectWithGivenProto(cx, &sXPC_COW_JSClass.base, NULL, parent); + if (!wrapperObj) { + return JS_FALSE; + } + + *vp = OBJECT_TO_JSVAL(wrapperObj); + if (!JS_SetReservedSlot(cx, wrapperObj, XPCWrapper::sWrappedObjSlot, v) || + !JS_SetReservedSlot(cx, wrapperObj, XPCWrapper::sFlagsSlot, + JSVAL_ZERO)) { + return JS_FALSE; + } + + return JS_TRUE; +} diff --git a/js/src/xpconnect/src/XPCWrapper.cpp b/js/src/xpconnect/src/XPCWrapper.cpp index a0b1761c376..3c2dc5616ed 100644 --- a/js/src/xpconnect/src/XPCWrapper.cpp +++ b/js/src/xpconnect/src/XPCWrapper.cpp @@ -94,6 +94,9 @@ XPCWrapper::Unwrap(JSContext *cx, JSObject *wrapper) if (clasp == &sXPC_SOW_JSClass.base) { return UnwrapSOW(cx, wrapper); } + if (clasp == &sXPC_COW_JSClass.base) { + return UnwrapCOW(cx, wrapper); + } return nsnull; } diff --git a/js/src/xpconnect/src/XPCWrapper.h b/js/src/xpconnect/src/XPCWrapper.h index 64895693ba7..3aa058d96b2 100644 --- a/js/src/xpconnect/src/XPCWrapper.h +++ b/js/src/xpconnect/src/XPCWrapper.h @@ -111,6 +111,7 @@ XPC_XOW_ClassNeedsXOW(const char *name) return JS_FALSE; } +extern JSExtendedClass sXPC_COW_JSClass; extern JSExtendedClass sXPC_SJOW_JSClass; extern JSExtendedClass sXPC_SOW_JSClass; extern JSExtendedClass sXPC_XOW_JSClass; @@ -285,6 +286,21 @@ public: return wrapper; } + static JSObject *UnwrapCOW(JSContext *cx, JSObject *wrapper) { + wrapper = UnwrapGeneric(cx, &sXPC_COW_JSClass, wrapper); + if (!wrapper) { + return nsnull; + } + + nsresult rv = CanAccessWrapper(cx, wrapper); + if (NS_FAILED(rv)) { + JS_ClearPendingException(cx); + wrapper = nsnull; + } + + return wrapper; + } + /** * Rewraps a property if it needs to be rewrapped. Used by * GetOrSetNativeProperty to rewrap the return value. @@ -377,7 +393,6 @@ public: uintN argc, jsval *argv, jsval *rval, JSBool isNativeWrapper); -private: /** * Looks up a property on obj. If it exists, then the parameters are filled * in with useful values. diff --git a/js/src/xpconnect/src/nsXPConnect.cpp b/js/src/xpconnect/src/nsXPConnect.cpp index 3aa3b6a05b5..c09671543cc 100644 --- a/js/src/xpconnect/src/nsXPConnect.cpp +++ b/js/src/xpconnect/src/nsXPConnect.cpp @@ -1198,7 +1198,8 @@ nsXPConnect::WrapNative(JSContext * aJSContext, NS_ASSERTION(aHolder, "bad param"); jsval v; - return WrapNativeToJSVal(aJSContext, aScope, aCOMObj, &aIID, &v, aHolder); + return WrapNativeToJSVal(aJSContext, aScope, aCOMObj, &aIID, PR_FALSE, + &v, aHolder); } /* void wrapNativeToJSVal (in JSContextPtr aJSContext, in JSObjectPtr aScope, in nsISupports aCOMObj, in nsIIDPtr aIID, out JSVal aVal, out nsIXPConnectJSObjectHolder aHolder); */ @@ -1207,6 +1208,7 @@ nsXPConnect::WrapNativeToJSVal(JSContext * aJSContext, JSObject * aScope, nsISupports *aCOMObj, const nsIID * aIID, + PRBool aAllowWrapping, jsval *aVal, nsIXPConnectJSObjectHolder **aHolder) { @@ -1223,7 +1225,7 @@ nsXPConnect::WrapNativeToJSVal(JSContext * aJSContext, nsresult rv; if(!XPCConvert::NativeInterface2JSObject(ccx, aVal, aHolder, aCOMObj, aIID, - nsnull, nsnull, aScope, PR_FALSE, + nsnull, nsnull, aScope, aAllowWrapping, OBJ_IS_NOT_GLOBAL, &rv)) return rv; @@ -2007,6 +2009,17 @@ nsXPConnect::GetXOWForObject(JSContext * aJSContext, ? NS_OK : NS_ERROR_FAILURE; } +NS_IMETHODIMP +nsXPConnect::GetCOWForObject(JSContext * aJSContext, + JSObject * aParent, + JSObject * aWrappedObj, + jsval * rval) +{ + *rval = OBJECT_TO_JSVAL(aWrappedObj); + return XPC_COW_WrapObject(aJSContext, aParent, *rval, rval) + ? NS_OK : NS_ERROR_FAILURE; +} + static inline PRBool PerformOp(JSContext *cx, PRUint32 aWay, JSObject *obj) { diff --git a/js/src/xpconnect/src/xpcconvert.cpp b/js/src/xpconnect/src/xpcconvert.cpp index 5a0b10ff4fd..5a35203611b 100644 --- a/js/src/xpconnect/src/xpcconvert.cpp +++ b/js/src/xpconnect/src/xpcconvert.cpp @@ -1370,14 +1370,15 @@ XPCConvert::NativeInterface2JSObject(XPCCallContext& ccx, CreateHolderIfNeeded(ccx, JSVAL_TO_OBJECT(v), d, dest); } - if(allowNativeWrapper && wrapper->NeedsChromeWrapper()) + *d = v; + if(allowNativeWrapper) { - if(!XPC_SOW_WrapObject(ccx, xpcscope->GetGlobalJSObject(), v, d)) - return JS_FALSE; - } - else - { - *d = v; + if(wrapper->NeedsChromeWrapper()) + if(!XPC_SOW_WrapObject(ccx, xpcscope->GetGlobalJSObject(), v, d)) + return JS_FALSE; + if(wrapper->IsDoubleWrapper()) + if(!XPC_COW_WrapObject(ccx, xpcscope->GetGlobalJSObject(), v, d)) + return JS_FALSE; } if(dest) *dest = strongWrapper.forget().get(); diff --git a/js/src/xpconnect/src/xpcjsruntime.cpp b/js/src/xpconnect/src/xpcjsruntime.cpp index 2ad548d0afe..814e62a2e97 100644 --- a/js/src/xpconnect/src/xpcjsruntime.cpp +++ b/js/src/xpconnect/src/xpcjsruntime.cpp @@ -61,7 +61,8 @@ const char* XPCJSRuntime::mStrings[] = { "createInstance", // IDX_CREATE_INSTANCE "item", // IDX_ITEM "__proto__", // IDX_PROTO - "__iterator__" // IDX_ITERATOR + "__iterator__", // IDX_ITERATOR + "__parent__" // IDX_PARENT #ifdef XPC_IDISPATCH_SUPPORT , "GeckoActiveXObject" // IDX_ACTIVEX_OBJECT , "COMObject" // IDX_COMOBJECT diff --git a/js/src/xpconnect/src/xpcprivate.h b/js/src/xpconnect/src/xpcprivate.h index 7a9638a6504..2ce45487d1b 100644 --- a/js/src/xpconnect/src/xpcprivate.h +++ b/js/src/xpconnect/src/xpcprivate.h @@ -702,6 +702,7 @@ public: IDX_ITEM , IDX_PROTO , IDX_ITERATOR , + IDX_PARENT , #ifdef XPC_IDISPATCH_SUPPORT IDX_ACTIVEX_OBJECT , IDX_COM_OBJECT , @@ -2457,16 +2458,20 @@ public: JSBool HasExternalReference() const {return mRefCnt > 1;} - JSBool NeedsChromeWrapper() { return !!(mWrapper & 1); } - void SetNeedsChromeWrapper() { mWrapper |= 1; } + JSBool NeedsChromeWrapper() { return !!(mWrapperWord & CHROME_ONLY); } + void SetNeedsChromeWrapper() { mWrapperWord |= CHROME_ONLY; } + JSBool IsDoubleWrapper() { return !!(mWrapperWord & DOUBLE_WRAPPER); } + void SetIsDoubleWrapper() { mWrapperWord |= DOUBLE_WRAPPER; } + JSObject* GetWrapper() { - return (JSObject *)(mWrapper & ~1); + return (JSObject *) JSVAL_CLRTAG(mWrapperWord); } void SetWrapper(JSObject *obj) { - JSBool reset = NeedsChromeWrapper(); - mWrapper = PRWord(obj) | reset; + JSBool needsChrome = NeedsChromeWrapper(); + JSBool doubleWrapper = IsDoubleWrapper(); + mWrapperWord = PRWord(obj) | doubleWrapper | needsChrome; } void NoteTearoffs(nsCycleCollectionTraversalCallback& cb); @@ -2502,6 +2507,8 @@ protected: virtual ~XPCWrappedNative(); private: + enum { CHROME_ONLY = JS_BIT(0), DOUBLE_WRAPPER = JS_BIT(1) }; + void TraceOtherWrapper(JSTracer* trc); JSBool Init(XPCCallContext& ccx, JSObject* parent, JSBool isGlobal, const XPCNativeScriptableCreateInfo* sci); @@ -2535,7 +2542,7 @@ private: JSObject* mFlatJSObject; XPCNativeScriptableInfo* mScriptableInfo; XPCWrappedNativeTearOffChunk mFirstChunk; - PRWord mWrapper; + PRWord mWrapperWord; #ifdef XPC_CHECK_WRAPPER_THREADSAFETY public: @@ -4166,6 +4173,9 @@ JSBool XPC_SOW_WrapObject(JSContext *cx, JSObject *parent, jsval v, jsval *vp); +JSBool +XPC_COW_WrapObject(JSContext *cx, JSObject *parent, jsval v, jsval *vp); + #ifdef XPC_IDISPATCH_SUPPORT #ifdef WINCE diff --git a/js/src/xpconnect/src/xpcwrappedjsclass.cpp b/js/src/xpconnect/src/xpcwrappedjsclass.cpp index 4127f516a70..c4843de541f 100644 --- a/js/src/xpconnect/src/xpcwrappedjsclass.cpp +++ b/js/src/xpconnect/src/xpcwrappedjsclass.cpp @@ -248,6 +248,28 @@ nsXPCWrappedJSClass::CallQueryInterfaceOnJSObject(XPCCallContext& ccx, jsid funid; jsval fun; + // Don't call the actual function on a content object. We'll determine + // whether or not a content object is capable of implementing the + // interface (i.e. whether the interface is scriptable) and most content + // objects don't have QI implementations anyway. Also see bug 503926. + if(!STOBJ_IS_SYSTEM(JS_GetGlobalForObject(ccx, jsobj))) + { + nsCOMPtr objprin; + nsIScriptSecurityManager *ssm = XPCWrapper::GetSecurityManager(); + if(ssm) + { + nsresult rv = ssm->GetObjectPrincipal(ccx, jsobj, getter_AddRefs(objprin)); + NS_ENSURE_SUCCESS(rv, nsnull); + + PRBool isSystem; + rv = ssm->IsSystemPrincipal(objprin, &isSystem); + NS_ENSURE_SUCCESS(rv, nsnull); + + if(!isSystem) + return nsnull; + } + } + // check upfront for the existence of the function property funid = mRuntime->GetStringID(XPCJSRuntime::IDX_QUERY_INTERFACE); if(!JS_GetPropertyById(cx, jsobj, funid, &fun) || JSVAL_IS_PRIMITIVE(fun)) diff --git a/js/src/xpconnect/src/xpcwrappednative.cpp b/js/src/xpconnect/src/xpcwrappednative.cpp index 7ebeaf93034..966a4efae13 100644 --- a/js/src/xpconnect/src/xpcwrappednative.cpp +++ b/js/src/xpconnect/src/xpcwrappednative.cpp @@ -429,6 +429,7 @@ XPCWrappedNative::GetNewOrUsed(XPCCallContext& ccx, XPCMarkableJSVal newParentVal_markable(&newParentVal); AutoMarkingJSVal newParentVal_automarker(ccx, &newParentVal_markable); JSBool chromeOnly = JS_FALSE; + JSBool crossDoubleWrapped = JS_FALSE; if(sciWrapper.GetFlags().WantPreCreate()) { @@ -501,6 +502,21 @@ XPCWrappedNative::GetNewOrUsed(XPCCallContext& ccx, return NS_OK; } } + else + { + if(nsXPCWrappedJSClass::IsWrappedJS(Object)) + { + nsCOMPtr wrappedjs(do_QueryInterface(Object)); + JSObject *obj; + wrappedjs->GetJSObject(&obj); + if((STOBJ_IS_SYSTEM(obj) || + STOBJ_IS_SYSTEM(JS_GetGlobalForObject(ccx, obj))) && + !STOBJ_IS_SYSTEM(Scope->GetGlobalJSObject())) + { + crossDoubleWrapped = JS_TRUE; + } + } + } AutoMarkingWrappedNativeProtoPtr proto(ccx); @@ -568,6 +584,8 @@ XPCWrappedNative::GetNewOrUsed(XPCCallContext& ccx, if(chromeOnly) wrapper->SetNeedsChromeWrapper(); + if(crossDoubleWrapped) + wrapper->SetIsDoubleWrapper(); return FinishCreate(ccx, Scope, Interface, cache, wrapper, resultWrapper); } @@ -830,7 +848,7 @@ XPCWrappedNative::XPCWrappedNative(already_AddRefed aIdentity, mSet(aProto->GetSet()), mFlatJSObject((JSObject*)JSVAL_ONE), // non-null to pass IsValid() test mScriptableInfo(nsnull), - mWrapper(nsnull) + mWrapperWord(0) { mIdentity = aIdentity.get(); @@ -849,7 +867,7 @@ XPCWrappedNative::XPCWrappedNative(already_AddRefed aIdentity, mSet(aSet), mFlatJSObject((JSObject*)JSVAL_ONE), // non-null to pass IsValid() test mScriptableInfo(nsnull), - mWrapper(nsnull) + mWrapperWord(0) { mIdentity = aIdentity.get(); diff --git a/js/src/xpconnect/tests/chrome/Makefile.in b/js/src/xpconnect/tests/chrome/Makefile.in index 6ca468c20c2..4e8d2e5f6b6 100644 --- a/js/src/xpconnect/tests/chrome/Makefile.in +++ b/js/src/xpconnect/tests/chrome/Makefile.in @@ -45,6 +45,8 @@ include $(topsrcdir)/config/rules.mk _CHROME_FILES = \ test_bug500931.xul \ + bug503926.xul \ + test_bug503926.xul \ $(NULL) libs:: $(_CHROME_FILES) diff --git a/js/src/xpconnect/tests/chrome/bug503926.xul b/js/src/xpconnect/tests/chrome/bug503926.xul new file mode 100644 index 00000000000..31afa8ab765 --- /dev/null +++ b/js/src/xpconnect/tests/chrome/bug503926.xul @@ -0,0 +1,28 @@ + + + + + + + + Mozilla Bug 503926 + + + + + diff --git a/js/src/xpconnect/tests/chrome/test_bug503926.xul b/js/src/xpconnect/tests/chrome/test_bug503926.xul new file mode 100644 index 00000000000..ee26aab7255 --- /dev/null +++ b/js/src/xpconnect/tests/chrome/test_bug503926.xul @@ -0,0 +1,43 @@ + + + + + + + + + + + Mozilla Bug 503926 + + +