mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to fx-team.
This commit is contained in:
commit
0abec40370
@ -139,6 +139,7 @@ else
|
||||
$(RM) $(DIST)/$(APP_NAME).app/Contents/MacOS/$(PROGRAM)
|
||||
rsync -aL $(PROGRAM) $(DIST)/$(APP_NAME).app/Contents/MacOS
|
||||
endif
|
||||
cp -RL $(srcdir)/b2g.icns $(DIST)/$(APP_NAME).app/Contents/Resources/$(MOZ_APP_NAME).icns
|
||||
printf "APPLMOZB" > $(DIST)/$(APP_NAME).app/Contents/PkgInfo
|
||||
|
||||
else # MOZ_WIDGET_TOOLKIT != cocoa
|
||||
|
BIN
b2g/app/b2g.icns
Normal file
BIN
b2g/app/b2g.icns
Normal file
Binary file not shown.
@ -1009,7 +1009,7 @@ let RemoteDebugger = {
|
||||
}
|
||||
DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/styleeditor.js");
|
||||
DebuggerServer.addActors('chrome://browser/content/dbg-browser-actors.js');
|
||||
DebuggerServer.addActors('chrome://browser/content/dbg-webapps-actors.js');
|
||||
DebuggerServer.addActors("resource://gre/modules/devtools/server/actors/webapps.js");
|
||||
}
|
||||
|
||||
let port = Services.prefs.getIntPref('devtools.debugger.remote-port') || 6000;
|
||||
|
@ -10,7 +10,6 @@ chrome.jar:
|
||||
|
||||
content/arrow.svg (content/arrow.svg)
|
||||
* content/dbg-browser-actors.js (content/dbg-browser-actors.js)
|
||||
* content/dbg-webapps-actors.js (content/dbg-webapps-actors.js)
|
||||
content/forms.js (content/forms.js)
|
||||
* content/settings.js (content/settings.js)
|
||||
* content/shell.xul (content/shell.xul)
|
||||
|
@ -51,7 +51,7 @@ pref("extensions.blocklist.interval", 86400);
|
||||
// blocking them.
|
||||
pref("extensions.blocklist.level", 2);
|
||||
pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/3/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/%PING_COUNT%/%TOTAL_PING_COUNT%/%DAYS_SINCE_LAST_PING%/");
|
||||
pref("extensions.blocklist.detailsURL", "https://www.mozilla.com/%LOCALE%/blocklist/");
|
||||
pref("extensions.blocklist.detailsURL", "https://www.mozilla.org/%LOCALE%/blocklist/");
|
||||
pref("extensions.blocklist.itemURL", "https://addons.mozilla.org/%LOCALE%/%APP%/blocked/%blockID%");
|
||||
|
||||
pref("extensions.update.autoUpdateDefault", true);
|
||||
@ -753,7 +753,7 @@ pref("browser.safebrowsing.reportPhishURL", "http://%LOCALE%.phish-report.mozill
|
||||
pref("browser.safebrowsing.reportMalwareURL", "http://%LOCALE%.malware-report.mozilla.com/?hl=%LOCALE%");
|
||||
pref("browser.safebrowsing.reportMalwareErrorURL", "http://%LOCALE%.malware-error.mozilla.com/?hl=%LOCALE%");
|
||||
|
||||
pref("browser.safebrowsing.warning.infoURL", "http://www.mozilla.com/%LOCALE%/firefox/phishing-protection/");
|
||||
pref("browser.safebrowsing.warning.infoURL", "https://www.mozilla.org/%LOCALE%/firefox/phishing-protection/");
|
||||
pref("browser.safebrowsing.malware.reportURL", "http://safebrowsing.clients.google.com/safebrowsing/diagnostic?client=%NAME%&hl=%LOCALE%&site=");
|
||||
|
||||
#ifdef MOZILLA_OFFICIAL
|
||||
|
@ -117,7 +117,7 @@
|
||||
<hbox pack="center">
|
||||
<label class="text-link bottom-link" href="about:license">&bottomLinks.license;</label>
|
||||
<label class="text-link bottom-link" href="about:rights">&bottomLinks.rights;</label>
|
||||
<label class="text-link bottom-link" href="http://www.mozilla.com/legal/privacy/">&bottomLinks.privacy;</label>
|
||||
<label class="text-link bottom-link" href="https://www.mozilla.org/legal/privacy/">&bottomLinks.privacy;</label>
|
||||
</hbox>
|
||||
<description id="trademark">&trademarkInfo.part1;</description>
|
||||
</vbox>
|
||||
|
@ -369,7 +369,7 @@
|
||||
onclick="checkForMiddleClick(this, event);"/>
|
||||
<menuitem id="appmenu_gettingStarted"
|
||||
label="&appMenuGettingStarted.label;"
|
||||
oncommand="gBrowser.loadOneTab('http://www.mozilla.com/firefox/central/', {inBackground: false});"
|
||||
oncommand="gBrowser.loadOneTab('https://www.mozilla.org/firefox/central/', {inBackground: false});"
|
||||
onclick="checkForMiddleClick(this, event);"/>
|
||||
#ifdef MOZ_SERVICES_HEALTHREPORT
|
||||
<menuitem id="appmenu_healthReport"
|
||||
|
@ -21,10 +21,6 @@ pref("app.update.url.manual", "https://www.mozilla.org/firefox/aurora/");
|
||||
// supplied in the "An update is available" page of the update wizard.
|
||||
pref("app.update.url.details", "https://www.mozilla.org/firefox/aurora/");
|
||||
|
||||
// Release notes and vendor URLs
|
||||
pref("app.releaseNotesURL", "http://www.mozilla.org/projects/firefox/%VERSION%/releasenotes/");
|
||||
pref("app.vendorURL", "http://www.mozilla.org/projects/firefox/");
|
||||
|
||||
// Search codes belong only in builds with official branding
|
||||
pref("browser.search.param.yahoo-fr", "");
|
||||
pref("browser.search.param.yahoo-fr-cjkt", ""); // now unused
|
||||
|
@ -18,10 +18,6 @@ pref("app.update.url.manual", "https://nightly.mozilla.org");
|
||||
// supplied in the "An update is available" page of the update wizard.
|
||||
pref("app.update.url.details", "https://nightly.mozilla.org");
|
||||
|
||||
// Release notes and vendor URLs
|
||||
pref("app.releaseNotesURL", "http://www.mozilla.org/projects/firefox/%VERSION%/releasenotes/");
|
||||
pref("app.vendorURL", "http://www.mozilla.org/projects/firefox/");
|
||||
|
||||
// Search codes belong only in builds with official branding
|
||||
pref("browser.search.param.yahoo-fr", "");
|
||||
pref("browser.search.param.yahoo-fr-cjkt", ""); // now unused
|
||||
|
@ -10,8 +10,8 @@
|
||||
# instead of BrandFullName and typically should not be modified.
|
||||
!define BrandFullNameInternal "Mozilla Firefox"
|
||||
!define CompanyName "Mozilla Corporation"
|
||||
!define URLInfoAbout "http://www.mozilla.com/${AB_CD}/"
|
||||
!define URLUpdateInfo "http://www.mozilla.com/${AB_CD}/firefox/"
|
||||
!define URLInfoAbout "https://www.mozilla.org/${AB_CD}/"
|
||||
!define URLUpdateInfo "https://www.mozilla.org/${AB_CD}/firefox/"
|
||||
|
||||
; The OFFICIAL define is a workaround to support different urls for Release and
|
||||
; Beta since they share the same branding when building with other branches that
|
||||
|
@ -18,10 +18,6 @@ pref("app.update.url.manual", "https://www.mozilla.org/firefox/");
|
||||
// supplied in the "An update is available" page of the update wizard.
|
||||
pref("app.update.url.details", "https://www.mozilla.org/%LOCALE%/firefox/notes");
|
||||
|
||||
// Release notes and vendor URLs
|
||||
pref("app.releaseNotesURL", "http://www.mozilla.com/%LOCALE%/firefox/%VERSION%/releasenotes/");
|
||||
pref("app.vendorURL", "http://www.mozilla.com/%LOCALE%/firefox/");
|
||||
|
||||
pref("browser.search.param.ms-pc", "MOZI");
|
||||
pref("browser.search.param.yahoo-fr", "moz35");
|
||||
pref("browser.search.param.yahoo-fr-cjkt", "moz35"); // now unused
|
||||
|
@ -18,10 +18,6 @@ pref("app.update.url.manual", "https://nightly.mozilla.org");
|
||||
// supplied in the "An update is available" page of the update wizard.
|
||||
pref("app.update.url.details", "https://nightly.mozilla.org");
|
||||
|
||||
// Release notes and vendor URLs
|
||||
pref("app.releaseNotesURL", "http://www.mozilla.org/projects/firefox/%VERSION%/releasenotes/");
|
||||
pref("app.vendorURL", "http://www.mozilla.org/projects/firefox/");
|
||||
|
||||
// Search codes belong only in builds with official branding
|
||||
pref("browser.search.param.yahoo-fr", "");
|
||||
pref("browser.search.param.yahoo-fr-cjkt", ""); // now unused
|
||||
|
@ -992,17 +992,19 @@ DownloadsPlacesView.prototype = {
|
||||
|
||||
_removeElement: function DPV__removeElement(aElement) {
|
||||
// If the element was selected exclusively, select its next
|
||||
// sibling first, if any.
|
||||
if (aElement.nextSibling &&
|
||||
// sibling first, if not, try for previous sibling, if any.
|
||||
if ((aElement.nextSibling || aElement.previousSibling) &&
|
||||
this._richlistbox.selectedItems &&
|
||||
this._richlistbox.selectedItems.length > 0 &&
|
||||
this._richlistbox.selectedItems.length == 1 &&
|
||||
this._richlistbox.selectedItems[0] == aElement) {
|
||||
this._richlistbox.selectItem(aElement.nextSibling);
|
||||
this._richlistbox.selectItem(aElement.nextSibling ||
|
||||
aElement.previousSibling);
|
||||
}
|
||||
|
||||
if (this._lastSessionDownloadElement == aElement)
|
||||
this._lastSessionDownloadElement = aElement.previousSibling;
|
||||
|
||||
this._richlistbox.removeItemFromSelection(aElement);
|
||||
this._richlistbox.removeChild(aElement);
|
||||
this._ensureVisibleElementsAreActive();
|
||||
goUpdateCommand("downloadsCmd_clearDownloads");
|
||||
@ -1461,7 +1463,11 @@ DownloadsPlacesView.prototype = {
|
||||
goUpdateCommand("downloadsCmd_clearDownloads");
|
||||
break;
|
||||
default: {
|
||||
let selectedElements = this._richlistbox.selectedItems;
|
||||
// Slicing the array to get a freezed list of selected items. Otherwise,
|
||||
// the selectedItems array is live and doCommand may alter the selection
|
||||
// while we are trying to do one particular action, like removing items
|
||||
// from history.
|
||||
let selectedElements = this._richlistbox.selectedItems.slice();
|
||||
for (let element of selectedElements) {
|
||||
element._shell.doCommand(aCommand);
|
||||
}
|
||||
|
@ -1 +1 @@
|
||||
{"title":"","id":1,"dateAdded":1233157910552624,"lastModified":1233157955206833,"type":"text/x-moz-place-container","root":"placesRoot","children":[{"title":"Bookmarks Menu","id":2,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157993171424,"type":"text/x-moz-place-container","root":"bookmarksMenuFolder","children":[{"title":"examplejson","id":27,"parent":2,"dateAdded":1233157972101126,"lastModified":1233157984999673,"type":"text/x-moz-place","uri":"http://example.com/"}]},{"index":1,"title":"Bookmarks Toolbar","id":3,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157972101126,"annos":[{"name":"bookmarkProperties/description","flags":0,"expires":4,"mimeType":null,"type":3,"value":"Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar"}],"type":"text/x-moz-place-container","root":"toolbarFolder","children":[{"title":"examplejson","id":26,"parent":3,"dateAdded":1233157972101126,"lastModified":1233157984999673,"type":"text/x-moz-place","uri":"http://example.com/"}]},{"index":2,"title":"Tags","id":4,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157910582667,"type":"text/x-moz-place-container","root":"tagsFolder","children":[]},{"index":3,"title":"Unsorted Bookmarks","id":5,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157911033315,"type":"text/x-moz-place-container","root":"unfiledBookmarksFolder","children":[]},]}
|
||||
{"title":"","id":1,"dateAdded":1233157910552624,"lastModified":1233157955206833,"type":"text/x-moz-place-container","root":"placesRoot","children":[{"title":"Bookmarks Menu","id":2,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157993171424,"type":"text/x-moz-place-container","root":"bookmarksMenuFolder","children":[{"title":"examplejson","id":27,"parent":2,"dateAdded":1233157972101126,"lastModified":1233157984999673,"type":"text/x-moz-place","uri":"http://example.com/"}]},{"index":1,"title":"Bookmarks Toolbar","id":3,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157972101126,"annos":[{"name":"bookmarkProperties/description","flags":0,"expires":4,"mimeType":null,"type":3,"value":"Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar"}],"type":"text/x-moz-place-container","root":"toolbarFolder","children":[{"title":"examplejson","id":26,"parent":3,"dateAdded":1233157972101126,"lastModified":1233157984999673,"type":"text/x-moz-place","uri":"http://example.com/"}]},{"index":2,"title":"Tags","id":4,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157910582667,"type":"text/x-moz-place-container","root":"tagsFolder","children":[]},{"index":3,"title":"Unsorted Bookmarks","id":5,"parent":1,"dateAdded":1233157910552624,"lastModified":1233157911033315,"type":"text/x-moz-place-container","root":"unfiledBookmarksFolder","children":[]}]}
|
||||
|
@ -78,13 +78,13 @@ function test() {
|
||||
testFolder.events.addListener("removechild", onFolderRemoveChild);
|
||||
|
||||
// test adding a bookmark
|
||||
var testBookmark = testFolder.addBookmark("Mozilla", url("http://www.mozilla.com/"));
|
||||
var testBookmark = testFolder.addBookmark("Mozilla", url("https://www.mozilla.org/"));
|
||||
ok(testBookmark, "Check bookmark creation");
|
||||
ok(testBookmark.parent, "Check parent after bookmark creation");
|
||||
is(gLastFolderAction, "addchild", "Check event handler for adding a child to a folder");
|
||||
is(testBookmark.type, "bookmark", "Check 'bookmark.type' after creation");
|
||||
is(testBookmark.title, "Mozilla", "Check 'bookmark.title' after creation");
|
||||
is(testBookmark.uri.spec, "http://www.mozilla.com/", "Check 'bookmark.uri' after creation");
|
||||
is(testBookmark.uri.spec, "https://www.mozilla.org/", "Check 'bookmark.uri' after creation");
|
||||
|
||||
is(testFolder.children.length, 1, "Check test folder child count after adding a child bookmark");
|
||||
|
||||
@ -175,7 +175,7 @@ function test() {
|
||||
var testFolderA = root.addFolder("folder-a");
|
||||
var testFolderB = root.addFolder("folder-b");
|
||||
|
||||
var testMove = testFolderA.addBookmark("Mozilla", url("http://www.mozilla.com/"));
|
||||
var testMove = testFolderA.addBookmark("Mozilla", url("https://www.mozilla.org/"));
|
||||
testMove.events.addListener("move", onBookmarkMove);
|
||||
is(testMove.parent.title, "folder-a", "Checking for new parent before moving bookmark");
|
||||
|
||||
|
@ -36,7 +36,7 @@
|
||||
<!-- LOCALIZATION NOTE (bottomLinks.rights): This is a link title that links to about:rights. -->
|
||||
<!ENTITY bottomLinks.rights "End-User Rights">
|
||||
|
||||
<!-- LOCALIZATION NOTE (bottomLinks.privacy): This is a link title that links to http://www.mozilla.com/legal/privacy/. -->
|
||||
<!-- LOCALIZATION NOTE (bottomLinks.privacy): This is a link title that links to https://www.mozilla.org/legal/privacy/. -->
|
||||
<!ENTITY bottomLinks.privacy "Privacy Policy">
|
||||
|
||||
<!-- LOCALIZATION NOTE (update.checkingForUpdates): try to make the localized text short (see bug 596813 for screenshots). -->
|
||||
|
@ -3,9 +3,7 @@
|
||||
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
|
||||
|
||||
<!-- These strings are used in the about:robots page, which ties in with the
|
||||
robots theme used in the Firefox 3 Beta 2/3 first run pages...
|
||||
https://www.mozilla.com/en-US/firefox/3.0b2/firstrun/
|
||||
https://www.mozilla.com/en-US/firefox/3.0b3/firstrun/
|
||||
robots theme used in the Firefox 3 Beta 2/3 first run pages.
|
||||
They're just meant to be fun and whimsical, with references to some geeky
|
||||
but well-known robots in movies and books. Be creative with translations! -->
|
||||
|
||||
|
@ -433,7 +433,7 @@ identity.loggedIn.description = Signed in as: %S
|
||||
identity.loggedIn.signOut.label = Sign Out
|
||||
identity.loggedIn.signOut.accessKey = O
|
||||
|
||||
# LOCALIZATION NOTE (getUserMedia.shareCamera.message, getUserMedia.shareMicrophone.message, getUserMedia.shareCameraAndMicrophone.message, getUserMedia.sharingCamera.message, getUserMedia.sharingMicrophone.message, getUserMedia.sharingCameraAndMicrophone.message): %S is the website origin (e.g. www.mozilla.org)
|
||||
# LOCALIZATION NOTE (getUserMedia.shareCamera.message, getUserMedia.shareMicrophone.message, getUserMedia.shareCameraAndMicrophone.message): %S is the website origin (e.g. www.mozilla.org)
|
||||
# LOCALIZATION NOTE (getUserMedia.shareSelectedDevices.label):
|
||||
# Semicolon-separated list of plural forms. See:
|
||||
# http://developer.mozilla.org/en/docs/Localization_and_Plurals
|
||||
@ -447,9 +447,9 @@ getUserMedia.shareSelectedDevices.label = Share Selected Device;Share Selected D
|
||||
getUserMedia.shareSelectedDevices.accesskey = S
|
||||
getUserMedia.denyRequest.label = Don't Share
|
||||
getUserMedia.denyRequest.accesskey = D
|
||||
getUserMedia.sharingCamera.message = You are currently sharing your camera with %S.
|
||||
getUserMedia.sharingMicrophone.message = You are currently sharing your microphone with %S.
|
||||
getUserMedia.sharingCameraAndMicrophone.message = You are currently sharing your camera and microphone with %S.
|
||||
getUserMedia.sharingCamera.message2 = You are currently sharing your camera with this page.
|
||||
getUserMedia.sharingMicrophone.message2 = You are currently sharing your microphone with this page.
|
||||
getUserMedia.sharingCameraAndMicrophone.message2 = You are currently sharing your camera and microphone with this page.
|
||||
|
||||
# Mixed Content Blocker Doorhanger Notification
|
||||
# LOCALIZATION NOTE - %S is brandShortName
|
||||
|
@ -14,7 +14,7 @@
|
||||
#define bookmarks_toolbarfolder_description Add bookmarks to this folder to see them displayed on the Bookmarks Toolbar
|
||||
|
||||
# LOCALIZATION NOTE (getting_started):
|
||||
# link title for http://en-US.www.mozilla.com/en-US/firefox/central/
|
||||
# link title for https://www.mozilla.org/en-US/firefox/central/
|
||||
#define getting_started Getting Started
|
||||
|
||||
# LOCALIZATION NOTE (firefox_heading):
|
||||
@ -22,19 +22,19 @@
|
||||
#define firefox_heading Mozilla Firefox
|
||||
|
||||
# LOCALIZATION NOTE (firefox_help):
|
||||
# link title for http://en-US.www.mozilla.com/en-US/firefox/help/
|
||||
# link title for https://www.mozilla.org/en-US/firefox/help/
|
||||
#define firefox_help Help and Tutorials
|
||||
|
||||
# LOCALIZATION NOTE (firefox_customize):
|
||||
# link title for http://en-US.www.mozilla.com/en-US/firefox/customize/
|
||||
# link title for https://www.mozilla.org/en-US/firefox/customize/
|
||||
#define firefox_customize Customize Firefox
|
||||
|
||||
# LOCALIZATION NOTE (firefox_community):
|
||||
# link title for http://en-US.www.mozilla.com/en-US/firefox/community/
|
||||
# link title for https://www.mozilla.org/en-US/contribute/
|
||||
#define firefox_community Get Involved
|
||||
|
||||
# LOCALIZATION NOTE (firefox_about):
|
||||
# link title for http://en-US.www.mozilla.com/en-US/about/
|
||||
# link title for https://www.mozilla.org/en-US/about/
|
||||
#define firefox_about About Us
|
||||
|
||||
#unfilter emptyLines
|
||||
|
@ -32,7 +32,7 @@ template = '''#filter emptyLines
|
||||
#define bookmarks_toolbarfolder_description %s
|
||||
|
||||
# LOCALIZATION NOTE (getting_started):
|
||||
# link title for http://www.mozilla.com/en-US/firefox/central/
|
||||
# link title for https://www.mozilla.org/en-US/firefox/central/
|
||||
#define getting_started %s
|
||||
|
||||
# LOCALIZATION NOTE (firefox_heading):
|
||||
@ -40,19 +40,19 @@ template = '''#filter emptyLines
|
||||
#define firefox_heading %s
|
||||
|
||||
# LOCALIZATION NOTE (firefox_help):
|
||||
# link title for http://www.mozilla.com/en-US/firefox/help/
|
||||
# link title for https://www.mozilla.org/en-US/firefox/help/
|
||||
#define firefox_help %s
|
||||
|
||||
# LOCALIZATION NOTE (firefox_customize):
|
||||
# link title for http://www.mozilla.com/en-US/firefox/customize/
|
||||
# link title for https://www.mozilla.org/en-US/firefox/customize/
|
||||
#define firefox_customize %s
|
||||
|
||||
# LOCALIZATION NOTE (firefox_community):
|
||||
# link title for http://www.mozilla.com/en-US/firefox/community/
|
||||
# link title for https://www.mozilla.org/en-US/contribute/
|
||||
#define firefox_community %s
|
||||
|
||||
# LOCALIZATION NOTE (firefox_about):
|
||||
# link title for http://www.mozilla.com/en-US/about/
|
||||
# link title for https://www.mozilla.org/en-US/about/
|
||||
#define firefox_about %s
|
||||
|
||||
#unfilter emptyLines'''
|
||||
|
@ -15,13 +15,13 @@
|
||||
<DT><H3 PERSONAL_TOOLBAR_FOLDER="true" ID="rdf:#$FvPhC3">@bookmarks_toolbarfolder@</H3>
|
||||
<DD>@bookmarks_toolbarfolder_description@
|
||||
<DL><p>
|
||||
<DT><A HREF="http://www.mozilla.com/@AB_CD@/firefox/central/" ID="rdf:#$GvPhC3">@getting_started@</A>
|
||||
<DT><A HREF="https://www.mozilla.org/@AB_CD@/firefox/central/" ID="rdf:#$GvPhC3">@getting_started@</A>
|
||||
</DL><p>
|
||||
<DT><H3 ID="rdf:#$ZvPhC3">@firefox_heading@</H3>
|
||||
<DL><p>
|
||||
<DT><A HREF="http://www.mozilla.com/@AB_CD@/firefox/help/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$22iCK1">@firefox_help@</A>
|
||||
<DT><A HREF="http://www.mozilla.com/@AB_CD@/firefox/customize/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$32iCK1">@firefox_customize@</A>
|
||||
<DT><A HREF="http://www.mozilla.com/@AB_CD@/firefox/community/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$42iCK1">@firefox_community@</A>
|
||||
<DT><A HREF="http://www.mozilla.com/@AB_CD@/about/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$52iCK1">@firefox_about@</A>
|
||||
<DT><A HREF="https://www.mozilla.org/@AB_CD@/firefox/help/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$22iCK1">@firefox_help@</A>
|
||||
<DT><A HREF="https://www.mozilla.org/@AB_CD@/firefox/customize/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$32iCK1">@firefox_customize@</A>
|
||||
<DT><A HREF="https://www.mozilla.org/@AB_CD@/contribute/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$42iCK1">@firefox_community@</A>
|
||||
<DT><A HREF="https://www.mozilla.org/@AB_CD@/about/" ICON="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAHWSURBVHjaYvz//z8DJQAggJiQOe/fv2fv7Oz8rays/N+VkfG/iYnJfyD/1+rVq7ffu3dPFpsBAAHEAHIBCJ85c8bN2Nj4vwsDw/8zQLwKiO8CcRoQu0DxqlWrdsHUwzBAAIGJmTNnPgYa9j8UqhFElwPxf2MIDeIrKSn9FwSJoRkAEEAM0DD4DzMAyPi/G+QKY4hh5WAXGf8PDQ0FGwJ22d27CjADAAIIrLmjo+MXA9R2kAHvGBA2wwx6B8W7od6CeQcggKCmCEL8bgwxYCbUIGTDVkHDBia+CuotgACCueD3TDQN75D4xmAvCoK9ARMHBzAw0AECiBHkAlC0Mdy7x9ABNA3obAZXIAa6iKEcGlMVQHwWyjYuL2d4v2cPg8vZswx7gHyAAAK7AOif7SAbOqCmn4Ha3AHFsIDtgPq/vLz8P4MSkJ2W9h8ggBjevXvHDo4FQUQg/kdypqCg4H8lUIACnQ/SOBMYI8bAsAJFPcj1AAEEjwVQqLpAbXmH5BJjqI0gi9DTAAgDBBCcAVLkgmQ7yKCZxpCQxqUZhAECCJ4XgMl493ug21ZD+aDAXH0WLM4A9MZPXJkJIIAwTAR5pQMalaCABQUULttBGCCAGCnNzgABBgAMJ5THwGvJLAAAAABJRU5ErkJggg==" ID="rdf:#$52iCK1">@firefox_about@</A>
|
||||
</DL><p>
|
||||
</DL><p>
|
||||
|
@ -64,15 +64,19 @@ const WebProgress = {
|
||||
|
||||
_securityChange: function _securityChange(aJson, aTab) {
|
||||
let state = aJson.state;
|
||||
let identityBox = document.getElementById("identity-box-inner");
|
||||
let nsIWebProgressListener = Ci.nsIWebProgressListener;
|
||||
|
||||
if (state & nsIWebProgressListener.STATE_IDENTITY_EV_TOPLEVEL) {
|
||||
aTab._identityState = identityBox.className = "verifiedIdentity";
|
||||
aTab._identityState = "verifiedIdentity";
|
||||
} else if (state & nsIWebProgressListener.STATE_IS_SECURE) {
|
||||
aTab._identityState = identityBox.className = "verifiedDomain";
|
||||
aTab._identityState = "verifiedDomain";
|
||||
} else {
|
||||
aTab._identityState = identityBox.className = "";
|
||||
aTab._identityState = "";
|
||||
}
|
||||
|
||||
if (aTab == Browser.selectedTab) {
|
||||
let identityBox = document.getElementById("identity-box-inner");
|
||||
identityBox.className = aTab._identityState;
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -33,7 +33,7 @@
|
||||
-->
|
||||
<li>&rights.intro-point2-a;<a href="http://www.mozilla.org/foundation/trademarks/policy.html">&rights.intro-point2-b;</a>&rights.intro-point2-c;</li>
|
||||
<li>&rights.intro-point2.5;</li>
|
||||
<li>&rights2.intro-point3a;<a href="http://www.mozilla.com/legal/privacy/">&rights2.intro-point3b;</a>&rights.intro-point3c;</li>
|
||||
<li>&rights2.intro-point3a;<a href="https://www.mozilla.org/legal/privacy/">&rights2.intro-point3b;</a>&rights.intro-point3c;</li>
|
||||
<li>&rights2.intro-point4a;<a href="about:rights#webservices" onclick="showServices();">&rights.intro-point4b;</a>&rights.intro-point4c;</li>
|
||||
</ul>
|
||||
|
||||
|
@ -188,7 +188,7 @@ pref("extensions.update.enabled", false);
|
||||
pref("extensions.blocklist.enabled", true);
|
||||
pref("extensions.blocklist.interval", 86400);
|
||||
pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/3/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/%PING_COUNT%/%TOTAL_PING_COUNT%/%DAYS_SINCE_LAST_PING%/");
|
||||
pref("extensions.blocklist.detailsURL", "https://www.mozilla.com/%LOCALE%/blocklist/");
|
||||
pref("extensions.blocklist.detailsURL", "https://www.mozilla.org/%LOCALE%/blocklist/");
|
||||
|
||||
/* block popups by default, and notify the user about blocked popups */
|
||||
pref("dom.disable_open_during_load", true);
|
||||
@ -383,7 +383,7 @@ pref("breakpad.reportURL", "https://crash-stats.mozilla.com/report/index/");
|
||||
// TODO: This is not the correct article for metro!!!
|
||||
pref("app.sync.tutorialURL", "https://support.mozilla.org/kb/sync-firefox-between-desktop-and-mobile");
|
||||
pref("app.support.baseURL", "https://support.mozilla.org/1/firefox/%VERSION%/%OS%/%LOCALE%/");
|
||||
pref("app.privacyURL", "http://www.mozilla.com/legal/privacy/");
|
||||
pref("app.privacyURL", "https://www.mozilla.org/legal/privacy/");
|
||||
pref("app.creditsURL", "http://www.mozilla.org/credits/");
|
||||
pref("app.channelURL", "http://www.mozilla.org/%LOCALE%/firefox/channel/");
|
||||
|
||||
|
@ -57,22 +57,24 @@ this.webrtcUI = {
|
||||
}
|
||||
|
||||
function getBrowserForWindowId(aWindowID) {
|
||||
let contentWindow = Services.wm.getOuterWindowWithId(aWindowID);
|
||||
return contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler;
|
||||
return getBrowserForWindow(Services.wm.getOuterWindowWithId(aWindowID));
|
||||
}
|
||||
|
||||
function getBrowserForWindow(aContentWindow) {
|
||||
return aContentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIWebNavigation)
|
||||
.QueryInterface(Ci.nsIDocShell)
|
||||
.chromeEventHandler;
|
||||
}
|
||||
|
||||
function handleRequest(aSubject, aTopic, aData) {
|
||||
let {windowID: windowID, callID: callID} = JSON.parse(aData);
|
||||
|
||||
let browser = getBrowserForWindowId(windowID);
|
||||
let params = aSubject.QueryInterface(Ci.nsIMediaStreamOptions);
|
||||
|
||||
browser.ownerDocument.defaultView.navigator.mozGetUserMediaDevices(
|
||||
Services.wm.getMostRecentWindow(null).navigator.mozGetUserMediaDevices(
|
||||
function (devices) {
|
||||
prompt(browser, callID, params.audio, params.video || params.picture, devices);
|
||||
prompt(windowID, callID, params.audio, params.video || params.picture, devices);
|
||||
},
|
||||
function (error) {
|
||||
// bug 827146 -- In the future, the UI should catch NO_DEVICES_FOUND
|
||||
@ -91,7 +93,7 @@ function denyRequest(aCallID, aError) {
|
||||
Services.obs.notifyObservers(msg, "getUserMedia:response:deny", aCallID);
|
||||
}
|
||||
|
||||
function prompt(aBrowser, aCallID, aAudioRequested, aVideoRequested, aDevices) {
|
||||
function prompt(aWindowID, aCallID, aAudioRequested, aVideoRequested, aDevices) {
|
||||
let audioDevices = [];
|
||||
let videoDevices = [];
|
||||
for (let device of aDevices) {
|
||||
@ -120,8 +122,10 @@ function prompt(aBrowser, aCallID, aAudioRequested, aVideoRequested, aDevices) {
|
||||
return;
|
||||
}
|
||||
|
||||
let host = aBrowser.contentDocument.documentURIObject.asciiHost;
|
||||
let chromeDoc = aBrowser.ownerDocument;
|
||||
let contentWindow = Services.wm.getOuterWindowWithId(aWindowID);
|
||||
let host = contentWindow.document.documentURIObject.asciiHost;
|
||||
let browser = getBrowserForWindow(contentWindow);
|
||||
let chromeDoc = browser.ownerDocument;
|
||||
let chromeWin = chromeDoc.defaultView;
|
||||
let stringBundle = chromeWin.gNavigatorBundle;
|
||||
let message = stringBundle.getFormattedString("getUserMedia.share" + requestType + ".message",
|
||||
@ -195,7 +199,7 @@ function prompt(aBrowser, aCallID, aAudioRequested, aVideoRequested, aDevices) {
|
||||
|
||||
let options = null;
|
||||
|
||||
chromeWin.PopupNotifications.show(aBrowser, "webRTC-shareDevices", message,
|
||||
chromeWin.PopupNotifications.show(browser, "webRTC-shareDevices", message,
|
||||
"webRTC-shareDevices-notification-icon", mainAction,
|
||||
secondaryActions, options);
|
||||
}
|
||||
@ -231,10 +235,8 @@ function showBrowserSpecificIndicator(aBrowser) {
|
||||
|
||||
let chromeWin = aBrowser.ownerDocument.defaultView;
|
||||
let stringBundle = chromeWin.gNavigatorBundle;
|
||||
let host = aBrowser.contentDocument.documentURIObject.asciiHost;
|
||||
|
||||
let message = stringBundle.getFormattedString("getUserMedia.sharing" + captureState + ".message",
|
||||
[ host ]);
|
||||
let message = stringBundle.getString("getUserMedia.sharing" + captureState + ".message2");
|
||||
let mainAction = null;
|
||||
let secondaryActions = null;
|
||||
let options = {
|
||||
|
@ -68,6 +68,7 @@ template<typename T> class Optional;
|
||||
|
||||
namespace JS {
|
||||
class Value;
|
||||
template<typename T> class Handle;
|
||||
}
|
||||
|
||||
#define NODE_FLAG_BIT(n_) (1U << (n_))
|
||||
@ -812,6 +813,7 @@ public:
|
||||
const mozilla::dom::Nullable<bool>& aWantsUntrusted,
|
||||
mozilla::ErrorResult& aRv) MOZ_OVERRIDE;
|
||||
using nsIDOMEventTarget::AddSystemEventListener;
|
||||
virtual nsIDOMWindow* GetOwnerGlobal() MOZ_OVERRIDE;
|
||||
|
||||
/**
|
||||
* Adds a mutation observer to be notified when this node, or any of its
|
||||
@ -1580,7 +1582,8 @@ public:
|
||||
// HasAttributes is defined inline in Element.h.
|
||||
bool HasAttributes() const;
|
||||
nsDOMAttributeMap* GetAttributes();
|
||||
JS::Value SetUserData(JSContext* aCx, const nsAString& aKey, JS::Value aData,
|
||||
JS::Value SetUserData(JSContext* aCx, const nsAString& aKey,
|
||||
JS::Handle<JS::Value> aData,
|
||||
nsIDOMUserDataHandler* aHandler,
|
||||
mozilla::ErrorResult& aError);
|
||||
JS::Value GetUserData(JSContext* aCx, const nsAString& aKey,
|
||||
|
@ -338,8 +338,9 @@ GetParamsForMessage(JSContext* aCx,
|
||||
// properly cases when interface is implemented in JS and used
|
||||
// as a dictionary.
|
||||
nsAutoString json;
|
||||
JS::Value v = aObject;
|
||||
NS_ENSURE_TRUE(JS_Stringify(aCx, &v, nullptr, JSVAL_NULL, JSONCreator, &json), false);
|
||||
JS::Rooted<JS::Value> v(aCx, aObject);
|
||||
NS_ENSURE_TRUE(JS_Stringify(aCx, v.address(), nullptr, JSVAL_NULL,
|
||||
JSONCreator, &json), false);
|
||||
NS_ENSURE_TRUE(!json.IsEmpty(), false);
|
||||
|
||||
JS::Rooted<JS::Value> val(aCx, JS::NullValue());
|
||||
|
@ -104,6 +104,7 @@
|
||||
#include "DocumentType.h"
|
||||
#include <algorithm>
|
||||
#include "nsDOMEvent.h"
|
||||
#include "nsGlobalWindow.h"
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace mozilla::dom;
|
||||
@ -677,11 +678,13 @@ nsINode::SetUserData(const nsAString &aKey, nsIVariant *aData,
|
||||
}
|
||||
|
||||
JS::Value
|
||||
nsINode::SetUserData(JSContext* aCx, const nsAString& aKey, JS::Value aData,
|
||||
nsINode::SetUserData(JSContext* aCx, const nsAString& aKey,
|
||||
JS::Handle<JS::Value> aData,
|
||||
nsIDOMUserDataHandler* aHandler, ErrorResult& aError)
|
||||
{
|
||||
nsCOMPtr<nsIVariant> data;
|
||||
aError = nsContentUtils::XPConnect()->JSValToVariant(aCx, &aData,
|
||||
JS::Rooted<JS::Value> dataVal(aCx, aData);
|
||||
aError = nsContentUtils::XPConnect()->JSValToVariant(aCx, dataVal.address(),
|
||||
getter_AddRefs(data));
|
||||
if (aError.Failed()) {
|
||||
return JS::UndefinedValue();
|
||||
@ -1163,6 +1166,14 @@ nsINode::GetContextForEventHandlers(nsresult* aRv)
|
||||
return nsContentUtils::GetContextForEventHandlers(this, aRv);
|
||||
}
|
||||
|
||||
nsIDOMWindow*
|
||||
nsINode::GetOwnerGlobal()
|
||||
{
|
||||
bool dummy;
|
||||
return nsPIDOMWindow::GetOuterFromCurrentInner(
|
||||
static_cast<nsGlobalWindow*>(OwnerDoc()->GetScriptHandlingObject(dummy)));
|
||||
}
|
||||
|
||||
bool
|
||||
nsINode::UnoptimizableCCNode() const
|
||||
{
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include "nsIAtom.h"
|
||||
|
||||
class nsDOMEvent;
|
||||
class nsIDOMWindow;
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -64,6 +65,11 @@ public:
|
||||
virtual void EventListenerAdded(nsIAtom* aType) {}
|
||||
virtual void EventListenerRemoved(nsIAtom* aType) {}
|
||||
|
||||
// Returns an outer window that corresponds to the inner window this event
|
||||
// target is associated with. Will return null if the inner window is not the
|
||||
// current inner or if there is no window around at all.
|
||||
virtual nsIDOMWindow* GetOwnerGlobal() = 0;
|
||||
|
||||
protected:
|
||||
EventHandlerNonNull* GetEventHandler(nsIAtom* aType);
|
||||
void SetEventHandler(nsIAtom* aType, EventHandlerNonNull* aHandler,
|
||||
|
@ -60,7 +60,8 @@ nsDOMDataContainerEvent::SetData(const nsAString& aKey, nsIVariant *aData)
|
||||
|
||||
void
|
||||
nsDOMDataContainerEvent::SetData(JSContext* aCx, const nsAString& aKey,
|
||||
JS::Value aVal, mozilla::ErrorResult& aRv)
|
||||
JS::Handle<JS::Value> aVal,
|
||||
mozilla::ErrorResult& aRv)
|
||||
{
|
||||
if (!nsContentUtils::XPConnect()) {
|
||||
aRv = NS_ERROR_FAILURE;
|
||||
|
@ -39,8 +39,8 @@ public:
|
||||
return val.forget();
|
||||
}
|
||||
|
||||
void SetData(JSContext* aCx, const nsAString& aKey, JS::Value aVal,
|
||||
mozilla::ErrorResult& aRv);
|
||||
void SetData(JSContext* aCx, const nsAString& aKey,
|
||||
JS::Handle<JS::Value> aVal, mozilla::ErrorResult& aRv);
|
||||
|
||||
private:
|
||||
static PLDHashOperator
|
||||
|
@ -95,6 +95,10 @@ public:
|
||||
JSContext* aCx,
|
||||
JS::Value* aValue);
|
||||
using mozilla::dom::EventTarget::GetEventHandler;
|
||||
virtual nsIDOMWindow* GetOwnerGlobal() MOZ_OVERRIDE
|
||||
{
|
||||
return nsPIDOMWindow::GetOuterFromCurrentInner(GetOwner());
|
||||
}
|
||||
|
||||
nsresult CheckInnerWindowCorrectness()
|
||||
{
|
||||
|
@ -54,7 +54,7 @@ public:
|
||||
const nsAString& aType,
|
||||
bool aCanBubble,
|
||||
bool aCancelable,
|
||||
JS::Value aData,
|
||||
JS::Handle<JS::Value> aData,
|
||||
const nsAString& aOrigin,
|
||||
const nsAString& aLastEventId,
|
||||
nsIDOMWindow* aSource,
|
||||
|
@ -48,8 +48,8 @@ public:
|
||||
|
||||
JSObject* GetFrameBuffer(JSContext* aCx, mozilla::ErrorResult& aRv)
|
||||
{
|
||||
JS::Value dummy;
|
||||
aRv = GetFrameBuffer(aCx, &dummy);
|
||||
JS::Rooted<JS::Value> dummy(aCx);
|
||||
aRv = GetFrameBuffer(aCx, dummy.address());
|
||||
return mCachedArray;
|
||||
}
|
||||
|
||||
|
@ -724,7 +724,7 @@ nsresult
|
||||
HTMLCanvasElement::GetContext(const nsAString& aContextId,
|
||||
nsISupports** aContext)
|
||||
{
|
||||
return GetContext(aContextId, JS::UndefinedValue(), nullptr, aContext);
|
||||
return GetContext(aContextId, JS::UndefinedHandleValue, nullptr, aContext);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
|
@ -404,7 +404,7 @@ DecoderTraits::CreateDecoder(const nsACString& aType, MediaDecoderOwner* aOwner)
|
||||
if (IsOmxSupportedType(aType)) {
|
||||
// AMR audio is enabled for MMS, but we are discouraging Web and App
|
||||
// developers from using AMR, thus we only allow AMR to be played on WebApps.
|
||||
if (aType.EqualsASCII("audio/amr") || aType.EqualsASCII("video/3gpp")) {
|
||||
if (aType.EqualsASCII("audio/amr")) {
|
||||
HTMLMediaElement* element = aOwner->GetMediaElement();
|
||||
if (!element) {
|
||||
return nullptr;
|
||||
|
@ -1443,7 +1443,8 @@ MediaStreamGraphImpl::AppendMessage(ControlMessage* aMessage)
|
||||
// This should only happen during forced shutdown.
|
||||
aMessage->RunDuringShutdown();
|
||||
delete aMessage;
|
||||
if (IsEmpty()) {
|
||||
if (IsEmpty() &&
|
||||
mLifecycleState >= LIFECYCLE_WAITING_FOR_STREAM_DESTRUCTION) {
|
||||
if (gGraph == this) {
|
||||
gGraph = nullptr;
|
||||
}
|
||||
|
14
content/media/test/crashtests/868504.html
Normal file
14
content/media/test/crashtests/868504.html
Normal file
@ -0,0 +1,14 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
AudioContext().createBufferSource().playbackRate.linearRampToValueAtTime(0, -1);
|
||||
}
|
||||
|
||||
</script>
|
||||
</head>
|
||||
<body onload="boom();"></body>
|
||||
</html>
|
5
content/media/test/crashtests/876024-1.html
Normal file
5
content/media/test/crashtests/876024-1.html
Normal file
@ -0,0 +1,5 @@
|
||||
<script>
|
||||
o1 = new window.AudioContext(2, 8, 44100);
|
||||
o4 = o1.createBiquadFilter();
|
||||
o4.detune.setValueAtTime(0.0843, 1.7976931348623157e+308);
|
||||
</script>
|
17
content/media/test/crashtests/876024-2.html
Normal file
17
content/media/test/crashtests/876024-2.html
Normal file
@ -0,0 +1,17 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<script>
|
||||
|
||||
function boom()
|
||||
{
|
||||
var bufferSource = AudioContext().createScriptProcessor().context.createBufferSource();
|
||||
bufferSource.noteGrainOn(0, 0, 0);
|
||||
bufferSource.noteOff(562949953421313);
|
||||
}
|
||||
|
||||
</script></head>
|
||||
|
||||
<body onload="boom();"></body>
|
||||
</html>
|
4
content/media/test/crashtests/877820.html
Normal file
4
content/media/test/crashtests/877820.html
Normal file
@ -0,0 +1,4 @@
|
||||
<script>
|
||||
o1 = new window.OfflineAudioContext(2, 5, 0.39);
|
||||
window.location.reload();
|
||||
</script>
|
@ -15,6 +15,7 @@ skip-if(Android||B2G) load 789075-1.html # load failed, bug 833371 for B2G
|
||||
load 844563.html
|
||||
load 846612.html
|
||||
load 852838.html
|
||||
load 868504.html
|
||||
load 874869.html
|
||||
load 874915.html
|
||||
load 874934.html
|
||||
@ -22,9 +23,12 @@ load 874952.html
|
||||
load 875144.html
|
||||
load 875596.html
|
||||
load 875911.html
|
||||
load 876024-1.html
|
||||
load 876024-2.html
|
||||
load 876118.html
|
||||
load 876207.html
|
||||
load 876215.html
|
||||
load 876249.html
|
||||
load 876252.html
|
||||
load 876834.html
|
||||
load 877820.html
|
||||
|
@ -480,6 +480,12 @@ void
|
||||
AudioBufferSourceNode::Start(double aWhen, double aOffset,
|
||||
const Optional<double>& aDuration, ErrorResult& aRv)
|
||||
{
|
||||
if (!WebAudioUtils::IsTimeValid(aWhen) ||
|
||||
(aDuration.WasPassed() && !WebAudioUtils::IsTimeValid(aDuration.Value()))) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mStartCalled) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
@ -567,6 +573,11 @@ AudioBufferSourceNode::SendOffsetAndDurationParametersToStream(AudioNodeStream*
|
||||
void
|
||||
AudioBufferSourceNode::Stop(double aWhen, ErrorResult& aRv, bool aShuttingDown)
|
||||
{
|
||||
if (!WebAudioUtils::IsTimeValid(aWhen)) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mStartCalled) {
|
||||
aRv.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
|
@ -106,7 +106,7 @@ AudioContext::Constructor(const GlobalObject& aGlobal,
|
||||
if (aNumberOfChannels == 0 ||
|
||||
aNumberOfChannels > WebAudioUtils::MaxChannelCount ||
|
||||
aLength == 0 ||
|
||||
aSampleRate <= 0.0f ||
|
||||
aSampleRate <= 1.0f ||
|
||||
aSampleRate >= TRACK_RATE_MAX) {
|
||||
// The DOM binding protects us against infinity and NaN
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
|
@ -72,21 +72,38 @@ public:
|
||||
}
|
||||
void SetValueAtTime(float aValue, double aStartTime, ErrorResult& aRv)
|
||||
{
|
||||
if (!WebAudioUtils::IsTimeValid(aStartTime)) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
AudioParamTimeline::SetValueAtTime(aValue, aStartTime, aRv);
|
||||
mCallback(mNode);
|
||||
}
|
||||
void LinearRampToValueAtTime(float aValue, double aEndTime, ErrorResult& aRv)
|
||||
{
|
||||
if (!WebAudioUtils::IsTimeValid(aEndTime)) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
AudioParamTimeline::LinearRampToValueAtTime(aValue, aEndTime, aRv);
|
||||
mCallback(mNode);
|
||||
}
|
||||
void ExponentialRampToValueAtTime(float aValue, double aEndTime, ErrorResult& aRv)
|
||||
{
|
||||
if (!WebAudioUtils::IsTimeValid(aEndTime)) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
AudioParamTimeline::ExponentialRampToValueAtTime(aValue, aEndTime, aRv);
|
||||
mCallback(mNode);
|
||||
}
|
||||
void SetTargetAtTime(float aTarget, double aStartTime, double aTimeConstant, ErrorResult& aRv)
|
||||
{
|
||||
if (!WebAudioUtils::IsTimeValid(aStartTime) ||
|
||||
!WebAudioUtils::IsTimeValid(aTimeConstant)) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
AudioParamTimeline::SetTargetAtTime(aTarget, aStartTime, aTimeConstant, aRv);
|
||||
mCallback(mNode);
|
||||
}
|
||||
@ -94,8 +111,12 @@ public:
|
||||
{
|
||||
SetTargetAtTime(aTarget, aStartTime, aTimeConstant, aRv);
|
||||
}
|
||||
void CancelScheduledValues(double aStartTime)
|
||||
void CancelScheduledValues(double aStartTime, ErrorResult& aRv)
|
||||
{
|
||||
if (!WebAudioUtils::IsTimeValid(aStartTime)) {
|
||||
aRv.Throw(NS_ERROR_DOM_NOT_SUPPORTED_ERR);
|
||||
return;
|
||||
}
|
||||
AudioParamTimeline::CancelScheduledValues(aStartTime);
|
||||
mCallback(mNode);
|
||||
}
|
||||
|
@ -116,7 +116,7 @@ public:
|
||||
if (!mBuffer.SetLength(aNumberOfChannels)) {
|
||||
return false;
|
||||
}
|
||||
const int32_t numFrames = NS_lround(mMaxDelay) * aSampleRate;
|
||||
const int32_t numFrames = NS_lround(mMaxDelay * aSampleRate);
|
||||
for (uint32_t channel = 0; channel < aNumberOfChannels; ++channel) {
|
||||
if (!mBuffer[channel].SetLength(numFrames)) {
|
||||
return false;
|
||||
|
@ -23,7 +23,7 @@ namespace dom {
|
||||
struct WebAudioUtils {
|
||||
// This is an arbitrary large number used to protect against OOMs.
|
||||
// We can adjust it later if needed.
|
||||
static const uint32_t MaxChannelCount = 10000;
|
||||
static const uint32_t MaxChannelCount = 32;
|
||||
|
||||
static bool FuzzyEqual(float v1, float v2)
|
||||
{
|
||||
@ -104,6 +104,11 @@ struct WebAudioUtils {
|
||||
return 1.0 - std::exp(-1.0 / (sampleRate * timeConstant));
|
||||
}
|
||||
|
||||
static bool IsTimeValid(double aTime)
|
||||
{
|
||||
return aTime >= 0 && aTime <= (MEDIA_TIME_MAX >> MEDIA_TIME_FRAC_BITS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a stream position into the time coordinate of the destination
|
||||
* stream.
|
||||
|
@ -53,6 +53,7 @@ MOCHITEST_FILES := \
|
||||
test_channelSplitterNodeWithVolume.html \
|
||||
test_currentTime.html \
|
||||
test_delayNode.html \
|
||||
test_delayNodeSmallMaxDelay.html \
|
||||
test_delayNodeWithGain.html \
|
||||
test_delayNodeWithGainAlternate.html \
|
||||
test_dynamicsCompressorNode.html \
|
||||
|
@ -32,9 +32,9 @@ addLoadEvent(function() {
|
||||
expectException(function() {
|
||||
new OfflineAudioContext(0, 100, 44100);
|
||||
}, DOMException.NOT_SUPPORTED_ERR);
|
||||
new OfflineAudioContext(10000, 100, 44100);
|
||||
new OfflineAudioContext(32, 100, 44100);
|
||||
expectException(function() {
|
||||
new OfflineAudioContext(10001, 100, 44100);
|
||||
new OfflineAudioContext(33, 100, 44100);
|
||||
}, DOMException.NOT_SUPPORTED_ERR);
|
||||
expectException(function() {
|
||||
new OfflineAudioContext(2, 0, 44100);
|
||||
|
43
content/media/webaudio/test/test_delayNodeSmallMaxDelay.html
Normal file
43
content/media/webaudio/test/test_delayNodeSmallMaxDelay.html
Normal file
@ -0,0 +1,43 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test DelayNode</title>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script src="webaudio.js" type="text/javascript"></script>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
var gTest = {
|
||||
length: 2048,
|
||||
numberOfChannels: 1,
|
||||
createGraph: function(context) {
|
||||
var source = context.createBufferSource();
|
||||
|
||||
var delay = context.createDelay(0.02);
|
||||
|
||||
source.buffer = this.buffer;
|
||||
|
||||
source.connect(delay);
|
||||
|
||||
source.start(0);
|
||||
return delay;
|
||||
},
|
||||
createExpectedBuffers: function(context) {
|
||||
var expectedBuffer = context.createBuffer(1, 2048, context.sampleRate);
|
||||
for (var i = 0; i < 2048; ++i) {
|
||||
expectedBuffer.getChannelData(0)[i] = Math.sin(440 * 2 * Math.PI * i / context.sampleRate);
|
||||
}
|
||||
this.buffer = expectedBuffer;
|
||||
return expectedBuffer;
|
||||
},
|
||||
};
|
||||
|
||||
runTest();
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
@ -48,10 +48,13 @@ WMFReader::WMFReader(AbstractMediaDecoder* aDecoder)
|
||||
mVideoWidth(0),
|
||||
mVideoHeight(0),
|
||||
mVideoStride(0),
|
||||
mAudioFrameSum(0),
|
||||
mAudioFrameOffset(0),
|
||||
mHasAudio(false),
|
||||
mHasVideo(false),
|
||||
mCanSeek(false),
|
||||
mUseHwAccel(false),
|
||||
mMustRecaptureAudioPosition(true),
|
||||
mIsMP3Enabled(WMFDecoder::IsMP3Supported())
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Must be on main thread.");
|
||||
@ -605,6 +608,31 @@ GetSampleDuration(IMFSample* aSample)
|
||||
return HNsToUsecs(duration);
|
||||
}
|
||||
|
||||
HRESULT
|
||||
HNsToFrames(int64_t aHNs, uint32_t aRate, int64_t* aOutFrames)
|
||||
{
|
||||
MOZ_ASSERT(aOutFrames);
|
||||
const int64_t HNS_PER_S = USECS_PER_S * 10;
|
||||
CheckedInt<int64_t> i = aHNs;
|
||||
i *= aRate;
|
||||
i /= HNS_PER_S;
|
||||
NS_ENSURE_TRUE(i.isValid(), E_FAIL);
|
||||
*aOutFrames = i.value();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
HRESULT
|
||||
FramesToUsecs(int64_t aSamples, uint32_t aRate, int64_t* aOutUsecs)
|
||||
{
|
||||
MOZ_ASSERT(aOutUsecs);
|
||||
CheckedInt<int64_t> i = aSamples;
|
||||
i *= USECS_PER_S;
|
||||
i /= aRate;
|
||||
NS_ENSURE_TRUE(i.isValid(), E_FAIL);
|
||||
*aOutUsecs = i.value();
|
||||
return S_OK;
|
||||
}
|
||||
|
||||
bool
|
||||
WMFReader::DecodeAudioData()
|
||||
{
|
||||
@ -660,11 +688,33 @@ WMFReader::DecodeAudioData()
|
||||
memcpy(pcmSamples.get(), data, currentLength);
|
||||
buffer->Unlock();
|
||||
|
||||
int64_t offset = mDecoder->GetResource()->Tell();
|
||||
int64_t timestamp = HNsToUsecs(timestampHns);
|
||||
int64_t duration = GetSampleDuration(sample);
|
||||
// We calculate the timestamp and the duration based on the number of audio
|
||||
// frames we've already played. We don't trust the timestamp stored on the
|
||||
// IMFSample, as sometimes it's wrong, possibly due to buggy encoders?
|
||||
|
||||
mAudioQueue.Push(new AudioData(offset,
|
||||
// If this sample block comes after a discontinuity (i.e. a gap or seek)
|
||||
// reset the frame counters, and capture the timestamp. Future timestamps
|
||||
// will be offset from this block's timestamp.
|
||||
UINT32 discontinuity = false;
|
||||
sample->GetUINT32(MFSampleExtension_Discontinuity, &discontinuity);
|
||||
if (mMustRecaptureAudioPosition || discontinuity) {
|
||||
mAudioFrameSum = 0;
|
||||
hr = HNsToFrames(timestampHns, mAudioRate, &mAudioFrameOffset);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
|
||||
mMustRecaptureAudioPosition = false;
|
||||
}
|
||||
|
||||
int64_t timestamp;
|
||||
hr = FramesToUsecs(mAudioFrameOffset + mAudioFrameSum, mAudioRate, ×tamp);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
|
||||
|
||||
mAudioFrameSum += numFrames;
|
||||
|
||||
int64_t duration;
|
||||
hr = FramesToUsecs(numFrames, mAudioRate, &duration);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), false);
|
||||
|
||||
mAudioQueue.Push(new AudioData(mDecoder->GetResource()->Tell(),
|
||||
timestamp,
|
||||
duration,
|
||||
numFrames,
|
||||
@ -901,7 +951,7 @@ WMFReader::DecodeVideoFrame(bool &aKeyframeSkip,
|
||||
|
||||
#ifdef LOG_SAMPLE_DECODE
|
||||
LOG("Decoded video sample timestamp=%lld duration=%lld stride=%d height=%u flags=%u",
|
||||
timestamp, duration, stride, mVideoHeight, flags);
|
||||
timestamp, duration, mVideoStride, mVideoHeight, flags);
|
||||
#endif
|
||||
|
||||
if ((flags & MF_SOURCE_READERF_ENDOFSTREAM)) {
|
||||
@ -930,6 +980,12 @@ WMFReader::Seek(int64_t aTargetUs,
|
||||
nsresult rv = ResetDecode();
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
// Mark that we must recapture the audio frame count from the next sample.
|
||||
// WMF doesn't set a discontinuity marker when we seek to time 0, so we
|
||||
// must remember to recapture the audio frame offset and reset the frame
|
||||
// sum on the next audio packet we decode.
|
||||
mMustRecaptureAudioPosition = true;
|
||||
|
||||
AutoPropVar var;
|
||||
HRESULT hr = InitPropVariantFromInt64(UsecsToHNs(aTargetUs), &var);
|
||||
NS_ENSURE_TRUE(SUCCEEDED(hr), NS_ERROR_FAILURE);
|
||||
|
@ -91,6 +91,17 @@ private:
|
||||
uint32_t mVideoHeight;
|
||||
uint32_t mVideoStride;
|
||||
|
||||
// The offset, in audio frames, at which playback started since the
|
||||
// last discontinuity.
|
||||
int64_t mAudioFrameOffset;
|
||||
// The number of audio frames that we've played since the last
|
||||
// discontinuity.
|
||||
int64_t mAudioFrameSum;
|
||||
// True if we need to re-initialize mAudioFrameOffset and mAudioFrameSum
|
||||
// from the next audio packet we decode. This happens after a seek, since
|
||||
// WMF doesn't mark a stream as having a discontinuity after a seek(0).
|
||||
bool mMustRecaptureAudioPosition;
|
||||
|
||||
bool mHasAudio;
|
||||
bool mHasVideo;
|
||||
bool mCanSeek;
|
||||
|
@ -92,11 +92,15 @@ this.AlarmService = {
|
||||
},
|
||||
set _currentAlarm(aAlarm) {
|
||||
this._alarm = aAlarm;
|
||||
if (!aAlarm)
|
||||
if (!aAlarm) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._alarmHalService.setAlarm(this._getAlarmTime(aAlarm) / 1000, 0))
|
||||
let alarmTimeInMs = this._getAlarmTime(aAlarm);
|
||||
let ns = (alarmTimeInMs % 1000) * 1000000;
|
||||
if (!this._alarmHalService.setAlarm(alarmTimeInMs / 1000, ns)) {
|
||||
throw Components.results.NS_ERROR_FAILURE;
|
||||
}
|
||||
},
|
||||
|
||||
receiveMessage: function receiveMessage(aMessage) {
|
||||
|
@ -590,6 +590,7 @@ WebappsApplication.prototype = {
|
||||
this.progress = app.progress || msg.progress || 0;
|
||||
this.readyToApplyDownload = app.readyToApplyDownload;
|
||||
this.updateTime = app.updateTime;
|
||||
this.origin = app.origin;
|
||||
|
||||
switch(msg.type) {
|
||||
case "error":
|
||||
|
@ -84,6 +84,11 @@ this.DOMApplicationRegistry = {
|
||||
webapps: { },
|
||||
children: [ ],
|
||||
allAppsLaunchable: false,
|
||||
#ifdef MOZ_OFFICIAL_BRANDING
|
||||
get allowSideloadingCertified() false,
|
||||
#else
|
||||
get allowSideloadingCertified() true,
|
||||
#endif
|
||||
|
||||
init: function() {
|
||||
this.messages = ["Webapps:Install", "Webapps:Uninstall",
|
||||
@ -127,6 +132,10 @@ this.DOMApplicationRegistry = {
|
||||
let appDir = FileUtils.getDir(DIRECTORY_NAME, ["webapps"], false);
|
||||
for (let id in this.webapps) {
|
||||
let app = this.webapps[id];
|
||||
if (!app) {
|
||||
delete this.webapps[id];
|
||||
continue;
|
||||
}
|
||||
|
||||
app.id = id;
|
||||
|
||||
@ -1136,6 +1145,8 @@ this.DOMApplicationRegistry = {
|
||||
DOMApplicationRegistry._writeFile(manFile,
|
||||
JSON.stringify(aManifest),
|
||||
function() { });
|
||||
|
||||
app = DOMApplicationRegistry.webapps[aId];
|
||||
// Set state and fire events.
|
||||
app.downloading = false;
|
||||
app.downloadAvailable = false;
|
||||
@ -2044,7 +2055,7 @@ this.DOMApplicationRegistry = {
|
||||
manifest = new ManifestHelper(jsonManifest, app.manifestURL);
|
||||
this.downloadPackage(manifest, appObject, false, (function(aId, aManifest) {
|
||||
// Success! Move the zip out of TmpD.
|
||||
let app = DOMApplicationRegistry.webapps[id];
|
||||
let app = DOMApplicationRegistry.webapps[aId];
|
||||
let zipFile = FileUtils.getFile("TmpD", ["webapps", aId, "application.zip"], true);
|
||||
let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", aId], true, true);
|
||||
zipFile.moveTo(dir, "application.zip");
|
||||
@ -2552,15 +2563,65 @@ this.DOMApplicationRegistry = {
|
||||
app.appStatus = AppsUtils.getAppManifestStatus(manifest);
|
||||
}
|
||||
|
||||
// Check if the app declares which origin it will use.
|
||||
if (isSigned &&
|
||||
app.appStatus >= Ci.nsIPrincipal.APP_STATUS_PRIVILEGED &&
|
||||
manifest.origin !== undefined) {
|
||||
|
||||
let uri;
|
||||
try {
|
||||
uri = Services.io.newURI(manifest.origin, null, null);
|
||||
} catch(e) {
|
||||
throw "INVALID_ORIGIN";
|
||||
}
|
||||
|
||||
if (uri.scheme != "app") {
|
||||
throw "INVALID_ORIGIN";
|
||||
}
|
||||
|
||||
// Changing the origin during an update is not allowed.
|
||||
if (aIsUpdate && uri.prePath != app.origin) {
|
||||
throw "INVALID_ORIGIN_CHANGE";
|
||||
}
|
||||
|
||||
debug("Setting origin to " + uri.prePath +
|
||||
" for " + app.manifestURL);
|
||||
let newId = uri.prePath.substring(6); // "app://".length
|
||||
|
||||
if (newId in self.webapps) {
|
||||
throw "DUPLICATE_ORIGIN";
|
||||
}
|
||||
app.origin = uri.prePath;
|
||||
|
||||
// Update the registry.
|
||||
app.id = newId;
|
||||
self.webapps[newId] = app;
|
||||
delete self.webapps[id];
|
||||
|
||||
// Rename the directories where the files are installed.
|
||||
[DIRECTORY_NAME, "TmpD"].forEach(function(aDir) {
|
||||
let parent = FileUtils.getDir(aDir,
|
||||
["webapps"], true, true);
|
||||
let dir = FileUtils.getDir(aDir,
|
||||
["webapps", id], true, true);
|
||||
dir.moveTo(parent, newId);
|
||||
});
|
||||
|
||||
// Signals that we need to swap the old id with the new app.
|
||||
self.broadcastMessage("Webapps:RemoveApp", { id: id });
|
||||
self.broadcastMessage("Webapps:AddApp", { id: newId,
|
||||
app: app });
|
||||
}
|
||||
|
||||
if (aOnSuccess) {
|
||||
aOnSuccess(id, manifest);
|
||||
aOnSuccess(app.id, manifest);
|
||||
}
|
||||
} catch (e) {
|
||||
// Something bad happened when reading the package.
|
||||
// Unrecoverable error, don't bug the user.
|
||||
// Apps with installState 'pending' does not produce any
|
||||
// notification, so we are safe with its current
|
||||
// downladAvailable state.
|
||||
// downloadAvailable state.
|
||||
if (app.installState !== "pending") {
|
||||
app.downloadAvailable = false;
|
||||
}
|
||||
|
@ -3,5 +3,3 @@ head =
|
||||
tail =
|
||||
|
||||
[test_manifestSanitizer.js]
|
||||
[test_webappsActor.js]
|
||||
run-if = toolkit == "gonk"
|
||||
|
@ -68,7 +68,7 @@ IndexedDBHelper.prototype = {
|
||||
};
|
||||
req.onerror = function (aEvent) {
|
||||
if (DEBUG) debug("Failed to open database:" + self.dbName);
|
||||
aFailureCb(aEvent.target.errorMessage);
|
||||
aFailureCb(aEvent.target.error.name);
|
||||
};
|
||||
req.onblocked = function (aEvent) {
|
||||
if (DEBUG) debug("Opening database request is blocked.");
|
||||
|
@ -7072,8 +7072,9 @@ nsGlobalWindow::FinalClose()
|
||||
// round-trips to the event loop before the call to ReallyCloseWindow. This
|
||||
// allows setTimeout handlers that are set after FinalClose() is called to
|
||||
// run before the window is torn down.
|
||||
bool indirect = nsContentUtils::GetCurrentJSContext() ==
|
||||
GetContextInternal()->GetNativeContext();
|
||||
bool indirect = GetContextInternal() && // Occasionally null. See bug 877390.
|
||||
(nsContentUtils::GetCurrentJSContext() ==
|
||||
GetContextInternal()->GetNativeContext());
|
||||
if ((!indirect && nsContentUtils::IsCallerChrome()) ||
|
||||
NS_FAILED(nsCloseEvent::PostCloseEvent(this, indirect))) {
|
||||
ReallyCloseWindow();
|
||||
|
@ -392,6 +392,14 @@ public:
|
||||
bool aUseCapture,
|
||||
const mozilla::dom::Nullable<bool>& aWantsUntrusted,
|
||||
mozilla::ErrorResult& aRv) MOZ_OVERRIDE;
|
||||
virtual nsIDOMWindow* GetOwnerGlobal() MOZ_OVERRIDE
|
||||
{
|
||||
if (IsOuterWindow()) {
|
||||
return this;
|
||||
}
|
||||
|
||||
return GetOuterFromCurrentInner(this);
|
||||
}
|
||||
|
||||
// nsITouchEventReceiver
|
||||
NS_DECL_NSITOUCHEVENTRECEIVER
|
||||
|
@ -58,8 +58,8 @@ class AudioContext;
|
||||
}
|
||||
|
||||
#define NS_PIDOMWINDOW_IID \
|
||||
{ 0x7202842a, 0x0e24, 0x46dc, \
|
||||
{ 0xb2, 0x25, 0xd2, 0x9d, 0x28, 0xda, 0x87, 0xd8 } }
|
||||
{ 0xc7f20d00, 0xed38, 0x4d60, \
|
||||
{ 0x90, 0xf6, 0x3e, 0xde, 0x7b, 0x71, 0xc3, 0xb3 } }
|
||||
|
||||
class nsPIDOMWindow : public nsIDOMWindowInternal
|
||||
{
|
||||
@ -645,6 +645,22 @@ public:
|
||||
|
||||
void AddAudioContext(mozilla::dom::AudioContext* aAudioContext);
|
||||
|
||||
// Given an inner window, return its outer if the inner is the current inner.
|
||||
// Otherwise (argument null or not an inner or not current) return null.
|
||||
static nsPIDOMWindow* GetOuterFromCurrentInner(nsPIDOMWindow* aInner)
|
||||
{
|
||||
if (!aInner) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsPIDOMWindow* outer = aInner->GetOuterWindow();
|
||||
if (!outer || outer->GetCurrentInnerWindow() != aInner) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return outer;
|
||||
}
|
||||
|
||||
// WebIDL-ish APIs
|
||||
nsPerformance* GetPerformance();
|
||||
|
||||
|
@ -15,10 +15,9 @@ class nsIControllers;
|
||||
class nsIController;
|
||||
struct JSContext;
|
||||
|
||||
// 426C1B56-E38A-435E-B291-BE1557F2A0A2
|
||||
#define NS_IWINDOWROOT_IID \
|
||||
{ 0xc89780f2, 0x8905, 0x417f, \
|
||||
{ 0xa6, 0x62, 0xf6, 0xc, 0xa6, 0xd7, 0xc, 0x91 } }
|
||||
{ 0x3f71f50c, 0xa7e0, 0x43bc, \
|
||||
{ 0xac, 0x25, 0x4d, 0xbb, 0x88, 0x7b, 0x21, 0x09 } }
|
||||
|
||||
class nsPIWindowRoot : public mozilla::dom::EventTarget
|
||||
{
|
||||
@ -37,6 +36,7 @@ public:
|
||||
|
||||
virtual void SetParentTarget(mozilla::dom::EventTarget* aTarget) = 0;
|
||||
virtual mozilla::dom::EventTarget* GetParentTarget() = 0;
|
||||
virtual nsIDOMWindow* GetOwnerGlobal() MOZ_OVERRIDE = 0;
|
||||
};
|
||||
|
||||
NS_DEFINE_STATIC_IID_ACCESSOR(nsPIWindowRoot, NS_IWINDOWROOT_IID)
|
||||
|
@ -179,6 +179,12 @@ nsWindowRoot::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsIDOMWindow*
|
||||
nsWindowRoot::GetOwnerGlobal()
|
||||
{
|
||||
return GetWindow();
|
||||
}
|
||||
|
||||
nsPIDOMWindow*
|
||||
nsWindowRoot::GetWindow()
|
||||
{
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
mParent = aTarget;
|
||||
}
|
||||
virtual mozilla::dom::EventTarget* GetParentTarget() { return mParent; }
|
||||
virtual nsIDOMWindow* GetOwnerGlobal() MOZ_OVERRIDE;
|
||||
|
||||
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_AMBIGUOUS(nsWindowRoot,
|
||||
nsIDOMEventTarget)
|
||||
|
@ -599,8 +599,6 @@ DOMInterfaces = {
|
||||
|
||||
'MediaStreamList': {
|
||||
'headerFile': 'MediaStreamList.h',
|
||||
'wrapperCache': False,
|
||||
'nativeOwnership': 'owned',
|
||||
'resultNotAddRefed': [ '__indexedGetter' ],
|
||||
'binaryNames': { '__indexedGetter': 'IndexedGetter' }
|
||||
},
|
||||
@ -1213,6 +1211,17 @@ DOMInterfaces = {
|
||||
'nativeType': 'mozilla::dom::DOMWheelEvent',
|
||||
},
|
||||
|
||||
'WindowProxy': [
|
||||
{
|
||||
'nativeType': 'nsIDOMWindow',
|
||||
'concrete': False
|
||||
},
|
||||
{
|
||||
# We need a worker descriptor for WindowProxy because EventTarget exists in
|
||||
# workers. But it's an external interface, so it'll just map to JSObject*.
|
||||
'workers': True
|
||||
}],
|
||||
|
||||
'XMLHttpRequest': [
|
||||
{
|
||||
'nativeType': 'nsXMLHttpRequest',
|
||||
@ -1616,7 +1625,6 @@ addExternalIface('URI', nativeType='nsIURI', headerFile='nsIURI.h',
|
||||
notflattened=True)
|
||||
addExternalIface('UserDataHandler')
|
||||
addExternalIface('Window')
|
||||
addExternalIface('WindowProxy', nativeType='nsIDOMWindow')
|
||||
addExternalIface('XPathResult', nativeType='nsISupports')
|
||||
addExternalIface('XPathExpression')
|
||||
addExternalIface('XPathNSResolver')
|
||||
|
@ -5104,7 +5104,7 @@ class CGGenericMethod(CGAbstractBindingMethod):
|
||||
return CGIndenter(CGGeneric(
|
||||
"const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
|
||||
"MOZ_ASSERT(info->type == JSJitInfo::Method);\n"
|
||||
"JSJitMethodOp method = (JSJitMethodOp)info->op;\n"
|
||||
"JSJitMethodOp method = info->method;\n"
|
||||
"return method(cx, obj, self, argc, vp);"))
|
||||
|
||||
class CGSpecializedMethod(CGAbstractStaticMethod):
|
||||
@ -5240,7 +5240,7 @@ class CGGenericGetter(CGAbstractBindingMethod):
|
||||
return CGIndenter(CGGeneric(
|
||||
"const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
|
||||
"MOZ_ASSERT(info->type == JSJitInfo::Getter);\n"
|
||||
"JSJitPropertyOp getter = info->op;\n"
|
||||
"JSJitGetterOp getter = info->getter;\n"
|
||||
"return getter(cx, obj, self, vp);"))
|
||||
|
||||
class CGSpecializedGetter(CGAbstractStaticMethod):
|
||||
@ -5324,7 +5324,7 @@ class CGGenericSetter(CGAbstractBindingMethod):
|
||||
"JS::Value* argv = JS_ARGV(cx, vp);\n"
|
||||
"const JSJitInfo *info = FUNCTION_VALUE_TO_JITINFO(JS_CALLEE(cx, vp));\n"
|
||||
"MOZ_ASSERT(info->type == JSJitInfo::Setter);\n"
|
||||
"JSJitPropertyOp setter = info->op;\n"
|
||||
"JSJitSetterOp setter = info->setter;\n"
|
||||
"if (!setter(cx, obj, self, argv)) {\n"
|
||||
" return false;\n"
|
||||
"}\n"
|
||||
@ -5431,7 +5431,7 @@ class CGMemberJITInfo(CGThing):
|
||||
"")
|
||||
return ("\n"
|
||||
"static const JSJitInfo %s = {\n"
|
||||
" %s,\n"
|
||||
" { %s },\n"
|
||||
" %s,\n"
|
||||
" %s,\n"
|
||||
" JSJitInfo::%s,\n"
|
||||
@ -5445,7 +5445,9 @@ class CGMemberJITInfo(CGThing):
|
||||
def define(self):
|
||||
if self.member.isAttr():
|
||||
getterinfo = ("%s_getterinfo" % self.member.identifier.name)
|
||||
getter = ("(JSJitPropertyOp)get_%s" % self.member.identifier.name)
|
||||
# We need the cast here because JSJitGetterOp has a "void* self"
|
||||
# while we have the right type.
|
||||
getter = ("(JSJitGetterOp)get_%s" % self.member.identifier.name)
|
||||
getterinfal = "infallible" in self.descriptor.getExtendedAttributes(self.member, getter=True)
|
||||
getterconst = self.member.getExtendedAttribute("Constant")
|
||||
getterpure = getterconst or self.member.getExtendedAttribute("Pure")
|
||||
@ -5457,7 +5459,9 @@ class CGMemberJITInfo(CGThing):
|
||||
[self.member.type])
|
||||
if not self.member.readonly or self.member.getExtendedAttribute("PutForwards") is not None:
|
||||
setterinfo = ("%s_setterinfo" % self.member.identifier.name)
|
||||
setter = ("(JSJitPropertyOp)set_%s" % self.member.identifier.name)
|
||||
# Actually a JSJitSetterOp, but JSJitGetterOp is first in the
|
||||
# union.
|
||||
setter = ("(JSJitGetterOp)set_%s" % self.member.identifier.name)
|
||||
# Setters are always fallible, since they have to do a typed unwrap.
|
||||
result += self.defineJitInfo(setterinfo, setter, "Setter",
|
||||
False, False, False,
|
||||
@ -5466,8 +5470,8 @@ class CGMemberJITInfo(CGThing):
|
||||
if self.member.isMethod():
|
||||
methodinfo = ("%s_methodinfo" % self.member.identifier.name)
|
||||
name = CppKeywords.checkMethodName(self.member.identifier.name)
|
||||
# Actually a JSJitMethodOp, but JSJitPropertyOp by struct definition.
|
||||
method = ("(JSJitPropertyOp)%s" % name)
|
||||
# Actually a JSJitMethodOp, but JSJitGetterOp is first in the union.
|
||||
method = ("(JSJitGetterOp)%s" % name)
|
||||
|
||||
# Methods are infallible if they are infallible, have no arguments
|
||||
# to unwrap, and have a return type that's infallible to wrap up for
|
||||
@ -7512,6 +7516,12 @@ class CGDescriptor(CGThing):
|
||||
|
||||
if descriptor.concrete:
|
||||
if descriptor.proxy:
|
||||
if descriptor.nativeOwnership != 'nsisupports':
|
||||
raise TypeError("We don't support non-nsISupports native classes for "
|
||||
"proxy-based bindings yet (" + descriptor.name + ")")
|
||||
if not descriptor.wrapperCache:
|
||||
raise TypeError("We need a wrappercache to support expandos for proxy-based "
|
||||
"bindings (" + descriptor.name + ")")
|
||||
cgThings.append(CGProxyIsProxy(descriptor))
|
||||
cgThings.append(CGProxyUnwrap(descriptor))
|
||||
cgThings.append(CGDOMJSProxyHandlerDOMClass(descriptor))
|
||||
|
@ -8,6 +8,7 @@
|
||||
#define mozilla_dom_TypedArray_h
|
||||
|
||||
#include "jsfriendapi.h"
|
||||
#include "js/RootingAPI.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace dom {
|
||||
@ -65,7 +66,7 @@ struct TypedArray : public TypedArray_base<T,UnboxArray> {
|
||||
static inline JSObject*
|
||||
Create(JSContext* cx, nsWrapperCache* creator, uint32_t length,
|
||||
const T* data = NULL) {
|
||||
JSObject* creatorWrapper;
|
||||
JS::Rooted<JSObject*> creatorWrapper(cx);
|
||||
Maybe<JSAutoCompartment> ac;
|
||||
if (creator && (creatorWrapper = creator->GetWrapperPreserveColor())) {
|
||||
ac.construct(cx, creatorWrapper);
|
||||
|
@ -20,6 +20,13 @@ browserElementTestHelpers.addPermission();
|
||||
browserElementTestHelpers.enableProcessPriorityManager();
|
||||
|
||||
function runTest() {
|
||||
// To test bug 870480, run this test while holding the CPU and high-priority
|
||||
// wake locks. Without the fix for bug 870480, we won't set the priority of
|
||||
// the child process if the main process holds these wake locks and the test
|
||||
// will hang.
|
||||
navigator.requestWakeLock('cpu');
|
||||
navigator.requestWakeLock('high-priority');
|
||||
|
||||
var iframe = document.createElement('iframe');
|
||||
iframe.setAttribute('mozbrowser', true);
|
||||
iframe.setAttribute('mozapptype', 'critical');
|
||||
@ -86,8 +93,8 @@ function runTest() {
|
||||
[expectMozbrowserEvent(iframe, 'showmodalprompt').then(checkAlertInfo),
|
||||
expectPriorityChange(childID, priority).then(checkGracePeriod)]
|
||||
).then(function(results) {
|
||||
// expectMozbrowserEvent returns the function to call to unblock the
|
||||
// alert. It comes to us as the first element of the results array.
|
||||
// checkAlertInfo returns the function to call to unblock the alert.
|
||||
// It comes to us as the first element of the results array.
|
||||
results[0]();
|
||||
});
|
||||
}
|
||||
|
@ -13,9 +13,9 @@ interface nsIScriptGlobalObject;
|
||||
[ptr] native JSContext(JSContext);
|
||||
|
||||
/**
|
||||
* Encode and decode JSON text.
|
||||
* Don't use this! Use JSON.parse and JSON.stringify directly.
|
||||
*/
|
||||
[scriptable, uuid(43845d58-1054-47fb-8be3-970b3f7bd7ea)]
|
||||
[scriptable, uuid(083aebb0-7790-43b2-ae81-9e404e626236)]
|
||||
interface nsIJSON : nsISupports
|
||||
{
|
||||
/**
|
||||
@ -54,29 +54,4 @@ interface nsIJSON : nsISupports
|
||||
|
||||
// Make sure you GCroot the result of this function before using it.
|
||||
[noscript] jsval decodeToJSVal(in AString str, in JSContext cx);
|
||||
|
||||
|
||||
/*
|
||||
* Decode a JSON string, but also accept some strings in non-JSON format, as
|
||||
* the decoding methods here did previously before tightening.
|
||||
*
|
||||
* This method is provided only as a temporary transition path for users of
|
||||
* the old code who depended on the ability to decode leniently; new users
|
||||
* should use JSON.parse.
|
||||
*
|
||||
* This method must only be called from script.
|
||||
*
|
||||
* @param str the string to parse
|
||||
*/
|
||||
[implicit_jscontext]
|
||||
jsval legacyDecode(in AString str);
|
||||
|
||||
/* Identical to legacyDecode, but decode the contents of stream. */
|
||||
[implicit_jscontext]
|
||||
jsval legacyDecodeFromStream(in nsIInputStream stream,
|
||||
in long contentLength);
|
||||
|
||||
/* Identical to legacyDecode, but decode into a jsval. */
|
||||
// Make sure you GCroot the result of this function before using it.
|
||||
[noscript] jsval legacyDecodeToJSVal(in AString str, in JSContext cx);
|
||||
};
|
||||
|
@ -354,7 +354,7 @@ TabChild::Observe(nsISupports *aSubject,
|
||||
mInnerSize);
|
||||
mLastMetrics.mResolution =
|
||||
AsyncPanZoomController::CalculateResolution(mLastMetrics);
|
||||
mLastMetrics.mScrollOffset = gfx::Point(0, 0);
|
||||
mLastMetrics.mScrollOffset = CSSPoint(0, 0);
|
||||
utils->SetResolution(mLastMetrics.mResolution.width,
|
||||
mLastMetrics.mResolution.height);
|
||||
|
||||
@ -1452,7 +1452,7 @@ TabChild::DispatchMessageManagerMessage(const nsAString& aMessageName,
|
||||
}
|
||||
|
||||
static void
|
||||
ScrollWindowTo(nsIDOMWindow* aWindow, const mozilla::gfx::Point& aPoint)
|
||||
ScrollWindowTo(nsIDOMWindow* aWindow, const CSSPoint& aPoint)
|
||||
{
|
||||
nsGlobalWindow* window = static_cast<nsGlobalWindow*>(aWindow);
|
||||
nsIScrollableFrame* sf = window->GetScrollFrame();
|
||||
|
@ -243,7 +243,17 @@ SystemMessageInternal.prototype = {
|
||||
return -1;
|
||||
},
|
||||
|
||||
_removeTargetFromListener: function _removeTargetFromListener(aTarget, aManifest, aRemoveListener) {
|
||||
_isEmptyObject: function _isEmptyObject(aObj) {
|
||||
for (let name in aObj) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
|
||||
_removeTargetFromListener: function _removeTargetFromListener(aTarget,
|
||||
aManifest,
|
||||
aRemoveListener,
|
||||
aUri) {
|
||||
let targets = this._listeners[aManifest];
|
||||
if (!targets) {
|
||||
return false;
|
||||
@ -260,7 +270,13 @@ SystemMessageInternal.prototype = {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (--targets[index].winCount === 0) {
|
||||
let target = targets[index];
|
||||
if (aUri && target.winCounts[aUri] !== undefined &&
|
||||
--target.winCounts[aUri] === 0) {
|
||||
delete target.winCounts[aUri];
|
||||
}
|
||||
|
||||
if (this._isEmptyObject(target.winCounts)) {
|
||||
if (targets.length === 1) {
|
||||
// If it's the only one, get rid of this manifest entirely.
|
||||
debug("remove the listener for " + aManifest);
|
||||
@ -297,17 +313,25 @@ SystemMessageInternal.prototype = {
|
||||
case "SystemMessageManager:Register":
|
||||
{
|
||||
debug("Got Register from " + msg.uri + " @ " + msg.manifest);
|
||||
let uri = msg.uri;
|
||||
let targets, index;
|
||||
if (!(targets = this._listeners[msg.manifest])) {
|
||||
let winCounts = {};
|
||||
winCounts[uri] = 1;
|
||||
this._listeners[msg.manifest] = [{ target: aMessage.target,
|
||||
uri: msg.uri,
|
||||
winCount: 1 }];
|
||||
winCounts: winCounts }];
|
||||
} else if ((index = this._findTargetIndex(targets, aMessage.target)) === -1) {
|
||||
let winCounts = {};
|
||||
winCounts[uri] = 1;
|
||||
targets.push({ target: aMessage.target,
|
||||
uri: msg.uri,
|
||||
winCount: 1 });
|
||||
winCounts: winCounts });
|
||||
} else {
|
||||
targets[index].winCount++;
|
||||
let winCounts = targets[index].winCounts;
|
||||
if (winCounts[uri] === undefined) {
|
||||
winCounts[uri] = 1;
|
||||
} else {
|
||||
winCounts[uri]++;
|
||||
}
|
||||
}
|
||||
|
||||
debug("listeners for " + msg.manifest + " innerWinID " + msg.innerWindowID);
|
||||
@ -318,7 +342,7 @@ SystemMessageInternal.prototype = {
|
||||
debug("Got child-process-shutdown from " + aMessage.target);
|
||||
for (let manifest in this._listeners) {
|
||||
// See if any processes in this manifest have this target.
|
||||
if (this._removeTargetFromListener(aMessage.target, manifest, true)) {
|
||||
if (this._removeTargetFromListener(aMessage.target, manifest, true, null)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -327,7 +351,7 @@ SystemMessageInternal.prototype = {
|
||||
case "SystemMessageManager:Unregister":
|
||||
{
|
||||
debug("Got Unregister from " + aMessage.target + "innerWinID " + msg.innerWindowID);
|
||||
this._removeTargetFromListener(aMessage.target, msg.manifest, false);
|
||||
this._removeTargetFromListener(aMessage.target, msg.manifest, false, msg.uri);
|
||||
break;
|
||||
}
|
||||
case "SystemMessageManager:GetPendingMessages":
|
||||
@ -521,7 +545,7 @@ SystemMessageInternal.prototype = {
|
||||
let target = targets[index];
|
||||
// We only need to send the system message to the targets which match
|
||||
// the manifest URL and page URL of the destination of system message.
|
||||
if (target.uri != aPageURI) {
|
||||
if (target.winCounts[aPageURI] === undefined) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -144,6 +144,7 @@ SystemMessageManager.prototype = {
|
||||
|
||||
cpmm.sendAsyncMessage("SystemMessageManager:Unregister",
|
||||
{ manifest: this._manifest,
|
||||
uri: this._uri,
|
||||
innerWindowID: this.innerWindowID });
|
||||
},
|
||||
|
||||
|
@ -401,8 +401,7 @@ nsJSON::DecodeInternal(JSContext* cx,
|
||||
nsIInputStream *aStream,
|
||||
int32_t aContentLength,
|
||||
bool aNeedsConverter,
|
||||
JS::Value* aRetval,
|
||||
DecodingMode mode /* = STRICT */)
|
||||
JS::Value* aRetval)
|
||||
{
|
||||
// Consume the stream
|
||||
nsCOMPtr<nsIChannel> jsonChannel;
|
||||
@ -419,7 +418,7 @@ nsJSON::DecodeInternal(JSContext* cx,
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
nsRefPtr<nsJSONListener> jsonListener =
|
||||
new nsJSONListener(cx, aRetval, aNeedsConverter, mode);
|
||||
new nsJSONListener(cx, aRetval, aNeedsConverter);
|
||||
|
||||
//XXX this stream pattern should be consolidated in netwerk
|
||||
rv = jsonListener->OnStartRequest(jsonChannel, nullptr);
|
||||
@ -468,44 +467,6 @@ nsJSON::DecodeInternal(JSContext* cx,
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJSON::LegacyDecode(const nsAString& json, JSContext* cx, JS::Value* aRetval)
|
||||
{
|
||||
const PRUnichar *data;
|
||||
uint32_t len = NS_StringGetData(json, &data);
|
||||
nsCOMPtr<nsIInputStream> stream;
|
||||
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream),
|
||||
(const char*) data,
|
||||
len * sizeof(PRUnichar),
|
||||
NS_ASSIGNMENT_DEPEND);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
return DecodeInternal(cx, stream, len, false, aRetval, LEGACY);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJSON::LegacyDecodeFromStream(nsIInputStream *aStream, int32_t aContentLength,
|
||||
JSContext* cx, JS::Value* aRetval)
|
||||
{
|
||||
return DecodeInternal(cx, aStream, aContentLength, true, aRetval, LEGACY);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsJSON::LegacyDecodeToJSVal(const nsAString &str, JSContext *cx, JS::Value *result)
|
||||
{
|
||||
JS::RootedValue reviver(cx, JS::NullValue()), value(cx);
|
||||
|
||||
JS::StableCharPtr chars(static_cast<const jschar*>(PromiseFlatString(str).get()),
|
||||
str.Length());
|
||||
if (!js::ParseJSONWithReviver(cx, chars, str.Length(), reviver,
|
||||
&value, LEGACY)) {
|
||||
return NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
*result = value;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
NS_NewJSON(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
||||
{
|
||||
@ -520,12 +481,10 @@ NS_NewJSON(nsISupports* aOuter, REFNSIID aIID, void** aResult)
|
||||
}
|
||||
|
||||
nsJSONListener::nsJSONListener(JSContext *cx, JS::Value *rootVal,
|
||||
bool needsConverter,
|
||||
DecodingMode mode /* = STRICT */)
|
||||
bool needsConverter)
|
||||
: mNeedsConverter(needsConverter),
|
||||
mCx(cx),
|
||||
mRootVal(rootVal),
|
||||
mDecodingMode(mode)
|
||||
mRootVal(rootVal)
|
||||
{
|
||||
}
|
||||
|
||||
@ -568,10 +527,9 @@ nsJSONListener::OnStopRequest(nsIRequest *aRequest, nsISupports *aContext,
|
||||
|
||||
JS::StableCharPtr chars(reinterpret_cast<const jschar*>(mBufferedChars.Elements()),
|
||||
mBufferedChars.Length());
|
||||
JSBool ok = js::ParseJSONWithReviver(mCx, chars,
|
||||
(uint32_t) mBufferedChars.Length(),
|
||||
reviver, &value,
|
||||
mDecodingMode);
|
||||
JSBool ok = JS_ParseJSONWithReviver(mCx, chars.get(),
|
||||
uint32_t(mBufferedChars.Length()),
|
||||
reviver, value.address());
|
||||
|
||||
*mRootVal = value;
|
||||
mBufferedChars.TruncateLength(0);
|
||||
|
@ -7,7 +7,6 @@
|
||||
#define nsJSON_h__
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "json.h"
|
||||
#include "nsIJSON.h"
|
||||
#include "nsString.h"
|
||||
#include "nsCOMPtr.h"
|
||||
@ -61,8 +60,7 @@ protected:
|
||||
nsIInputStream* aStream,
|
||||
int32_t aContentLength,
|
||||
bool aNeedsConverter,
|
||||
JS::Value* aRetVal,
|
||||
DecodingMode mode = STRICT);
|
||||
JS::Value* aRetVal);
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
};
|
||||
|
||||
@ -72,8 +70,7 @@ NS_NewJSON(nsISupports* aOuter, REFNSIID aIID, void** aResult);
|
||||
class nsJSONListener : public nsIStreamListener
|
||||
{
|
||||
public:
|
||||
nsJSONListener(JSContext *cx, JS::Value *rootVal, bool needsConverter,
|
||||
DecodingMode mode);
|
||||
nsJSONListener(JSContext *cx, JS::Value *rootVal, bool needsConverter);
|
||||
virtual ~nsJSONListener();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
@ -87,7 +84,6 @@ protected:
|
||||
nsCOMPtr<nsIUnicodeDecoder> mDecoder;
|
||||
nsCString mSniffBuffer;
|
||||
nsTArray<PRUnichar> mBufferedChars;
|
||||
DecodingMode mDecodingMode;
|
||||
nsresult ProcessBytes(const char* aBuffer, uint32_t aByteLength);
|
||||
nsresult ConsumeConverted(const char* aBuffer, uint32_t aByteLength);
|
||||
nsresult Consume(const PRUnichar *data, uint32_t len);
|
||||
|
@ -34,6 +34,7 @@ interface AudioParam {
|
||||
void setValueCurveAtTime(Float32Array values, double startTime, double duration);
|
||||
|
||||
// Cancels all scheduled parameter changes with times greater than or equal to startTime.
|
||||
[Throws]
|
||||
void cancelScheduledValues(double startTime);
|
||||
|
||||
};
|
||||
|
@ -37,3 +37,11 @@ partial interface EventTarget {
|
||||
[ChromeOnly]
|
||||
EventHandler getEventHandler(DOMString type);
|
||||
};
|
||||
|
||||
// Mozilla extension to make firing events on event targets from
|
||||
// chrome easier. This returns the window which can be used to create
|
||||
// events to fire at this EventTarget, or null if there isn't one.
|
||||
partial interface EventTarget {
|
||||
[ChromeOnly]
|
||||
readonly attribute WindowProxy? ownerGlobal;
|
||||
};
|
||||
|
@ -74,6 +74,12 @@ public:
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JSObject* GetOwnerGlobal() const
|
||||
{
|
||||
// We have no windows
|
||||
return nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
END_WORKERS_NAMESPACE
|
||||
|
@ -24,13 +24,13 @@ Tests of DOM Worker Threads XHR(Bug 450452 )
|
||||
var worker = new Worker("xhr_implicit_cancel_worker.js");
|
||||
|
||||
worker.onmessage = function(event) {
|
||||
is(event.target, worker);
|
||||
is(event.target, worker, "Expected event target for message");
|
||||
ok(true, "Worker didn't have an error");
|
||||
SimpleTest.finish();
|
||||
};
|
||||
|
||||
worker.onerror = function(event) {
|
||||
is(event.target, worker);
|
||||
is(event.target, worker, "Expected event target for error");
|
||||
ok(false, "Worker had an error:" + event.data);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
@ -418,6 +418,22 @@ struct BaseRect {
|
||||
std::max(y, std::min(YMost(), aPoint.y)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Clamp aRect to this rectangle. This returns aRect after it is forced
|
||||
* inside the bounds of this rectangle. It will attempt to retain the size
|
||||
* but will shrink the dimensions that don't fit.
|
||||
*/
|
||||
Sub ClampRect(const Sub& aRect) const
|
||||
{
|
||||
Sub rect(std::max(aRect.x, x),
|
||||
std::max(aRect.y, y),
|
||||
std::min(aRect.width, width),
|
||||
std::min(aRect.height, height));
|
||||
rect.x = std::min(rect.XMost(), XMost()) - rect.width;
|
||||
rect.y = std::min(rect.YMost(), YMost()) - rect.height;
|
||||
return rect;
|
||||
}
|
||||
|
||||
private:
|
||||
// Do not use the default operator== or operator!= !
|
||||
// Use IsEqualEdges or IsEqualInterior explicitly.
|
||||
|
@ -36,6 +36,17 @@ struct PointTyped :
|
||||
PointTyped() : Super() {}
|
||||
PointTyped(Float aX, Float aY) : Super(aX, aY) {}
|
||||
PointTyped(const IntPointTyped<units>& point) : Super(float(point.x), float(point.y)) {}
|
||||
|
||||
// XXX When all of the code is ported, the following functions to convert to and from
|
||||
// unknown types should be removed.
|
||||
|
||||
static PointTyped<units> FromUnknownPoint(const PointTyped<UnknownUnits>& pt) {
|
||||
return PointTyped<units>(pt.x, pt.y);
|
||||
}
|
||||
|
||||
PointTyped<UnknownUnits> ToUnknownPoint() const {
|
||||
return PointTyped<UnknownUnits>(this->x, this->y);
|
||||
}
|
||||
};
|
||||
typedef PointTyped<UnknownUnits> Point;
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "gfxTypes.h"
|
||||
#include "nsRect.h"
|
||||
#include "mozilla/gfx/Rect.h"
|
||||
#include "Units.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -190,7 +191,7 @@ public:
|
||||
//
|
||||
// This is valid for any layer, but is always relative to this frame and
|
||||
// not any parents, regardless of parent transforms.
|
||||
gfx::Point mScrollOffset;
|
||||
mozilla::CSSPoint mScrollOffset;
|
||||
|
||||
// A unique ID assigned to each scrollable frame (unless this is
|
||||
// ROOT_SCROLL_ID, in which case it is not unique).
|
||||
|
@ -95,8 +95,9 @@ AppendToString(nsACString& s, const nsIntPoint& p,
|
||||
return s += sfx;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
nsACString&
|
||||
AppendToString(nsACString& s, const Point& p,
|
||||
AppendToString(nsACString& s, const PointTyped<T>& p,
|
||||
const char* pfx, const char* sfx)
|
||||
{
|
||||
s += pfx;
|
||||
|
@ -44,8 +44,9 @@ nsACString&
|
||||
AppendToString(nsACString& s, const nsIntPoint& p,
|
||||
const char* pfx="", const char* sfx="");
|
||||
|
||||
template<class T>
|
||||
nsACString&
|
||||
AppendToString(nsACString& s, const mozilla::gfx::Point& p,
|
||||
AppendToString(nsACString& s, const mozilla::gfx::PointTyped<T>& p,
|
||||
const char* pfx="", const char* sfx="");
|
||||
|
||||
nsACString&
|
||||
|
@ -18,7 +18,7 @@ ClientTiledThebesLayer::ClientTiledThebesLayer(ClientLayerManager* const aManage
|
||||
, mContentClient()
|
||||
{
|
||||
MOZ_COUNT_CTOR(ClientTiledThebesLayer);
|
||||
mPaintData.mLastScrollOffset = gfx::Point(0, 0);
|
||||
mPaintData.mLastScrollOffset = CSSPoint(0, 0);
|
||||
mPaintData.mFirstPaint = true;
|
||||
}
|
||||
|
||||
|
@ -273,7 +273,7 @@ BasicTiledLayerBuffer::ValidateTile(BasicTiledLayerTile aTile,
|
||||
|
||||
static nsIntRect
|
||||
RoundedTransformViewportBounds(const gfx::Rect& aViewport,
|
||||
const gfx::Point& aScrollOffset,
|
||||
const CSSPoint& aScrollOffset,
|
||||
const gfxSize& aResolution,
|
||||
float aScaleX,
|
||||
float aScaleY,
|
||||
|
@ -73,8 +73,8 @@ struct BasicTiledLayerTile {
|
||||
* doesn't need to be recalculated on every repeated transaction.
|
||||
*/
|
||||
struct BasicTiledLayerPaintData {
|
||||
gfx::Point mScrollOffset;
|
||||
gfx::Point mLastScrollOffset;
|
||||
CSSPoint mScrollOffset;
|
||||
CSSPoint mLastScrollOffset;
|
||||
gfx3DMatrix mTransformScreenToLayer;
|
||||
nsIntRect mLayerCriticalDisplayPort;
|
||||
gfxSize mResolution;
|
||||
|
@ -828,7 +828,7 @@ void AsyncPanZoomController::ScrollBy(const gfx::Point& aOffset) {
|
||||
gfx::Point newOffset(mFrameMetrics.mScrollOffset.x + aOffset.x,
|
||||
mFrameMetrics.mScrollOffset.y + aOffset.y);
|
||||
FrameMetrics metrics(mFrameMetrics);
|
||||
metrics.mScrollOffset = newOffset;
|
||||
metrics.mScrollOffset = CSSPoint::FromUnknownPoint(newOffset);
|
||||
mFrameMetrics = metrics;
|
||||
}
|
||||
|
||||
@ -940,7 +940,7 @@ const gfx::Rect AsyncPanZoomController::CalculatePendingDisplayPort(
|
||||
scrollableRect.height = compositionBounds.height;
|
||||
}
|
||||
|
||||
gfx::Point scrollOffset = aFrameMetrics.mScrollOffset;
|
||||
CSSPoint scrollOffset = aFrameMetrics.mScrollOffset;
|
||||
|
||||
gfx::Rect displayPort(0, 0,
|
||||
compositionBounds.width * gXStationarySizeMultiplier,
|
||||
@ -987,7 +987,7 @@ const gfx::Rect AsyncPanZoomController::CalculatePendingDisplayPort(
|
||||
|
||||
gfx::Rect shiftedDisplayPort = displayPort;
|
||||
shiftedDisplayPort.MoveBy(scrollOffset.x, scrollOffset.y);
|
||||
displayPort = shiftedDisplayPort.Intersect(scrollableRect);
|
||||
displayPort = scrollableRect.ClampRect(shiftedDisplayPort);
|
||||
displayPort.MoveBy(-scrollOffset.x, -scrollOffset.y);
|
||||
|
||||
return displayPort;
|
||||
@ -1055,8 +1055,8 @@ void AsyncPanZoomController::RequestContentRepaint() {
|
||||
GetAccelerationVector(),
|
||||
estimatedPaintDuration);
|
||||
|
||||
gfx::Point oldScrollOffset = mLastPaintRequestMetrics.mScrollOffset,
|
||||
newScrollOffset = mFrameMetrics.mScrollOffset;
|
||||
CSSPoint oldScrollOffset = mLastPaintRequestMetrics.mScrollOffset,
|
||||
newScrollOffset = mFrameMetrics.mScrollOffset;
|
||||
|
||||
// If we're trying to paint what we already think is painted, discard this
|
||||
// request since it's a pointless paint.
|
||||
@ -1157,12 +1157,12 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
|
||||
startZoom * (1 - sampledPosition));
|
||||
mFrameMetrics.mZoom = gfxSize(sampledZoom, sampledZoom);
|
||||
|
||||
mFrameMetrics.mScrollOffset = gfx::Point(
|
||||
mFrameMetrics.mScrollOffset = CSSPoint::FromUnknownPoint(gfx::Point(
|
||||
mEndZoomToMetrics.mScrollOffset.x * sampledPosition +
|
||||
mStartZoomToMetrics.mScrollOffset.x * (1 - sampledPosition),
|
||||
mEndZoomToMetrics.mScrollOffset.y * sampledPosition +
|
||||
mStartZoomToMetrics.mScrollOffset.y * (1 - sampledPosition)
|
||||
);
|
||||
));
|
||||
|
||||
requestAnimationFrame = true;
|
||||
|
||||
@ -1191,7 +1191,7 @@ bool AsyncPanZoomController::SampleContentTransformForFrame(const TimeStamp& aSa
|
||||
}
|
||||
|
||||
scrollOffset = gfxPoint(mFrameMetrics.mScrollOffset.x, mFrameMetrics.mScrollOffset.y);
|
||||
mCurrentAsyncScrollOffset = mFrameMetrics.mScrollOffset;
|
||||
mCurrentAsyncScrollOffset = mFrameMetrics.mScrollOffset.ToUnknownPoint();
|
||||
}
|
||||
|
||||
// Cancel the mAsyncScrollTimeoutTask because we will fire a
|
||||
@ -1345,7 +1345,7 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
|
||||
|
||||
nsIntRect compositionBounds = mFrameMetrics.mCompositionBounds;
|
||||
gfx::Rect cssPageRect = mFrameMetrics.mScrollableRect;
|
||||
gfx::Point scrollOffset = mFrameMetrics.mScrollOffset;
|
||||
CSSPoint scrollOffset = mFrameMetrics.mScrollOffset;
|
||||
gfxSize resolution = CalculateResolution(mFrameMetrics);
|
||||
gfxSize currentZoom = mFrameMetrics.mZoom;
|
||||
float targetZoom;
|
||||
@ -1419,7 +1419,8 @@ void AsyncPanZoomController::ZoomToRect(const gfxRect& aRect) {
|
||||
}
|
||||
|
||||
mStartZoomToMetrics = mFrameMetrics;
|
||||
mEndZoomToMetrics.mScrollOffset = gfx::Point(zoomToRect.x, zoomToRect.y);
|
||||
mEndZoomToMetrics.mScrollOffset = CSSPoint::FromUnknownPoint(
|
||||
gfx::Point(zoomToRect.x, zoomToRect.y));
|
||||
|
||||
mAnimationStartTime = TimeStamp::Now();
|
||||
|
||||
|
@ -292,7 +292,7 @@ float Axis::GetPageEnd() {
|
||||
}
|
||||
|
||||
float Axis::GetOrigin() {
|
||||
gfx::Point origin = mAsyncPanZoomController->GetFrameMetrics().mScrollOffset;
|
||||
CSSPoint origin = mAsyncPanZoomController->GetFrameMetrics().mScrollOffset;
|
||||
return GetPointOffset(origin);
|
||||
}
|
||||
|
||||
@ -334,7 +334,7 @@ AxisX::AxisX(AsyncPanZoomController* aAsyncPanZoomController)
|
||||
|
||||
}
|
||||
|
||||
float AxisX::GetPointOffset(const gfx::Point& aPoint)
|
||||
float AxisX::GetPointOffset(const CSSPoint& aPoint)
|
||||
{
|
||||
return aPoint.x;
|
||||
}
|
||||
@ -355,7 +355,7 @@ AxisY::AxisY(AsyncPanZoomController* aAsyncPanZoomController)
|
||||
|
||||
}
|
||||
|
||||
float AxisY::GetPointOffset(const gfx::Point& aPoint)
|
||||
float AxisY::GetPointOffset(const CSSPoint& aPoint)
|
||||
{
|
||||
return aPoint.y;
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/gfx/2D.h"
|
||||
#include "nsTArray.h"
|
||||
#include "Units.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace layers {
|
||||
@ -170,7 +171,7 @@ public:
|
||||
float GetCompositionEnd();
|
||||
float GetPageEnd();
|
||||
|
||||
virtual float GetPointOffset(const gfx::Point& aPoint) = 0;
|
||||
virtual float GetPointOffset(const CSSPoint& aPoint) = 0;
|
||||
virtual float GetRectLength(const gfx::Rect& aRect) = 0;
|
||||
virtual float GetRectOffset(const gfx::Rect& aRect) = 0;
|
||||
|
||||
@ -191,7 +192,7 @@ protected:
|
||||
class AxisX : public Axis {
|
||||
public:
|
||||
AxisX(AsyncPanZoomController* mAsyncPanZoomController);
|
||||
virtual float GetPointOffset(const gfx::Point& aPoint);
|
||||
virtual float GetPointOffset(const CSSPoint& aPoint);
|
||||
virtual float GetRectLength(const gfx::Rect& aRect);
|
||||
virtual float GetRectOffset(const gfx::Rect& aRect);
|
||||
};
|
||||
@ -199,7 +200,7 @@ public:
|
||||
class AxisY : public Axis {
|
||||
public:
|
||||
AxisY(AsyncPanZoomController* mAsyncPanZoomController);
|
||||
virtual float GetPointOffset(const gfx::Point& aPoint);
|
||||
virtual float GetPointOffset(const CSSPoint& aPoint);
|
||||
virtual float GetRectLength(const gfx::Rect& aRect);
|
||||
virtual float GetRectOffset(const gfx::Rect& aRect);
|
||||
};
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "mozilla/layers/ColorLayerComposite.h"
|
||||
#include "mozilla/layers/ContainerLayerComposite.h"
|
||||
#include "mozilla/layers/CanvasLayerComposite.h"
|
||||
#include "mozilla/layers/PLayerTransaction.h"
|
||||
|
||||
typedef std::vector<mozilla::layers::EditReply> EditReplyVector;
|
||||
|
||||
@ -454,7 +455,29 @@ LayerTransactionParent::RecvGetTransform(PLayerParent* aParent,
|
||||
return false;
|
||||
}
|
||||
|
||||
*aTransform = cast(aParent)->AsLayer()->GetLocalTransform();
|
||||
// The following code recovers the untranslated transform
|
||||
// from the shadow transform by undoing the translations in
|
||||
// AsyncCompositionManager::SampleValue.
|
||||
Layer* layer = cast(aParent)->AsLayer();
|
||||
*aTransform = layer->GetLocalTransform();
|
||||
float scale = 1;
|
||||
gfxPoint3D scaledOrigin;
|
||||
gfxPoint3D mozOrigin;
|
||||
for (uint32_t i=0; i < layer->GetAnimations().Length(); i++) {
|
||||
if (layer->GetAnimations()[i].data().type() == AnimationData::TTransformData) {
|
||||
const TransformData& data = layer->GetAnimations()[i].data().get_TransformData();
|
||||
scale = data.appUnitsPerDevPixel();
|
||||
scaledOrigin =
|
||||
gfxPoint3D(NS_round(NSAppUnitsToFloatPixels(data.origin().x, scale)),
|
||||
NS_round(NSAppUnitsToFloatPixels(data.origin().y, scale)),
|
||||
0.0f);
|
||||
mozOrigin = data.mozOrigin();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
aTransform->Translate(-scaledOrigin);
|
||||
*aTransform = nsLayoutUtils::ChangeMatrixBasis(-scaledOrigin - mozOrigin, *aTransform);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -788,10 +788,10 @@ struct ParamTraits<nsIntSize>
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct ParamTraits<mozilla::gfx::Point>
|
||||
template<class T>
|
||||
struct ParamTraits< mozilla::gfx::PointTyped<T> >
|
||||
{
|
||||
typedef mozilla::gfx::Point paramType;
|
||||
typedef mozilla::gfx::PointTyped<T> paramType;
|
||||
|
||||
static void Write(Message* msg, const paramType& param)
|
||||
{
|
||||
|
@ -100,11 +100,11 @@ TestShellCommandParent::RunCallback(const nsString& aResponse)
|
||||
JSString* str = JS_NewUCStringCopyN(mCx, aResponse.get(), aResponse.Length());
|
||||
NS_ENSURE_TRUE(str, JS_FALSE);
|
||||
|
||||
JS::Value argv[] = { STRING_TO_JSVAL(str) };
|
||||
unsigned argc = ArrayLength(argv);
|
||||
JS::Rooted<JS::Value> strVal(mCx, JS::StringValue(str));
|
||||
|
||||
JS::Value rval;
|
||||
JSBool ok = JS_CallFunctionValue(mCx, global, mCallback, argc, argv, &rval);
|
||||
JS::Rooted<JS::Value> rval(mCx);
|
||||
JSBool ok = JS_CallFunctionValue(mCx, global, mCallback, 1, strVal.address(),
|
||||
rval.address());
|
||||
NS_ENSURE_TRUE(ok, JS_FALSE);
|
||||
|
||||
return JS_TRUE;
|
||||
|
@ -31,6 +31,7 @@
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/TypeTraits.h"
|
||||
|
||||
#include "jstypes.h"
|
||||
|
||||
@ -92,30 +93,50 @@ namespace JS {
|
||||
* public interface are meant to be used by embedders! See inline comments to
|
||||
* for details.
|
||||
*/
|
||||
class MOZ_STACK_CLASS CallReceiver
|
||||
|
||||
namespace detail {
|
||||
|
||||
enum UsedRval { IncludeUsedRval, NoUsedRval };
|
||||
|
||||
template<UsedRval WantUsedRval>
|
||||
class MOZ_STACK_CLASS UsedRvalBase;
|
||||
|
||||
template<>
|
||||
class MOZ_STACK_CLASS UsedRvalBase<IncludeUsedRval>
|
||||
{
|
||||
protected:
|
||||
#ifdef DEBUG
|
||||
mutable bool usedRval_;
|
||||
void setUsedRval() const { usedRval_ = true; }
|
||||
void clearUsedRval() const { usedRval_ = false; }
|
||||
#else
|
||||
};
|
||||
|
||||
template<>
|
||||
class MOZ_STACK_CLASS UsedRvalBase<NoUsedRval>
|
||||
{
|
||||
protected:
|
||||
void setUsedRval() const {}
|
||||
void clearUsedRval() const {}
|
||||
};
|
||||
|
||||
template<UsedRval WantUsedRval>
|
||||
class MOZ_STACK_CLASS CallReceiverBase : public UsedRvalBase<
|
||||
#ifdef DEBUG
|
||||
WantUsedRval
|
||||
#else
|
||||
NoUsedRval
|
||||
#endif
|
||||
|
||||
>
|
||||
{
|
||||
protected:
|
||||
Value *argv_;
|
||||
|
||||
friend CallReceiver CallReceiverFromVp(Value *vp);
|
||||
friend CallReceiver CallReceiverFromArgv(Value *argv);
|
||||
|
||||
public:
|
||||
/*
|
||||
* Returns the function being called, as an object. Must not be called
|
||||
* after rval() has been used!
|
||||
*/
|
||||
JSObject &callee() const {
|
||||
MOZ_ASSERT(!usedRval_);
|
||||
MOZ_ASSERT(!this->usedRval_);
|
||||
return argv_[-2].toObject();
|
||||
}
|
||||
|
||||
@ -124,7 +145,7 @@ class MOZ_STACK_CLASS CallReceiver
|
||||
* rval() has been used!
|
||||
*/
|
||||
HandleValue calleev() const {
|
||||
MOZ_ASSERT(!usedRval_);
|
||||
MOZ_ASSERT(!this->usedRval_);
|
||||
return HandleValue::fromMarkedLocation(&argv_[-2]);
|
||||
}
|
||||
|
||||
@ -160,7 +181,7 @@ class MOZ_STACK_CLASS CallReceiver
|
||||
* fails.
|
||||
*/
|
||||
MutableHandleValue rval() const {
|
||||
setUsedRval();
|
||||
this->setUsedRval();
|
||||
return MutableHandleValue::fromMarkedLocation(&argv_[-2]);
|
||||
}
|
||||
|
||||
@ -171,7 +192,7 @@ class MOZ_STACK_CLASS CallReceiver
|
||||
Value *base() const { return argv_ - 2; }
|
||||
|
||||
Value *spAfterCall() const {
|
||||
setUsedRval();
|
||||
this->setUsedRval();
|
||||
return argv_ - 1;
|
||||
}
|
||||
|
||||
@ -181,7 +202,7 @@ class MOZ_STACK_CLASS CallReceiver
|
||||
// it. You probably don't want to use these!
|
||||
|
||||
void setCallee(Value aCalleev) const {
|
||||
clearUsedRval();
|
||||
this->clearUsedRval();
|
||||
argv_[-2] = aCalleev;
|
||||
}
|
||||
|
||||
@ -194,6 +215,15 @@ class MOZ_STACK_CLASS CallReceiver
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class MOZ_STACK_CLASS CallReceiver : public detail::CallReceiverBase<detail::IncludeUsedRval>
|
||||
{
|
||||
private:
|
||||
friend CallReceiver CallReceiverFromVp(Value *vp);
|
||||
friend CallReceiver CallReceiverFromArgv(Value *argv);
|
||||
};
|
||||
|
||||
MOZ_ALWAYS_INLINE CallReceiver
|
||||
CallReceiverFromArgv(Value *argv)
|
||||
{
|
||||
@ -233,11 +263,63 @@ CallReceiverFromVp(Value *vp)
|
||||
* public interface are meant to be used by embedders! See inline comments to
|
||||
* for details.
|
||||
*/
|
||||
class MOZ_STACK_CLASS CallArgs : public CallReceiver
|
||||
namespace detail {
|
||||
|
||||
template<UsedRval WantUsedRval>
|
||||
class MOZ_STACK_CLASS CallArgsBase :
|
||||
public mozilla::Conditional<WantUsedRval == detail::IncludeUsedRval,
|
||||
CallReceiver,
|
||||
CallReceiverBase<NoUsedRval> >::Type
|
||||
{
|
||||
protected:
|
||||
unsigned argc_;
|
||||
|
||||
public:
|
||||
/* Returns the number of arguments. */
|
||||
unsigned length() const { return argc_; }
|
||||
|
||||
/* Returns the i-th zero-indexed argument. */
|
||||
Value &operator[](unsigned i) const {
|
||||
MOZ_ASSERT(i < argc_);
|
||||
return this->argv_[i];
|
||||
}
|
||||
|
||||
/* Returns a mutable handle for the i-th zero-indexed argument. */
|
||||
MutableHandleValue handleAt(unsigned i) const {
|
||||
MOZ_ASSERT(i < argc_);
|
||||
return MutableHandleValue::fromMarkedLocation(&this->argv_[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the i-th zero-indexed argument, or |undefined| if there's no
|
||||
* such argument.
|
||||
*/
|
||||
Value get(unsigned i) const {
|
||||
return i < length() ? this->argv_[i] : UndefinedValue();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the i-th zero-indexed argument is present and is not
|
||||
* |undefined|.
|
||||
*/
|
||||
bool hasDefined(unsigned i) const {
|
||||
return i < argc_ && !this->argv_[i].isUndefined();
|
||||
}
|
||||
|
||||
public:
|
||||
// These methods are publicly exposed, but we're less sure of the interface
|
||||
// here than we'd like (because they're hackish and drop assertions). Try
|
||||
// to avoid using these if you can.
|
||||
|
||||
Value *array() const { return this->argv_; }
|
||||
Value *end() const { return this->argv_ + argc_; }
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
class MOZ_STACK_CLASS CallArgs : public detail::CallArgsBase<detail::IncludeUsedRval>
|
||||
{
|
||||
private:
|
||||
friend CallArgs CallArgsFromVp(unsigned argc, Value *vp);
|
||||
friend CallArgs CallArgsFromSp(unsigned argc, Value *sp);
|
||||
|
||||
@ -249,45 +331,6 @@ class MOZ_STACK_CLASS CallArgs : public CallReceiver
|
||||
return args;
|
||||
}
|
||||
|
||||
public:
|
||||
/* Returns the number of arguments. */
|
||||
unsigned length() const { return argc_; }
|
||||
|
||||
/* Returns the i-th zero-indexed argument. */
|
||||
Value &operator[](unsigned i) const {
|
||||
MOZ_ASSERT(i < argc_);
|
||||
return argv_[i];
|
||||
}
|
||||
|
||||
/* Returns a mutable handle for the i-th zero-indexed argument. */
|
||||
MutableHandleValue handleAt(unsigned i) const {
|
||||
MOZ_ASSERT(i < argc_);
|
||||
return MutableHandleValue::fromMarkedLocation(&argv_[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the i-th zero-indexed argument, or |undefined| if there's no
|
||||
* such argument.
|
||||
*/
|
||||
Value get(unsigned i) const {
|
||||
return i < length() ? argv_[i] : UndefinedValue();
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns true if the i-th zero-indexed argument is present and is not
|
||||
* |undefined|.
|
||||
*/
|
||||
bool hasDefined(unsigned i) const {
|
||||
return i < argc_ && !argv_[i].isUndefined();
|
||||
}
|
||||
|
||||
public:
|
||||
// These methods are publicly exposed, but we're less sure of the interface
|
||||
// here than we'd like (because they're hackish and drop assertions). Try
|
||||
// to avoid using these if you can.
|
||||
|
||||
Value *array() const { return argv_; }
|
||||
Value *end() const { return argv_ + argc_; }
|
||||
};
|
||||
|
||||
MOZ_ALWAYS_INLINE CallArgs
|
||||
|
@ -177,7 +177,7 @@ TryEvalJSON(JSContext *cx, JSScript *callerScript,
|
||||
if (cp == end) {
|
||||
bool isArray = (chars[0] == '[');
|
||||
JSONParser parser(cx, isArray ? chars : chars + 1U, isArray ? length : length - 2,
|
||||
JSONParser::StrictJSON, JSONParser::NoError);
|
||||
JSONParser::NoError);
|
||||
RootedValue tmp(cx);
|
||||
if (!parser.parse(&tmp))
|
||||
return EvalJSON_Failure;
|
||||
|
@ -18,42 +18,19 @@ using namespace js::types;
|
||||
|
||||
using mozilla::ArrayLength;
|
||||
|
||||
class RegExpMatchBuilder
|
||||
static inline bool
|
||||
DefinePropertyHelper(JSContext *cx, HandleObject obj, Handle<PropertyName*> name, HandleValue v)
|
||||
{
|
||||
JSContext * const cx;
|
||||
RootedObject array;
|
||||
|
||||
bool setProperty(Handle<PropertyName*> name, HandleValue v) {
|
||||
return !!baseops::DefineProperty(cx, array, name, v,
|
||||
JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE);
|
||||
}
|
||||
|
||||
public:
|
||||
RegExpMatchBuilder(JSContext *cx, HandleObject array) : cx(cx), array(cx, array) {}
|
||||
|
||||
bool append(uint32_t index, HandleValue v) {
|
||||
JS_ASSERT(!array->getOps()->getElement);
|
||||
return !!baseops::DefineElement(cx, array, index, v, JS_PropertyStub, JS_StrictPropertyStub,
|
||||
JSPROP_ENUMERATE);
|
||||
}
|
||||
|
||||
bool setIndex(int index) {
|
||||
RootedValue value(cx, Int32Value(index));
|
||||
return setProperty(cx->names().index, value);
|
||||
}
|
||||
|
||||
bool setInput(HandleString str) {
|
||||
JS_ASSERT(str);
|
||||
RootedValue value(cx, StringValue(str));
|
||||
return setProperty(cx->names().input, value);
|
||||
}
|
||||
};
|
||||
return !!baseops::DefineProperty(cx, obj, name, v,
|
||||
JS_PropertyStub, JS_StrictPropertyStub, JSPROP_ENUMERATE);
|
||||
}
|
||||
|
||||
bool
|
||||
js::CreateRegExpMatchResult(JSContext *cx, HandleString input_, const jschar *chars, size_t length,
|
||||
MatchPairs &matches, MutableHandleValue rval)
|
||||
{
|
||||
RootedString input(cx, input_);
|
||||
RootedValue undefinedValue(cx, UndefinedValue());
|
||||
|
||||
/*
|
||||
* Create the (slow) result array for a match.
|
||||
@ -64,39 +41,47 @@ js::CreateRegExpMatchResult(JSContext *cx, HandleString input_, const jschar *ch
|
||||
* input: input string
|
||||
* index: start index for the match
|
||||
*/
|
||||
RootedObject array(cx, NewDenseEmptyArray(cx));
|
||||
if (!array)
|
||||
return false;
|
||||
|
||||
if (!input) {
|
||||
input = js_NewStringCopyN<CanGC>(cx, chars, length);
|
||||
if (!input)
|
||||
return false;
|
||||
}
|
||||
|
||||
RegExpMatchBuilder builder(cx, array);
|
||||
RootedValue undefinedValue(cx, UndefinedValue());
|
||||
|
||||
size_t numPairs = matches.length();
|
||||
JS_ASSERT(numPairs > 0);
|
||||
|
||||
AutoValueVector elements(cx);
|
||||
if (!elements.reserve(numPairs))
|
||||
return false;
|
||||
|
||||
/* Accumulate a Value for each pair, in a rooted vector. */
|
||||
for (size_t i = 0; i < numPairs; ++i) {
|
||||
const MatchPair &pair = matches[i];
|
||||
|
||||
RootedString captured(cx);
|
||||
if (pair.isUndefined()) {
|
||||
JS_ASSERT(i != 0); /* Since we had a match, first pair must be present. */
|
||||
if (!builder.append(i, undefinedValue))
|
||||
return false;
|
||||
elements.infallibleAppend(undefinedValue);
|
||||
} else {
|
||||
captured = js_NewDependentString(cx, input, pair.start, pair.length());
|
||||
RootedValue value(cx, StringValue(captured));
|
||||
if (!captured || !builder.append(i, value))
|
||||
JSLinearString *str = js_NewDependentString(cx, input, pair.start, pair.length());
|
||||
if (!str)
|
||||
return false;
|
||||
elements.infallibleAppend(StringValue(str));
|
||||
}
|
||||
}
|
||||
|
||||
if (!builder.setIndex(matches[0].start) || !builder.setInput(input))
|
||||
/* Copy the rooted vector into the array object. */
|
||||
RootedObject array(cx, NewDenseCopiedArray(cx, elements.length(), elements.begin()));
|
||||
if (!array)
|
||||
return false;
|
||||
|
||||
/* Set the |index| property. */
|
||||
RootedValue index(cx, Int32Value(matches[0].start));
|
||||
if (!DefinePropertyHelper(cx, array, cx->names().index, index))
|
||||
return false;
|
||||
|
||||
/* Set the |input| property. */
|
||||
RootedValue inputVal(cx, StringValue(input));
|
||||
if (!DefinePropertyHelper(cx, array, cx->names().input, inputVal))
|
||||
return false;
|
||||
|
||||
rval.setObject(*array);
|
||||
|
@ -892,6 +892,74 @@ js::testingFunc_inParallelSection(JSContext *cx, unsigned argc, jsval *vp)
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSObject *objectMetadataFunction = NULL;
|
||||
|
||||
static JSObject *
|
||||
ShellObjectMetadataCallback(JSContext *cx)
|
||||
{
|
||||
Value thisv = UndefinedValue();
|
||||
|
||||
Value rval;
|
||||
if (!Invoke(cx, thisv, ObjectValue(*objectMetadataFunction), 0, NULL, &rval)) {
|
||||
cx->clearPendingException();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return rval.isObject() ? &rval.toObject() : NULL;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
SetObjectMetadataCallback(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
args.rval().setUndefined();
|
||||
|
||||
if (argc == 0 || !args[0].isObject() || !args[0].toObject().isFunction()) {
|
||||
if (objectMetadataFunction)
|
||||
JS_RemoveObjectRoot(cx, &objectMetadataFunction);
|
||||
objectMetadataFunction = NULL;
|
||||
js::SetObjectMetadataCallback(cx, NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!objectMetadataFunction && !JS_AddObjectRoot(cx, &objectMetadataFunction))
|
||||
return false;
|
||||
|
||||
objectMetadataFunction = &args[0].toObject();
|
||||
js::SetObjectMetadataCallback(cx, ShellObjectMetadataCallback);
|
||||
return true;
|
||||
}
|
||||
|
||||
static JSBool
|
||||
SetObjectMetadata(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (argc != 2 || !args[0].isObject() || !args[1].isObject()) {
|
||||
JS_ReportError(cx, "Both arguments must be objects");
|
||||
return false;
|
||||
}
|
||||
|
||||
args.rval().setUndefined();
|
||||
|
||||
RootedObject obj(cx, &args[0].toObject());
|
||||
RootedObject metadata(cx, &args[1].toObject());
|
||||
return SetObjectMetadata(cx, obj, metadata);
|
||||
}
|
||||
|
||||
static JSBool
|
||||
GetObjectMetadata(JSContext *cx, unsigned argc, jsval *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
if (argc != 1 || !args[0].isObject()) {
|
||||
JS_ReportError(cx, "Argument must be an object");
|
||||
return false;
|
||||
}
|
||||
|
||||
args.rval().setObjectOrNull(GetObjectMetadata(&args[0].toObject()));
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef JS_ION
|
||||
JSBool
|
||||
js::IsAsmJSCompilationAvailable(JSContext *cx, unsigned argc, Value *vp)
|
||||
@ -1079,6 +1147,18 @@ static JSFunctionSpecWithHelp TestingFunctions[] = {
|
||||
"inParallelSection()",
|
||||
" True if this code is executing within a parallel section."),
|
||||
|
||||
JS_FN_HELP("setObjectMetadataCallback", SetObjectMetadataCallback, 1, 0,
|
||||
"setObjectMetadataCallback(fn)",
|
||||
" Specify function to supply metadata for all newly created objects."),
|
||||
|
||||
JS_FN_HELP("setObjectMetadata", SetObjectMetadata, 2, 0,
|
||||
"setObjectMetadata(obj, metadataObj)",
|
||||
" Change the metadata for an object."),
|
||||
|
||||
JS_FN_HELP("getObjectMetadata", GetObjectMetadata, 1, 0,
|
||||
"getObjectMetadata(obj)",
|
||||
" Get the metadata for an object."),
|
||||
|
||||
JS_FS_HELP_END
|
||||
};
|
||||
|
||||
|
@ -27,6 +27,8 @@ class MinorCollectionTracer;
|
||||
namespace ion {
|
||||
class CodeGenerator;
|
||||
class MacroAssembler;
|
||||
class ICStubCompiler;
|
||||
class BaselineCompiler;
|
||||
}
|
||||
|
||||
class Nursery
|
||||
@ -189,6 +191,8 @@ class Nursery
|
||||
friend class gc::MinorCollectionTracer;
|
||||
friend class ion::CodeGenerator;
|
||||
friend class ion::MacroAssembler;
|
||||
friend class ion::ICStubCompiler;
|
||||
friend class ion::BaselineCompiler;
|
||||
};
|
||||
|
||||
} /* namespace js */
|
||||
|
@ -23,6 +23,9 @@ using namespace js::ion;
|
||||
BaselineCompiler::BaselineCompiler(JSContext *cx, HandleScript script)
|
||||
: BaselineCompilerSpecific(cx, script),
|
||||
return_(new HeapLabel())
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
, postBarrierSlot_(new HeapLabel())
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
@ -90,6 +93,11 @@ BaselineCompiler::compile()
|
||||
if (!emitEpilogue())
|
||||
return Method_Error;
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (!emitOutOfLinePostBarrierSlot())
|
||||
return Method_Error;
|
||||
#endif
|
||||
|
||||
if (masm.oom())
|
||||
return Method_Error;
|
||||
|
||||
@ -264,6 +272,40 @@ BaselineCompiler::emitEpilogue()
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
// On input:
|
||||
// R2.scratchReg() contains object being written to.
|
||||
// R1.scratchReg() contains slot index being written to.
|
||||
// Otherwise, baseline stack will be synced, so all other registers are usable as scratch.
|
||||
// This calls:
|
||||
// void PostWriteBarrier(JSRuntime *rt, JSObject *obj);
|
||||
bool
|
||||
BaselineCompiler::emitOutOfLinePostBarrierSlot()
|
||||
{
|
||||
masm.bind(postBarrierSlot_);
|
||||
|
||||
Register objReg = R2.scratchReg();
|
||||
GeneralRegisterSet regs(GeneralRegisterSet::All());
|
||||
regs.take(objReg);
|
||||
regs.take(BaselineFrameReg);
|
||||
Register scratch = regs.takeAny();
|
||||
#if defined(JS_CPU_ARM)
|
||||
// On ARM, save the link register before calling. It contains the return
|
||||
// address. The |masm.ret()| later will pop this into |pc| to return.
|
||||
masm.push(lr);
|
||||
#endif
|
||||
|
||||
masm.setupUnalignedABICall(2, scratch);
|
||||
masm.movePtr(ImmWord(cx->runtime), scratch);
|
||||
masm.passABIArg(scratch);
|
||||
masm.passABIArg(objReg);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, PostWriteBarrier));
|
||||
|
||||
masm.ret();
|
||||
return true;
|
||||
}
|
||||
#endif // JSGC_GENERATIONAL
|
||||
|
||||
bool
|
||||
BaselineCompiler::emitIC(ICStub *stub, bool isForOp)
|
||||
{
|
||||
@ -1676,23 +1718,36 @@ BaselineCompiler::emit_JSOP_DELPROP()
|
||||
return true;
|
||||
}
|
||||
|
||||
Address
|
||||
BaselineCompiler::getScopeCoordinateAddress(Register reg)
|
||||
void
|
||||
BaselineCompiler::getScopeCoordinateObject(Register reg)
|
||||
{
|
||||
ScopeCoordinate sc(pc);
|
||||
|
||||
masm.loadPtr(frame.addressOfScopeChain(), reg);
|
||||
for (unsigned i = sc.hops; i; i--)
|
||||
masm.extractObject(Address(reg, ScopeObject::offsetOfEnclosingScope()), reg);
|
||||
}
|
||||
|
||||
Address
|
||||
BaselineCompiler::getScopeCoordinateAddressFromObject(Register objReg, Register reg)
|
||||
{
|
||||
ScopeCoordinate sc(pc);
|
||||
Shape *shape = ScopeCoordinateToStaticScopeShape(cx, script, pc);
|
||||
|
||||
Address addr;
|
||||
if (shape->numFixedSlots() <= sc.slot) {
|
||||
masm.loadPtr(Address(reg, JSObject::offsetOfSlots()), reg);
|
||||
masm.loadPtr(Address(objReg, JSObject::offsetOfSlots()), reg);
|
||||
return Address(reg, (sc.slot - shape->numFixedSlots()) * sizeof(Value));
|
||||
}
|
||||
|
||||
return Address(reg, JSObject::getFixedSlotOffset(sc.slot));
|
||||
return Address(objReg, JSObject::getFixedSlotOffset(sc.slot));
|
||||
}
|
||||
|
||||
Address
|
||||
BaselineCompiler::getScopeCoordinateAddress(Register reg)
|
||||
{
|
||||
getScopeCoordinateObject(reg);
|
||||
return getScopeCoordinateAddressFromObject(reg, reg);
|
||||
}
|
||||
|
||||
bool
|
||||
@ -1720,13 +1775,34 @@ BaselineCompiler::emit_JSOP_CALLALIASEDVAR()
|
||||
bool
|
||||
BaselineCompiler::emit_JSOP_SETALIASEDVAR()
|
||||
{
|
||||
// Sync everything except the top value, so that we can use R0 as scratch
|
||||
// (storeValue does not touch it if the top value is in R0).
|
||||
frame.syncStack(1);
|
||||
// Keep rvalue in R0.
|
||||
frame.popRegsAndSync(1);
|
||||
Register objReg = R2.scratchReg();
|
||||
|
||||
Address address = getScopeCoordinateAddress(R2.scratchReg());
|
||||
getScopeCoordinateObject(objReg);
|
||||
Address address = getScopeCoordinateAddressFromObject(objReg, R1.scratchReg());
|
||||
masm.patchableCallPreBarrier(address, MIRType_Value);
|
||||
storeValue(frame.peek(-1), address, R0);
|
||||
masm.storeValue(R0, address);
|
||||
frame.push(R0);
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
// Fully sync the stack if post-barrier is needed.
|
||||
// Scope coordinate object is already in R2.scratchReg().
|
||||
frame.syncStack(0);
|
||||
|
||||
Nursery &nursery = cx->runtime->gcNursery;
|
||||
Label skipBarrier;
|
||||
Label isTenured;
|
||||
masm.branchTestObject(Assembler::NotEqual, R0, &skipBarrier);
|
||||
masm.branchPtr(Assembler::Below, objReg, ImmWord(nursery.start()), &isTenured);
|
||||
masm.branchPtr(Assembler::Below, objReg, ImmWord(nursery.end()), &skipBarrier);
|
||||
|
||||
masm.bind(&isTenured);
|
||||
masm.call(postBarrierSlot_);
|
||||
|
||||
masm.bind(&skipBarrier);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -176,6 +176,9 @@ class BaselineCompiler : public BaselineCompilerSpecific
|
||||
{
|
||||
FixedList<Label> labels_;
|
||||
HeapLabel * return_;
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
HeapLabel * postBarrierSlot_;
|
||||
#endif
|
||||
|
||||
// Native code offset right before the scope chain is initialized.
|
||||
CodeOffsetLabel prologueOffset_;
|
||||
@ -195,6 +198,9 @@ class BaselineCompiler : public BaselineCompilerSpecific
|
||||
|
||||
bool emitPrologue();
|
||||
bool emitEpilogue();
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
bool emitOutOfLinePostBarrierSlot();
|
||||
#endif
|
||||
bool emitIC(ICStub *stub, bool isForOp);
|
||||
bool emitOpIC(ICStub *stub) {
|
||||
return emitIC(stub, true);
|
||||
@ -246,6 +252,8 @@ class BaselineCompiler : public BaselineCompilerSpecific
|
||||
|
||||
bool addPCMappingEntry(bool addIndexEntry);
|
||||
|
||||
void getScopeCoordinateObject(Register reg);
|
||||
Address getScopeCoordinateAddressFromObject(Register objReg, Register reg);
|
||||
Address getScopeCoordinateAddress(Register reg);
|
||||
};
|
||||
|
||||
|
@ -11,8 +11,10 @@
|
||||
# include "x86/BaselineHelpers-x86.h"
|
||||
#elif defined(JS_CPU_X64)
|
||||
# include "x64/BaselineHelpers-x64.h"
|
||||
#else
|
||||
#elif defined(JS_CPU_ARM)
|
||||
# include "arm/BaselineHelpers-arm.h"
|
||||
#else
|
||||
# error "Unknown architecture!"
|
||||
#endif
|
||||
|
||||
namespace js {
|
||||
|
@ -638,6 +638,37 @@ ICStubCompiler::guardProfilingEnabled(MacroAssembler &masm, Register scratch, La
|
||||
masm.branch32(Assembler::Equal, AbsoluteAddress(enabledAddr), Imm32(0), skip);
|
||||
}
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
inline bool
|
||||
ICStubCompiler::emitPostWriteBarrierSlot(MacroAssembler &masm, Register obj, Register scratch,
|
||||
GeneralRegisterSet saveRegs)
|
||||
{
|
||||
Nursery &nursery = cx->runtime->gcNursery;
|
||||
|
||||
Label skipBarrier;
|
||||
Label isTenured;
|
||||
masm.branchPtr(Assembler::Below, obj, ImmWord(nursery.start()), &isTenured);
|
||||
masm.branchPtr(Assembler::Below, obj, ImmWord(nursery.end()), &skipBarrier);
|
||||
masm.bind(&isTenured);
|
||||
|
||||
// void PostWriteBarrier(JSRuntime *rt, JSObject *obj);
|
||||
#ifdef JS_CPU_ARM
|
||||
saveRegs.add(BaselineTailCallReg);
|
||||
#endif
|
||||
saveRegs = GeneralRegisterSet::Intersect(saveRegs, GeneralRegisterSet::Volatile());
|
||||
masm.PushRegsInMask(saveRegs);
|
||||
masm.setupUnalignedABICall(2, scratch);
|
||||
masm.movePtr(ImmWord(cx->runtime), scratch);
|
||||
masm.passABIArg(scratch);
|
||||
masm.passABIArg(obj);
|
||||
masm.callWithABI(JS_FUNC_TO_DATA_PTR(void *, PostWriteBarrier));
|
||||
masm.PopRegsInMask(saveRegs);
|
||||
|
||||
masm.bind(&skipBarrier);
|
||||
return true;
|
||||
}
|
||||
#endif // JSGC_GENERATIONAL
|
||||
|
||||
//
|
||||
// UseCount_Fallback
|
||||
//
|
||||
@ -4324,12 +4355,13 @@ ICSetElem_Dense::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
regs = availableGeneralRegs(2);
|
||||
scratchReg = regs.takeAny();
|
||||
|
||||
// Unbox object and key.
|
||||
obj = masm.extractObject(R0, ExtractTemp0);
|
||||
Register key = masm.extractInt32(R1, ExtractTemp1);
|
||||
|
||||
// Load obj->elements in scratchReg.
|
||||
masm.loadPtr(Address(obj, JSObject::offsetOfElements()), scratchReg);
|
||||
|
||||
// Unbox key.
|
||||
Register key = masm.extractInt32(R1, ExtractTemp1);
|
||||
|
||||
// Bounds check.
|
||||
Address initLength(scratchReg, ObjectElements::offsetOfInitializedLength());
|
||||
masm.branch32(Assembler::BelowOrEqual, initLength, key, &failure);
|
||||
@ -4338,32 +4370,50 @@ ICSetElem_Dense::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
BaseIndex element(scratchReg, key, TimesEight);
|
||||
masm.branchTestMagic(Assembler::Equal, element, &failure);
|
||||
|
||||
// Failure is not possible now. Free up registers.
|
||||
regs.add(R0);
|
||||
regs.add(R1);
|
||||
regs.takeUnchecked(obj);
|
||||
regs.takeUnchecked(key);
|
||||
Address valueAddr(BaselineStackReg, ICStackValueOffset);
|
||||
|
||||
// Convert int32 values to double if convertDoubleElements is set. In this
|
||||
// case the heap typeset is guaranteed to contain both int32 and double, so
|
||||
// it's okay to store a double.
|
||||
Label convertDoubles, convertDoublesDone;
|
||||
Label dontConvertDoubles;
|
||||
Address elementsFlags(scratchReg, ObjectElements::offsetOfFlags());
|
||||
masm.branchTest32(Assembler::NonZero, elementsFlags,
|
||||
masm.branchTest32(Assembler::Zero, elementsFlags,
|
||||
Imm32(ObjectElements::CONVERT_DOUBLE_ELEMENTS),
|
||||
&convertDoubles);
|
||||
masm.bind(&convertDoublesDone);
|
||||
|
||||
// It's safe to overwrite R0 now.
|
||||
Address valueAddr(BaselineStackReg, ICStackValueOffset);
|
||||
masm.loadValue(valueAddr, R0);
|
||||
EmitPreBarrier(masm, element, MIRType_Value);
|
||||
masm.storeValue(R0, element);
|
||||
EmitReturnFromIC(masm);
|
||||
|
||||
// Convert to double and jump back. Note that double arrays are only
|
||||
// created by IonMonkey, so if we have no floating-point support
|
||||
// Ion is disabled and there should be no double arrays.
|
||||
masm.bind(&convertDoubles);
|
||||
&dontConvertDoubles);
|
||||
// Note that double arrays are only created by IonMonkey, so if we have no
|
||||
// floating-point support Ion is disabled and there should be no double arrays.
|
||||
if (cx->runtime->jitSupportsFloatingPoint)
|
||||
masm.convertInt32ValueToDouble(valueAddr, R0.scratchReg(), &convertDoublesDone);
|
||||
masm.convertInt32ValueToDouble(valueAddr, regs.getAny(), &dontConvertDoubles);
|
||||
else
|
||||
masm.breakpoint();
|
||||
masm.jump(&convertDoublesDone);
|
||||
masm.bind(&dontConvertDoubles);
|
||||
|
||||
// Don't overwrite R0 becuase |obj| might overlap with it, and it's needed
|
||||
// for post-write barrier later.
|
||||
ValueOperand tmpVal = regs.takeAnyValue();
|
||||
masm.loadValue(valueAddr, tmpVal);
|
||||
EmitPreBarrier(masm, element, MIRType_Value);
|
||||
masm.storeValue(tmpVal, element);
|
||||
regs.add(key);
|
||||
regs.add(tmpVal);
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
Label skipBarrier;
|
||||
masm.branchTestObject(Assembler::NotEqual, tmpVal, &skipBarrier);
|
||||
{
|
||||
Register r = regs.takeAny();
|
||||
GeneralRegisterSet saveRegs;
|
||||
emitPostWriteBarrierSlot(masm, obj, r, saveRegs);
|
||||
regs.add(r);
|
||||
}
|
||||
masm.bind(&skipBarrier);
|
||||
#endif
|
||||
EmitReturnFromIC(masm);
|
||||
|
||||
|
||||
// Failure case - fail but first unstow R0 and R1
|
||||
masm.bind(&failureUnstow);
|
||||
@ -4459,6 +4509,7 @@ ICSetElemDenseAddCompiler::generateStubCode(MacroAssembler &masm)
|
||||
Register protoReg = regs.takeAny();
|
||||
for (size_t i = 0; i < protoChainDepth_; i++) {
|
||||
masm.loadObjProto(i == 0 ? obj : protoReg, protoReg);
|
||||
masm.branchTestPtr(Assembler::Zero, protoReg, protoReg, &failureUnstow);
|
||||
masm.loadPtr(Address(BaselineStubReg, ICSetElem_DenseAddImpl<0>::offsetOfShape(i + 1)),
|
||||
scratchReg);
|
||||
masm.branchTestObjShape(Assembler::NotEqual, protoReg, scratchReg, &failureUnstow);
|
||||
@ -4481,12 +4532,13 @@ ICSetElemDenseAddCompiler::generateStubCode(MacroAssembler &masm)
|
||||
regs = availableGeneralRegs(2);
|
||||
scratchReg = regs.takeAny();
|
||||
|
||||
// Unbox obj and key.
|
||||
obj = masm.extractObject(R0, ExtractTemp0);
|
||||
Register key = masm.extractInt32(R1, ExtractTemp1);
|
||||
|
||||
// Load obj->elements in scratchReg.
|
||||
masm.loadPtr(Address(obj, JSObject::offsetOfElements()), scratchReg);
|
||||
|
||||
// Unbox key.
|
||||
Register key = masm.extractInt32(R1, ExtractTemp1);
|
||||
|
||||
// Bounds check (key == initLength)
|
||||
Address initLength(scratchReg, ObjectElements::offsetOfInitializedLength());
|
||||
masm.branch32(Assembler::NotEqual, initLength, key, &failure);
|
||||
@ -4495,6 +4547,12 @@ ICSetElemDenseAddCompiler::generateStubCode(MacroAssembler &masm)
|
||||
Address capacity(scratchReg, ObjectElements::offsetOfCapacity());
|
||||
masm.branch32(Assembler::BelowOrEqual, capacity, key, &failure);
|
||||
|
||||
// Failure is not possible now. Free up registers.
|
||||
regs.add(R0);
|
||||
regs.add(R1);
|
||||
regs.takeUnchecked(obj);
|
||||
regs.takeUnchecked(key);
|
||||
|
||||
// Increment initLength before write.
|
||||
masm.add32(Imm32(1), initLength);
|
||||
|
||||
@ -4505,33 +4563,43 @@ ICSetElemDenseAddCompiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.add32(Imm32(1), length);
|
||||
masm.bind(&skipIncrementLength);
|
||||
|
||||
Address valueAddr(BaselineStackReg, ICStackValueOffset);
|
||||
|
||||
// Convert int32 values to double if convertDoubleElements is set. In this
|
||||
// case the heap typeset is guaranteed to contain both int32 and double, so
|
||||
// it's okay to store a double.
|
||||
Label convertDoubles, convertDoublesDone;
|
||||
Label dontConvertDoubles;
|
||||
Address elementsFlags(scratchReg, ObjectElements::offsetOfFlags());
|
||||
masm.branchTest32(Assembler::NonZero, elementsFlags,
|
||||
masm.branchTest32(Assembler::Zero, elementsFlags,
|
||||
Imm32(ObjectElements::CONVERT_DOUBLE_ELEMENTS),
|
||||
&convertDoubles);
|
||||
masm.bind(&convertDoublesDone);
|
||||
|
||||
// Write the value. No need for write barrier since we're not overwriting an old value.
|
||||
// It's safe to overwrite R0 now.
|
||||
BaseIndex element(scratchReg, key, TimesEight);
|
||||
Address valueAddr(BaselineStackReg, ICStackValueOffset);
|
||||
masm.loadValue(valueAddr, R0);
|
||||
masm.storeValue(R0, element);
|
||||
EmitReturnFromIC(masm);
|
||||
|
||||
// Convert to double and jump back. Note that double arrays are only
|
||||
// created by IonMonkey, so if we have no floating-point support
|
||||
// Ion is disabled and there should be no double arrays.
|
||||
masm.bind(&convertDoubles);
|
||||
&dontConvertDoubles);
|
||||
// Note that double arrays are only created by IonMonkey, so if we have no
|
||||
// floating-point support Ion is disabled and there should be no double arrays.
|
||||
if (cx->runtime->jitSupportsFloatingPoint)
|
||||
masm.convertInt32ValueToDouble(valueAddr, R0.scratchReg(), &convertDoublesDone);
|
||||
masm.convertInt32ValueToDouble(valueAddr, regs.getAny(), &dontConvertDoubles);
|
||||
else
|
||||
masm.breakpoint();
|
||||
masm.jump(&convertDoublesDone);
|
||||
masm.bind(&dontConvertDoubles);
|
||||
|
||||
// Write the value. No need for pre-barrier since we're not overwriting an old value.
|
||||
ValueOperand tmpVal = regs.takeAnyValue();
|
||||
BaseIndex element(scratchReg, key, TimesEight);
|
||||
masm.loadValue(valueAddr, tmpVal);
|
||||
masm.storeValue(tmpVal, element);
|
||||
regs.add(key);
|
||||
regs.add(tmpVal);
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
Label skipBarrier;
|
||||
masm.branchTestObject(Assembler::NotEqual, tmpVal, &skipBarrier);
|
||||
{
|
||||
Register r = regs.takeAny();
|
||||
GeneralRegisterSet saveRegs;
|
||||
emitPostWriteBarrierSlot(masm, obj, r, saveRegs);
|
||||
regs.add(r);
|
||||
}
|
||||
masm.bind(&skipBarrier);
|
||||
#endif
|
||||
EmitReturnFromIC(masm);
|
||||
|
||||
// Failure case - fail but first unstow R0 and R1
|
||||
masm.bind(&failureUnstow);
|
||||
@ -6299,13 +6367,35 @@ ICSetProp_Native::Compiler::generateStubCode(MacroAssembler &masm)
|
||||
// Unstow R0 and R1 (object and key)
|
||||
EmitUnstowICValues(masm, 2);
|
||||
|
||||
if (!isFixedSlot_)
|
||||
masm.loadPtr(Address(objReg, JSObject::offsetOfSlots()), objReg);
|
||||
regs.add(R0);
|
||||
regs.takeUnchecked(objReg);
|
||||
|
||||
Register holderReg;
|
||||
if (isFixedSlot_) {
|
||||
holderReg = objReg;
|
||||
} else {
|
||||
holderReg = regs.takeAny();
|
||||
masm.loadPtr(Address(objReg, JSObject::offsetOfSlots()), holderReg);
|
||||
}
|
||||
|
||||
// Perform the store.
|
||||
masm.load32(Address(BaselineStubReg, ICSetProp_Native::offsetOfOffset()), scratch);
|
||||
EmitPreBarrier(masm, BaseIndex(objReg, scratch, TimesOne), MIRType_Value);
|
||||
masm.storeValue(R1, BaseIndex(objReg, scratch, TimesOne));
|
||||
EmitPreBarrier(masm, BaseIndex(holderReg, scratch, TimesOne), MIRType_Value);
|
||||
masm.storeValue(R1, BaseIndex(holderReg, scratch, TimesOne));
|
||||
if (holderReg != objReg)
|
||||
regs.add(holderReg);
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
Label skipBarrier;
|
||||
masm.branchTestObject(Assembler::NotEqual, R1, &skipBarrier);
|
||||
{
|
||||
Register scr = regs.takeAny();
|
||||
GeneralRegisterSet saveRegs;
|
||||
saveRegs.add(R1);
|
||||
emitPostWriteBarrierSlot(masm, objReg, scr, saveRegs);
|
||||
regs.add(scr);
|
||||
}
|
||||
masm.bind(&skipBarrier);
|
||||
#endif
|
||||
|
||||
// The RHS has to be in R0.
|
||||
masm.moveValue(R1, R0);
|
||||
@ -6374,6 +6464,7 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler &masm)
|
||||
// Check the proto chain.
|
||||
for (size_t i = 0; i < protoChainDepth_; i++) {
|
||||
masm.loadObjProto(i == 0 ? objReg : protoReg, protoReg);
|
||||
masm.branchTestPtr(Assembler::Zero, protoReg, protoReg, &failureUnstow);
|
||||
masm.loadPtr(Address(BaselineStubReg, ICSetProp_NativeAddImpl<0>::offsetOfShape(i + 1)),
|
||||
scratch);
|
||||
masm.branchTestObjShape(Assembler::NotEqual, protoReg, scratch, &failureUnstow);
|
||||
@ -6400,13 +6491,35 @@ ICSetPropNativeAddCompiler::generateStubCode(MacroAssembler &masm)
|
||||
masm.loadPtr(Address(BaselineStubReg, ICSetProp_NativeAdd::offsetOfNewShape()), scratch);
|
||||
masm.storePtr(scratch, shapeAddr);
|
||||
|
||||
if (!isFixedSlot_)
|
||||
masm.loadPtr(Address(objReg, JSObject::offsetOfSlots()), objReg);
|
||||
Register holderReg;
|
||||
regs.add(R0);
|
||||
regs.takeUnchecked(objReg);
|
||||
if (isFixedSlot_) {
|
||||
holderReg = objReg;
|
||||
} else {
|
||||
holderReg = regs.takeAny();
|
||||
masm.loadPtr(Address(objReg, JSObject::offsetOfSlots()), holderReg);
|
||||
}
|
||||
|
||||
// Perform the store. No write barrier required since this is a new
|
||||
// initialization.
|
||||
masm.load32(Address(BaselineStubReg, ICSetProp_NativeAdd::offsetOfOffset()), scratch);
|
||||
masm.storeValue(R1, BaseIndex(objReg, scratch, TimesOne));
|
||||
masm.storeValue(R1, BaseIndex(holderReg, scratch, TimesOne));
|
||||
|
||||
if (holderReg != objReg)
|
||||
regs.add(holderReg);
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
Label skipBarrier;
|
||||
masm.branchTestObject(Assembler::NotEqual, R1, &skipBarrier);
|
||||
{
|
||||
Register scr = regs.takeAny();
|
||||
GeneralRegisterSet saveRegs;
|
||||
saveRegs.add(R1);
|
||||
emitPostWriteBarrierSlot(masm, objReg, scr, saveRegs);
|
||||
}
|
||||
masm.bind(&skipBarrier);
|
||||
#endif
|
||||
|
||||
// The RHS has to be in R0.
|
||||
masm.moveValue(R1, R0);
|
||||
@ -8225,7 +8338,8 @@ ICSetProp_Native::Compiler::getStub(ICStubSpace *space)
|
||||
|
||||
ICSetProp_NativeAdd::ICSetProp_NativeAdd(IonCode *stubCode, HandleTypeObject type,
|
||||
size_t protoChainDepth,
|
||||
HandleShape newShape, uint32_t offset)
|
||||
HandleShape newShape,
|
||||
uint32_t offset)
|
||||
: ICUpdatedStub(SetProp_NativeAdd, stubCode),
|
||||
type_(type),
|
||||
newShape_(newShape),
|
||||
@ -8250,7 +8364,8 @@ ICSetProp_NativeAddImpl<ProtoChainDepth>::ICSetProp_NativeAddImpl(IonCode *stubC
|
||||
|
||||
ICSetPropNativeAddCompiler::ICSetPropNativeAddCompiler(JSContext *cx, HandleObject obj,
|
||||
HandleShape oldShape,
|
||||
size_t protoChainDepth, bool isFixedSlot,
|
||||
size_t protoChainDepth,
|
||||
bool isFixedSlot,
|
||||
uint32_t offset)
|
||||
: ICStubCompiler(cx, ICStub::SetProp_NativeAdd),
|
||||
obj_(cx, obj),
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user