Merge mozilla-central to UX

This commit is contained in:
Matthew Noorenberghe 2013-09-04 23:31:53 -07:00
commit 3d7d1a0ddb
623 changed files with 14766 additions and 6890 deletions

View File

@ -67,6 +67,11 @@ MIDL_GENERATED_FILES = \
EMBED_MANIFEST_AT = 2
INSTALL_TARGETS += midl
midl_FILES := $(filter %.h %_i.c,$(MIDL_GENERATED_FILES))
midl_DEST = $(DIST)/include
midl_TARGET := export
include $(topsrcdir)/config/rules.mk
OS_LIBS = $(call EXPAND_LIBNAME,uuid kernel32 rpcns4 rpcrt4 ole32 oleaut32)

View File

@ -5,49 +5,5 @@
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
MODULE = 'accessibility'
# Please keep this list in sync with the Makefile.in until the rest of that file
# is ported over.
midl_interfaces = [
'Accessible2',
'Accessible2_2',
'AccessibleAction',
'AccessibleApplication',
'AccessibleComponent',
'AccessibleDocument',
'AccessibleEditableText',
'AccessibleHyperlink',
'AccessibleHypertext',
'AccessibleHypertext2',
'AccessibleImage',
'AccessibleRelation',
'AccessibleTable',
'AccessibleTable2',
'AccessibleTableCell',
'AccessibleText',
'AccessibleText2',
'AccessibleValue',
]
# Please keep this list in sync with the Makefile.in until the rest of that file
# is ported over.
midl_enums = [
'AccessibleEventId',
'AccessibleRole',
'AccessibleStates',
'IA2CommonTypes',
]
headers = ['%s.h' % x for x in midl_enums]
interfaces_h = ['%s.h' % x for x in midl_interfaces]
interfaces_c = ['%s_i.c' % x for x in midl_interfaces]
# The underscore throws off sorting and EXPORTS expects sorted lists.
interfaces_c.sort()
EXPORTS += headers
EXPORTS += interfaces_h
EXPORTS += interfaces_c
LIBRARY_NAME = 'IA2Marshal'

View File

@ -60,5 +60,19 @@ register::
EMBED_MANIFEST_AT = 2
midl_exports := \
ISimpleDOMDocument.h \
ISimpleDOMDocument_i.c \
ISimpleDOMNode.h \
ISimpleDOMNode_i.c \
ISimpleDOMText.h \
ISimpleDOMText_i.c \
$(NULL)
INSTALL_TARGETS += midl_exports
midl_exports_FILES := $(midl_exports)
midl_exports_DEST = $(DIST)/include
midl_exports_TARGET := export
include $(topsrcdir)/config/rules.mk

View File

@ -6,14 +6,5 @@
MODULE = 'accessibility'
EXPORTS += [
'ISimpleDOMDocument.h',
'ISimpleDOMDocument_i.c',
'ISimpleDOMNode.h',
'ISimpleDOMNode_i.c',
'ISimpleDOMText.h',
'ISimpleDOMText_i.c',
]
LIBRARY_NAME = 'AccessibleMarshal'

View File

@ -11,6 +11,11 @@ include $(DEPTH)/config/autoconf.mk
EXTRA_MDDEPEND_FILES = xpcAccEvents.pp
INSTALL_TARGETS += xpcaccevents
xpcaccevents_FILES := xpcAccEvents.h
xpcaccevents_DEST = $(DIST)/include
xpcaccevents_TARGET := export
include $(topsrcdir)/config/rules.mk
LOCAL_INCLUDES = \

View File

