mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge last PGO-green changeset of mozilla-inbound to mozilla-central
This commit is contained in:
commit
2e7fd7927e
@ -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();
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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() {
|
||||
|
@ -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"))
|
||||
|
@ -17,8 +17,11 @@ XPIDLSRCS = \
|
||||
nsIBrowserHandler.idl \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_PP_COMPONENTS = \
|
||||
EXTRA_COMPONENTS = \
|
||||
BrowserComponents.manifest \
|
||||
$(NULL)
|
||||
|
||||
EXTRA_PP_COMPONENTS = \
|
||||
nsBrowserContentHandler.js \
|
||||
nsBrowserGlue.js \
|
||||
$(NULL)
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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 =
|
||||
|
@ -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)
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
BIN
browser/themes/pinstripe/privatebrowsing-mask.png
Normal file
BIN
browser/themes/pinstripe/privatebrowsing-mask.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
@ -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
|
||||
|
||||
|
@ -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)
|
||||
|
BIN
browser/themes/winstripe/privatebrowsing-dark.png
Normal file
BIN
browser/themes/winstripe/privatebrowsing-dark.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.3 KiB |
BIN
browser/themes/winstripe/privatebrowsing-light.png
Normal file
BIN
browser/themes/winstripe/privatebrowsing-light.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 696 B |
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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 \
|
||||
|
@ -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();
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -821,8 +821,8 @@ void MediaDecoder::PlaybackEnded()
|
||||
PlaybackPositionChanged();
|
||||
ChangeState(PLAY_STATE_ENDED);
|
||||
|
||||
UpdateReadyStateForData();
|
||||
if (mOwner) {
|
||||
UpdateReadyStateForData();
|
||||
mOwner->PlaybackEnded();
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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) {
|
||||
|
@ -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
|
@ -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,27 +15,36 @@
|
||||
#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:
|
||||
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_NSIDOMSVGVIEWELEMENT
|
||||
NS_DECL_NSIDOMSVGFITTOVIEWBOX
|
||||
@ -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
|
@ -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,15 +43,14 @@ 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);
|
||||
|
||||
|
||||
mNewScale = SVGSVGElement->GetCurrentScale();
|
||||
mPreviousScale = SVGSVGElement->GetPreviousScale();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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]);
|
||||
|
@ -74,6 +74,10 @@ this.NetworkStatsService = {
|
||||
},
|
||||
|
||||
receiveMessage: function(aMessage) {
|
||||
if (!aMessage.target.assertPermission("networkstats-manage")) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (DEBUG) {
|
||||
debug("receiveMessage " + aMessage.name);
|
||||
}
|
||||
|
@ -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
|
||||
|
||||
|
@ -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>
|
||||
|
31
dom/network/tests/test_networkstats_disabled.html
Normal file
31
dom/network/tests/test_networkstats_disabled.html
Normal 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>
|
35
dom/network/tests/test_networkstats_enabled_no_perm.html
Normal file
35
dom/network/tests/test_networkstats_enabled_no_perm.html
Normal 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>
|
34
dom/network/tests/test_networkstats_enabled_perm.html
Normal file
34
dom/network/tests/test_networkstats_enabled_perm.html
Normal 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>
|
@ -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) {
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
/*
|
||||
};
|
||||
|
||||
|
20
dom/webidl/SVGFitToViewBox.webidl
Normal file
20
dom/webidl/SVGFitToViewBox.webidl
Normal 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;
|
||||
};
|
||||
|
21
dom/webidl/SVGViewElement.webidl
Normal file
21
dom/webidl/SVGViewElement.webidl
Normal 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;
|
||||
|
24
dom/webidl/SVGZoomAndPan.webidl
Normal file
24
dom/webidl/SVGZoomAndPan.webidl
Normal 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;
|
||||
};
|
||||
|
@ -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 \
|
||||
|
@ -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.
|
||||
|
@ -106,6 +106,8 @@ MOCHITEST_FILES = \
|
||||
transferable_worker.js \
|
||||
test_errorwarning.html \
|
||||
errorwarning_worker.js \
|
||||
test_contentWorker.html \
|
||||
content_worker.js \
|
||||
$(NULL)
|
||||
|
||||
_SUBDIRMOCHITEST_FILES = \
|
||||
|
12
dom/workers/test/content_worker.js
Normal file
12
dom/workers/test/content_worker.js
Normal 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 });
|
48
dom/workers/test/test_contentWorker.html
Normal file
48
dom/workers/test/test_contentWorker.html
Normal 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>
|
@ -24,6 +24,7 @@ EXPORTS = \
|
||||
|
||||
LOCAL_INCLUDES = \
|
||||
-I$(srcdir)/../../../content/base/src \
|
||||
-I$(srcdir)/../../../content/svg/content/src \
|
||||
$(NULL)
|
||||
|
||||
SDK_XPIDLSRCS = \
|
||||
|
@ -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"
|
||||
@ -1028,9 +1028,11 @@ DefaultTooltipTextProvider::GetNodeText(nsIDOMNode *aNode, PRUnichar **aText,
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aNode);
|
||||
NS_ENSURE_ARG_POINTER(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;
|
||||
@ -1108,7 +1106,7 @@ DefaultTooltipTextProvider::GetNodeText(nsIDOMNode *aNode, PRUnichar **aText,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// not found here, walk up to the parent and keep trying
|
||||
if ( !found ) {
|
||||
nsCOMPtr<nsIDOMNode> temp ( current );
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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.
|
||||
|
@ -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 ();
|
||||
|
@ -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
|
||||
|
@ -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 ();
|
||||
}
|
||||
|
@ -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 {
|
||||
|
145
gfx/cairo/win32-gdi-font-cache-no-HFONT.patch
Normal file
145
gfx/cairo/win32-gdi-font-cache-no-HFONT.patch
Normal 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
|
375
gfx/cairo/win32-gdi-font-cache.patch
Normal file
375
gfx/cairo/win32-gdi-font-cache.patch
Normal 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
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
{
|
||||
|
@ -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, ®exp->asRegExp());
|
||||
|
||||
RegExpGuard re;
|
||||
RegExpGuard re(cx);
|
||||
if (!reobj->getShared(cx, &re))
|
||||
return RegExpRunStatus_Error;
|
||||
|
||||
|
@ -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 ========================================================
|
||||
|
@ -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;
|
||||
|
@ -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.
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
12
js/src/jit-test/tests/basic/bug826581.js
Normal file
12
js/src/jit-test/tests/basic/bug826581.js
Normal 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) { }
|
20
js/src/jit-test/tests/debug/Frame-onPop-generators-01.js
Normal file
20
js/src/jit-test/tests/debug/Frame-onPop-generators-01.js
Normal 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);
|
17
js/src/jit-test/tests/debug/Frame-onPop-generators-02.js
Normal file
17
js/src/jit-test/tests/debug/Frame-onPop-generators-02.js
Normal 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);
|
7
js/src/jit-test/tests/debug/bug-826669.js
Normal file
7
js/src/jit-test/tests/debug/bug-826669.js
Normal 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({});
|
@ -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; }
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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),
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user