Merge last PGO-green changeset of mozilla-inbound to mozilla-central

This commit is contained in:
Ed Morley 2013-01-08 11:32:07 +00:00
commit 2e7fd7927e
182 changed files with 2630 additions and 864 deletions

View File

@ -92,8 +92,8 @@ MustBeAccessible(nsIContent* aContent, DocAccessible* aDocument)
if (aContent->GetPrimaryFrame()->IsFocusable())
return true;
PRUint32 attrCount = aContent->GetAttrCount();
for (PRUint32 attrIdx = 0; attrIdx < attrCount; attrIdx++) {
uint32_t attrCount = aContent->GetAttrCount();
for (uint32_t attrIdx = 0; attrIdx < attrCount; attrIdx++) {
const nsAttrName* attr = aContent->GetAttrNameAt(attrIdx);
if (attr->NamespaceEquals(kNameSpaceID_None)) {
nsIAtom* attrAtom = attr->Atom();

View File

@ -88,12 +88,32 @@ ContentPermissionPrompt.prototype = {
return false;
},
_id: 0,
prompt: function(request) {
// returns true if the request was handled
if (this.handleExistingPermission(request))
return;
// If the request was initiated from a hidden iframe
// we don't forward it to content and cancel it right away
let frame = request.element;
if (!frame) {
this.delegatePrompt(request);
}
var self = this;
frame.wrappedJSObject.getVisible().onsuccess = function gv_success(evt) {
if (!evt.target.result) {
request.cancel();
return;
}
self.delegatePrompt(request);
};
},
_id: 0,
delegatePrompt: function(request) {
let browser = Services.wm.getMostRecentWindow("navigator:browser");
let content = browser.getContentWindow();
if (!content)

View File

@ -132,7 +132,7 @@ let SocialUI = {
break;
}
} catch (e) {
Components.utils.reportError(e + e.stack);
Components.utils.reportError(e + "\n" + e.stack);
throw e;
}
},
@ -719,6 +719,8 @@ var SocialToolbar = {
if (!Social.provider)
return;
this.button.style.listStyleImage = "url(" + Social.provider.iconURL + ")";
this.button.setAttribute("label", Social.provider.name);
this.button.setAttribute("tooltiptext", Social.provider.name);
this.updateButton();
this.updateProfile();
this.populateProviderMenus();
@ -779,7 +781,6 @@ var SocialToolbar = {
let provider = Social.provider;
let icons = provider.ambientNotificationIcons;
let iconNames = Object.keys(icons);
let iconBox = document.getElementById("social-toolbar-item");
let panel = document.getElementById("social-notification-panel");
panel.hidden = false;
@ -824,7 +825,7 @@ var SocialToolbar = {
str);
}
let iconContainers = document.createDocumentFragment();
let toolbarButtons = document.createDocumentFragment();
let createdFrames = [];
@ -835,7 +836,6 @@ var SocialToolbar = {
let notificationFrame = document.getElementById(notificationFrameId);
if (!notificationFrame) {
notificationFrame = SharedFrame.createFrame(
notificationFrameId, /* frame name */
panel, /* parent */
@ -860,56 +860,41 @@ var SocialToolbar = {
SharedFrame.updateURL(notificationFrameId, icon.contentPanel);
}
let iconId = "social-notification-icon-" + icon.name;
let imageId = iconId + "-image";
let labelId = iconId + "-label";
let stackId = iconId + "-stack";
let stack = document.getElementById(stackId);
let image, label;
if (stack) {
image = document.getElementById(imageId);
label = document.getElementById(labelId);
} else {
let box = document.createElement("box");
box.classList.add("toolbarbutton-1");
box.setAttribute("id", iconId);
// Use the accessibility menuitem label as tooltiptext.
if (icon.label)
box.setAttribute("tooltiptext", icon.label);
box.addEventListener("mousedown", function (e) {
if (e.button == 0)
SocialToolbar.showAmbientPopup(box);
}, false);
box.setAttribute("notificationFrameId", notificationFrameId);
stack = document.createElement("stack");
stack.setAttribute("id", stackId);
stack.classList.add("social-notification-icon-stack");
stack.classList.add("toolbarbutton-icon");
image = document.createElement("image");
image.setAttribute("id", imageId);
image.classList.add("social-notification-icon-image");
image = stack.appendChild(image);
label = document.createElement("label");
label.setAttribute("id", labelId);
label.classList.add("social-notification-icon-label");
let hbox = document.createElement("hbox");
hbox.classList.add("social-notification-icon-hbox");
hbox.setAttribute("align", "start");
hbox.setAttribute("pack", "end");
label = hbox.appendChild(label);
stack.appendChild(hbox);
box.appendChild(stack);
iconContainers.appendChild(box);
let toolbarButtonContainerId = "social-notification-container-" + icon.name;
let toolbarButtonId = "social-notification-icon-" + icon.name;
let toolbarButtonContainer = document.getElementById(toolbarButtonContainerId);
let toolbarButton = document.getElementById(toolbarButtonId);
if (!toolbarButtonContainer) {
// The container is used to fix an issue with position:absolute on
// generated content not being constrained to the bounding box of a
// parent toolbarbutton that has position:relative.
toolbarButtonContainer = document.createElement("toolbaritem");
toolbarButtonContainer.classList.add("social-notification-container");
toolbarButtonContainer.setAttribute("id", toolbarButtonContainerId);
toolbarButton = document.createElement("toolbarbutton");
toolbarButton.classList.add("toolbarbutton-1");
toolbarButton.setAttribute("id", toolbarButtonId);
toolbarButton.setAttribute("notificationFrameId", notificationFrameId);
toolbarButton.addEventListener("mousedown", function (event) {
if (event.button == 0)
SocialToolbar.showAmbientPopup(toolbarButton);
});
toolbarButtonContainer.appendChild(toolbarButton);
toolbarButtons.appendChild(toolbarButtonContainer);
}
let labelValue = icon.counter || "";
// Only update the value attribute if it has changed to reduce layout changes.
if (!label.hasAttribute("value") || label.getAttribute("value") != labelValue)
label.setAttribute("value", labelValue);
toolbarButton.style.listStyleImage = "url(" + icon.iconURL + ")";
toolbarButton.setAttribute("label", icon.label);
toolbarButton.setAttribute("tooltiptext", icon.label);
image.style.listStyleImage = "url(" + icon.iconURL + ")";
let badge = icon.counter || "";
if (toolbarButton.getAttribute("badge") != badge)
toolbarButton.setAttribute("badge", badge);
}
iconBox.appendChild(iconContainers);
let socialToolbarItem = document.getElementById("social-toolbar-item");
socialToolbarItem.appendChild(toolbarButtons);
for (let frame of createdFrames) {
if (frame.docShell) {
@ -923,12 +908,12 @@ var SocialToolbar = {
}
},
showAmbientPopup: function SocialToolbar_showAmbientPopup(aToolbarButtonBox) {
showAmbientPopup: function SocialToolbar_showAmbientPopup(aToolbarButton) {
// Hide any other social panels that may be open.
SocialFlyout.panel.hidePopup();
let panel = document.getElementById("social-notification-panel");
let notificationFrameId = aToolbarButtonBox.getAttribute("notificationFrameId");
let notificationFrameId = aToolbarButton.getAttribute("notificationFrameId");
let notificationFrame = document.getElementById(notificationFrameId);
let wasAlive = SharedFrame.isGroupAlive(notificationFrameId);
@ -951,7 +936,8 @@ var SocialToolbar = {
let dynamicResizer = this._dynamicResizer;
panel.addEventListener("popuphidden", function onpopuphiding() {
panel.removeEventListener("popuphidden", onpopuphiding);
aToolbarButtonBox.removeAttribute("open");
aToolbarButton.removeAttribute("open");
aToolbarButton.parentNode.removeAttribute("open");
dynamicResizer.stop();
notificationFrame.docShell.isActive = false;
dispatchPanelEvent("socialFrameHide");
@ -959,7 +945,13 @@ var SocialToolbar = {
panel.addEventListener("popupshown", function onpopupshown() {
panel.removeEventListener("popupshown", onpopupshown);
aToolbarButtonBox.setAttribute("open", "true");
// This attribute is needed on both the button and the
// containing toolbaritem since the buttons on OS X have
// moz-appearance:none, while their container gets
// moz-appearance:toolbarbutton due to the way that toolbar buttons
// get combined on OS X.
aToolbarButton.setAttribute("open", "true");
aToolbarButton.parentNode.setAttribute("open", "true");
notificationFrame.docShell.isActive = true;
notificationFrame.docShell.isAppTab = true;
if (notificationFrame.contentDocument.readyState == "complete" && wasAlive) {
@ -977,9 +969,8 @@ var SocialToolbar = {
}
});
let imageId = aToolbarButtonBox.getAttribute("id") + "-image";
let toolbarButtonImage = document.getElementById(imageId);
panel.openPopup(toolbarButtonImage, "bottomcenter topright", 0, 0, false, false);
let toolbarButtonIcon = document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-icon");
panel.openPopup(toolbarButtonIcon, "bottomcenter topright", 0, 0, false, false);
},
setPanelErrorMessage: function SocialToolbar_setPanelErrorMessage(aNotificationFrame) {

View File

@ -618,6 +618,10 @@ html|*#gcli-output-frame,
transition: none;
}
.social-notification-container > .toolbarbutton-1[badge]:not([badge=""])::after {
content: attr(badge);
}
chatbox {
-moz-binding: url("chrome://browser/content/socialchat.xml#chatbox");
}

View File

@ -6925,6 +6925,12 @@ let gPrivateBrowsingUI = {
return;
}
#ifdef XP_MACOSX
if (!PrivateBrowsingUtils.permanentPrivateBrowsing) {
document.documentElement.setAttribute("drawintitlebar", true);
}
#endif
// Disable the Clear Recent History... menu item when in PB mode
// temporary fix until bug 463607 is fixed
document.getElementById("Tools:Sanitize").setAttribute("disabled", "true");
@ -6936,7 +6942,8 @@ let gPrivateBrowsingUI = {
docElement.getAttribute("title_privatebrowsing"));
docElement.setAttribute("titlemodifier",
docElement.getAttribute("titlemodifier_privatebrowsing"));
docElement.setAttribute("privatebrowsingmode", "temporary");
docElement.setAttribute("privatebrowsingmode",
PrivateBrowsingUtils.permanentPrivateBrowsing ? "permanent" : "temporary");
gBrowser.updateTitlebar();
}

View File

@ -28,10 +28,10 @@ var tests = {
}
function triggerIconPanel() {
let statusIcon = document.querySelector("#social-toolbar-item > box");
let statusIcon = document.querySelector("#social-toolbar-item > .social-notification-container > .toolbarbutton-1");
info("status icon is " + statusIcon);
waitForCondition(function() {
statusIcon = document.querySelector("#social-toolbar-item > box");
statusIcon = document.querySelector("#social-toolbar-item > .social-notification-container > .toolbarbutton-1");
info("status icon is " + statusIcon);
return !!statusIcon;
}, function() {

View File

@ -103,17 +103,18 @@ var tests = {
Social.provider.setAmbientNotification(ambience2);
Social.provider.setAmbientNotification(ambience3);
let statusIcon = document.querySelector("#social-toolbar-item > box");
let statusIcon = document.querySelector("#social-toolbar-item > .social-notification-container > .toolbarbutton-1");
waitForCondition(function() {
statusIcon = document.querySelector("#social-toolbar-item > box");
statusIcon = document.querySelector("#social-toolbar-item > .social-notification-container > .toolbarbutton-1");
return !!statusIcon;
}, function () {
let statusIconLabel = statusIcon.querySelector("label");
is(statusIconLabel.value, "42", "status value is correct");
let badge = statusIcon.getAttribute("badge");
is(badge, "42", "status value is correct");
ambience.counter = 0;
Social.provider.setAmbientNotification(ambience);
is(statusIconLabel.value, "", "status value is correct");
badge = statusIcon.getAttribute("badge");
is(badge, "", "status value is correct");
// The menu bar isn't as easy to instrument on Mac.
if (navigator.platform.contains("Mac"))

View File

@ -17,8 +17,11 @@ XPIDLSRCS = \
nsIBrowserHandler.idl \
$(NULL)
EXTRA_PP_COMPONENTS = \
EXTRA_COMPONENTS = \
BrowserComponents.manifest \
$(NULL)
EXTRA_PP_COMPONENTS = \
nsBrowserContentHandler.js \
nsBrowserGlue.js \
$(NULL)

View File

@ -13,12 +13,12 @@ richlistitem.download {
.download-state:not(:-moz-any([state="2"], /* Failed */
[state="4"]) /* Paused */)
.downloadCancelMenuItem,
.download-state:not(:-moz-any([state="1"], /* Finished */
[state="2"], /* Failed */
[state="3"], /* Canceled */
[state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */)
.download-state[state]:not(:-moz-any([state="1"], /* Finished */
[state="2"], /* Failed */
[state="3"], /* Canceled */
[state="6"], /* Blocked (parental) */
[state="8"], /* Blocked (dirty) */
[state="9"]) /* Blocked (policy) */)
.downloadRemoveFromHistoryMenuItem,
.download-state:not(:-moz-any([state="-1"],/* Starting (initial) */
[state="0"], /* Downloading */
@ -26,8 +26,7 @@ richlistitem.download {
[state="4"], /* Paused */
[state="5"]) /* Starting (queued) */)
.downloadShowMenuItem,
.download-state[state="7"] .downloadCommandsSeparator,
.download-state:not([state]) .downloadCommandsSeparator
.download-state[state="7"] .downloadCommandsSeparator
{
display: none;
}

View File

@ -154,8 +154,13 @@ DownloadElementShell.prototype = {
get _icon() {
if (this._targetFileURI)
return "moz-icon://" + this._targetFileURI + "?size=32";
if (this._placesNode)
return this.placesNode.icon;
if (this._placesNode) {
// Try to extract an extension from the uri.
let ext = this._downloadURIObj.QueryInterface(Ci.nsIURL).fileExtension;
if (ext)
return "moz-icon://." + ext + "?size=32";
return this._placesNode.icon || "moz-icon://.unknown?size=32";
}
if (this._dataItem)
throw new Error("Session-download items should always have a target file uri");
throw new Error("Unexpected download element state");

View File

@ -437,7 +437,7 @@ this.DownloadsCommon = {
}
if (showAlert) {
let name = this.dataItem.target;
let name = aFile.leafName;
let message =
DownloadsCommon.strings.fileExecutableSecurityWarning(name, name);
let title =

View File

@ -27,7 +27,7 @@ browser.jar:
content/browser/debugger-view.js (debugger/debugger-view.js)
content/browser/debugger-toolbar.js (debugger/debugger-toolbar.js)
content/browser/debugger-panes.js (debugger/debugger-panes.js)
* content/browser/profiler.xul (profiler/profiler.xul)
content/browser/profiler.xul (profiler/profiler.xul)
content/browser/profiler.css (profiler/profiler.css)
content/browser/devtools/cleopatra.html (profiler/cleopatra/cleopatra.html)
content/browser/devtools/profiler/cleopatra/css/ui.css (profiler/cleopatra/css/ui.css)

View File

@ -2344,29 +2344,8 @@ html|*#gcli-output-frame {
-moz-margin-end: 2px;
}
#social-toolbar-item {
-moz-box-orient: horizontal;
}
#social-toolbar-item > .toolbarbutton-1 {
margin: 0;
padding: 0;
-moz-appearance: toolbarbutton;
}
.social-notification-icon-hbox {
pointer-events: none;
}
.social-status-button {
list-style-image: none;
}
#social-provider-button {
-moz-image-region: rect(0, 16px, 16px, 0);
}
#social-provider-button > image {
#social-toolbar-item > .toolbarbutton-1 > .toolbarbutton-icon,
.social-notification-container > .toolbarbutton-1 > .toolbarbutton-icon {
margin: 5px 3px;
}
@ -2374,33 +2353,32 @@ html|*#gcli-output-frame {
display: none;
}
.social-notification-icon-stack {
padding: 0;
.social-notification-container {
/* position:relative on .toolbarbutton-1 does not get position:absolute
to work as expected on .toolbarbutton-1 generated content. Placing a
simple container outside of .toolbarbutton-1 and setting position:relative
on the simple container however will work. */
position: relative;
}
.social-notification-icon-image {
margin: 5px 3px;
-moz-image-region: rect(0, 16px, 16px, 0);
}
.social-notification-icon-hbox {
padding: 0;
}
.social-notification-icon-label {
background-color: rgb(240,61,37);
border: 1px solid rgb(216,55,34);
box-shadow: 0px 1px 0px rgba(0,39,121,0.77);
padding-right: 1px;
padding-left: 1px;
color: white;
.social-notification-container > .toolbarbutton-1[badge]:not([badge=""])::after {
/* The |content| property is set in the content stylesheet. */
font-size: 9px;
font-weight: bold;
margin: 0;
padding: 0 1px;
color: #fff;
background-color: rgb(240,61,37);
border: 1px solid rgb(216,55,34);
border-radius: 2px;
box-shadow: 0 1px 0 rgba(0,39,121,0.77);
position: absolute;
top: 2px;
right: 2px;
}
.social-notification-icon-label[value=""] {
display: none;
.social-notification-container > .toolbarbutton-1[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
left: 2px;
right: auto;
}
/* social toolbar provider menu */

View File

@ -2392,7 +2392,7 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
text-shadow: inherit;
}
#navigator-toolbox[tabsontop="true"]:not(:-moz-lwtheme)::before {
#main-window:not([privatebrowsingmode=temporary]) #navigator-toolbox[tabsontop="true"]:not(:-moz-lwtheme)::before {
/* We want the titlebar to be unified, but we still want to be able
* to give #TabsToolbar a background. So we can't set -moz-appearance:
* toolbar on #TabsToolbar itself. Instead, we set it on a box of the
@ -3002,11 +3002,6 @@ toolbarbutton.chevron > .toolbarbutton-menu-dropmarker {
}
}
#notification-popup .text-link, .panel-arrowcontent .text-link {
color: #0073e6;
text-decoration: none;
}
#geolocation-learnmore-link {
-moz-margin-start: 0; /* override default label margin to match description margin */
}
@ -3803,30 +3798,16 @@ html|*#gcli-output-frame {
/* === social toolbar button === */
/* button icon for the service */
toolbar[mode="icons"] > *|* > .social-notification-container {
-moz-appearance: toolbarbutton;
}
.social-notification-container > .toolbarbutton-1 {
-moz-appearance: none;
}
#social-toolbar-item {
-moz-box-orient: horizontal;
}
#social-toolbar-item > .toolbarbutton-1:not(:first-child):not(:last-child) {
margin-left: 0;
margin-right: 0;
}
#social-toolbar-item > .toolbarbutton-1:first-child {
-moz-margin-end: 0;
}
#social-toolbar-item > .toolbarbutton-1:last-child {
-moz-margin-start: 0;
}
.social-notification-icon-hbox {
pointer-events: none;
}
.social-status-button {
list-style-image: none;
margin: 0 4px;
}
#social-provider-button {
@ -3837,39 +3818,40 @@ html|*#gcli-output-frame {
display: none;
}
.social-notification-icon-stack {
padding: 0;
.social-notification-container {
/* position:relative on .toolbarbutton-1 does not get position:absolute
to work as expected on .toolbarbutton-1 generated content. Placing a
simple container outside of .toolbarbutton-1 and setting position:relative
on the simple container however will work. */
position: relative;
}
.social-notification-icon-hbox {
padding: 0;
}
.social-notification-icon-label {
text-align: end;
.social-notification-container > .toolbarbutton-1[badge]:not([badge=""])::after {
/* The |content| property is set in the content stylesheet. */
font-size: 9px;
font-weight: bold;
padding: 0 1px;
color: white;
margin: 0;
color: #fff;
background-color: rgb(240,61,37);
border: 1px solid rgb(216,55,34);
border-radius: 2px;
box-shadow: 0 1px 0 rgba(0,39,121,0.77);
-moz-margin-end: -4px;
margin-top: -4px;
position: absolute;
top: 2px;
right: 0;
}
.social-notification-icon-label[value=""] {
display: none;
.social-notification-container > .toolbarbutton-1[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
left: 0;
right: auto;
}
@media (-moz-mac-lion-theme) {
.social-notification-icon-stack > image:-moz-window-inactive {
opacity: .5;
}
toolbar[mode="icons"] > *|* > .social-notification-container > .toolbarbutton-1[badge]:not([badge=""])::after {
right: -2px;
}
.social-notification-icon-image {
-moz-image-region: rect(0, 16px, 16px, 0);
toolbar[mode="icons"] > *|* > .social-notification-container > .toolbarbutton-1[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
left: -2px;
}
/* === end of social toolbar button === */
@ -4161,3 +4143,27 @@ panel[type="arrow"][popupid="click-to-play-plugins"] > .panel-arrowcontainer > .
.center-item-button {
min-width: 0;
}
%ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
#main-window[privatebrowsingmode=temporary] {
background-image: url("chrome://browser/skin/privatebrowsing-mask.png");
background-position: top right;
background-repeat: no-repeat;
background-color: -moz-mac-chrome-active;
}
@media (-moz-mac-lion-theme) {
#main-window[privatebrowsingmode=temporary] {
background-position: top right 40px;
}
#main-window[privatebrowsingmode=temporary]:-moz-locale-dir(rtl) {
background-position: top left 70px;
}
}
#main-window[privatebrowsingmode=temporary]:-moz-window-inactive {
background-color: -moz-mac-chrome-inactive;
}
%endif

View File

@ -48,6 +48,7 @@ browser.jar:
skin/classic/browser/pageInfo.css
skin/classic/browser/Privacy-16.png
skin/classic/browser/Privacy-48.png
skin/classic/browser/privatebrowsing-mask.png
skin/classic/browser/reload-stop-go.png
skin/classic/browser/reload-stop-go@2x.png
skin/classic/browser/searchbar-dropmarker.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -727,7 +727,8 @@ toolbar[mode=full] .toolbarbutton-1 > .toolbarbutton-menubutton-button {
}
@navbarLargeIcons@ .toolbarbutton-1:not(:hover):not(:active):not([open]) > .toolbarbutton-menubutton-dropmarker::before,
@navbarLargeIcons@ > #social-toolbar-item > .toolbarbutton-1:not(:hover) + .toolbarbutton-1:not(:hover)::before {
@navbarLargeIcons@ > #social-toolbar-item > .toolbarbutton-1:not(:hover) + .social-notification-container:not(:hover) > .toolbarbutton-1::before,
@navbarLargeIcons@ > #social-toolbar-item > .social-notification-container:not(:hover) + .social-notification-container:not(:hover) > .toolbarbutton-1::before {
content: "";
display: -moz-box;
width: 1px;
@ -3028,6 +3029,7 @@ html|*#gcli-output-frame {
}
/* Social toolbar item */
#social-provider-button {
-moz-image-region: rect(0, 16px, 16px, 0);
}
@ -3036,47 +3038,47 @@ html|*#gcli-output-frame {
display: none;
}
#social-toolbar-item > .toolbarbutton-1 {
padding: 5px;
-moz-appearance: toolbarbutton;
@navbarLargeIcons@ > #social-toolbar-item > .toolbarbutton-1,
@navbarLargeIcons@ > #social-toolbar-item > .social-notification-container > .toolbarbutton-1 {
padding-left: 0;
padding-right: 0;
}
@navbarLargeIcons@ > #social-toolbar-item > .toolbarbutton-1 {
padding: 6px 0;
@navbarLargeIcons@ > #social-toolbar-item {
margin-left: 5px;
margin-right: 5px;
}
@navbarLargeIcons@ > #social-toolbar-item > .toolbarbutton-1:first-child {
-moz-padding-start: 5px;
.social-notification-container {
/* position:relative on .toolbarbutton-1 does not get position:absolute
to work as expected on .toolbarbutton-1 generated content. Placing a
simple container outside of .toolbarbutton-1 and setting position:relative
on the simple container however will work. */
position: relative;
}
@navbarLargeIcons@ > #social-toolbar-item > .toolbarbutton-1:last-child {
-moz-padding-end: 5px;
}
.social-notification-icon-hbox {
pointer-events: none;
margin-top: -5px;
-moz-margin-end: -12px;
}
.social-notification-icon-label {
text-align: end;
.social-notification-container > .toolbarbutton-1[badge]:not([badge=""])::after {
/* The |content| property is set in the content stylesheet. */
font-size: 9px;
font-weight: bold;
padding: 0 1px;
color: white;
color: #fff;
background-color: rgb(240,61,37);
border: 1px solid rgb(216,55,34);
border-radius: 2px;
box-shadow: 0 1px 0 rgba(0,39,121,0.77);
position: absolute;
top: 2px;
right: 2px;
}
.social-notification-icon-label[value=""] {
display: none;
@navbarLargeIcons@ > *|* > .social-notification-container > .toolbarbutton-1[badge]:not([badge=""])::after {
top: 7px;
}
.social-notification-icon-image {
-moz-image-region: rect(0, 16px, 16px, 0);
.social-notification-container > .toolbarbutton-1[badge]:not([badge=""]):-moz-locale-dir(rtl)::after {
left: 2px;
right: auto;
}
/* social toolbar provider menu */
@ -3377,3 +3379,20 @@ chatbox[minimized="true"] {
.center-item-button {
min-width: 0;
}
%ifdef MOZ_PER_WINDOW_PRIVATE_BROWSING
#main-window[privatebrowsingmode=temporary] #toolbar-menubar {
background-image: url("chrome://browser/skin/privatebrowsing-dark.png");
background-position: top right;
background-repeat: no-repeat;
}
#main-window[privatebrowsingmode=temporary] #toolbar-menubar:-moz-locale-dir(rtl) {
background-position: top left;
}
#main-window[privatebrowsingmode=temporary] #appmenu-button {
list-style-image: url("chrome://browser/skin/privatebrowsing-light.png");
}
%endif

View File

@ -44,6 +44,8 @@ browser.jar:
skin/classic/browser/page-livemarks.png (feeds/feedIcon16.png)
skin/classic/browser/Privacy-16.png
skin/classic/browser/Privacy-48.png
skin/classic/browser/privatebrowsing-light.png
skin/classic/browser/privatebrowsing-dark.png
skin/classic/browser/reload-stop-go.png
skin/classic/browser/searchbar.css
skin/classic/browser/searchbar-dropdown-arrow.png
@ -266,6 +268,8 @@ browser.jar:
skin/classic/aero/browser/page-livemarks.png (feeds/feedIcon16-aero.png)
skin/classic/aero/browser/Privacy-16.png (Privacy-16-aero.png)
skin/classic/aero/browser/Privacy-48.png (Privacy-48-aero.png)
skin/classic/aero/browser/privatebrowsing-light.png
skin/classic/aero/browser/privatebrowsing-dark.png
skin/classic/aero/browser/reload-stop-go.png
skin/classic/aero/browser/searchbar.css
skin/classic/aero/browser/searchbar-dropdown-arrow.png (searchbar-dropdown-arrow-aero.png)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

View File

@ -74,6 +74,7 @@ class nsStyleSet;
class nsTextNode;
class nsWindowSizes;
class nsSmallVoidArray;
class nsDOMCaretPosition;
namespace mozilla {
class ErrorResult;
@ -1916,6 +1917,19 @@ public:
virtual nsIDOMDOMStringList* StyleSheetSets() = 0;
virtual void EnableStyleSheetsForSet(const nsAString& aSheetSet) = 0;
Element* ElementFromPoint(float aX, float aY);
/**
* Retrieve the location of the caret position (DOM node and character
* offset within that node), given a point.
*
* @param aX Horizontal point at which to determine the caret position, in
* page coordinates.
* @param aY Vertical point at which to determine the caret position, in
* page coordinates.
*/
already_AddRefed<nsDOMCaretPosition>
CaretPositionFromPoint(float aX, float aY);
// QuerySelector and QuerySelectorAll already defined on nsINode
nsINodeList* GetAnonymousNodes(Element& aElement);
Element* GetAnonymousElementByAttribute(Element& aElement,

View File

@ -8853,32 +8853,29 @@ ResetFullScreen(nsIDocument* aDocument, void* aData)
return true;
}
NS_IMETHODIMP
nsDocument::CaretPositionFromPoint(float aX, float aY, nsISupports** aCaretPos)
already_AddRefed<nsDOMCaretPosition>
nsIDocument::CaretPositionFromPoint(float aX, float aY)
{
NS_ENSURE_ARG_POINTER(aCaretPos);
*aCaretPos = nullptr;
nscoord x = nsPresContext::CSSPixelsToAppUnits(aX);
nscoord y = nsPresContext::CSSPixelsToAppUnits(aY);
nsPoint pt(x, y);
nsIPresShell *ps = GetShell();
if (!ps) {
return NS_OK;
return nullptr;
}
nsIFrame *rootFrame = ps->GetRootFrame();
// XUL docs, unlike HTML, have no frame tree until everything's done loading
if (!rootFrame) {
return NS_OK; // return null to premature XUL callers as a reminder to wait
return nullptr;
}
nsIFrame *ptFrame = nsLayoutUtils::GetFrameForPoint(rootFrame, pt, true,
false);
if (!ptFrame) {
return NS_OK;
return nullptr;
}
// GetContentOffsetsFromPoint requires frame-relative coordinates, so we need
@ -8906,8 +8903,15 @@ nsDocument::CaretPositionFromPoint(float aX, float aY, nsISupports** aCaretPos)
}
}
*aCaretPos = new nsDOMCaretPosition(node, offset);
NS_ADDREF(*aCaretPos);
nsRefPtr<nsDOMCaretPosition> aCaretPos = new nsDOMCaretPosition(node, offset);
return aCaretPos.forget();
}
NS_IMETHODIMP
nsDocument::CaretPositionFromPoint(float aX, float aY, nsISupports** aCaretPos)
{
NS_ENSURE_ARG_POINTER(aCaretPos);
*aCaretPos = nsIDocument::CaretPositionFromPoint(aX, aY).get();
return NS_OK;
}

View File

@ -506,8 +506,8 @@ MOCHITEST_FILES_B = \
file_html_in_xhr3.html \
file_html_in_xhr.sjs \
test_bug647518.html \
test_bug654352.html \
Ahem.ttf \
test_caretPositionFromPoint.html \
Ahem.ttf \
test_bug664916.html \
test_bug666604.html \
test_bug675121.html \

View File

@ -64,6 +64,16 @@
checkOffsetsFromPoint(test4Rect.left + 1, test4Rect.top + 1, 0);
checkOffsetsFromPoint(Math.round(test4Rect.left + convertEmToPx(3)), Math.round(test4Rect.top + 10), 3);
// Check to make sure that x or y outside the viewport returns null.
var nullCp1 = document.caretPositionFromPoint(-10, 0);
ok(!nullCp1, "caret position with negative x should be null");
var nullCp2 = document.caretPositionFromPoint(0, -10);
ok(!nullCp2, "caret position with negative y should be null");
var nullCp3 = document.caretPositionFromPoint(9000, 0);
ok(!nullCp3, "caret position with x > viewport width should be null");
var nullCp4 = document.caretPositionFromPoint(0, 9000);
ok(!nullCp4, "caret position with x > viewport height should be null");
// Check the first and last characters of the marquee.
SimpleTest.finish();
}

View File

@ -3166,9 +3166,6 @@ WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width,
WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
uint32_t dataByteLen = JS_GetTypedArrayByteLength(pixels->Obj());
int dataType = JS_GetTypedArrayType(pixels->Obj());
uint32_t channels = 0;
// Check the format param
@ -3205,6 +3202,8 @@ WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width,
return ErrorInvalidEnum("readPixels: Bad type");
}
int dataType = JS_GetArrayBufferViewType(pixels->Obj());
// Check the pixels param type
if (dataType != requiredDataType)
return ErrorInvalidOperation("readPixels: Mismatched type/pixels types");
@ -3221,6 +3220,7 @@ WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width,
if (!checked_neededByteLength.isValid())
return ErrorInvalidOperation("readPixels: integer overflow computing the needed buffer size");
uint32_t dataByteLen = JS_GetTypedArrayByteLength(pixels->Obj());
if (checked_neededByteLength.value() > dataByteLen)
return ErrorInvalidOperation("readPixels: buffer too small");
@ -4890,7 +4890,7 @@ WebGLContext::TexImage2D(WebGLenum target, WebGLint level,
return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type,
pixels ? pixels->Data() : 0,
pixels ? pixels->Length() : 0,
pixels ? (int)JS_GetTypedArrayType(pixels->Obj()) : -1,
pixels ? (int)JS_GetArrayBufferViewType(pixels->Obj()) : -1,
WebGLTexelConversions::Auto, false);
}
@ -5044,7 +5044,7 @@ WebGLContext::TexSubImage2D(WebGLenum target, WebGLint level,
return TexSubImage2D_base(target, level, xoffset, yoffset,
width, height, 0, format, type,
pixels->Data(), pixels->Length(),
JS_GetTypedArrayType(pixels->Obj()),
JS_GetArrayBufferViewType(pixels->Obj()),
WebGLTexelConversions::Auto, false);
}

View File

@ -240,6 +240,11 @@ public:
return style;
}
/**
* Determine whether an attribute is an event (onclick, etc.)
* @param aName the attribute
* @return whether the name is an event handler name
*/
virtual bool IsEventAttributeName(nsIAtom* aName) MOZ_OVERRIDE;
#define EVENT(name_, id_, type_, struct_) /* nothing; handled by nsINode */
@ -773,13 +778,6 @@ private:
void RegUnRegAccessKey(bool aDoReg);
protected:
/**
* Determine whether an attribute is an event (onclick, etc.)
* @param aName the attribute
* @return whether the name is an event handler name
*/
bool IsEventName(nsIAtom* aName);
virtual nsresult BeforeSetAttr(int32_t aNamespaceID, nsIAtom* aName,
const nsAttrValueOrString* aValue,
bool aNotify);

View File

@ -821,8 +821,8 @@ void MediaDecoder::PlaybackEnded()
PlaybackPositionChanged();
ChangeState(PLAY_STATE_ENDED);
UpdateReadyStateForData();
if (mOwner) {
UpdateReadyStateForData();
mOwner->PlaybackEnded();
}

View File

@ -68,7 +68,6 @@ CPPSRCS = \
nsSVGUnknownElement.cpp \
nsSVGUseElement.cpp \
nsSVGViewBox.cpp \
nsSVGViewElement.cpp \
SVGAltGlyphElement.cpp \
SVGAngle.cpp \
SVGAnimatedAngle.cpp \
@ -137,6 +136,7 @@ CPPSRCS = \
SVGTransformListSMILType.cpp \
SVGTSpanElement.cpp \
SVGViewBoxSMILType.cpp \
SVGViewElement.cpp \
$(NULL)
include $(topsrcdir)/config/config.mk
@ -188,6 +188,7 @@ EXPORTS_mozilla/dom = \
SVGTitleElement.h \
SVGTransformableElement.h \
SVGTSpanElement.h \
SVGViewElement.h \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -6,7 +6,7 @@
#include "SVGFragmentIdentifier.h"
#include "nsIDOMSVGDocument.h"
#include "nsSVGSVGElement.h"
#include "nsSVGViewElement.h"
#include "mozilla/dom/SVGViewElement.h"
#include "SVGAnimatedTransformList.h"
using namespace mozilla;
@ -27,12 +27,12 @@ IgnoreWhitespace(PRUnichar aChar)
return false;
}
static nsSVGViewElement*
static dom::SVGViewElement*
GetViewElement(nsIDocument *aDocument, const nsAString &aId)
{
dom::Element* element = aDocument->GetElementById(aId);
return (element && element->IsSVG(nsGkAtoms::view)) ?
static_cast<nsSVGViewElement*>(element) : nullptr;
static_cast<dom::SVGViewElement*>(element) : nullptr;
}
void
@ -236,7 +236,7 @@ SVGFragmentIdentifier::ProcessFragmentIdentifier(nsIDocument *aDocument,
SaveOldZoomAndPan(rootElement);
}
const nsSVGViewElement *viewElement = GetViewElement(aDocument, aAnchorName);
const dom::SVGViewElement *viewElement = GetViewElement(aDocument, aAnchorName);
if (viewElement) {
if (!rootElement->mCurrentViewID) {

View File

@ -3,24 +3,35 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsSVGViewElement.h"
#include "mozilla/dom/SVGViewElement.h"
#include "mozilla/dom/SVGViewElementBinding.h"
#include "DOMSVGStringList.h"
using namespace mozilla;
using namespace mozilla::dom;
DOMCI_NODE_DATA(SVGViewElement, mozilla::dom::SVGViewElement)
nsSVGElement::StringListInfo nsSVGViewElement::sStringListInfo[1] =
NS_IMPL_NS_NEW_NAMESPACED_SVG_ELEMENT(View)
namespace mozilla {
namespace dom {
JSObject*
SVGViewElement::WrapNode(JSContext *aCx, JSObject *aScope, bool *aTriedToWrap)
{
return SVGViewElementBinding::Wrap(aCx, aScope, this, aTriedToWrap);
}
nsSVGElement::StringListInfo SVGViewElement::sStringListInfo[1] =
{
{ &nsGkAtoms::viewTarget }
};
nsSVGEnumMapping nsSVGViewElement::sZoomAndPanMap[] = {
nsSVGEnumMapping SVGViewElement::sZoomAndPanMap[] = {
{&nsGkAtoms::disable, nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_DISABLE},
{&nsGkAtoms::magnify, nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY},
{nullptr, 0}
};
nsSVGElement::EnumInfo nsSVGViewElement::sEnumInfo[1] =
nsSVGElement::EnumInfo SVGViewElement::sEnumInfo[1] =
{
{ &nsGkAtoms::zoomAndPan,
sZoomAndPanMap,
@ -28,58 +39,62 @@ nsSVGElement::EnumInfo nsSVGViewElement::sEnumInfo[1] =
}
};
NS_IMPL_NS_NEW_SVG_ELEMENT(View)
//----------------------------------------------------------------------
// nsISupports methods
NS_IMPL_ADDREF_INHERITED(nsSVGViewElement,nsSVGViewElementBase)
NS_IMPL_RELEASE_INHERITED(nsSVGViewElement,nsSVGViewElementBase)
NS_IMPL_ADDREF_INHERITED(SVGViewElement,SVGViewElementBase)
NS_IMPL_RELEASE_INHERITED(SVGViewElement,SVGViewElementBase)
DOMCI_NODE_DATA(SVGViewElement, nsSVGViewElement)
NS_INTERFACE_TABLE_HEAD(nsSVGViewElement)
NS_NODE_INTERFACE_TABLE6(nsSVGViewElement, nsIDOMNode, nsIDOMElement,
NS_INTERFACE_TABLE_HEAD(SVGViewElement)
NS_NODE_INTERFACE_TABLE6(SVGViewElement, nsIDOMNode, nsIDOMElement,
nsIDOMSVGElement, nsIDOMSVGViewElement,
nsIDOMSVGFitToViewBox,
nsIDOMSVGZoomAndPan)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(SVGViewElement)
NS_INTERFACE_MAP_END_INHERITING(nsSVGViewElementBase)
NS_INTERFACE_MAP_END_INHERITING(SVGViewElementBase)
//----------------------------------------------------------------------
// Implementation
nsSVGViewElement::nsSVGViewElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: nsSVGViewElementBase(aNodeInfo)
SVGViewElement::SVGViewElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: SVGViewElementBase(aNodeInfo)
{
}
//----------------------------------------------------------------------
// nsIDOMNode methods
NS_IMPL_ELEMENT_CLONE_WITH_INIT(nsSVGViewElement)
NS_IMPL_ELEMENT_CLONE_WITH_INIT(SVGViewElement)
//----------------------------------------------------------------------
// nsIDOMSVGZoomAndPan methods
/* attribute unsigned short zoomAndPan; */
NS_IMETHODIMP
nsSVGViewElement::GetZoomAndPan(uint16_t *aZoomAndPan)
SVGViewElement::GetZoomAndPan(uint16_t *aZoomAndPan)
{
*aZoomAndPan = mEnumAttributes[ZOOMANDPAN].GetAnimValue();
*aZoomAndPan = ZoomAndPan();
return NS_OK;
}
NS_IMETHODIMP
nsSVGViewElement::SetZoomAndPan(uint16_t aZoomAndPan)
SVGViewElement::SetZoomAndPan(uint16_t aZoomAndPan)
{
ErrorResult rv;
SetZoomAndPan(aZoomAndPan, rv);
return rv.ErrorCode();
}
void
SVGViewElement::SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv)
{
if (aZoomAndPan == nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_DISABLE ||
aZoomAndPan == nsIDOMSVGZoomAndPan::SVG_ZOOMANDPAN_MAGNIFY) {
mEnumAttributes[ZOOMANDPAN].SetBaseValue(aZoomAndPan, this);
return NS_OK;
return;
}
return NS_ERROR_RANGE_ERR;
rv.Throw(NS_ERROR_RANGE_ERR);
}
//----------------------------------------------------------------------
@ -87,58 +102,82 @@ nsSVGViewElement::SetZoomAndPan(uint16_t aZoomAndPan)
/* readonly attribute nsIDOMSVGAnimatedRect viewBox; */
NS_IMETHODIMP
nsSVGViewElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox)
SVGViewElement::GetViewBox(nsIDOMSVGAnimatedRect * *aViewBox)
{
return mViewBox.ToDOMAnimatedRect(aViewBox, this);
*aViewBox = ViewBox().get();
return NS_OK;
}
already_AddRefed<nsIDOMSVGAnimatedRect>
SVGViewElement::ViewBox()
{
nsCOMPtr<nsIDOMSVGAnimatedRect> box;
mViewBox.ToDOMAnimatedRect(getter_AddRefs(box), this);
return box.forget();
}
/* readonly attribute SVGPreserveAspectRatio preserveAspectRatio; */
NS_IMETHODIMP
nsSVGViewElement::GetPreserveAspectRatio(nsISupports
**aPreserveAspectRatio)
SVGViewElement::GetPreserveAspectRatio(nsISupports
**aPreserveAspectRatio)
{
*aPreserveAspectRatio = PreserveAspectRatio().get();
return NS_OK;
}
already_AddRefed<DOMSVGAnimatedPreserveAspectRatio>
SVGViewElement::PreserveAspectRatio()
{
nsRefPtr<DOMSVGAnimatedPreserveAspectRatio> ratio;
mPreserveAspectRatio.ToDOMAnimatedPreserveAspectRatio(getter_AddRefs(ratio), this);
ratio.forget(aPreserveAspectRatio);
return NS_OK;
return ratio.forget();
}
//----------------------------------------------------------------------
// nsIDOMSVGViewElement methods
/* readonly attribute nsIDOMSVGStringList viewTarget; */
NS_IMETHODIMP nsSVGViewElement::GetViewTarget(nsIDOMSVGStringList * *aViewTarget)
NS_IMETHODIMP SVGViewElement::GetViewTarget(nsIDOMSVGStringList * *aViewTarget)
{
*aViewTarget = DOMSVGStringList::GetDOMWrapper(
&mStringListAttributes[VIEW_TARGET], this, false, VIEW_TARGET).get();
*aViewTarget = ViewTarget().get();
return NS_OK;
}
already_AddRefed<nsIDOMSVGStringList>
SVGViewElement::ViewTarget()
{
return DOMSVGStringList::GetDOMWrapper(
&mStringListAttributes[VIEW_TARGET], this, false, VIEW_TARGET);
}
//----------------------------------------------------------------------
// nsSVGElement methods
nsSVGElement::EnumAttributesInfo
nsSVGViewElement::GetEnumInfo()
SVGViewElement::GetEnumInfo()
{
return EnumAttributesInfo(mEnumAttributes, sEnumInfo,
ArrayLength(sEnumInfo));
}
nsSVGViewBox *
nsSVGViewElement::GetViewBox()
SVGViewElement::GetViewBox()
{
return &mViewBox;
}
SVGAnimatedPreserveAspectRatio *
nsSVGViewElement::GetPreserveAspectRatio()
SVGViewElement::GetPreserveAspectRatio()
{
return &mPreserveAspectRatio;
}
nsSVGElement::StringListAttributesInfo
nsSVGViewElement::GetStringListInfo()
SVGViewElement::GetStringListInfo()
{
return StringListAttributesInfo(mStringListAttributes, sStringListInfo,
ArrayLength(sStringListInfo));
}
} // namespace dom
} // namespace mozilla

View File

@ -3,8 +3,8 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __NS_SVGVIEWELEMENT_H__
#define __NS_SVGVIEWELEMENT_H__
#ifndef mozilla_dom_SVGViewElement_h
#define mozilla_dom_SVGViewElement_h
#include "nsIDOMSVGViewElement.h"
#include "nsIDOMSVGFitToViewBox.h"
@ -15,23 +15,32 @@
#include "SVGAnimatedPreserveAspectRatio.h"
#include "SVGStringList.h"
typedef nsSVGElement SVGViewElementBase;
class nsSVGSVGElement;
class nsSVGOuterSVGFrame;
nsresult NS_NewSVGViewElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo);
namespace mozilla {
class SVGFragmentIdentifier;
}
class SVGFragmentIdentifier;
typedef nsSVGElement nsSVGViewElementBase;
namespace dom {
class nsSVGViewElement : public nsSVGViewElementBase,
public nsIDOMSVGViewElement,
public nsIDOMSVGFitToViewBox,
public nsIDOMSVGZoomAndPan
class SVGViewElement : public SVGViewElementBase,
public nsIDOMSVGViewElement,
public nsIDOMSVGFitToViewBox,
public nsIDOMSVGZoomAndPan
{
protected:
friend class mozilla::SVGFragmentIdentifier;
friend class nsSVGSVGElement;
friend class nsSVGOuterSVGFrame;
friend nsresult NS_NewSVGViewElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo);
nsSVGViewElement(already_AddRefed<nsINodeInfo> aNodeInfo);
friend class ::nsSVGSVGElement;
friend class ::nsSVGOuterSVGFrame;
SVGViewElement(already_AddRefed<nsINodeInfo> aNodeInfo);
friend nsresult (::NS_NewSVGViewElement(nsIContent **aResult,
already_AddRefed<nsINodeInfo> aNodeInfo));
virtual JSObject* WrapNode(JSContext *cx, JSObject *scope, bool *triedToWrap) MOZ_OVERRIDE;
public:
// interfaces:
@ -45,13 +54,21 @@ public:
// forward here :-(
NS_FORWARD_NSIDOMNODE_TO_NSINODE
NS_FORWARD_NSIDOMELEMENT_TO_GENERIC
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGViewElementBase::)
NS_FORWARD_NSIDOMSVGELEMENT(SVGViewElementBase::)
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
virtual nsXPCClassInfo* GetClassInfo();
virtual nsIDOMNode* AsDOMNode() { return this; }
// WebIDL
uint16_t ZoomAndPan() { return mEnumAttributes[ZOOMANDPAN].GetAnimValue(); }
void SetZoomAndPan(uint16_t aZoomAndPan, ErrorResult& rv);
already_AddRefed<nsIDOMSVGAnimatedRect> ViewBox();
already_AddRefed<DOMSVGAnimatedPreserveAspectRatio> PreserveAspectRatio();
already_AddRefed<nsIDOMSVGStringList> ViewTarget();
private:
// nsSVGElement overrides
@ -76,4 +93,7 @@ private:
static StringListInfo sStringListInfo[1];
};
#endif
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_SVGViewElement_h

View File

@ -7,7 +7,6 @@
#include "nsSVGRect.h"
#include "DOMSVGPoint.h"
#include "nsSVGSVGElement.h"
#include "nsIDOMSVGSVGElement.h"
#include "nsIPresShell.h"
#include "nsIDocument.h"
#include "mozilla/dom/Element.h"
@ -44,12 +43,11 @@ nsDOMSVGZoomEvent::nsDOMSVGZoomEvent(nsPresContext* aPresContext,
if (doc) {
Element *rootElement = doc->GetRootElement();
if (rootElement) {
// If the root element isn't an SVG 'svg' element this QI will fail
// If the root element isn't an SVG 'svg' element
// (e.g. if this event was created by calling createEvent on a
// non-SVGDocument). In these circumstances the "New" and "Previous"
// non-SVGDocument), then the "New" and "Previous"
// properties will be left null which is probably what we want.
nsCOMPtr<nsIDOMSVGSVGElement> svgElement = do_QueryInterface(rootElement);
if (svgElement) {
if (rootElement->IsSVG(nsGkAtoms::svg)) {
nsSVGSVGElement *SVGSVGElement =
static_cast<nsSVGSVGElement*>(rootElement);

View File

@ -28,7 +28,7 @@
#include "nsGUIEvent.h"
#include "nsSVGSVGElement.h"
#include "nsSVGUtils.h"
#include "nsSVGViewElement.h"
#include "mozilla/dom/SVGViewElement.h"
#include "nsStyleUtil.h"
#include "SVGContentUtils.h"
@ -608,11 +608,11 @@ nsSVGSVGElement::GetPreserveAspectRatio(nsISupports
NS_IMETHODIMP
nsSVGSVGElement::GetZoomAndPan(uint16_t *aZoomAndPan)
{
nsSVGViewElement* viewElement = GetCurrentViewElement();
SVGViewElement* viewElement = GetCurrentViewElement();
if (viewElement && viewElement->mEnumAttributes[
nsSVGViewElement::ZOOMANDPAN].IsExplicitlySet()) {
SVGViewElement::ZOOMANDPAN].IsExplicitlySet()) {
*aZoomAndPan = viewElement->mEnumAttributes[
nsSVGViewElement::ZOOMANDPAN].GetAnimValue();
SVGViewElement::ZOOMANDPAN].GetAnimValue();
} else {
*aZoomAndPan = mEnumAttributes[ZOOMANDPAN].GetAnimValue();
}
@ -974,7 +974,7 @@ nsSVGSVGElement::HasPreserveAspectRatio()
mPreserveAspectRatio.IsAnimated();
}
nsSVGViewElement*
SVGViewElement*
nsSVGSVGElement::GetCurrentViewElement() const
{
if (mCurrentViewID) {
@ -982,7 +982,7 @@ nsSVGSVGElement::GetCurrentViewElement() const
if (doc) {
Element *element = doc->GetElementById(*mCurrentViewID);
if (element && element->IsSVG(nsGkAtoms::view)) {
return static_cast<nsSVGViewElement*>(element);
return static_cast<SVGViewElement*>(element);
}
}
}
@ -994,7 +994,7 @@ nsSVGSVGElement::GetViewBoxWithSynthesis(
float aViewportWidth, float aViewportHeight) const
{
// The logic here should match HasViewBox().
nsSVGViewElement* viewElement = GetCurrentViewElement();
SVGViewElement* viewElement = GetCurrentViewElement();
if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
return viewElement->mViewBox.GetAnimValue();
}
@ -1029,7 +1029,7 @@ nsSVGSVGElement::GetPreserveAspectRatioWithOverride() const
}
}
nsSVGViewElement* viewElement = GetCurrentViewElement();
SVGViewElement* viewElement = GetCurrentViewElement();
// This check is equivalent to "!HasViewBox() && ShouldSynthesizeViewBox()".
// We're just holding onto the viewElement that HasViewBox() would look up,
@ -1055,7 +1055,7 @@ nsSVGSVGElement::GetLength(uint8_t aCtxType)
{
float h, w;
nsSVGViewElement* viewElement = GetCurrentViewElement();
SVGViewElement* viewElement = GetCurrentViewElement();
const nsSVGViewBoxRect* viewbox = nullptr;
// The logic here should match HasViewBox().
@ -1177,7 +1177,7 @@ nsSVGSVGElement::GetPreserveAspectRatio()
bool
nsSVGSVGElement::HasViewBox() const
{
nsSVGViewElement* viewElement = GetCurrentViewElement();
SVGViewElement* viewElement = GetCurrentViewElement();
if (viewElement && viewElement->mViewBox.IsExplicitlySet()) {
return true;
}

View File

@ -21,10 +21,13 @@
#include "mozilla/Attributes.h"
class nsSMILTimeContainer;
class nsSVGViewElement;
namespace mozilla {
class DOMSVGMatrix;
class SVGFragmentIdentifier;
namespace dom {
class SVGViewElement;
}
}
typedef mozilla::dom::SVGGraphicsElement nsSVGSVGElementBase;
@ -261,7 +264,7 @@ private:
// implementation helpers:
nsSVGViewElement* GetCurrentViewElement() const;
mozilla::dom::SVGViewElement* GetCurrentViewElement() const;
// Methods for <image> elements to override my "PreserveAspectRatio" value.
// These are private so that only our friends (nsSVGImageFrame in

View File

@ -1035,6 +1035,12 @@ this.DOMApplicationRegistry = {
tmpDir.remove(true);
} catch(e) { }
// Flush the zip reader cache to make sure we use the new application.zip
// when re-launching the application.
let zipFile = dir.clone();
zipFile.append("application.zip");
Services.obs.notifyObservers(zipFile, "flush-cache-entry", null);
// Get the manifest, and set properties.
this.getManifestFor(app.origin, (function(aData) {
app.downloading = false;
@ -1128,6 +1134,12 @@ this.DOMApplicationRegistry = {
return;
}
// Store the new update manifest.
let dir = FileUtils.getDir(DIRECTORY_NAME, ["webapps", id], true, true);
let manFile = dir.clone();
manFile.append("update.webapp");
this._writeFile(manFile, JSON.stringify(aManifest), function() { });
let manifest = new ManifestHelper(aManifest, app.manifestURL);
// A package is available: set downloadAvailable to fire the matching
// event.
@ -1284,7 +1296,7 @@ this.DOMApplicationRegistry = {
app.etag = xhr.getResponseHeader("Etag");
app.lastCheckedUpdate = Date.now();
if (app.origin.startsWith("app://")) {
updatePackagedApp(manifest);
updatePackagedApp.call(this, manifest);
} else {
updateHostedApp.call(this, manifest);
}
@ -2336,18 +2348,17 @@ this.DOMApplicationRegistry = {
#elifdef XP_UNIX
let env = Cc["@mozilla.org/process/environment;1"]
.getService(Ci.nsIEnvironment);
let xdg_data_home_env = env.get("XDG_DATA_HOME");
let xdg_data_home_env;
try {
xdg_data_home_env = env.get("XDG_DATA_HOME");
} catch(ex) {
}
let desktopINI;
if (xdg_data_home_env != "") {
desktopINI = Cc["@mozilla.org/file/local;1"]
.createInstance(Ci.nsIFile);
desktopINI.initWithPath(xdg_data_home_env);
}
else {
desktopINI = Services.dirsvc.get("Home", Ci.nsIFile);
desktopINI.append(".local");
desktopINI.append("share");
if (xdg_data_home_env) {
desktopINI = new FileUtils.File(xdg_data_home_env);
} else {
desktopINI = FileUtils.getFile("Home", [".local", "share"]);
}
desktopINI.append("applications");

View File

@ -741,7 +741,8 @@ nsGlobalWindow::nsGlobalWindow(nsGlobalWindow *aOuterWindow)
if (!PR_GetEnv("MOZ_QUIET")) {
printf("++DOMWINDOW == %d (%p) [serial = %d] [outer = %p]\n", gRefCnt,
static_cast<void*>(static_cast<nsIScriptGlobalObject*>(this)),
gSerialCounter, static_cast<void*>(aOuterWindow));
gSerialCounter,
static_cast<void*>(static_cast<nsIScriptGlobalObject*>(aOuterWindow)));
}
#endif
@ -816,9 +817,10 @@ nsGlobalWindow::~nsGlobalWindow()
}
}
nsGlobalWindow* outer = static_cast<nsGlobalWindow*>(mOuterWindow.get());
printf("--DOMWINDOW == %d (%p) [serial = %d] [outer = %p] [url = %s]\n",
gRefCnt, static_cast<void*>(static_cast<nsIScriptGlobalObject*>(this)),
mSerial, static_cast<void*>(mOuterWindow.get()), url.get());
mSerial, static_cast<void*>(static_cast<nsIScriptGlobalObject*>(outer)), url.get());
}
#endif

View File

@ -124,6 +124,7 @@ BrowserElementChild.prototype = {
addMsgListener("purge-history", this._recvPurgeHistory);
addMsgListener("get-screenshot", this._recvGetScreenshot);
addMsgListener("set-visible", this._recvSetVisible);
addMsgListener("get-visible", this._recvVisible);
addMsgListener("send-mouse-event", this._recvSendMouseEvent);
addMsgListener("send-touch-event", this._recvSendTouchEvent);
addMsgListener("get-can-go-back", this._recvCanGoBack);
@ -617,6 +618,13 @@ BrowserElementChild.prototype = {
this._updateDocShellVisibility();
},
_recvVisible: function(data) {
sendAsyncMsg('got-visible', {
id: data.json.id,
successRv: docShell.isActive
});
},
/**
* Called when the window which contains this iframe becomes hidden or
* visible.

View File

@ -224,6 +224,7 @@ function BrowserElementParent(frameLoader, hasRemoteFrame) {
addMessageListener('fullscreen-origin-change', this._remoteFullscreenOriginChange);
addMessageListener('rollback-fullscreen', this._remoteFrameFullscreenReverted);
addMessageListener('exit-fullscreen', this._exitFullscreen);
addMessageListener('got-visible', this._gotDOMRequestResult);
let os = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
os.addObserver(this, 'ask-children-to-exit-fullscreen', /* ownsWeak = */ true);
@ -247,6 +248,7 @@ function BrowserElementParent(frameLoader, hasRemoteFrame) {
// Define methods on the frame element.
defineMethod('setVisible', this._setVisible);
defineDOMRequestMethod('getVisible', 'get-visible');
defineMethod('sendMouseEvent', this._sendMouseEvent);
// 0 = disabled, 1 = enabled, 2 - auto detect

View File

@ -48,6 +48,23 @@ function runTest() {
}
function iframeLoaded() {
testGetVisible();
}
function testGetVisible() {
iframe1.setVisible(false);
iframe1.getVisible().onsuccess = function(evt) {
ok(evt.target.result === false, 'getVisible() responds false after setVisible(false)');
iframe1.setVisible(true);
iframe1.getVisible().onsuccess = function(evt) {
ok(evt.target.result === true, 'getVisible() responds true after setVisible(true)');
testVisibilityChanges();
};
};
}
function testVisibilityChanges() {
mm = SpecialPowers.getBrowserFrameMessageManager(iframe1);
mm.addMessageListener('test:visibilitychange', recvVisibilityChanged);
mm.loadFrameScript('data:,(' + iframeScript.toString() + ')();', false);

View File

@ -44,15 +44,29 @@ function runTest() {
}
function test1() {
expectMessage('child1:hidden', test2);
expectMessage('child1:hidden', getVisibleTest1);
iframe.setVisible(false);
}
function getVisibleTest1() {
iframe.getVisible().onsuccess = function(evt) {
ok(evt.target.result === false, 'getVisible shows a hidden frame');
test2();
};
}
function test2() {
expectMessage('child1:visible', finish);
expectMessage('child1:visible', getVisibleTest2);
iframe.setVisible(true);
}
function getVisibleTest2() {
iframe.getVisible().onsuccess = function(evt) {
ok(evt.target.result === true, 'getVisible shows a displayed frame');
finish();
};
}
function finish() {
// We need to remove this listener because when this test finishes and the
// iframe containing this document is navigated, we'll fire a

View File

@ -30,7 +30,9 @@
#include "nsContentUtils.h"
#include "nsEmbedCID.h"
#include "nsEventListenerManager.h"
#ifdef MOZ_CRASHREPORTER
#include "nsExceptionHandler.h"
#endif
#include "mozilla/dom/Element.h"
#include "nsIAppsService.h"
#include "nsIBaseWindow.h"

View File

@ -356,7 +356,7 @@ public:
nsRefPtr<MediaInputPort> port = trackunion->GetStream()->AsProcessedStream()->
AllocateInputPort(stream, MediaInputPort::FLAG_BLOCK_OUTPUT);
trackunion->mSourceStream = stream;
trackunion->mPort = port;
trackunion->mPort = port.forget();
nsPIDOMWindow *window = static_cast<nsPIDOMWindow*>
(nsGlobalWindow::GetInnerWindowWithId(mWindowID));
@ -368,8 +368,7 @@ public:
// Activate our listener. We'll call Start() on the source when get a callback
// that the MediaStream has started consuming. The listener is freed
// when the page is invalidated (on navigation or close).
mListener->Activate(stream.forget(), port.forget(),
mAudioSource, mVideoSource);
mListener->Activate(stream.forget(), mAudioSource, mVideoSource);
// Dispatch to the media thread to ask it to start the sources,
// because that can take a while
@ -1069,7 +1068,7 @@ MediaManager::OnNavigation(uint64_t aWindowID)
for (uint32_t i = 0; i < length; i++) {
nsRefPtr<GetUserMediaCallbackMediaStreamListener> listener =
listeners->ElementAt(i);
listener->Invalidate(true);
listener->Invalidate();
listener->Remove();
}
listeners->Clear();
@ -1232,9 +1231,11 @@ MediaManager::GetActiveMediaCaptureWindows(nsISupportsArray **aArray)
return NS_OK;
}
// Can be invoked from EITHER MainThread or MSG thread
void
GetUserMediaCallbackMediaStreamListener::Invalidate(bool aNeedsFinish)
GetUserMediaCallbackMediaStreamListener::Invalidate()
{
nsRefPtr<MediaOperationRunnable> runnable;
// We can't take a chance on blocking here, so proxy this to another
// thread.
@ -1242,15 +1243,33 @@ GetUserMediaCallbackMediaStreamListener::Invalidate(bool aNeedsFinish)
// source stream info.
runnable = new MediaOperationRunnable(MEDIA_STOP,
this, mAudioSource, mVideoSource,
aNeedsFinish);
mFinished);
mMediaThread->Dispatch(runnable, NS_DISPATCH_NORMAL);
}
// Called from the MediaStreamGraph thread
void
GetUserMediaCallbackMediaStreamListener::NotifyFinished(MediaStreamGraph* aGraph)
{
Invalidate(false);
mFinished = true;
Invalidate();
NS_DispatchToMainThread(new GetUserMediaListenerRemove(mWindowID, this));
}
// Called from the MediaStreamGraph thread
// this can be in response to our own RemoveListener() (via ::Remove()), or
// because the DOM GC'd the DOMLocalMediaStream/etc we're attached to.
void
GetUserMediaCallbackMediaStreamListener::NotifyRemoved(MediaStreamGraph* aGraph)
{
{
MutexAutoLock lock(mLock); // protect access to mRemoved
MM_LOG(("Listener removed by DOM Destroy(), mFinished = %d", (int) mFinished));
mRemoved = true;
}
if (!mFinished) {
NotifyFinished(aGraph);
}
}
} // namespace mozilla

View File

@ -73,21 +73,23 @@ public:
GetUserMediaCallbackMediaStreamListener(nsIThread *aThread,
uint64_t aWindowID)
: mMediaThread(aThread)
, mWindowID(aWindowID) {}
, mWindowID(aWindowID)
, mFinished(false)
, mLock("mozilla::GUMCMSL")
, mRemoved(false) {}
~GetUserMediaCallbackMediaStreamListener()
{
// It's OK to release mStream and mPort on any thread; they have thread-safe
// It's OK to release mStream on any thread; they have thread-safe
// refcounts.
}
void Activate(already_AddRefed<SourceMediaStream> aStream,
already_AddRefed<MediaInputPort> aPort,
MediaEngineSource* aAudioSource,
MediaEngineSource* aVideoSource)
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
mStream = aStream; // also serves as IsActive();
mPort = aPort;
mAudioSource = aAudioSource;
mVideoSource = aVideoSource;
mLastEndTimeAudio = 0;
@ -107,20 +109,26 @@ public:
}
// implement in .cpp to avoid circular dependency with MediaOperationRunnable
void Invalidate(bool aNeedsFinish);
// Can be invoked from EITHER MainThread or MSG thread
void Invalidate();
void
Remove()
{
NS_ASSERTION(NS_IsMainThread(), "Only call on main thread");
// allow calling even if inactive (!mStream) for easier cleanup
// Caller holds strong reference to us, so no death grip required
if (mStream) // allow even if inactive for easier cleanup
MutexAutoLock lock(mLock); // protect access to mRemoved
if (mStream && !mRemoved) {
MM_LOG(("Listener removed on purpose, mFinished = %d", (int) mFinished));
mRemoved = true; // RemoveListener is async, avoid races
mStream->RemoveListener(this);
}
}
// Proxy NotifyPull() to sources
void
NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime)
virtual void
NotifyPull(MediaStreamGraph* aGraph, StreamTime aDesiredTime) MOZ_OVERRIDE
{
// Currently audio sources ignore NotifyPull, but they could
// watch it especially for fake audio.
@ -132,18 +140,31 @@ public:
}
}
void
NotifyFinished(MediaStreamGraph* aGraph);
virtual void
NotifyFinished(MediaStreamGraph* aGraph) MOZ_OVERRIDE;
virtual void
NotifyRemoved(MediaStreamGraph* aGraph) MOZ_OVERRIDE;
private:
// Set at construction
nsCOMPtr<nsIThread> mMediaThread;
uint64_t mWindowID;
nsRefPtr<MediaEngineSource> mAudioSource;
nsRefPtr<MediaEngineSource> mVideoSource;
nsRefPtr<SourceMediaStream> mStream;
nsRefPtr<MediaInputPort> mPort;
// Set at Activate on MainThread
// Accessed from MediaStreamGraph thread, MediaManager thread, and MainThread
// No locking needed as they're only addrefed except on the MediaManager thread
nsRefPtr<MediaEngineSource> mAudioSource; // threadsafe refcnt
nsRefPtr<MediaEngineSource> mVideoSource; // threadsafe refcnt
nsRefPtr<SourceMediaStream> mStream; // threadsafe refcnt
TrackTicks mLastEndTimeAudio;
TrackTicks mLastEndTimeVideo;
bool mFinished;
// Accessed from MainThread and MSG thread
Mutex mLock; // protects mRemoved access from MainThread
bool mRemoved;
};
typedef enum {

View File

@ -12,6 +12,16 @@ const {classes: Cc, interfaces: Ci, utils: Cu, results: Cr} = Components;
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
Cu.import("resource://gre/modules/ObjectWrapper.jsm");
// Ensure NetworkStatsService and NetworkStatsDB are loaded in the parent process
// to receive messages from the child processes.
let appInfo = Cc["@mozilla.org/xre/app-info;1"];
let isParentProcess = !appInfo || appInfo.getService(Ci.nsIXULRuntime)
.processType == Ci.nsIXULRuntime.PROCESS_TYPE_DEFAULT;
if (isParentProcess) {
Cu.import("resource://gre/modules/NetworkStatsService.jsm");
}
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
@ -43,14 +53,14 @@ NetworkStatsData.prototype = {
flags: nsIClassInfo.DOM_OBJECT}),
QueryInterface : XPCOMUtils.generateQI([nsIDOMMozNetworkStatsData])
}
};
// NetworkStats
const NETWORKSTATS_CONTRACTID = "@mozilla.org/networkstats;1";
const NETWORKSTATS_CID = Components.ID("{037435a6-f563-48f3-99b3-a0106d8ba5bd}");
const nsIDOMMozNetworkStats = Components.interfaces.nsIDOMMozNetworkStats;
function NetworkStats(aStats) {
function NetworkStats(aWindow, aStats) {
if (DEBUG) {
debug("NetworkStats Constructor");
}
@ -58,11 +68,10 @@ function NetworkStats(aStats) {
this.start = aStats.start || null;
this.end = aStats.end || null;
let samples = [];
let samples = this.data = Cu.createArrayIn(aWindow);
for (let i = 0; i < aStats.data.length; i++) {
samples.push(new NetworkStatsData(aStats.data[i]));
}
this.data = samples;
}
NetworkStats.prototype = {
@ -101,7 +110,7 @@ NetworkStatsManager.prototype = {
checkPrivileges: function checkPrivileges() {
if (!this.hasPrivileges) {
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
throw Components.Exception("Permission denied", Cr.NS_ERROR_FAILURE);
}
},
@ -133,19 +142,16 @@ NetworkStatsManager.prototype = {
get connectionTypes() {
this.checkPrivileges();
return cpmm.sendSyncMessage("NetworkStats:Types")[0];
return ObjectWrapper.wrap(cpmm.sendSyncMessage("NetworkStats:Types")[0], this._window);
},
get sampleRate() {
this.checkPrivileges();
return cpmm.sendSyncMessage("NetworkStats:SampleRate")[0] / 1000;
},
get maxStorageSamples() {
this.checkPrivileges();
return cpmm.sendSyncMessage("NetworkStats:MaxStorageSamples")[0];
},
@ -170,7 +176,7 @@ NetworkStatsManager.prototype = {
return;
}
let result = new NetworkStats(msg.result);
let result = new NetworkStats(this._window, msg.result);
if (DEBUG) {
debug("result: " + JSON.stringify(result));
}
@ -198,8 +204,6 @@ NetworkStatsManager.prototype = {
if (!Services.prefs.getBoolPref("dom.mozNetworkStats.enabled")) {
return null;
}
this.initHelper(aWindow, ["NetworkStats:Get:Return",
"NetworkStats:Clear:Return"]);
let principal = aWindow.document.nodePrincipal;
let secMan = Services.scriptSecurityManager;
@ -213,6 +217,13 @@ NetworkStatsManager.prototype = {
if (DEBUG) {
debug("has privileges: " + this.hasPrivileges);
}
if (!this.hasPrivileges) {
return null;
}
this.initHelper(aWindow, ["NetworkStats:Get:Return",
"NetworkStats:Clear:Return"]);
},
// Called from DOMRequestIpcHelper
@ -235,4 +246,4 @@ NetworkStatsManager.prototype = {
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([NetworkStatsData,
NetworkStats,
NetworkStatsManager])
NetworkStatsManager]);

View File

@ -74,6 +74,10 @@ this.NetworkStatsService = {
},
receiveMessage: function(aMessage) {
if (!aMessage.target.assertPermission("networkstats-manage")) {
return;
}
if (DEBUG) {
debug("receiveMessage " + aMessage.name);
}

View File

@ -24,6 +24,9 @@ MOCHITEST_FILES = \
ifdef MOZ_B2G_RIL
MOCHITEST_FILES = \
test_networkstats_basics.html \
test_networkstats_disabled.html \
test_networkstats_enabled_no_perm.html \
test_networkstats_enabled_perm.html \
$(NULL)
endif

View File

@ -12,20 +12,13 @@
<pre id="test">
<script type="application/javascript">
/** Test for NetworkStats **/
// Test for NetworkStats
function checkInterface(aInterface) {
ok(!(aInterface in window), aInterface + " should be prefixed");
ok(("Moz" + aInterface) in window, aInterface + " should be prefixed");
}
function test() {
var gNetworkStatsEnabled = SpecialPowers.getBoolPref("dom.mozNetworkStats.enabled");
if (!gNetworkStatsEnabled) {
is(navigator.mozNetworkStats, null, "mozNetworkStats is null when not enabled.");
SimpleTest.finish();
}
// Test interfaces
checkInterface("NetworkStatsManager");
checkInterface("NetworkStats");
@ -34,7 +27,6 @@ function test() {
ok('mozNetworkStats' in navigator, "navigator.mozMozNetworkStats should exist");
ok(navigator.mozNetworkStats, "navigator.mozNetworkStats returns an object");
SpecialPowers.addPermission("networkstats-manage", true, document);
netStats = navigator.mozNetworkStats;
// Test IDL attributes
@ -279,6 +271,7 @@ var steps = [
},
function () {
ok(true, "all done!\n");
SpecialPowers.removePermission("networkstats-manage", document);
SimpleTest.finish();
return;
}
@ -298,7 +291,9 @@ function next() {
}
SimpleTest.waitForExplicitFinish();
addLoadEvent(test);
SpecialPowers.addPermission("networkstats-manage", true, document);
SpecialPowers.pushPrefEnv({'set': [["dom.mozNetworkStats.enabled", true]]}, test);
</script>
</pre>

View File

@ -0,0 +1,31 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test to ensure NetworkStats is not accessible when it is disabled</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
// Test to ensure NetworkStats is not accessible when it is disabled
SpecialPowers.pushPrefEnv({'set': [["dom.mozNetworkStats.enabled", false]]}, function(){
ok('mozNetworkStats' in navigator, "navigator.mozNetworkStats should exist");
is(navigator.mozNetworkStats, null, "mozNetworkStats should be null when not enabled.");
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,35 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test to ensure NetworkStats enabled and no networkstats-manage perm does not allow open</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
// Test to ensure NetworkStats is enabled but mozNetworkStats.connectionTypes
// does not work in content.
SpecialPowers.setBoolPref("dom.mozNetworkStats.enabled", true);
SpecialPowers.removePermission("networkstats-manage", document);
ok('mozNetworkStats' in navigator, "navigator.mozNetworkStats should be accessible if dom.mozNetworkStats.enabled is true");
var error;
try {
navigator.mozNetworkStats.connectionTypes;
ok(false, "Accessing navigator.mozNetworkStats.connectionTypes should have thrown!");
} catch (ex) {
error = ex;
}
ok(error, "Got an exception accessing navigator.mozNetworkStats.connectionTypes");
</script>
</pre>
</body>
</html>

View File

@ -0,0 +1,34 @@
<!DOCTYPE HTML>
<html>
<head>
<title>Test to ensure NetworkStats is not accessible when it is disabled</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script type="application/javascript">
"use strict";
SimpleTest.waitForExplicitFinish();
// Test to ensure NetworkStats is not accessible when it is disabled
SpecialPowers.addPermission("networkstats-manage", true, document);
SpecialPowers.pushPrefEnv({'set': [["dom.mozNetworkStats.enabled", true]]}, function(){
ok('mozNetworkStats' in navigator, "navigator.mozNetworkStats should exist");
ok(navigator.mozNetworkStats instanceof SpecialPowers.Ci.nsIDOMMozNetworkStatsManager,
"navigator.mozNetworkStats should be a nsIDOMMozNetworkStatsManager object");
SpecialPowers.removePermission("networkstats-manage", document);
SimpleTest.finish();
});
</script>
</pre>
</body>
</html>

View File

@ -95,7 +95,7 @@ PostToRIL(JSContext *cx, unsigned argc, jsval *vp)
return false;
}
uint32_t type = JS_GetTypedArrayType(obj);
uint32_t type = JS_GetArrayBufferViewType(obj);
if (type != js::ArrayBufferView::TYPE_INT8 &&
type != js::ArrayBufferView::TYPE_UINT8 &&
type != js::ArrayBufferView::TYPE_UINT8_CLAMPED) {
@ -223,7 +223,7 @@ DoNetdCommand(JSContext *cx, unsigned argc, jsval *vp)
return false;
}
uint32_t type = JS_GetTypedArrayType(obj);
uint32_t type = JS_GetArrayBufferViewType(obj);
if (type != js::ArrayBufferView::TYPE_INT8 &&
type != js::ArrayBufferView::TYPE_UINT8 &&
type != js::ArrayBufferView::TYPE_UINT8_CLAMPED) {

View File

@ -127,8 +127,13 @@ Telephony::NotifyCallsChanged(TelephonyCall* aCall)
nsRefPtr<CallEvent> event = CallEvent::Create(aCall);
NS_ASSERTION(event, "This should never fail!");
if (aCall->CallState() == nsIRadioInterfaceLayer::CALL_STATE_DIALING) {
if (aCall->CallState() == nsIRadioInterfaceLayer::CALL_STATE_DIALING ||
aCall->CallState() == nsIRadioInterfaceLayer::CALL_STATE_ALERTING ||
aCall->CallState() == nsIRadioInterfaceLayer::CALL_STATE_CONNECTED) {
NS_ASSERTION(!mActiveCall, "Already have an active call!");
mActiveCall = aCall;
} else if (mActiveCall && mActiveCall->CallIndex() == aCall->CallIndex()) {
mActiveCall = nullptr;
}
nsresult rv =
@ -383,18 +388,11 @@ Telephony::CallStateChanged(uint32_t aCallIndex, uint16_t aCallState,
}
if (modifiedCall) {
// See if this should replace our current active call.
if (aIsActive) {
if (aCallState == nsIRadioInterfaceLayer::CALL_STATE_DISCONNECTED) {
mActiveCall = nullptr;
} else {
mActiveCall = modifiedCall;
}
} else {
if (mActiveCall && mActiveCall->CallIndex() == aCallIndex) {
mActiveCall = nullptr;
}
} else if (mActiveCall && mActiveCall->CallIndex() == aCallIndex) {
mActiveCall = nullptr;
}
// Change state.
@ -403,11 +401,13 @@ Telephony::CallStateChanged(uint32_t aCallIndex, uint16_t aCallState,
return NS_OK;
}
// Didn't know anything about this call before now, could be 'incoming' or
// 'dialing' that was placed by others.
NS_ASSERTION(aCallState == nsIRadioInterfaceLayer::CALL_STATE_INCOMING ||
aCallState == nsIRadioInterfaceLayer::CALL_STATE_DIALING,
"Serious logic problem here!");
// Didn't know anything about this call before now.
if (aCallState == nsIRadioInterfaceLayer::CALL_STATE_DISCONNECTED) {
// Do nothing since we didn't know anything about it before now and it's
// been ended already.
return NS_OK;
}
nsRefPtr<TelephonyCall> call =
TelephonyCall::Create(this, aNumber, aCallState, aCallIndex);
@ -433,24 +433,22 @@ Telephony::EnumerateCallState(uint32_t aCallIndex, uint16_t aCallState,
const nsAString& aNumber, bool aIsActive,
bool* aContinue)
{
#ifdef DEBUG
// Make sure we don't somehow add duplicates.
for (uint32_t index = 0; index < mCalls.Length(); index++) {
NS_ASSERTION(mCalls[index]->CallIndex() != aCallIndex,
"Something is really wrong here!");
nsRefPtr<TelephonyCall>& tempCall = mCalls[index];
if (tempCall->CallIndex() == aCallIndex) {
// We have the call already. Skip it.
*aContinue = true;
return NS_OK;
}
}
#endif
nsRefPtr<TelephonyCall> call =
TelephonyCall::Create(this, aNumber, aCallState, aCallIndex);
NS_ASSERTION(call, "This should never fail!");
NS_ASSERTION(mCalls.Contains(call), "Should have auto-added new call!");
if (aIsActive) {
NS_ASSERTION(!mActiveCall, "Already have an active call!");
mActiveCall = call;
}
*aContinue = true;
return NS_OK;
}

View File

@ -376,7 +376,8 @@ http://dev.w3.org/csswg/cssom-view/#extensions-to-the-document-interface
partial interface Document {
*/
Element? elementFromPoint (float x, float y);
//(Not implemented)CaretPosition? caretPositionFromPoint (float x, float y);
CaretPosition? caretPositionFromPoint (float x, float y);
/*
};

View File

@ -0,0 +1,20 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/SVG2/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface SVGAnimatedRect;
[NoInterfaceObject]
interface SVGFitToViewBox {
readonly attribute SVGAnimatedRect viewBox;
readonly attribute SVGAnimatedPreserveAspectRatio preserveAspectRatio;
};

View File

@ -0,0 +1,21 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/SVG2/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
interface SVGStringList;
interface SVGViewElement : SVGElement {
readonly attribute SVGStringList viewTarget;
};
SVGViewElement implements SVGFitToViewBox;
SVGViewElement implements SVGZoomAndPan;

View File

@ -0,0 +1,24 @@
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/.
*
* The origin of this IDL file is
* http://www.w3.org/TR/SVG2/
*
* Copyright © 2012 W3C® (MIT, ERCIM, Keio), All Rights Reserved. W3C
* liability, trademark and document use rules apply.
*/
[NoInterfaceObject]
interface SVGZoomAndPan {
// Zoom and Pan Types
const unsigned short SVG_ZOOMANDPAN_UNKNOWN = 0;
const unsigned short SVG_ZOOMANDPAN_DISABLE = 1;
const unsigned short SVG_ZOOMANDPAN_MAGNIFY = 2;
[SetterThrows]
attribute unsigned short zoomAndPan;
};

View File

@ -114,6 +114,7 @@ webidl_files = \
SVGDescElement.webidl \
SVGElement.webidl \
SVGEllipseElement.webidl \
SVGFitToViewBox.webidl \
SVGForeignObjectElement.webidl \
SVGGElement.webidl \
SVGGraphicsElement.webidl \
@ -149,6 +150,8 @@ webidl_files = \
SVGTransformList.webidl \
SVGTSpanElement.webidl \
SVGURIReference.webidl \
SVGViewElement.webidl \
SVGZoomAndPan.webidl \
Text.webidl \
TextDecoder.webidl \
TextEncoder.webidl \

View File

@ -963,14 +963,12 @@ CreateDedicatedWorkerGlobalScope(JSContext* aCx)
return NULL;
}
if (worker->IsChromeWorker() &&
(!chromeworker::InitClass(aCx, global, workerProto, false) ||
!DefineChromeWorkerFunctions(aCx, global))) {
return NULL;
}
if (!DefineOSFileConstants(aCx, global)) {
return NULL;
if (worker->IsChromeWorker()) {
if (!chromeworker::InitClass(aCx, global, workerProto, false) ||
!DefineChromeWorkerFunctions(aCx, global) ||
!DefineOSFileConstants(aCx, global)) {
return NULL;
}
}
// Init other classes we care about.

View File

@ -106,6 +106,8 @@ MOCHITEST_FILES = \
transferable_worker.js \
test_errorwarning.html \
errorwarning_worker.js \
test_contentWorker.html \
content_worker.js \
$(NULL)
_SUBDIRMOCHITEST_FILES = \

View File

@ -0,0 +1,12 @@
/**
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var props = {
'ctypes': 1,
'OS': 1
};
for (var prop in props) {
postMessage({ "prop": prop, "value": self[prop] });
}
postMessage({ "testfinished": 1 });

View File

@ -0,0 +1,48 @@
<!--
Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Test for DOM Worker privileged properties</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
</head>
<body>
<p id="display"></p>
<div id="content" style="display: none">
</div>
<pre id="test">
<script class="testbody" language="javascript">
var workerFilename = "content_worker.js";
var worker = new Worker(workerFilename);
var props = {
'ctypes': 1,
'OS': 1
};
worker.onmessage = function(event) {
if (event.data.testfinished) {
SimpleTest.finish();
return;
}
var prop = event.data.prop;
ok(prop in props, "checking " + prop);
is(event.data.value, undefined, prop + " should be undefined");
};
worker.onerror = function(event) {
ok(false, "Worker had an error: " + event.message);
SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
</script>
</pre>
</body>
</html>

View File

@ -24,6 +24,7 @@ EXPORTS = \
LOCAL_INCLUDES = \
-I$(srcdir)/../../../content/base/src \
-I$(srcdir)/../../../content/svg/content/src \
$(NULL)
SDK_XPIDLSRCS = \

View File

@ -33,7 +33,7 @@
#include "nsIDOMElement.h"
#include "Link.h"
#include "mozilla/dom/Element.h"
#include "nsIDOMSVGTitleElement.h"
#include "mozilla/dom/SVGTitleElement.h"
#include "nsIDOMEvent.h"
#include "nsIDOMMouseEvent.h"
#include "nsIFormControl.h"
@ -1031,6 +1031,8 @@ DefaultTooltipTextProvider::GetNodeText(nsIDOMNode *aNode, PRUnichar **aText,
nsString outText;
nsCOMPtr<nsINode> node = do_QueryInterface(aNode);
bool lookingForSVGTitle = true;
bool found = false;
nsCOMPtr<nsIDOMNode> current ( aNode );
@ -1087,16 +1089,12 @@ DefaultTooltipTextProvider::GetNodeText(nsIDOMNode *aNode, PRUnichar **aText,
lookingForSVGTitle = UseSVGTitle(currElement);
}
if (lookingForSVGTitle) {
nsCOMPtr<nsIDOMNodeList>childNodes;
aNode->GetChildNodes(getter_AddRefs(childNodes));
uint32_t childNodeCount;
childNodes->GetLength(&childNodeCount);
nsINodeList* childNodes = node->ChildNodes();
uint32_t childNodeCount = childNodes->Length();
for (uint32_t i = 0; i < childNodeCount; i++) {
nsCOMPtr<nsIDOMNode>childNode;
childNodes->Item(i, getter_AddRefs(childNode));
nsCOMPtr<nsIDOMSVGTitleElement> titleElement(do_QueryInterface(childNode));
if (titleElement) {
titleElement->GetTextContent(outText);
nsIContent* child = childNodes->Item(i);
if (child->IsSVG(nsGkAtoms::title)) {
static_cast<dom::SVGTitleElement*>(child)->GetTextContent(outText);
if ( outText.Length() )
found = true;
break;

View File

@ -73,8 +73,6 @@
#include "nsIDOMHTMLOptionElement.h"
#include "nsIDOMHTMLTextAreaElement.h"
#include "nsIDOMHTMLDocument.h"
#include "nsIDOMSVGImageElement.h"
#include "nsIDOMSVGScriptElement.h"
#ifdef MOZ_MEDIA
#include "nsIDOMHTMLSourceElement.h"
#include "nsIDOMHTMLMediaElement.h"
@ -2700,6 +2698,12 @@ nsresult nsWebBrowserPersist::OnWalkDOMNode(nsIDOMNode *aNode)
return NS_OK;
}
nsCOMPtr<nsIContent> content = do_QueryInterface(aNode);
if (!content)
{
return NS_OK;
}
// Test the node to see if it's an image, frame, iframe, css, js
nsCOMPtr<nsIDOMHTMLImageElement> nodeAsImage = do_QueryInterface(aNode);
if (nodeAsImage)
@ -2708,8 +2712,7 @@ nsresult nsWebBrowserPersist::OnWalkDOMNode(nsIDOMNode *aNode)
return NS_OK;
}
nsCOMPtr<nsIDOMSVGImageElement> nodeAsSVGImage = do_QueryInterface(aNode);
if (nodeAsSVGImage)
if (content->IsSVG(nsGkAtoms::img))
{
StoreURIAttributeNS(aNode, "http://www.w3.org/1999/xlink", "href");
return NS_OK;
@ -2765,8 +2768,7 @@ nsresult nsWebBrowserPersist::OnWalkDOMNode(nsIDOMNode *aNode)
return NS_OK;
}
nsCOMPtr<nsIDOMSVGScriptElement> nodeAsSVGScript = do_QueryInterface(aNode);
if (nodeAsSVGScript)
if (content->IsSVG(nsGkAtoms::script))
{
StoreURIAttributeNS(aNode, "http://www.w3.org/1999/xlink", "href");
return NS_OK;
@ -2991,6 +2993,12 @@ nsWebBrowserPersist::CloneNodeWithFixedUpAttributes(
}
}
nsCOMPtr<nsIContent> content = do_QueryInterface(aNodeIn);
if (!content)
{
return NS_OK;
}
// Fix up href and file links in the elements
nsCOMPtr<nsIDOMHTMLAnchorElement> nodeAsAnchor = do_QueryInterface(aNodeIn);
@ -3103,8 +3111,7 @@ nsWebBrowserPersist::CloneNodeWithFixedUpAttributes(
}
#endif // MOZ_MEDIA
nsCOMPtr<nsIDOMSVGImageElement> nodeAsSVGImage = do_QueryInterface(aNodeIn);
if (nodeAsSVGImage)
if (content->IsSVG(nsGkAtoms::img))
{
rv = GetNodeToFixup(aNodeIn, aNodeOut);
if (NS_SUCCEEDED(rv) && *aNodeOut)
@ -3132,8 +3139,7 @@ nsWebBrowserPersist::CloneNodeWithFixedUpAttributes(
return rv;
}
nsCOMPtr<nsIDOMSVGScriptElement> nodeAsSVGScript = do_QueryInterface(aNodeIn);
if (nodeAsSVGScript)
if (content->IsSVG(nsGkAtoms::script))
{
rv = GetNodeToFixup(aNodeIn, aNodeOut);
if (NS_SUCCEEDED(rv) && *aNodeOut)

View File

@ -755,14 +755,20 @@ nsPermissionManager::AddInternal(nsIPrincipal* aPrincipal,
id = entry->GetPermissions()[index].mID;
// If the new expireType is EXPIRE_SESSION, then we have to keep a
// copy of the previous permission value. This cached value will be
// copy of the previous permission/expireType values. This cached value will be
// used when restoring the permissions of an app.
if (entry->GetPermissions()[index].mExpireType != nsIPermissionManager::EXPIRE_SESSION &&
aExpireType == nsIPermissionManager::EXPIRE_SESSION) {
entry->GetPermissions()[index].mNonSessionPermission = entry->GetPermissions()[index].mPermission;
entry->GetPermissions()[index].mNonSessionExpireType = entry->GetPermissions()[index].mExpireType;
} else if (aExpireType != nsIPermissionManager::EXPIRE_SESSION) {
entry->GetPermissions()[index].mNonSessionPermission = aPermission;
entry->GetPermissions()[index].mNonSessionExpireType = aExpireType;
entry->GetPermissions()[index].mExpireTime = aExpireTime;
}
entry->GetPermissions()[index].mPermission = aPermission;
entry->GetPermissions()[index].mExpireType = aExpireType;
if (aDBOperation == eWriteToDB && aExpireType != nsIPermissionManager::EXPIRE_SESSION)
// We care only about the id, the permission and expireType/expireTime here.
@ -1225,7 +1231,11 @@ nsPermissionManager::RemoveExpiredPermissionsForAppEnumerator(
}
nsPermissionManager::PermissionEntry& permEntry = entry->GetPermissions()[i];
if (permEntry.mExpireType == nsIPermissionManager::EXPIRE_SESSION) {
if (permEntry.mExpireType != nsIPermissionManager::EXPIRE_SESSION) {
continue;
}
if (permEntry.mNonSessionExpireType == nsIPermissionManager::EXPIRE_SESSION) {
PermissionEntry oldPermissionEntry = entry->GetPermissions()[i];
entry->GetPermissions().RemoveElementAt(i);
@ -1242,18 +1252,17 @@ nsPermissionManager::RemoveExpiredPermissionsForAppEnumerator(
continue;
}
if (permEntry.mNonSessionPermission != permEntry.mPermission) {
permEntry.mPermission = permEntry.mNonSessionPermission;
permEntry.mPermission = permEntry.mNonSessionPermission;
permEntry.mExpireType = permEntry.mNonSessionExpireType;
gPermissionManager->NotifyObserversWithPermission(entry->GetKey()->mHost,
entry->GetKey()->mAppId,
entry->GetKey()->mIsInBrowserElement,
gPermissionManager->mTypeArray.ElementAt(permEntry.mType),
permEntry.mPermission,
permEntry.mExpireType,
permEntry.mExpireTime,
NS_LITERAL_STRING("changed").get());
}
gPermissionManager->NotifyObserversWithPermission(entry->GetKey()->mHost,
entry->GetKey()->mAppId,
entry->GetKey()->mIsInBrowserElement,
gPermissionManager->mTypeArray.ElementAt(permEntry.mType),
permEntry.mPermission,
permEntry.mExpireType,
permEntry.mExpireTime,
NS_LITERAL_STRING("changed").get());
}
return PL_DHASH_NEXT;

View File

@ -44,6 +44,7 @@ public:
, mExpireType(aExpireType)
, mExpireTime(aExpireTime)
, mNonSessionPermission(aPermission)
, mNonSessionExpireType(aExpireType)
{}
int64_t mID;
@ -52,6 +53,7 @@ public:
uint32_t mExpireType;
int64_t mExpireTime;
uint32_t mNonSessionPermission;
uint32_t mNonSessionExpireType;
};
/**

View File

@ -198,6 +198,10 @@ dwrite-font-match-robustness.patch: bug 717178, don't crash when _name_tables_ma
handle-multi-path-clip.patch: bug 813124, handle multiple clip paths correctly
win32-gdi-font-cache.patch: Bug 717178, cache GDI font faces to reduce usage of GDI resources
win32-gdi-font-cache-no-HFONT.patch: Bug 717178, don't cache GDI font faces when an HFONT belonging to the caller is passed in
==== pixman patches ====
pixman-android-cpu-detect.patch: Add CPU detection support for Android, where we can't reliably access /proc/self/auxv.

View File

@ -69,6 +69,10 @@ cairo_debug_reset_static_data (void)
_cairo_ft_font_reset_static_data ();
#endif
#if CAIRO_HAS_WIN32_FONT
_cairo_win32_font_reset_static_data ();
#endif
_cairo_intern_string_reset_static_data ();
_cairo_scaled_font_reset_static_data ();

View File

@ -51,6 +51,10 @@ CAIRO_MUTEX_DECLARE (_cairo_scaled_font_error_mutex)
CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex)
#endif
#if CAIRO_HAS_WIN32_FONT
CAIRO_MUTEX_DECLARE (_cairo_win32_font_face_mutex)
#endif
#if CAIRO_HAS_XLIB_SURFACE
CAIRO_MUTEX_DECLARE (_cairo_xlib_display_mutex)
#endif

View File

@ -47,6 +47,8 @@
#include "cairo-win32-private.h"
#include "cairo-error-private.h"
#include <wchar.h>
#ifndef SPI_GETFONTSMOOTHINGTYPE
#define SPI_GETFONTSMOOTHINGTYPE 0x200a
#endif
@ -1892,9 +1894,7 @@ struct _cairo_win32_font_face {
/* implement the platform-specific interface */
static void
_cairo_win32_font_face_destroy (void *abstract_face)
{
}
_cairo_win32_font_face_destroy (void *abstract_face);
static cairo_bool_t
_is_scale (const cairo_matrix_t *matrix, double scale)
@ -1937,6 +1937,125 @@ const cairo_font_face_backend_t _cairo_win32_font_face_backend = {
_cairo_win32_font_face_scaled_font_create
};
/* We maintain a hash table from LOGFONT,HFONT => #cairo_font_face_t.
* The primary purpose of this mapping is to provide unique
* #cairo_font_face_t values so that our cache and mapping from
* #cairo_font_face_t => #cairo_scaled_font_t works. Once the
* corresponding #cairo_font_face_t objects fall out of downstream
* caches, we don't need them in this hash table anymore.
*
* Modifications to this hash table are protected by
* _cairo_win32_font_face_mutex.
*
* Only #cairo_font_face_t values with null 'hfont' (no
* HFONT preallocated by caller) are stored in this table. We rely
* on callers to manage the lifetime of the HFONT, and they can't
* do that if we share #cairo_font_face_t values with other callers.
*/
static cairo_hash_table_t *cairo_win32_font_face_hash_table = NULL;
static int
_cairo_win32_font_face_keys_equal (const void *key_a,
const void *key_b);
static void
_cairo_win32_font_face_hash_table_destroy (void)
{
cairo_hash_table_t *hash_table;
/* We manually acquire the lock rather than calling
* _cairo_win32_font_face_hash_table_lock simply to avoid creating
* the table only to destroy it again. */
CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex);
hash_table = cairo_win32_font_face_hash_table;
cairo_win32_font_face_hash_table = NULL;
CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
if (hash_table != NULL)
_cairo_hash_table_destroy (hash_table);
}
static cairo_hash_table_t *
_cairo_win32_font_face_hash_table_lock (void)
{
CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex);
if (unlikely (cairo_win32_font_face_hash_table == NULL))
{
cairo_win32_font_face_hash_table =
_cairo_hash_table_create (_cairo_win32_font_face_keys_equal);
if (unlikely (cairo_win32_font_face_hash_table == NULL)) {
CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return NULL;
}
}
return cairo_win32_font_face_hash_table;
}
static void
_cairo_win32_font_face_hash_table_unlock (void)
{
CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
}
static void
_cairo_win32_font_face_init_key (cairo_win32_font_face_t *key,
LOGFONTW *logfont,
HFONT font)
{
unsigned long hash = _CAIRO_HASH_INIT_VALUE;
key->logfont = *logfont;
key->hfont = font;
hash = _cairo_hash_bytes (0, logfont->lfFaceName, 2*wcslen(logfont->lfFaceName));
hash = _cairo_hash_bytes (hash, &logfont->lfWeight, sizeof(logfont->lfWeight));
hash = _cairo_hash_bytes (hash, &logfont->lfItalic, sizeof(logfont->lfItalic));
key->base.hash_entry.hash = hash;
}
static int
_cairo_win32_font_face_keys_equal (const void *key_a,
const void *key_b)
{
const cairo_win32_font_face_t *face_a = key_a;
const cairo_win32_font_face_t *face_b = key_b;
if (face_a->logfont.lfWeight == face_b->logfont.lfWeight &&
face_a->logfont.lfItalic == face_b->logfont.lfItalic &&
face_a->logfont.lfUnderline == face_b->logfont.lfUnderline &&
face_a->logfont.lfStrikeOut == face_b->logfont.lfStrikeOut &&
face_a->logfont.lfCharSet == face_b->logfont.lfCharSet &&
face_a->logfont.lfOutPrecision == face_b->logfont.lfOutPrecision &&
face_a->logfont.lfClipPrecision == face_b->logfont.lfClipPrecision &&
face_a->logfont.lfPitchAndFamily == face_b->logfont.lfPitchAndFamily &&
(wcscmp (face_a->logfont.lfFaceName, face_b->logfont.lfFaceName) == 0))
return TRUE;
else
return FALSE;
}
static void
_cairo_win32_font_face_destroy (void *abstract_face)
{
cairo_hash_table_t *hash_table;
cairo_win32_font_face_t *font_face = abstract_face;
if (!font_face->hfont) {
hash_table = _cairo_win32_font_face_hash_table_lock ();
if (unlikely (hash_table == NULL)) {
return;
}
_cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
_cairo_win32_font_face_hash_table_unlock ();
}
}
/**
* cairo_win32_font_face_create_for_logfontw_hfont:
* @logfont: A #LOGFONTW structure specifying the font to use.
@ -1959,20 +2078,59 @@ const cairo_font_face_backend_t _cairo_win32_font_face_backend = {
cairo_font_face_t *
cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font)
{
cairo_win32_font_face_t *font_face;
cairo_win32_font_face_t *font_face, key;
cairo_hash_table_t *hash_table;
cairo_status_t status;
if (!font) {
hash_table = _cairo_win32_font_face_hash_table_lock ();
if (unlikely (hash_table == NULL)) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_face_t *)&_cairo_font_face_nil;
}
_cairo_win32_font_face_init_key (&key, logfont, font);
/* Return existing unscaled font if it exists in the hash table. */
font_face = _cairo_hash_table_lookup (hash_table,
&key.base.hash_entry);
if (font_face != NULL) {
cairo_font_face_reference (&font_face->base);
goto DONE;
}
}
/* Otherwise create it and insert into hash table. */
font_face = malloc (sizeof (cairo_win32_font_face_t));
if (!font_face) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
return (cairo_font_face_t *)&_cairo_font_face_nil;
goto FAIL;
}
font_face->logfont = *logfont;
font_face->hfont = font;
_cairo_win32_font_face_init_key (font_face, logfont, font);
_cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend);
assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash);
if (!font) {
status = _cairo_hash_table_insert (hash_table,
&font_face->base.hash_entry);
if (unlikely (status))
goto FAIL;
}
DONE:
if (!font) {
_cairo_win32_font_face_hash_table_unlock ();
}
return &font_face->base;
FAIL:
if (!font) {
_cairo_win32_font_face_hash_table_unlock ();
}
return (cairo_font_face_t *)&_cairo_font_face_nil;
}
/**
@ -2181,3 +2339,9 @@ cairo_win32_scaled_font_get_device_to_logical (cairo_scaled_font_t *scaled_font,
}
*device_to_logical = win_font->device_to_logical;
}
void
_cairo_win32_font_reset_static_data (void)
{
_cairo_win32_font_face_hash_table_destroy ();
}

View File

@ -408,6 +408,9 @@ _cairo_toy_font_face_reset_static_data (void);
cairo_private void
_cairo_ft_font_reset_static_data (void);
cairo_private void
_cairo_win32_font_reset_static_data (void);
/* the font backend interface */
struct _cairo_unscaled_font_backend {

View File

@ -0,0 +1,145 @@
# HG changeset patch
# User Robert O'Callahan <robert@ocallahan.org>
# Date 1357107533 -46800
# Node ID ed54dfdd2facb11a4d4158138b460a31de45e9f7
# Parent ab6457cc16ec14ea07386dcfc57cad6b8a9ac55d
Bug 717178. Part 3 alternative: don't put Win32 cairo_font_face_ts into the font-face cache if they were created with an explicit HFONT. r=jrmuizel
diff --git a/gfx/cairo/cairo/src/cairo-win32-font.c b/gfx/cairo/cairo/src/cairo-win32-font.c
--- a/gfx/cairo/cairo/src/cairo-win32-font.c
+++ b/gfx/cairo/cairo/src/cairo-win32-font.c
@@ -1941,16 +1942,21 @@ const cairo_font_face_backend_t _cairo_w
* The primary purpose of this mapping is to provide unique
* #cairo_font_face_t values so that our cache and mapping from
* #cairo_font_face_t => #cairo_scaled_font_t works. Once the
* corresponding #cairo_font_face_t objects fall out of downstream
* caches, we don't need them in this hash table anymore.
*
* Modifications to this hash table are protected by
* _cairo_win32_font_face_mutex.
+ *
+ * Only #cairo_font_face_t values with null 'hfont' (no
+ * HFONT preallocated by caller) are stored in this table. We rely
+ * on callers to manage the lifetime of the HFONT, and they can't
+ * do that if we share #cairo_font_face_t values with other callers.
*/
static cairo_hash_table_t *cairo_win32_font_face_hash_table = NULL;
static int
_cairo_win32_font_face_keys_equal (const void *key_a,
const void *key_b);
@@ -2036,22 +2042,24 @@ static int
}
static void
_cairo_win32_font_face_destroy (void *abstract_face)
{
cairo_hash_table_t *hash_table;
cairo_win32_font_face_t *font_face = abstract_face;
- hash_table = _cairo_win32_font_face_hash_table_lock ();
- if (unlikely (hash_table == NULL)) {
- return;
+ if (!font_face->hfont) {
+ hash_table = _cairo_win32_font_face_hash_table_lock ();
+ if (unlikely (hash_table == NULL)) {
+ return;
+ }
+ _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
+ _cairo_win32_font_face_hash_table_unlock ();
}
- _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
- _cairo_win32_font_face_hash_table_unlock ();
}
/**
* cairo_win32_font_face_create_for_logfontw_hfont:
* @logfont: A #LOGFONTW structure specifying the font to use.
* If @font is %NULL then the lfHeight, lfWidth, lfOrientation and lfEscapement
* fields of this structure are ignored. Otherwise lfWidth, lfOrientation and
* lfEscapement must be zero.
@@ -2070,55 +2078,63 @@ static void
**/
cairo_font_face_t *
cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font)
{
cairo_win32_font_face_t *font_face, key;
cairo_hash_table_t *hash_table;
cairo_status_t status;
- hash_table = _cairo_win32_font_face_hash_table_lock ();
- if (unlikely (hash_table == NULL)) {
- _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
- return (cairo_font_face_t *)&_cairo_font_face_nil;
- }
+ if (!font) {
+ hash_table = _cairo_win32_font_face_hash_table_lock ();
+ if (unlikely (hash_table == NULL)) {
+ _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_font_face_t *)&_cairo_font_face_nil;
+ }
- _cairo_win32_font_face_init_key (&key, logfont, font);
+ _cairo_win32_font_face_init_key (&key, logfont, font);
- /* Return existing unscaled font if it exists in the hash table. */
- font_face = _cairo_hash_table_lookup (hash_table,
- &key.base.hash_entry);
- if (font_face != NULL) {
- cairo_font_face_reference (&font_face->base);
- goto DONE;
+ /* Return existing unscaled font if it exists in the hash table. */
+ font_face = _cairo_hash_table_lookup (hash_table,
+ &key.base.hash_entry);
+ if (font_face != NULL) {
+ cairo_font_face_reference (&font_face->base);
+ goto DONE;
+ }
}
/* Otherwise create it and insert into hash table. */
font_face = malloc (sizeof (cairo_win32_font_face_t));
if (!font_face) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
goto FAIL;
}
_cairo_win32_font_face_init_key (font_face, logfont, font);
_cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend);
+ assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash);
- assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash);
- status = _cairo_hash_table_insert (hash_table,
- &font_face->base.hash_entry);
- if (unlikely (status))
- goto FAIL;
+ if (!font) {
+ status = _cairo_hash_table_insert (hash_table,
+ &font_face->base.hash_entry);
+ if (unlikely (status))
+ goto FAIL;
+ }
DONE:
- _cairo_win32_font_face_hash_table_unlock ();
+ if (!font) {
+ _cairo_win32_font_face_hash_table_unlock ();
+ }
return &font_face->base;
FAIL:
- _cairo_win32_font_face_hash_table_unlock ();
+ if (!font) {
+ _cairo_win32_font_face_hash_table_unlock ();
+ }
return (cairo_font_face_t *)&_cairo_font_face_nil;
}
/**
* cairo_win32_font_face_create_for_logfontw:
* @logfont: A #LOGFONTW structure specifying the font to use.
* The lfHeight, lfWidth, lfOrientation and lfEscapement

View File

@ -0,0 +1,375 @@
# HG changeset patch
# User Andrea Canciani <ranma42@gmail.com>, Adrian Johnson <ajohnson@redneon.com>
# Date 1354838294 -46800
# Node ID 390df735b9d5c5ba07a4d3fe9ca2ebc9e7626a78
# Parent e30a5b6a5a003b85fc1ca8b76719a56ef59d976e
Bug 717178. Part 2: Import changesets eb29a25d, 6e3e3291 and 101fab7c from upstream.
======
From 101fab7cd8a90f7cf3d8113c792b3f8c2a9afb7d Mon Sep 17 00:00:00 2001
From: Andrea Canciani <ranma42@gmail.com>
Date: Wed, 15 Jun 2011 09:37:36 +0000
Subject: win32-font: Improve static data reset function
The hashtable is guaranteed to only contain font faces which are
currently referenced, hence there is no need to remove any font face
when it is reset (just like for toy-font).
This makes the function simpler and fixes the assertion
Assertion failed: predicate != NULL, file cairo-hash.c, line 373
hit by multiple tests (the first one being "clear").
See https://bugs.freedesktop.org/show_bug.cgi?id=38049
======
From eb29a25dd6dddc511388bf883c9b95843ecdb823 Mon Sep 17 00:00:00 2001
From: Adrian Johnson <ajohnson@redneon.com>
Date: Tue, 16 Nov 2010 13:18:39 +0000
Subject: win32: Use a font_face hash table to provide unique font faces
Similar to the freetype and toy font backends, use a hash table
to map logfont,hfont to font faces.
This fixes the multiple embedding of the same font in PDF.
https://bugs.freedesktop.org/show_bug.cgi?id=24849
======
From 6e3e329170ab4b96bc0d587c8071e869e228e758 Mon Sep 17 00:00:00 2001
From: Adrian Johnson <ajohnson@redneon.com>
Date: Thu, 18 Nov 2010 12:37:45 +0000
Subject: win32: fix font_face hashing
some bugs were discovered while testing with firefox
======
diff --git a/gfx/cairo/cairo/src/cairo-debug.c b/gfx/cairo/cairo/src/cairo-debug.c
--- a/gfx/cairo/cairo/src/cairo-debug.c
+++ b/gfx/cairo/cairo/src/cairo-debug.c
@@ -64,16 +64,20 @@ cairo_debug_reset_static_data (void)
_cairo_scaled_font_map_destroy ();
_cairo_toy_font_face_reset_static_data ();
#if CAIRO_HAS_FT_FONT
_cairo_ft_font_reset_static_data ();
#endif
+#if CAIRO_HAS_WIN32_FONT
+ _cairo_win32_font_reset_static_data ();
+#endif
+
_cairo_intern_string_reset_static_data ();
_cairo_scaled_font_reset_static_data ();
_cairo_pattern_reset_static_data ();
_cairo_clip_reset_static_data ();
diff --git a/gfx/cairo/cairo/src/cairo-mutex-list-private.h b/gfx/cairo/cairo/src/cairo-mutex-list-private.h
--- a/gfx/cairo/cairo/src/cairo-mutex-list-private.h
+++ b/gfx/cairo/cairo/src/cairo-mutex-list-private.h
@@ -46,16 +46,20 @@ CAIRO_MUTEX_DECLARE (_cairo_intern_strin
CAIRO_MUTEX_DECLARE (_cairo_scaled_font_map_mutex)
CAIRO_MUTEX_DECLARE (_cairo_scaled_glyph_page_cache_mutex)
CAIRO_MUTEX_DECLARE (_cairo_scaled_font_error_mutex)
#if CAIRO_HAS_FT_FONT
CAIRO_MUTEX_DECLARE (_cairo_ft_unscaled_font_map_mutex)
#endif
+#if CAIRO_HAS_WIN32_FONT
+CAIRO_MUTEX_DECLARE (_cairo_win32_font_face_mutex)
+#endif
+
#if CAIRO_HAS_XLIB_SURFACE
CAIRO_MUTEX_DECLARE (_cairo_xlib_display_mutex)
#endif
#if CAIRO_HAS_XCB_SURFACE
CAIRO_MUTEX_DECLARE (_cairo_xcb_connections_mutex)
#endif
diff --git a/gfx/cairo/cairo/src/cairo-win32-font.c b/gfx/cairo/cairo/src/cairo-win32-font.c
--- a/gfx/cairo/cairo/src/cairo-win32-font.c
+++ b/gfx/cairo/cairo/src/cairo-win32-font.c
@@ -42,16 +42,18 @@
# define _WIN32_WINNT 0x0500
#endif
#include "cairoint.h"
#include "cairo-win32-private.h"
#include "cairo-error-private.h"
+#include <wchar.h>
+
#ifndef SPI_GETFONTSMOOTHINGTYPE
#define SPI_GETFONTSMOOTHINGTYPE 0x200a
#endif
#ifndef FE_FONTSMOOTHINGCLEARTYPE
#define FE_FONTSMOOTHINGCLEARTYPE 2
#endif
#ifndef CLEARTYPE_QUALITY
#define CLEARTYPE_QUALITY 5
@@ -1887,19 +1889,17 @@ struct _cairo_win32_font_face {
cairo_font_face_t base;
LOGFONTW logfont;
HFONT hfont;
};
/* implement the platform-specific interface */
static void
-_cairo_win32_font_face_destroy (void *abstract_face)
-{
-}
+_cairo_win32_font_face_destroy (void *abstract_face);
static cairo_bool_t
_is_scale (const cairo_matrix_t *matrix, double scale)
{
return matrix->xx == scale && matrix->yy == scale &&
matrix->xy == 0. && matrix->yx == 0. &&
matrix->x0 == 0. && matrix->y0 == 0.;
}
@@ -1932,16 +1932,128 @@ static cairo_status_t
const cairo_font_face_backend_t _cairo_win32_font_face_backend = {
CAIRO_FONT_TYPE_WIN32,
_cairo_win32_font_face_create_for_toy,
_cairo_win32_font_face_destroy,
_cairo_win32_font_face_scaled_font_create
};
+/* We maintain a hash table from LOGFONT,HFONT => #cairo_font_face_t.
+ * The primary purpose of this mapping is to provide unique
+ * #cairo_font_face_t values so that our cache and mapping from
+ * #cairo_font_face_t => #cairo_scaled_font_t works. Once the
+ * corresponding #cairo_font_face_t objects fall out of downstream
+ * caches, we don't need them in this hash table anymore.
+ *
+ * Modifications to this hash table are protected by
+ * _cairo_win32_font_face_mutex.
+ */
+
+static cairo_hash_table_t *cairo_win32_font_face_hash_table = NULL;
+
+static int
+_cairo_win32_font_face_keys_equal (const void *key_a,
+ const void *key_b);
+
+static void
+_cairo_win32_font_face_hash_table_destroy (void)
+{
+ cairo_hash_table_t *hash_table;
+
+ /* We manually acquire the lock rather than calling
+ * _cairo_win32_font_face_hash_table_lock simply to avoid creating
+ * the table only to destroy it again. */
+ CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex);
+ hash_table = cairo_win32_font_face_hash_table;
+ cairo_win32_font_face_hash_table = NULL;
+ CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
+
+ if (hash_table != NULL)
+ _cairo_hash_table_destroy (hash_table);
+}
+
+static cairo_hash_table_t *
+_cairo_win32_font_face_hash_table_lock (void)
+{
+ CAIRO_MUTEX_LOCK (_cairo_win32_font_face_mutex);
+
+ if (unlikely (cairo_win32_font_face_hash_table == NULL))
+ {
+ cairo_win32_font_face_hash_table =
+ _cairo_hash_table_create (_cairo_win32_font_face_keys_equal);
+
+ if (unlikely (cairo_win32_font_face_hash_table == NULL)) {
+ CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
+ _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+ return NULL;
+ }
+ }
+
+ return cairo_win32_font_face_hash_table;
+}
+
+static void
+_cairo_win32_font_face_hash_table_unlock (void)
+{
+ CAIRO_MUTEX_UNLOCK (_cairo_win32_font_face_mutex);
+}
+
+static void
+_cairo_win32_font_face_init_key (cairo_win32_font_face_t *key,
+ LOGFONTW *logfont,
+ HFONT font)
+{
+ unsigned long hash = _CAIRO_HASH_INIT_VALUE;
+
+ key->logfont = *logfont;
+ key->hfont = font;
+
+ hash = _cairo_hash_bytes (0, logfont->lfFaceName, 2*wcslen(logfont->lfFaceName));
+ hash = _cairo_hash_bytes (hash, &logfont->lfWeight, sizeof(logfont->lfWeight));
+ hash = _cairo_hash_bytes (hash, &logfont->lfItalic, sizeof(logfont->lfItalic));
+
+ key->base.hash_entry.hash = hash;
+}
+
+static int
+_cairo_win32_font_face_keys_equal (const void *key_a,
+ const void *key_b)
+{
+ const cairo_win32_font_face_t *face_a = key_a;
+ const cairo_win32_font_face_t *face_b = key_b;
+
+ if (face_a->logfont.lfWeight == face_b->logfont.lfWeight &&
+ face_a->logfont.lfItalic == face_b->logfont.lfItalic &&
+ face_a->logfont.lfUnderline == face_b->logfont.lfUnderline &&
+ face_a->logfont.lfStrikeOut == face_b->logfont.lfStrikeOut &&
+ face_a->logfont.lfCharSet == face_b->logfont.lfCharSet &&
+ face_a->logfont.lfOutPrecision == face_b->logfont.lfOutPrecision &&
+ face_a->logfont.lfClipPrecision == face_b->logfont.lfClipPrecision &&
+ face_a->logfont.lfPitchAndFamily == face_b->logfont.lfPitchAndFamily &&
+ (wcscmp (face_a->logfont.lfFaceName, face_b->logfont.lfFaceName) == 0))
+ return TRUE;
+ else
+ return FALSE;
+}
+
+static void
+_cairo_win32_font_face_destroy (void *abstract_face)
+{
+ cairo_hash_table_t *hash_table;
+ cairo_win32_font_face_t *font_face = abstract_face;
+
+ hash_table = _cairo_win32_font_face_hash_table_lock ();
+ if (unlikely (hash_table == NULL)) {
+ return;
+ }
+ _cairo_hash_table_remove (hash_table, &font_face->base.hash_entry);
+ _cairo_win32_font_face_hash_table_unlock ();
+}
+
/**
* cairo_win32_font_face_create_for_logfontw_hfont:
* @logfont: A #LOGFONTW structure specifying the font to use.
* If @font is %NULL then the lfHeight, lfWidth, lfOrientation and lfEscapement
* fields of this structure are ignored. Otherwise lfWidth, lfOrientation and
* lfEscapement must be zero.
* @font: An #HFONT that can be used when the font matrix is a scale by
* -lfHeight and the CTM is identity.
@@ -1954,30 +2066,61 @@ const cairo_font_face_backend_t _cairo_w
* and can be used with functions such as cairo_win32_scaled_font_select_font().
*
* Return value: a newly created #cairo_font_face_t. Free with
* cairo_font_face_destroy() when you are done using it.
**/
cairo_font_face_t *
cairo_win32_font_face_create_for_logfontw_hfont (LOGFONTW *logfont, HFONT font)
{
- cairo_win32_font_face_t *font_face;
+ cairo_win32_font_face_t *font_face, key;
+ cairo_hash_table_t *hash_table;
+ cairo_status_t status;
+ hash_table = _cairo_win32_font_face_hash_table_lock ();
+ if (unlikely (hash_table == NULL)) {
+ _cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
+ return (cairo_font_face_t *)&_cairo_font_face_nil;
+ }
+
+ _cairo_win32_font_face_init_key (&key, logfont, font);
+
+ /* Return existing unscaled font if it exists in the hash table. */
+ font_face = _cairo_hash_table_lookup (hash_table,
+ &key.base.hash_entry);
+ if (font_face != NULL) {
+ cairo_font_face_reference (&font_face->base);
+ goto DONE;
+ }
+
+ /* Otherwise create it and insert into hash table. */
font_face = malloc (sizeof (cairo_win32_font_face_t));
if (!font_face) {
_cairo_error_throw (CAIRO_STATUS_NO_MEMORY);
- return (cairo_font_face_t *)&_cairo_font_face_nil;
+ goto FAIL;
}
- font_face->logfont = *logfont;
- font_face->hfont = font;
-
+ _cairo_win32_font_face_init_key (font_face, logfont, font);
_cairo_font_face_init (&font_face->base, &_cairo_win32_font_face_backend);
+ assert (font_face->base.hash_entry.hash == key.base.hash_entry.hash);
+ status = _cairo_hash_table_insert (hash_table,
+ &font_face->base.hash_entry);
+ if (unlikely (status))
+ goto FAIL;
+
+DONE:
+ _cairo_win32_font_face_hash_table_unlock ();
+
return &font_face->base;
+
+FAIL:
+ _cairo_win32_font_face_hash_table_unlock ();
+
+ return (cairo_font_face_t *)&_cairo_font_face_nil;
}
/**
* cairo_win32_font_face_create_for_logfontw:
* @logfont: A #LOGFONTW structure specifying the font to use.
* The lfHeight, lfWidth, lfOrientation and lfEscapement
* fields of this structure are ignored.
*
@@ -2176,8 +2319,14 @@ cairo_win32_scaled_font_get_device_to_lo
cairo_win32_scaled_font_t *win_font = (cairo_win32_scaled_font_t *)scaled_font;
if (! _cairo_scaled_font_is_win32 (scaled_font)) {
_cairo_error_throw (CAIRO_STATUS_FONT_TYPE_MISMATCH);
cairo_matrix_init_identity (device_to_logical);
return;
}
*device_to_logical = win_font->device_to_logical;
}
+
+void
+_cairo_win32_font_reset_static_data (void)
+{
+ _cairo_win32_font_face_hash_table_destroy ();
+}
diff --git a/gfx/cairo/cairo/src/cairoint.h b/gfx/cairo/cairo/src/cairoint.h
--- a/gfx/cairo/cairo/src/cairoint.h
+++ b/gfx/cairo/cairo/src/cairoint.h
@@ -403,16 +403,19 @@ cairo_private void
_cairo_reset_static_data (void);
cairo_private void
_cairo_toy_font_face_reset_static_data (void);
cairo_private void
_cairo_ft_font_reset_static_data (void);
+cairo_private void
+_cairo_win32_font_reset_static_data (void);
+
/* the font backend interface */
struct _cairo_unscaled_font_backend {
void (*destroy) (void *unscaled_font);
};
/* #cairo_toy_font_face_t - simple family/slant/weight font faces used for
* the built-in font API

View File

@ -174,7 +174,7 @@ FontPrefsObserver::Observe(nsISupports *aSubject,
return NS_OK;
}
class OrientationSyncPrefsObserver : public nsIObserver
class OrientationSyncPrefsObserver MOZ_FINAL : public nsIObserver
{
public:
NS_DECL_ISUPPORTS

View File

@ -267,7 +267,7 @@ private:
static size_t pageSize;
static size_t largeAllocSize;
#if WTF_OS_WINDOWS
static int64_t rngSeed;
static uint64_t rngSeed;
#endif
static const size_t OVERSIZE_ALLOCATION = size_t(-1);

View File

@ -30,12 +30,12 @@
#include "jswin.h"
#include "prmjtime.h"
extern void random_setSeed(int64_t *, int64_t);
extern uint64_t random_next(int64_t *, int);
extern void random_setSeed(uint64_t *, uint64_t);
extern uint64_t random_next(uint64_t *, int);
namespace JSC {
int64_t ExecutableAllocator::rngSeed;
uint64_t ExecutableAllocator::rngSeed;
void ExecutableAllocator::initSeed()
{

View File

@ -143,7 +143,7 @@ js::ExecuteRegExpLegacy(JSContext *cx, RegExpStatics *res, RegExpObject &reobj,
Handle<JSStableString*> input, StableCharPtr chars, size_t length,
size_t *lastIndex, JSBool test, jsval *rval)
{
RegExpGuard shared;
RegExpGuard shared(cx);
if (!reobj.getShared(cx, &shared))
return false;
@ -252,7 +252,7 @@ CompileRegExpObject(JSContext *cx, RegExpObjectBuilder &builder, CallArgs args)
*/
RegExpFlag flags;
{
RegExpGuard g;
RegExpGuard g(cx);
if (!RegExpToShared(cx, *sourceObj, &g))
return false;
@ -556,7 +556,7 @@ js::ExecuteRegExp(JSContext *cx, HandleObject regexp, HandleString string, Match
/* Step 1 (b) was performed by CallNonGenericMethod. */
Rooted<RegExpObject*> reobj(cx, &regexp->asRegExp());
RegExpGuard re;
RegExpGuard re(cx);
if (!reobj->getShared(cx, &re))
return RegExpRunStatus_Error;

View File

@ -4097,6 +4097,29 @@ else
fi
fi
dnl ========================================================
dnl = Disable -fstrict-aliasing on Linux/Android with GCC 4.4 and earlier.
dnl = See bug 821502.
dnl ========================================================
case "$target" in
*-android*|*-linuxandroid*|*-*linux*)
if test "$GNU_CC"; then
changequote(,)
GCC_VERSION_FULL=`echo "$CXX_VERSION" | $PERL -pe 's/^.*gcc version ([^ ]*).*/$1/'`
GCC_VERSION=`echo "$GCC_VERSION_FULL" | $PERL -pe '(split(/\./))[0]>=4&&s/(^\d*\.\d*).*/$1/;'`
changequote([,])
GCC_MAJOR_VERSION=`echo ${GCC_VERSION} | $AWK -F\. '{ print $1 }'`
GCC_MINOR_VERSION=`echo ${GCC_VERSION} | $AWK -F\. '{ print $2 }'`
dnl GCC 3.x isn't supported, so we don't need to check for that.
if test "$GCC_MAJOR_VERSION" -eq "4" -a "$GCC_MINOR_VERSION" -lt "5" ; then
CFLAGS="$CFLAGS -fno-strict-aliasing"
CXXFLAGS="$CXXFLAGS -fno-strict-aliasing"
fi
fi
esac
dnl ========================================================
dnl = Link js shell to system readline
dnl ========================================================

View File

@ -2138,7 +2138,7 @@ bool CanConvertTypedArrayItemTo(JSObject *baseType, JSObject *valObj, JSContext
return true;
}
TypeCode elementTypeCode;
switch (JS_GetTypedArrayType(valObj)) {
switch (JS_GetArrayBufferViewType(valObj)) {
case TypedArray::TYPE_INT8:
elementTypeCode = TYPE_int8_t;
break;

View File

@ -119,15 +119,12 @@ frontend::IsIdentifier(JSLinearString *str)
TokenStream::TokenStream(JSContext *cx, const CompileOptions &options,
StableCharPtr base, size_t length, StrictModeGetter *smg)
: tokens(),
tokensRoot(cx, &tokens),
cursor(),
lookahead(),
lineno(options.lineno),
flags(),
linebase(base.get()),
prevLinebase(NULL),
linebaseRoot(cx, &linebase),
prevLinebaseRoot(cx, &prevLinebase),
userbuf(base.get(), length),
filename(options.filename),
sourceMap(NULL),
@ -139,7 +136,8 @@ TokenStream::TokenStream(JSContext *cx, const CompileOptions &options,
cx(cx),
originPrincipals(JSScript::normalizeOriginPrincipals(options.principals,
options.originPrincipals)),
strictModeGetter(smg)
strictModeGetter(smg),
tokenSkip(cx, &tokens)
{
if (originPrincipals)
JS_HoldPrincipals(originPrincipals);
@ -1442,8 +1440,6 @@ TokenStream::getTokenInternal()
const jschar *identStart;
bool hadUnicodeEscape;
SkipRoot skipNum(cx, &numStart), skipIdent(cx, &identStart);
#if JS_HAS_XML_SUPPORT
/*
* Look for XML text and tags.

View File

@ -852,15 +852,12 @@ class TokenStream
void updateFlagsForEOL();
Token tokens[ntokens];/* circular token buffer */
js::SkipRoot tokensRoot; /* prevent overwriting of token buffer */
unsigned cursor; /* index of last parsed token */
unsigned lookahead; /* count of lookahead tokens */
unsigned lineno; /* current line number */
unsigned flags; /* flags -- see above */
const jschar *linebase; /* start of current line; points into userbuf */
const jschar *prevLinebase; /* start of previous line; NULL if on the first line */
js::SkipRoot linebaseRoot;
js::SkipRoot prevLinebaseRoot;
TokenBuf userbuf; /* user input buffer */
const char *filename; /* input filename or null */
jschar *sourceMap; /* source map's filename or null */
@ -876,6 +873,13 @@ class TokenStream
JSPrincipals *const originPrincipals;
StrictModeGetter *strictModeGetter; /* used to test for strict mode */
Position lastFunctionKeyword; /* used as a starting point for reparsing strict functions */
/*
* The tokens array stores pointers to JSAtoms. These are rooted by the
* atoms table using AutoKeepAtoms in the Parser. This SkipRoot tells the
* exact rooting analysis to ignore the atoms in the tokens array.
*/
SkipRoot tokenSkip;
};
struct KeywordInfo {

View File

@ -272,25 +272,13 @@ template <typename T>
class MutableHandle : public js::MutableHandleBase<T>
{
public:
template <typename S>
MutableHandle(MutableHandle<S> handle,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0)
{
this->ptr = reinterpret_cast<const T *>(handle.address());
}
template <typename S>
inline MutableHandle(js::Rooted<S> *root,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy = 0);
inline MutableHandle(js::Rooted<T> *root);
void set(T v) {
JS_ASSERT(!js::RootMethods<T>::poisoned(v));
*ptr = v;
}
template <typename S>
inline void set(const js::Unrooted<S> &v);
/*
* This may be called only if the location of the T is guaranteed
* to be marked (for some reason other than being a Rooted),
@ -859,21 +847,13 @@ Handle<T>::Handle(MutableHandle<S> &root,
ptr = reinterpret_cast<const T *>(root.address());
}
template <typename T> template <typename S>
template <typename T>
inline
MutableHandle<T>::MutableHandle(js::Rooted<S> *root,
typename mozilla::EnableIf<mozilla::IsConvertible<S, T>::value, int>::Type dummy)
MutableHandle<T>::MutableHandle(js::Rooted<T> *root)
{
ptr = root->address();
}
template <typename T> template <typename S>
inline void MutableHandle<T>::set(const js::Unrooted<S> &v)
{
JS_ASSERT(!js::RootMethods<T>::poisoned(v));
*ptr = static_cast<S>(v);
}
/*
* The scoped guard object AutoAssertNoGC forces the GC to assert if a GC is
* attempted while the guard object is live. If you have a GC-unsafe operation

View File

@ -970,7 +970,7 @@ CodeGenerator::visitCallGetIntrinsicValue(LCallGetIntrinsicValue *lir)
return callVM(GetIntrinsicValueInfo, lir);
}
typedef bool (*InvokeFunctionFn)(JSContext *, JSFunction *, uint32_t, Value *, Value *);
typedef bool (*InvokeFunctionFn)(JSContext *, HandleFunction, uint32_t, Value *, Value *);
static const VMFunction InvokeFunctionInfo = FunctionInfo<InvokeFunctionFn>(InvokeFunction);
bool
@ -1106,7 +1106,7 @@ CodeGenerator::visitCallKnown(LCallKnown *call)
Register calleereg = ToRegister(call->getFunction());
Register objreg = ToRegister(call->getTempObject());
uint32_t unusedStack = StackOffsetOfPassedArg(call->argslot());
JSFunction *target = call->getSingleTarget();
RootedFunction target(cx, call->getSingleTarget());
Label end, invoke;
// Native single targets are handled by LCallNative.
@ -1117,7 +1117,7 @@ CodeGenerator::visitCallKnown(LCallKnown *call)
masm.checkStackAlignment();
// Make sure the function has a JSScript
if (target->isInterpretedLazy() && !target->getOrCreateScript(cx))
if (target->isInterpretedLazy() && !JSFunction::getOrCreateScript(cx, target))
return false;
// If the function is known to be uncompilable, only emit the call to InvokeFunction.

View File

@ -1072,8 +1072,8 @@ public:
return SequentialExecution;
}
bool compile(IonBuilder *builder, MIRGraph *graph,
AutoDestroyAllocator &autoDestroy);
AbortReason compile(IonBuilder *builder, MIRGraph *graph,
AutoDestroyAllocator &autoDestroy);
};
void
@ -1139,7 +1139,7 @@ AttachFinishedCompilations(JSContext *cx)
static const size_t BUILDER_LIFO_ALLOC_PRIMARY_CHUNK_SIZE = 1 << 12;
template <typename CompileContext>
static bool
static AbortReason
IonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing,
CompileContext &compileContext)
{
@ -1153,50 +1153,52 @@ IonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *o
LifoAlloc *alloc = cx->new_<LifoAlloc>(BUILDER_LIFO_ALLOC_PRIMARY_CHUNK_SIZE);
if (!alloc)
return false;
return AbortReason_Alloc;
AutoDestroyAllocator autoDestroy(alloc);
TempAllocator *temp = alloc->new_<TempAllocator>(alloc);
if (!temp)
return false;
return AbortReason_Alloc;
IonContext ictx(cx, cx->compartment, temp);
if (!cx->compartment->ensureIonCompartmentExists(cx))
return false;
return AbortReason_Alloc;
MIRGraph *graph = alloc->new_<MIRGraph>(temp);
ExecutionMode executionMode = compileContext.executionMode();
CompileInfo *info = alloc->new_<CompileInfo>(script, fun, osrPc, constructing,
executionMode);
if (!info)
return false;
return AbortReason_Alloc;
types::AutoEnterTypeInference enter(cx, true);
TypeInferenceOracle oracle;
if (!oracle.init(cx, script))
return false;
return AbortReason_Disable;
AutoFlushCache afc("IonCompile");
types::AutoEnterCompilation enterCompiler(cx, CompilerOutputKind(executionMode));
if (!enterCompiler.init(script, false, 0))
return false;
return AbortReason_Disable;
AutoTempAllocatorRooter root(cx, temp);
IonBuilder *builder = alloc->new_<IonBuilder>(cx, temp, graph, &oracle, info);
if (!compileContext.compile(builder, graph, autoDestroy)) {
IonSpew(IonSpew_Abort, "IM Compilation failed.");
return false;
}
if (!builder)
return AbortReason_Alloc;
return true;
AbortReason abortReason = compileContext.compile(builder, graph, autoDestroy);
if (abortReason != AbortReason_NoAbort)
IonSpew(IonSpew_Abort, "IM Compilation failed.");
return abortReason;
}
bool
AbortReason
SequentialCompileContext::compile(IonBuilder *builder, MIRGraph *graph,
AutoDestroyAllocator &autoDestroy)
{
@ -1208,7 +1210,7 @@ SequentialCompileContext::compile(IonBuilder *builder, MIRGraph *graph,
if (!builder->build()) {
IonSpew(IonSpew_Abort, "Builder failed to build.");
return false;
return builder->abortReason();
}
builder->clearForBackEnd();
@ -1226,20 +1228,20 @@ SequentialCompileContext::compile(IonBuilder *builder, MIRGraph *graph,
if (!StartOffThreadIonCompile(cx, builder)) {
IonSpew(IonSpew_Abort, "Unable to start off-thread ion compilation.");
return false;
return AbortReason_Alloc;
}
// The allocator and associated data will be destroyed after being
// processed in the finishedOffThreadCompilations list.
autoDestroy.cancel();
return true;
return AbortReason_NoAbort;
}
CodeGenerator *codegen = CompileBackEnd(builder);
if (!codegen) {
IonSpew(IonSpew_Abort, "Failed during back-end compilation.");
return false;
return AbortReason_Disable;
}
bool success = codegen->link();
@ -1247,19 +1249,30 @@ SequentialCompileContext::compile(IonBuilder *builder, MIRGraph *graph,
IonSpewEndFunction();
return success;
return success ? AbortReason_NoAbort : AbortReason_Disable;
}
bool
MethodStatus
TestIonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing)
{
SequentialCompileContext compileContext;
if (!IonCompile(cx, script, fun, osrPc, constructing, compileContext)) {
AbortReason reason = IonCompile(cx, script, fun, osrPc, constructing, compileContext);
if (reason == AbortReason_Alloc)
return Method_Skipped;
if (reason == AbortReason_Inlining)
return Method_Skipped;
if (reason == AbortReason_Disable) {
if (!cx->isExceptionPending())
ForbidCompilation(cx, script);
return false;
return Method_CantCompile;
}
return true;
JS_ASSERT(reason == AbortReason_NoAbort);
return Method_Compiled;
}
static bool
@ -1375,10 +1388,12 @@ Compile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrP
}
SequentialCompileContext compileContext;
if (!IonCompile(cx, script, fun, osrPc, constructing, compileContext))
AbortReason reason = IonCompile(cx, script, fun, osrPc, constructing, compileContext);
if (reason == AbortReason_Disable)
return Method_CantCompile;
// Compilation succeeded, but we invalidated right away.
// Compilation succeeded or we invalidated right away or an inlining/alloc abort
return script->hasIonScript() ? Method_Compiled : Method_Skipped;
}

View File

@ -211,6 +211,13 @@ enum MethodStatus
Method_Compiled
};
enum AbortReason {
AbortReason_Alloc,
AbortReason_Inlining,
AbortReason_Disable,
AbortReason_NoAbort
};
// An Ion context is needed to enter into either an Ion method or an instance
// of the Ion compiler. It points to a temporary allocator and the active
// JSContext, either of which may be NULL, and the active compartment, which
@ -296,7 +303,7 @@ class CodeGenerator;
CodeGenerator *CompileBackEnd(MIRGenerator *mir);
void AttachFinishedCompilations(JSContext *cx);
void FinishOffThreadBuilder(IonBuilder *builder);
bool TestIonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing);
MethodStatus TestIonCompile(JSContext *cx, HandleScript script, HandleFunction fun, jsbytecode *osrPc, bool constructing);
static inline bool IsEnabled(JSContext *cx)
{

View File

@ -35,6 +35,7 @@ IonBuilder::IonBuilder(JSContext *cx, TempAllocator *temp, MIRGraph *graph,
backgroundCodegen_(NULL),
recompileInfo(cx->compartment->types.compiledInfo),
cx(cx),
abortReason_(AbortReason_Disable),
loopDepth_(loopDepth),
callerResumePoint_(NULL),
callerBuilder_(NULL),
@ -346,6 +347,7 @@ IonBuilder::build()
return false;
JS_ASSERT(loopDepth_ == 0);
abortReason_ = AbortReason_NoAbort;
return true;
}
@ -2910,8 +2912,16 @@ IonBuilder::jsop_call_inline(HandleFunction callee, uint32_t argc, bool construc
}
// Build the graph.
if (!inlineBuilder.buildInline(this, inlineResumePoint, thisDefn, argv))
if (!inlineBuilder.buildInline(this, inlineResumePoint, thisDefn, argv)) {
JS_ASSERT(calleeScript->hasAnalysis());
// Inlining the callee failed. Disable inlining the function
if (inlineBuilder.abortReason_ == AbortReason_Disable)
calleeScript->analysis()->setIonUninlineable();
abortReason_ = AbortReason_Inlining;
return false;
}
MIRGraphExits &exits = *inlineBuilder.graph().exitAccumulator();

View File

@ -475,8 +475,11 @@ class IonBuilder : public MIRGenerator
CodeGenerator *backgroundCodegen() const { return backgroundCodegen_; }
void setBackgroundCodegen(CodeGenerator *codegen) { backgroundCodegen_ = codegen; }
AbortReason abortReason() { return abortReason_; }
private:
JSContext *cx;
AbortReason abortReason_;
jsbytecode *pc;
MBasicBlock *current;

View File

@ -47,14 +47,14 @@ ShouldMonitorReturnType(JSFunction *fun)
}
bool
InvokeFunction(JSContext *cx, JSFunction *fun, uint32_t argc, Value *argv, Value *rval)
InvokeFunction(JSContext *cx, HandleFunction fun, uint32_t argc, Value *argv, Value *rval)
{
Value fval = ObjectValue(*fun);
AssertCanGC();
// In order to prevent massive bouncing between Ion and JM, see if we keep
// hitting functions that are uncompilable.
if (fun->isInterpreted()) {
if (fun->isInterpretedLazy() && !fun->getOrCreateScript(cx))
if (fun->isInterpretedLazy() && !JSFunction::getOrCreateScript(cx, fun))
return false;
if (!fun->nonLazyScript()->canIonCompile()) {
UnrootedScript script = GetTopIonJSScript(cx);
@ -87,7 +87,7 @@ InvokeFunction(JSContext *cx, JSFunction *fun, uint32_t argc, Value *argv, Value
Value *argvWithoutThis = argv + 1;
// Run the function in the interpreter.
bool ok = Invoke(cx, thisv, fval, argc, argvWithoutThis, rval);
bool ok = Invoke(cx, thisv, ObjectValue(*fun), argc, argvWithoutThis, rval);
if (ok && needsMonitor)
types::TypeScript::Monitor(cx, *rval);

View File

@ -410,7 +410,7 @@ class AutoDetectInvalidation
}
};
bool InvokeFunction(JSContext *cx, JSFunction *fun, uint32_t argc, Value *argv, Value *rval);
bool InvokeFunction(JSContext *cx, HandleFunction fun, uint32_t argc, Value *argv, Value *rval);
JSObject *NewGCThing(JSContext *cx, gc::AllocKind allocKind, size_t thingSize);
bool CheckOverRecursed(JSContext *cx);

View File

@ -1163,7 +1163,7 @@ CodeGeneratorARM::visitCompareD(LCompareD *comp)
Assembler::DoubleCondition cond = JSOpToDoubleCondition(comp->mir()->jsop());
masm.compareDouble(lhs, rhs);
emitSet(Assembler::ConditionFromDoubleCondition(cond), ToRegister(comp->output()));
return false;
return true;
}
bool

View File

@ -0,0 +1,12 @@
// Don't crash.
try {
x = " () ";
for (var y = 0; y < 19; y++) {
x += x;
}
} catch (e) {}
try {
"".replace(x, "", "gy");
} catch (e) { }

View File

@ -0,0 +1,20 @@
// Returning {throw:} from an onPop handler when yielding works and
// does not close the generator-iterator.
load(libdir + "asserts.js");
var g = newGlobal('new-compartment');
var dbg = new Debugger;
var gw = dbg.addDebuggee(g);
dbg.onDebuggerStatement = function handleDebugger(frame) {
frame.onPop = function (c) {
return {throw: "fit"};
};
};
g.eval("function g() { for (var i = 0; i < 10; i++) { debugger; yield i; } }");
g.eval("var it = g();");
var rv = gw.evalInGlobal("it.next();");
assertEq(rv.throw, "fit");
dbg.enabled = false;
assertEq(g.it.next(), 1);

View File

@ -0,0 +1,17 @@
// Throwing an exception from an onPop handler when yielding terminates the debuggee
// but does not close the generator-iterator.
var g = newGlobal('new-compartment');
var dbg = new Debugger;
var gw = dbg.addDebuggee(g);
dbg.onDebuggerStatement = function handleDebugger(frame) {
frame.onPop = function (c) {
throw "fit";
};
};
g.eval("function g() { for (var i = 0; i < 10; i++) { debugger; yield i; } }");
g.eval("var it = g();");
assertEq(gw.evalInGlobal("it.next();"), null);
dbg.enabled = false;
assertEq(g.it.next(), 1);

View File

@ -0,0 +1,7 @@
gczeal(9, 2)
var g1 = newGlobal('new-compartment');
var g2 = newGlobal('new-compartment');
var dbg = new Debugger();
var g1w = dbg.addDebuggee(g1);
g1.eval('function f() {}');
scripts = dbg.findScripts({});

View File

@ -884,6 +884,7 @@ class ScriptAnalysis
bool failed() const { return hadFailure; }
bool ionInlineable() const { return isIonInlineable; }
bool ionInlineable(uint32_t argc) const { return isIonInlineable && argc == script_->function()->nargs; }
void setIonUninlineable() { isIonInlineable = false; }
bool jaegerInlineable() const { return isJaegerInlineable; }
bool jaegerInlineable(uint32_t argc) const { return isJaegerInlineable && argc == script_->function()->nargs; }
bool jaegerCompileable() { return isJaegerCompileable; }

View File

@ -8,9 +8,7 @@
BEGIN_TEST(testOOM)
{
JSString *jsstr = JS_ValueToString(cx, INT_TO_JSVAL(9));
jsval tmp = STRING_TO_JSVAL(jsstr);
JS_SetProperty(cx, global, "rootme", &tmp);
js::RootedString jsstr(cx, JS_ValueToString(cx, INT_TO_JSVAL(9)));
mozilla::DebugOnly<const jschar *> s = JS_GetStringCharsZ(cx, jsstr);
JS_ASSERT(s[0] == '9' && s[1] == '\0');
return true;

View File

@ -3,6 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "tests.h"
#include "jsscript.h"
BEGIN_TEST(testBug795104)
{
@ -21,3 +22,26 @@ BEGIN_TEST(testBug795104)
return true;
}
END_TEST(testBug795104)
const char *simpleSource = "var x = 4;";
static void
newScriptHook(JSContext *cx, const char *fn, unsigned lineno,
JSScript *script, JSFunction *fun, void *data)
{
if (!JS_StringEqualsAscii(cx, script->sourceData(cx), simpleSource, (JSBool *)data))
*((JSBool *)data) = JS_FALSE;
}
BEGIN_TEST(testScriptSourceReentrant)
{
JS::CompileOptions opts(cx);
JSBool match = false;
JS_SetNewScriptHook(rt, newScriptHook, &match);
CHECK(JS::Evaluate(cx, global, opts, simpleSource, strlen(simpleSource), NULL));
CHECK(match);
JS_SetNewScriptHook(rt, NULL, NULL);
return true;
}
END_TEST(testScriptSourceReentrant)

View File

@ -890,7 +890,8 @@ JSRuntime::JSRuntime(JSUseHelperThreads useHelperThreads)
ctypesActivityCallback(NULL),
ionReturnOverride_(MagicValue(JS_ARG_POISON)),
useHelperThreads_(useHelperThreads),
requestedHelperThreadCount(-1)
requestedHelperThreadCount(-1),
rngNonce(0)
{
/* Initialize infallibly first, so we can goto bad and JS_DestroyRuntime. */
JS_INIT_CLIST(&onNewGlobalObjectWatchers);

View File

@ -265,8 +265,6 @@ js::NewContext(JSRuntime *rt, size_t stackChunkSize)
bool first = rt->contextList.isEmpty();
rt->contextList.insertBack(cx);
js_InitRandom(cx);
/*
* If cx is the first context on this runtime, initialize well-known atoms,
* keywords, numbers, strings and self-hosted scripts. If one of these
@ -1117,7 +1115,6 @@ JSContext::JSContext(JSRuntime *rt)
outstandingRequests(0),
#endif
resolveFlags(0),
rngSeed(0),
iterValue(MagicValue(JS_NO_ITER_VALUE)),
#ifdef JS_METHODJIT
methodJitEnabled(false),

View File

@ -1220,6 +1220,16 @@ struct JSRuntime : js::RuntimeFriendFields
return 0;
#endif
}
private:
/*
* Used to ensure that compartments created at the same time get different
* random number sequences. See js::InitRandom.
*/
uint64_t rngNonce;
public:
uint64_t nextRNGNonce() { return rngNonce++; }
};
/* Common macros to access thread-local caches in JSRuntime. */
@ -1583,9 +1593,6 @@ struct JSContext : js::ContextFriendFields,
/* Stored here to avoid passing it around as a parameter. */
unsigned resolveFlags;
/* Random number generator state, used by jsmath.cpp. */
int64_t rngSeed;
/* Location to stash the iteration value between JSOP_MOREITER and JSOP_ITERNEXT. */
js::Value iterValue;

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