@ -6,10 +6,6 @@
MODULE = 'accessibility'
EXPORTS += [
'xpcAccEvents.h',
]
CPP_SOURCES += [
'nsAccessibleRelation.cpp',
'xpcAccEvents.cpp',

View File

@ -4,7 +4,7 @@
#filter substitution
pref("toolkit.defaultChromeURI", "chrome://browser/content/shell.html");
pref("toolkit.defaultChromeURI", "chrome://browser/content/shell.xul");
pref("browser.chromeURL", "chrome://browser/content/");
// Device pixel to CSS px ratio, in percent. Set to -1 to calculate based on display density.

View File

@ -11,7 +11,7 @@ window.addEventListener('ContentStart', function() {
let shell = document.getElementById('shell');
// The <browser> element inside it
let browser = document.getElementById('systemapp');
let browser = document.getElementById('homescreen');
// Figure out the native resolution of the screen
let windowUtils = window.QueryInterface(Ci.nsIInterfaceRequestor)

View File

@ -4,7 +4,7 @@
* 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/. */
"use strict;"
"use strict";
const Cc = Components.classes;
const Ci = Components.interfaces;
@ -21,47 +21,65 @@ XPCOMUtils.defineLazyGetter(this, "libcutils", function () {
});
#endif
// Once Bug 731746 - Allow chrome JS object to implement nsIDOMEventTarget
// is resolved this helper could be removed.
var SettingsListener = {
_callbacks: {},
// Timer to remove the lock.
_timer: null,
init: function sl_init() {
if ('mozSettings' in navigator && navigator.mozSettings) {
navigator.mozSettings.onsettingchange = this.onchange.bind(this);
}
},
// lock stores here
_lock: null,
onchange: function sl_onchange(evt) {
var callback = this._callbacks[evt.settingName];
if (callback) {
callback(evt.settingValue);
/**
* getSettingsLock: create a lock or retrieve one that we saved.
* mozSettings.createLock() is expensive and lock should be reused
* whenever possible.
*/
getSettingsLock: function sl_getSettingsLock() {
// Each time there is a getSettingsLock call, we postpone the removal.
clearTimeout(this._timer);
this._timer = setTimeout((function() {
this._lock = null;
}).bind(this), 0);
// If there is a lock present we return that.
if (this._lock) {
return this._lock;
}
// If there isn't we create a new one.
let settings = window.navigator.mozSettings;
return (this._lock = settings.createLock());
},
observe: function sl_observe(name, defaultValue, callback) {
var settings = window.navigator.mozSettings;
if (!settings) {
window.setTimeout(function() { callback(defaultValue); });
return;
let settings = window.navigator.mozSettings;
let req;
try {
req = this.getSettingsLock().get(name);
} catch (e) {
// It is possible (but rare) for getSettingsLock() to return
// a SettingsLock object that is no longer valid.
// Until https://bugzilla.mozilla.org/show_bug.cgi?id=793239
// is fixed, we just catch the resulting exception and try
// again with a fresh lock
console.warn('Stale lock in settings.js.',
'See https://bugzilla.mozilla.org/show_bug.cgi?id=793239');
this._lock = null;
req = this.getSettingsLock().get(name);
}
if (!callback || typeof callback !== 'function') {
throw new Error('Callback is not a function');
}
var req = settings.createLock().get(name);
req.addEventListener('success', (function onsuccess() {
callback(typeof(req.result[name]) != 'undefined' ?
req.result[name] : defaultValue);
}));
this._callbacks[name] = callback;
settings.addObserver(name, function settingChanged(evt) {
callback(evt.settingValue);
});
}
};
SettingsListener.init();
// =================== Console ======================
SettingsListener.observe('debug.console.enabled', true, function(value) {

View File

@ -1,33 +0,0 @@
<!DOCTYPE html>
<!-- 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/. -->
<html xmlns="http://www.w3.org/1999/xhtml"
id="shell"
windowtype="navigator:browser"
#ifdef ANDROID
sizemode="fullscreen"
#endif
style="background: black; overflow: hidden; width:100%; height:100%; padding: 0px !important"
onunload="shell.stop();">
<head>
<script type="application/javascript;version=1.8"
src="chrome://browser/content/settings.js"> </script>
<script type="application/javascript;version=1.8"
src="chrome://browser/content/shell.js"> </script>
#ifndef MOZ_WIDGET_GONK
<!-- this script handles the screen argument for desktop builds -->
<script type="application/javascript;version=1.8"
src="chrome://browser/content/screen.js"> </script>
<!-- this script handles the "runapp" argument for desktop builds -->
<script type="application/javascript;version=1.8"
src="chrome://browser/content/runapp.js"> </script>
#endif
</head>
<body id="container" style="margin: 0px; width:100%; height:100%;">
<!-- The html:iframe containing the UI is created here. -->
</body>
</html>

View File

@ -6,9 +6,6 @@
Cu.import('resource://gre/modules/ContactService.jsm');
Cu.import('resource://gre/modules/SettingsChangeNotifier.jsm');
#ifdef MOZ_B2G_FM
Cu.import('resource://gre/modules/DOMFMRadioParent.jsm');
#endif
Cu.import('resource://gre/modules/AlarmService.jsm');
Cu.import('resource://gre/modules/ActivitiesService.jsm');
Cu.import('resource://gre/modules/PermissionPromptHelper.jsm');
@ -186,7 +183,7 @@ var shell = {
get contentBrowser() {
delete this.contentBrowser;
return this.contentBrowser = document.getElementById('systemapp');
return this.contentBrowser = document.getElementById('homescreen');
},
get homeURL() {
@ -269,25 +266,25 @@ var shell = {
}
let manifestURL = this.manifestURL;
// <html:iframe id="systemapp"
// <html:iframe id="homescreen"
// mozbrowser="true" allowfullscreen="true"
// style="overflow: hidden; height: 100%; width: 100%; border: none;"
// style="overflow: hidden; -moz-box-flex: 1; border: none;"
// src="data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;'>"/>
let systemAppFrame =
let browserFrame =
document.createElementNS('http://www.w3.org/1999/xhtml', 'html:iframe');
systemAppFrame.setAttribute('id', 'systemapp');
systemAppFrame.setAttribute('mozbrowser', 'true');
systemAppFrame.setAttribute('mozapp', manifestURL);
systemAppFrame.setAttribute('allowfullscreen', 'true');
systemAppFrame.setAttribute('style', "overflow: hidden; height: 100%; width: 100%; border: none;");
systemAppFrame.setAttribute('src', "data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;");
document.getElementById('container').appendChild(systemAppFrame);
browserFrame.setAttribute('id', 'homescreen');
browserFrame.setAttribute('mozbrowser', 'true');
browserFrame.setAttribute('mozapp', manifestURL);
browserFrame.setAttribute('allowfullscreen', 'true');
browserFrame.setAttribute('style', "overflow: hidden; -moz-box-flex: 1; border: none;");
browserFrame.setAttribute('src', "data:text/html;charset=utf-8,%3C!DOCTYPE html>%3Cbody style='background:black;");
document.getElementById('shell').appendChild(browserFrame);
systemAppFrame.contentWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.sessionHistory = Cc["@mozilla.org/browser/shistory;1"]
.createInstance(Ci.nsISHistory);
browserFrame.contentWindow
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.sessionHistory = Cc["@mozilla.org/browser/shistory;1"]
.createInstance(Ci.nsISHistory);
// Capture all key events so we can filter out hardware buttons
// And send them to Gaia via mozChromeEvents.

View File

@ -0,0 +1,26 @@
<?xml version="1.0"?>
<!-- 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/. -->
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
id="shell"
windowtype="navigator:browser"
#ifdef ANDROID
sizemode="fullscreen"
#endif
style="background: black; overflow: hidden; width:320px; height:480px"
onunload="shell.stop();">
<script type="application/javascript" src="chrome://browser/content/settings.js"/>
<script type="application/javascript" src="chrome://browser/content/shell.js"/>
#ifndef MOZ_WIDGET_GONK
<!-- this script handles the screen argument for desktop builds -->
<script type="application/javascript" src="chrome://browser/content/screen.js"/>
<!-- this script handles the "runapp" argument for desktop builds -->
<script type="application/javascript" src="chrome://browser/content/runapp.js"/>
#endif
<!-- The html:iframe containing the UI is created here. -->
</window>

View File

@ -12,7 +12,7 @@ chrome.jar:
* content/dbg-browser-actors.js (content/dbg-browser-actors.js)
content/forms.js (content/forms.js)
* content/settings.js (content/settings.js)
* content/shell.html (content/shell.html)
* content/shell.xul (content/shell.xul)
* content/shell.js (content/shell.js)
#ifndef ANDROID
content/screen.js (content/screen.js)

View File

@ -1,4 +1,4 @@
{
"revision": "f2d88904536ccd68a3981a7feb17e56b2132838c",
"revision": "4296bbf526e4ed8d0ae443f20947bd2d7189aa0e",
"repo_path": "/integration/gaia-central"
}

View File

@ -172,9 +172,6 @@
@BINPATH@/components/dom_cellbroadcast.xpt
@BINPATH@/components/dom_wappush.xpt
#endif
#ifdef MOZ_B2G_FM
@BINPATH@/components/dom_fm.xpt
#endif
#ifdef MOZ_B2G_BT
@BINPATH@/components/dom_bluetooth.xpt
#endif
@ -475,10 +472,6 @@
@BINPATH@/components/NetworkInterfaceListService.manifest
@BINPATH@/components/NetworkInterfaceListService.js
#endif
#ifdef MOZ_B2G_FM
@BINPATH@/components/DOMFMRadioChild.js
@BINPATH@/components/DOMFMRadio.manifest
#endif
#ifdef MOZ_ENABLE_DBUS
@BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
#endif

View File

@ -1074,6 +1074,7 @@ pref("devtools.inspector.enabled", true);
pref("devtools.inspector.activeSidebar", "ruleview");
pref("devtools.inspector.markupPreview", false);
pref("devtools.inspector.remote", false);
pref("devtools.inspector.show_pseudo_elements", true);
// Enable the Layout View
pref("devtools.layoutview.enabled", true);

View File

@ -0,0 +1,56 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- 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/. -->
<!DOCTYPE html [
<!ENTITY % htmlDTD
PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"DTD/xhtml1-strict.dtd">
%htmlDTD;
<!ENTITY % globalDTD
SYSTEM "chrome://global/locale/global.dtd">
%globalDTD;
<!ENTITY % browserDTD
SYSTEM "chrome://browser/locale/browser.dtd">
%browserDTD;
]>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<link rel="stylesheet" type="text/css" media="all"
href="chrome://browser/skin/aboutTabCrashed.css"/>
</head>
<body dir="&locale.dir;">
<div id="error-box">
<p id="main-error-msg">&tabCrashed.header;</p>
<p id="helper-error-msg">&tabCrashed.message;</p>
</div>
<div id="button-box">
<button id="tryAgain">&tabCrashed.tryAgain;</button>
</div>
</body>
<script type="text/javascript;version=1.8"><![CDATA[
function parseQueryString() {
let url = document.documentURI;
let queryString = url.replace(/^about:tabcrashed?e=tabcrashed/, "");
let urlMatch = queryString.match(/u=([^&]+)/);
let url = urlMatch && urlMatch[1] ? decodeURIComponent(urlMatch[1]) : "";
let titleMatch = queryString.match(/d=([^&]*)/);
title = titleMatch && titleMatch[1] ? decodeURIComponent(titleMatch[1]) : "";
return [url, title];
}
let [url, title] = parseQueryString();
document.title = title;
document.getElementById("tryAgain").setAttribute("url", url);
]]></script>
</html>

View File

@ -37,6 +37,10 @@ SocialUI = {
Services.obs.addObserver(this, "social:provider-set", false);
Services.obs.addObserver(this, "social:providers-changed", false);
Services.obs.addObserver(this, "social:provider-reload", false);
Services.obs.addObserver(this, "social:provider-installed", false);
Services.obs.addObserver(this, "social:provider-uninstalled", false);
Services.obs.addObserver(this, "social:provider-enabled", false);
Services.obs.addObserver(this, "social:provider-disabled", false);
Services.prefs.addObserver("social.sidebar.open", this, false);
Services.prefs.addObserver("social.toast-notifications.enabled", this, false);
@ -62,6 +66,10 @@ SocialUI = {
Services.obs.removeObserver(this, "social:provider-set");
Services.obs.removeObserver(this, "social:providers-changed");
Services.obs.removeObserver(this, "social:provider-reload");
Services.obs.removeObserver(this, "social:provider-installed");
Services.obs.removeObserver(this, "social:provider-uninstalled");
Services.obs.removeObserver(this, "social:provider-enabled");
Services.obs.removeObserver(this, "social:provider-disabled");
Services.prefs.removeObserver("social.sidebar.open", this);
Services.prefs.removeObserver("social.toast-notifications.enabled", this);
@ -76,6 +84,18 @@ SocialUI = {
// manually :(
try {
switch (topic) {
case "social:provider-installed":
SocialStatus.setPosition(data);
break;
case "social:provider-uninstalled":
SocialStatus.removePosition(data);
break;
case "social:provider-enabled":
SocialStatus.populateToolbarPalette();
break;
case "social:provider-disabled":
SocialStatus.removeProvider(data);
break;
case "social:provider-reload":
// if the reloaded provider is our current provider, fall through
// to social:provider-set so the ui will be reset
@ -98,6 +118,7 @@ SocialUI = {
SocialSidebar.update();
SocialMark.update();
SocialToolbar.update();
SocialStatus.populateToolbarPalette();
SocialMenu.populate();
break;
case "social:providers-changed":
@ -106,10 +127,12 @@ SocialUI = {
// and the multi-provider menu
SocialToolbar.populateProviderMenus();
SocialShare.populateProviderMenu();
SocialStatus.populateToolbarPalette();
break;
// Provider-specific notifications
case "social:ambient-notification-changed":
SocialStatus.updateNotification(data);
if (this._matchesCurrentProvider(data)) {
SocialToolbar.updateButton();
SocialMenu.populate();
@ -1054,6 +1077,15 @@ SocialToolbar = {
Services.prefs.clearUserPref(CACHE_PREF_NAME);
return;
}
// If the provider uses the new SocialStatus button, then they do not get
// to use the ambient icons in the old toolbar button. Since the status
// button depends on multiple workers, if not enabled we will ignore this
// limitation. That allows a provider to migrate to the new functionality
// once we enable multiple workers.
if (Social.provider.statusURL && Social.allowMultipleWorkers)
return;
let icons = Social.provider.ambientNotificationIcons;
let iconNames = Object.keys(icons);
@ -1152,9 +1184,8 @@ SocialToolbar = {
socialToolbarItem.insertBefore(toolbarButtons, SocialMark.button);
for (let frame of createdFrames) {
if (frame.socialErrorListener) {
if (frame.socialErrorListener)
frame.socialErrorListener.remove();
}
if (frame.docShell) {
frame.docShell.isActive = false;
Social.setErrorListener(frame, this.setPanelErrorMessage.bind(this));
@ -1199,11 +1230,10 @@ SocialToolbar = {
panel.addEventListener("popupshown", function onpopupshown() {
panel.removeEventListener("popupshown", onpopupshown);
// 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.
// The "open" 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;
@ -1388,4 +1418,353 @@ SocialSidebar = {
}
}
// this helper class is used by removable/customizable buttons to handle
// location persistence and insertion into palette and/or toolbars
// When a provider is installed we show all their UI so the user will see the
// functionality of what they installed. The user can later customize the UI,
// moving buttons around or off the toolbar.
//
// To make this happen, on install we add a button id to the navbar currentset.
// On enabling the provider (happens just after install) we insert the button
// into the toolbar as well. The button is then persisted on restart (assuming
// it was not removed).
//
// When a provider is disabled, we do not remove the buttons from currentset.
// That way, if the provider is re-enabled during the same session, the buttons
// will reappear where they were before. When a provider is uninstalled, we make
// sure that the id is removed from currentset.
//
// On startup, we insert the buttons of any enabled provider into either the
// apropriate toolbar or the palette.
function ToolbarHelper(type, createButtonFn) {
this._createButton = createButtonFn;
this._type = type;
}
ToolbarHelper.prototype = {
idFromOrgin: function(origin) {
return this._type + "-" + origin;
},
// find a button either in the document or the palette
_getExistingButton: function(id) {
let button = document.getElementById(id);
if (button)
return button;
let palette = document.getElementById("navigator-toolbox").palette;
let paletteItem = palette.firstChild;
while (paletteItem) {
if (paletteItem.id == id)
return paletteItem;
paletteItem = paletteItem.nextSibling;
}
return null;
},
setPersistentPosition: function(id) {
// called when a provider is installed. add provider buttons to nav-bar
let toolbar = document.getElementById("nav-bar");
// first startups will not have a currentset attribute, always rely on
// currentSet since it will be derived from the defaultset in that case.
let currentset = toolbar.currentSet;
if (currentset == "__empty")
currentset = []
else
currentset = currentset.split(",");
if (currentset.indexOf(id) >= 0)
return;
// we do not set toolbar.currentSet since that will try to add the button,
// and we have not added it yet (happens on provider being enabled)
currentset.push(id);
toolbar.setAttribute("currentset", currentset.join(","));
document.persist(toolbar.id, "currentset");
},
removeProviderButton: function(origin) {
// this will remove the button from the palette or the toolbar
let button = this._getExistingButton(this.idFromOrgin(origin));
if (button)
button.parentNode.removeChild(button);
},
removePersistence: function(id) {
let persisted = document.querySelectorAll("*[currentset]");
for (let pent of persisted) {
// the button will have been removed, but left in the currentset attribute
// in case the user re-enables (e.g. undo in addon manager). So we only
// check the attribute here.
let currentset = pent.getAttribute("currentset").split(",");
let pos = currentset.indexOf(id);
if (pos >= 0) {
currentset.splice(pos, 1);
pent.setAttribute("currentset", currentset.join(","));
document.persist(pent.id, "currentset");
return;
}
}
},
// if social is entirely disabled, we need to clear the palette, but leave
// the persisted id's in place
clearPalette: function() {
[this.removeProviderButton(p.origin) for (p of Social.providers)];
},
// should be called on startup of each window, otherwise the addon manager
// listener will handle new activations, or enable/disabling of a provider
// XXX we currently call more regularly, will fix during refactoring
populatePalette: function() {
if (!Social.enabled) {
this.clearPalette();
return;
}
let persisted = document.querySelectorAll("*[currentset]");
let persistedById = {};
for (let pent of persisted) {
let pset = pent.getAttribute("currentset").split(',');
for (let id of pset)
persistedById[id] = pent;
}
// create any buttons that do not exist yet if they have been persisted
// as a part of the UI (otherwise they belong in the palette).
for (let provider of Social.providers) {
let id = this.idFromOrgin(provider.origin);
if (this._getExistingButton(id))
return;
let button = this._createButton(provider);
if (button && persistedById.hasOwnProperty(id)) {
let parent = persistedById[id];
let pset = persistedById[id].getAttribute("currentset").split(',');
let pi = pset.indexOf(id) + 1;
let next = document.getElementById(pset[pi]);
parent.insertItem(id, next, null, false);
}
}
}
}
SocialStatus = {
populateToolbarPalette: function() {
if (!Social.allowMultipleWorkers)
return;
this._toolbarHelper.populatePalette();
},
setPosition: function(origin) {
if (!Social.allowMultipleWorkers)
return;
// this is called during install, before the provider is enabled so we have
// to use the manifest rather than the provider instance as we do elsewhere.
let manifest = Social.getManifestByOrigin(origin);
if (!manifest.statusURL)
return;
let tbh = this._toolbarHelper;
tbh.setPersistentPosition(tbh.idFromOrgin(origin));
},
removePosition: function(origin) {
if (!Social.allowMultipleWorkers)
return;
let tbh = this._toolbarHelper;
tbh.removePersistence(tbh.idFromOrgin(origin));
},
removeProvider: function(origin) {
if (!Social.allowMultipleWorkers)
return;
this._toolbarHelper.removeProviderButton(origin);
},
get _toolbarHelper() {
delete this._toolbarHelper;
this._toolbarHelper = new ToolbarHelper("social-status-button", this._createButton.bind(this));
return this._toolbarHelper;
},
get _dynamicResizer() {
delete this._dynamicResizer;
this._dynamicResizer = new DynamicResizeWatcher();
return this._dynamicResizer;
},
_createButton: function(provider) {
if (!provider.statusURL)
return null;
let palette = document.getElementById("navigator-toolbox").palette;
let button = document.createElement("toolbarbutton");
button.setAttribute("class", "toolbarbutton-1 social-status-button");
button.setAttribute("type", "badged");
button.setAttribute("removable", "true");
button.setAttribute("image", provider.iconURL);
button.setAttribute("label", provider.name);
button.setAttribute("tooltiptext", provider.name);
button.setAttribute("origin", provider.origin);
button.setAttribute("oncommand", "SocialStatus.showPopup(this);");
button.setAttribute("id", this._toolbarHelper.idFromOrgin(provider.origin));
palette.appendChild(button);
return button;
},
// status panels are one-per button per-process, we swap the docshells between
// windows when necessary
_attachNotificatonPanel: function(aButton, provider) {
let panel = document.getElementById("social-notification-panel");
panel.hidden = !SocialUI.enabled;
let notificationFrameId = "social-status-" + provider.origin;
let frame = document.getElementById(notificationFrameId);
if (!frame) {
frame = SharedFrame.createFrame(
notificationFrameId, /* frame name */
panel, /* parent */
{
"type": "content",
"mozbrowser": "true",
"class": "social-panel-frame",
"id": notificationFrameId,
"tooltip": "aHTMLTooltip",
// work around bug 793057 - by making the panel roughly the final size
// we are more likely to have the anchor in the correct position.
"style": "width: " + PANEL_MIN_WIDTH + "px;",
"origin": provider.origin,
"src": provider.statusURL
}
);
if (frame.socialErrorListener)
frame.socialErrorListener.remove();
if (frame.docShell) {
frame.docShell.isActive = false;
Social.setErrorListener(frame, this.setPanelErrorMessage.bind(this));
}
} else {
frame.setAttribute("origin", provider.origin);
SharedFrame.updateURL(notificationFrameId, provider.statusURL);
}
aButton.setAttribute("notificationFrameId", notificationFrameId);
},
updateNotification: function(origin) {
if (!Social.allowMultipleWorkers)
return;
let provider = Social._getProviderFromOrigin(origin);
let button = document.getElementById(this._toolbarHelper.idFromOrgin(provider.origin));
if (button) {
// we only grab the first notification, ignore all others
let icons = provider.ambientNotificationIcons;
let iconNames = Object.keys(icons);
let notif = icons[iconNames[0]];
if (!notif) {
button.setAttribute("badge", "");
button.setAttribute("aria-label", "");
button.setAttribute("tooltiptext", "");
return;
}
button.style.listStyleImage = "url(" + notif.iconURL || provider.iconURL + ")";
button.setAttribute("tooltiptext", notif.label);
let badge = notif.counter || "";
button.setAttribute("badge", badge);
let ariaLabel = notif.label;
// if there is a badge value, we must use a localizable string to insert it.
if (badge)
ariaLabel = gNavigatorBundle.getFormattedString("social.aria.toolbarButtonBadgeText",
[ariaLabel, badge]);
button.setAttribute("aria-label", ariaLabel);
}
},
showPopup: function(aToolbarButton) {
if (!Social.allowMultipleWorkers)
return;
// attach our notification panel if necessary
let origin = aToolbarButton.getAttribute("origin");
let provider = Social._getProviderFromOrigin(origin);
this._attachNotificatonPanel(aToolbarButton, provider);
let panel = document.getElementById("social-notification-panel");
let notificationFrameId = aToolbarButton.getAttribute("notificationFrameId");
let notificationFrame = document.getElementById(notificationFrameId);
let wasAlive = SharedFrame.isGroupAlive(notificationFrameId);
SharedFrame.setOwner(notificationFrameId, notificationFrame);
// Clear dimensions on all browsers so the panel size will
// only use the selected browser.
let frameIter = panel.firstElementChild;
while (frameIter) {
frameIter.collapsed = (frameIter != notificationFrame);
frameIter = frameIter.nextElementSibling;
}
function dispatchPanelEvent(name) {
let evt = notificationFrame.contentDocument.createEvent("CustomEvent");
evt.initCustomEvent(name, true, true, {});
notificationFrame.contentDocument.documentElement.dispatchEvent(evt);
}
let dynamicResizer = this._dynamicResizer;
panel.addEventListener("popuphidden", function onpopuphiding() {
panel.removeEventListener("popuphidden", onpopuphiding);
aToolbarButton.removeAttribute("open");
dynamicResizer.stop();
notificationFrame.docShell.isActive = false;
dispatchPanelEvent("socialFrameHide");
});
panel.addEventListener("popupshown", function onpopupshown() {
panel.removeEventListener("popupshown", onpopupshown);
// 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");
notificationFrame.docShell.isActive = true;
notificationFrame.docShell.isAppTab = true;
if (notificationFrame.contentDocument.readyState == "complete" && wasAlive) {
dynamicResizer.start(panel, notificationFrame);
dispatchPanelEvent("socialFrameShow");
} else {
// first time load, wait for load and dispatch after load
notificationFrame.addEventListener("load", function panelBrowserOnload(e) {
notificationFrame.removeEventListener("load", panelBrowserOnload, true);
dynamicResizer.start(panel, notificationFrame);
dispatchPanelEvent("socialFrameShow");
}, true);
}
});
let navBar = document.getElementById("nav-bar");
let anchor = navBar.getAttribute("mode") == "text" ?
document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-text") :
document.getAnonymousElementByAttribute(aToolbarButton, "class", "toolbarbutton-badge-container");
// Bug 849216 - open the popup in a setTimeout so we avoid the auto-rollup
// handling from preventing it being opened in some cases.
setTimeout(function() {
panel.openPopup(anchor, "bottomcenter topright", 0, 0, false, false);
}, 0);
},
setPanelErrorMessage: function(aNotificationFrame) {
if (!aNotificationFrame)
return;
let src = aNotificationFrame.getAttribute("src");
aNotificationFrame.removeAttribute("src");
aNotificationFrame.webNavigation.loadURI("about:socialerror?mode=tryAgainOnly&url=" +
encodeURIComponent(src),
null, null, null, null);
let panel = aNotificationFrame.parentNode;
sizeSocialPanelToContent(panel, aNotificationFrame);
},
};
})();

View File

@ -2180,9 +2180,10 @@ function losslessDecodeURI(aURI) {
encodeURIComponent);
} catch (e) {}
// Encode invisible characters (line and paragraph separator,
// object replacement character) (bug 452979)
value = value.replace(/[\v\x0c\x1c\x1d\x1e\x1f\u2028\u2029\ufffc]/g,
// Encode invisible characters (C0/C1 control characters, U+007F [DEL],
// U+00A0 [no-break space], line and paragraph separator,
// object replacement character) (bug 452979, bug 909264)
value = value.replace(/[\u0000-\u001f\u007f-\u00a0\u2028\u2029\ufffc]/g,
encodeURIComponent);
// Encode default ignorable characters (bug 546013)
@ -2286,6 +2287,9 @@ let BrowserOnClick = {
ownerDoc.documentURI.toLowerCase() == "about:newtab") {
this.onE10sAboutNewTab(aEvent, ownerDoc);
}
else if (ownerDoc.documentURI.startsWith("about:tabcrashed")) {
this.onAboutTabCrashed(aEvent, ownerDoc);
}
},
onAboutCertError: function BrowserOnClick_onAboutCertError(aTargetElm, aOwnerDoc) {
@ -2418,6 +2422,22 @@ let BrowserOnClick = {
}
},
/**
* The about:tabcrashed can't do window.reload() because that
* would reload the page but not use a remote browser.
*/
onAboutTabCrashed: function(aEvent, aOwnerDoc) {
let isTopFrame = (aOwnerDoc.defaultView.parent === aOwnerDoc.defaultView);
if (!isTopFrame) {
return;
}
let button = aEvent.originalTarget;
if (button.id == "tryAgain") {
openUILinkIn(button.getAttribute("url"), "current");
}
},
ignoreWarningButton: function BrowserOnClick_ignoreWarningButton(aIsMalware) {
// Allow users to override and continue through to the site,
// but add a notify bar as a reminder, so that they don't lose
@ -2527,6 +2547,16 @@ function getWebNavigation()
}
function BrowserReloadWithFlags(reloadFlags) {
let url = gBrowser.currentURI.spec;
if (gBrowser._updateBrowserRemoteness(gBrowser.selectedBrowser,
gBrowser._shouldBrowserBeRemote(url))) {
// If the remoteness has changed, the new browser doesn't have any
// information of what was loaded before, so we need to load the previous
// URL again.
gBrowser.loadURIWithFlags(url, reloadFlags);
return;
}
/* First, we'll try to use the session history object to reload so
* that framesets are handled properly. If we're in a special
* window (such as view-source) that has no session history, fall

View File

@ -1316,7 +1316,7 @@
<![CDATA[
let isRemote = aBrowser.getAttribute("remote") == "true";
if (isRemote == aRemote)
return;
return false;
// Unhook our progress listener.
let tab = this._getTabForBrowser(aBrowser);
@ -1337,6 +1337,8 @@
tab.setAttribute("remote", "true");
else
tab.removeAttribute("remote");
return true;
]]>
</body>
</method>
@ -3116,6 +3118,22 @@
tab.setAttribute("titlechanged", "true");
]]>
</handler>
<handler event="oop-browser-crashed">
<![CDATA[
if (!event.isTrusted)
return;
let browser = event.originalTarget;
let title = browser.contentTitle;
let uri = browser.currentURI;
this._updateBrowserRemoteness(browser, false);
browser.setAttribute("crashedPageTitle", title);
browser.docShell.displayLoadError(Cr.NS_ERROR_CONTENT_CRASHED, uri, null);
browser.removeAttribute("crashedPageTitle");
]]>
</handler>
</handlers>
</binding>

View File

@ -31,6 +31,7 @@ MOCHITEST_BROWSER_FILES = \
browser_social_multiprovider.js \
browser_social_multiworker.js \
browser_social_errorPage.js \
browser_social_status.js \
browser_social_window.js \
social_activate.html \
social_activate_iframe.html \

View File

@ -50,9 +50,10 @@ function installListener(next, aManifest) {
let expectEvent = "onInstalling";
let prefname = getManifestPrefname(aManifest);
// wait for the actual removal to call next
SocialService.registerProviderListener(function providerListener(topic, data) {
if (topic == "provider-removed") {
SocialService.registerProviderListener(function providerListener(topic, origin, providers) {
if (topic == "provider-disabled") {
SocialService.unregisterProviderListener(providerListener);
is(origin, aManifest.origin, "provider disabled");
executeSoon(next);
}
});
@ -295,14 +296,15 @@ var tests = {
Social.enabled = true;
// watch for the provider-update and test the new version
SocialService.registerProviderListener(function providerListener(topic, data) {
SocialService.registerProviderListener(function providerListener(topic, origin, providers) {
if (topic != "provider-update")
return;
is(origin, addonManifest.origin, "provider updated")
SocialService.unregisterProviderListener(providerListener);
Services.prefs.clearUserPref("social.whitelist");
let provider = Social._getProviderFromOrigin(addonManifest.origin);
let provider = Social._getProviderFromOrigin(origin);
is(provider.manifest.version, 2, "manifest version is 2");
Social.uninstallProvider(addonManifest.origin, function() {
Social.uninstallProvider(origin, function() {
gBrowser.removeTab(tab);
next();
});

View File

@ -155,14 +155,15 @@ var tests = {
setManifestPref("social.manifest.blocked", manifest_bad);
try {
SocialService.addProvider(manifest_bad, function(provider) {
// the act of blocking should cause a 'provider-removed' notification
// the act of blocking should cause a 'provider-disabled' notification
// from SocialService.
SocialService.registerProviderListener(function providerListener(topic) {
if (topic != "provider-removed")
SocialService.registerProviderListener(function providerListener(topic, origin, providers) {
if (topic != "provider-disabled")
return;
SocialService.unregisterProviderListener(providerListener);
is(origin, provider.origin, "provider disabled");
SocialService.getProvider(provider.origin, function(p) {
ok(p==null, "blocklisted provider removed");
ok(p == null, "blocklisted provider disabled");
Services.prefs.clearUserPref("social.manifest.blocked");
resetBlocklist(finish);
});

View File

@ -19,6 +19,13 @@ function test() {
var tests = {
testStatusIcons: function(next) {
let icon = {
name: "testIcon",
iconURL: "chrome://browser/skin/Info.png",
contentPanel: "https://example.com/browser/browser/base/content/test/social/social_panel.html",
counter: 1
};
let iconsReady = false;
let gotSidebarMessage = false;
@ -71,7 +78,7 @@ var tests = {
ok(true, "got sidebar message");
gotSidebarMessage = true;
// load a status panel
port.postMessage({topic: "test-ambient-notification"});
port.postMessage({topic: "test-ambient-notification", data: icon});
checkNext();
break;
}

View File

@ -0,0 +1,220 @@
/* 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/. */
let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
let manifest = { // builtin provider
name: "provider example.com",
origin: "https://example.com",
sidebarURL: "https://example.com/browser/browser/base/content/test/social/social_sidebar.html",
workerURL: "https://example.com/browser/browser/base/content/test/social/social_worker.js",
iconURL: "https://example.com/browser/browser/base/content/test/moz.png"
};
let manifest2 = { // used for testing install
name: "provider test1",
origin: "https://test1.example.com",
workerURL: "https://test1.example.com/browser/browser/base/content/test/social/social_worker.js",
statusURL: "https://test1.example.com/browser/browser/base/content/test/social/social_panel.html",
iconURL: "https://test1.example.com/browser/browser/base/content/test/moz.png",
version: 1
};
let manifest3 = { // used for testing install
name: "provider test2",
origin: "https://test2.example.com",
sidebarURL: "https://test2.example.com/browser/browser/base/content/test/social/social_sidebar.html",
iconURL: "https://test2.example.com/browser/browser/base/content/test/moz.png",
version: 1
};
function openWindowAndWaitForInit(callback) {
let topic = "browser-delayed-startup-finished";
let w = OpenBrowserWindow();
Services.obs.addObserver(function providerSet(subject, topic, data) {
Services.obs.removeObserver(providerSet, topic);
executeSoon(() => callback(w));
}, topic, false);
}
function test() {
waitForExplicitFinish();
Services.prefs.setBoolPref("social.allowMultipleWorkers", true);
let toolbar = document.getElementById("nav-bar");
let currentsetAtStart = toolbar.currentSet;
info("tb0 "+currentsetAtStart);
runSocialTestWithProvider(manifest, function () {
runSocialTests(tests, undefined, undefined, function () {
Services.prefs.clearUserPref("social.remote-install.enabled");
// just in case the tests failed, clear these here as well
Services.prefs.clearUserPref("social.allowMultipleWorkers");
Services.prefs.clearUserPref("social.whitelist");
// This post-test test ensures that a new window maintains the same
// toolbar button set as when we started. That means our insert/removal of
// persistent id's is working correctly
is(currentsetAtStart, toolbar.currentSet, "toolbar currentset unchanged");
openWindowAndWaitForInit(function(w1) {
checkSocialUI(w1);
// Sometimes the new window adds other buttons to currentSet that are
// outside the scope of what we're checking. So we verify that all
// buttons from startup are in currentSet for a new window, and that the
// provider buttons are properly removed. (e.g on try, window-controls
// was not present in currentsetAtStart, but present on the second
// window)
let tb1 = w1.document.getElementById("nav-bar");
info("tb0 "+toolbar.currentSet);
info("tb1 "+tb1.currentSet);
let startupSet = Set(toolbar.currentSet.split(','));
let newSet = Set(tb1.currentSet.split(','));
let intersect = Set([x for (x of startupSet) if (newSet.has(x))]);
info("intersect "+intersect);
let difference = Set([x for (x of newSet) if (!startupSet.has(x))]);
info("difference "+difference);
is(startupSet.size, intersect.size, "new window toolbar same as old");
// verify that our provider buttons are not in difference
let id = SocialStatus._toolbarHelper.idFromOrgin(manifest2.origin);
ok(!difference.has(id), "status button not persisted at end");
w1.close();
finish();
});
});
});
}
var tests = {
testNoButtonOnInstall: function(next) {
// we expect the addon install dialog to appear, we need to accept the
// install from the dialog.
info("Waiting for install dialog");
let panel = document.getElementById("servicesInstall-notification");
PopupNotifications.panel.addEventListener("popupshown", function onpopupshown() {
PopupNotifications.panel.removeEventListener("popupshown", onpopupshown);
info("servicesInstall-notification panel opened");
panel.button.click();
})
let id = "social-status-button-" + manifest3.origin;
let toolbar = document.getElementById("nav-bar");
let currentset = toolbar.getAttribute("currentset").split(',');
ok(currentset.indexOf(id) < 0, "button is not part of currentset at start");
let activationURL = manifest3.origin + "/browser/browser/base/content/test/social/social_activate.html"
addTab(activationURL, function(tab) {
let doc = tab.linkedBrowser.contentDocument;
Social.installProvider(doc, manifest3, function(addonManifest) {
// enable the provider so we know the button would have appeared
SocialService.addBuiltinProvider(manifest3.origin, function(provider) {
ok(provider, "provider is installed");
currentset = toolbar.getAttribute("currentset").split(',');
ok(currentset.indexOf(id) < 0, "button was not added to currentset");
Social.uninstallProvider(manifest3.origin, function() {
gBrowser.removeTab(tab);
next();
});
});
});
});
},
testButtonOnInstall: function(next) {
// we expect the addon install dialog to appear, we need to accept the
// install from the dialog.
info("Waiting for install dialog");
let panel = document.getElementById("servicesInstall-notification");
PopupNotifications.panel.addEventListener("popupshown", function onpopupshown() {
PopupNotifications.panel.removeEventListener("popupshown", onpopupshown);
info("servicesInstall-notification panel opened");
panel.button.click();
})
let activationURL = manifest2.origin + "/browser/browser/base/content/test/social/social_activate.html"
addTab(activationURL, function(tab) {
let doc = tab.linkedBrowser.contentDocument;
Social.installProvider(doc, manifest2, function(addonManifest) {
// at this point, we should have a button id in the currentset for our provider
let id = "social-status-button-" + manifest2.origin;
let toolbar = document.getElementById("nav-bar");
waitForCondition(function() {
let currentset = toolbar.getAttribute("currentset").split(',');
return currentset.indexOf(id) >= 0;
},
function() {
// no longer need the tab
gBrowser.removeTab(tab);
next();
}, "status button added to currentset");
});
});
},
testButtonOnEnable: function(next) {
// enable the provider now
SocialService.addBuiltinProvider(manifest2.origin, function(provider) {
ok(provider, "provider is installed");
let id = "social-status-button-" + manifest2.origin;
waitForCondition(function() { return document.getElementById(id) },
next, "button exists after enabling social");
});
},
testStatusPanel: function(next) {
let icon = {
name: "testIcon",
iconURL: "chrome://browser/skin/Info.png",
counter: 1
};
// click on panel to open and wait for visibility
let provider = Social._getProviderFromOrigin(manifest2.origin);
let id = "social-status-button-" + provider.origin;
let btn = document.getElementById(id)
ok(btn, "got a status button");
let port = provider.getWorkerPort();
port.onmessage = function (e) {
let topic = e.data.topic;
switch (topic) {
case "test-init-done":
ok(true, "test-init-done received");
ok(provider.profile.userName, "profile was set by test worker");
btn.click();
break;
case "got-social-panel-visibility":
ok(true, "got the panel message " + e.data.result);
if (e.data.result == "shown") {
let panel = document.getElementById("social-notification-panel");
panel.hidePopup();
} else {
port.postMessage({topic: "test-ambient-notification", data: icon});
port.close();
waitForCondition(function() { return btn.getAttribute("badge"); },
function() {
is(btn.style.listStyleImage, "url(\"" + icon.iconURL + "\")", "notification icon updated");
next();
}, "button updated by notification");
}
break;
}
};
port.postMessage({topic: "test-init"});
},
testButtonOnDisable: function(next) {
// enable the provider now
let provider = Social._getProviderFromOrigin(manifest2.origin);
ok(provider, "provider is installed");
SocialService.removeProvider(manifest2.origin, function() {
let id = "social-status-button-" + manifest2.origin;
waitForCondition(function() { return !document.getElementById(id) },
next, "button does not exist after disabling the provider");
});
},
testButtonOnUninstall: function(next) {
Social.uninstallProvider(manifest2.origin, function() {
// test that the button is no longer persisted
let id = "social-status-button-" + manifest2.origin;
let toolbar = document.getElementById("nav-bar");
let currentset = toolbar.getAttribute("currentset").split(',');
is(currentset.indexOf(id), -1, "button no longer in currentset");
next();
});
}
}

View File

@ -177,7 +177,7 @@ function runSocialTests(tests, cbPreTest, cbPostTest, cbFinish) {
cbPostTest(runNextTest);
}
cbPreTest(function() {
is(providersAtStart, Social.providers.length, "pre-test: no new providers left enabled");
info("pre-test: starting with " + Social.providers.length + " providers");
info("sub-test " + name + " starting");
try {
func.call(tests, cleanupAndRunNextTest);

View File

@ -14,6 +14,7 @@ var data = {
// at least one of these must be defined
"sidebarURL": "/browser/browser/base/content/test/social/social_sidebar.html",
"workerURL": "/browser/browser/base/content/test/social/social_worker.js",
"statusURL": "/browser/browser/base/content/test/social/social_panel.html",
// should be available for display purposes
"description": "A short paragraph about this provider",

View File

@ -119,13 +119,7 @@ onconnect = function(e) {
});
break;
case "test-ambient-notification":
let icon = {
name: "testIcon",
iconURL: "chrome://browser/skin/Info.png",
contentPanel: "https://example.com/browser/browser/base/content/test/social/social_panel.html",
counter: 1
};
apiPort.postMessage({topic: "social.ambient-notification", data: icon});
apiPort.postMessage({topic: "social.ambient-notification", data: event.data.data});
break;
case "test-isVisible":
sidebarPort.postMessage({topic: "test-isVisible"});

View File

@ -54,6 +54,7 @@ browser.jar:
content/browser/aboutRobots-icon.png (content/aboutRobots-icon.png)
content/browser/aboutRobots-widget-left.png (content/aboutRobots-widget-left.png)
content/browser/aboutSocialError.xhtml (content/aboutSocialError.xhtml)
content/browser/aboutTabCrashed.xhtml (content/aboutTabCrashed.xhtml)
* content/browser/browser.css (content/browser.css)
* content/browser/browser.js (content/browser.js)
* content/browser/browser.xul (content/browser.xul)

View File

@ -44,6 +44,10 @@ static RedirEntry kRedirMap[] = {
{ "socialerror", "chrome://browser/content/aboutSocialError.xhtml",
nsIAboutModule::ALLOW_SCRIPT |
nsIAboutModule::HIDE_FROM_ABOUTABOUT },
{ "tabcrashed", "chrome://browser/content/aboutTabCrashed.xhtml",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
nsIAboutModule::ALLOW_SCRIPT |
nsIAboutModule::HIDE_FROM_ABOUTABOUT },
{ "feeds", "chrome://browser/content/feeds/subscribe.xhtml",
nsIAboutModule::URI_SAFE_FOR_UNTRUSTED_CONTENT |
nsIAboutModule::ALLOW_SCRIPT |

View File

@ -90,6 +90,7 @@ static const mozilla::Module::ContractIDEntry kBrowserContracts[] = {
#endif
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "certerror", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "socialerror", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "tabcrashed", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "feeds", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "privatebrowsing", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },
{ NS_ABOUT_MODULE_CONTRACTID_PREFIX "rights", &kNS_BROWSER_ABOUT_REDIRECTOR_CID },

View File

@ -1788,15 +1788,11 @@ ContentPermissionPrompt.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentPermissionPrompt]),
_getBrowserForRequest: function (aRequest) {
var browser;
try {
// "element" is only defined in e10s mode, otherwise it throws.
browser = aRequest.element;
} catch (e) {}
// "element" is only defined in e10s mode.
let browser = aRequest.element;
if (!browser) {
var requestingWindow = aRequest.window.top;
// find the requesting browser or iframe
browser = requestingWindow.QueryInterface(Ci.nsIInterfaceRequestor)
// Find the requesting browser.
browser = aRequest.window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell)
.chromeEventHandler;

View File

@ -20,6 +20,7 @@ let { Cc, Ci, Cu } = require("chrome");
let promise = require("sdk/core/promise");
let Telemetry = require("devtools/shared/telemetry");
let TargetFactory = require("devtools/framework/target").TargetFactory;
const escodegen = require("escodegen/escodegen");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm");
@ -31,6 +32,8 @@ Cu.import("resource://gre/modules/jsdebugger.jsm");
Cu.import("resource:///modules/devtools/gDevTools.jsm");
Cu.import("resource://gre/modules/osfile.jsm");
Cu.import("resource:///modules/devtools/ViewHelpers.jsm");
Cu.import("resource://gre/modules/reflect.jsm");
Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm");
XPCOMUtils.defineLazyModuleGetter(this, "VariablesView",
"resource:///modules/devtools/VariablesView.jsm");
@ -521,6 +524,20 @@ var Scratchpad = {
return deferred.promise;
},
/**
* Pretty print the source text inside the scratchpad.
*/
prettyPrint: function SP_prettyPrint() {
const uglyText = this.getText();
try {
const ast = Reflect.parse(uglyText);
const prettyText = escodegen.generate(ast);
this.setText(prettyText);
} catch (e) {
this.writeAsErrorComment(DevToolsUtils.safeErrorString(e));
}
},
/**
* Writes out a primitive value as a comment. This handles values which are
* to be printed directly (number, string) as well as grips to values

View File

@ -46,6 +46,7 @@
<command id="sp-cmd-run" oncommand="Scratchpad.run();"/>
<command id="sp-cmd-inspect" oncommand="Scratchpad.inspect();"/>
<command id="sp-cmd-display" oncommand="Scratchpad.display();"/>
<command id="sp-cmd-pprint" oncommand="Scratchpad.prettyPrint();"/>
<command id="sp-cmd-contentContext" oncommand="Scratchpad.setContentContext();"/>
<command id="sp-cmd-browserContext" oncommand="Scratchpad.setBrowserContext();" disabled="true"/>
<command id="sp-cmd-reloadAndRun" oncommand="Scratchpad.reloadAndRun();"/>
@ -94,6 +95,10 @@
key="&display.key;"
command="sp-cmd-display"
modifiers="accel"/>
<key id="sp-key-pprint"
key="&pprint.key;"
command="sp-cmd-pprint"
modifiers="accel"/>
<key id="sp-key-reloadAndRun"
key="&reloadAndRun.key;"
command="sp-cmd-reloadAndRun"
@ -272,6 +277,11 @@
class="devtools-toolbarbutton"
label="&display.label;"
command="sp-cmd-display"/>
<toolbarspacer/>
<toolbarbutton id="sp-toolbar-pprint"
class="devtools-toolbarbutton"
label="&pprint.label;"
command="sp-cmd-pprint"/>
</toolbar>

View File

@ -39,6 +39,7 @@ MOCHITEST_BROWSER_FILES = \
browser_scratchpad_bug807924_cannot_convert_to_string.js \
browser_scratchpad_long_string.js \
browser_scratchpad_open_error_console.js \
browser_scratchpad_pprint.js \
head.js \
# Disable test due to bug 807234 becoming basically permanent

View File

@ -0,0 +1,26 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test()
{
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
openScratchpad(runTests);
}, true);
content.location = "data:text/html;charset=utf8,test Scratchpad pretty print.";
}
function runTests(sw)
{
const sp = sw.Scratchpad;
sp.setText("function main() { console.log(5); }");
sp.prettyPrint();
const prettyText = sp.getText();
ok(prettyText.contains("\n"));
finish();
}

View File

@ -11,7 +11,7 @@ const promise = require("sdk/core/promise");
let {CssLogic} = require("devtools/styleinspector/css-logic");
let {InplaceEditor, editableField, editableItem} = require("devtools/shared/inplace-editor");
let {ELEMENT_STYLE} = require("devtools/server/actors/styles");
let {ELEMENT_STYLE, PSEUDO_ELEMENTS} = require("devtools/server/actors/styles");
Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
@ -203,7 +203,9 @@ ElementStyle.prototype = {
}
// Mark overridden computed styles.
this.markOverridden();
this.markOverriddenAll();
this._sortRulesForPseudoElement();
// We're done with the previous list of rules.
delete this._refreshRules;
@ -215,6 +217,16 @@ ElementStyle.prototype = {
return this.populated;
},
/**
* Put pseudo elements in front of others.
*/
_sortRulesForPseudoElement: function ElementStyle_sortRulesForPseudoElement()
{
this.rules = this.rules.sort((a, b) => {
return (a.pseudoElement || "z") > (b.pseudoElement || "z");
});
},
/**
* Add a rule if it's one we care about. Filters out duplicates and
* inherited styles with no inherited properties.
@ -266,22 +278,38 @@ ElementStyle.prototype = {
},
/**
* Mark the properties listed in this.rules with an overridden flag
* if an earlier property overrides it.
* Calls markOverridden with all supported pseudo elements
*/
markOverridden: function ElementStyle_markOverridden()
markOverriddenAll: function ElementStyle_markOverriddenAll()
{
this.markOverridden();
for (let pseudo of PSEUDO_ELEMENTS) {
this.markOverridden(pseudo);
}
},
/**
* Mark the properties listed in this.rules for a given pseudo element
* with an overridden flag if an earlier property overrides it.
* @param {string} pseudo
* Which pseudo element to flag as overridden.
* Empty string or undefined will default to no pseudo element.
*/
markOverridden: function ElementStyle_markOverridden(pseudo="")
{
// Gather all the text properties applied by these rules, ordered
// from more- to less-specific.
let textProps = [];
for each (let rule in this.rules) {
textProps = textProps.concat(rule.textProps.slice(0).reverse());
for (let rule of this.rules) {
if (rule.pseudoElement == pseudo) {
textProps = textProps.concat(rule.textProps.slice(0).reverse());
}
}
// Gather all the computed properties applied by those text
// properties.
let computedProps = [];
for each (let textProp in textProps) {
for (let textProp of textProps) {
computedProps = computedProps.concat(textProp.computed);
}
@ -302,7 +330,7 @@ ElementStyle.prototype = {
// _overriddenDirty will be set on each prop, indicating whether its
// dirty status changed during this pass.
let taken = {};
for each (let computedProp in computedProps) {
for (let computedProp of computedProps) {
let earlier = taken[computedProp.name];
let overridden;
if (earlier
@ -328,7 +356,7 @@ ElementStyle.prototype = {
// computed properties are marked overridden. Update the text
// property's associated editor, if any. This will clear the
// _overriddenDirty state on all computed properties.
for each (let textProp in textProps) {
for (let textProp of textProps) {
// _updatePropertyOverridden will return true if the
// overridden state has changed for the text property.
if (this._updatePropertyOverridden(textProp)) {
@ -384,6 +412,7 @@ function Rule(aElementStyle, aOptions)
this.domRule = aOptions.rule || null;
this.style = aOptions.rule;
this.matchedSelectors = aOptions.matchedSelectors || [];
this.pseudoElement = aOptions.pseudoElement || "";
this.inherited = aOptions.inherited || null;
this._modificationDepth = 0;
@ -558,7 +587,7 @@ Rule.prototype = {
textProp.priority = cssProp.priority;
}
this.elementStyle.markOverridden();
this.elementStyle.markOverriddenAll();
if (promise === this._applyingModifications) {
this._applyingModifications = null;
@ -642,7 +671,6 @@ Rule.prototype = {
let props = [];
for (let line of lines) {
dump("line: " + line + "\n");
let [, name, value, priority] = CSS_PROP_RE.exec(line) || []
if (!name || !value) {
continue;
@ -1078,6 +1106,7 @@ CssRuleView.prototype = {
}
this._createEditors();
// Notify anyone that cares that we refreshed.
var evt = this.doc.createEvent("Events");
evt.initEvent("CssRuleViewRefreshed", true, false);
@ -1132,6 +1161,59 @@ CssRuleView.prototype = {
this.element.dispatchEvent(evt);
},
/**
* Text for header that shows above rules for this element
*/
get selectedElementLabel ()
{
if (this._selectedElementLabel) {
return this._selectedElementLabel;
}
this._selectedElementLabel = CssLogic.l10n("rule.selectedElement");
return this._selectedElementLabel;
},
/**
* Text for header that shows above rules for pseudo elements
*/
get pseudoElementLabel ()
{
if (this._pseudoElementLabel) {
return this._pseudoElementLabel;
}
this._pseudoElementLabel = CssLogic.l10n("rule.pseudoElement");
return this._pseudoElementLabel;
},
togglePseudoElementVisibility: function(value)
{
this._showPseudoElements = !!value;
let isOpen = this.showPseudoElements;
Services.prefs.setBoolPref("devtools.inspector.show_pseudo_elements",
isOpen);
this.element.classList.toggle("show-pseudo-elements", isOpen);
if (this.pseudoElementTwisty) {
if (isOpen) {
this.pseudoElementTwisty.setAttribute("open", "true");
}
else {
this.pseudoElementTwisty.removeAttribute("open");
}
}
},
get showPseudoElements ()
{
if (this._showPseudoElements === undefined) {
this._showPseudoElements =
Services.prefs.getBoolPref("devtools.inspector.show_pseudo_elements");
}
return this._showPseudoElements;
},
/**
* Creates editor UI for each of the rules in _elementStyle.
*/
@ -1140,18 +1222,48 @@ CssRuleView.prototype = {
// Run through the current list of rules, attaching
// their editors in order. Create editors if needed.
let lastInheritedSource = "";
let seenPseudoElement = false;
let seenNormalElement = false;
for (let rule of this._elementStyle.rules) {
if (rule.domRule.system) {
continue;
}
// Only print header for this element if there are pseudo elements
if (seenPseudoElement && !seenNormalElement && !rule.pseudoElement) {
seenNormalElement = true;
let div = this.doc.createElementNS(HTML_NS, "div");
div.className = "theme-gutter ruleview-header";
div.textContent = this.selectedElementLabel;
this.element.appendChild(div);
}
let inheritedSource = rule.inheritedSource;
if (inheritedSource != lastInheritedSource) {
let h2 = this.doc.createElementNS(HTML_NS, "div");
h2.className = "ruleview-rule-inheritance theme-gutter";
h2.textContent = inheritedSource;
let div = this.doc.createElementNS(HTML_NS, "div");
div.className = "theme-gutter ruleview-header";
div.textContent = inheritedSource;
lastInheritedSource = inheritedSource;
this.element.appendChild(h2);
this.element.appendChild(div);
}
if (!seenPseudoElement && rule.pseudoElement) {
seenPseudoElement = true;
let div = this.doc.createElementNS(HTML_NS, "div");
div.className = "theme-gutter ruleview-header";
div.textContent = this.pseudoElementLabel;
let twisty = this.pseudoElementTwisty =
this.doc.createElementNS(HTML_NS, "span");
twisty.className = "ruleview-expander theme-twisty";
twisty.addEventListener("click", () => {
this.togglePseudoElementVisibility(!this.showPseudoElements);
}, false);
div.insertBefore(twisty, div.firstChild);
this.element.appendChild(div);
}
if (!rule.editor) {
@ -1160,6 +1272,8 @@ CssRuleView.prototype = {
this.element.appendChild(rule.editor.element);
}
this.togglePseudoElementVisibility(this.showPseudoElements);
},
/**
@ -1227,6 +1341,9 @@ RuleEditor.prototype = {
this.element = this.doc.createElementNS(HTML_NS, "div");
this.element.className = "ruleview-rule theme-separator";
this.element._ruleEditor = this;
if (this.rule.pseudoElement) {
this.element.classList.add("ruleview-rule-pseudo-element");
}
// Give a relative position for the inplace editor's measurement
// span to be placed absolutely against.
@ -1358,12 +1475,15 @@ RuleEditor.prototype = {
* Property value.
* @param {string} aPriority
* Property priority.
* @return {TextProperty}
* The new property
*/
addProperty: function RuleEditor_addProperty(aName, aValue, aPriority)
{
let prop = this.rule.createProperty(aName, aValue, aPriority);
let editor = new TextPropertyEditor(this, prop);
this.propertyList.appendChild(editor.element);
return prop;
},
/**

View File

@ -36,3 +36,21 @@
.ruleview-warning[hidden] {
display: none;
}
.ruleview-rule-pseudo-element {
display: none;
}
.show-pseudo-elements .ruleview-rule-pseudo-element {
display: block;
}
.ruleview .ruleview-expander {
vertical-align: middle;
}
.ruleview-header {
vertical-align:middle;
height: 1.5em;
line-height: 1.5em;
}

View File

@ -43,6 +43,7 @@ MOCHITEST_BROWSER_FILES = \
browser_bug894376_css_value_completion_new_property_value_pair.js \
browser_bug894376_css_value_completion_existing_property_value_pair.js \
browser_ruleview_bug_902966_revert_value_on_ESC.js \
browser_ruleview_pseudoelement.js \
head.js \
$(NULL)
@ -60,6 +61,7 @@ MOCHITEST_BROWSER_FILES += \
browser_styleinspector_bug_677930_urls_clickable \
browser_styleinspector_bug_677930_urls_clickable/browser_styleinspector_bug_677930_urls_clickable.css \
test-image.png \
browser_ruleview_pseudoelement.html \
$(NULL)
include $(topsrcdir)/config/rules.mk

View File

@ -0,0 +1,115 @@
<!-- Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ -->
<html>
<head>
<style>
body {
color: #333;
}
.box {
float:left;
width: 128px;
height: 128px;
background: #ddd;
padding: 32px;
margin: 32px;
position:relative;
}
* {
cursor: default;
}
nothing {
cursor: pointer;
}
p::-moz-selection {
color: white;
background: black;
}
p::selection {
color: white;
background: black;
}
p:first-line {
background: blue;
}
p:first-letter {
color: red;
font-size: 130%;
}
.box:before {
background: green;
content: " ";
position: absolute;
height:32px;
width:32px;
}
.box:after {
background: red;
content: " ";
position: absolute;
border-radius: 50%;
height:32px;
width:32px;
top: 50%;
left: 50%;
margin-top: -16px;
margin-left: -16px;
}
.topleft:before {
top:0;
left:0;
}
.topright:before {
top:0;
right:0;
}
.bottomright:before {
bottom:10px;
right:10px;
color: red;
}
.bottomright:before {
bottom:0;
right:0;
}
.bottomleft:before {
bottom:0;
left:0;
}
</style>
</head>
<body>
<h1>ruleview pseudoelement($("test"));</h1>
<div id="topleft" class="box topleft">
<p>Top Left<br />Position</p>
</div>
<div id="topright" class="box topright">
<p>Top Right<br />Position</p>
</div>
<div id="bottomright" class="box bottomright">
<p>Bottom Right<br />Position</p>
</div>
<div id="bottomleft" class="box bottomleft">
<p>Bottom Left<br />Position</p>
</div>
</body>
</html>

View File

@ -0,0 +1,317 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
let doc;
let inspector;
let view;
const TEST_URI = "http://example.com/browser/browser/" +
"devtools/styleinspector/test/" +
"browser_ruleview_pseudoelement.html";
function testPseudoElements(aInspector, aRuleView)
{
inspector = aInspector;
view = aRuleView;
testTopLeft();
}
function testTopLeft()
{
testNode(doc.querySelector("#topleft"), (element, elementStyle) => {
let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; });
let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; });
let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; });
let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; });
let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; });
let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; });
is(elementRules.length, 4, "TopLeft has the correct number of non psuedo element rules");
is(afterRules.length, 1, "TopLeft has the correct number of :after rules");
is(beforeRules.length, 2, "TopLeft has the correct number of :before rules");
is(firstLineRules.length, 0, "TopLeft has the correct number of :first-line rules");
is(firstLetterRules.length, 0, "TopLeft has the correct number of :first-letter rules");
is(selectionRules.length, 0, "TopLeft has the correct number of :selection rules");
let gutters = view.element.querySelectorAll(".theme-gutter");
is (gutters.length, 3, "There are three gutter headings");
is (gutters[0].textContent, "Pseudo-elements", "Gutter heading is correct");
is (gutters[1].textContent, "This Element", "Gutter heading is correct");
is (gutters[2].textContent, "Inherited from body", "Gutter heading is correct");
// Make sure that clicking on the twisty hides pseudo elements
let expander = gutters[0].querySelector(".ruleview-expander");
ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are expanded");
expander.click();
ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are collapsed by twisty");
expander.click();
ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are expanded again");
expander.click();
let defaultView = element.ownerDocument.defaultView;
let elementRule = elementRules[0];
let elementRuleView = [].filter.call(view.element.children, (e) => {
return e._ruleEditor && e._ruleEditor.rule === elementRule;
})[0]._ruleEditor;
let elementAfterRule = afterRules[0];
let elementAfterRuleView = [].filter.call(view.element.children, (e) => {
return e._ruleEditor && e._ruleEditor.rule === elementAfterRule;
})[0]._ruleEditor;
is
(
convertTextPropsToString(elementAfterRule.textProps),
"background: none repeat scroll 0% 0% red; content: \" \"; position: absolute; " +
"border-radius: 50%; height: 32px; width: 32px; top: 50%; left: 50%; margin-top: -16px; margin-left: -16px",
"TopLeft after properties are correct"
);
let elementBeforeRule = beforeRules[0];
let elementBeforeRuleView = [].filter.call(view.element.children, (e) => {
return e._ruleEditor && e._ruleEditor.rule === elementBeforeRule;
})[0]._ruleEditor;
is
(
convertTextPropsToString(elementBeforeRule.textProps),
"top: 0px; left: 0px",
"TopLeft before properties are correct"
);
let firstProp = elementAfterRuleView.addProperty("background-color", "rgb(0, 255, 0)", "");
let secondProp = elementAfterRuleView.addProperty("padding", "100px", "");
is (firstProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 2],
"First added property is on back of array");
is (secondProp, elementAfterRule.textProps[elementAfterRule.textProps.length - 1],
"Second added property is on back of array");
promiseDone(elementAfterRule._applyingModifications.then(() => {
is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"),
"rgb(0, 255, 0)", "Added property should have been used.");
is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"),
"100px", "Added property should have been used.");
is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"),
"32px", "Added property should not apply to element");
secondProp.setEnabled(false);
return elementAfterRule._applyingModifications;
}).then(() => {
is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "0px",
"Disabled property should have been used.");
is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px",
"Added property should not apply to element");
secondProp.setEnabled(true);
return elementAfterRule._applyingModifications;
}).then(() => {
is(defaultView.getComputedStyle(element, ":after").getPropertyValue("padding-top"), "100px",
"Enabled property should have been used.");
is(defaultView.getComputedStyle(element).getPropertyValue("padding-top"), "32px",
"Added property should not apply to element");
let firstProp = elementRuleView.addProperty("background-color", "rgb(0, 0, 255)", "");
return elementRule._applyingModifications;
}).then(() => {
is(defaultView.getComputedStyle(element).getPropertyValue("background-color"), "rgb(0, 0, 255)",
"Added property should have been used.");
is(defaultView.getComputedStyle(element, ":after").getPropertyValue("background-color"), "rgb(0, 255, 0)",
"Added prop does not apply to pseudo");
testTopRight();
}));
});
}
function testTopRight()
{
testNode(doc.querySelector("#topright"), (element, elementStyle) => {
let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; });
let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; });
let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; });
let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; });
let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; });
let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; });
is(elementRules.length, 4, "TopRight has the correct number of non psuedo element rules");
is(afterRules.length, 1, "TopRight has the correct number of :after rules");
is(beforeRules.length, 2, "TopRight has the correct number of :before rules");
is(firstLineRules.length, 0, "TopRight has the correct number of :first-line rules");
is(firstLetterRules.length, 0, "TopRight has the correct number of :first-letter rules");
is(selectionRules.length, 0, "TopRight has the correct number of :selection rules");
let gutters = view.element.querySelectorAll(".theme-gutter");
is (gutters.length, 3, "There are three gutter headings");
is (gutters[0].textContent, "Pseudo-elements", "Gutter heading is correct");
is (gutters[1].textContent, "This Element", "Gutter heading is correct");
is (gutters[2].textContent, "Inherited from body", "Gutter heading is correct");
let expander = gutters[0].querySelector(".ruleview-expander");
ok (!view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements remain collapsed after switching element");
expander.scrollIntoView();
expander.click();
ok (view.element.classList.contains("show-pseudo-elements"), "Pseudo Elements are shown again after clicking twisty");
testBottomRight();
});
}
function testBottomRight()
{
testNode(doc.querySelector("#bottomright"), (element, elementStyle) => {
let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; });
let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; });
let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; });
let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; });
let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; });
let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; });
is(elementRules.length, 4, "BottomRight has the correct number of non psuedo element rules");
is(afterRules.length, 1, "BottomRight has the correct number of :after rules");
is(beforeRules.length, 3, "BottomRight has the correct number of :before rules");
is(firstLineRules.length, 0, "BottomRight has the correct number of :first-line rules");
is(firstLetterRules.length, 0, "BottomRight has the correct number of :first-letter rules");
is(selectionRules.length, 0, "BottomRight has the correct number of :selection rules");
testBottomLeft();
});
}
function testBottomLeft()
{
testNode(doc.querySelector("#bottomleft"), (element, elementStyle) => {
let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; });
let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; });
let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; });
let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; });
let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; });
let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; });
is(elementRules.length, 4, "BottomLeft has the correct number of non psuedo element rules");
is(afterRules.length, 1, "BottomLeft has the correct number of :after rules");
is(beforeRules.length, 2, "BottomLeft has the correct number of :before rules");
is(firstLineRules.length, 0, "BottomLeft has the correct number of :first-line rules");
is(firstLetterRules.length, 0, "BottomLeft has the correct number of :first-letter rules");
is(selectionRules.length, 0, "BottomLeft has the correct number of :selection rules");
testParagraph();
});
}
function testParagraph()
{
testNode(doc.querySelector("#bottomleft p"), (element, elementStyle) => {
let elementRules = elementStyle.rules.filter((rule) => { return !rule.pseudoElement; });
let afterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":after"; });
let beforeRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":before"; });
let firstLineRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-line"; });
let firstLetterRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":first-letter"; });
let selectionRules = elementStyle.rules.filter((rule) => { return rule.pseudoElement === ":-moz-selection"; });
is(elementRules.length, 3, "Paragraph has the correct number of non psuedo element rules");
is(afterRules.length, 0, "Paragraph has the correct number of :after rules");
is(beforeRules.length, 0, "Paragraph has the correct number of :before rules");
is(firstLineRules.length, 1, "Paragraph has the correct number of :first-line rules");
is(firstLetterRules.length, 1, "Paragraph has the correct number of :first-letter rules");
is(selectionRules.length, 1, "Paragraph has the correct number of :selection rules");
let gutters = view.element.querySelectorAll(".theme-gutter");
is (gutters.length, 3, "There are three gutter headings");
is (gutters[0].textContent, "Pseudo-elements", "Gutter heading is correct");
is (gutters[1].textContent, "This Element", "Gutter heading is correct");
is (gutters[2].textContent, "Inherited from body", "Gutter heading is correct");
let elementFirstLineRule = firstLineRules[0];
let elementFirstLineRuleView = [].filter.call(view.element.children, (e) => {
return e._ruleEditor && e._ruleEditor.rule === elementFirstLineRule;
})[0]._ruleEditor;
is
(
convertTextPropsToString(elementFirstLineRule.textProps),
"background: none repeat scroll 0% 0% blue",
"Paragraph first-line properties are correct"
);
let elementFirstLetterRule = firstLetterRules[0];
let elementFirstLetterRuleView = [].filter.call(view.element.children, (e) => {
return e._ruleEditor && e._ruleEditor.rule === elementFirstLetterRule;
})[0]._ruleEditor;
is
(
convertTextPropsToString(elementFirstLetterRule.textProps),
"color: red; font-size: 130%",
"Paragraph first-letter properties are correct"
);
let elementSelectionRule = selectionRules[0];
let elementSelectionRuleView = [].filter.call(view.element.children, (e) => {
return e._ruleEditor && e._ruleEditor.rule === elementSelectionRule;
})[0]._ruleEditor;
is
(
convertTextPropsToString(elementSelectionRule.textProps),
"color: white; background: none repeat scroll 0% 0% black",
"Paragraph first-letter properties are correct"
);
testBody();
});
}
function testBody() {
testNode(doc.querySelector("body"), (element, elementStyle) => {
let gutters = view.element.querySelectorAll(".theme-gutter");
is (gutters.length, 0, "There are no gutter headings");
finishTest();
});
}
function convertTextPropsToString(textProps) {
return textProps.map((t) => {
return t.name + ": " + t.value;
}).join("; ");
}
function testNode(node, cb)
{
inspector.once("inspector-updated", () => {
cb(node, view._elementStyle)
});
inspector.selection.setNode(node);
}
function finishTest()
{
doc = null;
gBrowser.removeCurrentTab();
finish();
}
function test()
{
waitForExplicitFinish();
gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function(evt) {
gBrowser.selectedBrowser.removeEventListener(evt.type, arguments.callee, true);
doc = content.document;
waitForFocus(() => openRuleView(testPseudoElements), content);
}, true);
content.location = TEST_URI;
}

View File

@ -693,6 +693,10 @@ just addresses the organization to follow, e.g. "This site is run by " -->
<!ENTITY pluginActivateAlways.label "Allow and Remember">
<!ENTITY pluginBlockNow.label "Block Plugin">
<!ENTITY tabCrashed.header "Tab crashed">
<!ENTITY tabCrashed.message "Well, this is embarrassing. We tried to display this Web page, but it's not responding.">
<!ENTITY tabCrashed.tryAgain "Try Again">
<!-- LOCALIZATION NOTE: the following strings are unused in Australis, they're
kept here to avoid warnings from l10n tools like compare-locales on
l10n-central. They will be definitely removed when Australis is ready

View File

@ -65,6 +65,9 @@
<!ENTITY display.accesskey "D">
<!ENTITY display.key "l">
<!ENTITY pprint.label "Pretty Print">
<!ENTITY pprint.key "p">
<!-- LOCALIZATION NOTE (environmentMenu.label, accesskey): This menu item was
- renamed from "Context" to avoid confusion with the right-click context
- menu in the text area. It refers to the JavaScript Environment (or context)

View File

@ -35,6 +35,14 @@ rule.sourceElement=element
# e.g "Inherited from body#bodyID"
rule.inheritedFrom=Inherited from %S
# LOCALIZATION NOTE (rule.pseudoElement): Shown for CSS rules
# pseudo element header
rule.pseudoElement=Pseudo-elements
# LOCALIZATION NOTE (rule.pseudoElement): Shown for CSS rules
# pseudo element header
rule.selectedElement=This Element
# LOCALIZATION NOTE (helpLinkTitle): For each style property
# the user can hover it and get a help link button which allows one to
# quickly jump to the documentation from the Mozilla Developer Network site.

View File

@ -42,32 +42,28 @@ function isSelectable(aElement) {
// placeholder logic
return aElement.nodeName == 'richgriditem';
}
function withinCone(aLen, aHeight) {
// check pt falls within 45deg either side of the cross axis
return aLen > aHeight;
}
function getScrollAxisFromElement(aElement) {
let elem = aElement,
win = elem.ownerDocument.defaultView;
let scrollX, scrollY;
for (; elem && 1==elem.nodeType; elem = elem.parentNode) {
let cs = win.getComputedStyle(elem);
scrollX = (cs.overflowX=='scroll' || cs.overflowX=='auto');
scrollY = (cs.overflowX=='scroll' || cs.overflowX=='auto');
if (scrollX || scrollY) {
break;
}
}
return scrollX ? 'x' : 'y';
}
// keeping it simple - just return apparent scroll axis for the document
let win = aElement.ownerDocument.defaultView;
let scrollX = win.scrollMaxX,
scrollY = win.scrollMaxY;
// determine scroll axis from scrollable content when possible
if (scrollX || scrollY)
return scrollX >= scrollY ? 'x' : 'y';
// fall back to guessing at scroll axis from document aspect ratio
let docElem = aElement.ownerDocument.documentElement;
return docElem.clientWidth >= docElem.clientHeight ?
'x' : 'y';
}
function pointFromTouchEvent(aEvent) {
let touch = aEvent.touches[0];
return { x: touch.clientX, y: touch.clientY };
}
// This damping function has these important properties:
// f(0) = 0
// f'(0) = 1

View File

@ -169,24 +169,28 @@ this.Social = {
}
// Register an observer for changes to the provider list
SocialService.registerProviderListener(function providerListener(topic, data) {
SocialService.registerProviderListener(function providerListener(topic, origin, providers) {
// An engine change caused by adding/removing a provider should notify.
// any providers we receive are enabled in the AddonsManager
if (topic == "provider-added" || topic == "provider-removed") {
Social._updateProviderCache(data);
if (topic == "provider-installed" || topic == "provider-uninstalled") {
// installed/uninstalled do not send the providers param
Services.obs.notifyObservers(null, "social:" + topic, origin);
return;
}
if (topic == "provider-enabled" || topic == "provider-disabled") {
Social._updateProviderCache(providers);
Social._updateWorkerState(true);
Services.obs.notifyObservers(null, "social:providers-changed", null);
Services.obs.notifyObservers(null, "social:" + topic, origin);
return;
}
if (topic == "provider-update") {
// a provider has self-updated its manifest, we need to update our cache
// and reload the provider.
let provider = data;
SocialService.getOrderedProviderList(function(providers) {
Social._updateProviderCache(providers);
provider.reload();
Services.obs.notifyObservers(null, "social:providers-changed", null);
});
Social._updateProviderCache(providers);
let provider = Social._getProviderFromOrigin(origin);
provider.reload();
Services.obs.notifyObservers(null, "social:providers-changed", null);
}
});
},
@ -259,6 +263,10 @@ this.Social = {
return null;
},
getManifestByOrigin: function(origin) {
return SocialService.getManifestByOrigin(origin);
},
installProvider: function(doc, data, installCallback) {
SocialService.installProvider(doc, data, installCallback);
},

View File

@ -0,0 +1,98 @@
body {
background-color: rgb(241, 244, 248);
margin-top: 2em;
font: message-box;
font-size: 100%;
}
p {
font-size: .8em;
}
#error-box {
background: url('chrome://global/skin/icons/information-24.png') no-repeat left 4px;
-moz-padding-start: 30px;
}
#error-box:-moz-locale-dir(rtl) {
background-position: right 4px;
}
#main-error-msg {
color: #4b4b4b;
font-weight: bold;
}
#button-box {
text-align: center;
width: 75%;
margin: 0 auto;
}
@media all and (min-width: 300px) {
#error-box {
max-width: 50%;
margin: 0 auto;
background-image: url('chrome://global/skin/icons/information-32.png');
min-height: 36px;
-moz-padding-start: 38px;
}
button {
width: auto !important;
min-width: 150px;
}
}
@media all and (min-width: 780px) {
#error-box {
max-width: 30%;
}
}
button {
font: message-box;
font-size: 0.6875em;
-moz-appearance: none;
-moz-user-select: none;
width: 100%;
margin: 2px 0;
padding: 2px 6px;
line-height: 1.2;
background-color: hsla(210,30%,95%,.1);
background-image: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1));
background-clip: padding-box;
border: 1px solid hsla(210,15%,25%,.4);
border-color: hsla(210,15%,25%,.3) hsla(210,15%,25%,.35) hsla(210,15%,25%,.4);
border-radius: 3px;
box-shadow: 0 1px 0 hsla(0,0%,100%,.3) inset,
0 0 0 1px hsla(0,0%,100%,.3) inset,
0 1px 0 hsla(0,0%,100%,.1);
transition-property: background-color, border-color, box-shadow;
transition-duration: 150ms;
transition-timing-function: ease;
}
button:hover {
background-color: hsla(210,30%,95%,.8);
border-color: hsla(210,15%,25%,.45) hsla(210,15%,25%,.5) hsla(210,15%,25%,.55);
box-shadow: 0 1px 0 hsla(0,0%,100%,.3) inset,
0 0 0 1px hsla(0,0%,100%,.3) inset,
0 1px 0 hsla(0,0%,100%,.1),
0 0 3px hsla(210,15%,25%,.1);
transition-property: background-color, border-color, box-shadow;
transition-duration: 150ms;
transition-timing-function: ease;
}
button:hover:active {
background-color: hsla(210,15%,25%,.2);
box-shadow: 0 1px 1px hsla(210,15%,25%,.2) inset,
0 0 2px hsla(210,15%,25%,.4) inset;
transition-property: background-color, border-color, box-shadow;
transition-duration: 10ms;
transition-timing-function: linear;
}

View File

@ -14,7 +14,7 @@
-moz-user-select: none;
}
.ruleview-rule-inheritance {
.ruleview-header {
border-top-width: 1px;
border-bottom-width: 1px;
border-top-style: solid;

View File

@ -18,6 +18,7 @@ browser.jar:
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/aboutSyncTabs.css
#endif
skin/classic/browser/aboutTabCrashed.css
skin/classic/browser/actionicon-tab.png
skin/classic/browser/appmenu.png
* skin/classic/browser/browser.css

View File

@ -0,0 +1,98 @@
body {
background-color: rgb(241, 244, 248);
margin-top: 2em;
font: message-box;
font-size: 100%;
}
p {
font-size: .8em;
}
#error-box {
background: url('chrome://global/skin/icons/information-24.png') no-repeat left 4px;
-moz-padding-start: 30px;
}
#error-box:-moz-locale-dir(rtl) {
background-position: right 4px;
}
#main-error-msg {
color: #4b4b4b;
font-weight: bold;
}
#button-box {
text-align: center;
width: 75%;
margin: 0 auto;
}
@media all and (min-width: 300px) {
#error-box {
max-width: 50%;
margin: 0 auto;
background-image: url('chrome://global/skin/icons/information-32.png');
min-height: 36px;
-moz-padding-start: 38px;
}
button {
width: auto !important;
min-width: 150px;
}
}
@media all and (min-width: 780px) {
#error-box {
max-width: 30%;
}
}
button {
font: message-box;
font-size: 0.6875em;
-moz-appearance: none;
-moz-user-select: none;
width: 100%;
margin: 2px 0;
padding: 2px 6px;
line-height: 1.2;
background-color: hsla(210,30%,95%,.1);
background-image: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1));
background-clip: padding-box;
border: 1px solid hsla(210,15%,25%,.4);
border-color: hsla(210,15%,25%,.3) hsla(210,15%,25%,.35) hsla(210,15%,25%,.4);
border-radius: 3px;
box-shadow: 0 1px 0 hsla(0,0%,100%,.3) inset,
0 0 0 1px hsla(0,0%,100%,.3) inset,
0 1px 0 hsla(0,0%,100%,.1);
transition-property: background-color, border-color, box-shadow;
transition-duration: 150ms;
transition-timing-function: ease;
}
button:hover {
background-color: hsla(210,30%,95%,.8);
border-color: hsla(210,15%,25%,.45) hsla(210,15%,25%,.5) hsla(210,15%,25%,.55);
box-shadow: 0 1px 0 hsla(0,0%,100%,.3) inset,
0 0 0 1px hsla(0,0%,100%,.3) inset,
0 1px 0 hsla(0,0%,100%,.1),
0 0 3px hsla(210,15%,25%,.1);
transition-property: background-color, border-color, box-shadow;
transition-duration: 150ms;
transition-timing-function: ease;
}
button:hover:active {
background-color: hsla(210,15%,25%,.2);
box-shadow: 0 1px 1px hsla(210,15%,25%,.2) inset,
0 0 2px hsla(210,15%,25%,.4) inset;
transition-property: background-color, border-color, box-shadow;
transition-duration: 10ms;
transition-timing-function: linear;
}

View File

@ -14,16 +14,20 @@
-moz-user-select: none;
}
.ruleview-rule-inheritance {
.ruleview-header {
border-top-width: 1px;
border-bottom-width: 1px;
border-top-style: solid;
border-bottom-style: solid;
padding: 1px 4px;
margin-top: 4px;
-moz-user-select: none;
}
.ruleview-rule-pseudo-element {
padding-left:20px;
border-left: solid 10px;
}
.ruleview-rule-source:hover {
text-decoration: underline;
}

View File

@ -17,6 +17,7 @@ browser.jar:
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/aboutSyncTabs.css
#endif
skin/classic/browser/aboutTabCrashed.css
skin/classic/browser/actionicon-tab.png
skin/classic/browser/actionicon-tab@2x.png
* skin/classic/browser/browser.css (browser.css)

View File

@ -0,0 +1,98 @@
body {
background-color: rgb(241, 244, 248);
margin-top: 2em;
font: message-box;
font-size: 100%;
}
p {
font-size: .8em;
}
#error-box {
background: url('chrome://global/skin/icons/information-24.png') no-repeat left 4px;
-moz-padding-start: 30px;
}
#error-box:-moz-locale-dir(rtl) {
background-position: right 4px;
}
#main-error-msg {
color: #4b4b4b;
font-weight: bold;
}
#button-box {
text-align: center;
width: 75%;
margin: 0 auto;
}
@media all and (min-width: 300px) {
#error-box {
max-width: 50%;
margin: 0 auto;
background-image: url('chrome://global/skin/icons/information-32.png');
min-height: 36px;
-moz-padding-start: 38px;
}
button {
width: auto !important;
min-width: 150px;
}
}
@media all and (min-width: 780px) {
#error-box {
max-width: 30%;
}
}
button {
font: message-box;
font-size: 0.6875em;
-moz-appearance: none;
-moz-user-select: none;
width: 100%;
margin: 2px 0;
padding: 2px 6px;
line-height: 1.2;
background-color: hsla(210,30%,95%,.1);
background-image: linear-gradient(hsla(0,0%,100%,.6), hsla(0,0%,100%,.1));
background-clip: padding-box;
border: 1px solid hsla(210,15%,25%,.4);
border-color: hsla(210,15%,25%,.3) hsla(210,15%,25%,.35) hsla(210,15%,25%,.4);
border-radius: 3px;
box-shadow: 0 1px 0 hsla(0,0%,100%,.3) inset,
0 0 0 1px hsla(0,0%,100%,.3) inset,
0 1px 0 hsla(0,0%,100%,.1);
transition-property: background-color, border-color, box-shadow;
transition-duration: 150ms;
transition-timing-function: ease;
}
button:hover {
background-color: hsla(210,30%,95%,.8);
border-color: hsla(210,15%,25%,.45) hsla(210,15%,25%,.5) hsla(210,15%,25%,.55);
box-shadow: 0 1px 0 hsla(0,0%,100%,.3) inset,
0 0 0 1px hsla(0,0%,100%,.3) inset,
0 1px 0 hsla(0,0%,100%,.1),
0 0 3px hsla(210,15%,25%,.1);
transition-property: background-color, border-color, box-shadow;
transition-duration: 150ms;
transition-timing-function: ease;
}
button:hover:active {
background-color: hsla(210,15%,25%,.2);
box-shadow: 0 1px 1px hsla(210,15%,25%,.2) inset,
0 0 2px hsla(210,15%,25%,.4) inset;
transition-property: background-color, border-color, box-shadow;
transition-duration: 10ms;
transition-timing-function: linear;
}

View File

@ -14,7 +14,7 @@
-moz-user-select: none;
}
.ruleview-rule-inheritance {
.ruleview-header {
border-top-width: 1px;
border-bottom-width: 1px;
border-top-style: solid;

View File

@ -20,6 +20,7 @@ browser.jar:
#ifdef MOZ_SERVICES_SYNC
skin/classic/browser/aboutSyncTabs.css
#endif
skin/classic/browser/aboutTabCrashed.css
skin/classic/browser/actionicon-tab.png
* skin/classic/browser/browser.css
* skin/classic/browser/browser-lightweightTheme.css
@ -294,6 +295,7 @@ browser.jar:
#ifdef MOZ_SERVICES_SYNC
skin/classic/aero/browser/aboutSyncTabs.css
#endif
skin/classic/aero/browser/aboutTabCrashed.css
skin/classic/aero/browser/actionicon-tab.png
* skin/classic/aero/browser/browser.css (browser-aero.css)
* skin/classic/aero/browser/browser-lightweightTheme.css

View File

@ -22,9 +22,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=732413
aPrincipal is the system principal.
**/
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
const nsIScriptSecurityManager = Components.interfaces.nsIScriptSecurityManager;
var secMan = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
const nsIScriptSecurityManager = SpecialPowers.Ci.nsIScriptSecurityManager;
var secMan = SpecialPowers.Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(nsIScriptSecurityManager);
var sysPrincipal = secMan.getSystemPrincipal();
isnot(sysPrincipal, undefined, "Should have a principal");
@ -33,8 +32,8 @@ is(secMan.isSystemPrincipal(sysPrincipal), true,
"Should have system principal here");
var ioService = Components.classes["@mozilla.org/network/io-service;1"].
getService(Components.interfaces.nsIIOService);
var ioService = SpecialPowers.Cc["@mozilla.org/network/io-service;1"].
getService(SpecialPowers.Ci.nsIIOService);
var inheritingURI = ioService.newURI("javascript:1+1", null, null);
// First try a normal call to checkLoadURIWithPrincipal

View File

@ -25,6 +25,7 @@
#include "mozilla/TimeStamp.h"
#include "nsContentListDeclarations.h"
#include "nsMathUtils.h"
#include "Units.h"
class imgICache;
class imgIContainer;
@ -1245,28 +1246,6 @@ public:
*/
static void DestroyAnonymousContent(nsCOMPtr<nsIContent>* aContent);
/**
* Keep the JS objects held by aScriptObjectHolder alive.
*
* @param aScriptObjectHolder the object that holds JS objects that we want to
* keep alive
* @param aTracer the tracer for aScriptObject
*/
static void HoldJSObjects(void* aScriptObjectHolder,
nsScriptObjectTracer* aTracer);
/**
* Drop the JS objects held by aScriptObjectHolder.
*
* @param aScriptObjectHolder the object that holds JS objects that we want to
* drop
*/
static void DropJSObjects(void* aScriptObjectHolder);
#ifdef DEBUG
static bool AreJSObjectsHeld(void* aScriptObjectHolder);
#endif
static void DeferredFinalize(nsISupports* aSupports);
static void DeferredFinalize(mozilla::DeferredFinalizeAppendFunction aAppendFunc,
mozilla::DeferredFinalizeFunction aFunc,
@ -1530,8 +1509,7 @@ public:
* will return viewport information that specifies default information.
*/
static nsViewportInfo GetViewportInfo(nsIDocument* aDocument,
uint32_t aDisplayWidth,
uint32_t aDisplayHeight);
const mozilla::ScreenIntSize& aDisplaySize);
// Call EnterMicroTask when you're entering JS execution.
// Usually the best way to do this is to use nsAutoMicroTask.
@ -1612,6 +1590,7 @@ public:
static nsresult GetUTFOrigin(nsIPrincipal* aPrincipal,
nsString& aOrigin);
static nsresult GetUTFOrigin(nsIURI* aURI, nsString& aOrigin);
static void GetUTFNonNullOrigin(nsIURI* aURI, nsString& aOrigin);
/**
* This method creates and dispatches "command" event, which implements

View File

@ -26,6 +26,7 @@
#include "nsPropertyTable.h" // for member
#include "nsTHashtable.h" // for member
#include "mozilla/dom/DocumentBinding.h"
#include "Units.h"
class imgIRequest;
class nsAString;
@ -622,8 +623,7 @@ public:
*/
Element* GetRootElement() const;
virtual nsViewportInfo GetViewportInfo(uint32_t aDisplayWidth,
uint32_t aDisplayHeight) = 0;
virtual nsViewportInfo GetViewportInfo(const mozilla::ScreenIntSize& aDisplaySize) = 0;
/**
* True iff this doc will ignore manual character encoding overrides.

View File

@ -7,16 +7,15 @@
#include <stdint.h>
#include "nscore.h"
#include "Units.h"
/**
* Default values for the nsViewportInfo class.
*/
static const double kViewportMinScale = 0.0;
static const double kViewportMaxScale = 10.0;
static const uint32_t kViewportMinWidth = 200;
static const uint32_t kViewportMaxWidth = 10000;
static const uint32_t kViewportMinHeight = 223;
static const uint32_t kViewportMaxHeight = 10000;
static const mozilla::LayoutDeviceToScreenScale kViewportMinScale(0.0f);
static const mozilla::LayoutDeviceToScreenScale kViewportMaxScale(10.0f);
static const mozilla::CSSIntSize kViewportMinSize(200, 223);
static const mozilla::CSSIntSize kViewportMaxSize(10000, 10000);
static const int32_t kViewportDefaultScreenWidth = 980;
/**
@ -26,43 +25,40 @@ static const int32_t kViewportDefaultScreenWidth = 980;
class MOZ_STACK_CLASS nsViewportInfo
{
public:
nsViewportInfo(uint32_t aDisplayWidth, uint32_t aDisplayHeight) :
nsViewportInfo(const mozilla::ScreenIntSize& aDisplaySize) :
mDefaultZoom(1.0),
mMinZoom(kViewportMinScale),
mMaxZoom(kViewportMaxScale),
mWidth(aDisplayWidth),
mHeight(aDisplayHeight),
mAutoSize(true),
mAllowZoom(true)
{
mSize = mozilla::gfx::RoundedToInt(mozilla::ScreenSize(aDisplaySize) / mDefaultZoom);
mozilla::CSSToLayoutDeviceScale pixelRatio(1.0f);
mMinZoom = pixelRatio * kViewportMinScale;
mMaxZoom = pixelRatio * kViewportMaxScale;
ConstrainViewportValues();
}
nsViewportInfo(double aDefaultZoom,
double aMinZoom,
double aMaxZoom,
uint32_t aWidth,
uint32_t aHeight,
nsViewportInfo(const mozilla::CSSToScreenScale& aDefaultZoom,
const mozilla::CSSToScreenScale& aMinZoom,
const mozilla::CSSToScreenScale& aMaxZoom,
const mozilla::CSSIntSize& aSize,
bool aAutoSize,
bool aAllowZoom) :
mDefaultZoom(aDefaultZoom),
mMinZoom(aMinZoom),
mMaxZoom(aMaxZoom),
mWidth(aWidth),
mHeight(aHeight),
mSize(aSize),
mAutoSize(aAutoSize),
mAllowZoom(aAllowZoom)
{
ConstrainViewportValues();
}
double GetDefaultZoom() { return mDefaultZoom; }
void SetDefaultZoom(const double aDefaultZoom);
double GetMinZoom() { return mMinZoom; }
double GetMaxZoom() { return mMaxZoom; }
mozilla::CSSToScreenScale GetDefaultZoom() { return mDefaultZoom; }
void SetDefaultZoom(const mozilla::CSSToScreenScale& aDefaultZoom);
mozilla::CSSToScreenScale GetMinZoom() { return mMinZoom; }
mozilla::CSSToScreenScale GetMaxZoom() { return mMaxZoom; }
uint32_t GetWidth() { return mWidth; }
uint32_t GetHeight() { return mHeight; }
mozilla::CSSIntSize GetSize() { return mSize; }
bool IsAutoSizeEnabled() { return mAutoSize; }
bool IsZoomAllowed() { return mAllowZoom; }
@ -78,21 +74,16 @@ class MOZ_STACK_CLASS nsViewportInfo
// Default zoom indicates the level at which the display is 'zoomed in'
// initially for the user, upon loading of the page.
double mDefaultZoom;
mozilla::CSSToScreenScale mDefaultZoom;
// The minimum zoom level permitted by the page.
double mMinZoom;
mozilla::CSSToScreenScale mMinZoom;
// The maximum zoom level permitted by the page.
double mMaxZoom;
mozilla::CSSToScreenScale mMaxZoom;
// The width of the viewport, specified by the <meta name="viewport"> tag,
// in CSS pixels.
uint32_t mWidth;
// The height of the viewport, specified by the <meta name="viewport"> tag,
// in CSS pixels.
uint32_t mHeight;
// The size of the viewport, specified by the <meta name="viewport"> tag.
mozilla::CSSIntSize mSize;
// Whether or not we should automatically size the viewport to the device's
// width. This is true if the document has been optimized for mobile, and

View File

@ -146,6 +146,32 @@ Link::SetProtocol(const nsAString &aProtocol)
SetHrefAttribute(uri);
}
void
Link::SetPassword(const nsAString &aPassword)
{
nsCOMPtr<nsIURI> uri(GetURIToMutate());
if (!uri) {
// Ignore failures to be compatible with NS4.
return;
}
uri->SetPassword(NS_ConvertUTF16toUTF8(aPassword));
SetHrefAttribute(uri);
}
void
Link::SetUsername(const nsAString &aUsername)
{
nsCOMPtr<nsIURI> uri(GetURIToMutate());
if (!uri) {
// Ignore failures to be compatible with NS4.
return;
}
uri->SetUsername(NS_ConvertUTF16toUTF8(aUsername));
SetHrefAttribute(uri);
}
void
Link::SetHost(const nsAString &aHost)
{
@ -155,32 +181,7 @@ Link::SetHost(const nsAString &aHost)
return;
}
// We cannot simply call nsIURI::SetHost because that would treat the name as
// an IPv6 address (like http:://[server:443]/). We also cannot call
// nsIURI::SetHostPort because that isn't implemented. Sadfaces.
// First set the hostname.
nsAString::const_iterator start, end;
aHost.BeginReading(start);
aHost.EndReading(end);
nsAString::const_iterator iter(start);
(void)FindCharInReadable(':', iter, end);
NS_ConvertUTF16toUTF8 host(Substring(start, iter));
(void)uri->SetHost(host);
// Also set the port if needed.
if (iter != end) {
iter++;
if (iter != end) {
nsAutoString portStr(Substring(iter, end));
nsresult rv;
int32_t port = portStr.ToInteger(&rv);
if (NS_SUCCEEDED(rv)) {
(void)uri->SetPort(port);
}
}
};
(void)uri->SetHostPort(NS_ConvertUTF16toUTF8(aHost));
SetHrefAttribute(uri);
return;
}
@ -259,6 +260,21 @@ Link::SetHash(const nsAString &aHash)
SetHrefAttribute(uri);
}
void
Link::GetOrigin(nsAString &aOrigin)
{
aOrigin.Truncate();
nsCOMPtr<nsIURI> uri(GetURI());
if (!uri) {
return;
}
nsString origin;
nsContentUtils::GetUTFNonNullOrigin(uri, origin);
aOrigin.Assign(origin);
}
void
Link::GetProtocol(nsAString &_protocol)
{
@ -275,6 +291,36 @@ Link::GetProtocol(nsAString &_protocol)
return;
}
void
Link::GetUsername(nsAString& aUsername)
{
aUsername.Truncate();
nsCOMPtr<nsIURI> uri(GetURI());
if (!uri) {
return;
}
nsAutoCString username;
uri->GetUsername(username);
CopyASCIItoUTF16(username, aUsername);
}
void
Link::GetPassword(nsAString &aPassword)
{
aPassword.Truncate();
nsCOMPtr<nsIURI> uri(GetURI());
if (!uri) {
return;
}
nsAutoCString password;
uri->GetPassword(password);
CopyASCIItoUTF16(password, aPassword);
}
void
Link::GetHost(nsAString &_host)
{

View File

@ -54,13 +54,18 @@ public:
* Helper methods for modifying and obtaining parts of the URI of the Link.
*/
void SetProtocol(const nsAString &aProtocol);
void SetUsername(const nsAString &aUsername);
void SetPassword(const nsAString &aPassword);
void SetHost(const nsAString &aHost);
void SetHostname(const nsAString &aHostname);
void SetPathname(const nsAString &aPathname);
void SetSearch(const nsAString &aSearch);
void SetPort(const nsAString &aPort);
void SetHash(const nsAString &aHash);
void GetOrigin(nsAString &aOrigin);
void GetProtocol(nsAString &_protocol);
void GetUsername(nsAString &aUsername);
void GetPassword(nsAString &aPassword);
void GetHost(nsAString &_host);
void GetHostname(nsAString &_hostname);
void GetPathname(nsAString &_pathname);

View File

@ -4323,30 +4323,6 @@ nsContentUtils::DestroyAnonymousContent(nsCOMPtr<nsIContent>* aContent)
}
}
/* static */
void
nsContentUtils::HoldJSObjects(void* aScriptObjectHolder,
nsScriptObjectTracer* aTracer)
{
cyclecollector::AddJSHolder(aScriptObjectHolder, aTracer);
}
/* static */
void
nsContentUtils::DropJSObjects(void* aScriptObjectHolder)
{
cyclecollector::RemoveJSHolder(aScriptObjectHolder);
}
#ifdef DEBUG
/* static */
bool
nsContentUtils::AreJSObjectsHeld(void* aScriptObjectHolder)
{
return cyclecollector::IsJSHolder(aScriptObjectHolder);
}
#endif
/* static */
void
nsContentUtils::NotifyInstalledMenuKeyboardListener(bool aInstalling)
@ -4899,10 +4875,9 @@ static void ProcessViewportToken(nsIDocument *aDocument,
/* static */
nsViewportInfo
nsContentUtils::GetViewportInfo(nsIDocument *aDocument,
uint32_t aDisplayWidth,
uint32_t aDisplayHeight)
const ScreenIntSize& aDisplaySize)
{
return aDocument->GetViewportInfo(aDisplayWidth, aDisplayHeight);
return aDocument->GetViewportInfo(aDisplaySize);
}
/* static */
@ -5541,6 +5516,19 @@ nsContentUtils::GetUTFOrigin(nsIURI* aURI, nsString& aOrigin)
return NS_OK;
}
/* static */
void
nsContentUtils::GetUTFNonNullOrigin(nsIURI* aURI, nsString& aOrigin)
{
aOrigin.Truncate();
nsString origin;
nsresult rv = GetUTFOrigin(aURI, origin);
if (NS_SUCCEEDED(rv) && !origin.EqualsLiteral("null")) {
aOrigin.Assign(origin);
}
}
/* static */
already_AddRefed<nsIDocument>
nsContentUtils::GetDocumentFromScriptContext(nsIScriptContext *aScriptContext)

View File

@ -602,6 +602,9 @@ nsDOMFileFile::GetInternalStream(nsIInputStream **aStream)
void
nsDOMFileFile::SetPath(const nsAString& aPath)
{
MOZ_ASSERT(aPath.IsEmpty() ||
aPath[aPath.Length() - 1] == PRUnichar('/'),
"Path must end with a path separator");
mPath = aPath;
}

View File

@ -94,7 +94,7 @@ NS_IMPL_FORWARD_EVENT_HANDLER(nsDOMFileReader, error, FileIOObject)
void
nsDOMFileReader::RootResultArrayBuffer()
{
NS_HOLD_JS_OBJECTS(this, nsDOMFileReader);
mozilla::HoldJSObjects(this);
}
//nsDOMFileReader constructors/initializers
@ -112,7 +112,7 @@ nsDOMFileReader::~nsDOMFileReader()
{
FreeFileData();
mResultArrayBuffer = nullptr;
NS_DROP_JS_OBJECTS(this, nsDOMFileReader);
mozilla::DropJSObjects(this);
}

View File

@ -1470,10 +1470,7 @@ nsDocument::~nsDocument()
mCustomPrototypes.Clear();
nsISupports* supports;
QueryInterface(NS_GET_IID(nsCycleCollectionISupports), reinterpret_cast<void**>(&supports));
NS_ASSERTION(supports, "Failed to QI to nsCycleCollectionISupports?!");
nsContentUtils::DropJSObjects(supports);
mozilla::DropJSObjects(this);
// Clear mObservers to keep it in sync with the mutationobserver list
mObservers.Clear();
@ -1986,14 +1983,7 @@ nsDocument::Init()
mImageTracker.Init();
mPlugins.Init();
nsXPCOMCycleCollectionParticipant* participant;
CallQueryInterface(this, &participant);
NS_ASSERTION(participant, "Failed to QI to nsXPCOMCycleCollectionParticipant!");
nsISupports* thisSupports;
QueryInterface(NS_GET_IID(nsCycleCollectionISupports), reinterpret_cast<void**>(&thisSupports));
NS_ASSERTION(thisSupports, "Failed to QI to nsCycleCollectionISupports!");
nsContentUtils::HoldJSObjects(thisSupports, participant);
mozilla::HoldJSObjects(this);
return NS_OK;
}
@ -6792,12 +6782,11 @@ nsIDocument::AdoptNode(nsINode& aAdoptedNode, ErrorResult& rv)
}
nsViewportInfo
nsDocument::GetViewportInfo(uint32_t aDisplayWidth,
uint32_t aDisplayHeight)
nsDocument::GetViewportInfo(const ScreenIntSize& aDisplaySize)
{
switch (mViewportType) {
case DisplayWidthHeight:
return nsViewportInfo(aDisplayWidth, aDisplayHeight);
return nsViewportInfo(aDisplaySize);
case Unknown:
{
nsAutoString viewport;
@ -6817,8 +6806,7 @@ nsDocument::GetViewportInfo(uint32_t aDisplayWidth,
{
// We're making an assumption that the docType can't change here
mViewportType = DisplayWidthHeight;
nsViewportInfo ret(aDisplayWidth, aDisplayHeight);
return ret;
return nsViewportInfo(aDisplaySize);
}
}
}
@ -6827,8 +6815,7 @@ nsDocument::GetViewportInfo(uint32_t aDisplayWidth,
GetHeaderData(nsGkAtoms::handheldFriendly, handheldFriendly);
if (handheldFriendly.EqualsLiteral("true")) {
mViewportType = DisplayWidthHeight;
nsViewportInfo ret(aDisplayWidth, aDisplayHeight);
return ret;
return nsViewportInfo(aDisplaySize);
}
}
@ -6836,14 +6823,14 @@ nsDocument::GetViewportInfo(uint32_t aDisplayWidth,
GetHeaderData(nsGkAtoms::viewport_minimum_scale, minScaleStr);
nsresult errorCode;
mScaleMinFloat = minScaleStr.ToFloat(&errorCode);
mScaleMinFloat = LayoutDeviceToScreenScale(minScaleStr.ToFloat(&errorCode));
if (NS_FAILED(errorCode)) {
mScaleMinFloat = kViewportMinScale;
}
mScaleMinFloat = std::min((double)mScaleMinFloat, kViewportMaxScale);
mScaleMinFloat = std::max((double)mScaleMinFloat, kViewportMinScale);
mScaleMinFloat = mozilla::clamped(
mScaleMinFloat, kViewportMinScale, kViewportMaxScale);
nsAutoString maxScaleStr;
GetHeaderData(nsGkAtoms::viewport_maximum_scale, maxScaleStr);
@ -6851,20 +6838,20 @@ nsDocument::GetViewportInfo(uint32_t aDisplayWidth,
// We define a special error code variable for the scale and max scale,
// because they are used later (see the width calculations).
nsresult scaleMaxErrorCode;
mScaleMaxFloat = maxScaleStr.ToFloat(&scaleMaxErrorCode);
mScaleMaxFloat = LayoutDeviceToScreenScale(maxScaleStr.ToFloat(&scaleMaxErrorCode));
if (NS_FAILED(scaleMaxErrorCode)) {
mScaleMaxFloat = kViewportMaxScale;
}
mScaleMaxFloat = std::min((double)mScaleMaxFloat, kViewportMaxScale);
mScaleMaxFloat = std::max((double)mScaleMaxFloat, kViewportMinScale);
mScaleMaxFloat = mozilla::clamped(
mScaleMaxFloat, kViewportMinScale, kViewportMaxScale);
nsAutoString scaleStr;
GetHeaderData(nsGkAtoms::viewport_initial_scale, scaleStr);
nsresult scaleErrorCode;
mScaleFloat = scaleStr.ToFloat(&scaleErrorCode);
mScaleFloat = LayoutDeviceToScreenScale(scaleStr.ToFloat(&scaleErrorCode));
nsAutoString widthStr, heightStr;
@ -6879,20 +6866,19 @@ nsDocument::GetViewportInfo(uint32_t aDisplayWidth,
if (widthStr.IsEmpty() &&
(heightStr.EqualsLiteral("device-height") ||
(mScaleFloat /* not adjusted for pixel ratio */ == 1.0)))
(mScaleFloat.scale == 1.0)))
{
mAutoSize = true;
}
nsresult widthErrorCode, heightErrorCode;
mViewportWidth = widthStr.ToInteger(&widthErrorCode);
mViewportHeight = heightStr.ToInteger(&heightErrorCode);
mViewportSize.width = widthStr.ToInteger(&widthErrorCode);
mViewportSize.height = heightStr.ToInteger(&heightErrorCode);
// If width or height has not been set to a valid number by this point,
// fall back to a default value.
mValidWidth = (!widthStr.IsEmpty() && NS_SUCCEEDED(widthErrorCode) && mViewportWidth > 0);
mValidHeight = (!heightStr.IsEmpty() && NS_SUCCEEDED(heightErrorCode) && mViewportHeight > 0);
mValidWidth = (!widthStr.IsEmpty() && NS_SUCCEEDED(widthErrorCode) && mViewportSize.width > 0);
mValidHeight = (!heightStr.IsEmpty() && NS_SUCCEEDED(heightErrorCode) && mViewportSize.height > 0);
mAllowZoom = true;
nsAutoString userScalable;
@ -6913,63 +6899,62 @@ nsDocument::GetViewportInfo(uint32_t aDisplayWidth,
}
case Specified:
default:
uint32_t width = mViewportWidth, height = mViewportHeight;
CSSIntSize size = mViewportSize;
if (!mValidWidth) {
if (mValidHeight && aDisplayWidth > 0 && aDisplayHeight > 0) {
width = uint32_t((height * aDisplayWidth) / aDisplayHeight);
if (mValidHeight && !aDisplaySize.IsEmpty()) {
size.width = int32_t(size.height * aDisplaySize.width / aDisplaySize.height);
} else {
width = Preferences::GetInt("browser.viewport.desktopWidth",
kViewportDefaultScreenWidth);
size.width = Preferences::GetInt("browser.viewport.desktopWidth",
kViewportDefaultScreenWidth);
}
}
if (!mValidHeight) {
if (aDisplayWidth > 0 && aDisplayHeight > 0) {
height = uint32_t((width * aDisplayHeight) / aDisplayWidth);
if (!aDisplaySize.IsEmpty()) {
size.height = int32_t(size.width * aDisplaySize.height / aDisplaySize.width);
} else {
height = width;
size.height = size.width;
}
}
// Now convert the scale into device pixels per CSS pixel.
nsIWidget *widget = nsContentUtils::WidgetForDocument(this);
double pixelRatio = widget ? widget->GetDefaultScale() : 1.0;
float scaleFloat = mScaleFloat * pixelRatio;
float scaleMinFloat= mScaleMinFloat * pixelRatio;
float scaleMaxFloat = mScaleMaxFloat * pixelRatio;
CSSToLayoutDeviceScale pixelRatio(widget ? widget->GetDefaultScale() : 1.0f);
CSSToScreenScale scaleFloat = mScaleFloat * pixelRatio;
CSSToScreenScale scaleMinFloat = mScaleMinFloat * pixelRatio;
CSSToScreenScale scaleMaxFloat = mScaleMaxFloat * pixelRatio;
if (mAutoSize) {
// aDisplayWidth and aDisplayHeight are in device pixels; convert them to
// CSS pixels for the viewport size.
width = aDisplayWidth / pixelRatio;
height = aDisplayHeight / pixelRatio;
// aDisplaySize is in screen pixels; convert them to CSS pixels for the viewport size.
CSSToScreenScale defaultPixelScale = pixelRatio * LayoutDeviceToScreenScale(1.0f);
size = mozilla::gfx::RoundedToInt(ScreenSize(aDisplaySize) / defaultPixelScale);
}
width = std::min(width, kViewportMaxWidth);
width = std::max(width, kViewportMinWidth);
size.width = clamped(size.width, kViewportMinSize.width, kViewportMaxSize.width);
// Also recalculate the default zoom, if it wasn't specified in the metadata,
// and the width is specified.
if (mScaleStrEmpty && !mWidthStrEmpty) {
scaleFloat = std::max(scaleFloat, float(aDisplayWidth) / float(width));
CSSToScreenScale defaultScale(float(aDisplaySize.width) / float(size.width));
scaleFloat = (scaleFloat > defaultScale) ? scaleFloat : defaultScale;
}
height = std::min(height, kViewportMaxHeight);
height = std::max(height, kViewportMinHeight);
size.height = clamped(size.height, kViewportMinSize.height, kViewportMaxSize.height);
// We need to perform a conversion, but only if the initial or maximum
// scale were set explicitly by the user.
if (mValidScaleFloat) {
width = std::max(width, (uint32_t)(aDisplayWidth / scaleFloat));
height = std::max(height, (uint32_t)(aDisplayHeight / scaleFloat));
CSSIntSize displaySize = RoundedToInt(ScreenSize(aDisplaySize) / scaleFloat);
size.width = std::max(size.width, displaySize.width);
size.height = std::max(size.height, displaySize.height);
} else if (mValidMaxScale) {
width = std::max(width, (uint32_t)(aDisplayWidth / scaleMaxFloat));
height = std::max(height, (uint32_t)(aDisplayHeight / scaleMaxFloat));
CSSIntSize displaySize = RoundedToInt(ScreenSize(aDisplaySize) / scaleMaxFloat);
size.width = std::max(size.width, displaySize.width);
size.height = std::max(size.height, displaySize.height);
}
nsViewportInfo ret(scaleFloat, scaleMinFloat, scaleMaxFloat, width, height,
mAutoSize, mAllowZoom);
return ret;
return nsViewportInfo(scaleFloat, scaleMinFloat, scaleMaxFloat, size,
mAutoSize, mAllowZoom);
}
}

View File

@ -753,9 +753,7 @@ public:
nsRadioGroupStruct* GetRadioGroup(const nsAString& aName) const;
nsRadioGroupStruct* GetOrCreateRadioGroup(const nsAString& aName);
virtual nsViewportInfo GetViewportInfo(uint32_t aDisplayWidth,
uint32_t aDisplayHeight) MOZ_OVERRIDE;
virtual nsViewportInfo GetViewportInfo(const mozilla::ScreenIntSize& aDisplaySize) MOZ_OVERRIDE;
private:
nsRadioGroupStruct* GetRadioGroupInternal(const nsAString& aName) const;
@ -1412,9 +1410,12 @@ private:
// These member variables cache information about the viewport so we don't have to
// recalculate it each time.
bool mValidWidth, mValidHeight;
float mScaleMinFloat, mScaleMaxFloat, mScaleFloat, mPixelRatio;
mozilla::LayoutDeviceToScreenScale mScaleMinFloat;
mozilla::LayoutDeviceToScreenScale mScaleMaxFloat;
mozilla::LayoutDeviceToScreenScale mScaleFloat;
mozilla::CSSToLayoutDeviceScale mPixelRatio;
bool mAutoSize, mAllowZoom, mValidScaleFloat, mValidMaxScale, mScaleStrEmpty, mWidthStrEmpty;
uint32_t mViewportWidth, mViewportHeight;
mozilla::CSSIntSize mViewportSize;
nsrefcnt mStackRefCnt;
bool mNeedsReleaseAfterStackRefCntRelease;

View File

@ -638,6 +638,7 @@ GK_ATOM(onalerting, "onalerting")
GK_ATOM(onanimationend, "onanimationend")
GK_ATOM(onanimationiteration, "onanimationiteration")
GK_ATOM(onanimationstart, "onanimationstart")
GK_ATOM(onantennaavailablechange, "onantennaavailablechange")
GK_ATOM(onAppCommand, "onAppCommand")
GK_ATOM(onaudioprocess, "onaudioprocess")
GK_ATOM(onbeforecopy, "onbeforecopy")
@ -709,6 +710,7 @@ GK_ATOM(onemergencycbmodechange, "onemergencycbmodechange")
GK_ATOM(onerror, "onerror")
GK_ATOM(onfailed, "onfailed")
GK_ATOM(onfocus, "onfocus")
GK_ATOM(onfrequencychange, "onfrequencychange")
GK_ATOM(onget, "onget")
GK_ATOM(ongroupchange, "ongroupchange")
GK_ATOM(onhashchange, "onhashchange")
@ -771,6 +773,7 @@ GK_ATOM(onremoteheld, "onremoteheld")
GK_ATOM(onremoteresumed, "onremoteresumed")
GK_ATOM(onretrieving, "onretrieving")
GK_ATOM(onRequest, "onRequest")
GK_ATOM(onrequestmediaplaystatus, "onrequestmediaplaystatus")
GK_ATOM(onreset, "onreset")
GK_ATOM(onresuming, "onresuming")
GK_ATOM(onMozBeforeResize, "onMozBeforeResize")
@ -785,8 +788,6 @@ GK_ATOM(onshow, "onshow")
GK_ATOM(onstatechange, "onstatechange")
GK_ATOM(onstatuschanged, "onstatuschanged")
GK_ATOM(onstkcommand, "onstkcommand")
GK_ATOM(onantennastatechange, "onantennastatechange")
GK_ATOM(onseekcomplete, "onseekcomplete")
GK_ATOM(onstksessionend, "onstksessionend")
GK_ATOM(onsubmit, "onsubmit")
GK_ATOM(onsuccess, "onsuccess")

View File

@ -6,10 +6,12 @@
#include "mozilla/Assertions.h"
#include <algorithm>
using namespace mozilla;
void
nsViewportInfo::SetDefaultZoom(const double aDefaultZoom)
nsViewportInfo::SetDefaultZoom(const CSSToScreenScale& aDefaultZoom)
{
MOZ_ASSERT(aDefaultZoom >= 0.0f);
MOZ_ASSERT(aDefaultZoom.scale >= 0.0f);
mDefaultZoom = aDefaultZoom;
}
@ -20,6 +22,6 @@ nsViewportInfo::ConstrainViewportValues()
// dev.w3.org/csswg/css-device-adapt section 6.2
mMaxZoom = std::max(mMinZoom, mMaxZoom);
mDefaultZoom = std::min(mDefaultZoom, mMaxZoom);
mDefaultZoom = std::max(mDefaultZoom, mMinZoom);
mDefaultZoom = mDefaultZoom < mMaxZoom ? mDefaultZoom : mMaxZoom;
mDefaultZoom = mDefaultZoom > mMinZoom ? mDefaultZoom : mMinZoom;
}

View File

@ -323,13 +323,13 @@ nsXMLHttpRequest::~nsXMLHttpRequest()
mResultJSON = JSVAL_VOID;
mResultArrayBuffer = nullptr;
NS_DROP_JS_OBJECTS(this, nsXMLHttpRequest);
mozilla::DropJSObjects(this);
}
void
nsXMLHttpRequest::RootJSResultObjects()
{
NS_HOLD_JS_OBJECTS(this, nsXMLHttpRequest);
mozilla::HoldJSObjects(this);
}
/**

View File

@ -23,7 +23,7 @@ function modifySelection(s) {
}
function getLoadContext() {
var Ci = SpecialPowers.wrap(Components).interfaces;
var Ci = SpecialPowers.Ci;
return SpecialPowers.wrap(window).QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsILoadContext);
@ -35,16 +35,16 @@ function testCopyPaste (isXHTML) {
var suppressUnicodeCheckIfHidden = !!isXHTML;
var suppressHTMLCheck = !!isXHTML;
var webnav = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
var webnav = window.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
.getInterface(SpecialPowers.Ci.nsIWebNavigation)
var docShell = webnav.QueryInterface(Components.interfaces.nsIDocShell);
var docShell = webnav.QueryInterface(SpecialPowers.Ci.nsIDocShell);
var documentViewer = docShell.contentViewer
.QueryInterface(Components.interfaces.nsIContentViewerEdit);
.QueryInterface(SpecialPowers.Ci.nsIContentViewerEdit);
var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
.getService(Components.interfaces.nsIClipboard);
var clipboard = SpecialPowers.Cc["@mozilla.org/widget/clipboard;1"]
.getService(SpecialPowers.Ci.nsIClipboard);
var textarea = SpecialPowers.wrap(document.getElementById('input'));
@ -83,8 +83,8 @@ function testCopyPaste (isXHTML) {
copySelectionToClipboard();
}
function getClipboardData(mime) {
var transferable = Components.classes['@mozilla.org/widget/transferable;1']
.createInstance(Components.interfaces.nsITransferable);
var transferable = SpecialPowers.Cc['@mozilla.org/widget/transferable;1']
.createInstance(SpecialPowers.Ci.nsITransferable);
transferable.init(getLoadContext());
transferable.addDataFlavor(mime);
clipboard.getData(transferable, 1);
@ -97,7 +97,7 @@ function testCopyPaste (isXHTML) {
return null;
var data = getClipboardData(mime);
is (data.value == null ? data.value :
data.value.QueryInterface(Components.interfaces.nsISupportsString).data,
data.value.QueryInterface(SpecialPowers.Ci.nsISupportsString).data,
expected,
mime + " value in the clipboard");
return data.value;
@ -257,7 +257,6 @@ if (false) {
setTimeout(function(){testSelectionToString("div11")},0);
setTimeout(function(){
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
copyRangeToClipboard($("div12").childNodes[0],0, $("div12").childNodes[1],2);
testClipboardValue("text/unicode", "Xdiv12");
testClipboardValue("text/html", "<div><p>X<span>div</span>12</p></div>");

View File

@ -134,27 +134,25 @@ function testHasRun() {
}
function createFileWithData(fileData) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"].getService(SpecialPowers.Ci.nsIProperties);
var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
testFile.append("fileAPItestfile2-" + fileNum);
fileNum++;
var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].createInstance(SpecialPowers.Ci.nsIFileOutputStream);
outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
0666, 0);
outStream.write(fileData, fileData.length);
outStream.close();
var fileList = document.getElementById('fileList');
fileList.value = testFile.path;
SpecialPowers.wrap(fileList).value = testFile.path;
return fileList.files[0];
}
function gc() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIDOMWindowUtils)
window.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
.getInterface(SpecialPowers.Ci.nsIDOMWindowUtils)
.garbageCollect();
}

View File

@ -78,10 +78,10 @@ extensions.forEach(
);
function createFileWithDataExt(fileData, extension) {
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"].getService(SpecialPowers.Ci.nsIProperties);
var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
testFile.append("testfile" + extension);
var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].createInstance(SpecialPowers.Ci.nsIFileOutputStream);
outStream.init(testFile, 0x02 | 0x08 | 0x20, 0666, 0);
outStream.write(fileData, fileData.length);
outStream.close();

View File

@ -17,10 +17,9 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=270145
<script class="testbody" type="text/javascript">
//<![CDATA[
function testHtmlCopyEncoder () {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const de = Components.interfaces.nsIDocumentEncoder;
var encoder = Components.classes["@mozilla.org/layout/htmlCopyEncoder;1"]
.createInstance(Components.interfaces.nsIDocumentEncoder);
const de = SpecialPowers.Ci.nsIDocumentEncoder;
var encoder = SpecialPowers.Cc["@mozilla.org/layout/htmlCopyEncoder;1"]
.createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
var out, expected;
var node = document.getElementById('draggable');

View File

@ -24,9 +24,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=401662
SimpleTest.waitForExplicitFinish();
window.onload = function() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cc = SpecialPowers.Cc;
const Ci = SpecialPowers.Ci;
var encoder = Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"]
.createInstance(Ci.nsIDocumentEncoder);

View File

@ -23,8 +23,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=403852
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"].getService(SpecialPowers.Ci.nsIProperties);
var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
testFile.append("prefs.js");
var fileList = document.getElementById('fileList');

View File

@ -21,8 +21,6 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=417384
var expectedSerialization = "about:blank document";
function testSerializer() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var doc = document.getElementById('test_iframe').contentDocument;
doc.body.textContent = expectedSerialization;
var head1 = doc.createElement("head");
@ -34,8 +32,8 @@ function testSerializer() {
span.appendChild(doc.createTextNode("\nafter inner head"));
var encoder =
Components.classes["@mozilla.org/layout/documentEncoder;1?type=text/html"]
.createInstance(Components.interfaces.nsIDocumentEncoder);
SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"]
.createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
encoder.init(doc, "text/plain", 0);
encoder.setCharset("UTF-8");
var out = encoder.encodeToString();

View File

@ -23,17 +23,17 @@ function loadFileContent(aFile, aCharset) {
if(aCharset == undefined)
aCharset = 'UTF-8';
var baseUri = Components.classes['@mozilla.org/network/standard-url;1']
.createInstance(Components.interfaces.nsIURI);
var baseUri = SpecialPowers.Cc['@mozilla.org/network/standard-url;1']
.createInstance(SpecialPowers.Ci.nsIURI);
baseUri.spec = window.location.href;
var ios = Components.classes['@mozilla.org/network/io-service;1']
.getService(Components.interfaces.nsIIOService);
var ios = SpecialPowers.Cc['@mozilla.org/network/io-service;1']
.getService(SpecialPowers.Ci.nsIIOService);
var chann = ios.newChannel(aFile, aCharset, baseUri);
var cis = Components.interfaces.nsIConverterInputStream;
var cis = SpecialPowers.Ci.nsIConverterInputStream;
var inputStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(cis);
inputStream.init(chann.open(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
var str = {}, content = '';
@ -45,10 +45,9 @@ function loadFileContent(aFile, aCharset) {
function testHtmlSerializer_1 () {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const de = Components.interfaces.nsIDocumentEncoder
var encoder = Components.classes["@mozilla.org/layout/documentEncoder;1?type=application/xhtml+xml"]
.createInstance(Components.interfaces.nsIDocumentEncoder);
const de = SpecialPowers.Ci.nsIDocumentEncoder
var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=application/xhtml+xml"]
.createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
var doc = $("testframe").contentDocument;
var out, expected;

View File

@ -23,17 +23,17 @@ function loadFileContent(aFile, aCharset) {
if(aCharset == undefined)
aCharset = 'UTF-8';
var baseUri = Components.classes['@mozilla.org/network/standard-url;1']
.createInstance(Components.interfaces.nsIURI);
var baseUri = SpecialPowers.Cc['@mozilla.org/network/standard-url;1']
.createInstance(SpecialPowers.Ci.nsIURI);
baseUri.spec = window.location.href;
var ios = Components.classes['@mozilla.org/network/io-service;1']
.getService(Components.interfaces.nsIIOService);
var ios = SpecialPowers.Cc['@mozilla.org/network/io-service;1']
.getService(SpecialPowers.Ci.nsIIOService);
var chann = ios.newChannel(aFile, aCharset, baseUri);
var cis = Components.interfaces.nsIConverterInputStream;
var cis = SpecialPowers.Ci.nsIConverterInputStream;
var inputStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(cis);
inputStream.init(chann.open(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
var str = {}, content = '';
@ -50,10 +50,9 @@ function isRoughly(actual, expected, message) {
}
function testHtmlSerializer_1 () {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const de = Components.interfaces.nsIDocumentEncoder
var encoder = Components.classes["@mozilla.org/layout/documentEncoder;1?type=text/html"]
.createInstance(Components.interfaces.nsIDocumentEncoder);
const de = SpecialPowers.Ci.nsIDocumentEncoder;
var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"]
.createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
var doc = $("testframe").contentDocument;
var out, expected;

View File

@ -23,17 +23,17 @@ function loadFileContent(aFile, aCharset) {
if(aCharset == undefined)
aCharset = 'UTF-8';
var baseUri = Components.classes['@mozilla.org/network/standard-url;1']
.createInstance(Components.interfaces.nsIURI);
var baseUri = SpecialPowers.Cc['@mozilla.org/network/standard-url;1']
.createInstance(SpecialPowers.Ci.nsIURI);
baseUri.spec = window.location.href;
var ios = Components.classes['@mozilla.org/network/io-service;1']
.getService(Components.interfaces.nsIIOService);
var ios = SpecialPowers.Cc['@mozilla.org/network/io-service;1']
.getService(SpecialPowers.Ci.nsIIOService);
var chann = ios.newChannel(aFile, aCharset, baseUri);
var cis = Components.interfaces.nsIConverterInputStream;
var cis = SpecialPowers.Ci.nsIConverterInputStream;
var inputStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(cis);
inputStream.init(chann.open(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
var str = {}, content = '';
@ -50,10 +50,9 @@ function isRoughly(actual, expected, message) {
}
function testHtmlSerializer_1 () {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const de = Components.interfaces.nsIDocumentEncoder
var encoder = Components.classes["@mozilla.org/layout/documentEncoder;1?type=text/html"]
.createInstance(Components.interfaces.nsIDocumentEncoder);
const de = SpecialPowers.Ci.nsIDocumentEncoder;
var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"]
.createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
var doc = $("testframe").contentDocument;
var out, expected;

View File

@ -22,17 +22,17 @@ function loadFileContent(aFile, aCharset) {
if (aCharset == undefined)
aCharset = 'UTF-8';
var baseUri = Components.classes['@mozilla.org/network/standard-url;1']
.createInstance(Components.interfaces.nsIURI);
var baseUri = SpecialPowers.Cc['@mozilla.org/network/standard-url;1']
.createInstance(SpecialPowers.Ci.nsIURI);
baseUri.spec = window.location.href;
var ios = Components.classes['@mozilla.org/network/io-service;1']
.getService(Components.interfaces.nsIIOService);
var ios = SpecialPowers.Cc['@mozilla.org/network/io-service;1']
.getService(SpecialPowers.Ci.nsIIOService);
var chann = ios.newChannel(aFile, aCharset, baseUri);
var cis = Components.interfaces.nsIConverterInputStream;
var cis = SpecialPowers.Ci.nsIConverterInputStream;
var inputStream = Components.classes["@mozilla.org/intl/converter-input-stream;1"]
var inputStream = SpecialPowers.Cc["@mozilla.org/intl/converter-input-stream;1"]
.createInstance(cis);
inputStream.init(chann.open(), aCharset, 1024, cis.DEFAULT_REPLACEMENT_CHARACTER);
var str = {}, content = '';
@ -49,10 +49,9 @@ function isRoughly(actual, expected, message) {
}
function testHtmlSerializer_1 () {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const de = Components.interfaces.nsIDocumentEncoder
var encoder = Components.classes["@mozilla.org/layout/documentEncoder;1?type=text/html"]
.createInstance(Components.interfaces.nsIDocumentEncoder);
const de = SpecialPowers.Ci.nsIDocumentEncoder;
var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"]
.createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
var doc = $("testframe").contentDocument;
var out, expected;

View File

@ -23,23 +23,21 @@ var checkedLoad = false;
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cc = SpecialPowers.Cc;
const Ci = SpecialPowers.Ci;
// Content policy / factory implementation for the test
var policyID = Components.ID("{65944d64-2390-422e-bea3-80d0af7f69ef}");
var policyID = SpecialPowers.wrap(SpecialPowers.Components).ID("{65944d64-2390-422e-bea3-80d0af7f69ef}");
var policyName = "@mozilla.org/498897_testpolicy;1";
var policy = {
// nsISupports implementation
QueryInterface: function(iid) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
if (iid.equals(Ci.nsISupports) ||
iid.equals(Ci.nsIFactory) ||
iid.equals(Ci.nsIContentPolicy))
return this;
throw Components.results.NS_ERROR_NO_INTERFACE;
throw SpecialPowers.Cr.NS_ERROR_NO_INTERFACE;
},
// nsIFactory implementation
@ -50,8 +48,6 @@ var policy = {
// nsIContentPolicy implementation
shouldLoad: function(contentType, contentLocation, requestOrigin, context,
mimeTypeGuess, extra) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
if (contentLocation instanceof Ci.nsIURL &&
contentLocation.fileName == "file_bug498897.css" &&
requestOrigin instanceof Ci.nsIURL &&
@ -64,13 +60,11 @@ var policy = {
shouldProcess: function(contentType, contentLocation, requestOrigin, context,
mimeTypeGuess, extra) {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
return Ci.nsIContentPolicy.ACCEPT;
}
}
var componentManager = Components.manager
var componentManager = SpecialPowers.wrap(SpecialPowers.Components).manager
.QueryInterface(Ci.nsIComponentRegistrar);
componentManager.registerFactory(policyID, "Test content policy for bug 498897",
policyName, policy);
@ -82,15 +76,11 @@ categoryManager.addCategoryEntry("content-policy", policyName, policyName,
function testFinished()
{
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
ok(checkedLoad, "Content policy didn't get called!");
categoryManager.deleteCategoryEntry("content-policy", policyName, false);
setTimeout(function() {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
componentManager.unregisterFactory(policyID, policy);
SimpleTest.finish();

View File

@ -21,10 +21,9 @@
<script class="testbody" type="text/javascript">
function testSerializer () {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const de = Components.interfaces.nsIDocumentEncoder
var encoder = Components.classes["@mozilla.org/layout/documentEncoder;1?type=text/html"]
.createInstance(Components.interfaces.nsIDocumentEncoder);
const de = SpecialPowers.Ci.nsIDocumentEncoder;
var encoder = SpecialPowers.Cc["@mozilla.org/layout/documentEncoder;1?type=text/html"]
.createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
var parser = new DOMParser();
var serializer = new XMLSerializer();

View File

@ -17,10 +17,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=578096
</div>
<pre id="test">
<script class="testbody" type="text/javascript">
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cc = SpecialPowers.Cc;
const Ci = SpecialPowers.Ci;
var file = Cc["@mozilla.org/file/directory_service;1"]
.getService(Ci.nsIProperties)
@ -29,12 +27,11 @@ file.append("foo.txt");
file.createUnique(Ci.nsIFile.NORMAL_FILE_TYPE, 0600);
SimpleTest.waitForExplicitFinish();
document.getElementById('file').value = file.path;
SpecialPowers.wrap(document.getElementById('file')).value = file.path;
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function(event) {
if (xhr.readyState == 4) {
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
file.remove(false);
ok(true, "We didn't throw! Yay!");
SimpleTest.finish();

View File

@ -16,25 +16,24 @@
<script class="testbody" type="text/javascript">
function testCopyImage () {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
// selection of the node
var node = document.getElementById('logo');
var webnav = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
.getInterface(Components.interfaces.nsIWebNavigation)
var webnav = SpecialPowers.wrap(window)
.QueryInterface(SpecialPowers.Ci.nsIInterfaceRequestor)
.getInterface(SpecialPowers.Ci.nsIWebNavigation)
var docShell = webnav.QueryInterface(Components.interfaces.nsIDocShell);
var docShell = webnav.QueryInterface(SpecialPowers.Ci.nsIDocShell);
docShell.chromeEventHandler.ownerDocument.popupNode = node;
// let's copy the node
var documentViewer = docShell.contentViewer
.QueryInterface(Components.interfaces.nsIContentViewerEdit);
.QueryInterface(SpecialPowers.Ci.nsIContentViewerEdit);
documentViewer.copyImage(documentViewer.COPY_IMAGE_ALL);
//--------- now check the content of the clipboard
var clipboard = Components.classes["@mozilla.org/widget/clipboard;1"]
.getService(Components.interfaces.nsIClipboard);
var clipboard = SpecialPowers.Cc["@mozilla.org/widget/clipboard;1"]
.getService(SpecialPowers.Ci.nsIClipboard);
// does the clipboard contain text/unicode data ?
ok(clipboard.hasDataMatchingFlavors(["text/unicode"], 1, clipboard.kGlobalClipboard), "clipboard contains unicode text");

View File

@ -33,7 +33,6 @@ var fileNum = 1;
var testRanCounter = 0;
var expectedTestCount = 0;
SimpleTest.waitForExplicitFinish();
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
is(FileReader.EMPTY, 0, "correct EMPTY value");
is(FileReader.LOADING, 1, "correct LOADING value");
@ -65,7 +64,7 @@ var asciiFile = createFileWithData(testASCIIData);
var binaryFile = createFileWithData(testBinaryData);
var fileList = document.getElementById('fileList');
fileList.value = "/none/existing/path/fileAPI/testing";
SpecialPowers.wrap(fileList).value = "/none/existing/path/fileAPI/testing";
var nonExistingFile = fileList.files[0];
// Test that plain reading works and fires events as expected, both
@ -424,18 +423,18 @@ function testHasRun() {
}
function createFileWithData(fileData) {
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties);
var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"].getService(SpecialPowers.Ci.nsIProperties);
var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
testFile.append("fileAPItestfile" + fileNum);
fileNum++;
var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"].createInstance(SpecialPowers.Ci.nsIFileOutputStream);
outStream.init(testFile, 0x02 | 0x08 | 0x20, // write, create, truncate
0666, 0);
outStream.write(fileData, fileData.length);
outStream.close();
var fileList = document.getElementById('fileList');
fileList.value = testFile.path;
SpecialPowers.wrap(fileList).value = testFile.path;
return fileList.files[0];
}

View File

@ -16,10 +16,9 @@
<script class="testbody" type="text/javascript">
function testHtmlCopyEncoder () {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const de = Components.interfaces.nsIDocumentEncoder;
var encoder = Components.classes["@mozilla.org/layout/htmlCopyEncoder;1"]
.createInstance(Components.interfaces.nsIDocumentEncoder);
const de = SpecialPowers.Ci.nsIDocumentEncoder;
var encoder = SpecialPowers.Cc["@mozilla.org/layout/htmlCopyEncoder;1"]
.createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
var out, expected;
var node = document.getElementById('draggable');

View File

@ -16,10 +16,9 @@
<script class="testbody" type="text/javascript">
//<![CDATA[
function testHtmlCopyEncoder () {
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
const de = Components.interfaces.nsIDocumentEncoder;
var encoder = Components.classes["@mozilla.org/layout/htmlCopyEncoder;1"]
.createInstance(Components.interfaces.nsIDocumentEncoder);
const de = SpecialPowers.Ci.nsIDocumentEncoder;
var encoder = SpecialPowers.Cc["@mozilla.org/layout/htmlCopyEncoder;1"]
.createInstance(SpecialPowers.Ci.nsIDocumentEncoder);
var out, expected;
var node = document.getElementById('draggable');

View File

@ -1225,15 +1225,15 @@ function test41()
ok(true, "test 41c close");
// clean up the STS state
netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
const Cc = Components.classes;
const Ci = Components.interfaces;
const Cc = SpecialPowers.Cc;
const Ci = SpecialPowers.Ci;
var ios = Cc["@mozilla.org/network/io-service;1"].getService(Ci.nsIIOService);
var thehost = ios.newURI("http://example.com", null, null);
var sss = Cc["@mozilla.org/ssservice;1"].getService(Ci.nsISiteSecurityService);
var loadContext = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsILoadContext);
var loadContext = SpecialPowers.wrap(window)
.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsILoadContext);
var flags = 0;
if (loadContext.usePrivateBrowsing)
flags |= Ci.nsISocketProvider.NO_PERMANENT_STORAGE;
@ -1338,24 +1338,20 @@ function test44()
function createDOMFile(fileName, fileData)
{
// enablePrivilege is picky about where it's called? if I put it in global
// scope at start of <script> it doesn't work...
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
// create File in profile dir
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties);
var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"]
.getService(SpecialPowers.Ci.nsIProperties);
var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
testFile.append(fileName);
var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"]
.createInstance(SpecialPowers.Ci.nsIFileOutputStream);
outStream.init(testFile, 0x02 | 0x08 | 0x20, 0666, 0);
outStream.write(fileData, fileData.length);
outStream.close();
// Set filename into DOM <input> field, as if selected by user
var fileList = document.getElementById('fileList');
fileList.value = testFile.path;
SpecialPowers.wrap(fileList).value = testFile.path;
// return JS File object, aka Blob
return fileList.files[0];

View File

@ -22,17 +22,13 @@ function startsWith(target, prefix)
function createDOMFile(fileName, fileData)
{
// enablePrivilege is picky about where it's called? if I put it in global
// scope at start of <script> it doesn't work...
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
// create File in profile dir
var dirSvc = Components.classes["@mozilla.org/file/directory_service;1"]
.getService(Components.interfaces.nsIProperties);
var testFile = dirSvc.get("ProfD", Components.interfaces.nsIFile);
var dirSvc = SpecialPowers.Cc["@mozilla.org/file/directory_service;1"]
.getService(SpecialPowers.Ci.nsIProperties);
var testFile = dirSvc.get("ProfD", SpecialPowers.Ci.nsIFile);
testFile.append(fileName);
var outStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
.createInstance(Components.interfaces.nsIFileOutputStream);
var outStream = SpecialPowers.Cc["@mozilla.org/network/file-output-stream;1"]
.createInstance(SpecialPowers.Ci.nsIFileOutputStream);
outStream.init(testFile, 0x02 | 0x08 | 0x20, 0666, 0);
if (fileData) {
outStream.write(fileData, fileData.length);
@ -41,7 +37,7 @@ function createDOMFile(fileName, fileData)
// Set filename into DOM <input> field, as if selected by user
var fileList = document.getElementById('fileList');
fileList.value = testFile.path;
SpecialPowers.wrap(fileList).value = testFile.path;
// return JS File object, aka Blob
return fileList.files[0];

View File

@ -874,7 +874,7 @@ CanvasRenderingContext2D::EnsureTarget()
if (!mForceSoftware && CheckSizeForSkiaGL(size))
{
glContext = GLContextProvider::CreateOffscreen(gfxIntSize(size.width, size.height),
caps, GLContext::ContextFlagsNone);
caps, gl::ContextFlagsNone);
}
if (glContext) {

View File

@ -6,8 +6,8 @@
#include "mozilla/dom/ImageData.h"
#include "nsContentUtils.h" // for NS_HOLD_JS_OBJECTS, NS_DROP_JS_OBJECTS
#include "mozilla/dom/ImageDataBinding.h"
#include "nsCycleCollectionHoldDrop.h"
#include "jsapi.h"
@ -38,7 +38,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
void
ImageData::HoldData()
{
NS_HOLD_JS_OBJECTS(this, ImageData);
mozilla::HoldJSObjects(this);
}
void
@ -46,7 +46,7 @@ ImageData::DropData()
{
if (mData) {
mData = nullptr;
NS_DROP_JS_OBJECTS(this, ImageData);
mozilla::DropJSObjects(this);
}
}

View File

@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGL2Context.h"
#include "GLContext.h"
#include "mozilla/dom/WebGL2RenderingContextBinding.h"
#include "mozilla/Telemetry.h"

View File

@ -6,8 +6,7 @@
#ifndef WEBGLACTIVEINFO_H_
#define WEBGLACTIVEINFO_H_
#include "WebGLTypes.h"
#include "nsISupports.h"
#include "WebGLObjectModel.h"
#include "nsString.h"
#include "js/TypeDecls.h"
@ -16,7 +15,7 @@ namespace mozilla {
class WebGLActiveInfo MOZ_FINAL
{
public:
WebGLActiveInfo(WebGLint size, WebGLenum type, const nsACString& name) :
WebGLActiveInfo(GLint size, GLenum type, const nsACString& name) :
mSize(size),
mType(type),
mName(NS_ConvertASCIItoUTF16(name))
@ -24,11 +23,11 @@ public:
// WebIDL attributes
WebGLint Size() const {
GLint Size() const {
return mSize;
}
WebGLenum Type() const {
GLenum Type() const {
return mType;
}
@ -41,8 +40,8 @@ public:
NS_INLINE_DECL_REFCOUNTING(WebGLActiveInfo)
protected:
WebGLint mSize;
WebGLenum mType;
GLint mSize;
GLenum mType;
nsString mName;
};

View File

@ -5,6 +5,7 @@
#include "WebGLBuffer.h"
#include "WebGLContext.h"
#include "GLContext.h"
#include "mozilla/dom/WebGLRenderingContextBinding.h"
using namespace mozilla;

View File

@ -40,10 +40,10 @@ public:
bool HasEverBeenBound() { return mHasEverBeenBound; }
void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
GLuint GLName() const { return mGLName; }
GLuint ByteLength() const { return mByteLength; }
WebGLsizeiptr ByteLength() const { return mByteLength; }
GLenum Target() const { return mTarget; }
void SetByteLength(GLuint byteLength) { mByteLength = byteLength; }
void SetByteLength(WebGLsizeiptr byteLength) { mByteLength = byteLength; }
void SetTarget(GLenum target);
@ -51,7 +51,7 @@ public:
void ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes);
bool Validate(WebGLenum type, uint32_t max_allowed, size_t first, size_t count) {
bool Validate(GLenum type, uint32_t max_allowed, size_t first, size_t count) {
return mCache->Validate(type, max_allowed, first, count);
}
@ -67,9 +67,9 @@ public:
protected:
WebGLuint mGLName;
GLuint mGLName;
bool mHasEverBeenBound;
GLuint mByteLength;
WebGLsizeiptr mByteLength;
GLenum mTarget;
nsAutoPtr<WebGLElementArrayCache> mCache;

View File

@ -37,6 +37,7 @@
#include "nsDisplayList.h"
#include "GLContextProvider.h"
#include "GLContext.h"
#include "gfxCrashReporterUtils.h"
@ -184,7 +185,7 @@ WebGLContext::WebGLContext()
mContextLossTimerRunning = false;
mDrawSinceContextLossTimerSet = false;
mContextRestorer = do_CreateInstance("@mozilla.org/timer;1");
mContextStatus = ContextStable;
mContextStatus = ContextNotLost;
mContextLostErrorSet = false;
mLoseContextOnHeapMinimize = false;
mCanLoseContextInForeground = true;
@ -530,9 +531,9 @@ WebGLContext::SetDimensions(int32_t width, int32_t height)
// try the default provider, whatever that is
if (!gl && useOpenGL) {
GLContext::ContextFlags flag = useMesaLlvmPipe
? GLContext::ContextFlagsMesaLLVMPipe
: GLContext::ContextFlagsNone;
gl::ContextFlags flag = useMesaLlvmPipe
? gl::ContextFlagsMesaLLVMPipe
: gl::ContextFlagsNone;
gl = gl::GLContextProvider::CreateOffscreen(size, caps, flag);
if (gl && !InitAndValidateGL()) {
GenerateWarning("Error during %s initialization",
@ -844,7 +845,7 @@ WebGLContext::GetCanvasLayer(nsDisplayListBuilder* aBuilder,
CanvasLayer *aOldLayer,
LayerManager *aManager)
{
if (!IsContextStable())
if (IsContextLost())
return nullptr;
if (!mResetLayer && aOldLayer &&
@ -899,7 +900,7 @@ void
WebGLContext::GetContextAttributes(Nullable<dom::WebGLContextAttributesInitializer> &retval)
{
retval.SetNull();
if (!IsContextStable())
if (IsContextLost())
return;
dom::WebGLContextAttributes& result = retval.SetValue();
@ -914,11 +915,11 @@ WebGLContext::GetContextAttributes(Nullable<dom::WebGLContextAttributesInitializ
result.mPreserveDrawingBuffer = mOptions.preserveDrawingBuffer;
}
/* [noscript] DOMString mozGetUnderlyingParamString(in WebGLenum pname); */
/* [noscript] DOMString mozGetUnderlyingParamString(in GLenum pname); */
NS_IMETHODIMP
WebGLContext::MozGetUnderlyingParamString(uint32_t pname, nsAString& retval)
{
if (!IsContextStable())
if (IsContextLost())
return NS_OK;
retval.SetIsVoid(true);
@ -1156,7 +1157,7 @@ WebGLContext::PresentScreenBuffer()
void
WebGLContext::DummyFramebufferOperation(const char *info)
{
WebGLenum status = CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
GLenum status = CheckFramebufferStatus(LOCAL_GL_FRAMEBUFFER);
if (status == LOCAL_GL_FRAMEBUFFER_COMPLETE)
return;
else
@ -1220,7 +1221,7 @@ WebGLContext::RobustnessTimerCallback(nsITimer* timer)
SetupContextLossTimer();
return;
}
mContextStatus = ContextStable;
mContextStatus = ContextNotLost;
nsContentUtils::DispatchTrustedEvent(mCanvasElement->OwnerDoc(),
static_cast<nsIDOMHTMLCanvasElement*>(mCanvasElement),
NS_LITERAL_STRING("webglcontextrestored"),
@ -1240,10 +1241,10 @@ void
WebGLContext::MaybeRestoreContext()
{
// Don't try to handle it if we already know it's busted.
if (mContextStatus != ContextStable || gl == nullptr)
if (mContextStatus != ContextNotLost || gl == nullptr)
return;
bool isEGL = gl->GetContextType() == GLContext::ContextTypeEGL,
bool isEGL = gl->GetContextType() == gl::ContextTypeEGL,
isANGLE = gl->IsANGLE();
GLContext::ContextResetARB resetStatus = GLContext::CONTEXT_NO_ERROR;
@ -1311,6 +1312,9 @@ WebGLContext::ForceRestoreContext()
mContextStatus = ContextLostAwaitingRestore;
}
void
WebGLContext::MakeContextCurrent() const { gl->MakeCurrent(); }
//
// XPCOM goop
//
@ -1318,7 +1322,7 @@ WebGLContext::ForceRestoreContext()
NS_IMPL_CYCLE_COLLECTING_ADDREF(WebGLContext)
NS_IMPL_CYCLE_COLLECTING_RELEASE(WebGLContext)
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_12(WebGLContext,
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_13(WebGLContext,
mCanvasElement,
mExtensions,
mBound2DTextures,
@ -1329,6 +1333,7 @@ NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_12(WebGLContext,
mBoundFramebuffer,
mBoundRenderbuffer,
mBoundVertexArray,
mDefaultVertexArray,
mActiveOcclusionQuery,
mActiveTransformFeedbackQuery)

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@
#include "WebGLContext.h"
#include "WebGLQuery.h"
#include "GLContext.h"
using namespace mozilla;
@ -19,7 +20,7 @@ using namespace mozilla;
*/
static const char*
GetQueryTargetEnumString(WebGLenum target)
GetQueryTargetEnumString(GLenum target)
{
switch (target)
{
@ -56,7 +57,7 @@ SimulateOcclusionQueryTarget(const gl::GLContext* gl, GLenum target)
already_AddRefed<WebGLQuery>
WebGLContext::CreateQuery()
{
if (!IsContextStable())
if (IsContextLost())
return nullptr;
if (mActiveOcclusionQuery && !gl->IsGLES2()) {
@ -81,7 +82,7 @@ WebGLContext::CreateQuery()
void
WebGLContext::DeleteQuery(WebGLQuery *query)
{
if (!IsContextStable())
if (IsContextLost())
return;
if (!query)
@ -108,9 +109,9 @@ WebGLContext::DeleteQuery(WebGLQuery *query)
}
void
WebGLContext::BeginQuery(WebGLenum target, WebGLQuery *query)
WebGLContext::BeginQuery(GLenum target, WebGLQuery *query)
{
if (!IsContextStable())
if (IsContextLost())
return;
WebGLRefPtr<WebGLQuery>* targetSlot = GetQueryTargetSlot(target, "beginQuery");
@ -178,9 +179,9 @@ WebGLContext::BeginQuery(WebGLenum target, WebGLQuery *query)
}
void
WebGLContext::EndQuery(WebGLenum target)
WebGLContext::EndQuery(GLenum target)
{
if (!IsContextStable())
if (IsContextLost())
return;
WebGLRefPtr<WebGLQuery>* targetSlot = GetQueryTargetSlot(target, "endQuery");
@ -222,7 +223,7 @@ WebGLContext::EndQuery(WebGLenum target)
bool
WebGLContext::IsQuery(WebGLQuery *query)
{
if (!IsContextStable())
if (IsContextLost())
return false;
if (!query)
@ -234,9 +235,9 @@ WebGLContext::IsQuery(WebGLQuery *query)
}
already_AddRefed<WebGLQuery>
WebGLContext::GetQuery(WebGLenum target, WebGLenum pname)
WebGLContext::GetQuery(GLenum target, GLenum pname)
{
if (!IsContextStable())
if (IsContextLost())
return nullptr;
WebGLRefPtr<WebGLQuery>* targetSlot = GetQueryTargetSlot(target, "getQuery");
@ -257,9 +258,9 @@ WebGLContext::GetQuery(WebGLenum target, WebGLenum pname)
}
JS::Value
WebGLContext::GetQueryObject(JSContext* cx, WebGLQuery *query, WebGLenum pname)
WebGLContext::GetQueryObject(JSContext* cx, WebGLQuery *query, GLenum pname)
{
if (!IsContextStable())
if (IsContextLost())
return JS::NullValue();
if (!query) {
@ -333,7 +334,7 @@ WebGLContext::GetQueryObject(JSContext* cx, WebGLQuery *query, WebGLenum pname)
}
WebGLRefPtr<WebGLQuery>*
WebGLContext::GetQueryTargetSlot(WebGLenum target, const char* infos)
WebGLContext::GetQueryTargetSlot(GLenum target, const char* infos)
{
switch (target) {
case LOCAL_GL_ANY_SAMPLES_PASSED:

View File

@ -4,6 +4,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "WebGLContext.h"
#include "GLContext.h"
#include "WebGLBuffer.h"
#include "WebGLVertexArray.h"
@ -11,9 +12,9 @@ using namespace mozilla;
using namespace mozilla::dom;
void
WebGLContext::BindBuffer(WebGLenum target, WebGLBuffer *buffer)
WebGLContext::BindBuffer(GLenum target, WebGLBuffer *buffer)
{
if (!IsContextStable())
if (IsContextLost())
return;
if (!ValidateObjectAllowDeletedOrNull("bindBuffer", buffer))
@ -46,9 +47,9 @@ WebGLContext::BindBuffer(WebGLenum target, WebGLBuffer *buffer)
}
void
WebGLContext::BindBufferBase(WebGLenum target, WebGLuint index, WebGLBuffer* buffer)
WebGLContext::BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer)
{
if (!IsContextStable())
if (IsContextLost())
return;
if (!ValidateObjectAllowDeletedOrNull("bindBufferBase", buffer))
@ -87,10 +88,10 @@ WebGLContext::BindBufferBase(WebGLenum target, WebGLuint index, WebGLBuffer* buf
}
void
WebGLContext::BindBufferRange(WebGLenum target, WebGLuint index, WebGLBuffer* buffer,
WebGLContext::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
WebGLintptr offset, WebGLsizeiptr size)
{
if (!IsContextStable())
if (IsContextLost())
return;
if (!ValidateObjectAllowDeletedOrNull("bindBufferRange", buffer))
@ -113,6 +114,12 @@ WebGLContext::BindBufferRange(WebGLenum target, WebGLuint index, WebGLBuffer* bu
} else if (target != buffer->Target()) {
return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target");
}
CheckedInt<WebGLsizeiptr> checked_neededByteLength = CheckedInt<WebGLsizeiptr>(offset) + size;
if (!checked_neededByteLength.isValid() ||
checked_neededByteLength.value() > buffer->ByteLength())
{
return ErrorInvalidValue("bindBufferRange: invalid range");
}
}
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bindBuffer");
@ -128,10 +135,10 @@ WebGLContext::BindBufferRange(WebGLenum target, WebGLuint index, WebGLBuffer* bu
}
void
WebGLContext::BufferData(WebGLenum target, WebGLsizeiptr size,
WebGLenum usage)
WebGLContext::BufferData(GLenum target, WebGLsizeiptr size,
GLenum usage)
{
if (!IsContextStable())
if (IsContextLost())
return;
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferData");
@ -146,6 +153,10 @@ WebGLContext::BufferData(WebGLenum target, WebGLsizeiptr size,
if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
return;
// careful: WebGLsizeiptr is always 64-bit, but GLsizeiptr is like intptr_t.
if (!CheckedInt<GLsizeiptr>(size).isValid())
return ErrorOutOfMemory("bufferData: bad size");
WebGLBuffer* boundBuffer = bufferSlot->get();
if (!boundBuffer)
@ -173,11 +184,11 @@ WebGLContext::BufferData(WebGLenum target, WebGLsizeiptr size,
}
void
WebGLContext::BufferData(WebGLenum target,
WebGLContext::BufferData(GLenum target,
const Nullable<ArrayBuffer> &maybeData,
WebGLenum usage)
GLenum usage)
{
if (!IsContextStable())
if (IsContextLost())
return;
if (maybeData.IsNull()) {
@ -193,6 +204,10 @@ WebGLContext::BufferData(WebGLenum target,
const ArrayBuffer& data = maybeData.Value();
// careful: data.Length() could conceivably be any size_t, but GLsizeiptr is like intptr_t.
if (!CheckedInt<GLsizeiptr>(data.Length()).isValid())
return ErrorOutOfMemory("bufferData: bad size");
if (!ValidateBufferUsageEnum(usage, "bufferData: usage"))
return;
@ -218,10 +233,10 @@ WebGLContext::BufferData(WebGLenum target,
}
void
WebGLContext::BufferData(WebGLenum target, const ArrayBufferView& data,
WebGLenum usage)
WebGLContext::BufferData(GLenum target, const ArrayBufferView& data,
GLenum usage)
{
if (!IsContextStable())
if (IsContextLost())
return;
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData");
@ -238,6 +253,10 @@ WebGLContext::BufferData(WebGLenum target, const ArrayBufferView& data,
if (!boundBuffer)
return ErrorInvalidOperation("bufferData: no buffer bound!");
// careful: data.Length() could conceivably be any size_t, but GLsizeiptr is like intptr_t.
if (!CheckedInt<GLsizeiptr>(data.Length()).isValid())
return ErrorOutOfMemory("bufferData: bad size");
InvalidateBufferFetching();
MakeContextCurrent();
@ -257,7 +276,7 @@ void
WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
const Nullable<ArrayBuffer> &maybeData)
{
if (!IsContextStable())
if (IsContextLost())
return;
if (maybeData.IsNull()) {
@ -281,7 +300,7 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
if (!boundBuffer)
return ErrorInvalidOperation("bufferData: no buffer bound!");
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length();
CheckedInt<WebGLsizeiptr> checked_neededByteLength = CheckedInt<WebGLsizeiptr>(byteOffset) + data.Length();
if (!checked_neededByteLength.isValid())
return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length");
@ -297,10 +316,10 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
}
void
WebGLContext::BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
const ArrayBufferView& data)
{
if (!IsContextStable())
if (IsContextLost())
return;
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bufferSubData");
@ -317,7 +336,7 @@ WebGLContext::BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
if (!boundBuffer)
return ErrorInvalidOperation("bufferSubData: no buffer bound!");
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length();
CheckedInt<WebGLsizeiptr> checked_neededByteLength = CheckedInt<WebGLsizeiptr>(byteOffset) + data.Length();
if (!checked_neededByteLength.isValid())
return ErrorInvalidValue("bufferSubData: integer overflow computing the needed byte length");
@ -334,7 +353,7 @@ WebGLContext::BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
already_AddRefed<WebGLBuffer>
WebGLContext::CreateBuffer()
{
if (!IsContextStable())
if (IsContextLost())
return nullptr;
nsRefPtr<WebGLBuffer> globj = new WebGLBuffer(this);
@ -344,7 +363,7 @@ WebGLContext::CreateBuffer()
void
WebGLContext::DeleteBuffer(WebGLBuffer *buffer)
{
if (!IsContextStable())
if (IsContextLost())
return;
if (!ValidateObjectAllowDeletedOrNull("deleteBuffer", buffer))
@ -374,7 +393,7 @@ WebGLContext::DeleteBuffer(WebGLBuffer *buffer)
bool
WebGLContext::IsBuffer(WebGLBuffer *buffer)
{
if (!IsContextStable())
if (IsContextLost())
return false;
return ValidateObjectAllowDeleted("isBuffer", buffer) &&
@ -383,7 +402,7 @@ WebGLContext::IsBuffer(WebGLBuffer *buffer)
}
bool
WebGLContext::ValidateBufferUsageEnum(WebGLenum target, const char *infos)
WebGLContext::ValidateBufferUsageEnum(GLenum target, const char *infos)
{
switch (target) {
case LOCAL_GL_STREAM_DRAW:
@ -440,3 +459,39 @@ WebGLContext::GetBufferSlotByTargetIndexed(GLenum target, GLuint index, const ch
ErrorInvalidEnum("%s: target: invalid enum value 0x%x", infos, target);
return nullptr;
}
GLenum
WebGLContext::CheckedBufferData(GLenum target,
GLsizeiptr size,
const GLvoid *data,
GLenum usage)
{
#ifdef XP_MACOSX
// bug 790879
if (gl->WorkAroundDriverBugs() &&
int64_t(size) > INT32_MAX) // the cast avoids a potential always-true warning on 32bit
{
GenerateWarning("Rejecting valid bufferData call with size %lu to avoid a Mac bug", size);
return LOCAL_GL_INVALID_VALUE;
}
#endif
WebGLBuffer *boundBuffer = nullptr;
if (target == LOCAL_GL_ARRAY_BUFFER) {
boundBuffer = mBoundArrayBuffer;
} else if (target == LOCAL_GL_ELEMENT_ARRAY_BUFFER) {
boundBuffer = mBoundVertexArray->mBoundElementArrayBuffer;
}
NS_ABORT_IF_FALSE(boundBuffer != nullptr, "no buffer bound for this target");
bool sizeChanges = uint32_t(size) != boundBuffer->ByteLength();
if (sizeChanges) {
UpdateWebGLErrorAndClearGLError();
gl->fBufferData(target, size, data, usage);
GLenum error = LOCAL_GL_NO_ERROR;
UpdateWebGLErrorAndClearGLError(&error);
return error;
} else {
gl->fBufferData(target, size, data, usage);
return LOCAL_GL_NO_ERROR;
}
}

View File

@ -136,7 +136,7 @@ CompareWebGLExtensionName(const nsACString& name, const char *other)
JSObject*
WebGLContext::GetExtension(JSContext *cx, const nsAString& aName, ErrorResult& rv)
{
if (!IsContextStable())
if (IsContextLost())
return nullptr;
NS_LossyConvertUTF16toASCII name(aName);
@ -257,7 +257,7 @@ void
WebGLContext::GetSupportedExtensions(JSContext *cx, Nullable< nsTArray<nsString> > &retval)
{
retval.SetNull();
if (!IsContextStable())
if (IsContextLost())
return;
nsTArray<nsString>& arr = retval.SetValue();

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