author | Ryan VanderMeulen <ryanvm@gmail.com> |
Tue, 20 Aug 2013 16:33:28 -0400 | |
changeset 143570 | 7e83ba2dfb5154d03ba3071c1f0476cb132b3fff |
parent 143569 | 37e17d2fe8a7de9b9af6e2b031492fee818dc7b6 (current diff) |
parent 143295 | d136c8999d967cb04004373ba80420217e1a8ce4 (diff) |
child 143571 | 6cd2461aa319baac1dee58ab3f67eb23ff3a2721 |
push id | 25130 |
push user | lrocha@mozilla.com |
push date | Wed, 21 Aug 2013 09:41:27 +0000 |
treeherder | mozilla-central@b2486721572e [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 26.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
mobile/android/base/PageActionLayout.java | file | annotate | diff | comparison | revisions | |
mobile/android/chrome/content/browser.js | file | annotate | diff | comparison | revisions | |
toolkit/devtools/apps/tests/Makefile.in | file | annotate | diff | comparison | revisions | |
xpcom/ds/nsByteBuffer.cpp | file | annotate | diff | comparison | revisions | |
xpcom/ds/nsByteBuffer.h | file | annotate | diff | comparison | revisions | |
xpcom/ds/nsIByteBuffer.h | file | annotate | diff | comparison | revisions | |
xpcom/ds/nsIUnicharBuffer.h | file | annotate | diff | comparison | revisions | |
xpcom/ds/nsUnicharBuffer.cpp | file | annotate | diff | comparison | revisions | |
xpcom/ds/nsUnicharBuffer.h | file | annotate | diff | comparison | revisions |
--- a/Makefile.in +++ b/Makefile.in @@ -89,16 +89,19 @@ export:: $(MAKE) -C config export $(MAKE) tier_nspr ifdef ENABLE_TESTS # Additional makefile targets to call automated test suites include $(topsrcdir)/testing/testsuite-targets.mk endif +# Hacky way for precompile tier to bypass default tier traversal mechanism. +TIER_precompile_CUSTOM := 1 + include $(topsrcdir)/config/rules.mk distclean:: cat unallmakefiles | $(XARGS) rm -f $(RM) unallmakefiles $(DIST_GARBAGE) ifeq ($(OS_ARCH),WINNT) # we want to copy PDB files on Windows
--- a/b2g/components/UpdatePrompt.js +++ b/b2g/components/UpdatePrompt.js @@ -504,50 +504,61 @@ UpdatePrompt.prototype = { // nsITimerCallback notify: function UP_notify(aTimer) { if (aTimer == this._applyPromptTimer) { log("Timed out waiting for result, restarting"); this._applyPromptTimer = null; this.finishUpdate(); this._update = null; + return; + } + if (aTimer == this._watchdogTimer) { + log("Download watchdog fired"); + this._watchdogTimer = null; + this._autoRestartDownload = true; + Services.aus.pauseDownload(); + return; } }, createTimer: function UP_createTimer(aTimeoutMs) { let timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); timer.initWithCallback(this, aTimeoutMs, timer.TYPE_ONE_SHOT); return timer; }, // nsIRequestObserver _startedSent: false, _watchdogTimer: null, - _watchdogTimeout: 0, _autoRestartDownload: false, _autoRestartCount: 0, - watchdogTimerFired: function UP_watchdogTimerFired() { - log("Download watchdog fired"); - this._autoRestartDownload = true; - Services.aus.pauseDownload(); - }, - startWatchdogTimer: function UP_startWatchdogTimer() { + let watchdogTimeout = 120000; // 120 seconds + try { + watchdogTimeout = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_TIMEOUT); + } catch (e) { + // This means that the preference doesn't exist. watchdogTimeout will + // retain its default assigned above. + } + if (watchdogTimeout <= 0) { + // 0 implies don't bother using the watchdog timer at all. + this._watchdogTimer = null; + return; + } if (this._watchdogTimer) { this._watchdogTimer.cancel(); } else { this._watchdogTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - this._watchdogTimeout = Services.prefs.getIntPref(PREF_DOWNLOAD_WATCHDOG_TIMEOUT); } - this._watchdogTimer.initWithCallback(this.watchdogTimerFired.bind(this), - this._watchdogTimeout, + this._watchdogTimer.initWithCallback(this, watchdogTimeout, Ci.nsITimer.TYPE_ONE_SHOT); }, stopWatchdogTimer: function UP_stopWatchdogTimer() { if (this._watchdogTimer) { this._watchdogTimer.cancel(); this._watchdogTimer = null; }
--- a/b2g/config/gaia.json +++ b/b2g/config/gaia.json @@ -1,4 +1,4 @@ { - "revision": "f98ec5e292dffd144f0a6520cc18ff5cb7762d09", + "revision": "dbaee540a7d23d271e62e7da80d7db226be8860b", "repo_path": "/integration/gaia-central" }
--- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -331,17 +331,17 @@ pref("browser.download.manager.closeWhen pref("browser.download.manager.focusWhenStarting", false); pref("browser.download.manager.flashCount", 2); pref("browser.download.manager.addToRecentDocs", true); pref("browser.download.manager.quitBehavior", 0); pref("browser.download.manager.scanWhenDone", true); pref("browser.download.manager.resumeOnWakeDelay", 10000); // Enables the asynchronous Downloads API in the Downloads Panel. -pref("browser.download.useJSTransfer", true); +pref("browser.download.useJSTransfer", false); // This allows disabling the Downloads Panel in favor of the old interface. pref("browser.download.useToolkitUI", false); // This allows disabling the animated notifications shown by // the Downloads Indicator when a download starts or completes. pref("browser.download.animateNotifications", true);
--- a/browser/base/content/sanitize.js +++ b/browser/base/content/sanitize.js @@ -82,18 +82,17 @@ Sanitizer.prototype = { // Callers should check returned errors and give user feedback // about items that could not be sanitized let item = this.items[itemName]; try { if (aCanClear) item.clear(); } catch(er) { seenError = true; - Components.utils.reportError("Error sanitizing " + itemName + - ": " + er + "\n"); + Cu.reportError("Error sanitizing " + itemName + ": " + er + "\n"); } onItemComplete(); }; this.canClearItem(itemName, clearCallback); } else { onItemComplete(); } } @@ -317,17 +316,17 @@ Sanitizer.prototype = { download.startTime <= this.range[1]) : null; // Clear all completed/cancelled downloads let publicList = yield Downloads.getPublicDownloadList(); publicList.removeFinished(filterByTime); let privateList = yield Downloads.getPrivateDownloadList(); privateList.removeFinished(filterByTime); - }.bind(this)).then(null, Components.utils.reportError); + }.bind(this)).then(null, Cu.reportError); } else { var dlMgr = Components.classes["@mozilla.org/download-manager;1"] .getService(Components.interfaces.nsIDownloadManager); if (this.range) { // First, remove the completed/cancelled downloads dlMgr.removeDownloadsByTimeframe(this.range[0], this.range[1]);
--- a/browser/base/content/test/browser_sanitize-timespans.js +++ b/browser/base/content/test/browser_sanitize-timespans.js @@ -1,53 +1,39 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); // Bug 453440 - Test the timespan-based logic of the sanitizer code var now_uSec = Date.now() * 1000; +const dm = Cc["@mozilla.org/download-manager;1"].getService(Ci.nsIDownloadManager); + const kUsecPerMin = 60 * 1000000; let tempScope = {}; Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader) .loadSubScript("chrome://browser/content/sanitize.js", tempScope); let Sanitizer = tempScope.Sanitizer; let FormHistory = (Components.utils.import("resource://gre/modules/FormHistory.jsm", {})).FormHistory; -let Downloads = (Components.utils.import("resource://gre/modules/Downloads.jsm", {})).Downloads; function promiseFormHistoryRemoved() { let deferred = Promise.defer(); Services.obs.addObserver(function onfh() { Services.obs.removeObserver(onfh, "satchel-storage-changed", false); deferred.resolve(); }, "satchel-storage-changed", false); return deferred.promise; } -function promiseDownloadRemoved(list) { - let deferred = Promise.defer(); - - let view = { - onDownloadRemoved: function(download) { - list.removeView(view); - deferred.resolve(); - } - }; - - list.addView(view); - - return deferred.promise; -} - function test() { waitForExplicitFinish(); Task.spawn(function() { - yield setupDownloads(); + setupDownloads(); yield setupFormHistory(); yield setupHistory(); yield onHistoryReady(); }).then(finish); } function countEntries(name, message, check) { let deferred = Promise.defer(); @@ -89,26 +75,22 @@ function onHistoryReady() { itemPrefs.setBoolPref("cache", false); itemPrefs.setBoolPref("cookies", false); itemPrefs.setBoolPref("formdata", true); itemPrefs.setBoolPref("offlineApps", false); itemPrefs.setBoolPref("passwords", false); itemPrefs.setBoolPref("sessions", false); itemPrefs.setBoolPref("siteSettings", false); - let publicList = yield Downloads.getPublicDownloadList(); - let downloadPromise = promiseDownloadRemoved(publicList); - // Clear 10 minutes ago s.range = [now_uSec - 10*60*1000000, now_uSec]; s.sanitize(); s.range = null; yield promiseFormHistoryRemoved(); - yield downloadPromise; ok(!(yield promiseIsURIVisited(makeURI("http://10minutes.com"))), "Pretend visit to 10minutes.com should now be deleted"); ok((yield promiseIsURIVisited(makeURI("http://1hour.com"))), "Pretend visit to 1hour.com should should still exist"); ok((yield promiseIsURIVisited(makeURI("http://1hour10minutes.com"))), "Pretend visit to 1hour10minutes.com should should still exist"); ok((yield promiseIsURIVisited(makeURI("http://2hour.com"))), @@ -135,37 +117,33 @@ function onHistoryReady() { yield countEntries("2hour", "2hour form entry should still exist", checkOne); yield countEntries("2hour10minutes", "2hour10minutes form entry should still exist", checkOne); yield countEntries("4hour", "4hour form entry should still exist", checkOne); yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne); if (minutesSinceMidnight > 10) yield countEntries("today", "today form entry should still exist", checkOne); yield countEntries("b4today", "b4today form entry should still exist", checkOne); - let downloads = yield publicList.getAll(); - ok(!(yield downloadExists(publicList, "fakefile-10-minutes")), "10 minute download should now be deleted"); - ok((yield downloadExists(publicList, "fakefile-1-hour")), "<1 hour download should still be present"); - ok((yield downloadExists(publicList, "fakefile-1-hour-10-minutes")), "1 hour 10 minute download should still be present"); - ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present"); - ok((yield downloadExists(publicList, "fakefile-2-hour")), "<2 hour old download should still be present"); - ok((yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "2 hour 10 minute download should still be present"); - ok((yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should still be present"); - ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present"); + ok(!downloadExists(5555555), "10 minute download should now be deleted"); + ok(downloadExists(5555551), "<1 hour download should still be present"); + ok(downloadExists(5555556), "1 hour 10 minute download should still be present"); + ok(downloadExists(5555550), "Year old download should still be present"); + ok(downloadExists(5555552), "<2 hour old download should still be present"); + ok(downloadExists(5555557), "2 hour 10 minute download should still be present"); + ok(downloadExists(5555553), "<4 hour old download should still be present"); + ok(downloadExists(5555558), "4 hour 10 minute download should still be present"); if (minutesSinceMidnight > 10) - ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present"); - - downloadPromise = promiseDownloadRemoved(publicList); + ok(downloadExists(5555554), "'Today' download should still be present"); // Clear 1 hour Sanitizer.prefs.setIntPref("timeSpan", 1); s.sanitize(); yield promiseFormHistoryRemoved(); - yield downloadPromise; ok(!(yield promiseIsURIVisited(makeURI("http://1hour.com"))), "Pretend visit to 1hour.com should now be deleted"); ok((yield promiseIsURIVisited(makeURI("http://1hour10minutes.com"))), "Pretend visit to 1hour10minutes.com should should still exist"); ok((yield promiseIsURIVisited(makeURI("http://2hour.com"))), "Pretend visit to 2hour.com should should still exist"); ok((yield promiseIsURIVisited(makeURI("http://2hour10minutes.com"))), @@ -186,36 +164,33 @@ function onHistoryReady() { yield countEntries("2hour", "2hour form entry should still exist", checkOne); yield countEntries("2hour10minutes", "2hour10minutes form entry should still exist", checkOne); yield countEntries("4hour", "4hour form entry should still exist", checkOne); yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne); if (hoursSinceMidnight > 1) yield countEntries("today", "today form entry should still exist", checkOne); yield countEntries("b4today", "b4today form entry should still exist", checkOne); - ok(!(yield downloadExists(publicList, "fakefile-1-hour")), "<1 hour download should now be deleted"); - ok((yield downloadExists(publicList, "fakefile-1-hour-10-minutes")), "1 hour 10 minute download should still be present"); - ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present"); - ok((yield downloadExists(publicList, "fakefile-2-hour")), "<2 hour old download should still be present"); - ok((yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "2 hour 10 minute download should still be present"); - ok((yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should still be present"); - ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present"); + ok(!downloadExists(5555551), "<1 hour download should now be deleted"); + ok(downloadExists(5555556), "1 hour 10 minute download should still be present"); + ok(downloadExists(5555550), "Year old download should still be present"); + ok(downloadExists(5555552), "<2 hour old download should still be present"); + ok(downloadExists(5555557), "2 hour 10 minute download should still be present"); + ok(downloadExists(5555553), "<4 hour old download should still be present"); + ok(downloadExists(5555558), "4 hour 10 minute download should still be present"); if (hoursSinceMidnight > 1) - ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present"); + ok(downloadExists(5555554), "'Today' download should still be present"); - downloadPromise = promiseDownloadRemoved(publicList); - // Clear 1 hour 10 minutes s.range = [now_uSec - 70*60*1000000, now_uSec]; s.sanitize(); s.range = null; yield promiseFormHistoryRemoved(); - yield downloadPromise; ok(!(yield promiseIsURIVisited(makeURI("http://1hour10minutes.com"))), "Pretend visit to 1hour10minutes.com should now be deleted"); ok((yield promiseIsURIVisited(makeURI("http://2hour.com"))), "Pretend visit to 2hour.com should should still exist"); ok((yield promiseIsURIVisited(makeURI("http://2hour10minutes.com"))), "Pretend visit to 2hour10minutes.com should should still exist"); ok((yield promiseIsURIVisited(makeURI("http://4hour.com"))), @@ -233,33 +208,30 @@ function onHistoryReady() { yield countEntries("2hour", "2hour form entry should still exist", checkOne); yield countEntries("2hour10minutes", "2hour10minutes form entry should still exist", checkOne); yield countEntries("4hour", "4hour form entry should still exist", checkOne); yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne); if (minutesSinceMidnight > 70) yield countEntries("today", "today form entry should still exist", checkOne); yield countEntries("b4today", "b4today form entry should still exist", checkOne); - ok(!(yield downloadExists(publicList, "fakefile-1-hour-10-minutes")), "1 hour 10 minute old download should now be deleted"); - ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present"); - ok((yield downloadExists(publicList, "fakefile-2-hour")), "<2 hour old download should still be present"); - ok((yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "2 hour 10 minute download should still be present"); - ok((yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should still be present"); - ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present"); + ok(!downloadExists(5555556), "1 hour 10 minute old download should now be deleted"); + ok(downloadExists(5555550), "Year old download should still be present"); + ok(downloadExists(5555552), "<2 hour old download should still be present"); + ok(downloadExists(5555557), "2 hour 10 minute download should still be present"); + ok(downloadExists(5555553), "<4 hour old download should still be present"); + ok(downloadExists(5555558), "4 hour 10 minute download should still be present"); if (minutesSinceMidnight > 70) - ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present"); - - downloadPromise = promiseDownloadRemoved(publicList); + ok(downloadExists(5555554), "'Today' download should still be present"); // Clear 2 hours Sanitizer.prefs.setIntPref("timeSpan", 2); s.sanitize(); yield promiseFormHistoryRemoved(); - yield downloadPromise; ok(!(yield promiseIsURIVisited(makeURI("http://2hour.com"))), "Pretend visit to 2hour.com should now be deleted"); ok((yield promiseIsURIVisited(makeURI("http://2hour10minutes.com"))), "Pretend visit to 2hour10minutes.com should should still exist"); ok((yield promiseIsURIVisited(makeURI("http://4hour.com"))), "Pretend visit to 4hour.com should should still exist"); ok((yield promiseIsURIVisited(makeURI("http://4hour10minutes.com"))), @@ -274,33 +246,30 @@ function onHistoryReady() { yield countEntries("2hour", "2hour form entry should be deleted", checkZero); yield countEntries("2hour10minutes", "2hour10minutes form entry should still exist", checkOne); yield countEntries("4hour", "4hour form entry should still exist", checkOne); yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne); if (hoursSinceMidnight > 2) yield countEntries("today", "today form entry should still exist", checkOne); yield countEntries("b4today", "b4today form entry should still exist", checkOne); - ok(!(yield downloadExists(publicList, "fakefile-2-hour")), "<2 hour old download should now be deleted"); - ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present"); - ok((yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "2 hour 10 minute download should still be present"); - ok((yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should still be present"); - ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present"); + ok(!downloadExists(5555552), "<2 hour old download should now be deleted"); + ok(downloadExists(5555550), "Year old download should still be present"); + ok(downloadExists(5555557), "2 hour 10 minute download should still be present"); + ok(downloadExists(5555553), "<4 hour old download should still be present"); + ok(downloadExists(5555558), "4 hour 10 minute download should still be present"); if (hoursSinceMidnight > 2) - ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present"); + ok(downloadExists(5555554), "'Today' download should still be present"); - downloadPromise = promiseDownloadRemoved(publicList); - // Clear 2 hours 10 minutes s.range = [now_uSec - 130*60*1000000, now_uSec]; s.sanitize(); s.range = null; yield promiseFormHistoryRemoved(); - yield downloadPromise; ok(!(yield promiseIsURIVisited(makeURI("http://2hour10minutes.com"))), "Pretend visit to 2hour10minutes.com should now be deleted"); ok((yield promiseIsURIVisited(makeURI("http://4hour.com"))), "Pretend visit to 4hour.com should should still exist"); ok((yield promiseIsURIVisited(makeURI("http://4hour10minutes.com"))), "Pretend visit to 4hour10minutes.com should should still exist"); if (minutesSinceMidnight > 130) { @@ -312,31 +281,28 @@ function onHistoryReady() { yield countEntries("2hour10minutes", "2hour10minutes form entry should be deleted", checkZero); yield countEntries("4hour", "4hour form entry should still exist", checkOne); yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne); if (minutesSinceMidnight > 130) yield countEntries("today", "today form entry should still exist", checkOne); yield countEntries("b4today", "b4today form entry should still exist", checkOne); - ok(!(yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "2 hour 10 minute old download should now be deleted"); - ok((yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should still be present"); - ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present"); - ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present"); + ok(!downloadExists(5555557), "2 hour 10 minute old download should now be deleted"); + ok(downloadExists(5555553), "<4 hour old download should still be present"); + ok(downloadExists(5555558), "4 hour 10 minute download should still be present"); + ok(downloadExists(5555550), "Year old download should still be present"); if (minutesSinceMidnight > 130) - ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present"); - - downloadPromise = promiseDownloadRemoved(publicList); + ok(downloadExists(5555554), "'Today' download should still be present"); // Clear 4 hours Sanitizer.prefs.setIntPref("timeSpan", 3); s.sanitize(); yield promiseFormHistoryRemoved(); - yield downloadPromise; ok(!(yield promiseIsURIVisited(makeURI("http://4hour.com"))), "Pretend visit to 4hour.com should now be deleted"); ok((yield promiseIsURIVisited(makeURI("http://4hour10minutes.com"))), "Pretend visit to 4hour10minutes.com should should still exist"); if (hoursSinceMidnight > 4) { ok((yield promiseIsURIVisited(makeURI("http://today.com"))), "Pretend visit to today.com should still exist"); @@ -345,94 +311,85 @@ function onHistoryReady() { "Pretend visit to before-today.com should still exist"); yield countEntries("4hour", "4hour form entry should be deleted", checkZero); yield countEntries("4hour10minutes", "4hour10minutes form entry should still exist", checkOne); if (hoursSinceMidnight > 4) yield countEntries("today", "today form entry should still exist", checkOne); yield countEntries("b4today", "b4today form entry should still exist", checkOne); - ok(!(yield downloadExists(publicList, "fakefile-4-hour")), "<4 hour old download should now be deleted"); - ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should still be present"); - ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present"); + ok(!downloadExists(5555553), "<4 hour old download should now be deleted"); + ok(downloadExists(5555558), "4 hour 10 minute download should still be present"); + ok(downloadExists(5555550), "Year old download should still be present"); if (hoursSinceMidnight > 4) - ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present"); - - downloadPromise = promiseDownloadRemoved(publicList); + ok(downloadExists(5555554), "'Today' download should still be present"); // Clear 4 hours 10 minutes s.range = [now_uSec - 250*60*1000000, now_uSec]; s.sanitize(); s.range = null; yield promiseFormHistoryRemoved(); - yield downloadPromise; ok(!(yield promiseIsURIVisited(makeURI("http://4hour10minutes.com"))), "Pretend visit to 4hour10minutes.com should now be deleted"); if (minutesSinceMidnight > 250) { ok((yield promiseIsURIVisited(makeURI("http://today.com"))), "Pretend visit to today.com should still exist"); } ok((yield promiseIsURIVisited(makeURI("http://before-today.com"))), "Pretend visit to before-today.com should still exist"); yield countEntries("4hour10minutes", "4hour10minutes form entry should be deleted", checkZero); if (minutesSinceMidnight > 250) yield countEntries("today", "today form entry should still exist", checkOne); yield countEntries("b4today", "b4today form entry should still exist", checkOne); - ok(!(yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "4 hour 10 minute download should now be deleted"); - ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present"); + ok(!downloadExists(5555558), "4 hour 10 minute download should now be deleted"); + ok(downloadExists(5555550), "Year old download should still be present"); if (minutesSinceMidnight > 250) - ok((yield downloadExists(publicList, "fakefile-today")), "'Today' download should still be present"); - - downloadPromise = promiseDownloadRemoved(publicList); + ok(downloadExists(5555554), "'Today' download should still be present"); // Clear Today Sanitizer.prefs.setIntPref("timeSpan", 4); s.sanitize(); yield promiseFormHistoryRemoved(); - yield downloadPromise; // Be careful. If we add our objectss just before midnight, and sanitize // runs immediately after, they won't be expired. This is expected, but // we should not test in that case. We cannot just test for opposite // condition because we could cross midnight just one moment after we // cache our time, then we would have an even worse random failure. var today = isToday(new Date(now_uSec/1000)); if (today) { ok(!(yield promiseIsURIVisited(makeURI("http://today.com"))), "Pretend visit to today.com should now be deleted"); yield countEntries("today", "today form entry should be deleted", checkZero); - ok(!(yield downloadExists(publicList, "fakefile-today")), "'Today' download should now be deleted"); + ok(!downloadExists(5555554), "'Today' download should now be deleted"); } ok((yield promiseIsURIVisited(makeURI("http://before-today.com"))), "Pretend visit to before-today.com should still exist"); yield countEntries("b4today", "b4today form entry should still exist", checkOne); - ok((yield downloadExists(publicList, "fakefile-old")), "Year old download should still be present"); - - downloadPromise = promiseDownloadRemoved(publicList); + ok(downloadExists(5555550), "Year old download should still be present"); // Choose everything Sanitizer.prefs.setIntPref("timeSpan", 0); s.sanitize(); yield promiseFormHistoryRemoved(); - yield downloadPromise; ok(!(yield promiseIsURIVisited(makeURI("http://before-today.com"))), "Pretend visit to before-today.com should now be deleted"); yield countEntries("b4today", "b4today form entry should be deleted", checkZero); - ok(!(yield downloadExists(publicList, "fakefile-old")), "Year old download should now be deleted"); + ok(!downloadExists(5555550), "Year old download should now be deleted"); } function setupHistory() { let deferred = Promise.defer(); let places = []; function addPlace(aURI, aTitle, aVisitDate) { @@ -600,124 +557,254 @@ function setupFormHistory() { yield countEntries("4hour10minutes", "Checking for 4hour10minutes form history entry creation", checkOne); yield countEntries("today", "Checking for today form history entry creation", checkOne); yield countEntries("b4today", "Checking for b4today form history entry creation", checkOne); is(checks, 9, "9 checks made"); } function setupDownloads() { - let publicList = yield Downloads.getPublicDownloadList(); - - let download = yield Downloads.createDownload({ + // Add 10-minutes download to DB + let data = { + id: "5555555", + name: "fakefile-10-minutes", source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169", - target: "fakefile-10-minutes" - }); - download.startTime = new Date(now_uSec - 10 * kUsecPerMin), // 10 minutes ago, in uSec - download.canceled = true; - publicList.add(download); + target: "fakefile-10-minutes", + startTime: now_uSec - 10 * kUsecPerMin, // 10 minutes ago, in uSec + endTime: now_uSec - 11 * kUsecPerMin, // 1 minute later + state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED, + currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0, + guid: "a1bcD23eF4g5" + }; - download = yield Downloads.createDownload({ + let db = dm.DBConnection; + let stmt = db.createStatement( + "INSERT INTO moz_downloads (id, name, source, target, startTime, endTime, " + + "state, currBytes, maxBytes, preferredAction, autoResume, guid) " + + "VALUES (:id, :name, :source, :target, :startTime, :endTime, :state, " + + ":currBytes, :maxBytes, :preferredAction, :autoResume, :guid)"); + try { + for (let prop in data) + stmt.params[prop] = data[prop]; + stmt.execute(); + } + finally { + stmt.reset(); + } + + // Add within-1-hour download to DB + data = { + id: "5555551", + name: "fakefile-1-hour", source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440", - target: "fakefile-1-hour" - }); - download.startTime = new Date(now_uSec - 45 * kUsecPerMin), // 45 minutes ago, in uSec - download.canceled = true; - publicList.add(download); + target: "fakefile-1-hour", + startTime: now_uSec - 45 * kUsecPerMin, // 45 minutes ago, in uSec + endTime: now_uSec - 44 * kUsecPerMin, // 1 minute later + state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED, + currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0, + guid: "1bcD23eF4g5a" + }; - download = yield Downloads.createDownload({ + try { + for (let prop in data) + stmt.params[prop] = data[prop]; + stmt.execute(); + } + finally { + stmt.reset(); + } + + // Add 1-hour-10-minutes download to DB + data = { + id: "5555556", + name: "fakefile-1-hour-10-minutes", source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169", - target: "fakefile-1-hour-10-minutes" - }); - download.startTime = new Date(now_uSec - 70 * kUsecPerMin), // 70 minutes ago, in uSec - download.canceled = true; - publicList.add(download); + target: "fakefile-1-hour-10-minutes", + startTime: now_uSec - 70 * kUsecPerMin, // 70 minutes ago, in uSec + endTime: now_uSec - 71 * kUsecPerMin, // 1 minute later + state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED, + currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0, + guid: "a1cbD23e4Fg5" + }; - download = yield Downloads.createDownload({ + try { + for (let prop in data) + stmt.params[prop] = data[prop]; + stmt.execute(); + } + finally { + stmt.reset(); + } + + // Add within-2-hour download + data = { + id: "5555552", + name: "fakefile-2-hour", source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440", - target: "fakefile-2-hour" - }); - download.startTime = new Date(now_uSec - 90 * kUsecPerMin), // 90 minutes ago, in uSec - download.canceled = true; - publicList.add(download); + target: "fakefile-2-hour", + startTime: now_uSec - 90 * kUsecPerMin, // 90 minutes ago, in uSec + endTime: now_uSec - 89 * kUsecPerMin, // 1 minute later + state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED, + currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0, + guid: "b1aDc23eFg54" + }; - download = yield Downloads.createDownload({ + try { + for (let prop in data) + stmt.params[prop] = data[prop]; + stmt.execute(); + } + finally { + stmt.reset(); + } + + // Add 2-hour-10-minutes download + data = { + id: "5555557", + name: "fakefile-2-hour-10-minutes", source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169", - target: "fakefile-2-hour-10-minutes" - }); - download.startTime = new Date(now_uSec - 130 * kUsecPerMin), // 130 minutes ago, in uSec - download.canceled = true; - publicList.add(download); + target: "fakefile-2-hour-10-minutes", + startTime: now_uSec - 130 * kUsecPerMin, // 130 minutes ago, in uSec + endTime: now_uSec - 131 * kUsecPerMin, // 1 minute later + state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED, + currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0, + guid: "z1bcD23eF4g5" + }; + + try { + for (let prop in data) + stmt.params[prop] = data[prop]; + stmt.execute(); + } + finally { + stmt.reset(); + } - download = yield Downloads.createDownload({ + // Add within-4-hour download + data = { + id: "5555553", + name: "fakefile-4-hour", source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440", - target: "fakefile-4-hour" - }); - download.startTime = new Date(now_uSec - 180 * kUsecPerMin), // 180 minutes ago, in uSec - download.canceled = true; - publicList.add(download); - - download = yield Downloads.createDownload({ + target: "fakefile-4-hour", + startTime: now_uSec - 180 * kUsecPerMin, // 180 minutes ago, in uSec + endTime: now_uSec - 179 * kUsecPerMin, // 1 minute later + state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED, + currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0, + guid: "zzzcD23eF4g5" + }; + + try { + for (let prop in data) + stmt.params[prop] = data[prop]; + stmt.execute(); + } + finally { + stmt.reset(); + } + + // Add 4-hour-10-minutes download + data = { + id: "5555558", + name: "fakefile-4-hour-10-minutes", source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169", - target: "fakefile-4-hour-10-minutes" - }); - download.startTime = new Date(now_uSec - 250 * kUsecPerMin), // 250 minutes ago, in uSec - download.canceled = true; - publicList.add(download); + target: "fakefile-4-hour-10-minutes", + startTime: now_uSec - 250 * kUsecPerMin, // 250 minutes ago, in uSec + endTime: now_uSec - 251 * kUsecPerMin, // 1 minute later + state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED, + currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0, + guid: "z1bzz23eF4gz" + }; + + try { + for (let prop in data) + stmt.params[prop] = data[prop]; + stmt.execute(); + } + finally { + stmt.reset(); + } // Add "today" download let today = new Date(); today.setHours(0); today.setMinutes(0); today.setSeconds(1); - - download = yield Downloads.createDownload({ + + data = { + id: "5555554", + name: "fakefile-today", source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440", - target: "fakefile-today" - }); - download.startTime = new Date(today.getTime() * 1000), // 12:00:30am this morning, in uSec - download.canceled = true; - publicList.add(download); + target: "fakefile-today", + startTime: today.getTime() * 1000, // 12:00:30am this morning, in uSec + endTime: (today.getTime() + 1000) * 1000, // 1 second later + state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED, + currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0, + guid: "ffffD23eF4g5" + }; + + try { + for (let prop in data) + stmt.params[prop] = data[prop]; + stmt.execute(); + } + finally { + stmt.reset(); + } // Add "before today" download let lastYear = new Date(); lastYear.setFullYear(lastYear.getFullYear() - 1); - - download = yield Downloads.createDownload({ + data = { + id: "5555550", + name: "fakefile-old", source: "https://bugzilla.mozilla.org/show_bug.cgi?id=453440", - target: "fakefile-old" - }); - download.startTime = new Date(lastYear.getTime() * 1000), // 1 year ago, in uSec - download.canceled = true; - publicList.add(download); + target: "fakefile-old", + startTime: lastYear.getTime() * 1000, // 1 year ago, in uSec + endTime: (lastYear.getTime() + 1000) * 1000, // 1 second later + state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED, + currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0, + guid: "ggggg23eF4g5" + }; + + try { + for (let prop in data) + stmt.params[prop] = data[prop]; + stmt.execute(); + } + finally { + stmt.finalize(); + } // Confirm everything worked - let downloads = yield publicList.getAll(); - is(downloads.length, 9, "9 Pretend downloads added"); - - ok((yield downloadExists(publicList, "fakefile-old")), "Pretend download for everything case should exist"); - ok((yield downloadExists(publicList, "fakefile-10-minutes")), "Pretend download for 10-minutes case should exist"); - ok((yield downloadExists(publicList, "fakefile-1-hour")), "Pretend download for 1-hour case should exist"); - ok((yield downloadExists(publicList, "fakefile-1-hour-10-minutes")), "Pretend download for 1-hour-10-minutes case should exist"); - ok((yield downloadExists(publicList, "fakefile-2-hour")), "Pretend download for 2-hour case should exist"); - ok((yield downloadExists(publicList, "fakefile-2-hour-10-minutes")), "Pretend download for 2-hour-10-minutes case should exist"); - ok((yield downloadExists(publicList, "fakefile-4-hour")), "Pretend download for 4-hour case should exist"); - ok((yield downloadExists(publicList, "fakefile-4-hour-10-minutes")), "Pretend download for 4-hour-10-minutes case should exist"); - ok((yield downloadExists(publicList, "fakefile-today")), "Pretend download for Today case should exist"); + ok(downloadExists(5555550), "Pretend download for everything case should exist"); + ok(downloadExists(5555555), "Pretend download for 10-minutes case should exist"); + ok(downloadExists(5555551), "Pretend download for 1-hour case should exist"); + ok(downloadExists(5555556), "Pretend download for 1-hour-10-minutes case should exist"); + ok(downloadExists(5555552), "Pretend download for 2-hour case should exist"); + ok(downloadExists(5555557), "Pretend download for 2-hour-10-minutes case should exist"); + ok(downloadExists(5555553), "Pretend download for 4-hour case should exist"); + ok(downloadExists(5555558), "Pretend download for 4-hour-10-minutes case should exist"); + ok(downloadExists(5555554), "Pretend download for Today case should exist"); } /** * Checks to see if the downloads with the specified id exists. * * @param aID * The ids of the downloads to check. */ -function downloadExists(list, path) +function downloadExists(aID) { - return Task.spawn(function() { - let listArray = yield list.getAll(); - throw new Task.Result(listArray.some(i => i.target.path == path)); - }); + let db = dm.DBConnection; + let stmt = db.createStatement( + "SELECT * " + + "FROM moz_downloads " + + "WHERE id = :id" + ); + stmt.params.id = aID; + var rows = stmt.executeStep(); + stmt.finalize(); + return rows; } function isToday(aDate) { return aDate.getDate() == new Date().getDate(); }
--- a/browser/base/content/test/browser_sanitizeDialog.js +++ b/browser/base/content/test/browser_sanitizeDialog.js @@ -16,27 +16,28 @@ * Some of this code, especially the history creation parts, was taken from * browser/base/content/test/browser_sanitize-timespans.js. */ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "FormHistory", "resource://gre/modules/FormHistory.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Downloads", - "resource://gre/modules/Downloads.jsm"); let tempScope = {}; Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader) .loadSubScript("chrome://browser/content/sanitize.js", tempScope); let Sanitizer = tempScope.Sanitizer; +const dm = Cc["@mozilla.org/download-manager;1"]. + getService(Ci.nsIDownloadManager); + const kUsecPerMin = 60 * 1000000; -let formEntries, downloadIDs, olderDownloadIDs; +let formEntries; // Add tests here. Each is a function that's called by doNextTest(). var gAllTests = [ /** * Initializes the dialog to its default state. */ function () { @@ -86,33 +87,16 @@ var gAllTests = [ yield promiseHistoryClearedState(uris, false); yield blankSlate(); yield promiseHistoryClearedState(uris, true); }; wh.open(); }); }, - function () { - // Add downloads (within the past hour). - Task.spawn(function () { - downloadIDs = []; - for (let i = 0; i < 5; i++) { - yield addDownloadWithMinutesAgo(downloadIDs, i); - } - // Add downloads (over an hour ago). - olderDownloadIDs = []; - for (let i = 0; i < 5; i++) { - yield addDownloadWithMinutesAgo(olderDownloadIDs, 61 + i); - } - - doNextTest(); - }).then(null, Components.utils.reportError); - }, - /** * Ensures that the combined history-downloads checkbox clears both history * visits and downloads when checked; the dialog respects simple timespan. */ function () { // Add history (within the past hour). let uris = []; let places = []; @@ -126,16 +110,26 @@ var gAllTests = [ let olderURIs = []; for (let i = 0; i < 5; i++) { pURI = makeURI("http://" + (61 + i) + "-minutes-ago.com/"); places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(61 + i)}); olderURIs.push(pURI); } addVisits(places, function() { + // Add downloads (within the past hour). + let downloadIDs = []; + for (let i = 0; i < 5; i++) { + downloadIDs.push(addDownloadWithMinutesAgo(i)); + } + // Add downloads (over an hour ago). + let olderDownloadIDs = []; + for (let i = 0; i < 5; i++) { + olderDownloadIDs.push(addDownloadWithMinutesAgo(61 + i)); + } let totalHistoryVisits = uris.length + olderURIs.length; let wh = new WindowHelper(); wh.onload = function () { this.selectDuration(Sanitizer.TIMESPAN_HOUR); this.checkPrefCheckbox("history", true); this.acceptDialog(); @@ -147,26 +141,26 @@ var gAllTests = [ "history checkbox checked"); boolPrefIs("cpd.downloads", true, "downloads pref should be true after accepting dialog with " + "history checkbox checked"); }; wh.onunload = function () { // History visits and downloads within one hour should be cleared. yield promiseHistoryClearedState(uris, true); - yield ensureDownloadsClearedState(downloadIDs, true); + ensureDownloadsClearedState(downloadIDs, true); // Visits and downloads > 1 hour should still exist. yield promiseHistoryClearedState(olderURIs, false); - yield ensureDownloadsClearedState(olderDownloadIDs, false); + ensureDownloadsClearedState(olderDownloadIDs, false); // OK, done, cleanup after ourselves. yield blankSlate(); yield promiseHistoryClearedState(olderURIs, true); - yield ensureDownloadsClearedState(olderDownloadIDs, true); + ensureDownloadsClearedState(olderDownloadIDs, true); }; wh.open(); }); }, /** * Add form history entries for the next test. */ @@ -179,44 +173,37 @@ var gAllTests = [ yield undefined; } doNextTest(); }(); iter.next(); }, - function () { - // Add downloads (within the past hour). - Task.spawn(function () { - downloadIDs = []; - for (let i = 0; i < 5; i++) { - yield addDownloadWithMinutesAgo(downloadIDs, i); - } - - doNextTest(); - }).then(null, Components.utils.reportError); - }, - /** * Ensures that the combined history-downloads checkbox removes neither * history visits nor downloads when not checked. */ function () { // Add history, downloads, form entries (within the past hour). let uris = []; let places = []; let pURI; for (let i = 0; i < 5; i++) { pURI = makeURI("http://" + i + "-minutes-ago.com/"); places.push({uri: pURI, visitDate: visitTimeForMinutesAgo(i)}); uris.push(pURI); } addVisits(places, function() { + let downloadIDs = []; + for (let i = 0; i < 5; i++) { + downloadIDs.push(addDownloadWithMinutesAgo(i)); + } + let wh = new WindowHelper(); wh.onload = function () { is(this.isWarningPanelVisible(), false, "Warning panel should be hidden after previously accepting dialog " + "with a predefined timespan"); this.selectDuration(Sanitizer.TIMESPAN_HOUR); // Remove only form entries, leave history (including downloads). @@ -232,27 +219,27 @@ var gAllTests = [ "history checkbox unchecked"); boolPrefIs("cpd.downloads", false, "downloads pref should be false after accepting dialog with " + "history checkbox unchecked"); }; wh.onunload = function () { // Of the three only form entries should be cleared. yield promiseHistoryClearedState(uris, false); - yield ensureDownloadsClearedState(downloadIDs, false); + ensureDownloadsClearedState(downloadIDs, false); formEntries.forEach(function (entry) { let exists = yield formNameExists(entry); is(exists, false, "form entry " + entry + " should no longer exist"); }); // OK, done, cleanup after ourselves. yield blankSlate(); yield promiseHistoryClearedState(uris, true); - yield ensureDownloadsClearedState(downloadIDs, true); + ensureDownloadsClearedState(downloadIDs, true); }; wh.open(); }); }, /** * Ensures that the "Everything" duration option works. */ @@ -647,16 +634,20 @@ var gAllTests = [ var pm = Cc["@mozilla.org/permissionmanager;1"] .getService(Ci.nsIPermissionManager); is(pm.testPermissionFromPrincipal(principal, "offline-app"), 0, "offline-app permissions removed"); }; wh.open(); } ]; +// Used as the download database ID for a new download. Incremented for each +// new download. See addDownloadWithMinutesAgo(). +var gDownloadId = 5555551; + // Index in gAllTests of the test currently being run. Incremented for each // test run. See doNextTest(). var gCurrTest = 0; var now_uSec = Date.now() * 1000; /////////////////////////////////////////////////////////////////////////////// @@ -851,17 +842,17 @@ WindowHelper.prototype = { executeSoon(function () { // Some exceptions that reach here don't reach the test harness, but // ok()/is() do... try { if (wh.onunload) { Task.spawn(wh.onunload).then(function() { waitForAsyncUpdates(doNextTest); - }).then(null, Components.utils.reportError); + }); } else { waitForAsyncUpdates(doNextTest); } } catch (exc) { win.close(); ok(false, "Unexpected exception: " + exc + "\n" + exc.stack); finish(); @@ -904,33 +895,50 @@ WindowHelper.prototype = { }; /** * Adds a download to history. * * @param aMinutesAgo * The download will be downloaded this many minutes ago */ -function addDownloadWithMinutesAgo(aExpectedPathList, aMinutesAgo) { - let publicList = yield Downloads.getPublicDownloadList(); - +function addDownloadWithMinutesAgo(aMinutesAgo) { let name = "fakefile-" + aMinutesAgo + "-minutes-ago"; - let download = yield Downloads.createDownload({ - source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169", - target: name - }); - download.startTime = now_uSec - (aMinutesAgo * kUsecPerMin); - download.canceled = true; - publicList.add(download); + let data = { + id: gDownloadId, + name: name, + source: "https://bugzilla.mozilla.org/show_bug.cgi?id=480169", + target: name, + startTime: now_uSec - (aMinutesAgo * kUsecPerMin), + endTime: now_uSec - ((aMinutesAgo + 1) * kUsecPerMin), + state: Ci.nsIDownloadManager.DOWNLOAD_FINISHED, + currBytes: 0, maxBytes: -1, preferredAction: 0, autoResume: 0 + }; - ok((yield downloadExists(name)), - "Sanity check: download " + name + + let db = dm.DBConnection; + let stmt = db.createStatement( + "INSERT INTO moz_downloads (id, name, source, target, startTime, endTime, " + + "state, currBytes, maxBytes, preferredAction, autoResume) " + + "VALUES (:id, :name, :source, :target, :startTime, :endTime, :state, " + + ":currBytes, :maxBytes, :preferredAction, :autoResume)"); + try { + for (let prop in data) { + stmt.params[prop] = data[prop]; + } + stmt.execute(); + } + finally { + stmt.reset(); + } + + is(downloadExists(gDownloadId), true, + "Sanity check: download " + gDownloadId + " should exist after creating it"); - aExpectedPathList.push(name); + return gDownloadId++; } /** * Adds a form entry to history. * * @param aMinutesAgo * The entry will be added this many minutes ago */ @@ -971,47 +979,25 @@ function formNameExists(name) return deferred.promise; } /** * Removes all history visits, downloads, and form entries. */ function blankSlate() { PlacesUtils.bhistory.removeAllPages(); - - // The promise is resolved only when removing both downloads and form history are done. - let deferred = Promise.defer(); - let formHistoryDone = false, downloadsDone = false; + dm.cleanUp(); - Task.spawn(function deleteAllDownloads() { - let publicList = yield Downloads.getPublicDownloadList(); - let downloads = yield publicList.getAll(); - for (let download of downloads) { - publicList.remove(download); - yield download.finalize(true); - } - downloadsDone = true; - if (formHistoryDone) { - deferred.resolve(); - } - }).then(null, Components.utils.reportError); - + let deferred = Promise.defer(); FormHistory.update({ op: "remove" }, { handleError: function (error) { do_throw("Error occurred updating form history: " + error); deferred.reject(error); }, - handleCompletion: function (reason) { - if (!reason) { - formHistoryDone = true; - if (downloadsDone) { - deferred.resolve(); - } - } - } + handleCompletion: function (reason) { if (!reason) deferred.resolve(); } }); return deferred.promise; } /** * Ensures that the given pref is the expected value. * * @param aPrefName @@ -1021,29 +1007,34 @@ function blankSlate() { * @param aMsg * Passed to is() */ function boolPrefIs(aPrefName, aExpectedVal, aMsg) { is(gPrefService.getBoolPref("privacy." + aPrefName), aExpectedVal, aMsg); } /** - * Checks to see if the download with the specified path exists. + * Checks to see if the download with the specified ID exists. * - * @param aPath - * The path of the download to check + * @param aID + * The ID of the download to check * @return True if the download exists, false otherwise */ -function downloadExists(aPath) +function downloadExists(aID) { - return Task.spawn(function() { - let publicList = yield Downloads.getPublicDownloadList(); - let listArray = yield publicList.getAll(); - throw new Task.Result(listArray.some(i => i.target.path == aPath)); - }); + let db = dm.DBConnection; + let stmt = db.createStatement( + "SELECT * " + + "FROM moz_downloads " + + "WHERE id = :id" + ); + stmt.params.id = aID; + let rows = stmt.executeStep(); + stmt.finalize(); + return !!rows; } /** * Runs the next test in the gAllTests array. If all tests have been run, * finishes the entire suite. */ function doNextTest() { if (gAllTests.length <= gCurrTest) { @@ -1063,17 +1054,17 @@ function doNextTest() { * @param aDownloadIDs * Array of download database IDs * @param aShouldBeCleared * True if each download should be cleared, false otherwise */ function ensureDownloadsClearedState(aDownloadIDs, aShouldBeCleared) { let niceStr = aShouldBeCleared ? "no longer" : "still"; aDownloadIDs.forEach(function (id) { - is((yield downloadExists(id)), !aShouldBeCleared, + is(downloadExists(id), !aShouldBeCleared, "download " + id + " should " + niceStr + " exist"); }); } /** * Ensures that the given pref is the expected value. * * @param aPrefName
--- a/browser/base/content/test/browser_tabopen_reflows.js +++ b/browser/base/content/test/browser_tabopen_reflows.js @@ -44,17 +44,21 @@ const EXPECTED_REFLOWS = [ // SessionStore.getWindowDimensions() "ssi_getWindowDimension@resource:///modules/sessionstore/SessionStore.jsm|" + "@resource:///modules/sessionstore/SessionStore.jsm|" + "ssi_updateWindowFeatures@resource:///modules/sessionstore/SessionStore.jsm|" + "ssi_collectWindowData@resource:///modules/sessionstore/SessionStore.jsm|", // tabPreviews.capture() "tabPreviews_capture@chrome://browser/content/browser.js|" + - "tabPreviews_handleEvent/<@chrome://browser/content/browser.js|" + "tabPreviews_handleEvent/<@chrome://browser/content/browser.js|", + + // tabPreviews.capture() + "tabPreviews_capture@chrome://browser/content/browser.js|" + + "@chrome://browser/content/browser.js|" ]; const PREF_PRELOAD = "browser.newtab.preload"; /* * This test ensures that there are no unexpected * uninterruptible reflows when opening new tabs. */
--- a/browser/components/downloads/test/browser/browser_basic_functionality.js +++ b/browser/components/downloads/test/browser/browser_basic_functionality.js @@ -2,53 +2,61 @@ /* vim: set ts=2 et sw=2 tw=80: */ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ /** * Make sure the downloads panel can display items in the right order and * contains the expected data. */ -function test_task() +function gen_test() { // Display one of each download state. const DownloadData = [ - { state: nsIDM.DOWNLOAD_NOTSTARTED }, - { state: nsIDM.DOWNLOAD_PAUSED }, - { state: nsIDM.DOWNLOAD_FINISHED }, - { state: nsIDM.DOWNLOAD_FAILED }, - { state: nsIDM.DOWNLOAD_CANCELED }, + { endTime: 1180493839859239, state: nsIDM.DOWNLOAD_NOTSTARTED }, + { endTime: 1180493839859238, state: nsIDM.DOWNLOAD_DOWNLOADING }, + { endTime: 1180493839859237, state: nsIDM.DOWNLOAD_PAUSED }, + { endTime: 1180493839859236, state: nsIDM.DOWNLOAD_SCANNING }, + { endTime: 1180493839859235, state: nsIDM.DOWNLOAD_QUEUED }, + { endTime: 1180493839859234, state: nsIDM.DOWNLOAD_FINISHED }, + { endTime: 1180493839859233, state: nsIDM.DOWNLOAD_FAILED }, + { endTime: 1180493839859232, state: nsIDM.DOWNLOAD_CANCELED }, + { endTime: 1180493839859231, state: nsIDM.DOWNLOAD_BLOCKED_PARENTAL }, + { endTime: 1180493839859230, state: nsIDM.DOWNLOAD_DIRTY }, + { endTime: 1180493839859229, state: nsIDM.DOWNLOAD_BLOCKED_POLICY }, ]; + // For testing purposes, show all the download items at once. + var originalCountLimit = DownloadsView.kItemCountLimit; + DownloadsView.kItemCountLimit = DownloadData.length; + registerCleanupFunction(function () { + DownloadsView.kItemCountLimit = originalCountLimit; + }); + try { // Ensure that state is reset in case previous tests didn't finish. - yield task_resetState(); - - // For testing purposes, show all the download items at once. - var originalCountLimit = DownloadsView.kItemCountLimit; - DownloadsView.kItemCountLimit = DownloadData.length; - registerCleanupFunction(function () { - DownloadsView.kItemCountLimit = originalCountLimit; - }); + for (let yy in gen_resetState(DownloadsCommon.getData(window))) yield undefined; // Populate the downloads database with the data required by this test. - yield task_addDownloads(DownloadData); + for (let yy in gen_addDownloadRows(DownloadData)) yield undefined; // Open the user interface and wait for data to be fully loaded. - yield task_openPanel(); + for (let yy in gen_openPanel(DownloadsCommon.getData(window))) yield undefined; // Test item data and count. This also tests the ordering of the display. let richlistbox = document.getElementById("downloadsListBox"); /* disabled for failing intermittently (bug 767828) is(richlistbox.children.length, DownloadData.length, "There is the correct number of richlistitems"); */ - let itemCount = richlistbox.children.length; - for (let i = 0; i < itemCount; i++) { - let element = richlistbox.children[itemCount - i - 1]; + for (let i = 0; i < richlistbox.children.length; i++) { + let element = richlistbox.children[i]; let dataItem = new DownloadsViewItemController(element).dataItem; + is(dataItem.target, DownloadData[i].name, "Download names match up"); is(dataItem.state, DownloadData[i].state, "Download states match up"); + is(dataItem.file, DownloadData[i].target, "Download targets match up"); + is(dataItem.uri, DownloadData[i].source, "Download sources match up"); } } finally { // Clean up when the test finishes. - yield task_resetState(); + for (let yy in gen_resetState(DownloadsCommon.getData(window))) yield undefined; } }
--- a/browser/components/downloads/test/browser/browser_first_download_panel.js +++ b/browser/components/downloads/test/browser/browser_first_download_panel.js @@ -3,51 +3,54 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ /** * Make sure the downloads panel only opens automatically on the first * download it notices. All subsequent downloads, even across sessions, should * not open the panel automatically. */ -function test_task() +function gen_test() { try { // Ensure that state is reset in case previous tests didn't finish. - yield task_resetState(); + for (let yy in gen_resetState(DownloadsCommon.getData(window))) yield undefined; - // With this set to false, we should automatically open the panel the first - // time a download is started. + // With this set to false, we should automatically open the panel + // the first time a download is started. DownloadsCommon.getData(window).panelHasShownBefore = false; - let promise = promisePanelOpened(); + prepareForPanelOpen(); DownloadsCommon.getData(window)._notifyDownloadEvent("start"); - yield promise; + yield undefined; // If we got here, that means the panel opened. DownloadsPanel.hidePanel(); ok(DownloadsCommon.getData(window).panelHasShownBefore, "Should have recorded that the panel was opened on a download.") - // Next, make sure that if we start another download, we don't open the - // panel automatically. - let originalOnPopupShown = DownloadsPanel.onPopupShown; - DownloadsPanel.onPopupShown = function () { - originalOnPopupShown.apply(this, arguments); - ok(false, "Should not have opened the downloads panel."); - }; - - try { - DownloadsCommon.getData(window)._notifyDownloadEvent("start"); - - // Wait 2 seconds to ensure that the panel does not open. - let deferTimeout = Promise.defer(); - setTimeout(deferTimeout.resolve, 2000); - yield deferTimeout.promise; - } finally { - DownloadsPanel.onPopupShown = originalOnPopupShown; - } + // Next, make sure that if we start another download, we don't open + // the panel automatically. + panelShouldNotOpen(); + DownloadsCommon.getData(window)._notifyDownloadEvent("start"); + yield waitFor(2); + } catch(e) { + ok(false, e); } finally { // Clean up when the test finishes. - yield task_resetState(); + for (let yy in gen_resetState(DownloadsCommon.getData(window))) yield undefined; } } + +/** + * Call this to record a test failure for the next time the downloads panel + * opens. + */ +function panelShouldNotOpen() +{ + // Hook to wait until the test data has been loaded. + let originalOnViewLoadCompleted = DownloadsPanel.onViewLoadCompleted; + DownloadsPanel.onViewLoadCompleted = function () { + DownloadsPanel.onViewLoadCompleted = originalOnViewLoadCompleted; + ok(false, "Should not have opened the downloads panel."); + }; +}
--- a/browser/components/downloads/test/browser/head.js +++ b/browser/components/downloads/test/browser/head.js @@ -5,108 +5,270 @@ /** * Provides infrastructure for automated download components tests. */ //////////////////////////////////////////////////////////////////////////////// //// Globals -XPCOMUtils.defineLazyModuleGetter(this, "Downloads", - "resource://gre/modules/Downloads.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", + "resource://gre/modules/FileUtils.jsm"); XPCOMUtils.defineLazyModuleGetter(this, "DownloadsCommon", "resource:///modules/DownloadsCommon.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", - "resource://gre/modules/FileUtils.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Promise", - "resource://gre/modules/Promise.jsm"); -XPCOMUtils.defineLazyModuleGetter(this, "Task", - "resource://gre/modules/Task.jsm"); const nsIDM = Ci.nsIDownloadManager; let gTestTargetFile = FileUtils.getFile("TmpD", ["dm-ui-test.file"]); gTestTargetFile.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, FileUtils.PERMS_FILE); registerCleanupFunction(function () { gTestTargetFile.remove(false); }); +/** + * This objects contains a property for each column in the downloads table. + */ +let gDownloadRowTemplate = { + name: "test-download.txt", + source: "http://www.example.com/test-download.txt", + target: NetUtil.newURI(gTestTargetFile).spec, + startTime: 1180493839859230, + endTime: 1180493839859234, + state: nsIDM.DOWNLOAD_FINISHED, + currBytes: 0, + maxBytes: -1, + preferredAction: 0, + autoResume: 0 +}; + //////////////////////////////////////////////////////////////////////////////// //// Infrastructure +// All test are run through the test runner. function test() { - waitForExplicitFinish(); - Task.spawn(test_task).then(null, ex => ok(false, ex)).then(finish); -} - -//////////////////////////////////////////////////////////////////////////////// -//// Asynchronous support subroutines - -function promiseFocus() -{ - let deferred = Promise.defer(); - waitForFocus(deferred.resolve); - return deferred.promise; + testRunner.runTest(this.gen_test); } -function promisePanelOpened() -{ - let deferred = Promise.defer(); +/** + * Runs a browser-chrome test defined through a generator function. + * + * This object is a singleton, initialized automatically when this script is + * included. Every browser-chrome test file includes a new copy of this object. + */ +var testRunner = { + _testIterator: null, + _lastEventResult: undefined, + _testRunning: false, + _eventRaised: false, + + // --- Main test runner --- - // Hook to wait until the panel is shown. - let originalOnPopupShown = DownloadsPanel.onPopupShown; - DownloadsPanel.onPopupShown = function () { - DownloadsPanel.onPopupShown = originalOnPopupShown; - originalOnPopupShown.apply(this, arguments); + /** + * Runs the test described by the provided generator function asynchronously. + * + * Calling yield in the generator will cause it to wait until continueTest is + * called. The parameter provided to continueTest will be the return value of + * the yield operator. + * + * @param aGenerator + * Test generator function. The function will be called with no + * arguments to retrieve its iterator. + */ + runTest: function TR_runTest(aGenerator) { + waitForExplicitFinish(); + testRunner._testIterator = aGenerator(); + testRunner.continueTest(); + }, + + /** + * Continues the currently running test. + * + * @param aEventResult + * This will be the return value of the yield operator in the test. + */ + continueTest: function TR_continueTest(aEventResult) { + // Store the last event result, or set it to undefined. + testRunner._lastEventResult = aEventResult; + + // Never reenter the main loop, but notify that the event has been raised. + if (testRunner._testRunning) { + testRunner._eventRaised = true; + return; + } - // Defer to the next tick of the event loop so that we don't continue - // processing during the DOM event handler itself. - setTimeout(deferred.resolve, 0); - }; + // Enter the main iteration loop. + testRunner._testRunning = true; + try { + do { + // Call the iterator, but don't leave the loop if the expected event is + // raised during the execution of the generator. + testRunner._eventRaised = false; + testRunner._testIterator.send(testRunner._lastEventResult); + } while (testRunner._eventRaised); + } + catch (e) { + // This block catches exceptions raised by the generator, including the + // normal StopIteration exception. Unexpected exceptions are reported as + // test failures. + if (!(e instanceof StopIteration)) + ok(false, e); + // In any case, stop the tests in this file. + finish(); + } - return deferred.promise; -} + // Wait for the next event or finish. + testRunner._testRunning = false; + } +}; + +//////////////////////////////////////////////////////////////////////////////// +//// Asynchronous generator-based support subroutines -function task_resetState() +// +// The following functions are all generators that can be used inside the main +// test generator to perform specific tasks asynchronously. To invoke these +// subroutines correctly, an iteration syntax should be used: +// +// for (let yy in gen_example("Parameter")) yield undefined; +// + +function gen_resetState(aData) { - // Remove all downloads. - let publicList = yield Downloads.getPublicDownloadList(); - let downloads = yield publicList.getAll(); - for (let download of downloads) { - publicList.remove(download); - yield download.finalize(true); + let statement = Services.downloads.DBConnection.createAsyncStatement( + "DELETE FROM moz_downloads"); + try { + statement.executeAsync({ + handleResult: function(aResultSet) { }, + handleError: function(aError) + { + Cu.reportError(aError); + }, + handleCompletion: function(aReason) + { + testRunner.continueTest(); + } + }); + yield undefined; + } finally { + statement.finalize(); } // Reset any prefs that might have been changed. Services.prefs.clearUserPref("browser.download.panel.shown"); + // Ensure that the panel is closed and data is unloaded. + aData.clear(); + aData._loadState = aData.kLoadNone; DownloadsPanel.hidePanel(); - yield promiseFocus(); + // Wait for focus on the main window. + waitForFocus(testRunner.continueTest); + yield undefined; } -function task_addDownloads(aItems) +function gen_addDownloadRows(aDataRows) { - let startTimeMs = Date.now(); + let columnNames = Object.keys(gDownloadRowTemplate).join(", "); + let parameterNames = Object.keys(gDownloadRowTemplate) + .map(function(n) ":" + n) + .join(", "); + let statement = Services.downloads.DBConnection.createAsyncStatement( + "INSERT INTO moz_downloads (" + columnNames + + ", guid) VALUES(" + parameterNames + ", GENERATE_GUID())"); + try { + // Execute the statement for each of the provided downloads in reverse. + for (let i = aDataRows.length - 1; i >= 0; i--) { + let dataRow = aDataRows[i]; - let publicList = yield Downloads.getPublicDownloadList(); - for (let item of aItems) { - publicList.add(yield Downloads.createDownload({ - source: "http://www.example.com/test-download.txt", - target: gTestTargetFile, - succeeded: item.state == nsIDM.DOWNLOAD_FINISHED, - canceled: item.state == nsIDM.DOWNLOAD_CANCELED || - item.state == nsIDM.DOWNLOAD_PAUSED, - error: item.state == nsIDM.DOWNLOAD_FAILED ? new Error("Failed.") : null, - hasPartialData: item.state == nsIDM.DOWNLOAD_PAUSED, - startTime: new Date(startTimeMs++), - })); + // Populate insert parameters from the provided data. + for (let columnName in gDownloadRowTemplate) { + if (!(columnName in dataRow)) { + // Update the provided row object with data from the global template, + // for columns whose value is not provided explicitly. + dataRow[columnName] = gDownloadRowTemplate[columnName]; + } + statement.params[columnName] = dataRow[columnName]; + } + + // Run the statement asynchronously and wait. + statement.executeAsync({ + handleResult: function(aResultSet) { }, + handleError: function(aError) + { + Cu.reportError(aError.message + " (Result = " + aError.result + ")"); + }, + handleCompletion: function(aReason) + { + testRunner.continueTest(); + } + }); + yield undefined; + + // At each iteration, ensure that the start and end time in the global + // template is distinct, as these column are used to sort each download + // in its category. + gDownloadRowTemplate.startTime++; + gDownloadRowTemplate.endTime++; + } + } finally { + statement.finalize(); } } -function task_openPanel() +function gen_openPanel(aData) { - yield promiseFocus(); + // Hook to wait until the test data has been loaded. + let originalOnViewLoadCompleted = DownloadsPanel.onViewLoadCompleted; + DownloadsPanel.onViewLoadCompleted = function () { + DownloadsPanel.onViewLoadCompleted = originalOnViewLoadCompleted; + originalOnViewLoadCompleted.apply(this); + testRunner.continueTest(); + }; + + // Start loading all the downloads from the database asynchronously. + aData.ensurePersistentDataLoaded(false); + + // Wait for focus on the main window. + waitForFocus(testRunner.continueTest); + yield undefined; + + // Open the downloads panel, waiting until loading is completed. + DownloadsPanel.showPanel(); + yield undefined; +} - let promise = promisePanelOpened(); - DownloadsPanel.showPanel(); - yield promise; +/** + * Spin the event loop for aSeconds seconds, and then signal the test to + * continue. + * + * @param aSeconds the number of seconds to wait. + * @note This helper should _only_ be used when there's no valid event to + * listen to and one can't be made. + */ +function waitFor(aSeconds) +{ + setTimeout(function() { + testRunner.continueTest(); + }, aSeconds * 1000); } + +/** + * Make it so that the next time the downloads panel opens, we signal to + * continue the test. This function needs to be called each time you want + * to wait for the panel to open. + * + * Example usage: + * + * prepareForPanelOpen(); + * // Do something to open the panel + * yield undefined; + * // We can assume the panel is open now. + */ +function prepareForPanelOpen() +{ + // Hook to wait until the test data has been loaded. + let originalOnPopupShown = DownloadsPanel.onPopupShown; + DownloadsPanel.onPopupShown = function (aEvent) { + DownloadsPanel.onPopupShown = originalOnPopupShown; + DownloadsPanel.onPopupShown.apply(this, [aEvent]); + testRunner.continueTest(); + }; +}
--- a/browser/components/sessionstore/src/SessionStore.jsm +++ b/browser/components/sessionstore/src/SessionStore.jsm @@ -72,16 +72,19 @@ const MESSAGES = [ ]; // These are tab events that we listen to. const TAB_EVENTS = [ "TabOpen", "TabClose", "TabSelect", "TabShow", "TabHide", "TabPinned", "TabUnpinned" ]; +// The number of milliseconds in a day +const MS_PER_DAY = 1000.0 * 60.0 * 60.0 * 24.0; + #ifndef XP_WIN #define BROKEN_WM_Z_ORDER #endif Cu.import("resource://gre/modules/Services.jsm", this); Cu.import("resource://gre/modules/XPCOMUtils.jsm", this); // debug.js adds NS_ASSERT. cf. bug 669196 Cu.import("resource://gre/modules/debug.js", this); @@ -459,20 +462,18 @@ let SessionStoreInternal = { } else if (this._hasSingleTabWithURL(state.windows, "about:welcomeback")) { // On a single about:welcomeback URL that crashed, replace about:welcomeback // with about:sessionrestore, to make clear to the user that we crashed. state.windows[0].tabs[0].entries[0].url = "about:sessionrestore"; } } - // Load the session start time from the previous state - this._sessionStartTime = state.session && - state.session.startTime || - this._sessionStartTime; + // Update the session start time using the restored session state. + this._updateSessionStartTime(state); // make sure that at least the first window doesn't have anything hidden delete state.windows[0].hidden; // Since nothing is hidden in the first window, it cannot be a popup delete state.windows[0].isPopup; // We don't want to minimize and then open a window at startup. if (state.windows[0].sizemode == "minimized") state.windows[0].sizemode = "normal"; @@ -1796,19 +1797,19 @@ let SessionStoreInternal = { if (lastSessionState.scratchpads) { ScratchpadManager.restoreSession(lastSessionState.scratchpads); } // Set data that persists between sessions this._recentCrashes = lastSessionState.session && lastSessionState.session.recentCrashes || 0; - this._sessionStartTime = lastSessionState.session && - lastSessionState.session.startTime || - this._sessionStartTime; + + // Update the session start time using the restored session state. + this._updateSessionStartTime(lastSessionState); this._lastSessionState = null; }, /** * See if aWindow is usable for use when restoring a previous session via * restoreLastSession. If usable, prepare it for use. * @@ -3631,16 +3632,38 @@ let SessionStoreInternal = { } SessionSaver.runDelayed(); }, /* ........ Auxiliary Functions .............. */ /** + * Update the session start time and send a telemetry measurement + * for the number of days elapsed since the session was started. + * + * @param state + * The session state. + */ + _updateSessionStartTime: function ssi_updateSessionStartTime(state) { + // Attempt to load the session start time from the session state + if (state.session && state.session.startTime) { + this._sessionStartTime = state.session.startTime; + + // ms to days + let sessionLength = (Date.now() - this._sessionStartTime) / MS_PER_DAY; + + if (sessionLength > 0) { + // Submit the session length telemetry measurement + Services.telemetry.getHistogramById("FX_SESSION_RESTORE_SESSION_LENGTH").add(sessionLength); + } + } + }, + + /** * call a callback for all currently opened browser windows * (might miss the most recent one) * @param aFunc * Callback each window is passed to */ _forEachBrowserWindow: function ssi_forEachBrowserWindow(aFunc) { var windowsEnum = Services.wm.getEnumerator("navigator:browser");
--- a/browser/devtools/markupview/markup-view.js +++ b/browser/devtools/markupview/markup-view.js @@ -1214,90 +1214,111 @@ ElementEditor.prototype = { } } }, _startModifyingAttributes: function() { return this.node.startModifyingAttributes(); }, - _createAttribute: function EE_createAttribute(aAttr, aBefore) + _createAttribute: function EE_createAttribute(aAttr, aBefore = null) { - if (this.attrs.hasOwnProperty(aAttr.name)) { - var attr = this.attrs[aAttr.name]; - var name = attr.querySelector(".attrname"); - var val = attr.querySelector(".attrvalue"); - } else { - // Create the template editor, which will save some variables here. - let data = { - attrName: aAttr.name, - }; - this.template("attribute", data); - var {attr, inner, name, val} = data; + // Create the template editor, which will save some variables here. + let data = { + attrName: aAttr.name, + }; + this.template("attribute", data); + var {attr, inner, name, val} = data; - // Figure out where we should place the attribute. - let before = aBefore || null; - if (aAttr.name == "id") { - before = this.attrList.firstChild; - } else if (aAttr.name == "class") { - let idNode = this.attrs["id"]; - before = idNode ? idNode.nextSibling : this.attrList.firstChild; - } - this.attrList.insertBefore(attr, before); + // Double quotes need to be handled specially to prevent DOMParser failing. + // name="v"a"l"u"e" when editing -> name='v"a"l"u"e"' + // name="v'a"l'u"e" when editing -> name="v'a"l'u"e" + let editValueDisplayed = aAttr.value; + let hasDoubleQuote = editValueDisplayed.contains('"'); + let hasSingleQuote = editValueDisplayed.contains("'"); + let initial = aAttr.name + '="' + editValueDisplayed + '"'; + + // Can't just wrap value with ' since the value contains both " and '. + if (hasDoubleQuote && hasSingleQuote) { + editValueDisplayed = editValueDisplayed.replace(/\"/g, """); + initial = aAttr.name + '="' + editValueDisplayed + '"'; + } + + // Wrap with ' since there are no single quotes in the attribute value. + if (hasDoubleQuote && !hasSingleQuote) { + initial = aAttr.name + "='" + editValueDisplayed + "'"; + } - // Make the attribute editable. - editableField({ - element: inner, - trigger: "dblclick", - stopOnReturn: true, - selectAll: false, - contentType: InplaceEditor.CONTENT_TYPES.CSS_MIXED, - popup: this.markup.popup, - start: (aEditor, aEvent) => { - // If the editing was started inside the name or value areas, - // select accordingly. - if (aEvent && aEvent.target === name) { - aEditor.input.setSelectionRange(0, name.textContent.length); - } else if (aEvent && aEvent.target === val) { - let length = val.textContent.length; - let editorLength = aEditor.input.value.length; - let start = editorLength - (length + 1); - aEditor.input.setSelectionRange(start, start + length); - } else { - aEditor.input.select(); - } - }, - done: (aVal, aCommit) => { - if (!aCommit) { - return; - } + // Make the attribute editable. + editableField({ + element: inner, + trigger: "dblclick", + stopOnReturn: true, + selectAll: false, + initial: initial, + contentType: InplaceEditor.CONTENT_TYPES.CSS_MIXED, + popup: this.markup.popup, + start: (aEditor, aEvent) => { + // If the editing was started inside the name or value areas, + // select accordingly. + if (aEvent && aEvent.target === name) { + aEditor.input.setSelectionRange(0, name.textContent.length); + } else if (aEvent && aEvent.target === val) { + let length = editValueDisplayed.length; + let editorLength = aEditor.input.value.length; + let start = editorLength - (length + 1); + aEditor.input.setSelectionRange(start, start + length); + } else { + aEditor.input.select(); + } + }, + done: (aVal, aCommit) => { + if (!aCommit) { + return; + } + + let doMods = this._startModifyingAttributes(); + let undoMods = this._startModifyingAttributes(); - let doMods = this._startModifyingAttributes(); - let undoMods = this._startModifyingAttributes(); + // Remove the attribute stored in this editor and re-add any attributes + // parsed out of the input element. Restore original attribute if + // parsing fails. + try { + this._saveAttribute(aAttr.name, undoMods); + doMods.removeAttribute(aAttr.name); + this._applyAttributes(aVal, attr, doMods, undoMods); + this.undo.do(() => { + doMods.apply(); + }, () => { + undoMods.apply(); + }) + } catch(ex) { + console.error(ex); + } + } + }); - // Remove the attribute stored in this editor and re-add any attributes - // parsed out of the input element. Restore original attribute if - // parsing fails. - try { - this._saveAttribute(aAttr.name, undoMods); - doMods.removeAttribute(aAttr.name); - this._applyAttributes(aVal, attr, doMods, undoMods); - this.undo.do(() => { - doMods.apply(); - }, () => { - undoMods.apply(); - }) - } catch(ex) { - console.error(ex); - } - } - }); - this.attrs[aAttr.name] = attr; + // Figure out where we should place the attribute. + let before = aBefore; + if (aAttr.name == "id") { + before = this.attrList.firstChild; + } else if (aAttr.name == "class") { + let idNode = this.attrs["id"]; + before = idNode ? idNode.nextSibling : this.attrList.firstChild; } + this.attrList.insertBefore(attr, before); + + // Remove the old version of this attribute from the DOM. + let oldAttr = this.attrs[aAttr.name]; + if (oldAttr && oldAttr.parentNode) { + oldAttr.parentNode.removeChild(oldAttr); + } + + this.attrs[aAttr.name] = attr; name.textContent = aAttr.name; val.textContent = aAttr.value; return attr; }, /**
--- a/browser/devtools/markupview/test/browser_inspector_markup_edit.html +++ b/browser/devtools/markupview/test/browser_inspector_markup_edit.html @@ -35,10 +35,12 @@ </div> <div id="node22" class="unchanged"></div> <div id="node23"></div> <div id="node24"></div> <div id="retag-me"> <div id="retag-me-2"></div> </div> <div id="node25"></div> + <div id="node26" style='background-image: url("moz-page-thumb://thumbnail?url=http%3A%2F%2Fwww.mozilla.org%2F");'></div> + <div id="node27" class="Double " and single '"></div> </body> </html>
--- a/browser/devtools/markupview/test/browser_inspector_markup_edit.js +++ b/browser/devtools/markupview/test/browser_inspector_markup_edit.js @@ -234,16 +234,89 @@ function test() { }, after: function() { assertAttributes(doc.querySelector("#node25"), { id: "node25", src: "somefile.html?param1=<a>¶m2=\xfc¶m3='\"'" }); } }, + + { + desc: "Modify inline style containing \"", + before: function() { + assertAttributes(doc.querySelector("#node26"), { + id: "node26", + style: 'background-image: url("moz-page-thumb://thumbnail?url=http%3A%2F%2Fwww.mozilla.org%2F");' + }); + }, + execute: function(after) { + inspector.once("markupmutation", after); + let editor = getContainerForRawNode(markup, doc.querySelector("#node26")).editor; + let attr = editor.attrs["style"].querySelector(".editable"); + + + attr.focus(); + EventUtils.sendKey("return", inspector.panelWin); + + let input = inplaceEditor(attr).input; + let value = input.value; + + is (value, + "style='background-image: url(\"moz-page-thumb://thumbnail?url=http%3A%2F%2Fwww.mozilla.org%2F\");'", + "Value contains actual double quotes" + ); + + value = value.replace(/mozilla\.org/, "mozilla.com"); + input.value = value; + + EventUtils.sendKey("return", inspector.panelWin); + }, + after: function() { + assertAttributes(doc.querySelector("#node26"), { + id: "node26", + style: 'background-image: url("moz-page-thumb://thumbnail?url=http%3A%2F%2Fwww.mozilla.com%2F");' + }); + } + }, + + { + desc: "Modify inline style containing \" and \'", + before: function() { + assertAttributes(doc.querySelector("#node27"), { + id: "node27", + class: 'Double " and single \'' + }); + }, + execute: function(after) { + inspector.once("markupmutation", after); + let editor = getContainerForRawNode(markup, doc.querySelector("#node27")).editor; + let attr = editor.attrs["class"].querySelector(".editable"); + + attr.focus(); + EventUtils.sendKey("return", inspector.panelWin); + + let input = inplaceEditor(attr).input; + let value = input.value; + + is (value, "class=\"Double " and single '\"", "Value contains ""); + + value = value.replace(/Double/, """).replace(/single/, "'"); + input.value = value; + + EventUtils.sendKey("return", inspector.panelWin); + }, + after: function() { + assertAttributes(doc.querySelector("#node27"), { + id: "node27", + class: '" " and \' \'' + }); + } + }, + { desc: "Add an attribute value without closing \"", enteredText: 'style="display: block;', expectedAttributes: { style: "display: block;" } }, {
--- a/browser/devtools/responsivedesign/responsivedesign.jsm +++ b/browser/devtools/responsivedesign/responsivedesign.jsm @@ -682,16 +682,17 @@ ResponsiveUI.prototype = { this.saveCustomSize(); delete this._resizing; if (this.transitionsEnabled) { this.stack.removeAttribute("notransition"); } this.ignoreY = false; + this.ignoreX = false; this.isResizing = false; }, /** * Store the custom size as a pref. */ saveCustomSize: function RUI_saveCustomSize() { Services.prefs.setIntPref("devtools.responsiveUI.customWidth", this.customPreset.width);
--- a/browser/devtools/styleinspector/test/browser_ruleview_inherit.js +++ b/browser/devtools/styleinspector/test/browser_ruleview_inherit.js @@ -37,17 +37,17 @@ function simpleInherit(aInspector, aRule ok(!!inheritRule.inherited, "Rule should consider itself inherited."); is(inheritRule.textProps.length, 1, "Should only display one inherited style"); let inheritProp = inheritRule.textProps[0]; is(inheritProp.name, "color", "color should have been inherited."); styleNode.parentNode.removeChild(styleNode); emptyInherit(); - }).then(null, console.error); + }); } function emptyInherit() { // No inheritable styles, this rule shouldn't show up. let style = '' + '#test2 {' + ' background-color: green;' + @@ -63,17 +63,17 @@ function emptyInherit() is(elementStyle.rules.length, 1, "Should have 1 rule."); let elementRule = elementStyle.rules[0]; ok(!elementRule.inherited, "Element style attribute should not consider itself inherited."); styleNode.parentNode.removeChild(styleNode); elementStyleInherit(); - }).then(null, console.error); + }); } function elementStyleInherit() { doc.body.innerHTML = '<div id="test2" style="color: red"><div id="test1">Styled Node</div></div>'; inspector.selection.setNode(doc.getElementById("test1")); inspector.once("inspector-updated", () => { @@ -87,17 +87,17 @@ function elementStyleInherit() let inheritRule = elementStyle.rules[1]; is(inheritRule.domRule.type, ELEMENT_STYLE, "Inherited rule should be an element style, not a rule."); ok(!!inheritRule.inherited, "Rule should consider itself inherited."); is(inheritRule.textProps.length, 1, "Should only display one inherited style"); let inheritProp = inheritRule.textProps[0]; is(inheritProp.name, "color", "color should have been inherited."); finishTest(); - }).then(null, console.error); + }); } function finishTest() { doc = null; gBrowser.removeCurrentTab(); finish(); }
--- a/browser/devtools/styleinspector/test/browser_styleinspector_bug_672744_search_filter.js +++ b/browser/devtools/styleinspector/test/browser_styleinspector_bug_672744_search_filter.js @@ -32,17 +32,17 @@ function SI_inspectNode() var span = doc.querySelector("#matches"); ok(span, "captain, we have the matches span"); inspector.selection.setNode(span); inspector.once("inspector-updated", () => { is(span, computedView.viewedElement.rawNode(), "style inspector node matches the selected node"); SI_toggleDefaultStyles(); - }).then(null, (err) => console.error(err)); + }); } function SI_toggleDefaultStyles() { info("checking \"Browser styles\" checkbox"); let doc = computedView.styleDocument; let checkbox = doc.querySelector(".includebrowserstyles");
--- a/browser/locales/en-US/chrome/browser/devtools/webConsole.dtd +++ b/browser/locales/en-US/chrome/browser/devtools/webConsole.dtd @@ -55,17 +55,17 @@ <!ENTITY btnPageCSS.label "CSS"> <!ENTITY btnPageCSS.tooltip "Log CSS parsing errors"> <!ENTITY btnPageCSS.accesskey "C"> <!ENTITY btnPageJS.label "JS"> <!ENTITY btnPageJS.tooltip "Log JavaScript exceptions"> <!ENTITY btnPageJS.accesskey "J"> <!ENTITY btnPageSecurity.label "Security"> <!ENTITY btnPageSecurity.tooltip "Log security errors and warnings"> -<!ENTITY btnPageSecurity.accesskey "S"> +<!ENTITY btnPageSecurity.accesskey "u"> <!-- LOCALIZATION NOTE (btnPageLogging): This is used as the text of the - the toolbar. It shows or hides messages that the web developer inserted on - the page for debugging purposes, using calls such console.log() and - console.error(). --> <!ENTITY btnPageLogging.label "Logging"> <!ENTITY btnPageLogging.tooltip "Log messages sent to the window.console object"> <!ENTITY btnPageLogging.accesskey2 "R">
--- a/browser/themes/shared/devtools/markup-view.css +++ b/browser/themes/shared/devtools/markup-view.css @@ -4,22 +4,16 @@ * { padding: 0; margin: 0; } .newattr { cursor: pointer; -} - -/* Give some padding to focusable elements to match the editor input - * that will replace them. */ -span[tabindex] { - display: inline-block; padding: 1px 0; } li.container { padding: 2px 0 0 2px; } .codebox {
--- a/build/autoconf/hooks.m4 +++ b/build/autoconf/hooks.m4 @@ -14,17 +14,40 @@ dnl Wrap AC_INIT_PREPARE to add the abov define([_MOZ_AC_INIT_PREPARE], defn([AC_INIT_PREPARE])) define([AC_INIT_PREPARE], [_MOZ_AC_INIT_PREPARE($1) MOZ_CONFIG_LOG_TRAP ]) dnl Disable the trap when running sub-configures. define([_MOZ_AC_OUTPUT_SUBDIRS], defn([AC_OUTPUT_SUBDIRS])) +define([MOZ_SUBCONFIGURE_WRAP], +[ _CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} +case "$host" in +*-mingw*) + _CONFIG_SHELL=$(cd $(dirname $_CONFIG_SHELL); pwd -W)/$(basename $_CONFIG_SHELL) + if test ! -e "$_CONFIG_SHELL" -a -e "${_CONFIG_SHELL}.exe"; then + _CONFIG_SHELL="${_CONFIG_SHELL}.exe" + fi + ;; +esac + +if test -d "$1"; then + (cd "$1"; $PYTHON $_topsrcdir/build/subconfigure.py dump "$_CONFIG_SHELL") +fi +$2 +(cd "$1"; $PYTHON $_topsrcdir/build/subconfigure.py adjust) +]) + define([AC_OUTPUT_SUBDIRS], [trap '' EXIT -_MOZ_AC_OUTPUT_SUBDIRS($1) +for moz_config_dir in $1; do + MOZ_SUBCONFIGURE_WRAP([$moz_config_dir],[ + _MOZ_AC_OUTPUT_SUBDIRS($moz_config_dir) + ]) +done + MOZ_CONFIG_LOG_TRAP ]) dnl Print error messages in config.log as well as stderr define([AC_MSG_ERROR], [{ echo "configure: error: $1" 1>&2; echo "configure: error: $1" 1>&5; exit 1; }])
new file mode 100644 --- /dev/null +++ b/build/subconfigure.py @@ -0,0 +1,124 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# This script is used to capture the content of config.status-generated +# files and subsequently restore their timestamp if they haven't changed. + +import os +import re +import subprocess +import sys +import pickle + +class File(object): + def __init__(self, path): + self._path = path + self._content = open(path, 'rb').read() + stat = os.stat(path) + self._times = (stat.st_atime, stat.st_mtime) + + def update_time(self): + '''If the file hasn't changed since the instance was created, + restore its old modification time.''' + if not os.path.exists(self._path): + return + if open(self._path, 'rb').read() == self._content: + os.utime(self._path, self._times) + + +# As defined in the various sub-configures in the tree +PRECIOUS_VARS = set([ + 'build_alias', + 'host_alias', + 'target_alias', + 'CC', + 'CFLAGS', + 'LDFLAGS', + 'LIBS', + 'CPPFLAGS', + 'CPP', + 'CCC', + 'CXXFLAGS', + 'CXX', + 'CCASFLAGS', + 'CCAS', +]) + + +# Autoconf, in some of the sub-configures used in the tree, likes to error +# out when "precious" variables change in value. The solution it gives to +# straighten things is to either run make distclean or remove config.cache. +# There's no reason not to do the latter automatically instead of failing, +# doing the cleanup (which, on buildbots means a full clobber), and +# restarting from scratch. +def maybe_clear_cache(): + comment = re.compile(r'^\s+#') + cache = {} + with open('config.cache') as f: + for line in f.readlines(): + if not comment.match(line) and '=' in line: + key, value = line.split('=', 1) + cache[key] = value + for precious in PRECIOUS_VARS: + entry = 'ac_cv_env_%s_value' % precious + if entry in cache and (not precious in os.environ or os.environ[precious] != cache[entry]): + os.remove('config.cache') + return + + +def dump(dump_file, shell): + if os.path.exists('config.cache'): + maybe_clear_cache() + if not os.path.exists('config.status'): + if os.path.exists(dump_file): + os.remove(dump_file) + return + + config_files = [File('config.status')] + + # Scan the config.status output for information about configuration files + # it generates. + config_status_output = subprocess.check_output( + [shell, '-c', './config.status --help'], + stderr=subprocess.STDOUT).splitlines() + state = None + for line in config_status_output: + if line.startswith('Configuration') and line.endswith(':'): + state = 'config' + elif not line.startswith(' '): + state = None + elif state == 'config': + for f in (couple.split(':')[0] for couple in line.split()): + if os.path.isfile(f): + config_files.append(File(f)) + + with open(dump_file, 'wb') as f: + pickle.dump(config_files, f) + + +def adjust(dump_file): + if not os.path.exists(dump_file): + return + + config_files = [] + + try: + with open(dump_file, 'rb') as f: + config_files = pickle.load(f) + except Exception: + pass + + for f in config_files: + f.update_time() + + os.remove(dump_file) + + +CONFIG_DUMP = 'config_files.pkl' + +if __name__ == '__main__': + if sys.argv[1] == 'dump': + dump(CONFIG_DUMP, sys.argv[2]) + elif sys.argv[1] == 'adjust': + adjust(CONFIG_DUMP)
--- a/config/makefiles/precompile/Makefile.in +++ b/config/makefiles/precompile/Makefile.in @@ -19,25 +19,27 @@ include $(topsrcdir)/config/rules.mk # otherwise the output is unexpected and it confuses downstream parsers. define make_subtier_dir $(call BUILDSTATUS,SUBTIER_START precompile $(1)) +$(MAKE) -C $(2) $(3) $(call BUILDSTATUS,SUBTIER_FINISH precompile $(1)) endef -export:: - $(call BUILDSTATUS,SUBTIERS IPDL WebIDL XPIDL XPIDLParser) +default:: + $(call BUILDSTATUS,TIER_START precompile IPDL WebIDL XPIDL) + +$(MAKE) export + $(call BUILDSTATUS,TIER_FINISH precompile) -export:: ipdl webidl xpidl-parser xpidl +export:: ipdl webidl xpidl ipdl: $(call make_subtier_dir,IPDL,$(DEPTH)/ipc/ipdl,ipdl) webidl: $(call make_subtier_dir,WebIDL,$(DEPTH)/dom/bindings,webidl) -xpidl-parser: - $(call make_subtier_dir,XPIDLParser,$(DEPTH)/xpcom/idl-parser,xpidl-parser) - -xpidl: xpidl-parser +xpidl: + $(call BUILDSTATUS,SUBTIER_START precompile XPIDL) + +$(MAKE) -C $(DEPTH)/xpcom/idl-parser xpidl-parser $(call py_action,process_install_manifest,$(DIST)/idl $(DEPTH)/_build_manifests/install/dist_idl) - $(call make_subtier_dir,XPIDL,$(DEPTH)/config/makefiles/xpidl,xpidl) + +$(MAKE) -C $(DEPTH)/config/makefiles/xpidl xpidl + $(call BUILDSTATUS,SUBTIER_FINISH precompile XPIDL)
--- a/config/makefiles/target_export.mk +++ b/config/makefiles/target_export.mk @@ -7,19 +7,19 @@ PARALLEL_DIRS_export = $(addsuffix _export,$(PARALLEL_DIRS)) .PHONY: export $(PARALLEL_DIRS_export) ############### ## TIER targets ############### -export_tier_%: +$(addprefix export_tier_,$(TIERS)): export_tier_%: @$(ECHO) "$@" - $(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,export,$(dir))) + $(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,$*,export,$(dir),export)) ################# ## Common targets ################# ifdef PARALLEL_DIRS export:: $(PARALLEL_DIRS_export) $(PARALLEL_DIRS_export): %_export: %/Makefile
--- a/config/makefiles/target_libs.mk +++ b/config/makefiles/target_libs.mk @@ -7,19 +7,19 @@ PARALLEL_DIRS_libs = $(addsuffix _libs,$(PARALLEL_DIRS)) .PHONY: libs $(PARALLEL_DIRS_libs) ############### ## TIER targets ############### -libs_tier_%: +$(addprefix libs_tier_,$(TIERS)): libs_tier_%: @$(ECHO) "$@" - $(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,libs,$(dir))) + $(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,$*,libs,$(dir),libs)) ################# ## Common targets ################# ifdef PARALLEL_DIRS libs:: $(PARALLEL_DIRS_libs) $(PARALLEL_DIRS_libs): %_libs: %/Makefile @@ -38,17 +38,17 @@ else EXPORT_LIBRARY = $(DEPTH)/staticlib endif else # If EXPORT_LIBRARY has a value, we'll be installing there. We also need to cleanup there GARBAGE += $(foreach lib,$(LIBRARY),$(EXPORT_LIBRARY)/$(lib)) endif endif # EXPORT_LIBRARY -libs:: $(SUBMAKEFILES) $(MAKE_DIRS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS) $(JAVA_LIBRARY) +libs:: $(SUBMAKEFILES) $(MAKE_DIRS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS) ifndef NO_DIST_INSTALL ifdef SHARED_LIBRARY ifdef IS_COMPONENT $(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)/components $(ELF_DYNSTR_GC) $(FINAL_TARGET)/components/$(SHARED_LIBRARY) ifndef NO_COMPONENTS_MANIFEST @$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/chrome.manifest "manifest components/components.manifest" @$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/components.manifest "binary-component $(SHARED_LIBRARY)" @@ -113,21 +113,11 @@ INSTALL_TARGETS += HOST_PROGRAMS endif ifdef HOST_LIBRARY HOST_LIBRARY_FILES = $(HOST_LIBRARY) HOST_LIBRARY_DEST ?= $(DIST)/host/lib INSTALL_TARGETS += HOST_LIBRARY endif -ifdef JAVA_LIBRARY -JAVA_LIBRARY_FILES = $(JAVA_LIBRARY) -ifdef IS_COMPONENT -JAVA_LIBRARY_DEST ?= $(FINAL_TARGET)/components -else -JAVA_LIBRARY_DEST ?= $(FINAL_TARGET) -endif -INSTALL_TARGETS += JAVA_LIBRARY -endif - endif # !NO_DIST_INSTALL # EOF
--- a/config/makefiles/target_tools.mk +++ b/config/makefiles/target_tools.mk @@ -7,19 +7,19 @@ PARALLEL_DIRS_tools = $(addsuffix _tools,$(PARALLEL_DIRS)) .PHONY: tools $(PARALLEL_DIRS_tools) ############### ## TIER targets ############### -tools_tier_%: +$(addprefix tools_tier_,$(TIERS)): tools_tier_%: @$(ECHO) "$@" - $(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,tools,$(dir))) + $(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,$*,tools,$(dir),tools)) ################# ## Common targets ################# ifdef PARALLEL_DIRS tools:: $(PARALLEL_DIRS_tools) $(PARALLEL_DIRS_tools): %_tools: %/Makefile
--- a/config/rules.mk +++ b/config/rules.mk @@ -25,16 +25,17 @@ endif HOST_CSRCS \ HOST_LIBRARY_NAME \ MODULE \ NO_DIST_INSTALL \ PARALLEL_DIRS \ TEST_DIRS \ TIERS \ TOOL_DIRS \ + XPCSHELL_TESTS \ XPIDL_MODULE \ $(NULL) _DEPRECATED_VARIABLES := \ XPIDL_FLAGS \ $(NULL) ifndef EXTERNALLY_MANAGED_MAKE_FILE @@ -298,20 +299,16 @@ endif endif ifdef FORCE_SHARED_LIB ifndef FORCE_STATIC_LIB LIBRARY := $(NULL) endif endif -ifdef JAVA_LIBRARY_NAME -JAVA_LIBRARY := $(JAVA_LIBRARY_NAME).jar -endif - ifeq ($(OS_ARCH),WINNT) ifndef GNU_CC # # Unless we're building SIMPLE_PROGRAMS, all C++ files share a PDB file per # directory. For parallel builds, this PDB file is shared and locked by # MSPDBSRV.EXE, starting with MSVC8 SP1. If you're using MSVC 7.1 or MSVC8 # without SP1, don't do parallel builds. @@ -428,33 +425,34 @@ endif ifdef MOZ_UPDATE_XTERM # Its good not to have a newline at the end of the titlebar string because it # makes the make -s output easier to read. Echo -n does not work on all # platforms, but we can trick printf into doing it. UPDATE_TITLE = printf "\033]0;%s in %s\007" $(1) $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$(2) ; endif ifdef MACH -BUILDSTATUS=@echo BUILDSTATUS $1 +BUILDSTATUS=@echo "BUILDSTATUS $1" endif + # Static directories are largely independent of our build system. But, they # could share the same build mechanism (like moz.build files). We need to # prevent leaking of our backend state to these independent build systems. This # is why MOZBUILD_BACKEND_CHECKED isn't exported to make invocations for static # directories. define SUBMAKE # $(call SUBMAKE,target,directory,static) +@$(UPDATE_TITLE) +$(if $(3), MOZBUILD_BACKEND_CHECKED=,) $(MAKE) $(if $(2),-C $(2)) $(1) endef # The extra line is important here! don't delete it define TIER_DIR_SUBMAKE -$(call BUILDSTATUS,TIERDIR_START $(2)) -$(call SUBMAKE,$(1),$(2),$(3)) -$(call BUILDSTATUS,TIERDIR_FINISH $(2)) +$(call BUILDSTATUS,TIERDIR_START $(1) $(2) $(3)) +$(call SUBMAKE,$(4),$(3),$(5)) +$(call BUILDSTATUS,TIERDIR_FINISH $(1) $(2) $(3)) endef # Ths empty line is important. ifneq (,$(strip $(DIRS))) LOOP_OVER_DIRS = \ $(foreach dir,$(DIRS),$(call SUBMAKE,$@,$(dir))) endif @@ -702,51 +700,57 @@ alldep:: $(MAKE) export $(MAKE) depend $(MAKE) libs $(MAKE) tools endif # TIERS endif # SUPPRESS_DEFAULT_RULES -ifeq ($(filter s,$(MAKEFLAGS)),) +ifeq ($(findstring s,$(filter-out --%, $(MAKEFLAGS))),) ECHO := echo QUIET := else ECHO := true QUIET := -q endif # This function is called and evaluated to produce the rule to build the -# specified tier. Each tier begins by building the "static" directories. -# The BUILDSTATUS echo commands are used to faciliate easier parsing -# of build output. Build drivers are encouraged to filter these lines -# from the user. +# specified tier. +# +# Tiers are traditionally composed of directories that are invoked either +# once (so-called "static" directories) or 3 times with the export, libs, and +# tools sub-tiers. +# +# If the TIER_$(tier)_CUSTOM variable is defined, then these traditional +# tier rules are ignored and each directory in the tier is executed via a +# sub-make invocation (make -C). define CREATE_TIER_RULE tier_$(1):: - $(call BUILDSTATUS,TIER_START $(1)) - $(call BUILDSTATUS,SUBTIERS $(if $(tier_$(1)_staticdirs),static )$(if $(tier_$(1)_dirs),export libs tools)) - $(call BUILDSTATUS,STATICDIRS $$($$@_staticdirs)) - $(call BUILDSTATUS,DIRS $$($$@_dirs)) +ifdef TIER_$(1)_CUSTOM + $$(foreach dir,$$($$@_dirs),$$(call SUBMAKE,,$$(dir))) +else + $(call BUILDSTATUS,TIER_START $(1) $(if $(tier_$(1)_staticdirs),static )$(if $(tier_$(1)_dirs),export libs tools)) ifneq (,$(tier_$(1)_staticdirs)) - $(call BUILDSTATUS,SUBTIER_START $(1) static) - $$(foreach dir,$$($$@_staticdirs),$$(call TIER_DIR_SUBMAKE,,$$(dir),1)) + $(call BUILDSTATUS,SUBTIER_START $(1) static $$($$@_staticdirs)) + $$(foreach dir,$$($$@_staticdirs),$$(call TIER_DIR_SUBMAKE,$(1),static,$$(dir),,1)) $(call BUILDSTATUS,SUBTIER_FINISH $(1) static) endif ifneq (,$(tier_$(1)_dirs)) - $(call BUILDSTATUS,SUBTIER_START $(1) export) + $(call BUILDSTATUS,SUBTIER_START $(1) export $$($$@_dirs)) $$(MAKE) export_$$@ $(call BUILDSTATUS,SUBTIER_FINISH $(1) export) - $(call BUILDSTATUS,SUBTIER_START $(1) libs) + $(call BUILDSTATUS,SUBTIER_START $(1) libs $$($$@_dirs)) $$(MAKE) libs_$$@ $(call BUILDSTATUS,SUBTIER_FINISH $(1) libs) - $(call BUILDSTATUS,SUBTIER_START $(1) tools) + $(call BUILDSTATUS,SUBTIER_START $(1) tools $$($$@_dirs)) $$(MAKE) tools_$$@ $(call BUILDSTATUS,SUBTIER_FINISH $(1) tools) - $(call BUILDSTATUS TIER_FINISH $(1)) +endif + $(call BUILDSTATUS,TIER_FINISH $(1)) endif endef $(foreach tier,$(TIERS),$(eval $(call CREATE_TIER_RULE,$(tier)))) # Do everything from scratch everything:: $(MAKE) clean @@ -1131,25 +1135,25 @@ endef $(COBJS): $(REPORT_BUILD) @$(MAKE_DEPS_AUTO_CC) $(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) # DEFINES and ACDEFINES are needed here to enable conditional compilation of Q_OBJECTs: # 'moc' only knows about #defines it gets on the command line (-D...), not in # included headers like mozilla-config.h -moc_%.cpp: %.h +$(filter moc_%.cpp,$(CPPSRCS)): moc_%.cpp: %.h $(REPORT_BUILD) $(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $< $(OUTOPTION)$@ -moc_%.cc: %.cc +$(filter moc_%.cc,$(CPPSRCS)): moc_%.cc: %.cc $(REPORT_BUILD) $(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $(_VPATH_SRCS:.cc=.h) $(OUTOPTION)$@ -qrc_%.cpp: %.qrc +$(filter qrc_%.cpp,$(CPPSRCS)): qrc_%.cpp: %.qrc $(REPORT_BUILD) $(ELOG) $(RCC) -name $* $< $(OUTOPTION)$@ ifdef ASFILES # The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept # a '-c' flag. $(ASOBJS): $(REPORT_BUILD) @@ -1170,72 +1174,62 @@ endif @$(MAKE_DEPS_AUTO_CXX) $(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) $(CMOBJS): $(REPORT_BUILD) @$(MAKE_DEPS_AUTO_CC) $(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) -%.s: %.cpp $(call mkdir_deps,$(MDDEPDIR)) +$(filter %.s,$(CPPSRCS:%.cpp=%.s)): %.s: %.cpp $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) $(CCC) -S $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) -%.s: %.cc $(call mkdir_deps,$(MDDEPDIR)) +$(filter %.s,$(CPPSRCS:%.cc=%.s)): %.s: %.cc $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) $(CCC) -S $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) -%.s: %.c $(call mkdir_deps,$(MDDEPDIR)) +$(filter %.s,$(CSRCS:%.c=%.s)): %.s: %.c $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) $(CC) -S $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) -%.i: %.cpp $(call mkdir_deps,$(MDDEPDIR)) +$(filter %.i,$(CPPSRCS:%.cpp=%.i)): %.i: %.cpp $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) $(CCC) -C -E $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i -%.i: %.cc $(call mkdir_deps,$(MDDEPDIR)) +$(filter %.i,$(CPPSRCS:%.cc=%.i)): %.i: %.cc $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) $(CCC) -C -E $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i -%.i: %.c $(call mkdir_deps,$(MDDEPDIR)) +$(filter %.i,$(CSRCS:%.c=%.i)): %.i: %.c $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) $(CC) -C -E $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i -%.i: %.mm $(call mkdir_deps,$(MDDEPDIR)) +$(filter %.i,$(CMMSRCS:%.mm=%.i)): %.i: %.mm $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) $(CCC) -C -E $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i -%.res: %.rc +$(RESFILE): %.res: %.rc $(REPORT_BUILD) @echo Creating Resource file: $@ ifeq ($(OS_ARCH),OS2) $(RC) $(RCFLAGS:-D%=-d %) -i $(subst /,\,$(srcdir)) -r $< $@ else ifdef GNU_CC $(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES:-I%=--include-dir %) $(OUTOPTION)$@ $(_VPATH_SRCS) else $(RC) $(RCFLAGS) -r $(DEFINES) $(INCLUDES) $(OUTOPTION)$@ $(_VPATH_SRCS) endif endif -# Cancel these implicit rules -# -%: %,v - -%: RCS/%,v - -%: RCS/% +# Cancel GNU make built-in implicit rules +ifndef .PYMAKE +MAKEFLAGS += -r +endif -%: s.% - -%: SCCS/s.% - -############################################################################### -# Java rules -############################################################################### ifneq (,$(filter OS2 WINNT,$(OS_ARCH))) SEP := ; else SEP := : endif EMPTY := SPACE := $(EMPTY) $(EMPTY) @@ -1250,50 +1244,23 @@ ifeq ($(HOST_OS_ARCH),WINNT) # on it, then merge with the rest of the path. root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\1|") non-root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\2|") normalizepath = $(foreach p,$(1),$(if $(filter /%,$(1)),$(patsubst %/,%,$(shell cd $(call root-path,$(1)) && pwd -W))/$(call non-root-path,$(1)),$(1))) else normalizepath = $(1) endif +############################################################################### +# Java rules +############################################################################### ifneq (,$(value JAVAFILES)$(value RESFILES)) include $(topsrcdir)/config/makefiles/java-build.mk endif -_srcdir = $(call normalizepath,$(srcdir)) -ifdef JAVA_SOURCEPATH -SP = $(subst $(SPACE),$(SEP),$(call normalizepath,$(strip $(JAVA_SOURCEPATH)))) -_JAVA_SOURCEPATH = ".$(SEP)$(_srcdir)$(SEP)$(SP)" -else -_JAVA_SOURCEPATH = ".$(SEP)$(_srcdir)" -endif - -ifdef JAVA_CLASSPATH -CP = $(subst $(SPACE),$(SEP),$(call normalizepath,$(strip $(JAVA_CLASSPATH)))) -_JAVA_CLASSPATH = ".$(SEP)$(CP)" -else -_JAVA_CLASSPATH = . -endif - -_JAVA_DIR = _java -$(_JAVA_DIR):: - $(NSINSTALL) -D $@ - -$(_JAVA_DIR)/%.class: %.java $(GLOBAL_DEPS) $(_JAVA_DIR) - $(REPORT_BUILD) - $(JAVAC) $(JAVAC_FLAGS) -classpath $(_JAVA_CLASSPATH) \ - -sourcepath $(_JAVA_SOURCEPATH) -d $(_JAVA_DIR) $(_VPATH_SRCS) - -$(JAVA_LIBRARY): $(addprefix $(_JAVA_DIR)/,$(JAVA_SRCS:.java=.class)) $(GLOBAL_DEPS) - $(REPORT_BUILD) - $(JAR) cf $@ -C $(_JAVA_DIR) . - -GARBAGE_DIRS += $(_JAVA_DIR) - ############################################################################### # Update Files Managed by Build Backend ############################################################################### ifndef NO_MAKEFILE_RULE Makefile: Makefile.in @$(PYTHON) $(DEPTH)/config.status -n --file=Makefile @$(TOUCH) $@
--- a/content/canvas/src/WebGLContext.cpp +++ b/content/canvas/src/WebGLContext.cpp @@ -165,16 +165,17 @@ WebGLContext::WebGLContext() mGLMaxRenderbufferSize = 0; mGLMaxTextureImageUnits = 0; mGLMaxVertexTextureImageUnits = 0; mGLMaxVaryingVectors = 0; mGLMaxFragmentUniformVectors = 0; mGLMaxVertexUniformVectors = 0; mGLMaxColorAttachments = 1; mGLMaxDrawBuffers = 1; + mGLMaxTransformFeedbackSeparateAttribs = 0; // See OpenGL ES 2.0.25 spec, 6.2 State Tables, table 6.13 mPixelStorePackAlignment = 4; mPixelStoreUnpackAlignment = 4; WebGLMemoryMultiReporterWrapper::AddWebGLContext(this); mAllowRestore = true; @@ -230,16 +231,17 @@ WebGLContext::DestroyResourcesAndContext if (!gl) return; gl->MakeCurrent(); mBound2DTextures.Clear(); mBoundCubeMapTextures.Clear(); mBoundArrayBuffer = nullptr; + mBoundTransformFeedbackBuffer = nullptr; mCurrentProgram = nullptr; mBoundFramebuffer = nullptr; mActiveOcclusionQuery = nullptr; mBoundRenderbuffer = nullptr; mBoundVertexArray = nullptr; mDefaultVertexArray = nullptr; while (!mTextures.isEmpty())
--- a/content/canvas/src/WebGLContext.h +++ b/content/canvas/src/WebGLContext.h @@ -317,42 +317,31 @@ public: void GetContextAttributes(dom::Nullable<dom::WebGLContextAttributesInitializer>& retval); bool IsContextLost() const { return !IsContextStable(); } void GetSupportedExtensions(JSContext *cx, dom::Nullable< nsTArray<nsString> > &retval); JSObject* GetExtension(JSContext* cx, const nsAString& aName, ErrorResult& rv); void ActiveTexture(WebGLenum texture); void AttachShader(WebGLProgram* program, WebGLShader* shader); void BindAttribLocation(WebGLProgram* program, WebGLuint location, const nsAString& name); - void BindBuffer(WebGLenum target, WebGLBuffer* buf); void BindFramebuffer(WebGLenum target, WebGLFramebuffer* wfb); void BindRenderbuffer(WebGLenum target, WebGLRenderbuffer* wrb); void BindTexture(WebGLenum target, WebGLTexture *tex); void BindVertexArray(WebGLVertexArray *vao); void BlendColor(WebGLclampf r, WebGLclampf g, WebGLclampf b, WebGLclampf a) { if (!IsContextStable()) return; MakeContextCurrent(); gl->fBlendColor(r, g, b, a); } void BlendEquation(WebGLenum mode); void BlendEquationSeparate(WebGLenum modeRGB, WebGLenum modeAlpha); void BlendFunc(WebGLenum sfactor, WebGLenum dfactor); void BlendFuncSeparate(WebGLenum srcRGB, WebGLenum dstRGB, WebGLenum srcAlpha, WebGLenum dstAlpha); - void BufferData(WebGLenum target, WebGLsizeiptr size, WebGLenum usage); - void BufferData(WebGLenum target, const dom::ArrayBufferView &data, - WebGLenum usage); - void BufferData(WebGLenum target, - const Nullable<dom::ArrayBuffer> &maybeData, - WebGLenum usage); - void BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset, - const dom::ArrayBufferView &data); - void BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset, - const Nullable<dom::ArrayBuffer> &maybeData); WebGLenum CheckFramebufferStatus(WebGLenum target); void Clear(WebGLbitfield mask); void ClearColor(WebGLclampf r, WebGLclampf g, WebGLclampf b, WebGLclampf a); void ClearDepth(WebGLclampf v); void ClearStencil(WebGLint v); void ColorMask(WebGLboolean r, WebGLboolean g, WebGLboolean b, WebGLboolean a); void CompileShader(WebGLShader *shader); void CompressedTexImage2D(WebGLenum target, WebGLint level, @@ -365,25 +354,23 @@ public: WebGLenum format, const dom::ArrayBufferView& view); void CopyTexImage2D(WebGLenum target, WebGLint level, WebGLenum internalformat, WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height, WebGLint border); void CopyTexSubImage2D(WebGLenum target, WebGLint level, WebGLint xoffset, WebGLint yoffset, WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height); - already_AddRefed<WebGLBuffer> CreateBuffer(); already_AddRefed<WebGLFramebuffer> CreateFramebuffer(); already_AddRefed<WebGLProgram> CreateProgram(); already_AddRefed<WebGLRenderbuffer> CreateRenderbuffer(); already_AddRefed<WebGLTexture> CreateTexture(); already_AddRefed<WebGLShader> CreateShader(WebGLenum type); already_AddRefed<WebGLVertexArray> CreateVertexArray(); void CullFace(WebGLenum face); - void DeleteBuffer(WebGLBuffer *buf); void DeleteFramebuffer(WebGLFramebuffer *fbuf); void DeleteProgram(WebGLProgram *prog); void DeleteRenderbuffer(WebGLRenderbuffer *rbuf); void DeleteShader(WebGLShader *shader); void DeleteVertexArray(WebGLVertexArray *vao); void DeleteTexture(WebGLTexture *tex); void DepthFunc(WebGLenum func); void DepthMask(WebGLboolean b); @@ -454,17 +441,16 @@ public: WebGLenum pname) { return GetTexParameter(target, pname); } JS::Value GetUniform(JSContext* cx, WebGLProgram *prog, WebGLUniformLocation *location, ErrorResult& rv); already_AddRefed<WebGLUniformLocation> GetUniformLocation(WebGLProgram *prog, const nsAString& name); void Hint(WebGLenum target, WebGLenum mode); - bool IsBuffer(WebGLBuffer *buffer); bool IsFramebuffer(WebGLFramebuffer *fb); bool IsProgram(WebGLProgram *prog); bool IsRenderbuffer(WebGLRenderbuffer *rb); bool IsShader(WebGLShader *shader); bool IsTexture(WebGLTexture *tex); bool IsVertexArray(WebGLVertexArray *vao); void LineWidth(WebGLfloat width) { if (!IsContextStable()) @@ -750,21 +736,55 @@ public: already_AddRefed<WebGLQuery> GetQuery(WebGLenum target, WebGLenum pname); JS::Value GetQueryObject(JSContext* cx, WebGLQuery *query, WebGLenum pname); private: bool ValidateTargetParameter(WebGLenum target, const char* infos); WebGLRefPtr<WebGLQuery>& GetActiveQueryByTarget(WebGLenum target); // ----------------------------------------------------------------------------- +// Buffer Objects (WebGLContextBuffers.cpp) +public: + void BindBuffer(WebGLenum target, WebGLBuffer* buf); + void BindBufferBase(WebGLenum target, WebGLuint index, WebGLBuffer* buffer); + void BindBufferRange(WebGLenum target, WebGLuint index, WebGLBuffer* buffer, + WebGLintptr offset, WebGLsizeiptr size); + void BufferData(WebGLenum target, WebGLsizeiptr size, WebGLenum usage); + void BufferData(WebGLenum target, const dom::ArrayBufferView &data, + WebGLenum usage); + void BufferData(WebGLenum target, + const Nullable<dom::ArrayBuffer> &maybeData, + WebGLenum usage); + void BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset, + const dom::ArrayBufferView &data); + void BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset, + const Nullable<dom::ArrayBuffer> &maybeData); + already_AddRefed<WebGLBuffer> CreateBuffer(); + void DeleteBuffer(WebGLBuffer *buf); + bool IsBuffer(WebGLBuffer *buffer); + +private: + // ARRAY_BUFFER slot + WebGLRefPtr<WebGLBuffer> mBoundArrayBuffer; + + // TRANSFORM_FEEDBACK_BUFFER slot + WebGLRefPtr<WebGLBuffer> mBoundTransformFeedbackBuffer; + + // these two functions emit INVALID_ENUM for invalid `target`. + WebGLRefPtr<WebGLBuffer>* GetBufferSlotByTarget(GLenum target, const char* infos); + WebGLRefPtr<WebGLBuffer>* GetBufferSlotByTargetIndexed(GLenum target, GLuint index, const char* infos); + bool ValidateBufferUsageEnum(WebGLenum target, const char* infos); + +// ----------------------------------------------------------------------------- // State and State Requests (WebGLContextState.cpp) public: void Disable(WebGLenum cap); void Enable(WebGLenum cap); JS::Value GetParameter(JSContext* cx, WebGLenum pname, ErrorResult& rv); + JS::Value GetParameterIndexed(JSContext* cx, WebGLenum pname, WebGLuint index); bool IsEnabled(WebGLenum cap); private: bool ValidateCapabilityEnum(WebGLenum cap, const char* info); // ----------------------------------------------------------------------------- // Vertices Feature (WebGLContextVertices.cpp) public: @@ -911,16 +931,17 @@ protected: int32_t mGLMaxRenderbufferSize; int32_t mGLMaxTextureImageUnits; int32_t mGLMaxVertexTextureImageUnits; int32_t mGLMaxVaryingVectors; int32_t mGLMaxFragmentUniformVectors; int32_t mGLMaxVertexUniformVectors; int32_t mGLMaxColorAttachments; int32_t mGLMaxDrawBuffers; + uint32_t mGLMaxTransformFeedbackSeparateAttribs; // Represents current status, or state, of the context. That is, is it lost // or stable and what part of the context lost process are we currently at. // This is used to support the WebGL spec's asyncronous nature in handling // context loss. enum ContextStatus { // The context is stable; there either are none or we don't know of any. ContextStable, @@ -974,17 +995,16 @@ protected: bool ValidateBlendEquationEnum(WebGLenum cap, const char *info); bool ValidateBlendFuncDstEnum(WebGLenum mode, const char *info); bool ValidateBlendFuncSrcEnum(WebGLenum mode, const char *info); bool ValidateBlendFuncEnumsCompatibility(WebGLenum sfactor, WebGLenum dfactor, const char *info); bool ValidateTextureTargetEnum(WebGLenum target, const char *info); bool ValidateComparisonEnum(WebGLenum target, const char *info); bool ValidateStencilOpEnum(WebGLenum action, const char *info); bool ValidateFaceEnum(WebGLenum face, const char *info); - bool ValidateBufferUsageEnum(WebGLenum target, const char *info); bool ValidateTexFormatAndType(WebGLenum format, WebGLenum type, int jsArrayType, uint32_t *texelSize, const char *info); bool ValidateDrawModeEnum(WebGLenum mode, const char *info); bool ValidateAttribIndex(WebGLuint index, const char *info); bool ValidateStencilParamsForDrawCall(); bool ValidateGLSLVariableName(const nsAString& name, const char *info); bool ValidateGLSLCharacter(PRUnichar c); @@ -1105,18 +1125,16 @@ protected: return mContextStatus == ContextStable; } void ForceLoseContext(); void ForceRestoreContext(); nsTArray<WebGLRefPtr<WebGLTexture> > mBound2DTextures; nsTArray<WebGLRefPtr<WebGLTexture> > mBoundCubeMapTextures; - WebGLRefPtr<WebGLBuffer> mBoundArrayBuffer; - WebGLRefPtr<WebGLProgram> mCurrentProgram; uint32_t mMaxFramebufferColorAttachments; WebGLRefPtr<WebGLFramebuffer> mBoundFramebuffer; WebGLRefPtr<WebGLRenderbuffer> mBoundRenderbuffer; WebGLRefPtr<WebGLVertexArray> mBoundVertexArray; WebGLRefPtr<WebGLQuery> mActiveOcclusionQuery;
new file mode 100644 --- /dev/null +++ b/content/canvas/src/WebGLContextBuffers.cpp @@ -0,0 +1,432 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "WebGLContext.h" +#include "WebGLBuffer.h" +#include "WebGLVertexArray.h" + +using namespace mozilla; +using namespace mozilla::dom; + +void +WebGLContext::BindBuffer(WebGLenum target, WebGLBuffer *buffer) +{ + if (!IsContextStable()) + return; + + if (!ValidateObjectAllowDeletedOrNull("bindBuffer", buffer)) + return; + + // silently ignore a deleted buffer + if (buffer && buffer->IsDeleted()) + return; + + WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bindBuffer"); + + if (!bufferSlot) { + return; + } + + if (buffer) { + if (!buffer->Target()) { + buffer->SetTarget(target); + buffer->SetHasEverBeenBound(true); + } else if (target != buffer->Target()) { + return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target"); + } + } + + *bufferSlot = buffer; + + MakeContextCurrent(); + + gl->fBindBuffer(target, buffer ? buffer->GLName() : 0); +} + +void +WebGLContext::BindBufferBase(WebGLenum target, WebGLuint index, WebGLBuffer* buffer) +{ + if (!IsContextStable()) + return; + + if (!ValidateObjectAllowDeletedOrNull("bindBufferBase", buffer)) + return; + + // silently ignore a deleted buffer + if (buffer && buffer->IsDeleted()) { + return; + } + + WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTargetIndexed(target, index, "bindBufferBase"); + + if (!bufferSlot) { + return; + } + + if (buffer) { + if (!buffer->Target()) { + buffer->SetTarget(target); + buffer->SetHasEverBeenBound(true); + } else if (target != buffer->Target()) { + return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target"); + } + } + + *bufferSlot = buffer; + + MakeContextCurrent(); + + gl->fBindBufferBase(target, index, buffer ? buffer->GLName() : 0); +} + +void +WebGLContext::BindBufferRange(WebGLenum target, WebGLuint index, WebGLBuffer* buffer, + WebGLintptr offset, WebGLsizeiptr size) +{ + if (!IsContextStable()) + return; + + if (!ValidateObjectAllowDeletedOrNull("bindBufferRange", buffer)) + return; + + // silently ignore a deleted buffer + if (buffer && buffer->IsDeleted()) + return; + + WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTargetIndexed(target, index, "bindBufferBase"); + + if (!bufferSlot) { + return; + } + + if (buffer) { + if (!buffer->Target()) { + buffer->SetTarget(target); + buffer->SetHasEverBeenBound(true); + } else if (target != buffer->Target()) { + return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target"); + } + } + + *bufferSlot = buffer; + + MakeContextCurrent(); + + gl->fBindBufferRange(target, index, buffer ? buffer->GLName() : 0, offset, size); +} + +void +WebGLContext::BufferData(WebGLenum target, WebGLsizeiptr size, + WebGLenum usage) +{ + if (!IsContextStable()) + return; + + WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferData"); + + if (!bufferSlot) { + return; + } + + if (size < 0) + return ErrorInvalidValue("bufferData: negative size"); + + if (!ValidateBufferUsageEnum(usage, "bufferData: usage")) + return; + + WebGLBuffer* boundBuffer = bufferSlot->get(); + + if (!boundBuffer) + return ErrorInvalidOperation("bufferData: no buffer bound!"); + + void* zeroBuffer = calloc(size, 1); + if (!zeroBuffer) + return ErrorOutOfMemory("bufferData: out of memory"); + + MakeContextCurrent(); + InvalidateBufferFetching(); + + GLenum error = CheckedBufferData(target, size, zeroBuffer, usage); + free(zeroBuffer); + + if (error) { + GenerateWarning("bufferData generated error %s", ErrorName(error)); + return; + } + + boundBuffer->SetByteLength(size); + if (!boundBuffer->ElementArrayCacheBufferData(nullptr, size)) { + return ErrorOutOfMemory("bufferData: out of memory"); + } +} + +void +WebGLContext::BufferData(WebGLenum target, + const Nullable<ArrayBuffer> &maybeData, + WebGLenum usage) +{ + if (!IsContextStable()) + return; + + if (maybeData.IsNull()) { + // see http://www.khronos.org/bugzilla/show_bug.cgi?id=386 + return ErrorInvalidValue("bufferData: null object passed"); + } + + WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferData"); + + if (!bufferSlot) { + return; + } + + const ArrayBuffer& data = maybeData.Value(); + + if (!ValidateBufferUsageEnum(usage, "bufferData: usage")) + return; + + WebGLBuffer* boundBuffer = bufferSlot->get(); + + if (!boundBuffer) + return ErrorInvalidOperation("bufferData: no buffer bound!"); + + MakeContextCurrent(); + InvalidateBufferFetching(); + + GLenum error = CheckedBufferData(target, data.Length(), data.Data(), usage); + + if (error) { + GenerateWarning("bufferData generated error %s", ErrorName(error)); + return; + } + + boundBuffer->SetByteLength(data.Length()); + if (!boundBuffer->ElementArrayCacheBufferData(data.Data(), data.Length())) { + return ErrorOutOfMemory("bufferData: out of memory"); + } +} + +void +WebGLContext::BufferData(WebGLenum target, const ArrayBufferView& data, + WebGLenum usage) +{ + if (!IsContextStable()) + return; + + WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData"); + + if (!bufferSlot) { + return; + } + + if (!ValidateBufferUsageEnum(usage, "bufferData: usage")) + return; + + WebGLBuffer* boundBuffer = bufferSlot->get(); + + if (!boundBuffer) + return ErrorInvalidOperation("bufferData: no buffer bound!"); + + InvalidateBufferFetching(); + MakeContextCurrent(); + + GLenum error = CheckedBufferData(target, data.Length(), data.Data(), usage); + if (error) { + GenerateWarning("bufferData generated error %s", ErrorName(error)); + return; + } + + boundBuffer->SetByteLength(data.Length()); + if (!boundBuffer->ElementArrayCacheBufferData(data.Data(), data.Length())) { + return ErrorOutOfMemory("bufferData: out of memory"); + } +} + +void +WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset, + const Nullable<ArrayBuffer> &maybeData) +{ + if (!IsContextStable()) + return; + + if (maybeData.IsNull()) { + // see http://www.khronos.org/bugzilla/show_bug.cgi?id=386 + return; + } + + WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData"); + + if (!bufferSlot) { + return; + } + + const ArrayBuffer& data = maybeData.Value(); + + if (byteOffset < 0) + return ErrorInvalidValue("bufferSubData: negative offset"); + + WebGLBuffer* boundBuffer = bufferSlot->get(); + + if (!boundBuffer) + return ErrorInvalidOperation("bufferData: no buffer bound!"); + + CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length(); + if (!checked_neededByteLength.isValid()) + return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length"); + + if (checked_neededByteLength.value() > boundBuffer->ByteLength()) + return ErrorInvalidValue("bufferSubData: not enough data - operation requires %d bytes, but buffer only has %d bytes", + checked_neededByteLength.value(), boundBuffer->ByteLength()); + + MakeContextCurrent(); + + boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(), data.Length()); + + gl->fBufferSubData(target, byteOffset, data.Length(), data.Data()); +} + +void +WebGLContext::BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset, + const ArrayBufferView& data) +{ + if (!IsContextStable()) + return; + + WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData"); + + if (!bufferSlot) { + return; + } + + if (byteOffset < 0) + return ErrorInvalidValue("bufferSubData: negative offset"); + + WebGLBuffer* boundBuffer = bufferSlot->get(); + + if (!boundBuffer) + return ErrorInvalidOperation("bufferSubData: no buffer bound!"); + + CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length(); + if (!checked_neededByteLength.isValid()) + return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length"); + + if (checked_neededByteLength.value() > boundBuffer->ByteLength()) + return ErrorInvalidValue("bufferSubData: not enough data -- operation requires %d bytes, but buffer only has %d bytes", + checked_neededByteLength.value(), boundBuffer->ByteLength()); + + boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(), data.Length()); + + MakeContextCurrent(); + gl->fBufferSubData(target, byteOffset, data.Length(), data.Data()); +} + +already_AddRefed<WebGLBuffer> +WebGLContext::CreateBuffer() +{ + if (!IsContextStable()) + return nullptr; + + nsRefPtr<WebGLBuffer> globj = new WebGLBuffer(this); + return globj.forget(); +} + +void +WebGLContext::DeleteBuffer(WebGLBuffer *buffer) +{ + if (!IsContextStable()) + return; + + if (!ValidateObjectAllowDeletedOrNull("deleteBuffer", buffer)) + return; + + if (!buffer || buffer->IsDeleted()) + return; + + if (mBoundArrayBuffer == buffer) { + BindBuffer(LOCAL_GL_ARRAY_BUFFER, + static_cast<WebGLBuffer*>(nullptr)); + } + + if (mBoundVertexArray->mBoundElementArrayBuffer == buffer) { + BindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER, + static_cast<WebGLBuffer*>(nullptr)); + } + + for (int32_t i = 0; i < mGLMaxVertexAttribs; i++) { + if (mBoundVertexArray->mAttribBuffers[i].buf == buffer) + mBoundVertexArray->mAttribBuffers[i].buf = nullptr; + } + + buffer->RequestDelete(); +} + +bool +WebGLContext::IsBuffer(WebGLBuffer *buffer) +{ + if (!IsContextStable()) + return false; + + return ValidateObjectAllowDeleted("isBuffer", buffer) && + !buffer->IsDeleted() && + buffer->HasEverBeenBound(); +} + +bool +WebGLContext::ValidateBufferUsageEnum(WebGLenum target, const char *infos) +{ + switch (target) { + case LOCAL_GL_STREAM_DRAW: + case LOCAL_GL_STATIC_DRAW: + case LOCAL_GL_DYNAMIC_DRAW: + return true; + default: + break; + } + + ErrorInvalidEnumInfo(infos, target); + return false; +} + +WebGLRefPtr<WebGLBuffer>* +WebGLContext::GetBufferSlotByTarget(GLenum target, const char* infos) +{ + switch (target) { + case LOCAL_GL_ARRAY_BUFFER: + return &mBoundArrayBuffer; + + case LOCAL_GL_ELEMENT_ARRAY_BUFFER: + return &mBoundVertexArray->mBoundElementArrayBuffer; + + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER: + if (!IsWebGL2()) { + break; + } + return &mBoundTransformFeedbackBuffer; + + default: + break; + } + + ErrorInvalidEnum("%s: target: invalid enum value 0x%x", infos, target); + return nullptr; +} + +WebGLRefPtr<WebGLBuffer>* +WebGLContext::GetBufferSlotByTargetIndexed(GLenum target, GLuint index, const char* infos) +{ + switch (target) { + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER: + if (index >= mGLMaxTransformFeedbackSeparateAttribs) { + ErrorInvalidValue("%s: index should be less than MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", infos, index); + return nullptr; + } + return nullptr; // See bug 903594 + + default: + break; + } + + ErrorInvalidEnum("%s: target: invalid enum value 0x%x", infos, target); + return nullptr; +}
--- a/content/canvas/src/WebGLContextGL.cpp +++ b/content/canvas/src/WebGLContextGL.cpp @@ -123,57 +123,16 @@ WebGLContext::BindAttribLocation(WebGLPr nsCString mappedName; prog->MapIdentifier(cname, &mappedName); MakeContextCurrent(); gl->fBindAttribLocation(progname, location, mappedName.get()); } void -WebGLContext::BindBuffer(WebGLenum target, WebGLBuffer *buf) -{ - if (!IsContextStable()) - return; - - if (!ValidateObjectAllowDeletedOrNull("bindBuffer", buf)) - return; - - WebGLuint bufname = buf ? buf->GLName() : 0; - - // silently ignore a deleted buffer - if (buf && buf->IsDeleted()) - return; - - if (target != LOCAL_GL_ARRAY_BUFFER && - target != LOCAL_GL_ELEMENT_ARRAY_BUFFER) - { - return ErrorInvalidEnumInfo("bindBuffer: target", target); - } - - if (buf) { - if ((buf->Target() != LOCAL_GL_NONE) && (target != buf->Target())) - return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target"); - buf->SetTarget(target); - buf->SetHasEverBeenBound(true); - } - - // we really want to do this AFTER all the validation is done, otherwise our bookkeeping could get confused. - // see bug 656752 - if (target == LOCAL_GL_ARRAY_BUFFER) { - mBoundArrayBuffer = buf; - } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) { - mBoundVertexArray->mBoundElementArrayBuffer = buf; - } - - MakeContextCurrent(); - - gl->fBindBuffer(target, bufname); -} - -void WebGLContext::BindFramebuffer(WebGLenum target, WebGLFramebuffer *wfb) { if (!IsContextStable()) return; if (target != LOCAL_GL_FRAMEBUFFER) return ErrorInvalidEnum("bindFramebuffer: target must be GL_FRAMEBUFFER"); @@ -347,230 +306,16 @@ GLenum WebGLContext::CheckedBufferData(G UpdateWebGLErrorAndClearGLError(&error); return error; } else { gl->fBufferData(target, size, data, usage); return LOCAL_GL_NO_ERROR; } } -void -WebGLContext::BufferData(WebGLenum target, WebGLsizeiptr size, - WebGLenum usage) -{ - if (!IsContextStable()) - return; - - WebGLBuffer *boundBuffer = nullptr; - - if (target == LOCAL_GL_ARRAY_BUFFER) { - boundBuffer = mBoundArrayBuffer; - } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) { - boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer; - } else { - return ErrorInvalidEnumInfo("bufferData: target", target); - } - - if (size < 0) - return ErrorInvalidValue("bufferData: negative size"); - - if (!ValidateBufferUsageEnum(usage, "bufferData: usage")) - return; - - if (!boundBuffer) - return ErrorInvalidOperation("bufferData: no buffer bound!"); - - void* zeroBuffer = calloc(size, 1); - if (!zeroBuffer) - return ErrorOutOfMemory("bufferData: out of memory"); - - MakeContextCurrent(); - InvalidateBufferFetching(); - - GLenum error = CheckedBufferData(target, size, zeroBuffer, usage); - free(zeroBuffer); - - if (error) { - GenerateWarning("bufferData generated error %s", ErrorName(error)); - return; - } - - boundBuffer->SetByteLength(size); - if (!boundBuffer->ElementArrayCacheBufferData(nullptr, size)) { - return ErrorOutOfMemory("bufferData: out of memory"); - } -} - -void -WebGLContext::BufferData(WebGLenum target, - const Nullable<ArrayBuffer> &maybeData, - WebGLenum usage) -{ - if (!IsContextStable()) - return; - - if (maybeData.IsNull()) { - // see http://www.khronos.org/bugzilla/show_bug.cgi?id=386 - return ErrorInvalidValue("bufferData: null object passed"); - } - - const ArrayBuffer& data = maybeData.Value(); - - WebGLBuffer *boundBuffer = nullptr; - - if (target == LOCAL_GL_ARRAY_BUFFER) { - boundBuffer = mBoundArrayBuffer; - } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) { - boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer; - } else { - return ErrorInvalidEnumInfo("bufferData: target", target); - } - - if (!ValidateBufferUsageEnum(usage, "bufferData: usage")) - return; - - if (!boundBuffer) - return ErrorInvalidOperation("bufferData: no buffer bound!"); - - MakeContextCurrent(); - InvalidateBufferFetching(); - - GLenum error = CheckedBufferData(target, data.Length(), data.Data(), usage); - - if (error) { - GenerateWarning("bufferData generated error %s", ErrorName(error)); - return; - } - - boundBuffer->SetByteLength(data.Length()); - if (!boundBuffer->ElementArrayCacheBufferData(data.Data(), data.Length())) { - return ErrorOutOfMemory("bufferData: out of memory"); - } -} - -void -WebGLContext::BufferData(WebGLenum target, const ArrayBufferView& data, - WebGLenum usage) -{ - if (!IsContextStable()) - return; - - WebGLBuffer *boundBuffer = nullptr; - - if (target == LOCAL_GL_ARRAY_BUFFER) { - boundBuffer = mBoundArrayBuffer; - } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) { - boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer; - } else { - return ErrorInvalidEnumInfo("bufferData: target", target); - } - - if (!ValidateBufferUsageEnum(usage, "bufferData: usage")) - return; - - if (!boundBuffer) - return ErrorInvalidOperation("bufferData: no buffer bound!"); - - InvalidateBufferFetching(); - MakeContextCurrent(); - - GLenum error = CheckedBufferData(target, data.Length(), data.Data(), usage); - if (error) { - GenerateWarning("bufferData generated error %s", ErrorName(error)); - return; - } - - boundBuffer->SetByteLength(data.Length()); - if (!boundBuffer->ElementArrayCacheBufferData(data.Data(), data.Length())) { - return ErrorOutOfMemory("bufferData: out of memory"); - } -} - -void -WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset, - const Nullable<ArrayBuffer> &maybeData) -{ - if (!IsContextStable()) - return; - - if (maybeData.IsNull()) { - // see http://www.khronos.org/bugzilla/show_bug.cgi?id=386 - return; - } - - const ArrayBuffer& data = maybeData.Value(); - - WebGLBuffer *boundBuffer = nullptr; - - if (target == LOCAL_GL_ARRAY_BUFFER) { - boundBuffer = mBoundArrayBuffer; - } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) { - boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer; - } else { - return ErrorInvalidEnumInfo("bufferSubData: target", target); - } - - if (byteOffset < 0) - return ErrorInvalidValue("bufferSubData: negative offset"); - - if (!boundBuffer) - return ErrorInvalidOperation("bufferData: no buffer bound!"); - - CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length(); - if (!checked_neededByteLength.isValid()) - return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length"); - - if (checked_neededByteLength.value() > boundBuffer->ByteLength()) - return ErrorInvalidValue("bufferSubData: not enough data - operation requires %d bytes, but buffer only has %d bytes", - checked_neededByteLength.value(), boundBuffer->ByteLength()); - - MakeContextCurrent(); - - boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(), data.Length()); - - gl->fBufferSubData(target, byteOffset, data.Length(), data.Data()); -} - -void -WebGLContext::BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset, - const ArrayBufferView& data) -{ - if (!IsContextStable()) - return; - - WebGLBuffer *boundBuffer = nullptr; - - if (target == LOCAL_GL_ARRAY_BUFFER) { - boundBuffer = mBoundArrayBuffer; - } else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) { - boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer; - } else { - return ErrorInvalidEnumInfo("bufferSubData: target", target); - } - - if (byteOffset < 0) - return ErrorInvalidValue("bufferSubData: negative offset"); - - if (!boundBuffer) - return ErrorInvalidOperation("bufferSubData: no buffer bound!"); - - CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length(); - if (!checked_neededByteLength.isValid()) - return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length"); - - if (checked_neededByteLength.value() > boundBuffer->ByteLength()) - return ErrorInvalidValue("bufferSubData: not enough data -- operation requires %d bytes, but buffer only has %d bytes", - checked_neededByteLength.value(), boundBuffer->ByteLength()); - - boundBuffer->ElementArrayCacheBufferSubData(byteOffset, data.Data(), data.Length()); - - MakeContextCurrent(); - gl->fBufferSubData(target, byteOffset, data.Length(), data.Data()); -} - WebGLenum WebGLContext::CheckFramebufferStatus(WebGLenum target) { if (!IsContextStable()) { return LOCAL_GL_FRAMEBUFFER_UNSUPPORTED; } @@ -940,44 +685,16 @@ WebGLContext::CullFace(WebGLenum face) if (!ValidateFaceEnum(face, "cullFace")) return; MakeContextCurrent(); gl->fCullFace(face); } void -WebGLContext::DeleteBuffer(WebGLBuffer *buf) -{ - if (!IsContextStable()) - return; - - if (!ValidateObjectAllowDeletedOrNull("deleteBuffer", buf)) - return; - - if (!buf || buf->IsDeleted()) - return; - - if (mBoundArrayBuffer == buf) - BindBuffer(LOCAL_GL_ARRAY_BUFFER, - static_cast<WebGLBuffer*>(nullptr)); - - if (mBoundVertexArray->mBoundElementArrayBuffer == buf) - BindBuffer(LOCAL_GL_ELEMENT_ARRAY_BUFFER, - static_cast<WebGLBuffer*>(nullptr)); - - for (int32_t i = 0; i < mGLMaxVertexAttribs; i++) { - if (mBoundVertexArray->mAttribBuffers[i].buf == buf) - mBoundVertexArray->mAttribBuffers[i].buf = nullptr; - } - - buf->RequestDelete(); -} - -void WebGLContext::DeleteFramebuffer(WebGLFramebuffer* fbuf) { if (!IsContextStable()) return; if (!ValidateObjectAllowDeletedOrNull("deleteFramebuffer", fbuf)) return; @@ -1726,25 +1443,16 @@ WebGLContext::GetRenderbufferParameter(W } default: ErrorInvalidEnumInfo("getRenderbufferParameter: parameter", pname); } return JS::NullValue(); } -already_AddRefed<WebGLBuffer> -WebGLContext::CreateBuffer() -{ - if (!IsContextStable()) - return nullptr; - nsRefPtr<WebGLBuffer> globj = new WebGLBuffer(this); - return globj.forget(); -} - already_AddRefed<WebGLTexture> WebGLContext::CreateTexture() { if (!IsContextStable()) return nullptr; nsRefPtr<WebGLTexture> globj = new WebGLTexture(this); return globj.forget(); } @@ -2201,27 +1909,16 @@ WebGLContext::Hint(WebGLenum target, Web if (!isValid) return ErrorInvalidEnum("hint: invalid hint"); gl->fHint(target, mode); } bool -WebGLContext::IsBuffer(WebGLBuffer *buffer) -{ - if (!IsContextStable()) - return false; - - return ValidateObjectAllowDeleted("isBuffer", buffer) && - !buffer->IsDeleted() && - buffer->HasEverBeenBound(); -} - -bool WebGLContext::IsFramebuffer(WebGLFramebuffer *fb) { if (!IsContextStable()) return false; return ValidateObjectAllowDeleted("isFramebuffer", fb) && !fb->IsDeleted() && fb->HasEverBeenBound();
--- a/content/canvas/src/WebGLContextState.cpp +++ b/content/canvas/src/WebGLContextState.cpp @@ -297,16 +297,23 @@ WebGLContext::GetParameter(JSContext* cx { uint32_t length = mCompressedTextureFormats.Length(); JSObject* obj = Uint32Array::Create(cx, this, length, mCompressedTextureFormats.Elements()); if (!obj) { rv = NS_ERROR_OUT_OF_MEMORY; } return JS::ObjectOrNullValue(obj); } + case LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS: + { + if (!IsWebGL2()) { + break; + } + return JS::Int32Value(mGLMaxTransformFeedbackSeparateAttribs); + } // unsigned int. here we may have to return very large values like 2^32-1 that can't be represented as // javascript integer values. We just return them as doubles and javascript doesn't care. case LOCAL_GL_STENCIL_BACK_VALUE_MASK: case LOCAL_GL_STENCIL_BACK_WRITEMASK: case LOCAL_GL_STENCIL_VALUE_MASK: case LOCAL_GL_STENCIL_WRITEMASK: { @@ -430,16 +437,24 @@ WebGLContext::GetParameter(JSContext* cx return JS::ObjectOrNullValue(obj); } case LOCAL_GL_ARRAY_BUFFER_BINDING: { return WebGLObjectAsJSValue(cx, mBoundArrayBuffer.get(), rv); } + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + { + if (!IsWebGL2()) { + break; + } + return WebGLObjectAsJSValue(cx, mBoundTransformFeedbackBuffer.get(), rv); + } + case LOCAL_GL_ELEMENT_ARRAY_BUFFER_BINDING: { return WebGLObjectAsJSValue(cx, mBoundVertexArray->mBoundElementArrayBuffer.get(), rv); } case LOCAL_GL_RENDERBUFFER_BINDING: { return WebGLObjectAsJSValue(cx, mBoundRenderbuffer.get(), rv); @@ -467,16 +482,42 @@ WebGLContext::GetParameter(JSContext* cx default: ErrorInvalidEnumInfo("getParameter: parameter", pname); } return JS::NullValue(); } +JS::Value +WebGLContext::GetParameterIndexed(JSContext* cx, WebGLenum pname, WebGLuint index) +{ + if (!IsContextStable()) + return JS::NullValue(); + + MakeContextCurrent(); + + switch (pname) { + case LOCAL_GL_TRANSFORM_FEEDBACK_BUFFER_BINDING: + { + if (index >= mGLMaxTransformFeedbackSeparateAttribs) { + ErrorInvalidValue("getParameterIndexed: index should be less than MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS", index); + return JS::NullValue(); + } + return JS::NullValue(); // See bug 903594 + } + + default: + break; + } + + ErrorInvalidEnumInfo("getParameterIndexed: parameter", pname); + return JS::NullValue(); +} + bool WebGLContext::IsEnabled(WebGLenum cap) { if (!IsContextStable()) return false; if (!ValidateCapabilityEnum(cap, "isEnabled")) return false;
--- a/content/canvas/src/WebGLContextValidate.cpp +++ b/content/canvas/src/WebGLContextValidate.cpp @@ -218,29 +218,16 @@ bool WebGLContext::ValidateFaceEnum(WebG case LOCAL_GL_FRONT_AND_BACK: return true; default: ErrorInvalidEnumInfo(info, face); return false; } } -bool WebGLContext::ValidateBufferUsageEnum(WebGLenum target, const char *info) -{ - switch (target) { - case LOCAL_GL_STREAM_DRAW: - case LOCAL_GL_STATIC_DRAW: - case LOCAL_GL_DYNAMIC_DRAW: - return true; - default: - ErrorInvalidEnumInfo(info, target); - return false; - } -} - bool WebGLContext::ValidateDrawModeEnum(WebGLenum mode, const char *info) { switch (mode) { case LOCAL_GL_TRIANGLES: case LOCAL_GL_TRIANGLE_STRIP: case LOCAL_GL_TRIANGLE_FAN: case LOCAL_GL_POINTS: case LOCAL_GL_LINE_STRIP: @@ -815,16 +802,17 @@ WebGLContext::InitAndValidateGL() mActiveTexture = 0; mWebGLError = LOCAL_GL_NO_ERROR; mBound2DTextures.Clear(); mBoundCubeMapTextures.Clear(); mBoundArrayBuffer = nullptr; + mBoundTransformFeedbackBuffer = nullptr; mCurrentProgram = nullptr; mBoundFramebuffer = nullptr; mBoundRenderbuffer = nullptr; MakeContextCurrent(); // on desktop OpenGL, we always keep vertex attrib 0 array enabled @@ -914,20 +902,24 @@ WebGLContext::InitAndValidateGL() mGLMaxVaryingVectors = std::min(maxVertexOutputComponents, minFragmentInputComponents) / 4; break; case LOCAL_GL_INVALID_ENUM: mGLMaxVaryingVectors = 16; // = 64/4, 64 is the min value for maxVertexOutputComponents in OpenGL 3.2 spec break; default: GenerateWarning("GL error 0x%x occurred during WebGL context initialization!", error); return false; - } + } } } + if (IsWebGL2()) { + gl->GetUIntegerv(LOCAL_GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &mGLMaxTransformFeedbackSeparateAttribs); + } + // Always 1 for GLES2 mMaxFramebufferColorAttachments = 1; if (!gl->IsGLES2()) { // gl_PointSize is always available in ES2 GLSL, but has to be // specifically enabled on desktop GLSL. gl->fEnable(LOCAL_GL_VERTEX_PROGRAM_POINT_SIZE);
--- a/content/canvas/src/moz.build +++ b/content/canvas/src/moz.build @@ -27,16 +27,17 @@ CPP_SOURCES += [ if CONFIG['MOZ_WEBGL']: CPP_SOURCES += [ 'WebGLActiveInfo.cpp', 'WebGLBuffer.cpp', 'WebGL1Context.cpp', 'WebGL2Context.cpp', 'WebGLContext.cpp', 'WebGLContextAsyncQueries.cpp', + 'WebGLContextBuffers.cpp', 'WebGLContextGL.cpp', 'WebGLContextUtils.cpp', 'WebGLContextReporter.cpp', 'WebGLContextState.cpp', 'WebGLContextValidate.cpp', 'WebGLContextFramebufferOperations.cpp', 'WebGLContextVertexArray.cpp', 'WebGLContextVertices.cpp',
--- a/content/media/TextTrack.cpp +++ b/content/media/TextTrack.cpp @@ -5,20 +5,21 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/dom/TextTrack.h" #include "mozilla/dom/TextTrackBinding.h" namespace mozilla { namespace dom { -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_3(TextTrack, - mParent, - mCueList, - mActiveCueList) +NS_IMPL_CYCLE_COLLECTION_INHERITED_3(TextTrack, + nsDOMEventTargetHelper, + mParent, + mCueList, + mActiveCueList) NS_IMPL_ADDREF_INHERITED(TextTrack, nsDOMEventTargetHelper) NS_IMPL_RELEASE_INHERITED(TextTrack, nsDOMEventTargetHelper) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TextTrack) NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper) TextTrack::TextTrack(nsISupports* aParent, TextTrackKind aKind,
--- a/content/media/TextTrack.h +++ b/content/media/TextTrack.h @@ -21,18 +21,17 @@ namespace dom { class TextTrackCue; class TextTrackCueList; class TextTrack MOZ_FINAL : public nsDOMEventTargetHelper { public: NS_DECL_ISUPPORTS_INHERITED - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TextTrack, - nsDOMEventTargetHelper) + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TextTrack, nsDOMEventTargetHelper) TextTrack(nsISupports* aParent); TextTrack(nsISupports* aParent, TextTrackKind aKind, const nsAString& aLabel, const nsAString& aLanguage); virtual JSObject* WrapObject(JSContext* aCx,
--- a/content/media/TextTrackCue.cpp +++ b/content/media/TextTrackCue.cpp @@ -12,21 +12,22 @@ #include "nsVideoFrame.h" // Alternate value for the 'auto' keyword. #define WEBVTT_AUTO -1 namespace mozilla { namespace dom { -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_4(TextTrackCue, - mDocument, - mTrack, - mTrackElement, - mDisplayState) +NS_IMPL_CYCLE_COLLECTION_INHERITED_4(TextTrackCue, + nsDOMEventTargetHelper, + mDocument, + mTrack, + mTrackElement, + mDisplayState) NS_IMPL_ADDREF_INHERITED(TextTrackCue, nsDOMEventTargetHelper) NS_IMPL_RELEASE_INHERITED(TextTrackCue, nsDOMEventTargetHelper) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TextTrackCue) NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper) // Set cue setting defaults based on step 19 & seq. // in http://dev.w3.org/html5/webvtt/#parsing
--- a/content/media/TextTrackCue.h +++ b/content/media/TextTrackCue.h @@ -21,18 +21,17 @@ namespace dom { class HTMLTrackElement; class TextTrack; class TextTrackCue MOZ_FINAL : public nsDOMEventTargetHelper { public: NS_DECL_ISUPPORTS_INHERITED - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TextTrackCue, - nsDOMEventTargetHelper) + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TextTrackCue, nsDOMEventTargetHelper) // TextTrackCue WebIDL // See bug 868509 about splitting out the WebVTT-specific interfaces. static already_AddRefed<TextTrackCue> Constructor(GlobalObject& aGlobal, double aStartTime, double aEndTime, const nsAString& aText,
--- a/content/media/TextTrackList.cpp +++ b/content/media/TextTrackList.cpp @@ -4,17 +4,20 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "mozilla/dom/TextTrackList.h" #include "mozilla/dom/TextTrackListBinding.h" namespace mozilla { namespace dom { -NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_2(TextTrackList, mGlobal, mTextTracks) +NS_IMPL_CYCLE_COLLECTION_INHERITED_2(TextTrackList, + nsDOMEventTargetHelper, + mGlobal, + mTextTracks) NS_IMPL_ADDREF_INHERITED(TextTrackList, nsDOMEventTargetHelper) NS_IMPL_RELEASE_INHERITED(TextTrackList, nsDOMEventTargetHelper) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(TextTrackList) NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper) TextTrackList::TextTrackList(nsISupports* aGlobal) : mGlobal(aGlobal) {
--- a/content/media/TextTrackList.h +++ b/content/media/TextTrackList.h @@ -15,18 +15,17 @@ namespace mozilla { namespace dom { class TextTrack; class TextTrackList MOZ_FINAL : public nsDOMEventTargetHelper { public: NS_DECL_ISUPPORTS_INHERITED - NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(TextTrackList, - nsDOMEventTargetHelper) + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(TextTrackList, nsDOMEventTargetHelper) TextTrackList(nsISupports* aGlobal); virtual JSObject* WrapObject(JSContext* aCx, JS::Handle<JSObject*> aScope) MOZ_OVERRIDE; nsISupports* GetParentObject() const {
--- a/content/media/moz.build +++ b/content/media/moz.build @@ -38,18 +38,17 @@ if CONFIG['MOZ_WMF']: PARALLEL_DIRS += ['wmf'] PARALLEL_DIRS += ['webrtc'] if CONFIG['MOZ_OMX_DECODER']: PARALLEL_DIRS += ['omx'] PARALLEL_DIRS += ['omx/mediaresourcemanager'] -if CONFIG['MOZ_WEBSPEECH']: - PARALLEL_DIRS += ['webspeech'] +PARALLEL_DIRS += ['webspeech'] TEST_DIRS += ['test'] MODULE = 'content' EXPORTS += [ 'AbstractMediaDecoder.h', 'AudioAvailableEventManager.h',
--- a/content/media/test/Makefile.in +++ b/content/media/test/Makefile.in @@ -140,16 +140,17 @@ MOCHITEST_FILES = \ test_texttrack.html \ test_texttrackcue.html \ test_timeupdate_small_files.html \ test_unseekable.html \ test_VideoPlaybackQuality.html \ test_VideoPlaybackQuality_disabled.html \ test_webvtt_disabled.html \ test_playback_rate_playpause.html \ + test_bug895305.html \ $(NULL) # Disabled on Windows for frequent intermittent failures ifneq ($(OS_ARCH), WINNT) MOCHITEST_FILES += \ test_streams_element_capture.html \ test_streams_element_capture_reset.html \ test_streams_element_capture_createObjectURL.html \
new file mode 100644 --- /dev/null +++ b/content/media/test/test_bug895305.html @@ -0,0 +1,43 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=895305 +https://bugzilla.mozilla.org/show_bug.cgi?id=905320 +--> +<head> + <meta charset='utf-8'> + <title>Regression test for bug 895305 and 905320 - TextTrack* leaks</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<p id="display"></p> +<div id="content" style="display: none"> +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +SimpleTest.waitForExplicitFinish(); +SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true]]}, + function() { + var audio = document.createElement("audio"); + // Check leaking on TextTrackList objects. + window.ttl = audio.textTracks; + ttl.addEventListener("click", function(){}, false); + + // Check leaking on TextTrackCue objects. + window.ttc = new TextTrackCue(3, 4, "Test."); + ttc.addEventListener("click", function() {}, false); + + // Check leaking on TextTrack objects. + audio.addTextTrack("subtitles", "label", "en-CA"); + ttl[0].addEventListener("click", function() {}, false); + + ok(true); // Need to have at least one assertion for Mochitest to be happy. + SimpleTest.finish(); + } +); +</script> +</pre> +</body> +</html>
--- a/content/media/webspeech/moz.build +++ b/content/media/webspeech/moz.build @@ -1,6 +1,9 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -PARALLEL_DIRS = ['recognition', 'synth'] +PARALLEL_DIRS = ['synth'] + +if CONFIG['MOZ_WEBSPEECH']: + PARALLEL_DIRS += ['recognition']
--- a/content/media/webspeech/synth/moz.build +++ b/content/media/webspeech/synth/moz.build @@ -1,43 +1,44 @@ # vim: set filetype=python: # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. -MODULE = 'content' +if CONFIG['MOZ_WEBSPEECH']: + MODULE = 'content' -TEST_DIRS += ['test', 'ipc/test'] + TEST_DIRS += ['test', 'ipc/test'] -XPIDL_MODULE = 'dom_webspeechsynth' + XPIDL_MODULE = 'dom_webspeechsynth' -XPIDL_SOURCES += [ - 'nsIDOMSpeechSynthesisEvent.idl', - 'nsISpeechService.idl', - 'nsISynthVoiceRegistry.idl' + XPIDL_SOURCES += [ + 'nsIDOMSpeechSynthesisEvent.idl', + 'nsISpeechService.idl', + 'nsISynthVoiceRegistry.idl' ] -EXPORTS.mozilla.dom += [ - 'EnableSpeechSynthesisCheck.h', - 'SpeechSynthesis.h', - 'SpeechSynthesisUtterance.h', - 'SpeechSynthesisVoice.h', - 'ipc/SpeechSynthesisChild.h', - 'ipc/SpeechSynthesisParent.h', - 'nsSpeechTask.h', - 'nsSynthVoiceRegistry.h', -] + EXPORTS.mozilla.dom += [ + 'EnableSpeechSynthesisCheck.h', + 'SpeechSynthesis.h', + 'SpeechSynthesisUtterance.h', + 'SpeechSynthesisVoice.h', + 'ipc/SpeechSynthesisChild.h', + 'ipc/SpeechSynthesisParent.h', + 'nsSpeechTask.h', + 'nsSynthVoiceRegistry.h', + ] -CPP_SOURCES += [ - 'EnableSpeechSynthesisCheck.cpp', - 'SpeechSynthesis.cpp', - 'SpeechSynthesisChild.cpp', - 'SpeechSynthesisParent.cpp', - 'SpeechSynthesisUtterance.cpp', - 'SpeechSynthesisVoice.cpp', - 'nsSpeechTask.cpp', - 'nsSynthVoiceRegistry.cpp', -] + CPP_SOURCES += [ + 'EnableSpeechSynthesisCheck.cpp', + 'SpeechSynthesis.cpp', + 'SpeechSynthesisChild.cpp', + 'SpeechSynthesisParent.cpp', + 'SpeechSynthesisUtterance.cpp', + 'SpeechSynthesisVoice.cpp', + 'nsSpeechTask.cpp', + 'nsSynthVoiceRegistry.cpp', + ] IPDL_SOURCES += [ 'ipc/PSpeechSynthesis.ipdl', 'ipc/PSpeechSynthesisRequest.ipdl', ]
--- a/dom/base/nsFocusManager.cpp +++ b/dom/base/nsFocusManager.cpp @@ -31,16 +31,17 @@ #include "nsViewManager.h" #include "nsFrameSelection.h" #include "mozilla/Selection.h" #include "nsXULPopupManager.h" #include "nsIScriptObjectPrincipal.h" #include "nsIPrincipal.h" #include "nsIObserverService.h" #include "nsIObjectFrame.h" +#include "nsBindingManager.h" #include "mozilla/dom/Element.h" #include "mozilla/LookAndFeel.h" #include "mozilla/Preferences.h" #include <algorithm> #ifdef MOZ_XUL #include "nsIDOMXULTextboxElement.h"
--- a/dom/base/nsWrapperCache.h +++ b/dom/base/nsWrapperCache.h @@ -608,9 +608,52 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsWrapperC NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field7) \ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field8) \ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field9) \ NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field10) \ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \ NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class) +#define NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_11(_class, \ + _field1, \ + _field2, \ + _field3, \ + _field4, \ + _field5, \ + _field6, \ + _field7, \ + _field8, \ + _field9, \ + _field10, \ + _field11) \ + NS_IMPL_CYCLE_COLLECTION_CLASS(_class) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(_class) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field1) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field2) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field3) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field4) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field5) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field6) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field7) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field8) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field9) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field10) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK(_field11) \ + NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER \ + NS_IMPL_CYCLE_COLLECTION_UNLINK_END \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(_class) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field1) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field2) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field3) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field4) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field5) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field6) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field7) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field8) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field9) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field10) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE(_field11) \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS \ + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END \ + NS_IMPL_CYCLE_COLLECTION_TRACE_WRAPPERCACHE(_class) + #endif /* nsWrapperCache_h___ */
--- a/dom/indexedDB/ipc/IndexedDBParent.cpp +++ b/dom/indexedDB/ipc/IndexedDBParent.cpp @@ -77,17 +77,19 @@ IndexedDBParent::IndexedDBParent(TabPare IndexedDBParent::~IndexedDBParent() { MOZ_COUNT_DTOR(IndexedDBParent); } void IndexedDBParent::Disconnect() { - MOZ_ASSERT(!mDisconnected); + if (mDisconnected) { + return; + } mDisconnected = true; const InfallibleTArray<PIndexedDBDatabaseParent*>& databases = ManagedPIndexedDBDatabaseParent(); for (uint32_t i = 0; i < databases.Length(); ++i) { static_cast<IndexedDBDatabaseParent*>(databases[i])->Disconnect(); }
--- a/dom/locales/en-US/chrome/layout/HtmlForm.properties +++ b/dom/locales/en-US/chrome/layout/HtmlForm.properties @@ -23,13 +23,16 @@ NoFileSelected=No file selected. # LOCALIZATION NOTE (NoFilesSelected): this string is shown on a # <input type='file' multiple> when there is no file selected yet. NoFilesSelected=No files selected. # LOCALIZATION NOTE (XFilesSelected): this string is shown on a # <input type='file' multiple> when there are more than one selected file. # %S will be a number greater or equal to 2. XFilesSelected=%S files selected. ColorPicker=Choose a color -# LOCALIZATION NOTE (AndXMoreFiles): this string is shown at the end of the -# tooltip text for <input type='file' multiple> when there are more than 21 -# files selected (when we will only list the first 20, plus an "and X more" -# line). %S will be the number of files minus 20. -AndXMoreFiles=and %S more +# LOCALIZATION NOTE (AndNMoreFiles): Semi-colon list of plural forms. +# See: http://developer.mozilla.org/en/docs/Localization_and_Plurals +# This string is shown at the end of the tooltip text for <input type='file' +# multiple> when there are more than 21 files selected (when we will only list +# the first 20, plus an "and X more" line). #1 represents the number of files +# minus 20 and will always be a number equal to or greater than 2. So the +# singular case will never be used. +AndNMoreFiles=and one more;and #1 more
--- a/dom/mobilemessage/src/gonk/MmsService.js +++ b/dom/mobilemessage/src/gonk/MmsService.js @@ -2013,19 +2013,29 @@ MmsService.prototype = { }; // Update the delivery status to pending in DB. gMobileMessageDatabaseService .setMessageDeliveryByMessageId(aMessageId, null, null, DELIVERY_STATUS_PENDING, null, - this.retrieveMessage(url, - responseNotify.bind(this), - aDomMessage)); + (function (rv) { + let success = Components.isSuccessCode(rv); + if (!success) { + if (DEBUG) debug("Could not change the delivery status: MMS " + + domMessage.id + ", error code " + rv); + aRequest.notifyGetMessageFailed(Ci.nsIMobileMessageCallback.INTERNAL_ERROR); + return; + } + + this.retrieveMessage(url, + responseNotify.bind(this), + aDomMessage); + }).bind(this)); }).bind(this)); }, // nsIWapPushApplication receiveWapPush: function receiveWapPush(array, length, offset, options) { let data = {array: array, offset: offset}; let msg = MMS.PduHelper.parse(data, null);
--- a/dom/plugins/base/nsPluginInstanceOwner.cpp +++ b/dom/plugins/base/nsPluginInstanceOwner.cpp @@ -52,16 +52,17 @@ using mozilla::DefaultXDisplay; #include "nsIObjectLoadingContent.h" #include "nsAttrName.h" #include "nsIFocusManager.h" #include "nsFocusManager.h" #include "nsIDOMDragEvent.h" #include "nsIScrollableFrame.h" #include "nsIDocShell.h" #include "ImageContainer.h" +#include "nsIDOMHTMLCollection.h" #include "nsContentCID.h" #include "nsWidgetsCID.h" static NS_DEFINE_CID(kWidgetCID, NS_CHILD_CID); static NS_DEFINE_CID(kAppShellCID, NS_APPSHELL_CID); #ifdef XP_WIN #include <wtypes.h>
--- a/dom/system/gonk/RadioInterfaceLayer.js +++ b/dom/system/gonk/RadioInterfaceLayer.js @@ -3227,16 +3227,18 @@ RadioInterface.prototype = { this.workerMessenger.send("deactivateDataCall", { cid: cid, reason: reason }); }, }; function RILNetworkInterface(radioInterface, apnSetting) { this.radioInterface = radioInterface; this.apnSetting = apnSetting; + + this.connectedTypes = []; } RILNetworkInterface.prototype = { classID: RILNETWORKINTERFACE_CID, classInfo: XPCOMUtils.generateCI({classID: RILNETWORKINTERFACE_CID, classDescription: "RILNetworkInterface", interfaces: [Ci.nsINetworkInterface, Ci.nsIRILDataCallback]}), @@ -3397,22 +3399,22 @@ RILNetworkInterface.prototype = { }, // Helpers cid: null, registeredAsDataCallCallback: false, registeredAsNetworkInterface: false, connecting: false, - apnSetting: {}, + apnSetting: null, // APN failed connections. Retry counter apnRetryCounter: 0, - connectedTypes: [], + connectedTypes: null, inConnectedTypes: function inConnectedTypes(type) { return this.connectedTypes.indexOf(type) != -1; }, get connected() { return this.state == RIL.GECKO_NETWORK_STATE_CONNECTED; },
--- a/dom/webidl/WebGL2RenderingContext.webidl +++ b/dom/webidl/WebGL2RenderingContext.webidl @@ -65,17 +65,30 @@ interface WebGL2RenderingContext : WebGL const GLenum QUERY_RESULT_AVAILABLE = 0x8867; /* instanced array */ const GLenum VERTEX_ATTRIB_ARRAY_DIVISOR = 0x88FE; void vertexAttribDivisor(GLuint index, GLuint divisor); /* transform feedback */ - const GLenum RASTERIZER_DISCARD = 0x8C89; + const GLenum RASTERIZER_DISCARD = 0x8C89; + const GLenum TRANSFORM_FEEDBACK_BUFFER = 0x8C8E; + const GLenum TRANSFORM_FEEDBACK_BUFFER_BINDING = 0x8C8F; + const GLenum TRANSFORM_FEEDBACK_BUFFER_START = 0x8C84; + const GLenum TRANSFORM_FEEDBACK_BUFFER_SIZE = 0x8C85; + const GLenum MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS = 0x8C8B; + + /* buffer objects */ + void bindBufferBase(GLenum target, GLuint index, WebGLBuffer? buffer); + void bindBufferRange(GLenum target, GLuint index, WebGLBuffer? buffer, + GLintptr offset, GLsizeiptr size); + + /* state requests */ + any getParameterIndexed(GLenum pname, GLuint index); void beginQuery(GLenum target, WebGLQuery? queryObject); void bindVertexArray(WebGLVertexArray? arrayObject); WebGLQuery? createQuery(); WebGLVertexArray? createVertexArray(); void drawArraysInstanced(GLenum mode, GLint first, GLsizei count, GLsizei primcount); void drawBuffers(sequence<GLenum> buffers);
--- a/dom/wifi/WifiWorker.js +++ b/dom/wifi/WifiWorker.js @@ -159,17 +159,21 @@ var WifiManager = (function() { function voidControlMessage(cmd, callback) { controlMessage({ cmd: cmd }, function (data) { callback(data.status); }); } var driverLoaded = false; - manager.getDriverLoaded = function() { return driverLoaded; } + manager.checkDriverState = function(expectState) { + if (!unloadDriverEnabled) + return true; + return (expectState === driverLoaded); + } function loadDriver(callback) { if (driverLoaded) { callback(0); return; } voidControlMessage("load_driver", function(status) { @@ -2838,59 +2842,59 @@ WifiWorker.prototype = { }, _notifyAfterStateChange: function(success, newState) { if (!this._stateRequests.length) return; // First, notify all of the requests that were trying to make this change. let state = this._stateRequests[0].enabled; - let driverLoaded = WifiManager.getDriverLoaded(); + let driverReady = WifiManager.checkDriverState(newState); // It is callback function's responsibility to handle the pending request. // So we just return here. if (this._stateRequests.length > 0 && ("callback" in this._stateRequests[0])) { return; } // If the new state is not the same as state or new state is not the same as // driver loaded state, then we weren't processing the first request (we // were racing somehow) so don't notify. // For newState is false(disable), we expect driverLoaded is false(driver unloaded) // to proceed, and vice versa. - if (!success || (newState === driverLoaded && state === newState)) { + if (!success || (driverReady && state === newState)) { do { if (!("callback" in this._stateRequests[0])) { this._stateRequests.shift(); } // Don't remove more than one request if the previous one failed. } while (success && this._stateRequests.length && !("callback" in this._stateRequests[0]) && this._stateRequests[0].enabled === state); } // If there were requests queued after this one, run them. if (this._stateRequests.length > 0) { let self = this; let callback = null; this._callbackTimer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); - if (newState === driverLoaded) { - // Driver status is as same as new state, proceed next request. + if (driverReady) { + // Driver is ready for next request. callback = function(timer) { if ("callback" in self._stateRequests[0]) { self._stateRequests[0].callback.call(self, self._stateRequests[0].enabled); } else { WifiManager.setWifiEnabled(self._stateRequests[0].enabled, self._setWifiEnabledCallback.bind(self)); } timer = null; }; } else { - // Driver status is not as same as new state, wait driver. + // Wait driver until it's ready. callback = function(timer) { self._notifyAfterStateChange(success, newState); timer = null; }; } this._callbackTimer.initWithCallback(callback, 1000, Ci.nsITimer.TYPE_ONE_SHOT); } },
--- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -649,16 +649,105 @@ GLContext::InitWithPrefix(const char *pr if (!LoadSymbols(instancedArraySymbols, trygl, prefix)) { NS_ERROR("GL supports array instanced without supplying it function."); mInitialized &= MarkExtensionGroupUnsupported(XXX_instanced_arrays); mSymbols.fVertexAttribDivisor = nullptr; } } + if (IsExtensionSupported(XXX_transform_feedback)) { + SymLoadStruct transformFeedbackSymbols[] = { + { (PRFuncPtr*) &mSymbols.fBindBufferBase, + { "BindBufferBase", + "BindBufferBaseEXT", + "BindBufferBaseNV", + nullptr + } + }, + { (PRFuncPtr*) &mSymbols.fBindBufferRange, + { "BindBufferRange", + "BindBufferRangeEXT", + "BindBufferRangeNV", + nullptr + } + }, + { (PRFuncPtr*) &mSymbols.fBeginTransformFeedback, + { "BeginTransformFeedback", + "BeginTransformFeedbackEXT", + "BeginTransformFeedbackNV", + nullptr + } + }, + { (PRFuncPtr*) &mSymbols.fEndTransformFeedback, + { "EndTransformFeedback", + "EndTransformFeedbackEXT", + "EndTransformFeedbackNV", + nullptr + } + }, + { (PRFuncPtr*) &mSymbols.fTransformFeedbackVaryings, + { "TransformFeedbackVaryings", + "TransformFeedbackVaryingsEXT", + "TransformFeedbackVaryingsNV", + nullptr + } + }, + { (PRFuncPtr*) &mSymbols.fGetTransformFeedbackVarying, + { "GetTransformFeedbackVarying", + "GetTransformFeedbackVaryingEXT", + "GetTransformFeedbackVaryingNV", + nullptr + } + }, + { (PRFuncPtr*) &mSymbols.fGetIntegeri_v, + { "GetIntegeri_v", + "GetIntegerIndexedvEXT", + "GetIntegerIndexedvNV", + nullptr + } + }, + { nullptr, { nullptr } }, + }; + + if (!LoadSymbols(transformFeedbackSymbols, trygl, prefix)) { + NS_ERROR("GL supports transform feedback without supplying its functions."); + + MarkExtensionGroupUnsupported(XXX_transform_feedback); + MarkExtensionGroupUnsupported(XXX_bind_buffer_offset); + mSymbols.fBindBufferBase = nullptr; + mSymbols.fBindBufferRange = nullptr; + mSymbols.fBeginTransformFeedback = nullptr; + mSymbols.fEndTransformFeedback = nullptr; + mSymbols.fTransformFeedbackVaryings = nullptr; + mSymbols.fGetTransformFeedbackVarying = nullptr; + mSymbols.fGetIntegeri_v = nullptr; + } + } + + if (IsExtensionSupported(XXX_bind_buffer_offset)) { + SymLoadStruct bindBufferOffsetSymbols[] = { + { (PRFuncPtr*) &mSymbols.fBindBufferOffset, + { "BindBufferOffset", + "BindBufferOffsetEXT", + "BindBufferOffsetNV", + nullptr + } + }, + { nullptr, { nullptr } }, + }; + + if (!LoadSymbols(bindBufferOffsetSymbols, trygl, prefix)) { + NS_ERROR("GL supports BindBufferOffset without supplying its function."); + + MarkExtensionGroupUnsupported(XXX_bind_buffer_offset); + mSymbols.fBindBufferOffset = nullptr; + } + } + if (IsExtensionSupported(XXX_query_objects)) { SymLoadStruct queryObjectsSymbols[] = { { (PRFuncPtr*) &mSymbols.fBeginQuery, { "BeginQuery", "BeginQueryEXT", nullptr } }, { (PRFuncPtr*) &mSymbols.fGenQueries, { "GenQueries", "GenQueriesEXT", nullptr } }, { (PRFuncPtr*) &mSymbols.fDeleteQueries, { "DeleteQueries", "DeleteQueriesEXT", nullptr } }, { (PRFuncPtr*) &mSymbols.fEndQuery, { "EndQuery", "EndQueryEXT", nullptr } }, { (PRFuncPtr*) &mSymbols.fGetQueryiv, { "GetQueryiv", "GetQueryivEXT", nullptr } }, { (PRFuncPtr*) &mSymbols.fGetQueryObjectuiv, { "GetQueryObjectuiv", "GetQueryObjectuivEXT", nullptr } },
--- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -469,16 +469,17 @@ protected: * regardless if it is an ARB, EXT, OES, etc. */ public: /** * This enum should be sorted by name. */ enum GLExtensionGroup { + XXX_bind_buffer_offset, XXX_depth_texture, XXX_draw_buffers, XXX_draw_instanced, XXX_element_index_uint, XXX_ES2_compatibility, XXX_ES3_compatibility, XXX_framebuffer_blit, XXX_framebuffer_multisample, @@ -2030,16 +2031,28 @@ public: BEFORE_GL_CALL; ASSERT_SYMBOL_PRESENT(fEGLImageTargetRenderbufferStorage); mSymbols.fEGLImageTargetRenderbufferStorage(target, image); AFTER_GL_CALL; } // ----------------------------------------------------------------------------- +// Package XXX_bind_buffer_offset +public: + void fBindBufferOffset(GLenum target, GLuint index, GLuint buffer, GLintptr offset) + { + BEFORE_GL_CALL; + ASSERT_SYMBOL_PRESENT(fBindBufferOffset); + mSymbols.fBindBufferOffset(target, index, buffer, offset); + AFTER_GL_CALL; + } + + +// ----------------------------------------------------------------------------- // Package XXX_draw_buffers public: void fDrawBuffers(GLsizei n, const GLenum* bufs) { BEFORE_GL_CALL; mSymbols.fDrawBuffers(n, bufs); AFTER_GL_CALL; } @@ -2183,16 +2196,76 @@ public: BEFORE_GL_CALL; ASSERT_SYMBOL_PRESENT(fGetQueryObjectiv); mSymbols.fGetQueryObjectiv(id, pname, params); AFTER_GL_CALL; } // ----------------------------------------------------------------------------- +// Package XXX_transform_feedback +public: + void fBindBufferBase(GLenum target, GLuint index, GLuint buffer) + { + BEFORE_GL_CALL; + ASSERT_SYMBOL_PRESENT(fBindBufferBase); + mSymbols.fBindBufferBase(target, index, buffer); + AFTER_GL_CALL; + } + + void fBindBufferRange(GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) + { + BEFORE_GL_CALL; + ASSERT_SYMBOL_PRESENT(fBindBufferRange); + mSymbols.fBindBufferRange(target, index, buffer, offset, size); + AFTER_GL_CALL; + } + + void fBeginTransformFeedback(GLenum primitiveMode) + { + BEFORE_GL_CALL; + ASSERT_SYMBOL_PRESENT(fBeginTransformFeedback); + mSymbols.fBeginTransformFeedback(primitiveMode); + AFTER_GL_CALL; + } + + void fEndTransformFeedback() + { + BEFORE_GL_CALL; + ASSERT_SYMBOL_PRESENT(fEndTransformFeedback); + mSymbols.fEndTransformFeedback(); + AFTER_GL_CALL; + } + + void fTransformFeedbackVaryings(GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode) + { + BEFORE_GL_CALL; + ASSERT_SYMBOL_PRESENT(fTransformFeedbackVaryings); + mSymbols.fTransformFeedbackVaryings(program, count, varyings, bufferMode); + AFTER_GL_CALL; + } + + void fGetTransformFeedbackVarying(GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name) + { + BEFORE_GL_CALL; + ASSERT_SYMBOL_PRESENT(fGetTransformFeedbackVarying); + mSymbols.fGetTransformFeedbackVarying(program, index, bufSize, length, size, type, name); + AFTER_GL_CALL; + } + + void fGetIntegeri_v(GLenum param, GLuint index, GLint* values) + { + BEFORE_GL_CALL; + ASSERT_SYMBOL_PRESENT(fGetIntegeri_v); + mSymbols.fGetIntegeri_v(param, index, values); + AFTER_GL_CALL; + } + + +// ----------------------------------------------------------------------------- // Package XXX_vertex_array_object public: void GLAPIENTRY fBindVertexArray(GLuint array) { BEFORE_GL_CALL; ASSERT_SYMBOL_PRESENT(fBindVertexArray); mSymbols.fBindVertexArray(array); AFTER_GL_CALL;
--- a/gfx/gl/GLContextExtensionGroupQueries.cpp +++ b/gfx/gl/GLContextExtensionGroupQueries.cpp @@ -23,16 +23,26 @@ struct ExtensionGroupInfo const char* mName; unsigned int mOpenGLVersion; unsigned int mOpenGLESVersion; GLContext::GLExtensions mExtensions[kMAX_EXTENSION_GROUP_SIZE]; }; static const ExtensionGroupInfo sExtensionGroupInfoArr[] = { { + "XXX_bind_buffer_offset", + 0, // OpenGL version + 0, // OpenGL ES version + { + GLContext::EXT_transform_feedback, + GLContext::NV_transform_feedback, + GLContext::Extensions_End + } + }, + { "XXX_depth_texture", 200, // OpenGL version 300, // OpenGL ES version { GLContext::ARB_depth_texture, GLContext::OES_depth_texture, GLContext::Extensions_End }
--- a/gfx/gl/GLContextProviderGLX.cpp +++ b/gfx/gl/GLContextProviderGLX.cpp @@ -258,16 +258,17 @@ GLXLibrary::EnsureInitialized(LibType li } if (HasExtension(extensionsStr, "GLX_ARB_create_context_robustness") && GLLibraryLoader::LoadSymbols(mOGLLibrary, symbols_robustness)) { mHasRobustness = true; } mIsATI = serverVendor && DoesStringMatch(serverVendor, "ATI"); + mIsNVIDIA = serverVendor && DoesStringMatch(serverVendor, "NVIDIA Corporation"); mClientIsMesa = clientVendor && DoesStringMatch(clientVendor, "Mesa"); mInitialized = true; mLibType = libType; return true; } @@ -362,17 +363,20 @@ GLXLibrary::CreatePixmap(gfxASurface* aS // Usually GLX counts only color bits in the Visual depth, but the // depth of Composite's ARGB Visual includes alpha bits. However, // bits not in the color masks are not necessarily alpha bits because // sometimes (NVIDIA) 32 bit Visuals are added for fbconfigs with 32 // bit BUFFER_SIZE but zero alpha bits and 24 color bits (NVIDIA // again). // // This checks that the depth matches in one of the two ways. - if (depth != format->depth && depth != format->depth - alphaSize) { + // NVIDIA now forces format->depth == depth so only the first way + // is checked for NVIDIA + if (depth != format->depth && + (mIsNVIDIA || depth != format->depth - alphaSize) ) { continue; } // If all bits of the Pixmap are color bits and the Pixmap depth // matches the depth of the fbconfig visual, then we can assume that // the driver will do whatever is necessary to ensure that any // GLXPixmap alpha bits are treated as set. We can skip the // ALPHA_SIZE check in this situation. We need to skip this check for
--- a/gfx/gl/GLContextSymbols.h +++ b/gfx/gl/GLContextSymbols.h @@ -414,14 +414,37 @@ struct GLContextSymbols typedef void (GLAPIENTRY * PFNGLDRAWARRAYSINSTANCED) (GLenum mode, GLint first, GLsizei count, GLsizei primcount); PFNGLDRAWARRAYSINSTANCED fDrawArraysInstanced; typedef void (GLAPIENTRY * PFNGLDRAWELEMENTSINSTANCED) (GLenum mode, GLsizei count, GLenum type, const GLvoid* indices, GLsizei primcount); PFNGLDRAWELEMENTSINSTANCED fDrawElementsInstanced; // ARB_instanced_array typedef void (GLAPIENTRY * PFNGLVERTEXATTRIBDIVISOR) (GLuint index, GLuint divisor); PFNGLVERTEXATTRIBDIVISOR fVertexAttribDivisor; + + // EXT_transform_feedback / OpenGL (ES) 3.0 + typedef void (GLAPIENTRY * PFNGLBINDBUFFERBASE) (GLenum target, GLuint index, GLuint buffer); + PFNGLBINDBUFFERBASE fBindBufferBase; + typedef void (GLAPIENTRY * PFNGLBINDBUFFERRANGE) (GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); + PFNGLBINDBUFFERRANGE fBindBufferRange; + + typedef void (GLAPIENTRY * PFNGLBEGINTRANSFORMFEEDBACK) (GLenum primitiveMode); + PFNGLBEGINTRANSFORMFEEDBACK fBeginTransformFeedback; + typedef void (GLAPIENTRY * PFNGLENDTRANSFORMFEEDBACK) (void); + PFNGLENDTRANSFORMFEEDBACK fEndTransformFeedback; + + typedef void (GLAPIENTRY * PFNGLTRANSFORMFEEDBACKVARYINGS) (GLuint program, GLsizei count, const GLchar* const* varyings, GLenum bufferMode); + PFNGLTRANSFORMFEEDBACKVARYINGS fTransformFeedbackVaryings; + typedef void (GLAPIENTRY * PFNGLGETTRANSFORMFEEDBACKVARYING) (GLuint program, GLuint index, GLsizei bufSize, GLsizei* length, GLsizei* size, GLenum* type, GLchar* name); + PFNGLGETTRANSFORMFEEDBACKVARYING fGetTransformFeedbackVarying; + + typedef void (GLAPIENTRY * PFNGLGETINTEGERI_V) (GLenum param, GLuint index, GLint* values); + PFNGLGETINTEGERI_V fGetIntegeri_v; + + // EXT_transform_feedback only + typedef void (GLAPIENTRY * PFNGLBINDBUFFEROFFSET) (GLenum target, GLuint index, GLuint buffer, GLintptr offset); + PFNGLBINDBUFFEROFFSET fBindBufferOffset; }; } } #endif /* GLCONTEXTSYMBOLS_H_ */
--- a/gfx/gl/GLXLibrary.h +++ b/gfx/gl/GLXLibrary.h @@ -13,17 +13,17 @@ typedef realGLboolean GLboolean; namespace mozilla { namespace gl { class GLXLibrary { public: GLXLibrary() : mInitialized(false), mTriedInitializing(false), mUseTextureFromPixmap(false), mDebug(false), - mHasRobustness(false), mIsATI(false), + mHasRobustness(false), mIsATI(false), mIsNVIDIA(false), mClientIsMesa(false), mGLXMajorVersion(0), mGLXMinorVersion(0), mLibType(OPENGL_LIB), mOGLLibrary(nullptr) {} void xDestroyContext(Display* display, GLXContext context); Bool xMakeCurrent(Display* display, GLXDrawable drawable, GLXContext context); @@ -197,16 +197,17 @@ private: #endif bool mInitialized; bool mTriedInitializing; bool mUseTextureFromPixmap; bool mDebug; bool mHasRobustness; bool mIsATI; + bool mIsNVIDIA; bool mClientIsMesa; int mGLXMajorVersion; int mGLXMinorVersion; LibraryType mLibType; PRLibrary *mOGLLibrary; }; // a global GLXLibrary instance
--- a/image/src/Decoder.cpp +++ b/image/src/Decoder.cpp @@ -338,16 +338,17 @@ Decoder::PostFrameStop(FrameBlender::Fra if (aFrameAlpha == FrameBlender::kFrameOpaque) { mCurrentFrame->SetHasNoAlpha(); } mCurrentFrame->SetFrameDisposalMethod(aDisposalMethod); mCurrentFrame->SetTimeout(aTimeout); mCurrentFrame->SetBlendMethod(aBlendMethod); + mCurrentFrame->ImageUpdated(mCurrentFrame->GetRect()); // Flush any invalidations before we finish the frame FlushInvalidations(); // Fire notifications if (mObserver) { mObserver->OnStopFrame(); if (mFrameCount > 1 && !mIsAnimated) {
--- a/intl/uconv/src/nsConverterInputStream.cpp +++ b/intl/uconv/src/nsConverterInputStream.cpp @@ -3,16 +3,17 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsConverterInputStream.h" #include "nsIInputStream.h" #include "nsICharsetConverterManager.h" #include "nsIServiceManager.h" #include "nsReadLine.h" +#include "nsStreamUtils.h" #include <algorithm> #define CONVERTER_BUFFER_SIZE 8192 NS_IMPL_ISUPPORTS3(nsConverterInputStream, nsIConverterInputStream, nsIUnicharInputStream, nsIUnicharLineInputStream) static NS_DEFINE_CID(kCharsetConverterManagerCID, NS_ICHARSETCONVERTERMANAGER_CID); @@ -34,21 +35,20 @@ nsConverterInputStream::Init(nsIInputStr nsCOMPtr<nsICharsetConverterManager> ccm = do_GetService(kCharsetConverterManagerCID, &rv); if (NS_FAILED(rv)) return rv; rv = ccm->GetUnicodeDecoder(aCharset ? aCharset : "ISO-8859-1", getter_AddRefs(mConverter)); if (NS_FAILED(rv)) return rv; // set up our buffers - rv = NS_NewByteBuffer(getter_AddRefs(mByteData), nullptr, aBufferSize); - if (NS_FAILED(rv)) return rv; - - rv = NS_NewUnicharBuffer(getter_AddRefs(mUnicharData), nullptr, aBufferSize); - if (NS_FAILED(rv)) return rv; + if (!mByteData.SetCapacity(aBufferSize) || + !mUnicharData.SetCapacity(aBufferSize)) { + return NS_ERROR_OUT_OF_MEMORY; + } mInput = aStream; mReplacementChar = aReplacementChar; if (!aReplacementChar || aReplacementChar != mConverter->GetCharacterForUnMapped()) { mConverter->SetInputErrorBehavior(nsIUnicodeDecoder::kOnError_Signal); } @@ -57,18 +57,18 @@ nsConverterInputStream::Init(nsIInputStr NS_IMETHODIMP nsConverterInputStream::Close() { nsresult rv = mInput ? mInput->Close() : NS_OK; mLineBuffer = nullptr; mInput = nullptr; mConverter = nullptr; - mByteData = nullptr; - mUnicharData = nullptr; + mByteData.Clear(); + mUnicharData.Clear(); return rv; } NS_IMETHODIMP nsConverterInputStream::Read(PRUnichar* aBuf, uint32_t aCount, uint32_t *aReadCount) { @@ -80,17 +80,17 @@ nsConverterInputStream::Read(PRUnichar* if (readCount == 0) { *aReadCount = 0; return mLastErrorCode; } } if (readCount > aCount) { readCount = aCount; } - memcpy(aBuf, mUnicharData->GetBuffer() + mUnicharDataOffset, + memcpy(aBuf, mUnicharData.Elements() + mUnicharDataOffset, readCount * sizeof(PRUnichar)); mUnicharDataOffset += readCount; *aReadCount = readCount; return NS_OK; } NS_IMETHODIMP nsConverterInputStream::ReadSegments(nsWriteUnicharSegmentFun aWriter, @@ -112,17 +112,17 @@ nsConverterInputStream::ReadSegments(nsW if (bytesToWrite > aCount) bytesToWrite = aCount; uint32_t bytesWritten; uint32_t totalBytesWritten = 0; while (bytesToWrite) { rv = aWriter(this, aClosure, - mUnicharData->GetBuffer() + mUnicharDataOffset, + mUnicharData.Elements() + mUnicharDataOffset, totalBytesWritten, bytesToWrite, &bytesWritten); if (NS_FAILED(rv)) { // don't propagate errors to the caller break; } bytesToWrite -= bytesWritten; totalBytesWritten += bytesWritten; @@ -147,18 +147,17 @@ nsConverterInputStream::ReadString(uint3 if (readCount == 0) { *aReadCount = 0; return mLastErrorCode; } } if (readCount > aCount) { readCount = aCount; } - const PRUnichar* buf = reinterpret_cast<const PRUnichar*>(mUnicharData->GetBuffer() + - mUnicharDataOffset); + const PRUnichar* buf = mUnicharData.Elements() + mUnicharDataOffset; aString.Assign(buf, readCount); mUnicharDataOffset += readCount; *aReadCount = readCount; return NS_OK; } uint32_t nsConverterInputStream::Fill(nsresult * aErrorCode) @@ -177,66 +176,61 @@ nsConverterInputStream::Fill(nsresult * } // We assume a many to one conversion and are using equal sizes for // the two buffers. However if an error happens at the very start // of a byte buffer we may end up in a situation where n bytes lead // to n+1 unicode chars. Thus we need to keep track of the leftover // bytes as we convert. - int32_t nb = mByteData->Fill(aErrorCode, mInput, mLeftOverBytes); -#if defined(DEBUG_bzbarsky) && 0 - for (unsigned int foo = 0; foo < mByteData->GetLength(); ++foo) { - fprintf(stderr, "%c", mByteData->GetBuffer()[foo]); - } - fprintf(stderr, "\n"); -#endif - if (nb <= 0 && mLeftOverBytes == 0) { + uint32_t nb; + *aErrorCode = NS_FillArray(mByteData, mInput, mLeftOverBytes, &nb); + if (nb == 0 && mLeftOverBytes == 0) { // No more data *aErrorCode = NS_OK; return 0; } - NS_ASSERTION(uint32_t(nb) + mLeftOverBytes == mByteData->GetLength(), + NS_ASSERTION(uint32_t(nb) + mLeftOverBytes == mByteData.Length(), "mByteData is lying to us somewhere"); - + // Now convert as much of the byte buffer to unicode as possible mUnicharDataOffset = 0; mUnicharDataLength = 0; uint32_t srcConsumed = 0; do { - int32_t srcLen = mByteData->GetLength() - srcConsumed; - int32_t dstLen = mUnicharData->GetBufferSize() - mUnicharDataLength; - *aErrorCode = mConverter->Convert(mByteData->GetBuffer()+srcConsumed, + int32_t srcLen = mByteData.Length() - srcConsumed; + int32_t dstLen = mUnicharData.Capacity() - mUnicharDataLength; + *aErrorCode = mConverter->Convert(mByteData.Elements()+srcConsumed, &srcLen, - mUnicharData->GetBuffer()+mUnicharDataLength, + mUnicharData.Elements()+mUnicharDataLength, &dstLen); mUnicharDataLength += dstLen; // XXX if srcLen is negative, we want to drop the _first_ byte in // the erroneous byte sequence and try again. This is not quite // possible right now -- see bug 160784 srcConsumed += srcLen; if (NS_FAILED(*aErrorCode) && mReplacementChar) { - NS_ASSERTION(0 < mUnicharData->GetBufferSize() - mUnicharDataLength, + NS_ASSERTION(0 < mUnicharData.Capacity() - mUnicharDataLength, "Decoder returned an error but filled the output buffer! " "Should not happen."); - mUnicharData->GetBuffer()[mUnicharDataLength++] = mReplacementChar; + mUnicharData.Elements()[mUnicharDataLength++] = mReplacementChar; ++srcConsumed; // XXX this is needed to make sure we don't underrun our buffer; // bug 160784 again srcConsumed = std::max<uint32_t>(srcConsumed, 0); mConverter->Reset(); } - NS_ASSERTION(srcConsumed <= mByteData->GetLength(), + NS_ASSERTION(srcConsumed <= mByteData.Length(), "Whoa. The converter should have returned NS_OK_UDEC_MOREINPUT before this point!"); } while (mReplacementChar && NS_FAILED(*aErrorCode) && - uint32_t(mUnicharData->GetBufferSize()) > mUnicharDataLength); + mUnicharData.Capacity() > mUnicharDataLength); - mLeftOverBytes = mByteData->GetLength() - srcConsumed; + mLeftOverBytes = mByteData.Length() - srcConsumed; return mUnicharDataLength; } NS_IMETHODIMP nsConverterInputStream::ReadLine(nsAString& aLine, bool* aResult) { if (!mLineBuffer) {
--- a/intl/uconv/src/nsConverterInputStream.h +++ b/intl/uconv/src/nsConverterInputStream.h @@ -2,22 +2,20 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsIInputStream.h" #include "nsIConverterInputStream.h" #include "nsIUnicharLineInputStream.h" #include "nsString.h" - +#include "nsTArray.h" #include "nsAutoPtr.h" #include "nsCOMPtr.h" #include "nsIUnicodeDecoder.h" -#include "nsIByteBuffer.h" -#include "nsIUnicharBuffer.h" #include "nsReadLine.h" #define NS_CONVERTERINPUTSTREAM_CONTRACTID "@mozilla.org/intl/converter-input-stream;1" // {2BC2AD62-AD5D-4b7b-A9DB-F74AE203C527} #define NS_CONVERTERINPUTSTREAM_CID \ { 0x2bc2ad62, 0xad5d, 0x4b7b, \ { 0xa9, 0xdb, 0xf7, 0x4a, 0xe2, 0x3, 0xc5, 0x27 } } @@ -44,18 +42,18 @@ class nsConverterInputStream : public ns virtual ~nsConverterInputStream() { Close(); } private: uint32_t Fill(nsresult *aErrorCode); nsCOMPtr<nsIUnicodeDecoder> mConverter; - nsCOMPtr<nsIByteBuffer> mByteData; - nsCOMPtr<nsIUnicharBuffer> mUnicharData; + FallibleTArray<char> mByteData; + FallibleTArray<PRUnichar> mUnicharData; nsCOMPtr<nsIInputStream> mInput; nsresult mLastErrorCode; uint32_t mLeftOverBytes; uint32_t mUnicharDataOffset; uint32_t mUnicharDataLength; PRUnichar mReplacementChar;
--- a/js/src/build/autoconf/hooks.m4 +++ b/js/src/build/autoconf/hooks.m4 @@ -14,17 +14,40 @@ dnl Wrap AC_INIT_PREPARE to add the abov define([_MOZ_AC_INIT_PREPARE], defn([AC_INIT_PREPARE])) define([AC_INIT_PREPARE], [_MOZ_AC_INIT_PREPARE($1) MOZ_CONFIG_LOG_TRAP ]) dnl Disable the trap when running sub-configures. define([_MOZ_AC_OUTPUT_SUBDIRS], defn([AC_OUTPUT_SUBDIRS])) +define([MOZ_SUBCONFIGURE_WRAP], +[ _CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} +case "$host" in +*-mingw*) + _CONFIG_SHELL=$(cd $(dirname $_CONFIG_SHELL); pwd -W)/$(basename $_CONFIG_SHELL) + if test ! -e "$_CONFIG_SHELL" -a -e "${_CONFIG_SHELL}.exe"; then + _CONFIG_SHELL="${_CONFIG_SHELL}.exe" + fi + ;; +esac + +if test -d "$1"; then + (cd "$1"; $PYTHON $_topsrcdir/build/subconfigure.py dump "$_CONFIG_SHELL") +fi +$2 +(cd "$1"; $PYTHON $_topsrcdir/build/subconfigure.py adjust) +]) + define([AC_OUTPUT_SUBDIRS], [trap '' EXIT -_MOZ_AC_OUTPUT_SUBDIRS($1) +for moz_config_dir in $1; do + MOZ_SUBCONFIGURE_WRAP([$moz_config_dir],[ + _MOZ_AC_OUTPUT_SUBDIRS($moz_config_dir) + ]) +done + MOZ_CONFIG_LOG_TRAP ]) dnl Print error messages in config.log as well as stderr define([AC_MSG_ERROR], [{ echo "configure: error: $1" 1>&2; echo "configure: error: $1" 1>&5; exit 1; }])
new file mode 100644 --- /dev/null +++ b/js/src/build/subconfigure.py @@ -0,0 +1,124 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +# This script is used to capture the content of config.status-generated +# files and subsequently restore their timestamp if they haven't changed. + +import os +import re +import subprocess +import sys +import pickle + +class File(object): + def __init__(self, path): + self._path = path + self._content = open(path, 'rb').read() + stat = os.stat(path) + self._times = (stat.st_atime, stat.st_mtime) + + def update_time(self): + '''If the file hasn't changed since the instance was created, + restore its old modification time.''' + if not os.path.exists(self._path): + return + if open(self._path, 'rb').read() == self._content: + os.utime(self._path, self._times) + + +# As defined in the various sub-configures in the tree +PRECIOUS_VARS = set([ + 'build_alias', + 'host_alias', + 'target_alias', + 'CC', + 'CFLAGS', + 'LDFLAGS', + 'LIBS', + 'CPPFLAGS', + 'CPP', + 'CCC', + 'CXXFLAGS', + 'CXX', + 'CCASFLAGS', + 'CCAS', +]) + + +# Autoconf, in some of the sub-configures used in the tree, likes to error +# out when "precious" variables change in value. The solution it gives to +# straighten things is to either run make distclean or remove config.cache. +# There's no reason not to do the latter automatically instead of failing, +# doing the cleanup (which, on buildbots means a full clobber), and +# restarting from scratch. +def maybe_clear_cache(): + comment = re.compile(r'^\s+#') + cache = {} + with open('config.cache') as f: + for line in f.readlines(): + if not comment.match(line) and '=' in line: + key, value = line.split('=', 1) + cache[key] = value + for precious in PRECIOUS_VARS: + entry = 'ac_cv_env_%s_value' % precious + if entry in cache and (not precious in os.environ or os.environ[precious] != cache[entry]): + os.remove('config.cache') + return + + +def dump(dump_file, shell): + if os.path.exists('config.cache'): + maybe_clear_cache() + if not os.path.exists('config.status'): + if os.path.exists(dump_file): + os.remove(dump_file) + return + + config_files = [File('config.status')] + + # Scan the config.status output for information about configuration files + # it generates. + config_status_output = subprocess.check_output( + [shell, '-c', './config.status --help'], + stderr=subprocess.STDOUT).splitlines() + state = None + for line in config_status_output: + if line.startswith('Configuration') and line.endswith(':'): + state = 'config' + elif not line.startswith(' '): + state = None + elif state == 'config': + for f in (couple.split(':')[0] for couple in line.split()): + if os.path.isfile(f): + config_files.append(File(f)) + + with open(dump_file, 'wb') as f: + pickle.dump(config_files, f) + + +def adjust(dump_file): + if not os.path.exists(dump_file): + return + + config_files = [] + + try: + with open(dump_file, 'rb') as f: + config_files = pickle.load(f) + except Exception: + pass + + for f in config_files: + f.update_time() + + os.remove(dump_file) + + +CONFIG_DUMP = 'config_files.pkl' + +if __name__ == '__main__': + if sys.argv[1] == 'dump': + dump(CONFIG_DUMP, sys.argv[2]) + elif sys.argv[1] == 'adjust': + adjust(CONFIG_DUMP)
--- a/js/src/config/makefiles/target_export.mk +++ b/js/src/config/makefiles/target_export.mk @@ -7,19 +7,19 @@ PARALLEL_DIRS_export = $(addsuffix _export,$(PARALLEL_DIRS)) .PHONY: export $(PARALLEL_DIRS_export) ############### ## TIER targets ############### -export_tier_%: +$(addprefix export_tier_,$(TIERS)): export_tier_%: @$(ECHO) "$@" - $(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,export,$(dir))) + $(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,$*,export,$(dir),export)) ################# ## Common targets ################# ifdef PARALLEL_DIRS export:: $(PARALLEL_DIRS_export) $(PARALLEL_DIRS_export): %_export: %/Makefile
--- a/js/src/config/makefiles/target_libs.mk +++ b/js/src/config/makefiles/target_libs.mk @@ -7,19 +7,19 @@ PARALLEL_DIRS_libs = $(addsuffix _libs,$(PARALLEL_DIRS)) .PHONY: libs $(PARALLEL_DIRS_libs) ############### ## TIER targets ############### -libs_tier_%: +$(addprefix libs_tier_,$(TIERS)): libs_tier_%: @$(ECHO) "$@" - $(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,libs,$(dir))) + $(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,$*,libs,$(dir),libs)) ################# ## Common targets ################# ifdef PARALLEL_DIRS libs:: $(PARALLEL_DIRS_libs) $(PARALLEL_DIRS_libs): %_libs: %/Makefile @@ -38,17 +38,17 @@ else EXPORT_LIBRARY = $(DEPTH)/staticlib endif else # If EXPORT_LIBRARY has a value, we'll be installing there. We also need to cleanup there GARBAGE += $(foreach lib,$(LIBRARY),$(EXPORT_LIBRARY)/$(lib)) endif endif # EXPORT_LIBRARY -libs:: $(SUBMAKEFILES) $(MAKE_DIRS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS) $(JAVA_LIBRARY) +libs:: $(SUBMAKEFILES) $(MAKE_DIRS) $(HOST_LIBRARY) $(LIBRARY) $(SHARED_LIBRARY) $(IMPORT_LIBRARY) $(HOST_PROGRAM) $(HOST_SIMPLE_PROGRAMS) $(SIMPLE_PROGRAMS) ifndef NO_DIST_INSTALL ifdef SHARED_LIBRARY ifdef IS_COMPONENT $(INSTALL) $(IFLAGS2) $(SHARED_LIBRARY) $(FINAL_TARGET)/components $(ELF_DYNSTR_GC) $(FINAL_TARGET)/components/$(SHARED_LIBRARY) ifndef NO_COMPONENTS_MANIFEST @$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/chrome.manifest "manifest components/components.manifest" @$(PYTHON) $(MOZILLA_DIR)/config/buildlist.py $(FINAL_TARGET)/components/components.manifest "binary-component $(SHARED_LIBRARY)" @@ -113,21 +113,11 @@ INSTALL_TARGETS += HOST_PROGRAMS endif ifdef HOST_LIBRARY HOST_LIBRARY_FILES = $(HOST_LIBRARY) HOST_LIBRARY_DEST ?= $(DIST)/host/lib INSTALL_TARGETS += HOST_LIBRARY endif -ifdef JAVA_LIBRARY -JAVA_LIBRARY_FILES = $(JAVA_LIBRARY) -ifdef IS_COMPONENT -JAVA_LIBRARY_DEST ?= $(FINAL_TARGET)/components -else -JAVA_LIBRARY_DEST ?= $(FINAL_TARGET) -endif -INSTALL_TARGETS += JAVA_LIBRARY -endif - endif # !NO_DIST_INSTALL # EOF
--- a/js/src/config/makefiles/target_tools.mk +++ b/js/src/config/makefiles/target_tools.mk @@ -7,19 +7,19 @@ PARALLEL_DIRS_tools = $(addsuffix _tools,$(PARALLEL_DIRS)) .PHONY: tools $(PARALLEL_DIRS_tools) ############### ## TIER targets ############### -tools_tier_%: +$(addprefix tools_tier_,$(TIERS)): tools_tier_%: @$(ECHO) "$@" - $(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,tools,$(dir))) + $(foreach dir,$(tier_$*_dirs),$(call TIER_DIR_SUBMAKE,$*,tools,$(dir),tools)) ################# ## Common targets ################# ifdef PARALLEL_DIRS tools:: $(PARALLEL_DIRS_tools) $(PARALLEL_DIRS_tools): %_tools: %/Makefile
--- a/js/src/config/rules.mk +++ b/js/src/config/rules.mk @@ -25,16 +25,17 @@ endif HOST_CSRCS \ HOST_LIBRARY_NAME \ MODULE \ NO_DIST_INSTALL \ PARALLEL_DIRS \ TEST_DIRS \ TIERS \ TOOL_DIRS \ + XPCSHELL_TESTS \ XPIDL_MODULE \ $(NULL) _DEPRECATED_VARIABLES := \ XPIDL_FLAGS \ $(NULL) ifndef EXTERNALLY_MANAGED_MAKE_FILE @@ -298,20 +299,16 @@ endif endif ifdef FORCE_SHARED_LIB ifndef FORCE_STATIC_LIB LIBRARY := $(NULL) endif endif -ifdef JAVA_LIBRARY_NAME -JAVA_LIBRARY := $(JAVA_LIBRARY_NAME).jar -endif - ifeq ($(OS_ARCH),WINNT) ifndef GNU_CC # # Unless we're building SIMPLE_PROGRAMS, all C++ files share a PDB file per # directory. For parallel builds, this PDB file is shared and locked by # MSPDBSRV.EXE, starting with MSVC8 SP1. If you're using MSVC 7.1 or MSVC8 # without SP1, don't do parallel builds. @@ -428,33 +425,34 @@ endif ifdef MOZ_UPDATE_XTERM # Its good not to have a newline at the end of the titlebar string because it # makes the make -s output easier to read. Echo -n does not work on all # platforms, but we can trick printf into doing it. UPDATE_TITLE = printf "\033]0;%s in %s\007" $(1) $(shell $(BUILD_TOOLS)/print-depth-path.sh)/$(2) ; endif ifdef MACH -BUILDSTATUS=@echo BUILDSTATUS $1 +BUILDSTATUS=@echo "BUILDSTATUS $1" endif + # Static directories are largely independent of our build system. But, they # could share the same build mechanism (like moz.build files). We need to # prevent leaking of our backend state to these independent build systems. This # is why MOZBUILD_BACKEND_CHECKED isn't exported to make invocations for static # directories. define SUBMAKE # $(call SUBMAKE,target,directory,static) +@$(UPDATE_TITLE) +$(if $(3), MOZBUILD_BACKEND_CHECKED=,) $(MAKE) $(if $(2),-C $(2)) $(1) endef # The extra line is important here! don't delete it define TIER_DIR_SUBMAKE -$(call BUILDSTATUS,TIERDIR_START $(2)) -$(call SUBMAKE,$(1),$(2),$(3)) -$(call BUILDSTATUS,TIERDIR_FINISH $(2)) +$(call BUILDSTATUS,TIERDIR_START $(1) $(2) $(3)) +$(call SUBMAKE,$(4),$(3),$(5)) +$(call BUILDSTATUS,TIERDIR_FINISH $(1) $(2) $(3)) endef # Ths empty line is important. ifneq (,$(strip $(DIRS))) LOOP_OVER_DIRS = \ $(foreach dir,$(DIRS),$(call SUBMAKE,$@,$(dir))) endif @@ -702,51 +700,57 @@ alldep:: $(MAKE) export $(MAKE) depend $(MAKE) libs $(MAKE) tools endif # TIERS endif # SUPPRESS_DEFAULT_RULES -ifeq ($(filter s,$(MAKEFLAGS)),) +ifeq ($(findstring s,$(filter-out --%, $(MAKEFLAGS))),) ECHO := echo QUIET := else ECHO := true QUIET := -q endif # This function is called and evaluated to produce the rule to build the -# specified tier. Each tier begins by building the "static" directories. -# The BUILDSTATUS echo commands are used to faciliate easier parsing -# of build output. Build drivers are encouraged to filter these lines -# from the user. +# specified tier. +# +# Tiers are traditionally composed of directories that are invoked either +# once (so-called "static" directories) or 3 times with the export, libs, and +# tools sub-tiers. +# +# If the TIER_$(tier)_CUSTOM variable is defined, then these traditional +# tier rules are ignored and each directory in the tier is executed via a +# sub-make invocation (make -C). define CREATE_TIER_RULE tier_$(1):: - $(call BUILDSTATUS,TIER_START $(1)) - $(call BUILDSTATUS,SUBTIERS $(if $(tier_$(1)_staticdirs),static )$(if $(tier_$(1)_dirs),export libs tools)) - $(call BUILDSTATUS,STATICDIRS $$($$@_staticdirs)) - $(call BUILDSTATUS,DIRS $$($$@_dirs)) +ifdef TIER_$(1)_CUSTOM + $$(foreach dir,$$($$@_dirs),$$(call SUBMAKE,,$$(dir))) +else + $(call BUILDSTATUS,TIER_START $(1) $(if $(tier_$(1)_staticdirs),static )$(if $(tier_$(1)_dirs),export libs tools)) ifneq (,$(tier_$(1)_staticdirs)) - $(call BUILDSTATUS,SUBTIER_START $(1) static) - $$(foreach dir,$$($$@_staticdirs),$$(call TIER_DIR_SUBMAKE,,$$(dir),1)) + $(call BUILDSTATUS,SUBTIER_START $(1) static $$($$@_staticdirs)) + $$(foreach dir,$$($$@_staticdirs),$$(call TIER_DIR_SUBMAKE,$(1),static,$$(dir),,1)) $(call BUILDSTATUS,SUBTIER_FINISH $(1) static) endif ifneq (,$(tier_$(1)_dirs)) - $(call BUILDSTATUS,SUBTIER_START $(1) export) + $(call BUILDSTATUS,SUBTIER_START $(1) export $$($$@_dirs)) $$(MAKE) export_$$@ $(call BUILDSTATUS,SUBTIER_FINISH $(1) export) - $(call BUILDSTATUS,SUBTIER_START $(1) libs) + $(call BUILDSTATUS,SUBTIER_START $(1) libs $$($$@_dirs)) $$(MAKE) libs_$$@ $(call BUILDSTATUS,SUBTIER_FINISH $(1) libs) - $(call BUILDSTATUS,SUBTIER_START $(1) tools) + $(call BUILDSTATUS,SUBTIER_START $(1) tools $$($$@_dirs)) $$(MAKE) tools_$$@ $(call BUILDSTATUS,SUBTIER_FINISH $(1) tools) - $(call BUILDSTATUS TIER_FINISH $(1)) +endif + $(call BUILDSTATUS,TIER_FINISH $(1)) endif endef $(foreach tier,$(TIERS),$(eval $(call CREATE_TIER_RULE,$(tier)))) # Do everything from scratch everything:: $(MAKE) clean @@ -1131,25 +1135,25 @@ endef $(COBJS): $(REPORT_BUILD) @$(MAKE_DEPS_AUTO_CC) $(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) # DEFINES and ACDEFINES are needed here to enable conditional compilation of Q_OBJECTs: # 'moc' only knows about #defines it gets on the command line (-D...), not in # included headers like mozilla-config.h -moc_%.cpp: %.h +$(filter moc_%.cpp,$(CPPSRCS)): moc_%.cpp: %.h $(REPORT_BUILD) $(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $< $(OUTOPTION)$@ -moc_%.cc: %.cc +$(filter moc_%.cc,$(CPPSRCS)): moc_%.cc: %.cc $(REPORT_BUILD) $(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $(_VPATH_SRCS:.cc=.h) $(OUTOPTION)$@ -qrc_%.cpp: %.qrc +$(filter qrc_%.cpp,$(CPPSRCS)): qrc_%.cpp: %.qrc $(REPORT_BUILD) $(ELOG) $(RCC) -name $* $< $(OUTOPTION)$@ ifdef ASFILES # The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept # a '-c' flag. $(ASOBJS): $(REPORT_BUILD) @@ -1170,72 +1174,62 @@ endif @$(MAKE_DEPS_AUTO_CXX) $(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) $(CMOBJS): $(REPORT_BUILD) @$(MAKE_DEPS_AUTO_CC) $(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) -%.s: %.cpp $(call mkdir_deps,$(MDDEPDIR)) +$(filter %.s,$(CPPSRCS:%.cpp=%.s)): %.s: %.cpp $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) $(CCC) -S $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) -%.s: %.cc $(call mkdir_deps,$(MDDEPDIR)) +$(filter %.s,$(CPPSRCS:%.cc=%.s)): %.s: %.cc $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) $(CCC) -S $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) -%.s: %.c $(call mkdir_deps,$(MDDEPDIR)) +$(filter %.s,$(CSRCS:%.c=%.s)): %.s: %.c $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) $(CC) -S $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) -%.i: %.cpp $(call mkdir_deps,$(MDDEPDIR)) +$(filter %.i,$(CPPSRCS:%.cpp=%.i)): %.i: %.cpp $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) $(CCC) -C -E $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i -%.i: %.cc $(call mkdir_deps,$(MDDEPDIR)) +$(filter %.i,$(CPPSRCS:%.cc=%.i)): %.i: %.cc $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) $(CCC) -C -E $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i -%.i: %.c $(call mkdir_deps,$(MDDEPDIR)) +$(filter %.i,$(CSRCS:%.c=%.i)): %.i: %.c $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) $(CC) -C -E $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i -%.i: %.mm $(call mkdir_deps,$(MDDEPDIR)) +$(filter %.i,$(CMMSRCS:%.mm=%.i)): %.i: %.mm $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) $(CCC) -C -E $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) > $*.i -%.res: %.rc +$(RESFILE): %.res: %.rc $(REPORT_BUILD) @echo Creating Resource file: $@ ifeq ($(OS_ARCH),OS2) $(RC) $(RCFLAGS:-D%=-d %) -i $(subst /,\,$(srcdir)) -r $< $@ else ifdef GNU_CC $(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES:-I%=--include-dir %) $(OUTOPTION)$@ $(_VPATH_SRCS) else $(RC) $(RCFLAGS) -r $(DEFINES) $(INCLUDES) $(OUTOPTION)$@ $(_VPATH_SRCS) endif endif -# Cancel these implicit rules -# -%: %,v - -%: RCS/%,v - -%: RCS/% +# Cancel GNU make built-in implicit rules +ifndef .PYMAKE +MAKEFLAGS += -r +endif -%: s.% - -%: SCCS/s.% - -############################################################################### -# Java rules -############################################################################### ifneq (,$(filter OS2 WINNT,$(OS_ARCH))) SEP := ; else SEP := : endif EMPTY := SPACE := $(EMPTY) $(EMPTY) @@ -1250,50 +1244,23 @@ ifeq ($(HOST_OS_ARCH),WINNT) # on it, then merge with the rest of the path. root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\1|") non-root-path = $(shell echo $(1) | sed -e "s|\(/[^/]*\)/\?\(.*\)|\2|") normalizepath = $(foreach p,$(1),$(if $(filter /%,$(1)),$(patsubst %/,%,$(shell cd $(call root-path,$(1)) && pwd -W))/$(call non-root-path,$(1)),$(1))) else normalizepath = $(1) endif +############################################################################### +# Java rules +############################################################################### ifneq (,$(value JAVAFILES)$(value RESFILES)) include $(topsrcdir)/config/makefiles/java-build.mk endif -_srcdir = $(call normalizepath,$(srcdir)) -ifdef JAVA_SOURCEPATH -SP = $(subst $(SPACE),$(SEP),$(call normalizepath,$(strip $(JAVA_SOURCEPATH)))) -_JAVA_SOURCEPATH = ".$(SEP)$(_srcdir)$(SEP)$(SP)" -else -_JAVA_SOURCEPATH = ".$(SEP)$(_srcdir)" -endif - -ifdef JAVA_CLASSPATH -CP = $(subst $(SPACE),$(SEP),$(call normalizepath,$(strip $(JAVA_CLASSPATH)))) -_JAVA_CLASSPATH = ".$(SEP)$(CP)" -else -_JAVA_CLASSPATH = . -endif - -_JAVA_DIR = _java -$(_JAVA_DIR):: - $(NSINSTALL) -D $@ - -$(_JAVA_DIR)/%.class: %.java $(GLOBAL_DEPS) $(_JAVA_DIR) - $(REPORT_BUILD) - $(JAVAC) $(JAVAC_FLAGS) -classpath $(_JAVA_CLASSPATH) \ - -sourcepath $(_JAVA_SOURCEPATH) -d $(_JAVA_DIR) $(_VPATH_SRCS) - -$(JAVA_LIBRARY): $(addprefix $(_JAVA_DIR)/,$(JAVA_SRCS:.java=.class)) $(GLOBAL_DEPS) - $(REPORT_BUILD) - $(JAR) cf $@ -C $(_JAVA_DIR) . - -GARBAGE_DIRS += $(_JAVA_DIR) - ############################################################################### # Update Files Managed by Build Backend ############################################################################### ifndef NO_MAKEFILE_RULE Makefile: Makefile.in @$(PYTHON) $(DEPTH)/config.status -n --file=Makefile @$(TOUCH) $@
--- a/js/src/configure.in +++ b/js/src/configure.in @@ -4356,25 +4356,27 @@ if test -n "$ENABLE_INTL_API" ; then ICU_BUILD_OPTS="$ICU_BUILD_OPTS --enable-debug" fi if test -z "$MOZ_OPTIMIZE"; then ICU_BUILD_OPTS="$ICU_BUILD_OPTS --disable-release" fi abs_srcdir=`(cd $srcdir; pwd)` mkdir -p $_objdir/intl/icu - (cd $_objdir/intl/icu; \ + (cd $_objdir/intl/icu + MOZ_SUBCONFIGURE_WRAP([.],[ CC="$CC" CXX="$CXX" \ CFLAGS="$ICU_CFLAGS" CPPFLAGS="$ICU_CPPFLAGS" CXXFLAGS="$ICU_CXXFLAGS" \ $SHELL $abs_srcdir/../../intl/icu/source/runConfigureICU \ $ICU_BUILD_OPTS \ $ICU_TARGET \ $ICU_LINK_OPTS \ --enable-extras=no --enable-icuio=no --enable-layout=no \ --enable-tests=no --enable-samples=no || exit 1 + ]) ) || exit 1 fi dnl ======================================================== dnl JavaScript shell dnl ========================================================
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug907085.js @@ -0,0 +1,22 @@ +try { + s.e +} catch (e) {} +o = o = s2 = /x/ +for (let e in []); +x = s2 +schedulegc(21) +eval("x.e=x.t") +try { + (function() { + this.eval("\ + (function(stdlib,fgn,heap) {\ + \"use asm\";\ + var Vie = new stdlib.Float64Array(heap);\ + var Iew = new stdlib.Int8Array(heap);\ + function f(){\ + ent\ + }\ + })()\ + ") + })() +} catch (e) {}
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug905989.js @@ -0,0 +1,10 @@ +function TestCase(n, d, e, a) {}; +function reportCompare() { + new TestCase(); +} +reportCompare(); +TestCase = ParallelArray; +try { + reportCompare(); +} catch(exc1) {} +reportCompare();
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/ion/bug906284.js @@ -0,0 +1,15 @@ +"use strict" +function f() { + h = {} +} +var c = 0; +for (var i=0; i<3; i++) { + try { + new f(); + assertEq(0, 1); + } catch(e) { + c++; + assertEq(e.message.contains("undeclared variable"), true); + } +} +assertEq(c, 3);
--- a/js/src/jit/BaselineJIT.cpp +++ b/js/src/jit/BaselineJIT.cpp @@ -887,47 +887,37 @@ ion::ToggleBaselineSPS(JSRuntime *runtim if (!script->hasBaselineScript()) continue; script->baselineScript()->toggleSPS(enable); } } } static void -MarkActiveBaselineScripts(JSContext *cx, const JitActivationIterator &activation) +MarkActiveBaselineScripts(JSRuntime *rt, const JitActivationIterator &activation) { for (ion::IonFrameIterator iter(activation); !iter.done(); ++iter) { switch (iter.type()) { case IonFrame_BaselineJS: iter.script()->baselineScript()->setActive(); break; case IonFrame_OptimizedJS: { // Keep the baseline script around, since bailouts from the ion // jitcode might need to re-enter into the baseline jitcode. iter.script()->baselineScript()->setActive(); - for (InlineFrameIterator inlineIter(cx, &iter); inlineIter.more(); ++inlineIter) + for (InlineFrameIterator inlineIter(rt, &iter); inlineIter.more(); ++inlineIter) inlineIter.script()->baselineScript()->setActive(); break; } default:; } } } void ion::MarkActiveBaselineScripts(Zone *zone) { - // First check if there is a JitActivation on the stack, so that there - // must be a valid IonContext. - JitActivationIterator iter(zone->runtimeFromMainThread()); - if (iter.done()) - return; - - // If baseline is disabled, there are no baseline scripts on the stack. - JSContext *cx = GetIonContext()->cx; - if (!ion::IsBaselineEnabled(cx)) - return; - - for (; !iter.done(); ++iter) { + JSRuntime *rt = zone->runtimeFromMainThread(); + for (JitActivationIterator iter(rt); !iter.done(); ++iter) { if (iter.activation()->compartment()->zone() == zone) - MarkActiveBaselineScripts(cx, iter); + MarkActiveBaselineScripts(rt, iter); } }
--- a/js/src/jit/CodeGenerator.cpp +++ b/js/src/jit/CodeGenerator.cpp @@ -6166,29 +6166,28 @@ CodeGenerator::visitBindNameIC(OutOfLine StoreRegisterTo(ic->outputReg()).generate(this); restoreLiveIgnore(lir, StoreRegisterTo(ic->outputReg()).clobbered()); masm.jump(ool->rejoin()); return true; } typedef bool (*SetPropertyFn)(JSContext *, HandleObject, - HandlePropertyName, const HandleValue, bool, int); + HandlePropertyName, const HandleValue, bool, jsbytecode *); static const VMFunction SetPropertyInfo = FunctionInfo<SetPropertyFn>(SetProperty); bool CodeGenerator::visitCallSetProperty(LCallSetProperty *ins) { ConstantOrRegister value = TypedOrValueRegister(ToValue(ins, LCallSetProperty::Value)); const Register objReg = ToRegister(ins->getOperand(0)); - JSOp op = JSOp(*ins->mir()->resumePoint()->pc()); - - pushArg(Imm32(op)); + + pushArg(ImmWord(ins->mir()->resumePoint()->pc())); pushArg(Imm32(ins->mir()->strict())); pushArg(value); pushArg(ImmGCPtr(ins->mir()->name())); pushArg(objReg); return callVM(SetPropertyInfo, ins); } @@ -6212,40 +6211,34 @@ CodeGenerator::visitCallDeleteProperty(L } bool CodeGenerator::visitSetPropertyCacheV(LSetPropertyCacheV *ins) { RegisterSet liveRegs = ins->safepoint()->liveRegs(); Register objReg = ToRegister(ins->getOperand(0)); ConstantOrRegister value = TypedOrValueRegister(ToValue(ins, LSetPropertyCacheV::Value)); - jsbytecode *pc = ins->mir()->resumePoint()->pc(); - bool isSetName = JSOp(*pc) == JSOP_SETNAME || JSOp(*pc) == JSOP_SETGNAME; - - SetPropertyIC cache(liveRegs, objReg, ins->mir()->name(), value, - isSetName, ins->mir()->strict()); + + SetPropertyIC cache(liveRegs, objReg, ins->mir()->name(), value, ins->mir()->strict()); return addCache(ins, allocateCache(cache)); } bool CodeGenerator::visitSetPropertyCacheT(LSetPropertyCacheT *ins) { RegisterSet liveRegs = ins->safepoint()->liveRegs(); Register objReg = ToRegister(ins->getOperand(0)); ConstantOrRegister value; - jsbytecode *pc = ins->mir()->resumePoint()->pc(); - bool isSetName = JSOp(*pc) == JSOP_SETNAME || JSOp(*pc) == JSOP_SETGNAME; if (ins->getOperand(1)->isConstant()) value = ConstantOrRegister(*ins->getOperand(1)->toConstant()); else value = TypedOrValueRegister(ins->valueType(), ToAnyRegister(ins->getOperand(1))); - SetPropertyIC cache(liveRegs, objReg, ins->mir()->name(), value, - isSetName, ins->mir()->strict()); + SetPropertyIC cache(liveRegs, objReg, ins->mir()->name(), value, ins->mir()->strict()); return addCache(ins, allocateCache(cache)); } typedef bool (*SetPropertyICFn)(JSContext *, size_t, HandleObject, HandleValue); const VMFunction SetPropertyIC::UpdateInfo = FunctionInfo<SetPropertyICFn>(SetPropertyIC::update); bool
--- a/js/src/jit/IonBuilder.cpp +++ b/js/src/jit/IonBuilder.cpp @@ -154,20 +154,18 @@ IonBuilder::getSingleCallTarget(types::S JSObject *obj = calleeTypes->getSingleton(); if (!obj || !obj->is<JSFunction>()) return NULL; return &obj->as<JSFunction>(); } bool -IonBuilder::getPolyCallTargets(types::StackTypeSet *calleeTypes, - AutoObjectVector &targets, - uint32_t maxTargets, - bool *gotLambda) +IonBuilder::getPolyCallTargets(types::StackTypeSet *calleeTypes, bool constructing, + AutoObjectVector &targets, uint32_t maxTargets, bool *gotLambda) { JS_ASSERT(targets.length() == 0); JS_ASSERT(gotLambda); *gotLambda = false; if (!calleeTypes) return true; @@ -178,42 +176,48 @@ IonBuilder::getPolyCallTargets(types::St if (objCount == 0 || objCount > maxTargets) return true; if (!targets.reserve(objCount)) return false; for(unsigned i = 0; i < objCount; i++) { JSObject *obj = calleeTypes->getSingleObject(i); + JSFunction *fun; if (obj) { if (!obj->is<JSFunction>()) { targets.clear(); return true; } - if (obj->as<JSFunction>().isInterpreted() && - !obj->as<JSFunction>().getOrCreateScript(cx)) - { - return false; - } - DebugOnly<bool> appendOk = targets.append(obj); - JS_ASSERT(appendOk); + fun = &obj->as<JSFunction>(); } else { types::TypeObject *typeObj = calleeTypes->getTypeObject(i); JS_ASSERT(typeObj); if (!typeObj->isFunction() || !typeObj->interpretedFunction) { targets.clear(); return true; } - if (!typeObj->interpretedFunction->getOrCreateScript(cx)) - return false; - DebugOnly<bool> appendOk = targets.append(typeObj->interpretedFunction); - JS_ASSERT(appendOk); - + + fun = typeObj->interpretedFunction; *gotLambda = true; } + + if (fun->isInterpreted() && !fun->getOrCreateScript(cx)) + return false; + + // Don't optimize if we're constructing and the callee is not a + // constructor, so that CallKnown does not have to handle this case + // (it should always throw). + if (constructing && !fun->isInterpretedConstructor() && !fun->isNativeConstructor()) { + targets.clear(); + return true; + } + + DebugOnly<bool> appendOk = targets.append(fun); + JS_ASSERT(appendOk); } // For now, only inline "singleton" lambda calls if (*gotLambda && targets.length() > 1) targets.clear(); return true; } @@ -4942,17 +4946,17 @@ IonBuilder::jsop_call(uint32_t argc, boo int calleeDepth = -((int)argc + 2); // Acquire known call target if existent. AutoObjectVector originals(cx); bool gotLambda = false; types::StackTypeSet *calleeTypes = current->peek(calleeDepth)->resultTypeSet(); if (calleeTypes) { - if (!getPolyCallTargets(calleeTypes, originals, 4, &gotLambda)) + if (!getPolyCallTargets(calleeTypes, constructing, originals, 4, &gotLambda)) return false; } JS_ASSERT_IF(gotLambda, originals.length() <= 1); // If any call targets need to be cloned, clone them. Keep track of the // originals as we need to case on them for poly inline. bool hasClones = false; AutoObjectVector targets(cx); @@ -4978,26 +4982,19 @@ IonBuilder::jsop_call(uint32_t argc, boo InliningStatus status = inlineCallsite(targets, originals, gotLambda, callInfo); if (status == InliningStatus_Inlined) return true; if (status == InliningStatus_Error) return false; // No inline, just make the call. RootedFunction target(cx, NULL); - if (targets.length() == 1) { + if (targets.length() == 1) target = &targets[0]->as<JSFunction>(); - // Don't optimize if we're constructing and the callee is not an - // interpreted constructor, so that CallKnown does not have to - // handle this case (it should always throw). - if (constructing && !target->isInterpretedConstructor()) - target = NULL; - } - return makeCall(target, callInfo, hasClones); } MDefinition * IonBuilder::makeCallsiteClone(HandleFunction target, MDefinition *fun) { // Bake in the clone eagerly if we have a known target. We have arrived here // because TI told us that the known target is a should-clone-at-callsite @@ -5261,17 +5258,18 @@ DOMCallNeedsBarrier(const JSJitInfo* jit return jitinfo->returnType != types->getKnownTypeTag(); } bool IonBuilder::makeCall(HandleFunction target, CallInfo &callInfo, bool cloneAtCallsite) { // Constructor calls to non-constructors should throw. We don't want to use // CallKnown in this case. - JS_ASSERT_IF(callInfo.constructing() && target, target->isInterpretedConstructor()); + JS_ASSERT_IF(callInfo.constructing() && target, + target->isInterpretedConstructor() || target->isNativeConstructor()); MCall *call = makeCallHelper(target, callInfo, cloneAtCallsite); if (!call) return false; current->push(call); if (!resumeAfter(call)) return false;
--- a/js/src/jit/IonBuilder.h +++ b/js/src/jit/IonBuilder.h @@ -220,20 +220,18 @@ class IonBuilder : public MIRGenerator bool abort(const char *message, ...); void spew(const char *message); static bool inliningEnabled() { return js_IonOptions.inlining; } JSFunction *getSingleCallTarget(types::StackTypeSet *calleeTypes); - bool getPolyCallTargets(types::StackTypeSet *calleeTypes, - AutoObjectVector &targets, - uint32_t maxTargets, - bool *gotLambda); + bool getPolyCallTargets(types::StackTypeSet *calleeTypes, bool constructing, + AutoObjectVector &targets, uint32_t maxTargets, bool *gotLambda); bool canInlineTarget(JSFunction *target, bool constructing); void popCfgStack(); DeferredEdge *filterDeadDeferredEdges(DeferredEdge *edge); bool processDeferredContinues(CFGState &state); ControlStatus processControlEnd(); ControlStatus processCfgStack(); ControlStatus processCfgEntry(CFGState &state);
--- a/js/src/jit/IonCaches.cpp +++ b/js/src/jit/IonCaches.cpp @@ -392,19 +392,19 @@ IonCache::linkAndAttachStub(JSContext *c { Rooted<IonCode *> code(cx); LinkStatus status = linkCode(cx, masm, ion, code.address()); if (status != LINK_GOOD) return status != LINK_ERROR; attachStub(masm, attacher, code); - if (pc) { + if (pc_) { IonSpew(IonSpew_InlineCaches, "Cache %p(%s:%d/%d) generated %s %s stub at %p", - this, script->filename(), script->lineno, pc - script->code, + this, script_->filename(), script_->lineno, pc_ - script_->code, attachKind, CacheName(kind()), code->raw()); } else { IonSpew(IonSpew_InlineCaches, "Cache %p generated %s %s stub at %p", this, attachKind, CacheName(kind()), code->raw()); } return true; } @@ -2282,17 +2282,17 @@ SetPropertyIC::update(JSContext *cx, siz } } } uint32_t oldSlots = obj->numDynamicSlots(); RootedShape oldShape(cx, obj->lastProperty()); // Set/Add the property on the object, the inlined cache are setup for the next execution. - if (!SetProperty(cx, obj, name, value, cache.strict(), cache.isSetName())) + if (!SetProperty(cx, obj, name, value, cache.strict(), cache.pc())) return false; // The property did not exist before, now we can try to inline the property add. if (inlinable && !addedSetterStub && obj->lastProperty() != oldShape && IsPropertyAddInlineable(cx, obj, id, oldSlots, &shape)) { RootedShape newShape(cx, obj->lastProperty()); if (!cache.attachNativeAdding(cx, ion, obj, oldShape, newShape, shape))
--- a/js/src/jit/IonCaches.h +++ b/js/src/jit/IonCaches.h @@ -160,18 +160,18 @@ class IonCache bool pure_ : 1; bool idempotent_ : 1; bool disabled_ : 1; size_t stubCount_ : 5; CodeLocationLabel fallbackLabel_; // Location of this operation, NULL for idempotent caches. - JSScript *script; - jsbytecode *pc; + JSScript *script_; + jsbytecode *pc_; private: static const size_t MAX_STUBS; void incrementStubCount() { // The IC should stop generating stubs before wrapping stubCount. stubCount_++; JS_ASSERT(stubCount_); } @@ -179,18 +179,18 @@ class IonCache public: IonCache() : pure_(false), idempotent_(false), disabled_(false), stubCount_(0), fallbackLabel_(), - script(NULL), - pc(NULL) + script_(NULL), + pc_(NULL) { } virtual void disable(); inline bool isDisabled() const { return disabled_; } @@ -251,30 +251,35 @@ class IonCache bool pure() const { return pure_; } bool idempotent() const { return idempotent_; } void setIdempotent() { JS_ASSERT(!idempotent_); - JS_ASSERT(!script); - JS_ASSERT(!pc); + JS_ASSERT(!script_); + JS_ASSERT(!pc_); idempotent_ = true; } void setScriptedLocation(JSScript *script, jsbytecode *pc) { JS_ASSERT(!idempotent_); - this->script = script; - this->pc = pc; + script_ = script; + pc_ = pc; } void getScriptedLocation(MutableHandleScript pscript, jsbytecode **ppc) const { - pscript.set(script); - *ppc = pc; + pscript.set(script_); + *ppc = pc_; + } + + jsbytecode *pc() const { + JS_ASSERT(pc_); + return pc_; } }; // // Repatch caches initially generate a patchable jump to an out of line call // to the cache function. Stubs are attached by appending: when attaching a // new stub, we patch the any failure conditions in last generated stub to // jump to the new stub. Failure conditions in the new stub jump to the cache @@ -600,45 +605,40 @@ class SetPropertyIC : public RepatchIonC protected: // Registers live after the cache, excluding output registers. The initial // value of these registers must be preserved by the cache. RegisterSet liveRegs_; Register object_; PropertyName *name_; ConstantOrRegister value_; - bool isSetName_; bool strict_; public: SetPropertyIC(RegisterSet liveRegs, Register object, PropertyName *name, - ConstantOrRegister value, bool isSetName, bool strict) + ConstantOrRegister value, bool strict) : liveRegs_(liveRegs), object_(object), name_(name), value_(value), - isSetName_(isSetName), strict_(strict) { } CACHE_HEADER(SetProperty) Register object() const { return object_; } PropertyName *name() const { return name_; } ConstantOrRegister value() const { return value_; } - bool isSetName() const { - return isSetName_; - } bool strict() const { return strict_; } bool attachNativeExisting(JSContext *cx, IonScript *ion, HandleObject obj, HandleShape shape); bool attachSetterCall(JSContext *cx, IonScript *ion, HandleObject obj, HandleObject holder, HandleShape shape, void *returnAddr); bool attachNativeAdding(JSContext *cx, IonScript *ion, JSObject *obj, HandleShape oldshape, @@ -773,17 +773,17 @@ class SetElementIC : public RepatchIonCa CACHE_HEADER(SetElement) void reset(); Register object() const { return object_; } Register tempToUnboxIndex() const { - return temp_; + return tempToUnboxIndex_; } Register temp() const { return temp_; } ValueOperand index() const { return index_; } ConstantOrRegister value() const {
--- a/js/src/jit/IonFrameIterator.h +++ b/js/src/jit/IonFrameIterator.h @@ -334,16 +334,23 @@ class InlineFrameIteratorMaybeGC public: InlineFrameIteratorMaybeGC(JSContext *cx, const IonFrameIterator *iter) : callee_(cx), script_(cx) { resetOn(iter); } + InlineFrameIteratorMaybeGC(JSRuntime *rt, const IonFrameIterator *iter) + : callee_(rt), + script_(rt) + { + resetOn(iter); + } + InlineFrameIteratorMaybeGC(JSContext *cx, const IonBailoutIterator *iter); InlineFrameIteratorMaybeGC(JSContext *cx, const InlineFrameIteratorMaybeGC *iter) : frame_(iter ? iter->frame_ : NULL), framesRead_(0), callee_(cx), script_(cx) {
--- a/js/src/jit/ParallelFunctions.cpp +++ b/js/src/jit/ParallelFunctions.cpp @@ -509,23 +509,29 @@ ion::PropagateAbortPar(JSScript *outermo outermostScript->parallelIonScript()->setHasUncompiledCallTarget(); ForkJoinSlice *slice = ForkJoinSlice::Current(); if (currentScript) slice->bailoutRecord->addTrace(currentScript, NULL); } void -ion::CallToUncompiledScriptPar(JSFunction *func) +ion::CallToUncompiledScriptPar(JSObject *obj) { JS_ASSERT(InParallelSection()); #ifdef DEBUG static const int max_bound_function_unrolling = 5; + if (!obj->is<JSFunction>()) { + Spew(SpewBailouts, "Call to non-function"); + return; + } + + JSFunction *func = &obj->as<JSFunction>(); if (func->hasScript()) { JSScript *script = func->nonLazyScript(); Spew(SpewBailouts, "Call to uncompiled script: %p:%s:%d", script, script->filename(), script->lineno); } else if (func->isInterpretedLazy()) { Spew(SpewBailouts, "Call to uncompiled lazy script"); } else if (func->isBoundFunction()) { int depth = 0;
--- a/js/src/jit/ParallelFunctions.h +++ b/js/src/jit/ParallelFunctions.h @@ -78,14 +78,14 @@ ParallelResult InitRestParameterPar(Fork void AbortPar(ParallelBailoutCause cause, JSScript *outermostScript, JSScript *currentScript, jsbytecode *bytecode); void PropagateAbortPar(JSScript *outermostScript, JSScript *currentScript); void TraceLIR(uint32_t bblock, uint32_t lir, uint32_t execModeInt, const char *lirOpName, const char *mirOpName, JSScript *script, jsbytecode *pc); -void CallToUncompiledScriptPar(JSFunction *func); +void CallToUncompiledScriptPar(JSObject *obj); } // namespace ion } // namespace js #endif /* jit_ParallelFunctions_h */
--- a/js/src/jit/VMFunctions.cpp +++ b/js/src/jit/VMFunctions.cpp @@ -392,32 +392,34 @@ StringFromCharCode(JSContext *cx, int32_ if (StaticStrings::hasUnit(c)) return cx->runtime()->staticStrings.getUnit(c); return js_NewStringCopyN<CanGC>(cx, &c, 1); } bool SetProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, HandleValue value, - bool strict, int jsop) + bool strict, jsbytecode *pc) { RootedValue v(cx, value); RootedId id(cx, NameToId(name)); - if (jsop == JSOP_SETALIASEDVAR) { + JSOp op = JSOp(*pc); + + if (op == JSOP_SETALIASEDVAR) { // Aliased var assigns ignore readonly attributes on the property, as // required for initializing 'const' closure variables. Shape *shape = obj->nativeLookup(cx, name); JS_ASSERT(shape && shape->hasSlot()); JSObject::nativeSetSlotWithType(cx, obj, shape, value); return true; } if (JS_LIKELY(!obj->getOps()->setProperty)) { - unsigned defineHow = (jsop == JSOP_SETNAME || jsop == JSOP_SETGNAME) ? DNP_UNQUALIFIED : 0; + unsigned defineHow = (op == JSOP_SETNAME || op == JSOP_SETGNAME) ? DNP_UNQUALIFIED : 0; return baseops::SetPropertyHelper(cx, obj, obj, id, defineHow, &v, strict); } return JSObject::setGeneric(cx, obj, obj, id, &v, strict); } bool InterruptCheck(JSContext *cx)
--- a/js/src/jit/VMFunctions.h +++ b/js/src/jit/VMFunctions.h @@ -609,17 +609,17 @@ bool ArrayPopDense(JSContext *cx, Handle bool ArrayPushDense(JSContext *cx, HandleObject obj, HandleValue v, uint32_t *length); bool ArrayShiftDense(JSContext *cx, HandleObject obj, MutableHandleValue rval); JSObject *ArrayConcatDense(JSContext *cx, HandleObject obj1, HandleObject obj2, HandleObject res); bool CharCodeAt(JSContext *cx, HandleString str, int32_t index, uint32_t *code); JSFlatString *StringFromCharCode(JSContext *cx, int32_t code); bool SetProperty(JSContext *cx, HandleObject obj, HandlePropertyName name, HandleValue value, - bool strict, int jsop); + bool strict, jsbytecode *pc); bool InterruptCheck(JSContext *cx); HeapSlot *NewSlots(JSRuntime *rt, unsigned nslots); JSObject *NewCallObject(JSContext *cx, HandleScript script, HandleShape shape, HandleTypeObject type, HeapSlot *slots); JSObject *NewStringObject(JSContext *cx, HandleString str);
--- a/js/src/jsscript.cpp +++ b/js/src/jsscript.cpp @@ -630,17 +630,17 @@ js::XDRScript(XDRState<mode> *xdr, Handl SharedScriptData *ssd; if (mode == XDR_DECODE) { ssd = SharedScriptData::new_(cx, length, nsrcnotes, natoms); if (!ssd) return false; code = ssd->data; if (natoms != 0) { script->natoms = natoms; - script->atoms = ssd->atoms(length, nsrcnotes); + script->atoms = ssd->atoms(); } } if (!xdr->codeBytes(code, length) || !xdr->codeBytes(code + length, nsrcnotes)) { if (mode == XDR_DECODE) js_free(ssd); return false; } @@ -1511,25 +1511,36 @@ ScriptSource::sourceMap() SharedScriptData * js::SharedScriptData::new_(ExclusiveContext *cx, uint32_t codeLength, uint32_t srcnotesLength, uint32_t natoms) { uint32_t baseLength = codeLength + srcnotesLength; uint32_t padding = sizeof(JSAtom *) - baseLength % sizeof(JSAtom *); uint32_t length = baseLength + padding + sizeof(JSAtom *) * natoms; + JS_ASSERT(length % sizeof(JSAtom *) == 0); SharedScriptData *entry = (SharedScriptData *)cx->malloc_(length + offsetof(SharedScriptData, data)); if (!entry) return NULL; + entry->length = length; + entry->natoms = natoms; entry->marked = false; - entry->length = length; memset(entry->data + baseLength, 0, padding); + + /* + * Call constructors to initialize the storage that will be accessed as a + * HeapPtrAtom array via atoms(). + */ + HeapPtrAtom *atoms = entry->atoms(); + for (unsigned i = 0; i < natoms; ++i) + new (&atoms[i]) HeapPtrAtom(); + return entry; } /* * Takes ownership of its *ssd parameter and either adds it into the runtime's * ScriptDataTable or frees it if a matching entry already exists. * * Sets the |code| and |atoms| fields on the given JSScript. @@ -1567,17 +1578,17 @@ SaveSharedScriptData(ExclusiveContext *c if (cx->isJSContext()) { JSRuntime *rt = cx->asJSContext()->runtime(); if (JS::IsIncrementalGCInProgress(rt) && rt->gcIsFull) ssd->marked = true; } #endif script->code = ssd->data; - script->atoms = ssd->atoms(script->length, nsrcnotes); + script->atoms = ssd->atoms(); return true; } static inline void MarkScriptData(JSRuntime *rt, const jsbytecode *bytecode) { /* * As an invariant, a ScriptBytecodeEntry should not be 'marked' outside of @@ -1911,17 +1922,17 @@ JSScript::fullyInitFromEmitter(Exclusive if (!ssd) return false; jsbytecode *code = ssd->data; PodCopy<jsbytecode>(code, bce->prolog.code.begin(), prologLength); PodCopy<jsbytecode>(code + prologLength, bce->code().begin(), mainLength); if (!FinishTakingSrcNotes(cx, bce, (jssrcnote *)(code + script->length))) return false; - InitAtomMap(bce->atomIndices.getMap(), ssd->atoms(script->length, nsrcnotes)); + InitAtomMap(bce->atomIndices.getMap(), ssd->atoms()); if (!SaveSharedScriptData(cx, script, ssd, nsrcnotes)) return false; uint32_t nfixed = bce->sc->isFunctionBox() ? script->bindings.numVars() : 0; JS_ASSERT(nfixed < SLOTNO_LIMIT); script->nfixed = uint16_t(nfixed); if (script->nfixed + bce->maxStackDepth >= JS_BIT(16)) { @@ -2789,17 +2800,17 @@ JSScript::markChildren(JSTracer *trc) MarkObject(trc, &function_, "function"); if (enclosingScopeOrOriginalFunction_) MarkObject(trc, &enclosingScopeOrOriginalFunction_, "enclosing"); if (IS_GC_MARKING_TRACER(trc)) { compartment()->mark(); - if (code) + if (code || natoms) MarkScriptData(trc->runtime, code); } bindings.trace(trc); if (hasAnyBreakpointsOrStepMode()) { for (unsigned i = 0; i < length; i++) { BreakpointSite *site = debugScript()->breakpoints[i];
--- a/js/src/jsscript.h +++ b/js/src/jsscript.h @@ -1380,32 +1380,37 @@ struct SourceCompressionToken extern void CallNewScriptHook(JSContext *cx, JS::HandleScript script, JS::HandleFunction fun); extern void CallDestroyScriptHook(FreeOp *fop, JSScript *script); struct SharedScriptData { + uint32_t length; + uint32_t natoms; bool marked; - uint32_t length; jsbytecode data[1]; static SharedScriptData *new_(ExclusiveContext *cx, uint32_t codeLength, uint32_t srcnotesLength, uint32_t natoms); - HeapPtrAtom *atoms(uint32_t codeLength, uint32_t srcnotesLength) { - uint32_t length = codeLength + srcnotesLength; - return reinterpret_cast<HeapPtrAtom *>(data + length + sizeof(JSAtom *) - - length % sizeof(JSAtom *)); + HeapPtrAtom *atoms() { + if (!natoms) + return NULL; + return reinterpret_cast<HeapPtrAtom *>(data + length - sizeof(JSAtom *) * natoms); } static SharedScriptData *fromBytecode(const jsbytecode *bytecode) { return (SharedScriptData *)(bytecode - offsetof(SharedScriptData, data)); } + + private: + SharedScriptData() MOZ_DELETE; + SharedScriptData(const SharedScriptData&) MOZ_DELETE; }; struct ScriptBytecodeHasher { struct Lookup { jsbytecode *code; uint32_t length;
--- a/js/src/tests/browser.js +++ b/js/src/tests/browser.js @@ -341,17 +341,17 @@ function jsTestDriverBrowserInit() if (properties.test.match(/^js1_6/)) { properties.version = '1.6'; } else if (properties.test.match(/^js1_7/)) { properties.version = '1.7'; } - else if (properties.test.match(/^js1_8|^ecma_6/)) + else if (properties.test.match(/^js1_8/)) { properties.version = '1.8'; } } // default to language=type;text/javascript. required for // reftest style manifests. if (!properties.language)
--- a/js/src/tests/ecma_6/Math/acosh-approx.js +++ b/js/src/tests/ecma_6/Math/acosh-approx.js @@ -257,17 +257,17 @@ var cosh_data = [ [48862560256, 25.305424481799395], [113763549184, 26.150535181949436], [161334755328, 26.499894449532565], [321933279232, 27.19075733422632], [715734122496, 27.989721778208146], [1875817529344, 28.953212876533797] ]; -for (let [x, y] of cosh_data) +for (var [x, y] of cosh_data) assertNear(Math.acosh(x), y); for (var i = 0; i <= 100; i++) { var x = (i - 50) / 5; var y = Math.cosh(x); var z = Math.acosh(y); assertNear(z, Math.abs(x)); }
--- a/js/src/tests/ecma_6/Math/asinh-approx.js +++ b/js/src/tests/ecma_6/Math/asinh-approx.js @@ -277,17 +277,17 @@ var sinh_data = [ [60601991168, 25.520740767599584], [134018236416, 26.31438890085422], [204864946176, 26.73876398039979], [284346286080, 27.06660583008718], [914576637952, 28.234874284944635], [1581915832320, 28.78280496108106] ]; -for (let [x, y] of sinh_data) +for (var [x, y] of sinh_data) assertNear(Math.asinh(x), y); for (var i = 0; i <= 80; i++) { var x = (i - 40) / 4; var y = Math.sinh(x); var z = Math.asinh(y); assertNear(z, x); }
--- a/js/src/tests/ecma_6/Math/atanh-approx.js +++ b/js/src/tests/ecma_6/Math/atanh-approx.js @@ -264,15 +264,15 @@ var tanh_data = [ [0.9928233623504639, 2.8132383539094192], [1e-300, 1e-300], [0.00001, 0.000010000000000333334], [0.3, 0.3095196042031117], [1e-30, 1e-30], [1e-10, 1e-10], ]; -for (let [x, y] of tanh_data) +for (var [x, y] of tanh_data) assertNear(Math.atanh(x), y); assertNear(Math.atanh(+3 / 5), +Math.log(2)); assertNear(Math.atanh(-3 / 5), -Math.log(2)); reportCompare(0, 0, "ok");
--- a/js/src/tests/ecma_6/Math/cbrt-approx.js +++ b/js/src/tests/ecma_6/Math/cbrt-approx.js @@ -6,13 +6,13 @@ assertNear(Math.cbrt(-1e-300), -1e-100); var cbrt_data = [ [ Math.E, 1.3956124250860895 ], [ Math.PI, 1.4645918875615231 ], [ Math.LN2, 0.8849970445005177 ], [ Math.SQRT2, 1.1224620483093728 ] ]; -for (let [x, y] of cbrt_data) +for (var [x, y] of cbrt_data) assertNear(Math.cbrt(x), y); reportCompare(0, 0, "ok");
--- a/js/src/tests/ecma_6/Math/cosh-approx.js +++ b/js/src/tests/ecma_6/Math/cosh-approx.js @@ -264,12 +264,12 @@ var cosh_data = [ [25.305424481799395, 48862560256.00005], [26.150535181949436, 113763549183.99998], [26.499894449532565, 161334755328.00018], [27.19075733422632, 321933279232.0004], [27.989721778208146, 715734122496], [28.953212876533797, 1875817529343.9976], ]; -for (let [x, y] of cosh_data) +for (var [x, y] of cosh_data) assertNear(Math.cosh(x), y); reportCompare(0, 0, "ok");
--- a/js/src/tests/ecma_6/Math/expm1-approx.js +++ b/js/src/tests/ecma_6/Math/expm1-approx.js @@ -13,12 +13,12 @@ var expm1_data = [ [ 6.261923313140869e-30, 6.261923313140869e-30 ], [ 7.09962844069878e-15, 7.099628440698805e-15 ], [ 1.3671879628418538e-12, 1.3671879628427884e-12 ], [ 2.114990849122478e-10, 2.1149908493461373e-10 ], [ 1.6900931765206906e-8, 1.6900931908027652e-8 ], [ 0.0000031404608812881633, 0.0000031404658125405988 ] ]; -for (let [x, y] of expm1_data) +for (var [x, y] of expm1_data) assertNear(Math.expm1(x), y); reportCompare(0, 0, "ok");
--- a/js/src/tests/ecma_6/Math/hypot-exact.js +++ b/js/src/tests/ecma_6/Math/hypot-exact.js @@ -1,13 +1,13 @@ // Properties of Math.hypot that are guaranteed by the spec. // If any argument is +∞, the result is +∞. // If any argument is −∞, the result is +∞. -for (let inf of [Infinity, -Infinity]) { +for (var inf of [Infinity, -Infinity]) { assertEq(Math.hypot(inf, 0), Infinity); assertEq(Math.hypot(0, inf), Infinity); assertEq(Math.hypot(inf, inf), Infinity); assertEq(Math.hypot(inf, -inf), Infinity); assertEq(Math.hypot(inf, -0), Infinity); assertEq(Math.hypot(-0, inf), Infinity); assertEq(Math.hypot(inf, Math.MIN_VALUE), Infinity);
--- a/js/src/tests/ecma_6/Math/log1p-approx.js +++ b/js/src/tests/ecma_6/Math/log1p-approx.js @@ -9,12 +9,12 @@ var log1p_data = [ [ 1.3671879628418538e-12, 1.3671879628409192e-12 ], [ 2.114990849122478e-10, 2.1149908488988187e-10 ], [ 1.6900931765206906e-8, 1.690093162238616e-8 ], [ 0.0000709962844069878, 0.00007099376429006658 ], [ 0.0016793412882520897, 0.00167793277137076 ], [ 0.011404608812881634, 0.011340066517988035 ], ]; -for (let [x, y] of log1p_data) +for (var [x, y] of log1p_data) assertNear(Math.log1p(x), y); reportCompare(0, 0, "ok");
--- a/js/src/tests/ecma_6/Math/sinh-approx.js +++ b/js/src/tests/ecma_6/Math/sinh-approx.js @@ -284,13 +284,13 @@ var sinh_data = [ [25.520740767599584, 60601991168.00004], [26.31438890085422, 134018236416.00002], [26.73876398039979, 204864946175.99973], [27.06660583008718, 284346286080.00024], [28.234874284944635, 914576637951.9989], [28.78280496108106, 1581915832319.9973] ]; -for (let [x, y] of sinh_data) +for (var [x, y] of sinh_data) assertNear(Math.sinh(x), y); reportCompare(0, 0, "ok");
--- a/js/src/tests/ecma_6/Math/tanh-approx.js +++ b/js/src/tests/ecma_6/Math/tanh-approx.js @@ -266,12 +266,12 @@ var tanh_data = [ [0.9928233623504639, 2.8132383539094192], [1e-300, 1e-300], [0.00001, 0.000010000000000333334], [0.3, 0.3095196042031117], [1e-30, 1e-30], [1e-10, 1e-10], ]; -for (let [x, y] of tanh_data) +for (var [x, y] of tanh_data) assertNear(Math.tanh(y), x); reportCompare(0, 0, "ok");
--- a/js/src/tests/ecma_6/shell.js +++ b/js/src/tests/ecma_6/shell.js @@ -1,12 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ -/* - * Any copyright is dedicated to the Public Domain. - * http://creativecommons.org/licenses/publicdomain/ - */ - -// explicitly turn on js185 -if (typeof version != 'undefined') -{ - version(185); -} -
--- a/layout/base/DisplayItemClip.cpp +++ b/layout/base/DisplayItemClip.cpp @@ -2,17 +2,16 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "DisplayItemClip.h" #include "gfxContext.h" #include "nsPresContext.h" -#include "nsDisplayList.h" #include "nsCSSRendering.h" #include "nsLayoutUtils.h" namespace mozilla { void DisplayItemClip::SetTo(const nsRect& aRect) {
--- a/layout/base/FrameLayerBuilder.cpp +++ b/layout/base/FrameLayerBuilder.cpp @@ -7,40 +7,29 @@ #include "FrameLayerBuilder.h" #include "nsDisplayList.h" #include "nsPresContext.h" #include "nsLayoutUtils.h" #include "Layers.h" #include "BasicLayers.h" -#include "nsSubDocumentFrame.h" -#include "nsCSSRendering.h" -#include "nsCSSFrameConstructor.h" #include "gfxUtils.h" #include "nsRenderingContext.h" #include "MaskLayerImageCache.h" #include "nsIScrollableFrame.h" #include "nsPrintfCString.h" #include "LayerTreeInvalidation.h" #include "nsSVGIntegrationUtils.h" -#include "mozilla/Preferences.h" #include "GeckoProfiler.h" #include "mozilla/gfx/Tools.h" -#include "nsAnimationManager.h" -#include "nsTransitionManager.h" #include <algorithm> -#ifdef DEBUG -#include <stdio.h> -//#define DEBUG_DISPLAY_ITEM_DATA -#endif - using namespace mozilla::layers; using namespace mozilla::gfx; namespace mozilla { FrameLayerBuilder::DisplayItemData::DisplayItemData(LayerManagerData* aParent, uint32_t aKey, Layer* aLayer, LayerState aLayerState, uint32_t aGeneration)
--- a/layout/base/FrameLayerBuilder.h +++ b/layout/base/FrameLayerBuilder.h @@ -6,26 +6,24 @@ #ifndef FRAMELAYERBUILDER_H_ #define FRAMELAYERBUILDER_H_ #include "nsTHashtable.h" #include "nsHashKeys.h" #include "nsTArray.h" #include "nsRegion.h" #include "nsIFrame.h" -#include "nsDisplayListInvalidation.h" -#include "LayerTreeInvalidation.h" #include "ImageLayers.h" #include "DisplayItemClip.h" class nsDisplayListBuilder; class nsDisplayList; class nsDisplayItem; class gfxContext; -class nsRootPresContext; +class nsDisplayItemGeometry; namespace mozilla { namespace layers { class ContainerLayer; class LayerManager; class ThebesLayer; }
--- a/layout/base/FramePropertyTable.cpp +++ b/layout/base/FramePropertyTable.cpp @@ -2,18 +2,16 @@ * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "FramePropertyTable.h" #include "mozilla/MemoryReporting.h" -#include "prlog.h" - namespace mozilla { void FramePropertyTable::Set(nsIFrame* aFrame, const FramePropertyDescriptor* aProperty, void* aValue) { NS_ASSERTION(aFrame, "Null frame?"); NS_ASSERTION(aProperty, "Null property?");
--- a/layout/base/MaskLayerImageCache.h +++ b/layout/base/MaskLayerImageCache.h @@ -1,17 +1,17 @@ /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef MASKLAYERIMAGECACHE_H_ #define MASKLAYERIMAGECACHE_H_ -#include "FrameLayerBuilder.h" +#include "gfxMatrix.h" #include "DisplayItemClip.h" #include "nsPresContext.h" namespace mozilla { namespace layers { class ImageContainer; }
--- a/layout/base/PaintTracker.h +++ b/layout/base/PaintTracker.h @@ -1,16 +1,16 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_PaintTracker_h #define mozilla_PaintTracker_h -#include "nscore.h" +#include "mozilla/Attributes.h" #include "nsDebug.h" namespace mozilla { class MOZ_STACK_CLASS PaintTracker { public: PaintTracker() {
--- a/layout/base/PositionedEventTargeting.h +++ b/layout/base/PositionedEventTargeting.h @@ -1,19 +1,20 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef mozilla_PositionedEventTargeting_h #define mozilla_PositionedEventTargeting_h -#include "nsPoint.h" -#include "nsGUIEvent.h" +#include <stdint.h> class nsIFrame; +class nsGUIEvent; +struct nsPoint; namespace mozilla { enum { INPUT_IGNORE_ROOT_SCROLL_FRAME = 0x01 }; /** * Finds the target frame for a pointer event given the event type and location.
--- a/layout/base/RestyleTracker.cpp +++ b/layout/base/RestyleTracker.cpp @@ -4,18 +4,18 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** * A class which manages pending restyles. This handles keeping track * of what nodes restyles need to happen on and so forth. */ #include "RestyleTracker.h" -#include "nsCSSFrameConstructor.h" #include "nsStyleChangeList.h" +#include "RestyleManager.h" #include "GeckoProfiler.h" namespace mozilla { inline nsIDocument* RestyleTracker::Document() const { return mRestyleManager->PresContext()->Document(); }
--- a/layout/base/RestyleTracker.h +++ b/layout/base/RestyleTracker.h @@ -9,17 +9,16 @@ */ #ifndef mozilla_RestyleTracker_h #define mozilla_RestyleTracker_h #include "mozilla/dom/Element.h" #include "nsDataHashtable.h" #include "nsIFrame.h" -#include "nsTPriorityQueue.h" #include "mozilla/SplayTree.h" namespace mozilla { class RestyleManager; /** * Helper class that collects a list of frames that need
--- a/layout/base/StackArena.cpp +++ b/layout/base/StackArena.cpp @@ -1,15 +1,15 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "StackArena.h" - -#include "mozilla/MemoryReporting.h" +#include "nsAlgorithm.h" +#include "nsDebug.h" namespace mozilla { #define STACK_ARENA_MARK_INCREMENT 50 /* a bit under 4096, for malloc overhead */ #define STACK_ARENA_BLOCK_INCREMENT 4044 /**A block of memory that the stack will
--- a/layout/base/StackArena.h +++ b/layout/base/StackArena.h @@ -1,16 +1,16 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this file, * You can obtain one at http://mozilla.org/MPL/2.0/. */ +#include "nsError.h" #include "mozilla/Assertions.h" #include "mozilla/MemoryReporting.h" -#include "nsAlgorithm.h" -#include "nsDebug.h" +#include "mozilla/NullPtr.h" namespace mozilla { struct StackBlock; struct StackMark; class AutoStackArena; /**
--- a/layout/base/nsBidi.cpp +++ b/layout/base/nsBidi.cpp @@ -2,17 +2,17 @@ * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifdef IBMBIDI #include "nsBidi.h" #include "nsUnicodeProperties.h" -#include "nsCRT.h" +#include "nsCRTGlue.h" using namespace mozilla::unicode; // These are #defined in <sys/regset.h> under Solaris 10 x86 #undef CS #undef ES /* Comparing the description of the Bidi algorithm with this implementation
--- a/layout/base/nsBidi.h +++ b/layout/base/nsBidi.h @@ -2,18 +2,16 @@ * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef nsBidi_h__ #define nsBidi_h__ -#include "nsCOMPtr.h" -#include "nsString.h" #include "nsBidiUtils.h" // Bidi reordering engine from ICU /* * javadoc-style comments are intended to be transformed into HTML * using DOC++ - see * http://www.zib.de/Visual/software/doc++/index.html . *
--- a/layout/base/nsBidiPresUtils.cpp +++ b/layout/base/nsBidiPresUtils.cpp @@ -1,31 +1,28 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifdef IBMBIDI #include "nsBidiPresUtils.h" -#include "nsTextFragment.h" #include "nsGkAtoms.h" #include "nsPresContext.h" #include "nsRenderingContext.h" -#include "nsIServiceManager.h" -#include "nsFrameManager.h" #include "nsBidiUtils.h" #include "nsCSSFrameConstructor.h" #include "nsContainerFrame.h" #include "nsInlineFrame.h" #include "nsPlaceholderFrame.h" #include "nsFirstLetterFrame.h" #include "nsUnicodeProperties.h" #include "nsTextFrame.h" -#include "nsStyleStructInlines.h" +#include "nsBlockFrame.h" #include <algorithm> #undef NOISY_BIDI #undef REALLY_NOISY_BIDI using namespace mozilla; static const PRUnichar kSpace = 0x0020;
--- a/layout/base/nsBidiPresUtils.h +++ b/layout/base/nsBidiPresUtils.h @@ -1,34 +1,36 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifdef IBMBIDI - #ifndef nsBidiPresUtils_h___ #define nsBidiPresUtils_h___ -#include "nsTArray.h" +#ifdef IBMBIDI + #include "nsBidi.h" #include "nsBidiUtils.h" -#include "nsCOMPtr.h" -#include "nsDataHashtable.h" -#include "nsBlockFrame.h" -#include "nsTHashtable.h" +#include "nsHashKeys.h" +#include "nsCoord.h" #ifdef DrawText #undef DrawText #endif struct BidiParagraphData; struct BidiLineData; class nsIFrame; +class nsBlockFrame; +class nsPresContext; +class nsRenderingContext; +class nsBlockInFlowLineIterator; +template<class T> class nsTHashtable; /** * A structure representing some continuation state for each frame on the line, * used to determine the first and the last continuation frame for each * continuation chain on the line. */ struct nsFrameContinuationState : public nsVoidPtrHashKey { @@ -468,11 +470,11 @@ private: nsBidiLevel aBaseDirection, nsBidi* aBidiEngine); static void WriteReverse(const PRUnichar* aSrc, uint32_t aSrcLength, PRUnichar* aDest); }; -#endif /* nsBidiPresUtils_h___ */ +#endif // IBMBIDI -#endif // IBMBIDI +#endif /* nsBidiPresUtils_h___ */
--- a/layout/base/nsCSSColorUtils.h +++ b/layout/base/nsCSSColorUtils.h @@ -3,18 +3,16 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* functions that manipulate colors */ #ifndef __nsCSSColorUtils_h #define __nsCSSColorUtils_h -#include "mozilla/MathAlgorithms.h" - #include "nsColor.h" // "Sufficient contrast" is determined by // "Techniques For Accessibility Evalution And Repair Tools". // See http://www.w3.org/TR/AERT#color-contrast #define NS_SUFFICIENT_LUMINOSITY_DIFFERENCE 125000 #define NS_LUMINOSITY_DIFFERENCE(a, b) \ int32_t(mozilla::Abs(NS_GetLuminosity(a) - NS_GetLuminosity(b)))
--- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -12,119 +12,88 @@ #include "nsCSSFrameConstructor.h" #include "mozilla/AutoRestore.h" #include "mozilla/DebugOnly.h" #include "mozilla/dom/HTMLSelectElement.h" #include "mozilla/Likely.h" #include "mozilla/LinkedList.h" #include "nsAbsoluteContainingBlock.h" -#include "nsCRT.h" #include "nsIAtom.h" -#include "nsIURL.h" -#include "nsIHTMLDocument.h" -#include "nsIStyleRule.h" #include "nsIFrame.h" #include "nsGkAtoms.h" #include "nsPresContext.h" -#include "nsILinkHandler.h" #include "nsIDocument.h" #include "nsTableFrame.h" -#include "nsTableColGroupFrame.h" #include "nsTableColFrame.h" #include "nsIDOMHTMLDocument.h" #include "nsHTMLParts.h" #include "nsIPresShell.h" #include "nsUnicharUtils.h" #include "nsStyleSet.h" #include "nsViewManager.h" #include "nsEventStates.h" #include "nsStyleConsts.h" -#include "nsTableOuterFrame.h" #include "nsIDOMXULElement.h" #include "nsContainerFrame.h" #include "nsINameSpaceManager.h" #include "nsIComboboxControlFrame.h" #include "nsIListControlFrame.h" -#include "nsISelectControlFrame.h" #include "nsIDOMCharacterData.h" -#include "nsIDOMHTMLImageElement.h" #include "nsPlaceholderFrame.h" #include "nsTableRowGroupFrame.h" #include "nsIFormControl.h" #include "nsCSSAnonBoxes.h" #include "nsTextFragment.h" #include "nsIAnonymousContentCreator.h" -#include "nsLegendFrame.h" -#include "nsIContentIterator.h" -#include "nsBoxLayoutState.h" #include "nsBindingManager.h" #include "nsXBLBinding.h" -#include "nsITheme.h" -#include "nsContentCID.h" #include "nsContentUtils.h" #include "nsIScriptError.h" -#include "nsIDocShell.h" +#ifdef XP_MACOSX #include "nsIDocShellTreeItem.h" -#include "nsObjectFrame.h" -#include "nsRuleNode.h" -#include "nsIDOMMutationEvent.h" +#endif #include "ChildIterator.h" -#include "nsCSSRendering.h" #include "nsError.h" #include "nsLayoutUtils.h" #include "nsAutoPtr.h" #include "nsBoxFrame.h" #include "nsBoxLayout.h" #include "nsFlexContainerFrame.h" #include "nsImageFrame.h" #include "nsIObjectLoadingContent.h" -#include "nsIPrincipal.h" -#include "nsBox.h" #include "nsTArray.h" #include "nsGenericDOMDataNode.h" #include "mozilla/dom/Element.h" -#include "FrameLayerBuilder.h" #include "nsAutoLayoutPhase.h" -#include "nsCSSRenderingBorders.h" -#include "nsRenderingContext.h" #include "nsStyleStructInlines.h" -#include "nsViewportFrame.h" #include "nsPageContentFrame.h" -#include <algorithm> +#include "RestyleManager.h" #ifdef MOZ_XUL #include "nsIRootBox.h" -#include "nsIDOMXULCommandDispatcher.h" -#include "nsIDOMXULDocument.h" -#include "nsIXULDocument.h" #endif #ifdef ACCESSIBILITY #include "nsAccessibilityService.h" #endif -#include "nsInlineFrame.h" #include "nsBlockFrame.h" #include "nsIScrollableFrame.h" #include "nsXBLService.h" #undef NOISY_FIRST_LETTER #include "nsMathMLParts.h" #include "mozilla/dom/SVGTests.h" -#include "nsSVGEffects.h" -#include "nsSVGTextFrame2.h" -#include "nsSVGTextPathFrame.h" #include "nsSVGUtils.h" #include "nsRefreshDriver.h" #include "nsRuleProcessorData.h" -#include "GeckoProfiler.h" #include "nsTextNode.h" using namespace mozilla; using namespace mozilla::dom; // An alias for convenience. static const nsIFrame::ChildListID kPrincipalList = nsIFrame::kPrincipalList; @@ -192,23 +161,20 @@ nsIFrame* NS_NewSVGFEContainerFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); nsIFrame* NS_NewSVGFELeafFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); nsIFrame* NS_NewSVGFEImageFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); nsIFrame* NS_NewSVGFEUnstyledLeafFrame(nsIPresShell* aPresShell, nsStyleContext* aContext); -#include "nsIScrollable.h" #include "nsINodeInfo.h" #include "prenv.h" -#include "nsWidgetsCID.h" #include "nsNodeInfoManager.h" #include "nsContentCreatorFunctions.h" -#include "nsIServiceManager.h" #ifdef DEBUG // Set the environment variable GECKO_FRAMECTOR_DEBUG_FLAGS to one or // more of the following flags (comma separated) for handy debug // output. static bool gNoisyContentUpdates = false; static bool gReallyNoisyContentUpdates = false; static bool gNoisyInlineConstruction = false; @@ -225,17 +191,16 @@ static FrameCtorDebugFlags gFlags[] = { }; #define NUM_DEBUG_FLAGS (sizeof(gFlags) / sizeof(gFlags[0])) #endif #ifdef MOZ_XUL #include "nsMenuFrame.h" -#include "nsMenuPopupFrame.h" #include "nsPopupSetFrame.h" #include "nsTreeColFrame.h" #include "nsIBoxObject.h" #include "nsPIListBoxObject.h" #include "nsListBoxBodyFrame.h" #include "nsListItemFrame.h" #include "nsXULLabelFrame.h"
--- a/layout/base/nsCSSFrameConstructor.h +++ b/layout/base/nsCSSFrameConstructor.h @@ -12,34 +12,25 @@ #define nsCSSFrameConstructor_h___ #include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsILayoutHistoryState.h" #include "nsQuoteList.h" #include "nsCounterManager.h" -#include "nsHashKeys.h" -#include "nsThreadUtils.h" #include "nsCSSPseudoElements.h" #include "nsIAnonymousContentCreator.h" #include "nsFrameManager.h" -#include "RestyleManager.h" -class nsIDocument; struct nsFrameItems; struct nsAbsoluteItems; class nsStyleContext; -struct nsStyleContent; struct nsStyleDisplay; -class nsIPresShell; class nsIDOMHTMLSelectElement; -class nsPresContext; -class nsStyleChangeList; -class nsIFrame; struct nsGenConInitializer; class nsICSSAnonBoxPseudo; class nsPageContentFrame; struct PendingBinding; class nsFrameConstructorState; class nsFrameConstructorSaveState;
--- a/layout/base/nsCSSRendering.cpp +++ b/layout/base/nsCSSRendering.cpp @@ -6,49 +6,40 @@ /* utility functions for drawing borders and backgrounds */ #include <ctime> #include "mozilla/DebugOnly.h" #include "mozilla/HashFunctions.h" #include "mozilla/MathAlgorithms.h" -#include "mozilla/Types.h" #include "nsStyleConsts.h" #include "nsPresContext.h" #include "nsIFrame.h" #include "nsPoint.h" #include "nsRect.h" -#include "nsViewManager.h" #include "nsIPresShell.h" #include "nsFrameManager.h" #include "nsStyleContext.h" #include "nsGkAtoms.h" #include "nsCSSAnonBoxes.h" -#include "nsTransform2D.h" #include "nsIContent.h" #include "nsIDocumentInlines.h" #include "nsIScrollableFrame.h" #include "imgIRequest.h" #include "imgIContainer.h" #include "ImageOps.h" #include "nsCSSRendering.h" #include "nsCSSColorUtils.h" #include "nsITheme.h" -#include "nsThemeConstants.h" -#include "nsIServiceManager.h" #include "nsLayoutUtils.h" -#include "nsINameSpaceManager.h" #include "nsBlockFrame.h" #include "gfxContext.h" #include "nsRenderingContext.h" -#include "nsIInterfaceRequestorUtils.h" -#include "gfxPlatform.h" -#include "gfxImageSurface.h" #include "nsStyleStructInlines.h" #include "nsCSSFrameConstructor.h" #include "nsCSSProps.h" #include "nsContentUtils.h" #include "nsSVGEffects.h" #include "nsSVGIntegrationUtils.h" #include "gfxDrawable.h" #include "GeckoProfiler.h"
--- a/layout/base/nsCSSRendering.h +++ b/layout/base/nsCSSRendering.h @@ -3,23 +3,20 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* utility functions for drawing borders and backgrounds */ #ifndef nsCSSRendering_h___ #define nsCSSRendering_h___ -#include "nsStyleConsts.h" #include "gfxBlur.h" #include "gfxContext.h" -#include "gfxImageSurface.h" #include "nsLayoutUtils.h" -struct nsPoint; class nsStyleContext; class nsPresContext; class nsRenderingContext; namespace mozilla { // A CSSSizeOrRatio represents a (possibly partially specified) size for use // in computing image sizes. Either or both of the width and height might be
--- a/layout/base/nsCSSRenderingBorders.cpp +++ b/layout/base/nsCSSRenderingBorders.cpp @@ -1,38 +1,21 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ // vim:cindent:ts=2:et:sw=2: /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsStyleConsts.h" -#include "nsPoint.h" -#include "nsRect.h" -#include "nsViewManager.h" -#include "nsFrameManager.h" -#include "nsStyleContext.h" -#include "nsGkAtoms.h" -#include "nsCSSAnonBoxes.h" -#include "nsTransform2D.h" -#include "nsIContent.h" -#include "nsIScrollableFrame.h" -#include "imgIRequest.h" -#include "imgIContainer.h" -#include "nsCSSRendering.h" #include "nsCSSColorUtils.h" -#include "nsITheme.h" -#include "nsThemeConstants.h" -#include "nsIServiceManager.h" -#include "nsLayoutUtils.h" -#include "nsINameSpaceManager.h" -#include "nsBlockFrame.h" #include "GeckoProfiler.h" #include "nsExpirationTracker.h" #include "RoundedRect.h" +#include "nsClassHashtable.h" +#include "nsStyleStruct.h" #include "gfxContext.h" #include "nsCSSRenderingBorders.h" #include "mozilla/gfx/2D.h" #include "gfx2DGlue.h" #include <algorithm>
--- a/layout/base/nsCSSRenderingBorders.h +++ b/layout/base/nsCSSRenderingBorders.h @@ -3,20 +3,18 @@ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef NS_CSS_RENDERING_BORDERS_H #define NS_CSS_RENDERING_BORDERS_H #include "nsColor.h" -#include "nsStyleStruct.h" -#include "gfxContext.h" -#include "mozilla/gfx/2D.h" +class gfxContext; // define this to enable a bunch of debug dump info #undef DEBUG_NEW_BORDERS //thickness of dashed line relative to dotted line #define DOT_LENGTH 1 //square #define DASH_LENGTH 3 //3 times longer than dot
--- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -5,33 +5,28 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* the caret is the text cursor used, e.g., when editing */ #include "nsCOMPtr.h" #include "nsITimer.h" -#include "nsIComponentManager.h" -#include "nsIServiceManager.h" #include "nsFrameSelection.h" #include "nsIFrame.h" #include "nsIScrollableFrame.h" #include "nsIDOMNode.h" -#include "nsIDOMRange.h" #include "nsISelection.h" #include "nsISelectionPrivate.h" -#include "nsIDOMCharacterData.h" #include "nsIContent.h" #include "nsIPresShell.h" #include "nsRenderingContext.h" #include "nsPresContext.h" #include "nsBlockFrame.h" #include "nsISelectionController.h" -#include "nsDisplayList.h" #include "nsCaret.h" #include "nsTextFrame.h" #include "nsXULPopupManager.h" #include "nsMenuPopupFrame.h" #include "nsTextFragment.h" #include "mozilla/Preferences.h" #include "mozilla/LookAndFeel.h" #include "mozilla/Selection.h"
--- a/layout/base/nsCaret.h +++ b/layout/base/nsCaret.h @@ -6,22 +6,22 @@ /* the caret is the text cursor used, e.g., when editing */ #ifndef nsCaret_h__ #define nsCaret_h__ #include "nsCoord.h" #include "nsISelectionListener.h" -#include "nsITimer.h" -#include "nsWeakPtr.h" +#include "nsIWeakReferenceUtils.h" #include "nsFrameSelection.h" class nsRenderingContext; class nsDisplayListBuilder; +class nsITimer; //----------------------------------------------------------------------------- class nsCaret : public nsISelectionListener { public: nsCaret(); virtual ~nsCaret();
--- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -5,43 +5,36 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * structures that represent things to be painted (ordered in z-order), * used during painting and hit testing */ -// include PBrowserChild explicitly because TabChild won't include it -// because we're in layout :( -#include "mozilla/dom/PBrowserChild.h" #include "mozilla/dom/TabChild.h" - #include "mozilla/layers/PLayerTransaction.h" #include "nsDisplayList.h" #include "nsCSSRendering.h" #include "nsRenderingContext.h" #include "nsISelectionController.h" #include "nsIPresShell.h" #include "nsRegion.h" -#include "nsFrameManager.h" -#include "gfxContext.h" #include "nsStyleStructInlines.h" #include "nsStyleTransformMatrix.h" #include "gfxMatrix.h" #include "nsSVGIntegrationUtils.h" #include "nsLayoutUtils.h" #include "nsIScrollableFrame.h" #include "nsThemeConstants.h" #include "LayerTreeInvalidation.h" #include "imgIContainer.h" -#include "nsIInterfaceRequestorUtils.h" #include "BasicLayers.h" #include "nsBoxFrame.h" #include "nsViewportFrame.h" #include "nsSubDocumentFrame.h" #include "nsSVGEffects.h" #include "nsSVGElement.h" #include "nsSVGClipPathFrame.h" #include "GeckoProfiler.h"
--- a/layout/base/nsDisplayList.h +++ b/layout/base/nsDisplayList.h @@ -13,37 +13,33 @@ #ifndef NSDISPLAYLIST_H_ #define NSDISPLAYLIST_H_ #include "mozilla/Attributes.h" #include "nsCOMPtr.h" #include "nsIFrame.h" #include "nsPoint.h" #include "nsRect.h" -#include "nsISelection.h" #include "nsCaret.h" #include "plarena.h" #include "nsRegion.h" #include "FrameLayerBuilder.h" -#include "nsThemeConstants.h" #include "nsLayoutUtils.h" #include "nsDisplayListInvalidation.h" #include "DisplayListClipState.h" #include <stdint.h> #include <stdlib.h> #include <algorithm> -class nsIPresShell; class nsIContent; class nsRenderingContext; -class nsDeviceContext; class nsDisplayTableItem; -class nsDisplayItem; +class nsISelection; namespace mozilla { namespace layers { class ImageLayer; class ImageContainer; } //namepsace } //namepsace
--- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -6,69 +6,57 @@ /* container for a document and its presentation */ #include "nscore.h" #include "nsCOMPtr.h" #include "nsCRT.h" #include "nsString.h" #include "nsReadableUtils.h" -#include "nsISupports.h" #include "nsIContent.h" #include "nsIContentViewerContainer.h" #include "nsIContentViewer.h" #include "nsIDocumentViewerPrint.h" #include "nsIDOMBeforeUnloadEvent.h" #include "nsIDocument.h" #include "nsPresContext.h" #include "nsIPresShell.h" #include "nsStyleSet.h" -#include "nsIStyleSheet.h" #include "nsCSSStyleSheet.h" #include "nsIFrame.h" #include "nsSubDocumentFrame.h" #include "nsILinkHandler.h" #include "nsIDOMDocument.h" #include "nsISelectionListener.h" #include "nsISelectionPrivate.h" #include "nsIDOMHTMLDocument.h" -#include "nsIDOMHTMLCollection.h" #include "nsIDOMHTMLElement.h" -#include "nsIDOMRange.h" -#include "nsContentCID.h" -#include "nsLayoutCID.h" #include "nsContentUtils.h" #include "nsLayoutStylesheetCache.h" #include "mozilla/Preferences.h" #include "mozilla/dom/EncodingUtils.h" -#include "nsIDeviceContextSpec.h" #include "nsViewManager.h" #include "nsView.h" #include "nsIPageSequenceFrame.h" -#include "nsIURL.h" #include "nsNetUtil.h" #include "nsIContentViewerEdit.h" #include "nsIContentViewerFile.h" #include "mozilla/css/Loader.h" #include "nsIMarkupDocumentViewer.h" #include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h" -#include "nsIDocShellTreeOwner.h" #include "nsIDocShell.h" #include "nsIBaseWindow.h" #include "nsILayoutHistoryState.h" #include "nsCharsetSource.h" #include "nsGUIEvent.h" #include "nsHTMLReflowState.h" -#include "nsIDOMHTMLAnchorElement.h" -#include "nsIDOMHTMLAreaElement.h" -#include "nsIDOMHTMLLinkElement.h" #include "nsIImageLoadingContent.h" #include "nsCopySupport.h" #include "nsIDOMHTMLFrameSetElement.h" #ifdef MOZ_XUL #include "nsIXULDocument.h" #include "nsXULPopupManager.h" #endif @@ -76,20 +64,17 @@ #include "nsPIDOMWindow.h" #include "nsDOMNavigationTiming.h" #include "nsPIWindowRoot.h" #include "nsJSEnvironment.h" #include "nsFocusManager.h" #include "nsIScrollableFrame.h" -#include "nsIHTMLDocument.h" -#include "nsGfxCIID.h" #include "nsStyleSheetService.h" -#include "nsURILoader.h" #include "nsRenderingContext.h" #include "nsILoadContext.h" #include "nsIPrompt.h" #include "imgIContainer.h" // image animation mode constants //-------------------------- // Printing Include @@ -97,69 +82,43 @@ #ifdef NS_PRINTING #include "nsIWebBrowserPrint.h" #include "nsPrintEngine.h" // Print Options #include "nsIPrintSettings.h" -#include "nsIPrintSettingsService.h" #include "nsIPrintOptions.h" -#include "nsIServiceManager.h" #include "nsISimpleEnumerator.h" -#include "nsXPCOM.h" -#include "nsISupportsPrimitives.h" // PrintOptions is now implemented by PrintSettingsService static const char sPrintOptionsContractID[] = "@mozilla.org/gfx/printsettings-service;1"; -// Printing Events -#include "nsPrintPreviewListener.h" - -#include "nsIDOMHTMLFrameElement.h" -#include "nsIDOMHTMLIFrameElement.h" -#include "nsIDOMHTMLObjectElement.h" #include "nsIPluginDocument.h" -// Print Progress -#include "nsIPrintProgress.h" -#include "nsIPrintProgressParams.h" - -// Print error dialog -#include "nsIWindowWatcher.h" - -// Printing -#include "nsPagePrintTimer.h" - #endif // NS_PRINTING //focus #include "nsIDOMEventTarget.h" #include "nsIDOMEventListener.h" #include "nsISelectionController.h" #include "nsBidiUtils.h" #include "nsISHEntry.h" #include "nsISHistory.h" #include "nsISHistoryInternal.h" #include "nsIWebNavigation.h" -#include "nsWeakPtr.h" #include "nsEventDispatcher.h" //paint forcing -#include "prenv.h" #include <stdio.h> -#include "nsObserverService.h" - #include "mozilla/dom/Element.h" -#include "jsfriendapi.h" - using namespace mozilla; using namespace mozilla::dom; #ifdef DEBUG #undef NOISY_VIEWER #else #undef NOISY_VIEWER
--- a/layout/base/nsFrameManager.cpp +++ b/layout/base/nsFrameManager.cpp @@ -10,60 +10,37 @@ * Modifications to Mozilla code or documentation identified per MPL Section 3.3 * * Date Modified by Description of modification * 04/20/2000 IBM Corp. OS/2 VisualAge build. */ /* storage of the frame tree and information about it */ -#include "mozilla/DebugOnly.h" - #include "nscore.h" -#include "nsPresContext.h" #include "nsIPresShell.h" -#include "nsStyleSet.h" -#include "nsCSSFrameConstructor.h" #include "nsStyleContext.h" -#include "nsStyleChangeList.h" -#include "nsIServiceManager.h" #include "nsCOMPtr.h" -#include "prthread.h" #include "plhash.h" #include "nsPlaceholderFrame.h" #include "nsGkAtoms.h" -#include "nsCSSPseudoElements.h" -#ifdef DEBUG -#include "nsIStyleRule.h" -#endif #include "nsILayoutHistoryState.h" #include "nsPresState.h" -#include "nsIContent.h" -#include "nsINameSpaceManager.h" +#include "mozilla/dom/Element.h" #include "nsIDocument.h" -#include "nsIScrollableFrame.h" -#include "nsIDOMNodeList.h" -#include "nsIDOMHTMLCollection.h" -#include "nsIFormControl.h" -#include "nsIDOMElement.h" -#include "nsIDOMHTMLFormElement.h" -#include "nsIForm.h" #include "nsContentUtils.h" -#include "nsReadableUtils.h" -#include "nsUnicharUtils.h" #include "nsError.h" -#include "nsLayoutUtils.h" #include "nsAutoPtr.h" -#include "imgIRequest.h" #include "nsAbsoluteContainingBlock.h" #include "ChildIterator.h" #include "nsFrameManager.h" #include "GeckoProfiler.h" +#include "nsIStatefulFrame.h" #ifdef DEBUG //#define DEBUG_UNDISPLAYED_MAP #else #undef DEBUG_UNDISPLAYED_MAP #endif using namespace mozilla;
--- a/layout/base/nsFrameManager.h +++ b/layout/base/nsFrameManager.h @@ -15,18 +15,16 @@ */ /* storage of the frame tree and information about it */ #ifndef _nsFrameManager_h_ #define _nsFrameManager_h_ #include "nsIFrame.h" -#include "nsIStatefulFrame.h" -#include "nsChangeHint.h" #include "nsFrameManagerBase.h" namespace mozilla { /** * Node in a linked list, containing the style for an element that * does not have a frame but whose parent does have a frame. */ struct UndisplayedNode {
--- a/layout/base/nsFrameTraversal.h +++ b/layout/base/nsFrameTraversal.h @@ -1,19 +1,20 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #ifndef NSFRAMETRAVERSAL_H #define NSFRAMETRAVERSAL_H #include "mozilla/Attributes.h" -#include "nsIFrame.h" #include "nsIFrameTraversal.h" +class nsIFrame; + nsresult NS_NewFrameTraversal(nsIFrameEnumerator **aEnumerator, nsPresContext* aPresContext, nsIFrame *aStart, nsIteratorType aType, bool aVisual, bool aLockInScrollView, bool aFollowOOFs);
--- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -1,34 +1,31 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 sw=2 et tw=78: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "nsLayoutUtils.h" -#include "base/basictypes.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Util.h" -#include "nsIFormControlFrame.h" #include "nsPresContext.h" #include "nsIContent.h" #include "nsIDOMHTMLDocument.h" #include "nsIDOMHTMLElement.h" #include "nsFrameList.h" #include "nsGkAtoms.h" #include "nsIAtom.h" #include "nsCSSPseudoElements.h" #include "nsCSSAnonBoxes.h" #include "nsCSSColorUtils.h" #include "nsView.h" #include "nsPlaceholderFrame.h" #include "nsIScrollableFrame.h" -#include "nsCSSFrameConstructor.h" #include "nsIDOMEvent.h" #include "nsGUIEvent.h" #include "nsDisplayList.h" #include "nsRegion.h" #include "nsFrameManager.h" #include "nsBlockFrame.h" #include "nsBidiPresUtils.h" #include "imgIContainer.h" @@ -36,66 +33,57 @@ #include "gfxContext.h" #include "gfxFont.h" #include "nsRenderingContext.h" #include "nsIInterfaceRequestorUtils.h" #include "nsCSSRendering.h" #include "nsCxPusher.h" #include "nsThemeConstants.h" #include "nsPIDOMWindow.h" -#include "nsIBaseWindow.h" #include "nsIDocShell.h" #include "nsIWidget.h" #include "gfxMatrix.h" #include "gfxPoint3D.h" #include "gfxTypes.h" -#include "gfxUserFontSet.h" #include "nsTArray.h" #include "mozilla/dom/HTMLCanvasElement.h" #include "nsICanvasRenderingContextInternal.h" #include "gfxPlatform.h" #include "nsClientRect.h" #include <algorithm> #include "mozilla/dom/HTMLVideoElement.h" #include "mozilla/dom/HTMLImageElement.h" #include "imgIRequest.h" #include "nsIImageLoadingContent.h" #include "nsCOMPtr.h" #include "nsCSSProps.h" #include "nsListControlFrame.h" -#include "ImageLayers.h" -#include "mozilla/arm.h" #include "mozilla/dom/Element.h" #include "nsCanvasFrame.h" #include "gfxDrawable.h" #include "gfxUtils.h" #include "nsDataHashtable.h" #include "nsTextFrame.h" #include "nsFontFaceList.h" #include "nsFontInflationData.h" #include "nsSVGUtils.h" -#include "nsSVGIntegrationUtils.h" -#include "nsSVGForeignObjectFrame.h" -#include "nsSVGOuterSVGFrame.h" #include "nsSVGTextFrame2.h" #include "nsStyleStructInlines.h" #include "nsStyleTransformMatrix.h" -#include "mozilla/dom/PBrowserChild.h" -#include "mozilla/dom/TabChild.h" #include "mozilla/Preferences.h" #ifdef MOZ_XUL #include "nsXULPopupManager.h" #endif #include "GeckoProfiler.h" #include "nsAnimationManager.h" #include "nsTransitionManager.h" -#include "nsViewportInfo.h" +#include "RestyleManager.h" using namespace mozilla; using namespace mozilla::css; using namespace mozilla::dom; using namespace mozilla::layers; using namespace mozilla::layout; #define FLEXBOX_ENABLED_PREF_NAME "layout.css.flexbox.enabled"
--- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -14,41 +14,38 @@ class nsIScrollableFrame; class nsIDOMEvent; class nsRegion; class nsDisplayListBuilder; class nsDisplayItem; class nsFontMetrics; class nsClientRectList; class nsFontFaceList; class nsIImageLoadingContent; +class nsStyleContext; +class nsBlockFrame; +class gfxDrawable; +class nsView; +class imgIContainer; #include "mozilla/MemoryReporting.h" #include "nsChangeHint.h" -#include "nsStyleContext.h" #include "nsAutoPtr.h" -#include "nsStyleSet.h" #include "nsIFrame.h" #include "nsThreadUtils.h" #include "nsIPresShell.h" #include "nsIPrincipal.h" #include "gfxPattern.h" -#include "imgIContainer.h" #include "nsCSSPseudoElements.h" #include "nsHTMLReflowState.h" -#include "nsIFrameLoader.h" #include "FrameMetrics.h" #include "gfx3DMatrix.h" #include <limits> #include <algorithm> -class nsBlockFrame; -class gfxDrawable; -class nsView; - namespace mozilla { class SVGImageContext; namespace dom { class Element; class HTMLImageElement; class HTMLCanvasElement; class HTMLVideoElement; } // namespace dom
--- a/layout/base/nsPresArena.cpp +++ b/layout/base/nsPresArena.cpp @@ -14,19 +14,19 @@ #define ALIGN_SHIFT 3 #define PL_ARENA_CONST_ALIGN_MASK ((uintptr_t(1) << ALIGN_SHIFT) - 1) #include "plarena.h" // plarena.h needs to be included first to make it use the above // PL_ARENA_CONST_ALIGN_MASK in this file. #include "nsPresArena.h" +#include "mozilla/MemoryChecking.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Poison.h" -#include "nsCRT.h" #include "nsDebug.h" #include "nsArenaMemoryStats.h" #include "nsPrintfCString.h" // Size to use for PLArena block allocations. static const size_t ARENA_PAGE_SIZE = 8192; nsPresArena::nsPresArena()
--- a/layout/base/nsPresArena.h +++ b/layout/base/nsPresArena.h @@ -5,17 +5,16 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* arena allocation for the frame tree and closely-related objects */ #ifndef nsPresArena_h___ #define nsPresArena_h___ -#include "mozilla/MemoryChecking.h" #include "mozilla/MemoryReporting.h" #include <stdint.h> #include "nscore.h" #include "nsQueryFrame.h" #include "nsTArray.h" #include "nsTHashtable.h" #include "plarena.h"
--- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -7,92 +7,65 @@ #include "mozilla/DebugOnly.h" #include "base/basictypes.h" #include "nsCOMPtr.h" #include "nsPresContext.h" #include "nsIPresShell.h" -#include "nsILinkHandler.h" #include "nsIDocShell.h" #include "nsIContentViewer.h" #include "nsPIDOMWindow.h" #include "nsStyleSet.h" #include "nsIContent.h" #include "nsIFrame.h" -#include "nsIURL.h" #include "nsIDocument.h" #include "nsIPrintSettings.h" #include "nsILanguageAtomService.h" -#include "nsStyleContext.h" #include "mozilla/LookAndFeel.h" -#include "nsIComponentManager.h" -#include "nsIURIContentListener.h" -#include "nsIInterfaceRequestor.h" #include "nsIInterfaceRequestorUtils.h" -#include "nsIServiceManager.h" -#include "nsIDOMElement.h" -#include "nsContentPolicyUtils.h" -#include "nsIDOMWindow.h" -#include "nsXPIDLString.h" #include "nsIWeakReferenceUtils.h" -#include "nsCSSRendering.h" -#include "prprf.h" #include "nsAutoPtr.h" #include "nsEventStateManager.h" #include "nsThreadUtils.h" #include "nsFrameManager.h" #include "nsLayoutUtils.h" #include "nsViewManager.h" #include "RestyleManager.h" #include "nsCSSRuleProcessor.h" -#include "nsStyleChangeList.h" #include "nsRuleNode.h" #include "nsEventDispatcher.h" -#include "gfxUserFontSet.h" #include "gfxPlatform.h" #include "nsCSSRules.h" #include "nsFontFaceLoader.h" #include "nsEventListenerManager.h" -#include "nsStyleStructInlines.h" -#include "nsIAppShell.h" #include "prenv.h" #include "nsObjectFrame.h" #include "nsTransitionManager.h" #include "nsAnimationManager.h" #include "mozilla/MemoryReporting.h" #include "mozilla/dom/Element.h" #include "nsIMessageManager.h" -#include "FrameLayerBuilder.h" #include "nsDOMMediaQueryList.h" #include "nsSMILAnimationController.h" #include "mozilla/css/ImageLoader.h" -#include "mozilla/dom/PBrowserChild.h" #include "mozilla/dom/TabChild.h" -#include "RestyleManager.h" #include "nsRefreshDriver.h" #include "Layers.h" -#ifdef IBMBIDI -#include "nsBidiPresUtils.h" -#endif // IBMBIDI - #include "nsContentUtils.h" #include "nsCxPusher.h" #include "nsPIWindowRoot.h" #include "mozilla/Preferences.h" // Needed for Start/Stop of Image Animation #include "imgIContainer.h" #include "nsIImageLoadingContent.h" -//needed for resetting of image service color -#include "nsLayoutCID.h" - #include "nsCSSParser.h" using namespace mozilla; using namespace mozilla::dom; using namespace mozilla::layers; uint8_t gNotifySubDocInvalidationData; @@ -195,18 +168,16 @@ IsVisualCharset(const nsCString& aCharse return true; // visual text type } else { return false; // logical text type } } #endif // IBMBIDI -#include "nsContentCID.h" - // NOTE! nsPresContext::operator new() zeroes out all members, so don't // bother initializing members to 0. nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType) : mType(aType), mDocument(aDocument), mMinFontSize(0), mTextZoom(1.0), mFullZoom(1.0), mLastFontInflationScreenWidth(-1.0), mPageSize(-1, -1), mPPScale(1.0f), mViewportStyleOverflow(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO),
--- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -4,82 +4,68 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* a presentation of a document, part 1 */ #ifndef nsPresContext_h___ #define nsPresContext_h___ #include "mozilla/Attributes.h" -#include "nsISupports.h" #include "nsColor.h" #include "nsCoord.h" #include "nsCOMPtr.h" #include "nsIPresShell.h" #include "nsRect.h" #include "nsDeviceContext.h" #include "nsFont.h" #include "nsIObserver.h" #include "nsITimer.h" #include "nsCRT.h" #include "FramePropertyTable.h" #include "nsGkAtoms.h" -#include "nsRefPtrHashtable.h" #include "nsCycleCollectionParticipant.h" #include "nsChangeHint.h" #include <algorithm> // This also pulls in gfxTypes.h, which we cannot include directly. #include "gfxRect.h" #include "nsTArray.h" #include "nsAutoPtr.h" -#include "nsIWidget.h" #include "mozilla/MemoryReporting.h" #include "mozilla/TimeStamp.h" #include "prclist.h" #include "nsThreadUtils.h" #ifdef IBMBIDI class nsBidiPresUtils; #endif // IBMBIDI -struct nsRect; - -class imgIRequest; - class nsAString; class nsIPrintSettings; class nsIDocument; class nsILanguageAtomService; class nsITheme; class nsIContent; -class nsFontMetrics; class nsIFrame; class nsFrameManager; class nsILinkHandler; -class nsStyleContext; class nsIAtom; class nsEventStateManager; -class nsIURI; class nsICSSPseudoComparator; struct nsStyleBackground; struct nsStyleBorder; class nsIRunnable; class gfxUserFontSet; class nsUserFontSet; struct nsFontFaceRuleContainer; class nsObjectFrame; class nsTransitionManager; class nsAnimationManager; -class imgIContainer; class nsIDOMMediaQueryList; class nsRefreshDriver; - -#ifdef MOZ_REFLOW_PERF -class nsRenderingContext; -#endif +class nsIWidget; namespace mozilla { class RestyleManager; namespace layers { class ContainerLayer; } }
--- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -14,138 +14,111 @@ * * Date Modified by Description of modification * 05/03/2000 IBM Corp. Observer events for reflow states */ /* a presentation of a document, part 2 */ #include "mozilla/MemoryReporting.h" -#include "mozilla/dom/PBrowserChild.h" #include "mozilla/dom/TabChild.h" #include "mozilla/Likely.h" #include "mozilla/Util.h" #include <algorithm> #ifdef XP_WIN #include "winuser.h" #endif #include "nsPresShell.h" #include "nsPresContext.h" #include "nsIContent.h" #include "mozilla/dom/Element.h" #include "nsIDocument.h" -#include "nsIDOMXULDocument.h" #include "nsCSSStyleSheet.h" -#include "nsIDOMCSSStyleSheet.h" // for Pref-related rule management (bugs 22963,20760,31816) #include "nsAnimationManager.h" #include "nsINameSpaceManager.h" // for Pref-related rule management (bugs 22963,20760,31816) -#include "nsIServiceManager.h" #include "nsFrame.h" #include "FrameLayerBuilder.h" #include "nsViewManager.h" #include "nsView.h" #include "nsCRTGlue.h" #include "prlog.h" #include "prprf.h" #include "prinrval.h" #include "nsTArray.h" #include "nsCOMArray.h" #include "nsContainerFrame.h" #include "nsDOMEvent.h" -#include "nsHTMLParts.h" #include "nsISelection.h" -#include "nsISelectionPrivate.h" #include "mozilla/Selection.h" -#include "nsLayoutCID.h" #include "nsGkAtoms.h" #include "nsIDOMRange.h" #include "nsIDOMDocument.h" #include "nsIDOMNode.h" #include "nsIDOMNodeList.h" #include "nsIDOMElement.h" #include "nsRange.h" -#include "nsCSSPseudoElements.h" #include "nsCOMPtr.h" #include "nsAutoPtr.h" #include "nsReadableUtils.h" -#include "nsUnicharUtils.h" #include "nsIPageSequenceFrame.h" #include "nsCaret.h" #include "nsIDOMHTMLDocument.h" -#include "nsIDOMXMLDocument.h" #include "nsFrameManager.h" #include "nsEventStateManager.h" #include "nsIMEStateManager.h" #include "nsXPCOM.h" -#include "nsISupportsPrimitives.h" #include "nsILayoutHistoryState.h" #include "nsILineIterator.h" // for ScrollContentIntoView -#include "nsWeakPtr.h" #include "pldhash.h" #include "mozilla/dom/Touch.h" #include "nsIObserverService.h" #include "nsIDocShell.h" // for reflow observation #include "nsIBaseWindow.h" #include "nsError.h" #include "nsLayoutUtils.h" #include "nsViewportInfo.h" #include "nsCSSRendering.h" // for |#ifdef DEBUG| code #include "prenv.h" -#include "nsAlgorithm.h" -#include "nsIAttribute.h" -#include "nsIGlobalHistory2.h" #include "nsDisplayList.h" #include "nsRegion.h" #include "nsRenderingContext.h" #include "nsAutoLayoutPhase.h" #ifdef MOZ_REFLOW_PERF #include "nsFontMetrics.h" #endif #include "PositionedEventTargeting.h" #include "nsIReflowCallback.h" #include "nsPIDOMWindow.h" #include "nsFocusManager.h" -#include "nsNPAPIPluginInstance.h" #include "nsIObjectFrame.h" #include "nsIObjectLoadingContent.h" #include "nsNetUtil.h" #include "nsEventDispatcher.h" #include "nsThreadUtils.h" #include "nsStyleSheetService.h" #include "gfxImageSurface.h" #include "gfxContext.h" -#include "mozilla/dom/HTMLMediaElement.h" #include "nsSMILAnimationController.h" #include "SVGContentUtils.h" -#include "nsSVGUtils.h" #include "nsSVGEffects.h" #include "SVGFragmentIdentifier.h" #include "nsPerformance.h" #include "nsRefreshDriver.h" #include "nsDOMNavigationTiming.h" // Drag & Drop, Clipboard -#include "nsWidgetsCID.h" -#include "nsIClipboard.h" -#include "nsIClipboardHelper.h" #include "nsIDocShellTreeItem.h" #include "nsIURI.h" #include "nsIScrollableFrame.h" -#include "prtime.h" -#include "nsIDragService.h" -#include "nsCopySupport.h" -#include "nsIDOMHTMLAnchorElement.h" -#include "nsIDOMHTMLAreaElement.h" -#include "nsIDOMHTMLLinkElement.h" #include "nsITimer.h" #ifdef ACCESSIBILITY #include "nsAccessibilityService.h" #include "mozilla/a11y/DocAccessible.h" #ifdef DEBUG #include "mozilla/a11y/Logging.h" #endif #endif @@ -163,31 +136,30 @@ #include "nsIDOMXULMultSelectCntrlEl.h" #include "nsIDOMXULSelectCntrlItemEl.h" #include "nsIDOMXULMenuListElement.h" #endif #include "GeckoProfiler.h" #include "gfxPlatform.h" -#include "imgIEncoder.h" #include "Layers.h" #include "LayerTreeInvalidation.h" #include "mozilla/css/ImageLoader.h" -#include "mozilla/layers/Compositor.h" #include "mozilla/Preferences.h" #include "mozilla/Telemetry.h" -#include "nsAsyncDOMEvent.h" #include "nsCanvasFrame.h" -#include "nsIContentViewer.h" #include "nsIImageLoadingContent.h" #include "nsIScreen.h" #include "nsIScreenManager.h" #include "nsPlaceholderFrame.h" #include "nsTransitionManager.h" +#include "RestyleManager.h" +#include "nsIDOMHTMLElement.h" +#include "nsIDragSession.h" #define ANCHOR_SCROLL_FLAGS \ (nsIPresShell::SCROLL_OVERFLOW_HIDDEN | nsIPresShell::SCROLL_NO_PARENT_FRAMES) using namespace mozilla; using namespace mozilla::css; using namespace mozilla::dom; using namespace mozilla::layers; @@ -8280,18 +8252,16 @@ nsIPresShell::RemoveRefreshObserverExter //------------------------------------------------------ // End of protected and private methods on the PresShell //------------------------------------------------------ // Start of DEBUG only code #ifdef DEBUG -#include "nsIURL.h" -#include "nsILinkHandler.h" static void LogVerifyMessage(nsIFrame* k1, nsIFrame* k2, const char* aMsg) { nsAutoString n1, n2; if (k1) { k1->GetFrameName(n1); } else {
--- a/layout/base/nsPresShell.h +++ b/layout/base/nsPresShell.h @@ -25,17 +25,16 @@ #include "nsStubDocumentObserver.h" #include "nsISelectionController.h" #include "nsIObserver.h" #include "nsWeakReference.h" #include "nsCRT.h" #include "nsAutoPtr.h" #include "nsIWidget.h" #include "nsStyleSet.h" -#include "nsPresArena.h" #include "nsFrameSelection.h" #include "nsGUIEvent.h" #include "nsContentUtils.h" // For AddScriptBlocker(). #include "nsRefreshDriver.h" #include "mozilla/Attributes.h" #include "mozilla/MemoryReporting.h" class nsRange;
--- a/layout/base/nsRefreshDriver.cpp +++ b/layout/base/nsRefreshDriver.cpp @@ -30,18 +30,16 @@ #include "nsRefreshDriver.h" #include "nsITimer.h" #include "nsLayoutUtils.h" #include "nsPresContext.h" #include "nsComponentManagerUtils.h" #include "prlog.h" #include "nsAutoPtr.h" #include "nsIDocument.h" -#include "nsGUIEvent.h" -#include "nsEventDispatcher.h" #include "jsapi.h" #include "nsContentUtils.h" #include "nsCxPusher.h" #include "mozilla/Preferences.h" #include "nsViewManager.h" #include "GeckoProfiler.h" #include "nsNPAPIPluginInstance.h" #include "nsPerformance.h"
--- a/layout/base/nsRefreshDriver.h +++ b/layout/base/nsRefreshDriver.h @@ -9,20 +9,18 @@ * refresh rate. (Perhaps temporary, until replaced by compositor.) */ #ifndef nsRefreshDriver_h_ #define nsRefreshDriver_h_ #include "mozilla/TimeStamp.h" #include "mozFlushType.h" -#include "nsCOMPtr.h" #include "nsTObserverArray.h" #include "nsTArray.h" -#include "nsAutoPtr.h" #include "nsTHashtable.h" #include "nsClassHashtable.h" #include "nsHashKeys.h" #include "mozilla/Attributes.h" #include "mozilla/Util.h" class nsPresContext; class nsIPresShell;
--- a/layout/base/nsStyleChangeList.cpp +++ b/layout/base/nsStyleChangeList.cpp @@ -4,20 +4,17 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * a list of the recomputation that needs to be done in response to a * style change */ #include "nsStyleChangeList.h" -#include "nsStyleConsts.h" -#include "nsIFrame.h" #include "nsIContent.h" -#include "nsCRT.h" static const uint32_t kGrowArrayBy = 10; nsStyleChangeList::nsStyleChangeList() : mArray(mBuffer), mArraySize(kStyleChangeBufferSize), mCount(0) {
--- a/layout/base/nsStyleSheetService.cpp +++ b/layout/base/nsStyleSheetService.cpp @@ -1,25 +1,22 @@ /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* implementation of interface for managing user and user-agent style sheets */ -#include "prlog.h" #include "nsStyleSheetService.h" #include "nsIStyleSheet.h" #include "mozilla/MemoryReporting.h" #include "mozilla/css/Loader.h" #include "nsCSSStyleSheet.h" #include "nsIURI.h" -#include "nsContentCID.h" #include "nsCOMPtr.h" -#include "nsIServiceManager.h" #include "nsICategoryManager.h" #include "nsISupportsPrimitives.h" #include "nsNetUtil.h" #include "nsIObserverService.h" #include "nsLayoutStatics.h" #include "nsIMemoryReporter.h" NS_MEMORY_REPORTER_MALLOC_SIZEOF_FUN(LayoutStyleSheetServiceMallocSizeOf)
--- a/layout/base/nsStyleSheetService.h +++ b/layout/base/nsStyleSheetService.h @@ -5,22 +5,22 @@ /* implementation of interface for managing user and user-agent style sheets */ #ifndef nsStyleSheetService_h_ #define nsStyleSheetService_h_ #include "nsIStyleSheetService.h" #include "nsCOMArray.h" -#include "nsIStyleSheet.h" #include "mozilla/Attributes.h" #include "mozilla/MemoryReporting.h" class nsISimpleEnumerator; class nsICategoryManager; +class nsIStyleSheet; #define NS_STYLESHEETSERVICE_CID \ {0xfcca6f83, 0x9f7d, 0x44e4, {0xa7, 0x4b, 0xb5, 0x94, 0x33, 0xe6, 0xc8, 0xc3}} #define NS_STYLESHEETSERVICE_CONTRACTID \ "@mozilla.org/content/style-sheet-service;1" class nsIMemoryReporter;
--- a/layout/forms/nsMeterFrame.cpp +++ b/layout/forms/nsMeterFrame.cpp @@ -16,16 +16,18 @@ #include "nsContentCreatorFunctions.h" #include "nsContentUtils.h" #include "nsFormControlFrame.h" #include "nsFontMetrics.h" #include "nsContentList.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/HTMLMeterElement.h" #include "nsContentList.h" +#include "nsStyleSet.h" +#include "nsThemeConstants.h" #include <algorithm> using mozilla::dom::HTMLMeterElement; nsIFrame* NS_NewMeterFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { return new (aPresShell) nsMeterFrame(aContext);
--- a/layout/forms/nsProgressFrame.cpp +++ b/layout/forms/nsProgressFrame.cpp @@ -16,16 +16,18 @@ #include "nsContentCreatorFunctions.h" #include "nsContentUtils.h" #include "nsFormControlFrame.h" #include "nsContentList.h" #include "nsFontMetrics.h" #include "mozilla/dom/Element.h" #include "mozilla/dom/HTMLProgressElement.h" #include "nsContentList.h" +#include "nsStyleSet.h" +#include "nsThemeConstants.h" #include <algorithm> using namespace mozilla::dom; nsIFrame* NS_NewProgressFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { return new (aPresShell) nsProgressFrame(aContext);
--- a/layout/forms/nsRangeFrame.cpp +++ b/layout/forms/nsRangeFrame.cpp @@ -19,16 +19,18 @@ #include "nsIPresShell.h" #include "nsGkAtoms.h" #include "mozilla/dom/HTMLInputElement.h" #include "nsPresContext.h" #include "nsNodeInfoManager.h" #include "nsRenderingContext.h" #include "mozilla/dom/Element.h" #include "prtypes.h" +#include "nsStyleSet.h" +#include "nsThemeConstants.h" #include <algorithm> #ifdef ACCESSIBILITY #include "nsAccessibilityService.h" #endif #define LONG_SIDE_TO_SHORT_SIDE_RATIO 10
--- a/layout/forms/test/Makefile.in +++ b/layout/forms/test/Makefile.in @@ -39,26 +39,21 @@ MOCHITEST_FILES = test_bug231389.html \ test_bug572406.html \ test_bug572649.html \ test_bug620936.html \ test_bug595310.html \ test_bug644542.html \ test_bug672810.html \ test_bug704049.html \ test_bug869314.html \ + test_bug903715.html \ test_listcontrol_search.html \ test_select_prevent_default.html \ $(NULL) -ifneq ($(OS_TARGET),Android) -MOCHITEST_FILES += \ - test_bug903715.html \ - $(NULL) -endif - MOCHITEST_CHROME_FILES = \ bug536567_iframe.html \ test_bug536567_perwindowpb.html \ bug536567_subframe.html \ test_bug665540.html \ bug665540_window.xul \ $(NULL)
--- a/layout/generic/nsGfxScrollFrame.cpp +++ b/layout/generic/nsGfxScrollFrame.cpp @@ -50,16 +50,17 @@ #include "FrameLayerBuilder.h" #include "nsSMILKeySpline.h" #include "nsSubDocumentFrame.h" #include "nsSVGOuterSVGFrame.h" #include "mozilla/Attributes.h" #include "ScrollbarActivity.h" #include "nsRefreshDriver.h" #include "nsContentList.h" +#include "nsThemeConstants.h" #include <algorithm> #include <cstdlib> // for std::abs(int/long) #include <cmath> // for std::abs(float/double) using namespace mozilla; using namespace mozilla::dom; using namespace mozilla::layout;
--- a/layout/generic/nsImageFrame.cpp +++ b/layout/generic/nsImageFrame.cpp @@ -63,16 +63,18 @@ #include "nsEventStates.h" #include "nsError.h" #include "nsBidiUtils.h" #include "nsBidiPresUtils.h" #include "gfxRect.h" #include "ImageLayers.h" #include "ImageContainer.h" +#include "nsStyleSet.h" +#include "nsBlockFrame.h" #include "mozilla/Preferences.h" #include "mozilla/dom/Link.h" using namespace mozilla; // sizes (pixels) for image icon, padding and border frame
--- a/layout/mathml/nsMathMLTokenFrame.cpp +++ b/layout/mathml/nsMathMLTokenFrame.cpp @@ -7,16 +7,17 @@ #include "nsFrame.h" #include "nsPresContext.h" #include "nsStyleContext.h" #include "nsStyleConsts.h" #include "nsContentUtils.h" #include "nsCSSFrameConstructor.h" #include "nsMathMLTokenFrame.h" #include "nsTextFrame.h" +#include "RestyleManager.h" #include <algorithm> nsIFrame* NS_NewMathMLTokenFrame(nsIPresShell* aPresShell, nsStyleContext* aContext) { return new (aPresShell) nsMathMLTokenFrame(aContext); }
--- a/layout/mathml/nsMathMLmtableFrame.cpp +++ b/layout/mathml/nsMathMLmtableFrame.cpp @@ -16,16 +16,17 @@ #include "nsTArray.h" #include "nsCSSFrameConstructor.h" #include "nsTableOuterFrame.h" #include "nsTableFrame.h" #include "nsTableCellFrame.h" #include "celldata.h" #include "nsMathMLmtableFrame.h" +#include "RestyleManager.h" #include <algorithm> using namespace mozilla; // // <mtable> -- table or matrix - implementation //
--- a/layout/style/AnimationCommon.cpp +++ b/layout/style/AnimationCommon.cpp @@ -12,16 +12,17 @@ #include "nsIFrame.h" #include "nsLayoutUtils.h" #include "mozilla/LookAndFeel.h" #include "Layers.h" #include "FrameLayerBuilder.h" #include "nsDisplayList.h" #include "mozilla/MemoryReporting.h" #include "mozilla/Preferences.h" +#include "RestyleManager.h" using namespace mozilla::layers; namespace mozilla { namespace css { /* static */ bool IsGeometricProperty(nsCSSProperty aProperty)
--- a/layout/style/nsHTMLStyleSheet.cpp +++ b/layout/style/nsHTMLStyleSheet.cpp @@ -29,16 +29,17 @@ #include "nsRuleData.h" #include "nsError.h" #include "nsRuleProcessorData.h" #include "nsCSSRuleProcessor.h" #include "mozilla/MemoryReporting.h" #include "mozilla/dom/Element.h" #include "nsCSSFrameConstructor.h" #include "nsHashKeys.h" +#include "RestyleManager.h" using namespace mozilla; using namespace mozilla::dom; NS_IMPL_ISUPPORTS1(nsHTMLStyleSheet::HTMLColorRule, nsIStyleRule) /* virtual */ void nsHTMLStyleSheet::HTMLColorRule::MapRuleInfoInto(nsRuleData* aRuleData)
--- a/layout/style/nsTransitionManager.cpp +++ b/layout/style/nsTransitionManager.cpp @@ -25,16 +25,18 @@ #include "nsGUIEvent.h" #include "mozilla/dom/Element.h" #include "nsIFrame.h" #include "nsCSSFrameConstructor.h" #include "Layers.h" #include "FrameLayerBuilder.h" #include "nsDisplayList.h" #include "nsStyleChangeList.h" +#include "nsStyleSet.h" +#include "RestyleManager.h" using mozilla::TimeStamp; using mozilla::TimeDuration; using namespace mozilla; using namespace mozilla::layers; using namespace mozilla::css;
--- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -4264,17 +4264,17 @@ if (SpecialPowers.getBoolPref("layout.cs }, "text-combine-horizontal": { domProp: "textCombineHorizontal", inherited: true, type: CSS_TYPE_LONGHAND, initial_values: [ "none" ], other_values: [ "all", "digits", "digits 2", "digits 3", "digits 4", "digits 3" ], invalid_values: [ "auto", "all 2", "none all", "digits -3", "digits 0", - "digits 12", "none 3", "digits 3.1415", "digits3", + "digits 12", "none 3", "digits 3.1415", "digits3", "digits 1", "digits 3 all", "digits foo", "digits all", "digits 3.0" ] } }; for (var prop in verticalTextProperties) { gCSSProperties[prop] = verticalTextProperties[prop]; } }
--- a/layout/svg/nsSVGContainerFrame.cpp +++ b/layout/svg/nsSVGContainerFrame.cpp @@ -8,16 +8,17 @@ // Keep others in (case-insensitive) order: #include "nsCSSFrameConstructor.h" #include "nsSVGEffects.h" #include "nsSVGElement.h" #include "nsSVGUtils.h" #include "nsSVGAnimatedTransformList.h" #include "nsSVGTextFrame2.h" +#include "RestyleManager.h" using namespace mozilla; NS_QUERYFRAME_HEAD(nsSVGContainerFrame) NS_QUERYFRAME_ENTRY(nsSVGContainerFrame) NS_QUERYFRAME_TAIL_INHERITING(nsSVGContainerFrameBase) NS_QUERYFRAME_HEAD(nsSVGDisplayContainerFrame)
--- a/layout/svg/nsSVGEffects.cpp +++ b/layout/svg/nsSVGEffects.cpp @@ -11,16 +11,17 @@ #include "nsISupportsImpl.h" #include "nsSVGClipPathFrame.h" #include "nsSVGPaintServerFrame.h" #include "nsSVGPathGeometryElement.h" #include "nsSVGFilterFrame.h" #include "nsSVGMaskFrame.h" #include "nsSVGTextPathFrame.h" #include "nsIReflowCallback.h" +#include "RestyleManager.h" using namespace mozilla; using namespace mozilla::dom; // nsSVGRenderingObserver impl NS_IMPL_ISUPPORTS1(nsSVGRenderingObserver, nsIMutationObserver) void
--- a/layout/xul/base/src/nsBoxFrame.cpp +++ b/layout/xul/base/src/nsBoxFrame.cpp @@ -56,16 +56,17 @@ #include "nsIDOMElement.h" #include "nsITheme.h" #include "nsTransform2D.h" #include "nsEventStateManager.h" #include "nsEventDispatcher.h" #include "nsIDOMEvent.h" #include "nsDisplayList.h" #include "mozilla/Preferences.h" +#include "nsThemeConstants.h" #include <algorithm> // Needed for Print Preview #include "nsIURI.h" using namespace mozilla; using namespace mozilla::dom;
--- a/layout/xul/base/src/nsMenuFrame.cpp +++ b/layout/xul/base/src/nsMenuFrame.cpp @@ -37,16 +37,17 @@ #include "nsISound.h" #include "nsEventStateManager.h" #include "nsIDOMXULMenuListElement.h" #include "mozilla/Attributes.h" #include "mozilla/Likely.h" #include "mozilla/LookAndFeel.h" #include "mozilla/Preferences.h" #include "mozilla/Services.h" +#include "mozilla/dom/Element.h" #include <algorithm> using namespace mozilla; #define NS_MENU_POPUP_LIST_INDEX 0 #if defined(XP_WIN) || defined(XP_OS2) #define NSCONTEXTMENUISMOUSEUP 1
--- a/layout/xul/base/src/nsMenuPopupFrame.cpp +++ b/layout/xul/base/src/nsMenuPopupFrame.cpp @@ -44,16 +44,17 @@ #include "nsIBaseWindow.h" #include "nsISound.h" #include "nsIScreenManager.h" #include "nsIServiceManager.h" #include "nsThemeConstants.h" #include "nsDisplayList.h" #include "mozilla/Preferences.h" #include "mozilla/LookAndFeel.h" +#include "mozilla/dom/Element.h" #include <algorithm> using namespace mozilla; int8_t nsMenuPopupFrame::sDefaultLevelIsTop = -1; // NS_NewMenuPopupFrame //
--- a/media/libvpx/Makefile.in +++ b/media/libvpx/Makefile.in @@ -425,26 +425,37 @@ else # We can extract the asm offsets directly from generated assembly using inline # asm. This is the preferred method. asm_com_offsets.s: CFLAGS += -DINLINE_ASM OFFSET_PATTERN := '^[a-zA-Z0-9_]* EQU' +# This rule, as well as the rule for asm_enc_offsets.s further below are here +# because the generic rule in rules.mk was made to not be implicit, and we +# can't put the C files in CSRCS. +asm_com_offsets.s: asm_com_offsets.c + $(REPORT_BUILD) + $(CC) -S $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) + asm_com_offsets.asm: asm_com_offsets.s grep $(OFFSET_PATTERN) $< | sed -e 's/[$$\#]//g' \ $(if $(VPX_AS_CONVERSION),| $(VPX_AS_CONVERSION)) > $@ GARBAGE += asm_com_offsets.s asm_com_offsets.asm ifdef MOZ_VP8_ENCODER asm_enc_offsets.s: CFLAGS += -DINLINE_ASM +asm_enc_offsets.s: asm_enc_offsets.c + $(REPORT_BUILD) + $(CC) -S $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) + asm_enc_offsets.asm: asm_enc_offsets.s grep $(OFFSET_PATTERN) $< | sed -e 's/[$$\#]//g' \ $(if $(VPX_AS_CONVERSION),| $(VPX_AS_CONVERSION)) > $@ GARBAGE += asm_enc_offsets.s asm_enc_offsets.asm endif
--- a/mobile/android/base/PageActionLayout.java +++ b/mobile/android/base/PageActionLayout.java @@ -26,39 +26,39 @@ import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.widget.Button; import android.widget.ImageButton; import android.widget.ImageView; import android.widget.LinearLayout; import java.util.UUID; -import java.util.LinkedHashMap; +import java.util.ArrayList; public class PageActionLayout extends LinearLayout implements GeckoEventListener, View.OnClickListener, View.OnLongClickListener { private final String LOGTAG = "GeckoPageActionLayout"; private final String MENU_BUTTON_KEY = "MENU_BUTTON_KEY"; private final int DEFAULT_PAGE_ACTIONS_SHOWN = 2; - private LinkedHashMap<String, PageAction> mPageActionList; + private ArrayList<PageAction> mPageActionList; private GeckoPopupMenu mPageActionsMenu; private Context mContext; private LinearLayout mLayout; // By default it's two, can be changed by calling setNumberShown(int) private int mMaxVisiblePageActions; public PageActionLayout(Context context, AttributeSet attrs) { super(context, attrs); mContext = context; mLayout = this; - mPageActionList = new LinkedHashMap<String, PageAction>(); + mPageActionList = new ArrayList<PageAction>(); setNumberShown(DEFAULT_PAGE_ACTIONS_SHOWN); refreshPageActionIcons(); registerEventListener("PageActions:Add"); registerEventListener("PageActions:Remove"); } public void setNumberShown(int count) { @@ -86,57 +86,68 @@ public class PageActionLayout extends Li @Override public void handleMessage(String event, JSONObject message) { try { if (event.equals("PageActions:Add")) { final String id = message.getString("id"); final String title = message.getString("title"); final String imageURL = message.optString("icon"); + final boolean mImportant = message.getBoolean("important"); addPageAction(id, title, imageURL, new OnPageActionClickListeners() { @Override public void onClick(String id) { GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("PageActions:Clicked", id)); } @Override public boolean onLongClick(String id) { GeckoAppShell.sendEventToGecko(GeckoEvent.createBroadcastEvent("PageActions:LongClicked", id)); return true; } - }); + }, mImportant); } else if (event.equals("PageActions:Remove")) { final String id = message.getString("id"); removePageAction(id); } } catch(JSONException ex) { Log.e(LOGTAG, "Error deocding", ex); } } - public void addPageAction(final String id, final String title, final String imageData, final OnPageActionClickListeners mOnPageActionClickListeners) { - final PageAction pageAction = new PageAction(id, title, null, mOnPageActionClickListeners); - mPageActionList.put(id, pageAction); + public void addPageAction(final String id, final String title, final String imageData, final OnPageActionClickListeners mOnPageActionClickListeners, boolean mImportant) { + final PageAction pageAction = new PageAction(id, title, null, mOnPageActionClickListeners, mImportant); + + int insertAt = mPageActionList.size(); + while(insertAt > 0 && mPageActionList.get(insertAt-1).isImportant()) { + insertAt--; + } + mPageActionList.add(insertAt, pageAction); BitmapUtils.getDrawable(mContext, imageData, new BitmapUtils.BitmapLoader() { @Override public void onBitmapFound(final Drawable d) { - if (mPageActionList.containsKey(id)) { + if (mPageActionList.contains(pageAction)) { pageAction.setDrawable(d); refreshPageActionIcons(); } } }); } public void removePageAction(String id) { - mPageActionList.remove(id); - refreshPageActionIcons(); + for(int i = 0; i < mPageActionList.size(); i++) { + if (mPageActionList.get(i).getID().equals(id)) { + mPageActionList.remove(i); + refreshPageActionIcons(); + return; + } + } } private ImageButton createImageButton() { ImageButton imageButton = new ImageButton(mContext, null, R.style.UrlBar_ImageButton_Icon); imageButton.setLayoutParams(new LayoutParams(mContext.getResources().getDimensionPixelSize(R.dimen.page_action_button_width), LayoutParams.MATCH_PARENT)); imageButton.setScaleType(ImageView.ScaleType.CENTER_INSIDE); imageButton.setOnClickListener(this); imageButton.setOnLongClickListener(this); @@ -145,29 +156,29 @@ public class PageActionLayout extends Li @Override public void onClick(View v) { String buttonClickedId = (String)v.getTag(); if (buttonClickedId != null) { if (buttonClickedId.equals(MENU_BUTTON_KEY)) { showMenu(v, mPageActionList.size() - mMaxVisiblePageActions + 1); } else { - mPageActionList.get(buttonClickedId).onClick(); + getPageActionWithId(buttonClickedId).onClick(); } } } @Override public boolean onLongClick(View v) { String buttonClickedId = (String)v.getTag(); if (buttonClickedId.equals(MENU_BUTTON_KEY)) { showMenu(v, mPageActionList.size() - mMaxVisiblePageActions + 1); return true; } else { - return mPageActionList.get(buttonClickedId).onLongClick(); + return getPageActionWithId(buttonClickedId).onLongClick(); } } private void setActionForView(final ImageButton view, final PageAction pageAction) { if (pageAction == null) { view.setTag(null); ThreadUtils.postToUiThread(new Runnable() { @Override @@ -225,79 +236,86 @@ public class PageActionLayout extends Li * and hence we maintain the insertion order of the child Views which is essentially the reverse of their index */ int buttonIndex = (this.getChildCount() - 1) - index; int totalVisibleButtons = ((mPageActionList.size() < this.getChildCount()) ? mPageActionList.size() : this.getChildCount()); if (mPageActionList.size() > buttonIndex) { // Return the pageactions starting from the end of the list for the number of visible pageactions. - return getPageActionAt((mPageActionList.size() - totalVisibleButtons) + buttonIndex); + return mPageActionList.get((mPageActionList.size() - totalVisibleButtons) + buttonIndex); } return null; } - private PageAction getPageActionAt(int index) { - int count = 0; - for(PageAction pageAction : mPageActionList.values()) { - if (count == index) { + private PageAction getPageActionWithId(String id) { + for(int i = 0; i < mPageActionList.size(); i++) { + PageAction pageAction = mPageActionList.get(i); + if (pageAction.getID().equals(id)) { return pageAction; } - count++; } return null; } private void showMenu(View mPageActionButton, int toShow) { if (mPageActionsMenu == null) { mPageActionsMenu = new GeckoPopupMenu(mPageActionButton.getContext(), mPageActionButton); mPageActionsMenu.inflate(0); mPageActionsMenu.setOnMenuItemClickListener(new GeckoPopupMenu.OnMenuItemClickListener() { @Override public boolean onMenuItemClick(MenuItem item) { - for(PageAction pageAction : mPageActionList.values()) { - if (pageAction.key() == item.getItemId()) { + int id = item.getItemId(); + for(int i = 0; i < mPageActionList.size(); i++) { + PageAction pageAction = mPageActionList.get(i); + if (pageAction.key() == id) { pageAction.onClick(); + return true; } } - return true; + return false; } }); } Menu menu = mPageActionsMenu.getMenu(); menu.clear(); - int count = 0; - for(PageAction pageAction : mPageActionList.values()) { - if (count < toShow) { + for(int i = 0; i < mPageActionList.size(); i++) { + if (i < toShow) { + PageAction pageAction = mPageActionList.get(i); MenuItem item = menu.add(Menu.NONE, pageAction.key(), Menu.NONE, pageAction.getTitle()); item.setIcon(pageAction.getDrawable()); } - count++; } mPageActionsMenu.show(); } public static interface OnPageActionClickListeners { public void onClick(String id); public boolean onLongClick(String id); } private static class PageAction { private OnPageActionClickListeners mOnPageActionClickListeners; private Drawable mDrawable; private String mTitle; private String mId; private int key; + private boolean mImportant; - public PageAction(String id, String title, Drawable image, OnPageActionClickListeners mOnPageActionClickListeners) { + public PageAction(String id, + String title, + Drawable image, + OnPageActionClickListeners mOnPageActionClickListeners, + boolean mImportant) { this.mId = id; this.mTitle = title; this.mDrawable = image; this.mOnPageActionClickListeners = mOnPageActionClickListeners; + this.mImportant = mImportant; this.key = UUID.fromString(mId.subSequence(1, mId.length() - 2).toString()).hashCode(); } public Drawable getDrawable() { return mDrawable; } @@ -312,16 +330,20 @@ public class PageActionLayout extends Li public String getID() { return mId; } public int key() { return key; } + public boolean isImportant() { + return mImportant; + } + public void onClick() { if (mOnPageActionClickListeners != null) { mOnPageActionClickListeners.onClick(mId); } } public boolean onLongClick() { if (mOnPageActionClickListeners != null) {
--- a/mobile/android/chrome/content/SelectionHandler.js +++ b/mobile/android/chrome/content/SelectionHandler.js @@ -69,23 +69,27 @@ var SelectionHandler = { switch (aTopic) { case "Gesture:SingleTap": { if (this._activeType == this.TYPE_SELECTION) { let data = JSON.parse(aData); if (this._pointInSelection(data.x, data.y)) this.copySelection(); else this._closeSelection(); + } else if (this._activeType == this.TYPE_CURSOR) { + // attachCaret() is called in the "Gesture:SingleTap" handler in BrowserEventHandler + // We're guaranteed to call this first, because this observer was added last + this._closeSelection(); } break; } case "Tab:Selected": this._closeSelection(); break; - + case "Window:Resize": { if (this._activeType == this.TYPE_SELECTION) { // Knowing when the page is done drawing is hard, so let's just cancel // the selection when the window changes. We should fix this later. this._closeSelection(); } break; }
--- a/mobile/android/chrome/content/browser.js +++ b/mobile/android/chrome/content/browser.js @@ -1622,17 +1622,18 @@ var NativeWindow = { pageactions: { _items: { }, add: function(aOptions) { let id = uuidgen.generateUUID().toString(); sendMessageToJava({ type: "PageActions:Add", id: id, title: aOptions.title, - icon: resolveGeckoURI(aOptions.icon) + icon: resolveGeckoURI(aOptions.icon), + important: "important" in aOptions ? aOptions.important : false }); this._items[id] = { clickCallback: aOptions.clickCallback, longClickCallback: aOptions.longClickCallback }; return id; }, remove: function(id) { @@ -7153,24 +7154,26 @@ let Reader = { NativeWindow.pageactions.remove(this.pageAction.id); delete this.pageAction.id; } if (tab.readerActive) { this.pageAction.id = NativeWindow.pageactions.add({ title: Strings.browser.GetStringFromName("readerMode.exit"), icon: "drawable://reader_active", - clickCallback: this.pageAction.readerModeCallback + clickCallback: this.pageAction.readerModeCallback, + important: true }); } else if (tab.readerEnabled) { this.pageAction.id = NativeWindow.pageactions.add({ title: Strings.browser.GetStringFromName("readerMode.enter"), icon: "drawable://reader", clickCallback:this.pageAction.readerModeCallback, - longClickCallback: this.pageAction.readerModeActiveCallback + longClickCallback: this.pageAction.readerModeActiveCallback, + important: true }); } }, observe: function(aMessage, aTopic, aData) { switch(aTopic) { case "Reader:Add": { let args = JSON.parse(aData);
--- a/modules/libjar/nsJAR.cpp +++ b/modules/libjar/nsJAR.cpp @@ -218,21 +218,16 @@ nsJAR::Extract(const nsACString &aEntryN nsZipItem *item = mZip->GetItem(PromiseFlatCString(aEntryName).get()); NS_ENSURE_TRUE(item, NS_ERROR_FILE_TARGET_DOES_NOT_EXIST); // Remove existing file or directory so we set permissions correctly. // If it's a directory that already exists and contains files, throw // an exception and return. - //XXX Bug 332139: - //XXX If we guarantee that rv in the case of a non-empty directory - //XXX is always FILE_DIR_NOT_EMPTY, we can remove - //XXX |rv == NS_ERROR_FAILURE| - bug 322183 needs to be completely - //XXX fixed before that can happen nsresult rv = outFile->Remove(false); if (rv == NS_ERROR_FILE_DIR_NOT_EMPTY || rv == NS_ERROR_FAILURE) return rv; if (item->IsDirectory()) { rv = outFile->Create(nsIFile::DIRECTORY_TYPE, item->Mode());
--- a/python/mozbuild/mozbuild/controller/building.py +++ b/python/mozbuild/mozbuild/controller/building.py @@ -4,68 +4,196 @@ from __future__ import unicode_literals import getpass import os import sys import time -from collections import namedtuple +from collections import ( + namedtuple, + OrderedDict, +) # keep in sync with psutil os support, see psutil/__init__.py if sys.platform.startswith("freebsd") or sys.platform.startswith("darwin") or sys.platform.startswith("win32") or sys.platform.startswith("linux"): try: import psutil except ImportError: psutil = None else: psutil = None +from ..base import MozbuildObject + from ..compilation.warnings import ( WarningsCollector, WarningsDatabase, ) BuildOutputResult = namedtuple('BuildOutputResult', ('warning', 'state_changed', 'for_display')) -class BuildMonitor(object): +class TierStatus(object): + """Represents the state and progress of tier traversal. + + The build system is organized into linear phases called tiers. Each tier + executes in the order it was defined, 1 at a time. + + Tiers can have subtiers. Subtiers can execute in any order. Some subtiers + execute sequentially. Others are concurrent. + + Subtiers can have directories. Directories can execute in any order, just + like subtiers. + """ + + def __init__(self): + self.tiers = OrderedDict() + self.active_tier = None + self.active_subtiers = set() + + def set_tiers(self, tiers): + """Record the set of known tiers.""" + for tier in tiers: + self.tiers[tier] = dict( + begin_time=None, + finish_time=None, + duration=None, + subtiers=OrderedDict(), + ) + + def begin_tier(self, tier, subtiers): + """Record that execution of a tier has begun.""" + t = self.tiers[tier] + # We should ideally use a monotonic clock here. Unfortunately, we won't + # have one until Python 3. + t['begin_time'] = time.time() + for subtier in subtiers: + t['subtiers'][subtier] = dict( + begin_time=None, + finish_time=None, + duration=None, + concurrent=False, + dirs=OrderedDict(), + dirs_complete=0, + ) + + self.active_tier = tier + self.active_subtiers = set() + self.active_dirs = {} + + def finish_tier(self, tier): + """Record that execution of a tier has finished.""" + t = self.tiers[tier] + t['finish_time'] = time.time() + t['duration'] = t['finish_time'] - t['begin_time'] + + def begin_subtier(self, tier, subtier, dirs): + """Record that execution of a subtier has begun.""" + st = self.tiers[tier]['subtiers'][subtier] + st['begin_time'] = time.time() + + for d in dirs: + st['dirs'][d] = dict( + begin_time=None, + finish_time=None, + duration=None, + concurrent=False, + ) + + if self.active_subtiers: + st['concurrent'] = True + + self.active_subtiers.add(subtier) + + def finish_subtier(self, tier, subtier): + """Record that execution of a subtier has finished.""" + st = self.tiers[tier]['subtiers'][subtier] + st['finish_time'] = time.time() + + self.active_subtiers.remove(subtier) + if self.active_subtiers: + st['concurrent'] = True + + # A subtier may not have directories. + try: + del self.active_dirs[subtier] + except KeyError: + pass + + st['duration'] = st['finish_time'] - st['begin_time'] + + def begin_dir(self, tier, subtier, d): + """Record that execution of a directory has begun.""" + entry = self.tiers[tier]['subtiers'][subtier]['dirs'][d] + entry['begin_time'] = time.time() + + self.active_dirs.setdefault(subtier, set()).add(d) + + if len(self.active_dirs[subtier]) > 1: + entry['concurrent'] = True + + def finish_dir(self, tier, subtier, d): + """Record that execution of a directory has finished.""" + st = self.tiers[tier]['subtiers'][subtier] + st['dirs_complete'] += 1 + + entry = st['dirs'][d] + entry['finish_time'] = time.time() + + self.active_dirs[subtier].remove(d) + entry['duration'] = entry['finish_time'] - entry['begin_time'] + + if self.active_dirs[subtier]: + entry['concurrent'] = True + + def tier_status(self): + for tier, state in self.tiers.items(): + active = self.active_tier == tier + finished = state['finish_time'] is not None + + yield tier, active, finished + + def current_subtier_status(self): + for subtier, state in self.tiers[self.active_tier]['subtiers'].items(): + active = subtier in self.active_subtiers + finished = state['finish_time'] is not None + + yield subtier, active, finished + + def current_dirs_status(self): + for subtier, dirs in self.active_dirs.items(): + st = self.tiers[self.active_tier]['subtiers'][subtier] + yield subtier, st['dirs'].keys(), dirs, st['dirs_complete'] + + +class BuildMonitor(MozbuildObject): """Monitors the output of the build.""" - def __init__(self, topobjdir, warnings_path): + def init(self, warnings_path): """Create a new monitor. warnings_path is a path of a warnings database to use. """ self._warnings_path = warnings_path - self.tiers = [] - self.subtiers = [] - self.current_tier = None - self.current_subtier = None - self.current_tier_dirs = [] - self.current_tier_static_dirs = [] - self.current_subtier_dirs = [] - self.current_subtier_started = set() - self.current_subtier_finished = set() - self.current_tier_dir = None - self.current_tier_dir_index = 0 + self.tiers = TierStatus() self.warnings_database = WarningsDatabase() if os.path.exists(warnings_path): try: self.warnings_database.load_from_file(warnings_path) except ValueError: os.remove(warnings_path) self._warnings_collector = WarningsCollector( - database=self.warnings_database, objdir=topobjdir) + database=self.warnings_database, objdir=self.topobjdir) def start(self): """Record the start of the build.""" self.start_time = time.time() self._finder_start_cpu = self._get_finder_cpu_usage() def on_line(self, line): """Consume a line of output from the build system. @@ -88,61 +216,38 @@ class BuildMonitor(object): """ if line.startswith('BUILDSTATUS'): args = line.split()[1:] action = args.pop(0) update_needed = True if action == 'TIERS': - self.tiers = args - update_needed = False - elif action == 'SUBTIERS': - self.subtiers = args - update_needed = False - elif action == 'STATICDIRS': - self.current_tier_static_dirs = args - update_needed = False - elif action == 'DIRS': - self.current_tier_dirs = args + self.tiers.set_tiers(args) update_needed = False elif action == 'TIER_START': - assert len(args) == 1 - self.current_tier = args[0] - self.current_subtier = None - self.current_tier_dirs = [] - self.current_subtier_started = set() - self.current_subtier_finished = set() - self.current_tier_dir = None + tier = args[0] + subtiers = args[1:] + self.tiers.begin_tier(tier, subtiers) elif action == 'TIER_FINISH': - assert len(args) == 1 - assert args[0] == self.current_tier + tier, = args + self.tiers.finish_tier(tier) elif action == 'SUBTIER_START': - assert len(args) == 2 + tier, subtier = args[0:2] + dirs = args[2:] + self.tiers.begin_subtier(tier, subtier, dirs) + elif action == 'SUBTIER_FINISH': tier, subtier = args - assert tier == self.current_tier - self.current_subtier = subtier - if subtier == 'static': - self.current_subtier_dirs = self.current_tier_static_dirs - else: - self.current_subtier_dirs = self.current_tier_dirs - self.current_tier_dir_index = 0 - self.current_subtier_started.add(subtier) - elif action == 'SUBTIER_FINISH': - assert len(args) == 2 - tier, subtier = args - assert tier == self.current_tier - self.current_subtier_finished.add(subtier) + self.tiers.finish_subtier(tier, subtier) elif action == 'TIERDIR_START': - assert len(args) == 1 - self.current_tier_dir = args[0] - self.current_tier_dir_index += 1 + tier, subtier, d = args + self.tiers.begin_dir(tier, subtier, d) elif action == 'TIERDIR_FINISH': - assert len(args) == 1 - assert self.current_tier_dir == args[0] + tier, subtier, d = args + self.tiers.finish_dir(tier, subtier, d) else: raise Exception('Unknown build status: %s' % action) return BuildOutputResult(None, update_needed, False) warning = None try:
--- a/python/mozbuild/mozbuild/mach_commands.py +++ b/python/mozbuild/mozbuild/mach_commands.py @@ -99,64 +99,80 @@ class BuildProgressFooter(object): def __init__(self, terminal, monitor): # terminal is a blessings.Terminal. self._t = terminal self._fh = sys.stdout self._monitor = monitor def _clear_lines(self, n): - self._fh.write(self._t.move(self._t.height - n, 0)) + self._fh.write(self._t.move_x(0)) self._fh.write(self._t.clear_eos()) def clear(self): """Removes the footer from the current terminal.""" self._clear_lines(1) def draw(self): """Draws this footer in the terminal.""" - if not self._monitor.tiers: + tiers = self._monitor.tiers + + if not tiers.tiers: return # The drawn terminal looks something like: # TIER: base nspr nss js platform app SUBTIER: static export libs tools DIRECTORIES: 06/09 (memory) # This is a list of 2-tuples of (encoding function, input). None means # no encoding. For a full reason on why we do things this way, read the # big comment below. parts = [('bold', 'TIER'), ':', ' '] - current_encountered = False - for tier in self._monitor.tiers: - if tier == self._monitor.current_tier: + for tier, active, finished in tiers.tier_status(): + if active: parts.extend([('underline_yellow', tier), ' ']) - current_encountered = True - elif not current_encountered: + elif finished: parts.extend([('green', tier), ' ']) else: parts.extend([tier, ' ']) parts.extend([('bold', 'SUBTIER'), ':', ' ']) - for subtier in self._monitor.subtiers: - if subtier in self._monitor.current_subtier_finished: + for subtier, active, finished in tiers.current_subtier_status(): + if active: + parts.extend([('underline_yellow', subtier), ' ']) + elif finished: parts.extend([('green', subtier), ' ']) - elif subtier in self._monitor.current_subtier_started: - parts.extend([('underline_yellow', subtier), ' ']) else: parts.extend([subtier, ' ']) - if self._monitor.current_subtier_dirs and self._monitor.current_tier_dir: - parts.extend([ - ('bold', 'DIRECTORIES'), ': ', - '%02d' % self._monitor.current_tier_dir_index, - '/', - '%02d' % len(self._monitor.current_subtier_dirs), - ' ', - '(', ('magenta', self._monitor.current_tier_dir), ')', - ]) + if tiers.active_dirs: + parts.extend([('bold', 'DIRECTORIES'), ': ']) + have_dirs = False + + for subtier, all_dirs, active_dirs, complete in tiers.current_dirs_status(): + if len(all_dirs) < 2: + continue + + have_dirs = True + + parts.extend([ + '%02d' % (complete + 1), + '/', + '%02d' % len(all_dirs), + ' ', + '(', + ]) + for d in active_dirs: + parts.extend([ + ('magenta', d), ' ,' + ]) + parts[-1] = ')' + + if not have_dirs: + parts = parts[0:-2] # We don't want to write more characters than the current width of the # terminal otherwise wrapping may result in weird behavior. We can't # simply truncate the line at terminal width characters because a) # non-viewable escape characters count towards the limit and b) we # don't want to truncate in the middle of an escape sequence because # subsequent output would inherit the escape sequence. max_width = self._t.width @@ -178,18 +194,19 @@ class BuildProgressFooter(object): else: if written + len(part) > max_width: write_pieces.append(part[0:max_width - written]) written += len(part) break write_pieces.append(part) written += len(part) - - self._fh.write(''.join(write_pieces)) + with self._t.location(): + self._t.move(self._t.height-1,0) + self._fh.write(''.join(write_pieces)) self._fh.flush() class BuildOutputManager(LoggingMixin): """Handles writing build output to a terminal, to logs, etc.""" def __init__(self, log_manager, monitor): self.populate_logger() @@ -269,17 +286,18 @@ class Build(MachCommandBase): help='Do not add extra make dependencies.') @CommandArgument('-v', '--verbose', action='store_true', help='Verbose output for what commands the build is running.') def build(self, what=None, disable_extra_make_dependencies=None, jobs=0, verbose=False): from mozbuild.controller.building import BuildMonitor from mozbuild.util import resolve_target_to_make warnings_path = self._get_state_filename('warnings.json') - monitor = BuildMonitor(self.topobjdir, warnings_path) + monitor = self._spawn(BuildMonitor) + monitor.init(warnings_path) with BuildOutputManager(self.log_manager, monitor) as output: monitor.start() if what: top_make = os.path.join(self.topobjdir, 'Makefile') if not os.path.exists(top_make): print('Your tree has not been configured yet. Please run '
--- a/security/manager/pki/resources/content/createCertInfo.xul +++ b/security/manager/pki/resources/content/createCertInfo.xul @@ -4,27 +4,27 @@ - file, You can obtain one at http://mozilla.org/MPL/2.0/. --> <?xml-stylesheet href="chrome://global/skin/" type="text/css"?> <!DOCTYPE window SYSTEM "chrome://pippki/locale/pippki.dtd"> <window id="domainMismatch" title="&createCertInfo.title;" - xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" + xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" onload="onLoad();" onclose="onClose();" > <stringbundle id="pippki_bundle" src="chrome://pippki/locale/pippki.properties"/> <script type="application/javascript" src="pippki.js" /> <script type="application/javascript" src="createCertInfo.js" /> <vbox style="margin: 5px; max-width: 50em;"> <description>&createCertInfo.msg1;</description> <separator/> - <description style="font-weight: bold; text-align: center; text-decoration: blink;">&createCertInfo.msg2;</description> + <description style="font-weight: bold; text-align: center;">&createCertInfo.msg2;</description> <separator/> </vbox> </window>
--- a/services/common/tests/unit/test_storage_server.js +++ b/services/common/tests/unit/test_storage_server.js @@ -341,17 +341,17 @@ add_test(function test_bso_if_unmodified server.createContents("123", { test: {bso: {foo: "bar"}} }); server.startSynchronous(); let coll = server.user("123").collection("test"); do_check_neq(coll, null); - let time = coll.timestamp; + let time = coll.bso("bso").modified; _("Ensure we get a 412 for specified times older than server time."); let request = localRequest(server, "/2.0/123/storage/test/bso", "123", "password"); request.setHeader("X-If-Unmodified-Since", time - 5000); request.setHeader("Content-Type", "application/json"); let payload = JSON.stringify({"payload": "foobar"}); let error = doPutRequest(request, payload);
--- a/testing/marionette/atoms/atoms.js +++ b/testing/marionette/atoms/atoms.js @@ -122,58 +122,59 @@ 0:parseInt(B[1],10))?1:0)||((0==A[2].len //isElementSelected var isElementSelected = function(){return function(){var f=!1,g=this;function h(a,b){function c(){}c.prototype=b.prototype;a.d=b.prototype;a.prototype=new c};function i(a,b){for(var c=1;c<arguments.length;c++)var d=(""+arguments[c]).replace(/\$/g,"$$$$"),a=a.replace(/\%s/,d);return a};var k,l="",m=/rv\:([^\);]+)(\)|;)/.exec(g.navigator?g.navigator.userAgent:null);k=l=m?m[1]:"";var n={};function o(a,b){this.code=a;this.message=b||"";this.name=p[a]||p[13];var c=Error(this.message);c.name=this.name;this.stack=c.stack||""}h(o,Error); var p={7:"NoSuchElementError",8:"NoSuchFrameError",9:"UnknownCommandError",10:"StaleElementReferenceError",11:"ElementNotVisibleError",12:"InvalidElementStateError",13:"UnknownError",15:"ElementNotSelectableError",19:"XPathLookupError",23:"NoSuchWindowError",24:"InvalidCookieDomainError",25:"UnableToSetCookieError",26:"ModalDialogOpenedError",27:"NoModalDialogOpenError",28:"ScriptTimeoutError",32:"InvalidSelectorError",33:"SqlDatabaseError",34:"MoveTargetOutOfBoundsError"}; o.prototype.toString=function(){return"["+this.name+"] "+this.message};function q(a){this.stack=Error().stack||"";a&&(this.message=""+a)}h(q,Error);q.prototype.name="CustomError";function r(a,b){b.unshift(a);q.call(this,i.apply(null,b));b.shift()}h(r,q);r.prototype.name="AssertionError";if(!n["1.9.1"]){for(var s=0,t=(""+k).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),u="1.9.1".replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split("."),v=Math.max(t.length,u.length),w=0;0==s&&w<v;w++){var x=t[w]||"",y=u[w]||"",z=RegExp("(\\d*)(\\D*)","g"),A=RegExp("(\\d*)(\\D*)","g");do{var B=z.exec(x)||["","",""],C=A.exec(y)||["","",""];if(0==B[0].length&&0==C[0].length)break;s=((0==B[1].length?0:parseInt(B[1],10))<(0==C[1].length?0:parseInt(C[1],10))?-1:(0==B[1].length?0:parseInt(B[1],10))>(0==C[1].length? 0:parseInt(C[1],10))?1:0)||((0==B[2].length)<(0==C[2].length)?-1:(0==B[2].length)>(0==C[2].length)?1:0)||(B[2]<C[2]?-1:B[2]>C[2]?1:0)}while(0==s)}n["1.9.1"]=0<=s};var D={SCRIPT:1,STYLE:1,HEAD:1,IFRAME:1,OBJECT:1},E={IMG:" ",BR:"\n"};function F(a,b,c){if(!(a.nodeName in D))if(3==a.nodeType)c?b.push((""+a.nodeValue).replace(/(\r\n|\r|\n)/g,"")):b.push(a.nodeValue);else if(a.nodeName in E)b.push(E[a.nodeName]);else for(a=a.firstChild;a;)F(a,b,c),a=a.nextSibling};(function(){var a=g.Components;if(!a)return f;try{if(!a.classes)return f}catch(b){return f}var c=a.classes,a=a.interfaces;c["@mozilla.org/xpcom/version-comparator;1"].getService(a.nsIVersionComparator);c["@mozilla.org/xre/app-info;1"].getService(a.nsIXULAppInfo);return!0})();function G(a,b,c,d,e){this.b=!!b;if(a&&(this.a=a))this.c="number"==typeof d?d:1!=this.a.nodeType?0:this.b?-1:1;this.depth=void 0!=e?e:this.c||0;this.b&&(this.depth*=-1)}h(G,function(){});G.prototype.a=null;G.prototype.c=0;h(function(a,b,c,d){G.call(this,a,b,0,null,d)},G);function H(a,b){return!!a&&1==a.nodeType&&(!b||a.tagName.toUpperCase()==b)}function I(a){return H(a,"OPTION")?!0:H(a,"INPUT")?(a=a.type.toLowerCase(),"checkbox"==a||"radio"==a):f}var J={"class":"className",readonly:"readOnly"},K=["checked","disabled","draggable","hidden"];function L(a){if(I(a)){if(!I(a))throw new o(15,"Element is not selectable");var b="selected",c=a.type&&a.type.toLowerCase();if("checkbox"==c||"radio"==c)b="checked";var c=b,d=J[c]||c,b=a[d],e;if(e=void 0===b){b:if("string"==typeof K)d="string"!=typeof d||1!=d.length?-1:K.indexOf(d,0);else{for(e=0;e<K.length;e++)if(e in K&&K[e]===d){d=e;break b}d=-1}e=0<=d}if(e)a=f;else{if(d="value"==c)if(d=H(a,"OPTION")){var j;c=c.toLowerCase();if(a.hasAttribute)j=a.hasAttribute(c);else try{j=a.attributes[c].specified}catch(P){j= f}d=!j}d&&(j=[],F(a,j,f),b=j.join(""));a=b}a=!!a}else a=f;return a}var M=["_"],N=g;!(M[0]in N)&&N.execScript&&N.execScript("var "+M[0]);for(var O;M.length&&(O=M.shift());)!M.length&&void 0!==L?N[O]=L:N=N[O]?N[O]:N[O]={};; return this._.apply(null,arguments);}.apply({navigator:typeof window!='undefined'?window.navigator:null}, arguments);} // isElementDisplayed -var isElementDisplayed = function(){return function(){function g(a){return function(){return a}}var h=this; +var isElementDisplayed = function(){return function(){function h(a){return function(){return a}}var k=this; function m(a){var b=typeof a;if("object"==b)if(a){if(a instanceof Array)return"array";if(a instanceof Object)return b;var c=Object.prototype.toString.call(a);if("[object Window]"==c)return"object";if("[object Array]"==c||"number"==typeof a.length&&"undefined"!=typeof a.splice&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("splice"))return"array";if("[object Function]"==c||"undefined"!=typeof a.call&&"undefined"!=typeof a.propertyIsEnumerable&&!a.propertyIsEnumerable("call"))return"function"}else return"null"; -else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function n(a){return"string"==typeof a};function q(a){var b=0,c=String(r).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split(".");a=String(a).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split(".");for(var d=Math.max(c.length,a.length),e=0;0==b&&e<d;e++){var f=c[e]||"",k=a[e]||"",w=RegExp("(\\d*)(\\D*)","g"),p=RegExp("(\\d*)(\\D*)","g");do{var l=w.exec(f)||["","",""],v=p.exec(k)||["","",""];if(0==l[0].length&&0==v[0].length)break;b=((0==l[1].length?0:parseInt(l[1],10))<(0==v[1].length?0:parseInt(v[1],10))?-1:(0==l[1].length?0:parseInt(l[1],10))>(0==v[1].length? +else if("function"==b&&"undefined"==typeof a.call)return"object";return b}function n(a){return"string"==typeof a};function q(a){var b=0,c=String(r).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split(".");a=String(a).replace(/^[\s\xa0]+|[\s\xa0]+$/g,"").split(".");for(var d=Math.max(c.length,a.length),e=0;0==b&&e<d;e++){var f=c[e]||"",g=a[e]||"",w=RegExp("(\\d*)(\\D*)","g"),p=RegExp("(\\d*)(\\D*)","g");do{var l=w.exec(f)||["","",""],v=p.exec(g)||["","",""];if(0==l[0].length&&0==v[0].length)break;b=((0==l[1].length?0:parseInt(l[1],10))<(0==v[1].length?0:parseInt(v[1],10))?-1:(0==l[1].length?0:parseInt(l[1],10))>(0==v[1].length? 0:parseInt(v[1],10))?1:0)||((0==l[2].length)<(0==v[2].length)?-1:(0==l[2].length)>(0==v[2].length)?1:0)||(l[2]<v[2]?-1:l[2]>v[2]?1:0)}while(0==b)}return b}function aa(a){return String(a).replace(/\-([a-z])/g,function(a,c){return c.toUpperCase()})};var s=Array.prototype;function t(a,b){for(var c=a.length,d=n(a)?a.split(""):a,e=0;e<c;e++)e in d&&b.call(void 0,d[e],e,a)}function ba(a,b){if(a.reduce)return a.reduce(b,"");var c="";t(a,function(d,e){c=b.call(void 0,c,d,e,a)});return c}function ca(a,b){for(var c=a.length,d=n(a)?a.split(""):a,e=0;e<c;e++)if(e in d&&b.call(void 0,d[e],e,a))return!0;return!1} function da(a,b){var c;a:if(n(a))c=n(b)&&1==b.length?a.indexOf(b,0):-1;else{for(c=0;c<a.length;c++)if(c in a&&a[c]===b)break a;c=-1}return 0<=c}function ea(a,b,c){return 2>=arguments.length?s.slice.call(a,b):s.slice.call(a,b,c)};var u={aliceblue:"#f0f8ff",antiquewhite:"#faebd7",aqua:"#00ffff",aquamarine:"#7fffd4",azure:"#f0ffff",beige:"#f5f5dc",bisque:"#ffe4c4",black:"#000000",blanchedalmond:"#ffebcd",blue:"#0000ff",blueviolet:"#8a2be2",brown:"#a52a2a",burlywood:"#deb887",cadetblue:"#5f9ea0",chartreuse:"#7fff00",chocolate:"#d2691e",coral:"#ff7f50",cornflowerblue:"#6495ed",cornsilk:"#fff8dc",crimson:"#dc143c",cyan:"#00ffff",darkblue:"#00008b",darkcyan:"#008b8b",darkgoldenrod:"#b8860b",darkgray:"#a9a9a9",darkgreen:"#006400", darkgrey:"#a9a9a9",darkkhaki:"#bdb76b",darkmagenta:"#8b008b",darkolivegreen:"#556b2f",darkorange:"#ff8c00",darkorchid:"#9932cc",darkred:"#8b0000",darksalmon:"#e9967a",darkseagreen:"#8fbc8f",darkslateblue:"#483d8b",darkslategray:"#2f4f4f",darkslategrey:"#2f4f4f",darkturquoise:"#00ced1",darkviolet:"#9400d3",deeppink:"#ff1493",deepskyblue:"#00bfff",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1e90ff",firebrick:"#b22222",floralwhite:"#fffaf0",forestgreen:"#228b22",fuchsia:"#ff00ff",gainsboro:"#dcdcdc", ghostwhite:"#f8f8ff",gold:"#ffd700",goldenrod:"#daa520",gray:"#808080",green:"#008000",greenyellow:"#adff2f",grey:"#808080",honeydew:"#f0fff0",hotpink:"#ff69b4",indianred:"#cd5c5c",indigo:"#4b0082",ivory:"#fffff0",khaki:"#f0e68c",lavender:"#e6e6fa",lavenderblush:"#fff0f5",lawngreen:"#7cfc00",lemonchiffon:"#fffacd",lightblue:"#add8e6",lightcoral:"#f08080",lightcyan:"#e0ffff",lightgoldenrodyellow:"#fafad2",lightgray:"#d3d3d3",lightgreen:"#90ee90",lightgrey:"#d3d3d3",lightpink:"#ffb6c1",lightsalmon:"#ffa07a", lightseagreen:"#20b2aa",lightskyblue:"#87cefa",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#b0c4de",lightyellow:"#ffffe0",lime:"#00ff00",limegreen:"#32cd32",linen:"#faf0e6",magenta:"#ff00ff",maroon:"#800000",mediumaquamarine:"#66cdaa",mediumblue:"#0000cd",mediumorchid:"#ba55d3",mediumpurple:"#9370db",mediumseagreen:"#3cb371",mediumslateblue:"#7b68ee",mediumspringgreen:"#00fa9a",mediumturquoise:"#48d1cc",mediumvioletred:"#c71585",midnightblue:"#191970",mintcream:"#f5fffa",mistyrose:"#ffe4e1", moccasin:"#ffe4b5",navajowhite:"#ffdead",navy:"#000080",oldlace:"#fdf5e6",olive:"#808000",olivedrab:"#6b8e23",orange:"#ffa500",orangered:"#ff4500",orchid:"#da70d6",palegoldenrod:"#eee8aa",palegreen:"#98fb98",paleturquoise:"#afeeee",palevioletred:"#db7093",papayawhip:"#ffefd5",peachpuff:"#ffdab9",peru:"#cd853f",pink:"#ffc0cb",plum:"#dda0dd",powderblue:"#b0e0e6",purple:"#800080",red:"#ff0000",rosybrown:"#bc8f8f",royalblue:"#4169e1",saddlebrown:"#8b4513",salmon:"#fa8072",sandybrown:"#f4a460",seagreen:"#2e8b57", seashell:"#fff5ee",sienna:"#a0522d",silver:"#c0c0c0",skyblue:"#87ceeb",slateblue:"#6a5acd",slategray:"#708090",slategrey:"#708090",snow:"#fffafa",springgreen:"#00ff7f",steelblue:"#4682b4",tan:"#d2b48c",teal:"#008080",thistle:"#d8bfd8",tomato:"#ff6347",turquoise:"#40e0d0",violet:"#ee82ee",wheat:"#f5deb3",white:"#ffffff",whitesmoke:"#f5f5f5",yellow:"#ffff00",yellowgreen:"#9acd32"};var fa="background-color border-top-color border-right-color border-bottom-color border-left-color color outline-color".split(" "),ga=/#([0-9a-fA-F])([0-9a-fA-F])([0-9a-fA-F])/;function ha(a){if(!x.test(a))throw Error("'"+a+"' is not a valid hex color");4==a.length&&(a=a.replace(ga,"#$1$1$2$2$3$3"));return a.toLowerCase()}var x=/^#(?:[0-9a-f]{3}){1,2}$/i,ia=/^(?:rgba)?\((\d{1,3}),\s?(\d{1,3}),\s?(\d{1,3}),\s?(0|1|0\.\d*)\)$/i; function ja(a){var b=a.match(ia);if(b){a=Number(b[1]);var c=Number(b[2]),d=Number(b[3]),b=Number(b[4]);if(0<=a&&255>=a&&0<=c&&255>=c&&0<=d&&255>=d&&0<=b&&1>=b)return[a,c,d,b]}return[]}var ka=/^(?:rgb)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\)$/i;function la(a){var b=a.match(ka);if(b){a=Number(b[1]);var c=Number(b[2]),b=Number(b[3]);if(0<=a&&255>=a&&0<=c&&255>=c&&0<=b&&255>=b)return[a,c,b]}return[]};function y(a,b){this.code=a;this.state=z[a]||ma;this.message=b||"";var c=this.state.replace(/((?:^|\s+)[a-z])/g,function(a){return a.toUpperCase().replace(/^[\s\xa0]+/g,"")}),d=c.length-5;if(0>d||c.indexOf("Error",d)!=d)c+="Error";this.name=c;c=Error(this.message);c.name=this.name;this.stack=c.stack||""}(function(){var a=Error;function b(){}b.prototype=a.prototype;y.I=a.prototype;y.prototype=new b})(); var ma="unknown error",z={15:"element not selectable",11:"element not visible",31:"ime engine activation failed",30:"ime not available",24:"invalid cookie domain",29:"invalid element coordinates",12:"invalid element state",32:"invalid selector",51:"invalid selector",52:"invalid selector",17:"javascript error",405:"unsupported operation",34:"move target out of bounds",27:"no such alert",7:"no such element",8:"no such frame",23:"no such window",28:"script timeout",33:"session not created",10:"stale element reference", -0:"success",21:"timeout",25:"unable to set cookie",26:"unexpected alert open"};z[13]=ma;z[9]="unknown command";y.prototype.toString=function(){return this.name+": "+this.message};var r,na="",oa=/rv\:([^\);]+)(\)|;)/.exec(h.navigator?h.navigator.userAgent:null);r=na=oa?oa[1]:"";var A={};var B;A["1.9.1"]||(A["1.9.1"]=0<=q("1.9.1"));function C(a,b){this.x=void 0!==a?a:0;this.y=void 0!==b?b:0}C.prototype.toString=function(){return"("+this.x+", "+this.y+")"};C.prototype.ceil=function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this};C.prototype.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};C.prototype.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};function D(a,b){this.width=a;this.height=b}D.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};D.prototype.ceil=function(){this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};D.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};D.prototype.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};var pa=3;function E(a,b){if(a.contains&&1==b.nodeType)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||Boolean(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a} +0:"success",21:"timeout",25:"unable to set cookie",26:"unexpected alert open"};z[13]=ma;z[9]="unknown command";y.prototype.toString=function(){return this.name+": "+this.message};var r,na="",oa=/rv\:([^\);]+)(\)|;)/.exec(k.navigator?k.navigator.userAgent:null);r=na=oa?oa[1]:"";var A={};var B;A["1.9.1"]||(A["1.9.1"]=0<=q("1.9.1"));function C(a,b){this.x=void 0!==a?a:0;this.y=void 0!==b?b:0}C.prototype.toString=function(){return"("+this.x+", "+this.y+")"};C.prototype.ceil=function(){this.x=Math.ceil(this.x);this.y=Math.ceil(this.y);return this};C.prototype.floor=function(){this.x=Math.floor(this.x);this.y=Math.floor(this.y);return this};C.prototype.round=function(){this.x=Math.round(this.x);this.y=Math.round(this.y);return this};function D(a,b){this.width=a;this.height=b}D.prototype.toString=function(){return"("+this.width+" x "+this.height+")"};D.prototype.ceil=function(){this.width=Math.ceil(this.width);this.height=Math.ceil(this.height);return this};D.prototype.floor=function(){this.width=Math.floor(this.width);this.height=Math.floor(this.height);return this};D.prototype.round=function(){this.width=Math.round(this.width);this.height=Math.round(this.height);return this};var pa=3;function E(a,b){if(a.contains&&1==b.nodeType)return a==b||a.contains(b);if("undefined"!=typeof a.compareDocumentPosition)return a==b||Boolean(a.compareDocumentPosition(b)&16);for(;b&&a!=b;)b=b.parentNode;return b==a} function qa(a,b){if(a==b)return 0;if(a.compareDocumentPosition)return a.compareDocumentPosition(b)&2?1:-1;if("sourceIndex"in a||a.parentNode&&"sourceIndex"in a.parentNode){var c=1==a.nodeType,d=1==b.nodeType;if(c&&d)return a.sourceIndex-b.sourceIndex;var e=a.parentNode,f=b.parentNode;return e==f?ra(a,b):!c&&E(e,b)?-1*sa(a,b):!d&&E(f,a)?sa(b,a):(c?a.sourceIndex:e.sourceIndex)-(d?b.sourceIndex:f.sourceIndex)}d=F(a);c=d.createRange();c.selectNode(a);c.collapse(!0);d=d.createRange();d.selectNode(b);d.collapse(!0); -return c.compareBoundaryPoints(h.Range.START_TO_END,d)}function sa(a,b){var c=a.parentNode;if(c==b)return-1;for(var d=b;d.parentNode!=c;)d=d.parentNode;return ra(d,a)}function ra(a,b){for(var c=b;c=c.previousSibling;)if(c==a)return-1;return 1}function F(a){return 9==a.nodeType?a:a.ownerDocument||a.document}function ta(a,b){a=a.parentNode;for(var c=0;a;){if(b(a))return a;a=a.parentNode;c++}return null}function G(a){this.p=a||h.document||document} +return c.compareBoundaryPoints(k.Range.START_TO_END,d)}function sa(a,b){var c=a.parentNode;if(c==b)return-1;for(var d=b;d.parentNode!=c;)d=d.parentNode;return ra(d,a)}function ra(a,b){for(var c=b;c=c.previousSibling;)if(c==a)return-1;return 1}function F(a){return 9==a.nodeType?a:a.ownerDocument||a.document}function ta(a,b){a=a.parentNode;for(var c=0;a;){if(b(a))return a;a=a.parentNode;c++}return null}function G(a){this.p=a||k.document||document} function ua(a){var b=a.p;a="CSS1Compat"==b.compatMode?b.documentElement:b.body;b=b.parentWindow||b.defaultView;return new C(b.pageXOffset||a.scrollLeft,b.pageYOffset||a.scrollTop)}G.prototype.contains=E;function H(a){var b=null,c=a.nodeType;1==c&&(b=a.textContent,b=void 0==b||null==b?a.innerText:b,b=void 0==b||null==b?"":b);if("string"!=typeof b)if(9==c||1==c){a=9==c?a.documentElement:a.firstChild;for(var c=0,d=[],b="";a;){do 1!=a.nodeType&&(b+=a.nodeValue),d[c++]=a;while(a=a.firstChild);for(;c&&!(a=d[--c].nextSibling););}}else b=a.nodeValue;return""+b} function I(a,b,c){if(null===b)return!0;try{if(!a.getAttribute)return!1}catch(d){return!1}return null==c?!!a.getAttribute(b):a.getAttribute(b,2)==c}function J(a,b,c,d,e){return va.call(null,a,b,n(c)?c:null,n(d)?d:null,e||new K)} function va(a,b,c,d,e){b.getElementsByName&&d&&"name"==c?(b=b.getElementsByName(d),t(b,function(b){a.matches(b)&&e.add(b)})):b.getElementsByClassName&&d&&"class"==c?(b=b.getElementsByClassName(d),t(b,function(b){b.className==d&&a.matches(b)&&e.add(b)})):b.getElementsByTagName&&(b=b.getElementsByTagName(a.getName()),t(b,function(a){I(a,c,d)&&e.add(a)}));return e}function wa(a,b,c,d,e){for(b=b.firstChild;b;b=b.nextSibling)I(b,c,d)&&a.matches(b)&&e.add(b);return e};function K(){this.d=this.c=null;this.g=0}function xa(a){this.m=a;this.next=this.i=null}K.prototype.unshift=function(a){a=new xa(a);a.next=this.c;this.d?this.c.i=a:this.c=this.d=a;this.c=a;this.g++};K.prototype.add=function(a){a=new xa(a);a.i=this.d;this.c?this.d.next=a:this.c=this.d=a;this.d=a;this.g++};function ya(a){return(a=a.c)?a.m:null}function L(a){return new za(a,!1)}function za(a,b){this.F=a;this.j=(this.n=b)?a.d:a.c;this.r=null} za.prototype.next=function(){var a=this.j;if(null==a)return null;var b=this.r=a;this.j=this.n?a.i:a.next;return b.m};function M(a,b,c,d,e){b=b.evaluate(d);c=c.evaluate(d);var f;if(b instanceof K&&c instanceof K){e=L(b);for(d=e.next();d;d=e.next())for(b=L(c),f=b.next();f;f=b.next())if(a(H(d),H(f)))return!0;return!1}if(b instanceof K||c instanceof K){b instanceof K?e=b:(e=c,c=b);e=L(e);b=typeof c;for(d=e.next();d;d=e.next()){switch(b){case "number":d=+H(d);break;case "boolean":d=!!H(d);break;case "string":d=H(d);break;default:throw Error("Illegal primitive type for comparison.");}if(a(d,c))return!0}return!1}return e? "boolean"==typeof b||"boolean"==typeof c?a(!!b,!!c):"number"==typeof b||"number"==typeof c?a(+b,+c):a(b,c):a(+b,+c)}function Aa(a,b,c,d){this.s=a;this.H=b;this.o=c;this.q=d}Aa.prototype.toString=function(){return this.s};var Ba={};function N(a,b,c,d){if(a in Ba)throw Error("Binary operator already created: "+a);a=new Aa(a,b,c,d);Ba[a.toString()]=a}N("div",6,1,function(a,b,c){return a.b(c)/b.b(c)});N("mod",6,1,function(a,b,c){return a.b(c)%b.b(c)});N("*",6,1,function(a,b,c){return a.b(c)*b.b(c)}); N("+",5,1,function(a,b,c){return a.b(c)+b.b(c)});N("-",5,1,function(a,b,c){return a.b(c)-b.b(c)});N("<",4,2,function(a,b,c){return M(function(a,b){return a<b},a,b,c)});N(">",4,2,function(a,b,c){return M(function(a,b){return a>b},a,b,c)});N("<=",4,2,function(a,b,c){return M(function(a,b){return a<=b},a,b,c)});N(">=",4,2,function(a,b,c){return M(function(a,b){return a>=b},a,b,c)});N("=",3,2,function(a,b,c){return M(function(a,b){return a==b},a,b,c,!0)}); -N("!=",3,2,function(a,b,c){return M(function(a,b){return a!=b},a,b,c,!0)});N("and",2,2,function(a,b,c){return a.f(c)&&b.f(c)});N("or",1,2,function(a,b,c){return a.f(c)||b.f(c)});function Ca(a,b,c,d,e,f,k,w,p){this.h=a;this.o=b;this.D=c;this.C=d;this.B=e;this.q=f;this.A=k;this.w=void 0!==w?w:k;this.G=!!p}Ca.prototype.toString=function(){return this.h};var Da={};function O(a,b,c,d,e,f,k,w){if(a in Da)throw Error("Function already created: "+a+".");Da[a]=new Ca(a,b,c,d,!1,e,f,k,w)}O("boolean",2,!1,!1,function(a,b){return b.f(a)},1);O("ceiling",1,!1,!1,function(a,b){return Math.ceil(b.b(a))},1); -O("concat",3,!1,!1,function(a,b){var c=ea(arguments,1);return ba(c,function(b,c){return b+c.a(a)})},2,null);O("contains",2,!1,!1,function(a,b,c){b=b.a(a);a=c.a(a);return-1!=b.indexOf(a)},2);O("count",1,!1,!1,function(a,b){return b.evaluate(a).g},1,1,!0);O("false",2,!1,!1,g(!1),0);O("floor",1,!1,!1,function(a,b){return Math.floor(b.b(a))},1); -O("id",4,!1,!1,function(a,b){var c=a.e(),d=9==c.nodeType?c:c.ownerDocument,c=b.a(a).split(/\s+/),e=[];t(c,function(a){(a=d.getElementById(a))&&!da(e,a)&&e.push(a)});e.sort(qa);var f=new K;t(e,function(a){f.add(a)});return f},1);O("lang",2,!1,!1,g(!1),1);O("last",1,!0,!1,function(a){if(1!=arguments.length)throw Error("Function last expects ()");return a.u()},0);O("local-name",3,!1,!0,function(a,b){var c=b?ya(b.evaluate(a)):a.e();return c?c.nodeName.toLowerCase():""},0,1,!0); -O("name",3,!1,!0,function(a,b){var c=b?ya(b.evaluate(a)):a.e();return c?c.nodeName.toLowerCase():""},0,1,!0);O("namespace-uri",3,!0,!1,g(""),0,1,!0);O("normalize-space",3,!1,!0,function(a,b){return(b?b.a(a):H(a.e())).replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,"")},0,1);O("not",2,!1,!1,function(a,b){return!b.f(a)},1);O("number",1,!1,!0,function(a,b){return b?b.b(a):+H(a.e())},0,1);O("position",1,!0,!1,function(a){return a.v()},0);O("round",1,!1,!1,function(a,b){return Math.round(b.b(a))},1); +N("!=",3,2,function(a,b,c){return M(function(a,b){return a!=b},a,b,c,!0)});N("and",2,2,function(a,b,c){return a.f(c)&&b.f(c)});N("or",1,2,function(a,b,c){return a.f(c)||b.f(c)});function Ca(a,b,c,d,e,f,g,w,p){this.h=a;this.o=b;this.D=c;this.C=d;this.B=e;this.q=f;this.A=g;this.w=void 0!==w?w:g;this.G=!!p}Ca.prototype.toString=function(){return this.h};var Da={};function O(a,b,c,d,e,f,g,w){if(a in Da)throw Error("Function already created: "+a+".");Da[a]=new Ca(a,b,c,d,!1,e,f,g,w)}O("boolean",2,!1,!1,function(a,b){return b.f(a)},1);O("ceiling",1,!1,!1,function(a,b){return Math.ceil(b.b(a))},1); +O("concat",3,!1,!1,function(a,b){var c=ea(arguments,1);return ba(c,function(b,c){return b+c.a(a)})},2,null);O("contains",2,!1,!1,function(a,b,c){b=b.a(a);a=c.a(a);return-1!=b.indexOf(a)},2);O("count",1,!1,!1,function(a,b){return b.evaluate(a).g},1,1,!0);O("false",2,!1,!1,h(!1),0);O("floor",1,!1,!1,function(a,b){return Math.floor(b.b(a))},1); +O("id",4,!1,!1,function(a,b){var c=a.e(),d=9==c.nodeType?c:c.ownerDocument,c=b.a(a).split(/\s+/),e=[];t(c,function(a){(a=d.getElementById(a))&&!da(e,a)&&e.push(a)});e.sort(qa);var f=new K;t(e,function(a){f.add(a)});return f},1);O("lang",2,!1,!1,h(!1),1);O("last",1,!0,!1,function(a){if(1!=arguments.length)throw Error("Function last expects ()");return a.u()},0);O("local-name",3,!1,!0,function(a,b){var c=b?ya(b.evaluate(a)):a.e();return c?c.nodeName.toLowerCase():""},0,1,!0); +O("name",3,!1,!0,function(a,b){var c=b?ya(b.evaluate(a)):a.e();return c?c.nodeName.toLowerCase():""},0,1,!0);O("namespace-uri",3,!0,!1,h(""),0,1,!0);O("normalize-space",3,!1,!0,function(a,b){return(b?b.a(a):H(a.e())).replace(/[\s\xa0]+/g," ").replace(/^\s+|\s+$/g,"")},0,1);O("not",2,!1,!1,function(a,b){return!b.f(a)},1);O("number",1,!1,!0,function(a,b){return b?b.b(a):+H(a.e())},0,1);O("position",1,!0,!1,function(a){return a.v()},0);O("round",1,!1,!1,function(a,b){return Math.round(b.b(a))},1); O("starts-with",2,!1,!1,function(a,b,c){b=b.a(a);a=c.a(a);return 0==b.lastIndexOf(a,0)},2);O("string",3,!1,!0,function(a,b){return b?b.a(a):H(a.e())},0,1);O("string-length",1,!1,!0,function(a,b){return(b?b.a(a):H(a.e())).length},0,1); O("substring",3,!1,!1,function(a,b,c,d){c=c.b(a);if(isNaN(c)||Infinity==c||-Infinity==c)return"";d=d?d.b(a):Infinity;if(isNaN(d)||-Infinity===d)return"";c=Math.round(c)-1;var e=Math.max(c,0);a=b.a(a);if(Infinity==d)return a.substring(e);b=Math.round(d);return a.substring(e,c+b)},2,3);O("substring-after",3,!1,!1,function(a,b,c){b=b.a(a);a=c.a(a);c=b.indexOf(a);return-1==c?"":b.substring(c+a.length)},2);